← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-pkg/yade/git-trunk] Rev 3590: fix fusion detection for hertz model in capillary law

 

------------------------------------------------------------
revno: 3590
committer: Christian Jakob <jakob@xxxxxxxxxxxxxxxxxxx>
timestamp: Thu 2015-02-19 13:54:58 +0100
message:
  fix fusion detection for hertz model in capillary law
modified:
  pkg/dem/Law2_ScGeom_CapillaryPhys_Capillarity.cpp
  pkg/dem/Law2_ScGeom_CapillaryPhys_Capillarity.hpp


--
lp:yade
https://code.launchpad.net/~yade-pkg/yade/git-trunk

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-pkg/yade/git-trunk/+edit-subscription
=== modified file 'pkg/dem/Law2_ScGeom_CapillaryPhys_Capillarity.cpp'
--- pkg/dem/Law2_ScGeom_CapillaryPhys_Capillarity.cpp	2014-12-10 01:37:09 +0000
+++ pkg/dem/Law2_ScGeom_CapillaryPhys_Capillarity.cpp	2015-02-19 12:54:58 +0000
@@ -58,18 +58,25 @@
 	if (!scene) cerr << "scene not defined!";
 	if (!capillary) postLoad(*this);//when the script does not define arguments, postLoad is never called
 	shared_ptr<BodyContainer>& bodies = scene->bodies;
-	if (fusionDetection && !bodiesMenisciiList.initialized) bodiesMenisciiList.prepare(scene);
+	
+	//check for contact model once (assuming that contact model does not change)
+	if (!hertzInitialized){//NOTE: We are assuming that only one type is used in one simulation here
+		FOREACH(const shared_ptr<Interaction>& I, *scene->interactions){
+			if (I->isReal()) {
+				if (CapillaryPhys::getClassIndexStatic()==I->phys->getClassIndex()) hertzOn=false;
+				else if (MindlinCapillaryPhys::getClassIndexStatic()==I->phys->getClassIndex()) hertzOn=true;
+				else LOG_ERROR("The capillary law is not implemented for interactions using"<<I->phys->getClassName());
+				break;
+			}
+		}
+		hertzInitialized = true;
+	}
+	
+	if (fusionDetection && !bodiesMenisciiList.initialized) bodiesMenisciiList.prepare(scene,hertzOn);
 
