← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 2632: 1. Add some data so that Hertz-Mindlin will work with L3Geom

 

------------------------------------------------------------
revno: 2632
committer: Václav Šmilauer <eu@xxxxxxxx>
branch nick: yade
timestamp: Sun 2011-01-02 11:12:16 +0100
message:
  1. Add some data so that Hertz-Mindlin will work with L3Geom
  2. Automatically compute "mass" of cell in PeriTriaxController, if not setFocus
  3. Fix auto-plotting of energies in case the simulation is reloaded
  4. Fix middle-click on attributes in inspector
modified:
  SConstruct
  gui/qt4/SerializableEditor.py
  pkg/dem/HertzMindlin.cpp
  pkg/dem/HertzMindlin.hpp
  pkg/dem/PeriIsoCompressor.cpp
  pkg/dem/PeriIsoCompressor.hpp
  py/plot.py


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

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription
=== modified file 'SConstruct'
--- SConstruct	2010-12-13 12:11:43 +0000
+++ SConstruct	2011-01-02 10:12:16 +0000
@@ -165,7 +165,7 @@
 if not env.has_key('realVersion') or not env['realVersion']: env['realVersion']=yadeSCons.getRealVersion() or 'unknown' # unknown if nothing returned
 if not env.has_key('version'): env['version']=env['realVersion']
 
-env['SUFFIX']='-'+env['version']+env['variant']
+env['SUFFIX']=('-'+env['version'] if len(env['version'])>0 else '')+env['variant']
 env['SUFFIX_DBG']=env['SUFFIX']+('' if not env['debug'] else '/dbg')
 env['LIBDIR']='$PREFIX/lib/yade$SUFFIX_DBG'
 print "Yade version is `%s' (%s), installed files will be suffixed with `%s'."%(env['version'],env['realVersion'],env['SUFFIX'])

=== modified file 'gui/qt4/SerializableEditor.py'
--- gui/qt4/SerializableEditor.py	2010-12-21 22:50:34 +0000
+++ gui/qt4/SerializableEditor.py	2011-01-02 10:12:16 +0000
@@ -269,7 +269,7 @@
 		if tooltip or path: self.setToolTip(('<b>'+path+'</b><br>' if self.path else '')+(tooltip if tooltip else ''))
 		self.linkActivated.connect(yade.qt.openUrl)
 	def mousePressEvent(self,event):
-		if event.button()!=Qt.MiddleButton:
+		if event.button()!=Qt.MidButton:
 			event.ignore(); return
 		# middle button clicked, paste pasteText to clipboard
 		cb=QApplication.clipboard()

=== modified file 'pkg/dem/HertzMindlin.cpp'
--- pkg/dem/HertzMindlin.cpp	2010-12-31 14:35:21 +0000
+++ pkg/dem/HertzMindlin.cpp	2011-01-02 10:12:16 +0000
@@ -46,10 +46,10 @@
 
 
 	/* from interaction geometry */
-	ScGeom* scg = YADE_CAST<ScGeom*>(interaction->geom.get());
-	Real Da = scg->radius1;
-	Real Db = scg->radius2;
-	Vector3r normal=scg->normal;
+	GenericSpheresContact* scg = YADE_CAST<GenericSpheresContact*>(interaction->geom.get());		
+	Real Da = scg->refR1; 
+	Real Db = scg->refR2; 
+	Vector3r normal=scg->normal; 
 
 
 	/* calculate stiffness coefficients */

=== modified file 'pkg/dem/HertzMindlin.hpp'
--- pkg/dem/HertzMindlin.hpp	2010-12-31 14:35:21 +0000
+++ pkg/dem/HertzMindlin.hpp	2011-01-02 10:12:16 +0000
@@ -44,6 +44,10 @@
 			((Real,betan,0.0,,"Fraction of the viscous damping coefficient (normal direction) equal to $\\frac{c_{n}}{C_{n,crit}}$."))
 			((Real,betas,0.0,,"Fraction of the viscous damping coefficient (shear direction) equal to $\\frac{c_{s}}{C_{s,crit}}$."))
 
+			// temporary
+			((Vector3r,prevU,Vector3r::Zero(),,"Previous local displacement; only used with :yref:`Law2_L3Geom_FrictPhys_HertzMindlin`."))
+			((Vector2r,Fs,Vector2r::Zero(),,"Shear force in local axes (computed incrementally)"))
+
 			//((Real,shearEnergy,0.0,,"Shear elastic potential energy"))
 			//((Real,frictionDissipation,0.0,,"Energy dissipation due to sliding"))
 			//((Real,normDampDissip,0.0,,"Energy dissipation due to sliding"))

