← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 2693: 1. Change Cell behavior as explained on the list -- trsf can be changed freely, without side-effe...

 

------------------------------------------------------------
revno: 2693
committer: Václav Šmilauer <eu@xxxxxxxx>
branch nick: yade
timestamp: Sun 2011-01-30 16:43:18 +0100
message:
  1. Change Cell behavior as explained on the list -- trsf can be changed freely, without side-effects; assigning refSize is deprecated (use new O.cell.setBox(...) function for that)
  2. SpherePack.toSimulation sets identity transformation, but rotated hSize (if requested)
  3. PeriTriaxController uses norms of hSize columns (with inverse transformaiton) as reference lengths ;; TODO (?): it should check that hSize is diagonal, otherwise it will probably behave erroneously
modified:
  core/Cell.cpp
  core/Cell.hpp
  doc/sphinx/tutorial/06-periodic-triaxial-test.py
  gui/qt4/SerializableEditor.py
  pkg/dem/PeriIsoCompressor.cpp
  py/pack/pack.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 'core/Cell.cpp'
--- core/Cell.cpp	2011-01-29 22:47:18 +0000
+++ core/Cell.cpp	2011-01-30 15:43:18 +0000
@@ -1,6 +1,8 @@
 
 #include<yade/core/Cell.hpp>
 