-	bool hertzInitialized = false;
 	FOREACH(const shared_ptr<Interaction>& interaction, *scene->interactions){ // could be done in parallel ? Was tried once, but needs maybe more comparison to assert it is OK: http://www.mail-archive.com/yade-dev@xxxxxxxxxxxxxxxxxxx/msg10842.html
 		/// interaction is real
 		if (interaction->isReal()) {
-			if (!hertzInitialized) {//NOTE: We are assuming that only one type is used in one simulation here
-				if (CapillaryPhys::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;
 			CapillaryPhys* cundallContactPhysics=NULL;
 			MindlinCapillaryPhys* mindlinContactPhysics=NULL;
 
@@ -148,7 +155,7 @@
 				if (!Vinterpol) {
 					if ((fusionDetection) || (hertzOn ? mindlinContactPhysics->isBroken : cundallContactPhysics->isBroken)) bodiesMenisciiList.remove(interaction);
 					if (D>0) scene->interactions->requestErase(interaction);
-					else if (Pinterpol > 0) LOG_ERROR("No meniscus found at a contact. capillaryPressure may be too large wrt. the loaded data files.") // V=0 at a contact reveals a problem if and only if uc* > 0
+					else if ((Pinterpol > 0)) LOG_ERROR("No meniscus found at a contact. capillaryPressure may be too large wrt. the loaded data files.") // V=0 at a contact reveals a problem if and only if uc* > 0
 				}
 				/// wetting angles
 				if (!hertzOn) {
@@ -204,9 +211,10 @@
 {
 	//Reset fusion numbers
 	FOREACH(const shared_ptr<Interaction>& interaction, *scene->interactions){ // same remark for parallel loops, the most problematic part ?
-		if ( !interaction->isReal()) continue;
-		if (!hertzOn) static_cast<CapillaryPhys*>(interaction->phys.get())->fusionNumber=0;
-		else static_cast<MindlinCapillaryPhys*>(interaction->phys.get())->fusionNumber=0;
+		if ( interaction->isReal()) {
+			if (!hertzOn) static_cast<CapillaryPhys*>(interaction->phys.get())->fusionNumber=0;
+			else static_cast<MindlinCapillaryPhys*>(interaction->phys.get())->fusionNumber=0;
+		}
 	}
 
 	list< shared_ptr<Interaction> >::iterator firstMeniscus, lastMeniscus, currentMeniscus;
@@ -260,7 +268,7 @@
 					if ((angle1+angle2)*Mathr::DEG_TO_RAD > normalAngle) {
 						if (!hertzOn) {++(cundallInteractionPhysics1->fusionNumber); ++(cundallInteractionPhysics2->fusionNumber);}//count +1 if 2 meniscii are overlaping
 						else {++(mindlinInteractionPhysics1->fusionNumber); ++(mindlinInteractionPhysics2->fusionNumber);}
-					};
+					}
 				}
 			}
 		}
@@ -499,13 +507,13 @@
         return os;
 }
 
-BodiesMenisciiList::BodiesMenisciiList(Scene * scene)
+BodiesMenisciiList::BodiesMenisciiList(Scene * scene, bool hertzOn)
 {
 	initialized=false;
-	prepare(scene);
+	prepare(scene, hertzOn);
 }
 
-bool BodiesMenisciiList::prepare(Scene * scene)
+bool BodiesMenisciiList::prepare(Scene * scene, bool hertzOn)
 {
 	//cerr << "preparing bodiesInteractionsList" << endl;
 	interactionsOnBody.clear();
@@ -523,10 +531,11 @@
 	{
 		interactionsOnBody[i].clear();
 	}
-
+	
 	FOREACH(const shared_ptr<Interaction>& I, *scene->interactions){ // parallel version using Engine::ompThreads variable not accessible, this function is not one of the Engine..
                 if (I->isReal()) {
-                    if (static_cast<CapillaryPhys*>(I->phys.get())->meniscus) insert(I);
+			if (!hertzOn) {if (static_cast<CapillaryPhys*>(I->phys.get())->meniscus) insert(I);}
+			else {if (static_cast<MindlinCapillaryPhys*>(I->phys.get())->meniscus) insert(I);}
                 }
         }
 

=== modified file 'pkg/dem/Law2_ScGeom_CapillaryPhys_Capillarity.hpp'
--- pkg/dem/Law2_ScGeom_CapillaryPhys_Capillarity.hpp	2015-02-03 21:52:41 +0000
+++ pkg/dem/Law2_ScGeom_CapillaryPhys_Capillarity.hpp	2015-02-19 12:54:58 +0000
@@ -48,7 +48,7 @@
 /// R = ratio(RadiusParticle1 on RadiusParticle2). Here, 10 R values from interpolation files (yade/extra/capillaryFiles), R = 1, 1.1, 1.25, 1.5, 1.75, 2, 3, 4, 5, 10
 const int NB_R_VALUES = 10;
 
-class capillarylaw; // fait appel a la classe def plus bas
+class capillarylaw; // fait appel a la classe def plus bas //TODO: translate this in english
 class Interaction;
 
 ///This container class is used to check if meniscii overlap. Wet interactions are put in a series of lists, with one list per body.
@@ -61,8 +61,8 @@
 		
 	public:
 		BodiesMenisciiList();
-		BodiesMenisciiList(Scene*);
-		bool prepare(Scene*);
+		BodiesMenisciiList(Scene*,bool);
+		bool prepare(Scene*,bool);
 		bool insert(const shared_ptr<Interaction>&);
 		bool remove(const shared_ptr<Interaction>&);
 		list< shared_ptr<Interaction> >& operator[] (int);
@@ -70,7 +70,6 @@
 		void display();
 		void checkLengthBuffer(const shared_ptr<Interaction>&);
 		
-		
 		bool initialized;
 };
 
@@ -85,15 +84,21 @@
 		void action();
 		void postLoad(Law2_ScGeom_CapillaryPhys_Capillarity&);
 		
+		bool hertzInitialized;
+		bool hertzOn;
+		bool getHertzOn();
+		
 	YADE_CLASS_BASE_DOC_ATTRS_DEPREC_INIT_CTOR_PY(Law2_ScGeom_CapillaryPhys_Capillarity,GlobalEngine,"This law allows one to take into account capillary forces/effects between spheres coming from the presence of interparticular liquid bridges (menisci).\n\nThe control parameter is the :yref:`capillary pressure<Law2_ScGeom_CapillaryPhys_Capillarity::capillaryPressure>` (or suction) Uc = Ugas - Uliquid. Liquid bridges properties (volume V, extent over interacting grains delta1 and delta2) are computed as a result of the defined capillary pressure and of the interacting geometry (spheres radii and interparticular distance).\n\nReferences: in english [Scholtes2009b]_; more detailed, but in french [Scholtes2009d]_.\n\nThe law needs ascii files M(r=i) with i=R1/R2 to work (see https://yade-dem.org/wiki/CapillaryTriaxialTest). These ASCII files contain a set of results from the resolution of the Laplace-Young equation for different configurations of the interacting geometry, assuming a null wetting angle.\n\nIn order to allow capillary forces between distant spheres, it is necessary to enlarge the bounding boxes using :yref:`Bo1_Sphere_Aabb::aabbEnlargeFactor` and make the Ig2 define define distant interactions via :yref:`interactionDetectionFactor<Ig2_Sphere_Sphere_ScGeom::interactionDetectionFactor>`. It is also necessary to disable interactions removal by the constitutive law (:yref:`Law2<Law2_ScGeom_FrictPhys_CundallStrack::neverErase>=True`). The only combinations of laws supported are currently capillary law + :yref:`Law2_ScGeom_FrictPhys_CundallStrack` and capillary law + :yref:`Law2_ScGeom_MindlinPhys_Mindlin` (and the other variants of Hertz-Mindlin).\n\nSee CapillaryPhys-example.py for an example script.",
 	((Real,capillaryPressure,0.,,"Value of the capillary pressure Uc defined as Uc=Ugas-Uliquid"))
 	((bool,fusionDetection,false,,"If true potential menisci overlaps are checked, computing :yref:`fusionNumber<CapillaryPhys.fusionNumber>` for each capillary interaction, and reducing :yref:`fCap<CapillaryPhys.fCap>` according to :yref:`binaryFusion<Law2_ScGeom_CapillaryPhys_Capillarity.binaryFusion>`"))
 	((bool,binaryFusion,true,,"If true, capillary forces are set to zero as soon as, at least, 1 overlap (menisci fusion) is detected. Otherwise :yref:`fCap<CapillaryPhys.fCap>` = :yref:`fCap<CapillaryPhys.fCap>` / (:yref:`fusionNumber<CapillaryPhys.fusionNumber>` + 1 )"))
-	((bool,hertzOn,false,,"|yupdate| true if hertz model is used"))
 	((bool,createDistantMeniscii,false,,"Generate meniscii between distant spheres? Else only maintain the existing ones. For modeling a wetting path this flag should always be false. For a drying path it should be true for one step (initialization) then false, as in the logic of [Scholtes2009c]_"))
 	,/*deprec*/
 	((CapillaryPressure,capillaryPressure,"naming convention"))
-	,,,
+	,,/*constructor*/
+	hertzInitialized = false;
+	hertzOn = false;
+	,
 	 );
 };
 
@@ -108,7 +113,7 @@
   		~TableauD();
 };
 
-// Fonction d'ecriture de tableau, utilisee dans le constructeur pour test 
+// Fonction d'ecriture de tableau, utilisee dans le constructeur pour test //TODO: translate this in english
 class Tableau;
 std::ostream& operator<<(std::ostream& os, Tableau& T);