예제 #1
0
파일: Cleaver.cpp 프로젝트: dyollb/Cleaver2
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;
}
예제 #2
0
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)) );
}
예제 #3
0
파일: Cleaver.cpp 프로젝트: dyollb/Cleaver2
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;
}
예제 #4
0
파일: Cleaver.cpp 프로젝트: dyollb/Cleaver2
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;
}
예제 #5
0
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());
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
파일: grid.hpp 프로젝트: hojonathanho/timb
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;
    }
  }
}
예제 #9
0
파일: grid.hpp 프로젝트: hojonathanho/timb
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;
    }
  }
}
예제 #10
0
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;
}
예제 #11
0
bool ChunkedPointCloud::isScalarFieldEnabled() const
{
    ScalarField* currentInScalarFieldArray = getCurrentInScalarField();
	if (!currentInScalarFieldArray)
        return false;

	unsigned sfValuesCount = currentInScalarFieldArray->currentSize();
    return (sfValuesCount>0 && sfValuesCount >= m_points->currentSize());
}
예제 #12
0
파일: grid.hpp 프로젝트: hojonathanho/timb
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));
    }
  }
}
예제 #13
0
파일: grid.hpp 프로젝트: hojonathanho/timb
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);
  }
}
예제 #14
0
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;
}
예제 #15
0
파일: grid.hpp 프로젝트: hojonathanho/timb
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);
  }
}
예제 #16
0
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);
}
예제 #18
0
// 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) );
}
예제 #19
0
파일: grid.hpp 프로젝트: hojonathanho/timb
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));
      }
    }
  }
}
예제 #20
0
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;
}
예제 #21
0
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;
}
예제 #23
0
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);
}
예제 #24
0
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;
}
예제 #25
0
	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];
	}
예제 #26
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;
}
예제 #27
0
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;
}
예제 #28
0
 inline void setPressure(const ScalarField& pp) {
   du.resize(pp.shape());
   p.reference(pp);
 }  
예제 #29
0
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;
}
예제 #30
0
파일: main.cpp 프로젝트: scalexm/GeoShoot
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;
}