yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #11847
[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);