+CREATE_LOGGER(Cell);
+
 void Cell::integrateAndUpdate(Real dt){
 	//incremental displacement gradient
 	_trsfInc=dt*velGrad;

=== modified file 'core/Cell.hpp'
--- core/Cell.hpp	2011-01-29 22:47:18 +0000
+++ core/Cell.hpp	2011-01-30 15:43:18 +0000
@@ -60,6 +60,8 @@
 		void fillGlShearTrsfMatrix(double m[16]);
 	public:
 
+	DECLARE_LOGGER;
+
 	//! "integrate" velGrad, update cached values used by public getter.
 	void integrateAndUpdate(Real dt);
 	/*! Return point inside periodic cell, even if shear is applied */
@@ -89,16 +91,26 @@
 	// return body velocity while taking away mean field velocity (coming from velGrad) if the mean field velocity is applied on velocity
 	Vector3r bodyFluctuationVel(const Vector3r& pos, const Vector3r& vel) const { if(homoDeform==HOMO_VEL || homoDeform==HOMO_VEL_2ND) return (vel-velGrad*pos); return vel; }
 
-	Vector3r getRefSize() const { return _refSize; }
-	// change length of initial cell vectors (scale current hSize by the ratio)
-	// should be identical to: { _refSize=s; hSize=_invTrsf*hSize; for(int i=0;i<3;i++) hSize.col(i)=hSize.col(i).normalized()*_refSize[i]; /* transform back*/ hSize=trsf*hSize; integrateAndUpdate(0); }
-	void setRefSize(const Vector3r& s){ for(int i=0;i<3;i++) hSize.col(i)*=s[i]/_refSize[i]; _refSize=s; refHSize=hSize; integrateAndUpdate(0); } 
+	// get/set mechanically undeformed shape; setting resets trsf to identity
 	Matrix3r getHSize() const { return hSize; }
-	void setHSize(const Matrix3r& m){ hSize=refHSize=m; integrateAndUpdate(0);}
+	void setHSize(const Matrix3r& m){ hSize=refHSize=m; trsf=Matrix3r::Identity(); postLoad(*this); }
+	// set current transformation; has no influence on current configuration (hSize); sets display refHSize as side-effect
+	Matrix3r getTrsf() const { return trsf; }
+	void setTrsf(const Matrix3r& m){ refHSize=hSize; trsf=m; postLoad(*this); }
+	// get undeformed shape
 	Matrix3r getHSize0() const { return _invTrsf*hSize; }
-	Matrix3r getTrsf() const { return trsf; }
-	void setTrsf(const Matrix3r& m){ hSize=refHSize=m*_invTrsf*hSize; trsf=m; integrateAndUpdate(0); }
-	void resetTrsf(){ trsf=_invTrsf=Matrix3r::Identity(); } 
+	// edge lengths of the undeformed shape
+	Vector3r getRefSize() const { Matrix3r h=getHSize0(); return Vector3r(h.col(0).norm(),h.col(1).norm(),h.col(2).norm()); }
+	// temporary, will be removed in favor of more descriptive setBox(...)
+	void setRefSize(const Vector3r& s){
+		// if refSize is set to the current size and the cell is a box (used in older scripts), say it is not necessary
+		if(s==_size && hSize==hSize.diagonal().asDiagonal()){ LOG_WARN("Setting O.cell.refSize=O.cell.size is useless, O.trsf=Matrix3.Identity is enough now."); }
+		else {LOG_WARN("Setting Cell.refSize is deprecated, use Cell.setBox(...) instead.");}
+		setBox(s); postLoad(*this);
+	} 
+	// set box shape of the cell
+	void setBox(const Vector3r& size){ setHSize(size.asDiagonal()); postLoad(*this); }
+	void setBox3(const Real& s0, const Real& s1, const Real& s2){ setBox(Vector3r(s0,s1,s2)); }
 
 	// return current cell volume
 	Real getVolume() const {return hSize.determinant();}
@@ -112,26 +124,27 @@
 	YADE_CLASS_BASE_DOC_ATTRS_DEPREC_INIT_CTOR_PY(Cell,Serializable,"Parameters of periodic boundary conditions. Only applies if O.isPeriodic==True.",
 		/* overridden below to be modified by getters/setters because of intended side-effects */
 		((Matrix3r,trsf,Matrix3r::Identity(),,"[overridden]")) //"Current transformation matrix of the cell, which defines how far is the current cell geometry (:yref:`hSize<Cell.hSize>`) from the reference configuration. Changing trsf will not change :yref:`hSize<Cell.hSize>`, it serves only as accumulator for transformations applied via :yref:`velGrad<Cell.velGrad>`."))
-		((Matrix3r,refHSize,Matrix3r::Identity(),,"Reference cell configuration, only used with :yref:`OpenGLRenderer.dispScale`"))
-		((Matrix3r,hSize,Matrix3r::Identity(),,"[overridden]"))
+		((Matrix3r,refHSize,Matrix3r::Identity(),,"Reference cell configuration, only used with :yref:`OpenGLRenderer.dispScale`. Updated automatically when :yref:`hSize<Cell.hSize>` or :yref:`trsf<Cell.trsf>` is assigned directly; also modified by :yref:`yade.utils.setRefSe3` (called e.g. by the :gui:`Reference` button in the UI)."))
+		((Matrix3r,hSize,Matrix3r::Identity(),,"[overridden below]"))
 		/* normal attributes */
-		((Matrix3r,velGrad,Matrix3r::Zero(),,"Velocity gradient of the transformation; used in :yref:`NewtonIntegrator`."))
+		((Matrix3r,velGrad,Matrix3r::Zero(),,"Velocity gradient of the transformation; used in :yref:`NewtonIntegrator`. Values of :yref:`velGrad<Cell.velGrad>` accumulate in :yref:`trsf<Cell.trsf>` at every step."))
 		((Matrix3r,prevVelGrad,Matrix3r::Zero(),Attr::readonly,"Velocity gradient in the previous step."))
 		((int,homoDeform,3,Attr::triggerPostLoad,"Deform (:yref:`velGrad<Cell.velGrad>`) the cell homothetically, by adjusting positions or velocities of particles. The values have the following meaning: 0: no homothetic deformation, 1: set absolute particle positions directly (when ``velGrad`` is non-zero), but without changing their velocity, 2: adjust particle velocity (only when ``velGrad`` changed) with Δv_i=Δ ∇v x_i. 3: as 2, but include a 2nd order term in addition -- the derivative of 1 (convective term in the velocity update).")),
 		/*deprec*/ ((Hsize,hSize,"conform to Yade's names convention.")),
 		/*init*/ ,
-		/*ctor*/ _refSize=Vector3r(1,1,1); _invTrsf=Matrix3r::Identity(); integrateAndUpdate(0),
+		/*ctor*/ _invTrsf=Matrix3r::Identity(); integrateAndUpdate(0),
 		/*py*/
 		// override some attributes above
-		.add_property("refSize",&Cell::getRefSize,&Cell::setRefSize,"Reference size of the cell (lengths of initial cell vectors, i.e. columns of :yref:`hSize<Cell.hSize>`). Modifying this value will scale cell vectors such to have desired length.")
-		.add_property("hSize",&Cell::getHSize,&Cell::setHSize,"Base cell vectors (columns of the matrix), updated at every step from :yref:`velGrad<Cell.velGrad>` (:yref:`trsf<Cell.trsf>` accumulates applied :yref:`velGrad<Cell.velGrad>` transformations).")
-		.add_property("trsf",&Cell::getTrsf,&Cell::setTrsf,"Current transformation matrix of the cell.")
+		.add_property("hSize",&Cell::getHSize,&Cell::setHSize,"Base cell vectors (columns of the matrix), updated at every step from :yref:`velGrad<Cell.velGrad>` (:yref:`trsf<Cell.trsf>` accumulates applied :yref:`velGrad<Cell.velGrad>` transformations). Setting *hSize* directly results in :yref:`trsf<Cell.trsf>` being set to identity.")
+		.add_property("refSize",&Cell::getRefSize,&Cell::setRefSize,"Reference size of the cell (lengths of initial cell vectors, i.e. column norms of :yref:`hSize<Cell.hSize>`).\n\n.. note:: Modifying this value is deprecated, use :yref:`setBox<Cell.setBox>` instead.\n\n")
+		.add_property("trsf",&Cell::getTrsf,&Cell::setTrsf,"Current transformation matrix of the cell with regards to the initial configuration.")
 		// useful properties
-		.add_property("hSize0",&Cell::getHSize0,"Value of untransformed hSize, with respect to current :yref:`trsf<Cell.trsf>` (computed as :yref:`trsf<Cell.invTrsf>`⁻¹ × :yref:`hSize<Cell.hSize>`.")
+		.add_property("hSize0",&Cell::getHSize0,"Value of untransformed hSize, with respect to current :yref:`trsf<Cell.trsf>` (computed as :yref:`trsf<Cell.trsf>`⁻¹ × :yref:`hSize<Cell.hSize>`.")
 		.def_readonly("size",&Cell::getSize_copy,"Current size of the cell, i.e. lengths of the 3 cell lateral vectors contained in :yref:`Cell.hSize` columns. Updated automatically at every step.")
 		.add_property("volume",&Cell::getVolume,"Current volume of the cell.")
-		// setting trsf value without the side effects
-		.def("resetTrsf",&Cell::resetTrsf,"Set :yref:`trsf<Cell.trsf>`=Identity without the side effects of direct assignment. There is no impact on :yref:`Cell.hSize`.")
+		// functions
+		.def("setBox",&Cell::setBox,"Set :yref:`Cell` shape to be rectangular, with dimensions along axes specified by given argument. Shorthand for assigning diagonal matrix with respective entries to :yref:`hSize<Cell.hSize>`.")
+		.def("setBox",&Cell::setBox3,"Set :yref:`Cell` shape to be rectangular, with dimensions along $x$, $y$, $z$ specified by arguments. Shorthand for assigning diagonal matrix with the respective entries to :yref:`hSize<Cell.hSize>`.")
 		// debugging only
 		.def("wrap",&Cell::wrapShearedPt_py,"Transform an arbitrary point into a point in the reference cell")
 		.def("unshearPt",&Cell::unshearPt,"Apply inverse shear on the point (removes skew+rot of the cell)")

=== modified file 'doc/sphinx/tutorial/06-periodic-triaxial-test.py'
--- doc/sphinx/tutorial/06-periodic-triaxial-test.py	2011-01-21 11:28:22 +0000
+++ doc/sphinx/tutorial/06-periodic-triaxial-test.py	2011-01-30 15:43:18 +0000
@@ -91,7 +91,6 @@
 
 def compactionFinished():
 	# set the current cell configuration to be the reference one
-	O.cell.refSize=O.cell.size
 	O.cell.trsf=Matrix3.Identity
 	# change control type: keep constant confinement in x,y, 20% compression in z
 	triax.goal=(sigmaIso,sigmaIso,-.3)

=== modified file 'gui/qt4/SerializableEditor.py'
--- gui/qt4/SerializableEditor.py	2011-01-09 16:34:50 +0000
+++ gui/qt4/SerializableEditor.py	2011-01-30 15:43:18 +0000
@@ -14,6 +14,15 @@
 
 seqSerializableShowType=True # show type headings in serializable sequences (takes vertical space, but makes the type hyperlinked)
 
+# BUG: cursor is moved to the beginnign of the input field even if it has focus
+#
+# checking for focus seems to return True always and cursor is never moved
+#
+# the 'True or' part effectively disables the condition (so that the cursor is moved always), but it might be fixed in the future somehow
+#
+# if True or w.hasFocus(): w.home(False)
+#
+#
 
 def makeWrapperHref(text,className,attr=None,static=False):
 	"""Create clickable HTML hyperlink to a Yade class or its attribute.
@@ -108,7 +117,9 @@
 		self.textEdited.connect(self.isHot)
 		self.selectionChanged.connect(self.isHot)
 		self.editingFinished.connect(self.update)
-	def refresh(self): self.setText(str(self.getter())); self.home(False)
+	def refresh(self):
+		self.setText(str(self.getter()));
+		if True or not self.hasFocus(): self.home(False)
 	def update(self):
 		try: self.trySetter(float(self.text()))
 		except ValueError: self.refresh()
@@ -130,7 +141,8 @@
 	def refresh(self):
 		val=self.getter(); axis,angle=val.toAxisAngle()
 		for i in (0,1,2,4):
-			w=self.grid.itemAt(i).widget(); w.setText(str(axis[i] if i<3 else angle)); w.home(False)
+			w=self.grid.itemAt(i).widget(); w.setText(str(axis[i] if i<3 else angle));
+			if True or not w.hasFocus(): w.home(False)
 	def update(self):
 		try:
 			x=[float((self.grid.itemAt(i).widget().text())) for i in (0,1,2,4)]
@@ -157,9 +169,11 @@
 	def refresh(self):
 		pos,ori=self.getter(); axis,angle=ori.toAxisAngle()
 		for i in (0,1,2,4):
-			w=self.grid.itemAtPosition(1,i).widget(); w.setText(str(axis[i] if i<3 else angle)); w.home(False)
+			w=self.grid.itemAtPosition(1,i).widget(); w.setText(str(axis[i] if i<3 else angle));
+			if True or not w.hasFocus(): w.home(False)
 		for i in (0,1,2):
-			w=self.grid.itemAtPosition(0,i).widget(); w.setText(str(pos[i])); w.home(False)
+			w=self.grid.itemAtPosition(0,i).widget(); w.setText(str(pos[i]));
+			if True or not w.hasFocus(): w.home(False)
 	def update(self):
 		try:
 			q=[float((self.grid.itemAtPosition(1,i).widget().text())) for i in (0,1,2,4)]
@@ -190,7 +204,7 @@
 		for row,col in itertools.product(range(self.rows),range(self.cols)):
 			w=self.grid.itemAtPosition(row,col).widget()
 			w.setText(str(val[self.idxConverter(row,col)]))
-			w.home(False) # make the left-most part visible, if the text is wider than the widget
+			if True or not w.hasFocus: w.home(False) # make the left-most part visible, if the text is wider than the widget
 	def update(self):
 		try:
 			val=self.getter()

=== modified file 'pkg/dem/PeriIsoCompressor.cpp'
--- pkg/dem/PeriIsoCompressor.cpp	2011-01-29 22:47:18 +0000
+++ pkg/dem/PeriIsoCompressor.cpp	2011-01-30 15:43:18 +0000
@@ -144,7 +144,7 @@
 	//FIXME : this is wrong I think (almost sure, B.)
 	Vector3r cellArea=Vector3r(cellSize[1]*cellSize[2],cellSize[0]*cellSize[2],cellSize[0]*cellSize[1]);
 	// initial updates
-	const Vector3r& refSize(scene->cell->getRefSize());
+	const Vector3r refSize=scene->cell->getRefSize();
 	if (maxBodySpan[0]<=0){
 		FOREACH(const shared_ptr<Body>& b,*scene->bodies){
 			if(!b || !b->bound) continue;

=== modified file 'py/pack/pack.py'
--- py/pack/pack.py	2011-01-20 14:55:15 +0000
+++ py/pack/pack.py	2011-01-30 15:43:18 +0000
@@ -73,14 +73,19 @@
 	>>> sp.toSimulation(rot=Quaternion((0,0,1),pi/4),color=(0,0,1))
 	[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
 
-Periodic properties are transferred to the simulation correctly:
+Periodic properties are transferred to the simulation correctly, including rotation:
 
 	>>> O.periodic
 	True
 	>>> O.cell.refSize
 	Vector3(5,5,5)
+	>>> O.cell.hSize
+	Matrix3(3.53553,-3.53553,0, 3.53553,3.53553,0, 0,0,5)
+
+The current state (even if rotated) is taken as mechanically undeformed, i.e. with identity transformation:
+
 	>>> O.cell.trsf
-	Matrix3(0.707107,-0.707107,0, 0.707107,0.707107,0, 0,0,1)
+	Matrix3(1,0,0, 0,1,0, 0,0,1)
 
 :param Quaternion/Matrix3 rot: rotation of the packing, which will be applied on spheres and will be used to set :yref:`Cell.trsf` as well.
 :param **kw: passed to :yref:`yade.utils.sphere`
@@ -90,8 +95,8 @@
 	assert(isinstance(rot,Matrix3))
 	if self.cellSize!=Vector3.Zero:
 		O.periodic=True
-		O.cell.trsf=rot
-		O.cell.refSize=self.cellSize
+		O.cell.hSize=rot*Matrix3(self.cellSize[0],0,0, 0,self.cellSize[0],0, 0,0,self.cellSize[1])
+		O.cell.trsf=Matrix3.Identity
 	if not self.hasClumps():
 		return O.bodies.append([utils.sphere(rot*c,r,**kw) for c,r in self])
 	else:


Follow ups