Example #1
0
double ProceduralTexture::noise2(double x,double y)
{
	double floorx=(double)((int)x);//This is kinda a cheap way to floor a double integer.
	double floory=(double)((int)y);
	double s,t,u,v;//Integer declaration
	s=findnoise2(floorx,floory);
	t=findnoise2(floorx+1,floory);
	u=findnoise2(floorx,floory+1);//Get the surrounding pixels to calculate the transition.
	v=findnoise2(floorx+1,floory+1);
	double int1=interpolate1(s,t,x-floorx);//Interpolate between the values.
	double int2=interpolate1(u,v,x-floorx);//Here we use x-floorx, to get 1st dimension. Don't mind the x-floorx thingie, it's part of the cosine formula.
	return interpolate1(int1,int2,y-floory);//Here we use y-floory, to get the 2nd dimension.
}
void Law2_ScGeom_CapillaryPhys_Capillarity1::solver(Real suction,bool reset)
{
     
    if (!scene) cerr << "scene not defined!";
    shared_ptr<BodyContainer>& bodies = scene->bodies;
    if (dtPbased.number_of_vertices ()<1 ) triangulateData();
    if (fusionDetection && !bodiesMenisciiList.initialized) bodiesMenisciiList.prepare(scene);
    InteractionContainer::iterator ii = scene->interactions->begin();
    InteractionContainer::iterator iiEnd = scene->interactions->end();
     bool hertzInitialized = false;
       Real i=0;

      for (; ii!=iiEnd ; ++ii) {

 	i+=1;
	CapillaryPhys1* phys = dynamic_cast<CapillaryPhys1*>((*ii)->phys.get());////////////////////////////////////////////////////////////////////////////////////////////
 

        if ((*ii)->isReal() && phys-> computeBridge==true) {
            const shared_ptr<Interaction>& interaction = *ii;
            if (!hertzInitialized) {//NOTE: We are assuming that only one type is used in one simulation here
                if (CapillaryPhys1::getClassIndexStatic()==interaction->phys->getClassIndex()) hertzOn=false;
                else if (MindlinCapillaryPhys::getClassIndexStatic()==interaction->phys->getClassIndex()) hertzOn=true;
                else LOG_ERROR("The capillary law is not implemented for interactions using"<<interaction->phys->getClassName());
            }
            hertzInitialized = true;
            CapillaryPhys1* cundallContactPhysics=NULL;
            MindlinCapillaryPhys* mindlinContactPhysics=NULL;

/// contact physics depends on the contact law, that is used (either linear model or hertz model)
            if (!hertzOn) cundallContactPhysics = static_cast<CapillaryPhys1*>(interaction->phys.get());//use CapillaryPhys for linear model
            else mindlinContactPhysics = static_cast<MindlinCapillaryPhys*>(interaction->phys.get());//use MindlinCapillaryPhys for hertz model

            unsigned int id1 = interaction->getId1();
            unsigned int id2 = interaction->getId2();

/// interaction geometry search (this test is to compute capillarity only between spheres (probably a better way to do that)
            int geometryIndex1 = (*bodies)[id1]->shape->getClassIndex(); // !!!
            int geometryIndex2 = (*bodies)[id2]->shape->getClassIndex();
            if (!(geometryIndex1 == geometryIndex2)) continue;

/// definition of interacting objects (not necessarily in contact)
            ScGeom* currentContactGeometry = static_cast<ScGeom*>(interaction->geom.get());
	    
/// Interacting Grains:
// If you want to define a ratio between YADE sphere size and real sphere size
            Real alpha=1;
            Real R1 = alpha*std::max(currentContactGeometry->radius2,currentContactGeometry->radius1);
            Real R2 =alpha*std::min(currentContactGeometry->radius2,currentContactGeometry->radius1);
	  
	    shared_ptr<BodyContainer>& bodies = scene->bodies;

	    Real N=bodies->size();
            Real epsilon1,epsilon2;
 	    Real ran1= (N-id1+0.5)/(N+1);
	    Real ran2= (N-id2+0.5)/(N+1);
	    epsilon1 = epsilonMean*(2*(ran1-0.5)* disp +1);//addednow
	    epsilon2 = epsilonMean*(2*(ran2-0.5)* disp +1);
//   	    cout << epsilon1 << "separate" <<epsilon2 <<endl;
	    R1 = R1-epsilon1*R1;  
	    R2 =R2-epsilon2*R2;
	    
/// intergranular distance
            Real D = alpha*(-(currentContactGeometry->penetrationDepth))+epsilon1*R1+epsilon2*R2;
	    if ((currentContactGeometry->penetrationDepth>=0)|| D<=0 || createDistantMeniscii) { //||(scene->iter < 1) ) // a simplified way to define meniscii everywhere
                if (!hertzOn) {
                    if (fusionDetection && !cundallContactPhysics->meniscus) bodiesMenisciiList.insert((*ii));
                    cundallContactPhysics->meniscus=true;
                } else {
                    if (fusionDetection && !mindlinContactPhysics->meniscus) bodiesMenisciiList.insert((*ii));
                    mindlinContactPhysics->meniscus=true;
                }
                
            
            }
            Real Dinterpol = D/R1;
 
/// Suction (Capillary pressure):
	    if (imposePressure || (!imposePressure && totalVolumeConstant)){
	      Real Pinterpol = 0;
	      if (!hertzOn) Pinterpol = cundallContactPhysics->isBroken ? 0 : suction*R1/liquidTension;
	      else Pinterpol = mindlinContactPhysics->isBroken ? 0 : suction*R1/liquidTension;
	      if (!hertzOn) cundallContactPhysics->capillaryPressure = suction;
	      else mindlinContactPhysics->capillaryPressure = suction;
	      /// Capillary solution finder:
	      if ((Pinterpol>=0) && (hertzOn? mindlinContactPhysics->meniscus : cundallContactPhysics->meniscus)) {//FIXME: need an "else {delete}"
		MeniscusPhysicalData solution = interpolate1(dtPbased,K::Point_3(R2/R1, Pinterpol, Dinterpol), cundallContactPhysics->m, solutions, reset);
/// capillary adhesion force
		Real Finterpol = solution.force;
		Vector3r fCap = Finterpol*R1*liquidTension*currentContactGeometry->normal;
		if (!hertzOn) cundallContactPhysics->fCap = fCap;
		else mindlinContactPhysics->fCap = fCap;
/// meniscus volume
//FIXME: hardcoding numerical constants is bad practice generaly, and it probably reveals a flaw in that case (Bruno)
		Real Vinterpol = solution.volume*pow(R1,3);
		Real SInterface = solution.surface*pow(R1,2);
		if (!hertzOn) { 
		   cundallContactPhysics->vMeniscus = Vinterpol;
                    cundallContactPhysics->SInterface = SInterface;
                    if (Vinterpol > 0) cundallContactPhysics->meniscus = true;
                    else cundallContactPhysics->meniscus = false;
                } else {
                    mindlinContactPhysics->vMeniscus = Vinterpol;
                    if (Vinterpol > 0) mindlinContactPhysics->meniscus = true;
                    else mindlinContactPhysics->meniscus = false;
                }
                if (cundallContactPhysics->meniscus== false) cundallContactPhysics->SInterface=4*3.141592653589793238462643383279502884*(pow(R1,2))+4*3.141592653589793238462643383279502884*(pow(R2,2));
                if (!Vinterpol) {
                    if ((fusionDetection) || (hertzOn ? mindlinContactPhysics->isBroken : cundallContactPhysics->isBroken)) bodiesMenisciiList.remove((*ii));
/// FIXME: the following D>(...) test is wrong, should be based on penetrationDepth, and should "continue" after erasing
		    if (D>((interactionDetectionFactor-1)*(currentContactGeometry->radius2+currentContactGeometry->radius1))) scene->interactions->requestErase(interaction);
                }
/// wetting angles
                if (!hertzOn) {
                    cundallContactPhysics->Delta1 = max(solution.delta1,solution.delta2);
                    cundallContactPhysics->Delta2 = min(solution.delta1,solution.delta2);
                } else {
                    mindlinContactPhysics->Delta1 = max(solution.delta1,solution.delta2);
                    mindlinContactPhysics->Delta2 = min(solution.delta1,solution.delta2);
                }
            }
	      
	    }
	    else{
	      if (cundallContactPhysics->vMeniscus==0 and cundallContactPhysics->capillaryPressure!=0){//FIXME: test capillaryPressure consistently (!0 or >0 or >=0?!)
		Real Pinterpol = 0;
	        if (!hertzOn) Pinterpol = cundallContactPhysics->isBroken ? 0 : cundallContactPhysics->capillaryPressure*R1/liquidTension;
	        else Pinterpol = mindlinContactPhysics->isBroken ? 0 : cundallContactPhysics->capillaryPressure*R1/liquidTension;
// 	        if (!hertzOn) cundallContactPhysics->capillaryPressure = suction;
// 	        else mindlinContactPhysics->capillaryPressure = suction;
	        /// Capillary solution finder:
	        if ((Pinterpol>=0) && (hertzOn? mindlinContactPhysics->meniscus : cundallContactPhysics->meniscus)) {
		  MeniscusPhysicalData solution = interpolate1(dtPbased,K::Point_3(R2/R1, Pinterpol, Dinterpol), cundallContactPhysics->m, solutions, reset);
/// capillary adhesion force
		  Real Finterpol = solution.force;
		  Vector3r fCap = Finterpol*R1*liquidTension*currentContactGeometry->normal;
		  if (!hertzOn) cundallContactPhysics->fCap = fCap;
		  else mindlinContactPhysics->fCap = fCap;
/// meniscus volume
//FIXME: hardcoding numerical constants is bad practice generaly, and it probably reveals a flaw in that case (Bruno)
		  Real Vinterpol = solution.volume*pow(R1,3);
		  Real SInterface = solution.surface*pow(R1,2);
		  if (!hertzOn) { 
		      cundallContactPhysics->vMeniscus = Vinterpol;
                      cundallContactPhysics->SInterface = SInterface;
                      if (Vinterpol > 0) cundallContactPhysics->meniscus = true;
                      else cundallContactPhysics->meniscus = false;
                  } else {
                      mindlinContactPhysics->vMeniscus = Vinterpol;
                      if (Vinterpol > 0) mindlinContactPhysics->meniscus = true;
                      else mindlinContactPhysics->meniscus = false;
                  }
                  if (cundallContactPhysics->meniscus== false) cundallContactPhysics->SInterface=4*3.141592653589793238462643383279502884*(pow(R1,2))+4*3.141592653589793238462643383279502884*(pow(R2,2));
                  if (!Vinterpol) {
                      if ((fusionDetection) || (hertzOn ? mindlinContactPhysics->isBroken : cundallContactPhysics->isBroken)) bodiesMenisciiList.remove((*ii));
		      if (D>((interactionDetectionFactor-1)*(currentContactGeometry->radius2+currentContactGeometry->radius1))) scene->interactions->requestErase(interaction);
                  }
/// wetting angles
                  if (!hertzOn) {
                      cundallContactPhysics->Delta1 = max(solution.delta1,solution.delta2);
                      cundallContactPhysics->Delta2 = min(solution.delta1,solution.delta2);
                  } else {
                      mindlinContactPhysics->Delta1 = max(solution.delta1,solution.delta2);
                      mindlinContactPhysics->Delta2 = min(solution.delta1,solution.delta2);
                  }
	      }
	      }
 	      else{
		Real Vinterpol = 0;
		if (!hertzOn) { Vinterpol = cundallContactPhysics->vMeniscus/pow(R1,3);  
	        }
	        else Vinterpol = mindlinContactPhysics->vMeniscus;
	        /// Capillary solution finder:
	        if ((hertzOn? mindlinContactPhysics->meniscus : cundallContactPhysics->meniscus)) {
		  MeniscusPhysicalData solution = interpolate2(dtVbased,K::Point_3(R2/R1, Vinterpol, Dinterpol), cundallContactPhysics->m, solutions,reset);
/// capillary adhesion force
	          Real Finterpol = solution.force;
                  Vector3r fCap = Finterpol*R1*liquidTension*currentContactGeometry->normal;
                  if (!hertzOn) cundallContactPhysics->fCap = fCap;
                  else mindlinContactPhysics->fCap = fCap;
/// suction and interfacial area
		
                  Real Pinterpol = solution.succion*liquidTension/R1;
                  Real SInterface = solution.surface*pow(R1,2);
                  if (!hertzOn) { 
                      cundallContactPhysics->capillaryPressure = Pinterpol;
                      cundallContactPhysics->SInterface = SInterface;
                      if (Finterpol > 0) cundallContactPhysics->meniscus = true;
                      else{
		        cundallContactPhysics->vMeniscus=0;
		        cundallContactPhysics->meniscus = false;
		      }
                  } else {
                      mindlinContactPhysics->capillaryPressure = Pinterpol;
                      if (Finterpol > 0) mindlinContactPhysics->meniscus = true;
                      else {
		        cundallContactPhysics->vMeniscus=0;
		        mindlinContactPhysics->meniscus = false;
		      }
                  }
                  if (!Vinterpol) {
                      if ((fusionDetection) || (hertzOn ? mindlinContactPhysics->isBroken : cundallContactPhysics->isBroken)) bodiesMenisciiList.remove((*ii));
                      if (D>((interactionDetectionFactor-1)*(currentContactGeometry->radius2+currentContactGeometry->radius1))) scene->interactions->requestErase(interaction);
                  }
/// wetting angles
                  if (!hertzOn) {
                      cundallContactPhysics->Delta1 = max(solution.delta1,solution.delta2);
                      cundallContactPhysics->Delta2 = min(solution.delta1,solution.delta2);
                  } else {
                      mindlinContactPhysics->Delta1 = max(solution.delta1,solution.delta2);
                      mindlinContactPhysics->Delta2 = min(solution.delta1,solution.delta2);
                  }
		}
	      }
	    }
	    


///interaction is not real //If the interaction is not real, it should not be in the list
        } else if (fusionDetection) bodiesMenisciiList.remove((*ii));
      

    }
    if (fusionDetection) checkFusion();

}