Volume* createFloatFieldVolumeFromVolume(Volume *base_volume) { int width = base_volume->width(); int height = base_volume->height(); int depth = base_volume->depth(); std::vector<AbstractScalarField*> fields; for(int m=0; m < base_volume->numberOfMaterials(); m++) { float *data = new float[width*height*depth]; for(int d=0; d < depth; d++){ for(int h=0; h < height; h++){ for(int w=0; w < width; w++){ data[d*width*height + h*width + w] = (float)base_volume->valueAt(w+0.5,h+0.5,d+0.5, m); } } } ScalarField<float> *floatField = new ScalarField<float>(data,width,height,depth); floatField->setName(base_volume->getMaterial(m)->name() + "_asFloat"); fields.push_back(floatField); } cleaver::Volume *floatVolume = new Volume(fields); floatVolume->setName(base_volume->name()); return floatVolume; }
TEST_F(FieldFETest, scalar) { FE_P_disc<1,1,3> fe1; FE_P_disc<1,2,3> fe2; FE_P_disc<1,3,3> fe3; ScalarField field; dh->distribute_dofs(fe1, fe2, fe3); field.set_fe_data(dh, &map1, &map2, &map3, &v); field.set_time(0.0); dof_values[0] = 1; dof_values[1] = 2; dof_values[2] = 3; vector<double> values(3); // test values at vertices of the triangle field.value_list( { { 1, 1, 5 }, { 4, 0, 5 }, { 2, 3, 5 } }, mesh->element_accessor(0), values ); EXPECT_DOUBLE_EQ( dof_values[0], values[0] ); EXPECT_DOUBLE_EQ( dof_values[1], values[1] ); EXPECT_DOUBLE_EQ( dof_values[2], values[2] ); // test value at barycenter EXPECT_DOUBLE_EQ( (dof_values[0]+dof_values[1]+dof_values[2])/3, field.value({ 7./3, 4./3, 5 }, mesh->element_accessor(0)) ); }
ScalarField<float>* createFloatFieldFromScalarField(AbstractScalarField *scalarField) { int w = (int)(scalarField->bounds().size.x); int h = (int)(scalarField->bounds().size.y); int d = (int)(scalarField->bounds().size.z); int wh = w*h; int whd = wh*d; float *data = new float[whd]; for(int k=0; k < d; k++) { for(int j=0; j < h; j++) { for(int i=0; i < w; i++) { data[k*wh + j*w + i] = (float)scalarField->valueAt(i+0.5, j+0.5, k+0.5); } } } ScalarField<float> *floatField = new ScalarField<float>(data, w, h, d); floatField->setBounds(scalarField->bounds()); return floatField; }
ScalarField<double>* createDoubleFieldFromScalarField(AbstractScalarField *scalarField) { int w = (int)(scalarField->bounds().size.x); int h = (int)(scalarField->bounds().size.y); int d = (int)(scalarField->bounds().size.z); int wh = w*h; int whd = wh*d; double *data = new double[whd]; for(int k=0; k < d; k++) { for(int j=0; j < h; j++) { for(int i=0; i < w; i++) { data[k*wh + j*w + i] = scalarField->valueAt(i+0.5, j+0.5, k+0.5); } } } ScalarField<double> *doubleField = new ScalarField<double>(data, w, h, d); doubleField->setBounds(scalarField->bounds()); return doubleField; }
bool ChunkedPointCloud::enableScalarField() { ScalarField* currentInScalarField = getCurrentInScalarField(); if (!currentInScalarField) { //if we get there, it means that either the caller has forgot to create //(and assign) a scalar field to the cloud, or that we are in a compatibility //mode with old/basic behaviour: a unique SF for everything (input/output) //we look for any already existing "default" scalar field m_currentInScalarFieldIndex = getScalarFieldIndexByName("Default"); if (m_currentInScalarFieldIndex < 0) { //if not, we create it m_currentInScalarFieldIndex = addScalarField("Default"); if (m_currentInScalarFieldIndex < 0) //Something went wrong return false; } currentInScalarField = getCurrentInScalarField(); assert(currentInScalarField); } //if there's no output scalar field either, we set this new scalar field as output also if (!getCurrentOutScalarField()) m_currentOutScalarFieldIndex = m_currentInScalarFieldIndex; return currentInScalarField->resize(m_points->capacity()); }
int ChunkedPointCloud::addScalarField(const char* uniqueName, bool isStrictlyPositive) { //we don't accept two SF with the same name! if (getScalarFieldIndexByName(uniqueName)>=0) return -1; //create requested scalar field ScalarField* sf = new ScalarField(uniqueName,isStrictlyPositive); if (!sf) return -1; //we don't want 'm_scalarFields' to grow by 50% each time! (default behavior of std::vector::push_back) try { m_scalarFields.push_back(sf); } catch (.../*const std::bad_alloc&*/) //out of memory { sf->release(); return -1; } sf->link(); return (int)m_scalarFields.size()-1; }
int ChunkedPointCloud::addScalarField(const char* uniqueName) { //we don't accept two SF with the same name! if (getScalarFieldIndexByName(uniqueName) >= 0) return -1; //create requested scalar field ScalarField* sf = new ScalarField(uniqueName); if (!sf || (size() && !sf->resize(size()))) { //Not enough memory! if (sf) sf->release(); return -1; } try { //we don't want 'm_scalarFields' to grow by 50% each time! (default behavior of std::vector::push_back) m_scalarFields.resize(m_scalarFields.size()+1); } catch (std::bad_alloc) //out of memory { sf->release(); return -1; } m_scalarFields.back() = sf; sf->link(); return (int)m_scalarFields.size()-1; }
void deriv_yy(const ScalarField<T, S>& f, ScalarField<S, S>& out) { const GridParams& p = f.grid_params(); assert(p == out.grid_params()); assert(p.ny >= 3); const double d = 1./(p.eps_y*p.eps_y); for (int i = 0; i < p.nx; ++i) { for (int j = 0; j < p.ny; ++j) { T a, b, c; if (j == 0) { a = f(i,j); b = f(i,j+1); c = f(i,j+2); } else if (j == p.ny-1) { a = f(i,j-2); b = f(i,j-1); c = f(i,j); } else { a = f(i,j-1); b = f(i,j); c = f(i,j+1); } out(i,j) = (a - 2.*b + c) * d; } } }
void deriv_xx(const ScalarField<T, S>& f, ScalarField<S, S>& out) { const GridParams& p = f.grid_params(); assert(p == out.grid_params()); assert(p.nx >= 3); const double d = 1./(p.eps_x*p.eps_x); for (int i = 0; i < p.nx; ++i) { for (int j = 0; j < p.ny; ++j) { T a, b, c; if (i == 0) { a = f(i,j); b = f(i+1,j); c = f(i+2,j); } else if (i == p.nx-1) { a = f(i-2,j); b = f(i-1,j); c = f(i,j); } else { a = f(i-1,j); b = f(i,j); c = f(i+1,j); } out(i,j) = (a - 2.*b + c) * d; } } }
ScalarField Real(const complexScalarField& C) { const GridInfo& gInfo = C->gInfo; ScalarField R; nullToZero(R, gInfo); callPref(eblas_daxpy)(gInfo.nr, C->scale, (const double*)C->dataPref(false), 2, R->dataPref(false), 1); R->scale = 1; return R; }
bool ChunkedPointCloud::isScalarFieldEnabled() const { ScalarField* currentInScalarFieldArray = getCurrentInScalarField(); if (!currentInScalarFieldArray) return false; unsigned sfValuesCount = currentInScalarFieldArray->currentSize(); return (sfValuesCount>0 && sfValuesCount >= m_points->currentSize()); }
void apply_flow(const ScalarField<ElemT, ExprT>& phi, const DoubleField& u_x, const DoubleField& u_y, ScalarField<ExprT, ExprT>& out) { const GridParams& gp = phi.grid_params(); assert(u_x.grid_params() == gp && u_y.grid_params() == gp && out.grid_params() == gp); for (int i = 0; i < gp.nx; ++i) { for (int j = 0; j < gp.ny; ++j) { auto xy = gp.to_xy(i, j); out(i,j) = phi.eval_xy(xy.first - u_x(i,j), xy.second - u_y(i,j)); } } }
void deriv_y(const ScalarField<T, S>& f, ScalarField<S, S>& g_y) { const GridParams& p = f.grid_params(); assert(p == g_y.grid_params()); // derivatives in y direction for (int i = 0; i < p.nx; ++i) { for (int j = 0; j < p.ny - 1; ++j) { g_y(i,j) = (f(i,j+1) - f(i,j)) * (1./p.eps_y); } // copy over last column g_y(i,p.ny-1) = g_y(i,p.ny-2); } }
bool ChunkedPointCloud::renameScalarField(int index, const char* newName) { if (getScalarFieldIndexByName(newName) < 0) { ScalarField* sf = getScalarField(index); if (sf) { sf->setName(newName); return true; } } return false; }
void deriv_x(const ScalarField<T, S>& f, ScalarField<S, S>& g_x) { const GridParams& p = f.grid_params(); assert(p == g_x.grid_params()); // derivatives in x direction for (int i = 0; i < p.nx - 1; ++i) { for (int j = 0; j < p.ny; ++j) { g_x(i,j) = (f(i+1,j) - f(i,j)) * (1./p.eps_x); } } // copy over last row for (int j = 0; j < p.ny; ++j) { g_x(p.nx-1,j) = g_x(p.nx-2,j); } }
int main(int argc, char *argv[]) { char str[200]; int i; if(argc<7 ) { std::cout<<"Usage: dtiFA xsize ysize zsize input_dtfile output_fa_file switch_endian_input(0/1)\n"; exit(0); } int Xdim= atoi(argv[1]); int Ydim= atoi(argv[2]); int Zdim= atoi(argv[3]); TensorField dti; dti.init(Xdim,Ydim,Zdim); int endian_be=0; endian_be= atoi(argv[6]); if(endian_be) { //std::cout<<"Reading in big endian format\n"; dti.importRawFieldFromFile_BE(argv[4]); } else { dti.importRawFieldFromFile(argv[4]); } //std::cout<<"DTI read\n"; ScalarField fa; fa.init(Xdim,Ydim,Zdim); // fa.setVoxelSize(0,Xres); fa.setVoxelSize(1,Yres); fa.setVoxelSize(2,Zres); dti.ComputeFA(&fa); //std::cout<<"Smooth FA computed\n"; sprintf(str,"%s",argv[5]); fa.exportRawFieldToFile(str); return 0; }
void Dump::dumpRsol(ScalarField nbound, string fname) { //Compute normalization factor for the partition: int nAtomsTot = 0; for(const auto& sp: e->iInfo.species) nAtomsTot += sp->atpos.size(); const double nFloor = 1e-5/nAtomsTot; //lower cap on densities to prevent Nyquist noise in low density regions ScalarField nAtomicTot; for(const auto& sp: e->iInfo.species) { RadialFunctionG nRadial; logSuspend(); sp->getAtom_nRadial(0,0, nRadial, true); logResume(); for(unsigned atom=0; atom<sp->atpos.size(); atom++) { ScalarField nAtomic = radialFunction(e->gInfo, nRadial, sp->atpos[atom]); double nMin, nMax; callPref(eblas_capMinMax)(e->gInfo.nr, nAtomic->dataPref(), nMin, nMax, nFloor); nAtomicTot += nAtomic; } } ScalarField nboundByAtomic = (nbound*nbound) * inv(nAtomicTot); ScalarField rInv0(ScalarFieldData::alloc(e->gInfo)); { logSuspend(); WignerSeitz ws(e->gInfo.R); logResume(); threadLaunch(set_rInv, e->gInfo.nr, e->gInfo.S, e->gInfo.RTR, &ws, rInv0->data()); } //Compute bound charge 1/r and 1/r^2 expectation values weighted by atom-density partition: FILE* fp = fopen(fname.c_str(), "w"); fprintf(fp, "#Species rMean +/- rSigma [bohrs] (rMean +/- rSigma [Angstrom]) sqrt(Int|nbound^2|) in partition\n"); for(const auto& sp: e->iInfo.species) { RadialFunctionG nRadial; logSuspend(); sp->getAtom_nRadial(0,0, nRadial, true); logResume(); for(unsigned atom=0; atom<sp->atpos.size(); atom++) { ScalarField w = radialFunction(e->gInfo, nRadial, sp->atpos[atom]) * nboundByAtomic; //Get r centered at current atom: ScalarFieldTilde trans; nullToZero(trans, e->gInfo); initTranslation(trans, e->gInfo.R*sp->atpos[atom]); ScalarField rInv = I(trans * J(rInv0), true); //Compute moments: double wNorm = integral(w); double rInvMean = integral(w * rInv) / wNorm; double rInvSqMean = integral(w * rInv * rInv) / wNorm; double rInvSigma = sqrt(rInvSqMean - rInvMean*rInvMean); double rMean = 1./rInvMean; double rSigma = rInvSigma / (rInvMean*rInvMean); //Print stats: fprintf(fp, "Rsol %s %.2lf +/- %.2lf ( %.2lf +/- %.2lf A ) Qrms: %.1le\n", sp->name.c_str(), rMean, rSigma, rMean/Angstrom, rSigma/Angstrom, sqrt(wNorm)); } } fclose(fp); }
// Public Methods void TextInOut::writeScalarField( const ScalarField &scalar_field ) { // Write header fprintf( f, "dx = %e, radius = %e, n = %d\n", dx, radius, n ); // Write the scalar values to file. for ( int i = 0; i < scalar_field.shape()(0); i++ ) fprintf( f, "%e\n", scalar_field(i) ); }
void deriv_y_central(const ScalarField<T, S>& f, ScalarField<S, S>& g_y) { const GridParams& p = f.grid_params(); assert(p == g_y.grid_params()); // derivatives in y direction // forward/backward differences for edges, central for everything else for (int i = 0; i < p.nx; ++i) { for (int j = 0; j < p.ny; ++j) { if (j == 0) { g_y(i,j) = (f(i,j+1) - f(i,j)) * (1./p.eps_y); } else if (j == p.ny-1) { g_y(i,j) = (f(i,j) - f(i,j-1)) * (1./p.eps_y); } else { g_y(i,j) = (f(i,j+1) - f(i,j-1)) * (1./(2.*p.eps_y)); } } } }
void PrescribedField::set_bound(const int d, const int i, const ScalarField & u) { if( i*i != 1 ) throw invalid_argument("In PrescribedField::set_bound(int d, int i, ScalarField u) direction i must be either -1 or 1"); if( d >= (int)m_r_len || d < 0 ) throw invalid_argument("In PrescribedField::set_bound(int d, int i, ScalarField u) axis number d must be >=0 and <m_r_len"); if( !(u.get_range() == m_bounds[2*d].get_range()) ) throw invalid_argument("In PrescribedField::set_bound(int d, int i, ScalarField u) invalid u range"); if(i == -1) m_bounds[2*d] = u; else m_bounds[2*d+1] = u; }
int main(int argc, char *argv[]) { char str[200]; int i; if(argc<7 ) { std::cout<<"Usage: dtiTrace xsize ysize zsize input_dtfile output_trace_file switch_endian_input(0/1)\n"; exit(0); } int Xdim= atoi(argv[1]); int Ydim= atoi(argv[2]); int Zdim= atoi(argv[3]); TensorField dti; dti.init(Xdim,Ydim,Zdim); int endian_be=0; endian_be= atoi(argv[6]); if(endian_be) dti.importRawFieldFromFile_BE(argv[4]); else dti.importRawFieldFromFile(argv[4]); std::cout<<"DTI read\n"; //std::cout<<"DTI read\n"; ScalarField trace; trace.init(Xdim,Ydim,Zdim); // trace.setVoxelSize(0,Xres); trace.setVoxelSize(1,Yres); trace.setVoxelSize(2,Zres); dti.ComputeTrace(&trace); //std::cout<<"Smooth TRACE computed\n"; sprintf(str,"%s",argv[5]); trace.exportRawFieldToFile(str); return 0; }
double Fex_H2O_FittedCorrelations::compute(const ScalarFieldTilde* Ntilde, ScalarFieldTilde* Phi_Ntilde) const { double PhiEx = 0.0; //Quadratic part: ScalarFieldTilde V_O = double(gInfo.nr)*(COO*Ntilde[0] + COH*Ntilde[1]); Phi_Ntilde[0] += V_O; ScalarFieldTilde V_H = double(gInfo.nr)*(COH*Ntilde[0] + CHH*Ntilde[1]); Phi_Ntilde[1] += V_H; PhiEx += 0.5*gInfo.dV*(dot(V_O,Ntilde[0]) + dot(V_H,Ntilde[1])); //Compute gaussian weighted densities: ScalarField NObar = I(fex_gauss*Ntilde[0]), Phi_NObar; nullToZero(Phi_NObar, gInfo); ScalarField NHbar = I(fex_gauss*Ntilde[1]), Phi_NHbar; nullToZero(Phi_NHbar, gInfo); //Evaluated weighted density functional: #ifdef GPU_ENABLED ScalarField fex(ScalarFieldData::alloc(gInfo,isGpuEnabled())); Fex_H20_FittedCorrelations_gpu(gInfo.nr, NObar->dataGpu(), NHbar->dataGpu(), fex->dataGpu(), Phi_NObar->dataGpu(), Phi_NHbar->dataGpu()); PhiEx += integral(fex); #else PhiEx += gInfo.dV*threadedAccumulate(Fex_H2O_FittedCorrelations_calc, gInfo.nr, NObar->data(), NHbar->data(), Phi_NObar->data(), Phi_NHbar->data()); #endif //Convert gradients: Phi_Ntilde[0] += fex_gauss*Idag(Phi_NObar); Phi_Ntilde[1] += fex_gauss*Idag(Phi_NHbar); return PhiEx; }
double Fex_ScalarEOS::compute(const ScalarFieldTilde* Ntilde, ScalarFieldTilde* Phi_Ntilde) const { //Polarizability-averaged density: double alphaTot = 0.; ScalarFieldTilde NavgTilde; for(unsigned i=0; i<molecule.sites.size(); i++) { const Molecule::Site& s = *(molecule.sites[i]); NavgTilde += s.alpha * Ntilde[i]; alphaTot += s.alpha * s.positions.size(); } NavgTilde *= (1./alphaTot); //Compute LJatt weighted density: ScalarField Nbar = I(fex_LJatt*NavgTilde); //Evaluated weighted density functional: ScalarField Aex, Aex_Nbar; nullToZero(Aex, gInfo); nullToZero(Aex_Nbar, gInfo); callPref(eos.evaluate)(gInfo.nr, Nbar->dataPref(), Aex->dataPref(), Aex_Nbar->dataPref(), Vhs); //Convert gradients: ScalarField Navg = I(NavgTilde); ScalarFieldTilde IdagAex = Idag(Aex); for(unsigned i=0; i<molecule.sites.size(); i++) { const Molecule::Site& s = *(molecule.sites[i]); Phi_Ntilde[i] += (fex_LJatt*Idag(Navg*Aex_Nbar) + IdagAex) * (s.alpha/alphaTot); } return gInfo.dV*dot(Navg,Aex); }
bool AutoSegmentationTools::frontPropagationBasedSegmentation(GenericIndexedCloudPersist* theCloud, ScalarType minSeedDist, uchar octreeLevel, ReferenceCloudContainer& theSegmentedLists, GenericProgressCallback* progressCb, DgmOctree* inputOctree, bool applyGaussianFilter, float alpha) { unsigned numberOfPoints = (theCloud ? theCloud->size() : 0); if (numberOfPoints == 0) return false; //compute octree if none was provided DgmOctree* theOctree = inputOctree; if (!theOctree) { theOctree = new DgmOctree(theCloud); if (theOctree->build(progressCb)<1) { delete theOctree; return false; } } //on calcule le gradient (va ecraser le champ des distances) if (ScalarFieldTools::computeScalarFieldGradient(theCloud,true,true,progressCb,theOctree) < 0) { if (!inputOctree) delete theOctree; return false; } //et on lisse le resultat if (applyGaussianFilter) { uchar level = theOctree->findBestLevelForAGivenPopulationPerCell(NUMBER_OF_POINTS_FOR_GRADIENT_COMPUTATION); PointCoordinateType cellSize = theOctree->getCellSize(level); ScalarFieldTools::applyScalarFieldGaussianFilter(static_cast<float>(cellSize/3),theCloud,-1,progressCb,theOctree); } unsigned seedPoints = 0; unsigned numberOfSegmentedLists = 0; //on va faire la propagation avec le FastMarching(); FastMarchingForPropagation* fm = new FastMarchingForPropagation(); fm->setJumpCoef(50.0); fm->setDetectionThreshold(alpha); int result = fm->init(theCloud,theOctree,octreeLevel); int octreeLength = OCTREE_LENGTH(octreeLevel)-1; if (result<0) { if (!inputOctree) delete theOctree; delete fm; return false; } if (progressCb) { progressCb->reset(); progressCb->setMethodTitle("FM Propagation"); char buffer[256]; sprintf(buffer,"Octree level: %i\nNumber of points: %u",octreeLevel,numberOfPoints); progressCb->setInfo(buffer); progressCb->start(); } ScalarField* theDists = new ScalarField("distances"); { ScalarType d = theCloud->getPointScalarValue(0); if (!theDists->resize(numberOfPoints,true,d)) { if (!inputOctree) delete theOctree; return false; } } unsigned maxDistIndex = 0, begin = 0; CCVector3 startPoint; while (true) { ScalarType maxDist = NAN_VALUE; //on cherche la premiere distance superieure ou egale a "minSeedDist" while (begin<numberOfPoints) { const CCVector3 *thePoint = theCloud->getPoint(begin); const ScalarType& theDistance = theDists->getValue(begin); ++begin; //FIXME DGM: what happens if SF is negative?! if (theCloud->getPointScalarValue(begin) >= 0 && theDistance >= minSeedDist) { maxDist = theDistance; startPoint = *thePoint; maxDistIndex = begin; break; } } //il n'y a plus de point avec des distances suffisamment grandes ! if (maxDist<minSeedDist) break; //on finit la recherche du max for (unsigned i=begin; i<numberOfPoints; ++i) { const CCVector3 *thePoint = theCloud->getPoint(i); const ScalarType& theDistance = theDists->getValue(i); if ((theCloud->getPointScalarValue(i)>=0.0)&&(theDistance > maxDist)) { maxDist = theDistance; startPoint = *thePoint; maxDistIndex = i; } } int pos[3]; theOctree->getTheCellPosWhichIncludesThePoint(&startPoint,pos,octreeLevel); //clipping (important!) pos[0] = std::min(octreeLength,pos[0]); pos[1] = std::min(octreeLength,pos[1]); pos[2] = std::min(octreeLength,pos[2]); fm->setSeedCell(pos); ++seedPoints; int result = fm->propagate(); //if the propagation was successful if (result >= 0) { //we extract the corresponding points ReferenceCloud* newCloud = new ReferenceCloud(theCloud); if (fm->extractPropagatedPoints(newCloud) && newCloud->size() != 0) { theSegmentedLists.push_back(newCloud); ++numberOfSegmentedLists; } else { //not enough memory?! delete newCloud; newCloud = 0; } if (progressCb) progressCb->update(float(numberOfSegmentedLists % 100)); fm->cleanLastPropagation(); //break; } if (maxDistIndex == begin) ++begin; } if (progressCb) progressCb->stop(); for (unsigned i=0; i<numberOfPoints; ++i) theCloud->setPointScalarValue(i,theDists->getValue(i)); delete fm; fm = 0; theDists->release(); theDists = 0; if (!inputOctree) delete theOctree; return true; }
ConvolutionJDFT(const Everything& e, const FluidSolverParams& fsp) : FluidSolver(e, fsp), Adiel_rhoExplicitTilde(0) { //Initialize fluid mixture: fluidMixture = new FluidMixtureJDFT(e, gInfo, fsp.T); fluidMixture->verboseLog = fsp.verboseLog; //Add the fluid components: for(const auto& c: fsp.components) c->addToFluidMixture(fluidMixture); if(fsp.FmixList.size()) { //create fluid mixtures logPrintf("\n------------ Fluid Mixing Functionals ------------\n"); for(const auto& f: fsp.FmixList) { std::shared_ptr<FluidComponent> c1 = f.fluid1; string name1 = c1->molecule.name; std::shared_ptr<FluidComponent> c2 = f.fluid2; string name2 = c2->molecule.name; std::shared_ptr<Fmix> Fmix; if (f.FmixType == GaussianKernel) Fmix = std::make_shared<Fmix_GaussianKernel>(fluidMixture,c1,c2,f.energyScale,f.lengthScale); else if (f.FmixType == LJPotential) Fmix = std::make_shared<Fmix_LJ>(fluidMixture,c1,c2,f.energyScale,f.lengthScale); else die("Valid mixing functional between %s and %s not specified!\n",name1.c_str(),name2.c_str()); FmixPtr.push_back(Fmix); } } fluidMixture->initialize(fsp.P, epsBulk, epsInf); //set fluid exCorr logPrintf("\n------- Fluid Exchange Correlation functional -------\n"); ((ExCorr&)fsp.exCorr).setup(e); //Initialize coupling: coupling = std::make_shared<ConvCoupling>(fluidMixture, fsp.exCorr); //Create van der Waals mixing functional myassert(e.vanDerWaals); vdwCoupling = std::make_shared<VDWCoupling>(fluidMixture, atpos, e.vanDerWaals, e.vanDerWaals->getScaleFactor(fsp.exCorr.getName(), fsp.vdwScale)); //---- G=0 constraints ----- //Electron density in the bulk of the fluid double nFl_bulk = 0.0; for(const auto& c: fsp.components) { for(unsigned i=0; i<c->molecule.sites.size(); i++) { const Molecule::Site& s = *(c->molecule.sites[i]); nFl_bulk += c->idealGas->get_Nbulk()*s.elecKernel(0)*s.positions.size(); } } logPrintf("\nBulk electron density of the liquid: %le bohr^-3\n",nFl_bulk); //calculate G=0 offset due to coupling functional evaluated at bulk fluid density ScalarField nBulk; nullToZero(nBulk,e.gInfo); //initialize constant ScalarField with density nFl_bulk for (int i=0; i<e.gInfo.nr; i++) nBulk->data()[i] = nFl_bulk; ScalarField Vxc_bulk; (coupling->exCorr)(nBulk, &Vxc_bulk, true); logPrintf("Electron deep in fluid experiences coupling potential: %lg H\n\n", Vxc_bulk->data()[0]); coupling->Vxc_bulk = Vxc_bulk->data()[0]; }
int main(int argc, char **argv ) { walberla::Environment env( argc, argv ); const uint_t cells [] = { 6,5,3 }; const uint_t blockCount [] = { 4, 3,2 }; const uint_t nrOfTimeSteps = 20; // Create BlockForest auto blocks = blockforest::createUniformBlockGrid(blockCount[0],blockCount[1],blockCount[2], //blocks cells[0],cells[1],cells[2], //cells 1, //dx false, //one block per process true,true,true); //periodicity LatticeModel latticeModel( lbm::collision_model::SRT(1.5 ) ); // In addition to the normal GhostLayerField's we allocated additionally a field containing the whole global simulation domain for each block // we can then check if the GhostLayer communication is correct, by comparing the small field to the corresponding part of the big field BlockDataID pdfField = lbm::addPdfFieldToStorage( blocks, "PdfField", latticeModel ); BlockDataID scalarField1 = field::addToStorage<ScalarField>( blocks, "ScalarFieldOneGl", real_t(0), field::zyxf, 1 ); BlockDataID scalarField2 = field::addToStorage<ScalarField>( blocks, "ScalarFieldTwoGl", real_t(0), field::zyxf, 2 ); BlockDataID vectorField = field::addToStorage<VectorField>( blocks, "VectorField", Vector3<real_t>(0,0,0) ); BlockDataID flagField = field::addFlagFieldToStorage<FField>( blocks, "FlagField" ); // Init src field with some values for( auto blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt ) // block loop { // Init PDF field PdfField * src = blockIt->getData<PdfField>(pdfField); for( auto cellIt = src->begin(); cellIt != src->end(); ++cellIt ) // over all x,y,z,f { Cell cell ( cellIt.x(), cellIt.y(), cellIt.z() ); blocks->transformBlockLocalToGlobalCell(cell, *blockIt); *cellIt = real_c( ( cell[0] + cell[1] + cell[2] + cellIt.f() ) % cell_idx_t(42) ); } // Init scalarField1 ScalarField * sf = blockIt->getData<ScalarField> ( scalarField1 ); for( auto cellIt = sf->beginWithGhostLayer(); cellIt != sf->end(); ++cellIt ) // over all x,y,z { Cell cell ( cellIt.x(), cellIt.y(), cellIt.z() ); blocks->transformBlockLocalToGlobalCell(cell, *blockIt); *cellIt = real_c( ( cell[0] + cell[1] + cell[2] ) % cell_idx_t(42) ); } // Init scalarField2 sf = blockIt->getData<ScalarField> ( scalarField2 ); for( auto cellIt = sf->beginWithGhostLayer(); cellIt != sf->end(); ++cellIt ) // over all x,y,z { Cell cell ( cellIt.x(), cellIt.y(), cellIt.z() ); blocks->transformBlockLocalToGlobalCell(cell, *blockIt); *cellIt = real_c( ( cell[0] + cell[1] + cell[2] ) % cell_idx_t(42) ); } // Init vector field VectorField * vf = blockIt->getData<VectorField> ( vectorField ); for ( auto cellIt = vf->beginWithGhostLayer(); cellIt != vf->end(); ++cellIt ) { Cell cell ( cellIt.x(), cellIt.y(), cellIt.z() ); blocks->transformBlockLocalToGlobalCell(cell, *blockIt); *cellIt = Vector3<real_t>( real_c(cell[0]), real_c(cell[1]), real_c(cell[2]) ); } // Init Flag field FField * ff = blockIt->getData<FField> ( flagField ); auto flag1 = ff->registerFlag( "AFlag 1" ); auto flag2 = ff->registerFlag( "BFlag 2" ); for ( auto cellIt = ff->beginWithGhostLayer(); cellIt != ff->end(); ++cellIt ) { Cell cell ( cellIt.x(), cellIt.y(), cellIt.z() ); blocks->transformBlockLocalToGlobalCell( cell, *blockIt ); if ( ( cell[0] + cell[1] + cell[2] ) % 2 ) addFlag( cellIt, flag1); else addFlag( cellIt, flag2); } } // Create TimeLoop SweepTimeloop timeloop (blocks, nrOfTimeSteps ); GUI gui (timeloop, blocks, argc, argv); lbm::connectToGui<LatticeModel>( gui ); gui.run(); //timeloop.singleStep(); return EXIT_SUCCESS; }
ICPRegistrationTools::CC_ICP_RESULT ICPRegistrationTools::RegisterClouds(GenericIndexedCloudPersist* _modelCloud, GenericIndexedCloudPersist* _dataCloud, PointProjectionTools::Transformation& transform, CC_ICP_CONVERGENCE_TYPE convType, double minErrorDecrease, unsigned nbMaxIterations, double& finalError, GenericProgressCallback* progressCb/*=0*/, bool filterOutFarthestPoints/*=false*/, unsigned samplingLimit/*=20000*/, ScalarField* modelWeights/*=0*/, ScalarField* dataWeights/*=0*/) { assert(_modelCloud && _dataCloud); finalError = -1.0; //MODEL CLOUD (reference, won't move) GenericIndexedCloudPersist* modelCloud=_modelCloud; ScalarField* _modelWeights=modelWeights; { if (_modelCloud->size()>samplingLimit) //shall we resample the clouds? (speed increase) { ReferenceCloud* subModelCloud = CloudSamplingTools::subsampleCloudRandomly(_modelCloud,samplingLimit); if (subModelCloud && modelWeights) { _modelWeights = new ScalarField("ResampledModelWeights",modelWeights->isPositive()); unsigned realCount = subModelCloud->size(); if (_modelWeights->reserve(realCount)) { for (unsigned i=0;i<realCount;++i) _modelWeights->addElement(modelWeights->getValue(subModelCloud->getPointGlobalIndex(i))); _modelWeights->computeMinAndMax(); } else { //not enough memory delete subModelCloud; subModelCloud=0; } } modelCloud = subModelCloud; } if (!modelCloud) //something bad happened return ICP_ERROR_NOT_ENOUGH_MEMORY; } //DATA CLOUD (will move) ReferenceCloud* dataCloud=0; ScalarField* _dataWeights=dataWeights; SimpleCloud* rotatedDataCloud=0; //temporary structure (rotated vertices) { if (_dataCloud->size()>samplingLimit) //shall we resample the clouds? (speed increase) { dataCloud = CloudSamplingTools::subsampleCloudRandomly(_dataCloud,samplingLimit); if (dataCloud && dataWeights) { _dataWeights = new ScalarField("ResampledDataWeights",dataWeights->isPositive()); unsigned realCount = dataCloud->size(); if (_dataWeights->reserve(realCount)) { for (unsigned i=0;i<realCount;++i) _dataWeights->addElement(dataWeights->getValue(dataCloud->getPointGlobalIndex(i))); _dataWeights->computeMinAndMax(); } else { //not enough memory delete dataCloud; dataCloud=0; } } } else { //create a 'fake' reference cloud with all points dataCloud = new ReferenceCloud(_dataCloud); if (dataCloud->reserve(_dataCloud->size())) { dataCloud->addPointIndex(0,_dataCloud->size()); } else //not enough memory { delete dataCloud; dataCloud=0; } } if (!dataCloud || !dataCloud->enableScalarField()) //something bad happened { if (dataCloud) delete dataCloud; if (modelCloud && modelCloud != _modelCloud) delete modelCloud; if (_modelWeights && _modelWeights!=modelWeights) _modelWeights->release(); return ICP_ERROR_NOT_ENOUGH_MEMORY; } } //Closest Point Set (see ICP algorithm) ReferenceCloud* CPSet = new ReferenceCloud(modelCloud); ScalarField* CPSetWeights = _modelWeights ? new ScalarField("CPSetWeights",_modelWeights->isPositive()) : 0; //algorithm result CC_ICP_RESULT result = ICP_NOTHING_TO_DO; unsigned iteration = 0; double error = 0.0; //we compute the initial distance between the two clouds (and the CPSet by the way) dataCloud->forEach(ScalarFieldTools::razDistsToHiddenValue); DistanceComputationTools::Cloud2CloudDistanceComputationParams params; params.CPSet = CPSet; if (DistanceComputationTools::computeHausdorffDistance(dataCloud,modelCloud,params,progressCb)>=0) { //12/11/2008 - A.BEY: ICP guarantees only the decrease of the squared distances sum (not the distances sum) error = DistanceComputationTools::computeMeanSquareDist(dataCloud); } else { //if an error occured during distances computation... error = -1.0; result = ICP_ERROR_DIST_COMPUTATION; } if (error > 0.0) { #ifdef _DEBUG FILE* fp = fopen("registration_trace_log.txt","wt"); if (fp) fprintf(fp,"Initial error: %f\n",error); #endif double lastError=error,initialErrorDelta=0.0,errorDelta=0.0; result = ICP_APPLY_TRANSFO; //as soon as we do at least one iteration, we'll have to apply a transformation while (true) { ++iteration; //regarding the progress bar if (progressCb && iteration>1) //on the first iteration, we do... nothing { char buffer[256]; //then on the second iteration, we init/show it if (iteration==2) { initialErrorDelta = errorDelta; progressCb->reset(); progressCb->setMethodTitle("Clouds registration"); sprintf(buffer,"Initial mean square error = %f\n",lastError); progressCb->setInfo(buffer); progressCb->start(); } else //and after we update it continuously { sprintf(buffer,"Mean square error = %f [%f]\n",error,-errorDelta); progressCb->setInfo(buffer); progressCb->update((float)((initialErrorDelta-errorDelta)/(initialErrorDelta-minErrorDecrease)*100.0)); } if (progressCb->isCancelRequested()) break; } //shall we remove points with distance above a given threshold? if (filterOutFarthestPoints) { NormalDistribution N; N.computeParameters(dataCloud,false); if (N.isValid()) { DistanceType mu,sigma2; N.getParameters(mu,sigma2); ReferenceCloud* c = new ReferenceCloud(dataCloud->getAssociatedCloud()); ReferenceCloud* newCPSet = new ReferenceCloud(CPSet->getAssociatedCloud()); //we must also update the CPSet! ScalarField* newdataWeights = (_dataWeights ? new ScalarField("ResampledDataWeights",_dataWeights->isPositive()) : 0); //unsigned realCount = dataCloud->size(); //if (_dataWeights->reserve(realCount)) //{ // for (unsigned i=0;i<realCount;++i) // _dataWeights->addElement(dataWeights->getValue(dataCloud->getPointGlobalIndex(i))); // _dataWeights->computeMinAndMax(); //} //else //{ // //not enough memory // delete dataCloud; // dataCloud=0; //} unsigned n=dataCloud->size(); if (!c->reserve(n) || !newCPSet->reserve(n) || (newdataWeights && !newdataWeights->reserve(n))) { //not enough memory delete c; delete newCPSet; if (newdataWeights) newdataWeights->release(); result = ICP_ERROR_REGISTRATION_STEP; break; } //we keep only the points with "not too high" distances DistanceType maxDist = mu+3.0f*sqrt(sigma2); unsigned realSize=0; for (unsigned i=0;i<n;++i) { unsigned index = dataCloud->getPointGlobalIndex(i); if (dataCloud->getAssociatedCloud()->getPointScalarValue(index)<maxDist) { c->addPointIndex(index); newCPSet->addPointIndex(CPSet->getPointGlobalIndex(i)); if (newdataWeights) newdataWeights->addElement(_dataWeights->getValue(index)); ++realSize; } } //resize should be ok as we have called reserve first c->resize(realSize); //should always be ok as counter<n newCPSet->resize(realSize); //idem if (newdataWeights) newdataWeights->resize(realSize); //idem //replace old structures by new ones delete CPSet; CPSet=newCPSet; delete dataCloud; dataCloud=c; if (_dataWeights) { _dataWeights->release(); _dataWeights = newdataWeights; } } } //update CPSet weights (if any) if (_modelWeights) { unsigned count=CPSet->size(); assert(CPSetWeights); if (CPSetWeights->currentSize()!=count) { if (!CPSetWeights->resize(count)) { result = ICP_ERROR_REGISTRATION_STEP; break; } } for (unsigned i=0;i<count;++i) CPSetWeights->setValue(i,_modelWeights->getValue(CPSet->getPointGlobalIndex(i))); CPSetWeights->computeMinAndMax(); } PointProjectionTools::Transformation currentTrans; //if registration procedure fails if (!RegistrationTools::RegistrationProcedure(dataCloud, CPSet, currentTrans, _dataWeights, _modelWeights)) { result = ICP_ERROR_REGISTRATION_STEP; break; } //get rotated data cloud if (!rotatedDataCloud || filterOutFarthestPoints) { //we create a new structure, with rotated points SimpleCloud* newDataCloud = PointProjectionTools::applyTransformation(dataCloud,currentTrans); if (!newDataCloud) { //not enough memory result = ICP_ERROR_REGISTRATION_STEP; break; } //update dataCloud if (rotatedDataCloud) delete rotatedDataCloud; rotatedDataCloud = newDataCloud; delete dataCloud; dataCloud = new ReferenceCloud(rotatedDataCloud); if (!dataCloud->reserve(rotatedDataCloud->size())) { //not enough memory result = ICP_ERROR_REGISTRATION_STEP; break; } dataCloud->addPointIndex(0,rotatedDataCloud->size()); } else { //we simply have to rotate the existing temporary cloud rotatedDataCloud->applyTransformation(currentTrans); } //compute (new) distances to model params.CPSet = CPSet; if (DistanceComputationTools::computeHausdorffDistance(dataCloud,modelCloud,params)<0) { //an error occured during distances computation... result = ICP_ERROR_REGISTRATION_STEP; break; } lastError = error; //12/11/2008 - A.BEY: ICP guarantees only the decrease of the squared distances sum (not the distances sum) error = DistanceComputationTools::computeMeanSquareDist(dataCloud); finalError = (error>0 ? sqrt(error) : error); #ifdef _DEBUG if (fp) fprintf(fp,"Iteration #%i --> error: %f\n",iteration,error); #endif //error update errorDelta = lastError-error; //is it better? if (errorDelta > 0.0) { //we update global transformation matrix if (currentTrans.R.isValid()) { if (transform.R.isValid()) transform.R = currentTrans.R * transform.R; else transform.R = currentTrans.R; transform.T = currentTrans.R * transform.T; } transform.T += currentTrans.T; } //stop criterion if ((errorDelta < 0.0) || //error increase (convType == MAX_ERROR_CONVERGENCE && errorDelta < minErrorDecrease) || //convergence reached (convType == MAX_ITER_CONVERGENCE && iteration > nbMaxIterations)) //max iteration reached { break; } } if (progressCb) progressCb->stop(); #ifdef _DEBUG if (fp) { fclose(fp); fp=0; } #endif } if (CPSet) delete CPSet; CPSet=0; if (CPSetWeights) CPSetWeights->release(); //release memory if (modelCloud && modelCloud != _modelCloud) delete modelCloud; if (_modelWeights && _modelWeights!=modelWeights) _modelWeights->release(); if (dataCloud) delete dataCloud; if (_dataWeights && _dataWeights!=dataWeights) _dataWeights->release(); if (rotatedDataCloud) delete rotatedDataCloud; return result; }
inline void setPressure(const ScalarField& pp) { du.resize(pp.shape()); p.reference(pp); }
bool AutoSegmentationTools::frontPropagationBasedSegmentation(GenericIndexedCloudPersist* theCloud, bool signedSF, DistanceType minSeedDist, uchar octreeLevel, ReferenceCloudContainer& theSegmentedLists, GenericProgressCallback* progressCb, DgmOctree* _theOctree, bool applyGaussianFilter, float alpha) { if (!theCloud) return false; unsigned numberOfPoints = theCloud->size(); if (numberOfPoints<1) return false; //on calcule l'octree DgmOctree* theOctree = _theOctree; if (!theOctree) { theOctree = new DgmOctree(theCloud); if (theOctree->build(progressCb)<1) { delete theOctree; return false; } } ScalarField* theDists = new ScalarField("distances",true); if (!theDists->reserve(numberOfPoints)) { if (!_theOctree) delete theOctree; return false; } theCloud->placeIteratorAtBegining(); unsigned k=0; DistanceType d = theCloud->getPointScalarValue(k); for (;k<numberOfPoints;++k) theDists->addElement(d); //on calcule le gradient (va écraser le champ des distances) if (ScalarFieldTools::computeScalarFieldGradient(theCloud,signedSF,true,true,progressCb,theOctree)<0) { if (!_theOctree) delete theOctree; return false; } //et on lisse le résultat if (applyGaussianFilter) { uchar level = theOctree->findBestLevelForAGivenPopulationPerCell(NUMBER_OF_POINTS_FOR_GRADIENT_COMPUTATION); float cellSize = theOctree->getCellSize(level); ScalarFieldTools::applyScalarFieldGaussianFilter(cellSize*0.33f,theCloud,signedSF,-1,progressCb,theOctree); } DistanceType maxDist; unsigned seedPoints = 0; unsigned numberOfSegmentedLists = 0; //on va faire la propagation avec le FastMarching(); FastMarchingForPropagation* fm = new FastMarchingForPropagation(); fm->setJumpCoef(50.0); fm->setDetectionThreshold(alpha); int result = fm->init(theCloud,theOctree,octreeLevel); int octreeLength = OCTREE_LENGTH(octreeLevel)-1; if (result<0) { if (!_theOctree) delete theOctree; delete fm; return false; } if (progressCb) { progressCb->reset(); progressCb->setMethodTitle("FM Propagation"); char buffer[256]; sprintf(buffer,"Octree level: %i\nNumber of points: %i",octreeLevel,numberOfPoints); progressCb->setInfo(buffer); progressCb->start(); } unsigned maxDistIndex=0,begin = 0; CCVector3 startPoint; while (true) { maxDist = HIDDEN_VALUE; //on cherche la première distance supérieure ou égale à "minSeedDist" while (begin<numberOfPoints) { const CCVector3 *thePoint = theCloud->getPoint(begin); const DistanceType& theDistance = theDists->getValue(begin); ++begin; if ((theCloud->getPointScalarValue(begin)>=0.0)&&(theDistance >= minSeedDist)) { maxDist = theDistance; startPoint = *thePoint; maxDistIndex = begin; break; } } //il n'y a plus de point avec des distances suffisamment grandes ! if (maxDist<minSeedDist) break; //on finit la recherche du max for (unsigned i=begin;i<numberOfPoints;++i) { const CCVector3 *thePoint = theCloud->getPoint(i); const DistanceType& theDistance = theDists->getValue(i); if ((theCloud->getPointScalarValue(i)>=0.0)&&(theDistance > maxDist)) { maxDist = theDistance; startPoint = *thePoint; maxDistIndex = i; } } //on lance la propagation à partir du point de distance maximale //propagateFromPoint(aList,_GradientNorms,maxDistIndex,octreeLevel,_gui); int pos[3]; theOctree->getTheCellPosWhichIncludesThePoint(&startPoint,pos,octreeLevel); //clipping (important !) pos[0] = std::min(octreeLength,pos[0]); pos[1] = std::min(octreeLength,pos[1]); pos[2] = std::min(octreeLength,pos[2]); fm->setSeedCell(pos); ++seedPoints; int result = fm->propagate(); //si la propagation s'est bien passée if (result>=0) { //on la termine (i.e. on extrait les points correspondant) ReferenceCloud* newCloud = fm->extractPropagatedPoints(); //si la liste convient //on la rajoute au groupe des listes segmentées theSegmentedLists.push_back(newCloud); ++numberOfSegmentedLists; if (progressCb) progressCb->update(float(numberOfSegmentedLists % 100)); fm->endPropagation(); //break; } if (maxDistIndex == begin) ++begin; } if (progressCb) progressCb->stop(); for (unsigned i=0;i<numberOfPoints;++i) theCloud->setPointScalarValue(i,theDists->getValue(i)); delete fm; theDists->release(); theDists=0; if (!_theOctree) delete theOctree; return true; }
int Run(int argc, char ** argv) { int N = 10; int nbIterations = 10; std::string momentumPath, outputPath = "./", deviceName, sourcePath = "./OpenCL.cl"; if (argc < 3) { usage(); return 1; } auto image = ScalarField::Read({ argv[1] }); auto target = ScalarField::Read({ argv[2] }); argc -= 2; argv += 2; Matrix<4, 4> transfo; memset(&transfo[0], 0, 16 * sizeof(float)); transfo[0][0] = transfo[1][1] = transfo[2][2] = transfo[3][3] = 1; std::array<float, 7> weights = {{ 100.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f }}, sigmaXs = {{ 3.f, 3.f, 3.f, 3.f, 3.f, 3.f, 3.f }}, sigmaYs = {{ 3.f, 3.f, 3.f, 3.f, 3.f, 3.f, 3.f }}, sigmaZs = {{ 3.f, 3.f, 3.f, 3.f, 3.f, 3.f, 3.f }}; float alpha = 0.001f, maxVeloUpdate = 0.5f; while (argc > 1) { auto arg = std::string { argv[1] }; --argc; ++argv; if (arg == "-subdivisions" && argc > 1) { N = atoi(argv[1]); --argc; ++argv; } else if (arg == "-iterations" && argc > 1) { nbIterations = atoi(argv[1]); --argc; ++argv; } else if (arg == "-InputInitMomentum" && argc > 1) { momentumPath = argv[1]; --argc; ++argv; } else if (arg == "-OutputPath" && argc > 1) { outputPath = argv[1]; --argc; ++argv; } else if (arg == "-Device" && argc > 1) { deviceName = argv[1]; --argc; ++argv; } else if (arg == "-ShowDevices") { for (auto && d : compute::system::devices()) std::cout << d.name() << std::endl; return 0; } else if (arg == "-affineT" && argc > 12) { for (auto i = 1; i <= 12; ++i) transfo[(i - 1) / 4][(i - 1) % 4] = atof(argv[i]); argc -= 12; argv += 12; } else if (arg == "-Gauss" && argc > 1) { sigmaXs[0] = sigmaYs[0] = sigmaZs[0] = atof(argv[1]); --argc; ++argv; } else if (arg == "-M_gauss" && argc > 1) { auto temp = atoi(argv[1]); --argc; ++argv; for (auto i = 1; i <= 7; ++i) { if (temp >= i && argc > 2) { weights[i - 1] = atof(argv[1]); sigmaXs[i - 1] = sigmaYs[i - 1] = sigmaZs[i - 1] = atof(argv[2]); argc -= 2; argv += 2; } } } else if (arg == "-M_Gauss_easier" && argc > 2) { sigmaXs[0] = atof(argv[1]); sigmaXs[6] = atof(argv[2]); argc -= 2; argv += 2; if (sigmaXs[0] < sigmaXs[6]) { std::swap(sigmaXs[0], sigmaXs[6]); } sigmaYs[0] = sigmaZs[0] = sigmaXs[0]; sigmaYs[6] = sigmaZs[6] = sigmaXs[6]; weights[0] = 0.f; auto a = (sigmaYs[6] - sigmaYs[0]) / 6.f; auto b = sigmaYs[0] - a; for (auto i = 2; i <= 6; ++i) sigmaXs[i - 1] = sigmaYs[i - 1] = sigmaZs[i - 1] = i * a + b; } else if (arg == "-alpha" && argc > 1) { alpha = atof(argv[1]); --argc; ++argv; } else if (arg == "-MaxVeloUpdate" && argc > 1) { maxVeloUpdate = atof(argv[1]); --argc; ++argv; } else if (arg == "-KernelSource" && argc > 1) { sourcePath = argv[1]; --argc; ++argv; } else { usage(); return 1; } } ScalarField momentum; if (momentumPath.empty()) { momentum = ScalarField { image.NX(), image.NY(), image.NZ() }; momentum.Fill(0.f); } else momentum = ScalarField::Read({ momentumPath.c_str() }); if (deviceName.empty()) SetDevice(compute::system::default_device()); else SetDevice(compute::system::find_device(deviceName)); std::cout << "OpenCL will use " << GetDevice().name() << std::endl; compute::command_queue queue { GetContext(), GetDevice() }; SetSourcePath(std::move(sourcePath)); GeoShoot gs { std::move(image), std::move(target), std::move(momentum), transfo, N, queue }; gs.Weights = std::move(weights); gs.SigmaXs = std::move(sigmaXs); gs.SigmaYs = std::move(sigmaYs); gs.SigmaZs = std::move(sigmaZs); gs.Alpha = alpha; gs.MaxUpdate = maxVeloUpdate; gs.Run(nbIterations); queue.finish(); gs.Save(outputPath); return 0; }