=== modified file 'pkg/dem/PeriIsoCompressor.cpp'
--- pkg/dem/PeriIsoCompressor.cpp	2010-12-06 11:54:38 +0000
+++ pkg/dem/PeriIsoCompressor.cpp	2011-01-02 10:12:16 +0000
@@ -179,6 +179,12 @@
 	bool doUpdate((scene->iter%globUpdate)==0);
 	if(doUpdate || min(stiff[0],min(stiff[1],stiff[2])) <=0 || dynCell){ strainStressStiffUpdate(); }
 
+	// set mass to be sum of masses, if not set by the user
+	if(dynCell && isnan(mass)){
+		mass=0; FOREACH(const shared_ptr<Body>& b, *scene->bodies){ if(b && b->state) mass+=b->state->mass; }
+		LOG_INFO("Setting cell mass to "<<mass<<" automatically.");
+	}
+
 	bool allOk=true;
 	// apply condition along each axis separately (stress or strain)
 	assert(scene->dt>0.);
@@ -242,7 +248,7 @@
 	//Update energy input
 	Real dW=(scene->cell->velGrad*stressTensor).trace()*scene->dt*scene->cell->Hsize.determinant();
 	externalWork+=dW;
-	if(scene->trackEnergy) scene->energy->add(dW,"velGradWork",velGradWorkIx,/*non-incremental*/false);
+	if(scene->trackEnergy) scene->energy->add(-dW,"velGradWork",velGradWorkIx,/*non-incremental*/false);
 	prevGrow = strainRate;
 
 	if(allOk){

=== modified file 'pkg/dem/PeriIsoCompressor.hpp'
--- pkg/dem/PeriIsoCompressor.hpp	2010-12-07 15:59:37 +0000
+++ pkg/dem/PeriIsoCompressor.hpp	2011-01-02 10:12:16 +0000
@@ -48,7 +48,7 @@
 		void strainStressStiffUpdate();
 	YADE_CLASS_BASE_DOC_ATTRS(PeriTriaxController,BoundaryController,"Engine for independently controlling stress or strain in periodic simulations.\n\n``strainStress`` contains absolute values for the controlled quantity, and ``stressMask`` determines meaning of those values (0 for strain, 1 for stress): e.g. ``( 1<<0 | 1<<2 ) = 1 | 4 = 5`` means that ``strainStress[0]`` and ``strainStress[2]`` are stress values, and ``strainStress[1]`` is strain. \n\nSee scripts/test/periodic-triax.py for a simple example.",
 		((bool,reversedForces,false,,"For broken constitutive laws, normalForce and shearForce on interactions are in the reverse sense. see `bugreport <https://bugs.launchpad.net/yade/+bug/493102>`_"))
-		((bool,dynCell,false,,"Imposed stress can be controlled using the packing stiffness or by applying the laws of dynamic (dynCell=true). Don't forget to assign a mass to the cell (PeriTriaxController->mass)."))
+		((bool,dynCell,false,,"Imposed stress can be controlled using the packing stiffness or by applying the laws of dynamic (dynCell=true). Don't forget to assign a :yref:`mass<PeriTriaxController.mass>` to the cell."))
 		((Vector3r,goal,Vector3r::Zero(),,"Desired stress or strain values (depending on stressMask), strains defined as ``strain(i)=log(Fii)``.\n\n.. warning:: Strains are relative to the :yref:`O.cell.refSize<Cell.refSize>` (reference cell size), not the current one (e.g. at the moment when the new strain value is set)."))
 		((int,stressMask,((void)"all strains",0),,"mask determining strain/stress (0/1) meaning for goal components"))
 		((Vector3r,maxStrainRate,Vector3r(1,1,1),,"Maximum strain rate of the periodic cell."))
@@ -66,7 +66,7 @@
 		((Vector3r,stiff,Vector3r::Zero(),,"average stiffness (only every globUpdate steps recomputed from interactions) |yupdate|"))
 		((Real,currUnbalanced,NaN,,"current unbalanced force (updated every globUpdate) |yupdate|"))
 		((Vector3r,prevGrow,Vector3r::Zero(),,"previous cell grow"))
-		((Real,mass,NaN,,"mass of the cell (user set)"))
+		((Real,mass,NaN,,"mass of the cell (user set); if not set and :yref:`dynCell<PeriTriaxController.dynCell>` is used, it will be computed as sum of masses of all particles."))
 		((Real,externalWork,0,,"Work input from boundary controller."))
 		((int,velGradWorkIx,-1,(Attr::hidden|Attr::noSave),"Index for work done by velocity gradient, if tracking energy"))
 	);

=== modified file 'py/plot.py'
--- py/plot.py	2010-12-26 15:42:43 +0000
+++ py/plot.py	2011-01-02 10:12:16 +0000
@@ -194,6 +194,8 @@
 				print 'yade.plot: creating fake plot, since there are no y-data yet'
 				line,=pylab.plot([nan],[nan])
 				currLineRefs.append(LineRef(line,None,[nan],[nan]))
+			# set different color series for y1 and y2 so that they are recognizable
+			pylab.rcParams['axes.color_cycle']='b,g,r,c,m,y,k' if not isY1 else 'm,y,k,b,g,r,c'
 			for d in ySpecs2:
 				yNames.add(d)
 				line,=pylab.plot(data[pStrip],data[d[0]],d[1],label=xlateLabel(d[0]))
@@ -215,7 +217,6 @@
 				pylab.xlabel(xlateLabel(pStrip) if (p not in xylabels or not xylabels[p][0]) else xylabels[p][0])
 				## should be done for y2 as well, but in that case the 10^.. label goes to y1 axis (bug in matplotlib, present in versions .99--1.0.5, and possibly beyond)
 			else:
-				pylab.rcParams['lines.color']=origLinesColor
 				pylab.ylabel((', '.join([xlateLabel(_p[0]) for _p in ySpecs2])) if (p not in xylabels or len(xylabels[p])<3 or not xylabels[p][2]) else xylabels[p][2])
 			# if there are callable ySpecs, save them inside the axes object, so that the live updater can use those
 			if yNameFuncs:
@@ -226,8 +227,6 @@
 			pylab.axvline(linewidth=axesWd,color='k')
 		# create y2 lines, if any
 		if len(plots_p_y2)>0:
-			# try to move in the color palette a little further (magenta is 5th): r,g,b,c,m,y,k
-			origLinesColor=pylab.rcParams['lines.color']; pylab.rcParams['lines.color']='m'
 			pylab.twinx() # create the y2 axis
 			createLines(pStrip,plots_p_y2,isY1=False,y2Exists=True)
 		if 'title' in O.tags.keys(): pylab.title(O.tags['title'])
@@ -239,11 +238,12 @@
 	liveTimeStamp=timestamp
 	while True:
 		if not live or liveTimeStamp!=timestamp: return
-		figs,axes=set(),set()
+		figs,axes,linesData=set(),set(),set()
 		for l in currLineRefs:
 			l.update()
 			figs.add(l.line.get_figure())
 			axes.add(l.line.get_axes())
+			linesData.add(id(l.ydata))
 		# find callables in y specifiers, create new lines if necessary
 		for ax in axes:
 			if not hasattr(ax,'yadeYFuncs') or not ax.yadeYFuncs: continue # not defined of empty
@@ -253,13 +253,14 @@
 			news=yy-ax.yadeYNames
 			if not news: continue
 			for new in news:
+				ax.yadeYNames.add(new)
+				if new in data.keys() and id(data[new]) in linesData: continue # do not add when reloaded and the old lines are already there
 				print 'yade.plot: creating new line for',new
 				if not new in data.keys(): data[new]=[] # create data entry if necessary
 				line,=ax.plot(data[ax.yadeXName],data[new],label=xlateLabel(new)) # no line specifier
 				scatterPt=(0 if len(data[ax.yadeXName])==0 and not math.isnan(data[ax.yadeXName]) else data[ax.yadeXName][current]),(0 if len(data[new])==0 and not math.isnan(data[new][current]) else data[new][current])
 				scatter=ax.scatter(scatterPt[0],scatterPt[1],color=line.get_color())
 				currLineRefs.append(LineRef(line,scatter,data[ax.yadeXName],data[new]))
-				ax.yadeYNames.add(new)
 				ax.set_ylabel(ax.get_ylabel()+(', ' if ax.get_ylabel() else '')+xlateLabel(new))
 			# it is possible that the legend has not yet been created
 			l=ax.legend(loc=ax.yadeLabelLoc)
@@ -277,7 +278,7 @@
 		time.sleep(liveInterval)
 	
 
-def plot(noShow=False,subPlots=False):
+def plot(noShow=False,subPlots=True):
 	"""Do the actual plot, which is either shown on screen (and nothing is returned: if *noShow* is ``False``) or, if *noShow* is ``True``, returned as matplotlib's Figure object or list of them.
 	
 	You can use