← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 2621: 1. Make middle-click paste path to variable in the ui

 

------------------------------------------------------------
revno: 2621
committer: Václav Šmilauer <eu@xxxxxxxx>
branch nick: yade
timestamp: Tue 2010-12-21 16:31:40 +0100
message:
  1. Make middle-click paste path to variable in the ui
  2. Clean up newton integrator; aspherical integration not called for things with 0 in inertia to avoid nans; this also fixed the problem of inverted normal with Wall
modified:
  gui/qt4/Inspector.py
  gui/qt4/SerializableEditor.py
  gui/qt4/__init__.py
  pkg/dem/L3Geom.cpp
  pkg/dem/NewtonIntegrator.cpp
  pkg/dem/NewtonIntegrator.hpp


--
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 'gui/qt4/Inspector.py'
--- gui/qt4/Inspector.py	2010-12-01 11:09:53 +0000
+++ gui/qt4/Inspector.py	2010-12-21 15:31:40 +0000
@@ -56,7 +56,7 @@
 		typeMap={'Sphere':u'⚫','Facet':u'△','Wall':u'┃','Box':u'⎕','Cylinder':u'⌭','ChainedCylinder':u'☡','Clump':u'☍'}
 		ret+=typeMap.get(b.shape.__class__.__name__,u'ï¹–')
 	if not b.dynamic: ret+=u'âš“'
-	elif b.state.blockedDOFs!=[]: ret+=u'⎈'
+	elif b.state.blockedDOFs: ret+=u'⎈'
 	return ret
 
 def getBodyIdFromLabel(label):

=== modified file 'gui/qt4/SerializableEditor.py'
--- gui/qt4/SerializableEditor.py	2010-12-21 12:19:50 +0000
+++ gui/qt4/SerializableEditor.py	2010-12-21 15:31:40 +0000
@@ -260,6 +260,22 @@
 _fundamentalEditorMap={bool:AttrEditor_Bool,str:AttrEditor_Str,int:AttrEditor_Int,float:AttrEditor_Float,Quaternion:AttrEditor_Quaternion,Vector2:AttrEditor_Vector2,Vector3:AttrEditor_Vector3,Vector6:AttrEditor_Vector6,Matrix3:AttrEditor_Matrix3,Vector6i:AttrEditor_Vector6i,Vector3i:AttrEditor_Vector3i,Vector2i:AttrEditor_Vector2i,Se3FakeType:AttrEditor_Se3}
 _fundamentalInitValues={bool:True,str:'',int:0,float:0.0,Quaternion:Quaternion.Identity,Vector3:Vector3.Zero,Matrix3:Matrix3.Zero,Vector6:Vector6.Zero,Vector6i:Vector6i.Zero,Vector3i:Vector3i.Zero,Vector2i:Vector2i.Zero,Vector2:Vector2.Zero,Se3FakeType:(Vector3.Zero,Quaternion.Identity)}
 
+class SerQLabel(QLabel):
+	def __init__(self,parent,label,tooltip,path):
+		QLabel.__init__(self,parent)
+		self.path=path
+		self.setText(label)
+		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:
+			event.ignore(); return
+		# middle button clicked, paste pasteText to clipboard
+		cb=QApplication.clipboard()
+		cb.setText(self.path,mode=QClipboard.Clipboard)
+		cb.setText(self.path,mode=QClipboard.Selection) # X11 global selection buffer
+		event.accept()
+
 class SerializableEditor(QFrame):
 	"Class displaying and modifying serializable attributes of a yade object."
 	import collections
@@ -273,7 +289,7 @@
 		"Construct window, *ser* is the object we want to show."
 		QtGui.QFrame.__init__(self,parent)
 		self.ser=ser
-		self.path=(ser.label if hasattr(ser,'label') else path)
+		self.path=(ser.label if (hasattr(ser,'label') and ser.label) else path)
 		self.showType=showType
 		self.hot=False
 		self.entries=[]
@@ -391,13 +407,17 @@
 		grid.setVerticalSpacing(0)
 		grid.setLabelAlignment(Qt.AlignRight)
 		if self.showType:
-			lab=QLabel(makeSerializableLabel(self.ser,addr=True,href=True))
+			#lab=QLabel(makeSerializableLabel(self.ser,addr=True,href=True))
+			#lab.setToolTip(('<b>'+self.path+'</b><br>' if self.path else '')+self.getDocstring())
+			lab=SerQLabel(self,makeSerializableLabel(self.ser,addr=True,href=True),tooltip=self.getDocstring(),path=self.path)
 			lab.setFrameShape(QFrame.Box); lab.setFrameShadow(QFrame.Sunken); lab.setLineWidth(2); lab.setAlignment(Qt.AlignHCenter); lab.linkActivated.connect(yade.qt.openUrl)
-			lab.setToolTip(('<b>'+self.path+'</b><br>' if self.path else '')+self.getDocstring())
 			grid.setWidget(0,QFormLayout.SpanningRole,lab)
 		for entry in self.entries:
 			entry.widget=self.mkWidget(entry)
-			label=QLabel(self); label.setText(serializableHref(self.ser,entry.name)); label.setToolTip(('<b>'+self.path+'.'+entry.name+'</b><br>' if self.path else '')+self.getDocstring(entry.name)); label.linkActivated.connect(yade.qt.openUrl)
+			objPath=(self.path+'.'+entry.name) if self.path else None
+			label=SerQLabel(self,serializableHref(self.ser,entry.name),tooltip=self.getDocstring(entry.name),path=objPath)
+			#label=SerAttrQLabel(self,serializableHref(self.ser,entry.name),tooltip=('<b>'+self.path+'.'+entry.name+'</b><br>' if self.path else '')+self.getDocstring(entry.name),
+			#label=QLabel(self); label.setText(); label.setToolTip(; label.linkActivated.connect(yade.qt.openUrl)
 			grid.addRow(label,entry.widget if entry.widget else QLabel('<i>unhandled type</i>'))
 		self.setLayout(grid)
 		self.refreshEvent()
@@ -452,6 +472,7 @@
 		self.refreshTimer=QTimer(self)
 		self.refreshTimer.timeout.connect(self.refreshEvent)
 		self.refreshTimer.start(1000) # 1s should be enough
+		#print 'SeqSerializable path is',self.path
 	def comboIndexSlot(self,ix): # different seq item selected
 		currSeq=self.getter();
 		if len(currSeq)==0: ix=-1
@@ -461,7 +482,7 @@
 		self.combo.setEnabled(ix>=0)
 		if ix>=0:
 			ser=currSeq[ix]
-			self.seqEdit=SerializableEditor(ser,parent=self,showType=seqSerializableShowType,path=(self.path+'['+str(ix)+']' if self.path else None))
+			self.seqEdit=SerializableEditor(ser,parent=self,showType=seqSerializableShowType,path=(self.path+'['+str(ix)+']') if self.path else None)
 			self.scroll.setWidget(self.seqEdit)
 			if self.shrink:
 				self.sizeHint=lambda: QSize(100,1000)

=== modified file 'gui/qt4/__init__.py'
--- gui/qt4/__init__.py	2010-12-05 17:10:06 +0000
+++ gui/qt4/__init__.py	2010-12-21 15:31:40 +0000
@@ -130,7 +130,8 @@
 				v=View(); v.center()
 	def displayComboSlot(self,dispStr):
 		ser=(self.renderer if dispStr=='OpenGLRenderer' else eval(str(dispStr)+'()'))
-		se=SerializableEditor(ser,parent=self.displayArea,ignoredAttrs=set(['label']),showType=True)
+		path='yade.qt.Renderer()' if dispStr=='OpenGLRenderer' else dispStr
+		se=SerializableEditor(ser,parent=self.displayArea,ignoredAttrs=set(['label']),showType=True,path=path)
 		self.displayArea.setWidget(se)
 	def loadSlot(self):
 		f=QFileDialog.getOpenFileName(self,'Load simulation','','Yade simulations (*.xml *.xml.bz2 *.xml.gz *.yade *.yade.gz *.yade.bz2);; *.*')

=== modified file 'pkg/dem/L3Geom.cpp'
--- pkg/dem/L3Geom.cpp	2010-12-11 23:01:30 +0000
+++ pkg/dem/L3Geom.cpp	2010-12-21 15:31:40 +0000
@@ -241,7 +241,6 @@
 			Vector3r u0slip=(1-ratio)*Vector3r(/*no slip in the normal sense*/0,geom->relU()[1],geom->relU()[2]);
 			geom->u0+=u0slip; // increment plastic displacement
 			Fs*=ratio; // decrement shear force value;
-			//cerr<<"SLIP: Fs="<<Fs<<", ratio="<<ratio<<", u0slip="<<u0slip<<", localF="<<localF<<endl;
 			if(unlikely(scene->trackEnergy)){ Real dissip=Fs.norm()*u0slip.norm(); if(dissip>0) scene->energy->add(dissip,"plastDissip",plastDissipIx,/*reset*/false); }
 		}
 	}

=== modified file 'pkg/dem/NewtonIntegrator.cpp'
--- pkg/dem/NewtonIntegrator.cpp	2010-12-21 12:19:50 +0000
+++ pkg/dem/NewtonIntegrator.cpp	2010-12-21 15:31:40 +0000
@@ -17,23 +17,23 @@
 void NewtonIntegrator::cundallDamp(const Real& dt, const Vector3r& N, const Vector3r& V, Vector3r& A){
 	for(int i=0; i<3; i++) A[i]*= 1 - damping*Mathr::Sign ( N[i]*(V[i] + (Real) 0.5 *dt*A[i]) );
 }
-void NewtonIntegrator::blockTranslateDOFs(unsigned blockedDOFs, Vector3r& v) {
-	if(likely(blockedDOFs==State::DOF_NONE)) return;
-	if(blockedDOFs==State::DOF_ALL) { v=Vector3r::Zero(); return; }
-	if((blockedDOFs & State::DOF_X)!=0) v[0]=0;
-	if((blockedDOFs & State::DOF_Y)!=0) v[1]=0;
-	if((blockedDOFs & State::DOF_Z)!=0) v[2]=0;
-}
-void NewtonIntegrator::blockRotateDOFs(unsigned blockedDOFs, Vector3r& v) {
-	if(likely(blockedDOFs==State::DOF_NONE)) return;
-	if(blockedDOFs==State::DOF_ALL) { v=Vector3r::Zero(); return; }
-	if((blockedDOFs & State::DOF_RX)!=0) v[0]=0;
-	if((blockedDOFs & State::DOF_RY)!=0) v[1]=0;
-	if((blockedDOFs & State::DOF_RZ)!=0) v[2]=0;
-}
+
+Vector3r NewtonIntegrator::computeAccel(const Vector3r& force, const Real& mass, int blockedDOFs){
+	if(likely(blockedDOFs==0)) return force/mass;
+	Vector3r ret(Vector3r::Zero());
+	for(int i=0; i<3; i++) if(!(blockedDOFs & State::axisDOF(i,false))) ret[i]+=force[i]/mass;
+	return ret;
+}
+Vector3r NewtonIntegrator::computeAngAccel(const Vector3r& torque, const Vector3r& inertia, int blockedDOFs){
+	if(likely(blockedDOFs==0)) return torque.cwise()/inertia;
+	Vector3r ret(Vector3r::Zero());
+	for(int i=0; i<3; i++) if(!(blockedDOFs & State::axisDOF(i,true))) ret[i]+=torque[i]/inertia[i];
+	return ret;
+}
+
 void NewtonIntegrator::handleClumpMemberAccel(Scene* scene, const Body::id_t& memberId, State* memberState, State* clumpState){
 	const Vector3r& f=scene->forces.getForce(memberId);
-	Vector3r diffClumpAccel=f/clumpState->mass;
+	Vector3r diffClumpAccel=computeAccel(f,clumpState->mass,clumpState->blockedDOFs); // use blockedDOFs of the clump
 	// damp increment of accels on the clump, using velocities of the clump MEMBER
 	cundallDamp(scene->dt,f,memberState->vel,diffClumpAccel);
 	clumpState->accel+=diffClumpAccel;
@@ -41,10 +41,10 @@
 void NewtonIntegrator::handleClumpMemberAngAccel(Scene* scene, const Body::id_t& memberId, State* memberState, State* clumpState){
 	// angular acceleration from: normal torque + torque generated by the force WRT particle centroid on the clump centroid
 	const Vector3r& m=scene->forces.getTorque(memberId); const Vector3r& f=scene->forces.getForce(memberId);
-	Vector3r diffClumpAngularAccel=m.cwise()/clumpState->inertia+(memberState->pos-clumpState->pos).cross(f).cwise()/clumpState->inertia;
+	Vector3r diffClumpAngAccel=computeAngAccel(m+(memberState->pos-clumpState->pos).cross(f),clumpState->inertia,clumpState->blockedDOFs);
 	// damp increment of accels on the clump, using velocities of the clump MEMBER
-	cundallDamp(scene->dt,m,memberState->angVel,diffClumpAngularAccel);
-	clumpState->angAccel+=diffClumpAngularAccel;
+	cundallDamp(scene->dt,m,memberState->angVel,diffClumpAngAccel);
+	clumpState->angAccel+=diffClumpAngAccel;
 }
 void NewtonIntegrator::handleClumpMemberTorque(Scene* scene, const Body::id_t& memberId, State* memberState, State* clumpState, Vector3r& M){
 	const Vector3r& m=scene->forces.getTorque(memberId); const Vector3r& f=scene->forces.getForce(memberId);
@@ -137,18 +137,14 @@
 
 			if(likely(b->isStandalone())){
 				// translate equation
-				if(b->state->blockedDOFs!=State::DOF_ALL){
-					state->accel=f/state->mass;
-					cundallDamp(dt,f,fluctVel,state->accel);
-				}
+				state->accel=computeAccel(f,state->mass,state->blockedDOFs);
+				cundallDamp(dt,f,fluctVel,state->accel);
 				leapfrogTranslate(scene,state,id,dt);
 				// rotate equation
 				// exactAsphericalRot is disabled or the body is spherical
-				if(likely(!exactAsphericalRot || !b->isAspherical())){
-					if(b->state->blockedDOFs!=State::DOF_ALL) {
-						state->angAccel=m.cwise()/state->inertia;
-						cundallDamp(dt,m,state->angVel,state->angAccel);
-					}
+				if(likely(!exactAsphericalRot || !b->isAspherical() || b->state->inertia.minCoeff()==0)){
+					state->angAccel=computeAngAccel(m,state->inertia,state->blockedDOFs);
+					cundallDamp(dt,m,state->angVel,state->angAccel);
 					leapfrogSphericalRotate(scene,state,id,dt);
 				} else { // exactAsphericalRot enabled & aspherical body
 					// no damping in this case
@@ -158,13 +154,13 @@
 				// reset acceleration of the clump itself; computed from accels on constituents
 				state->accel=state->angAccel=Vector3r::Zero();
 				// clump mass forces
-				Vector3r dLinAccel=f/state->mass;
+				Vector3r dLinAccel=computeAccel(f,state->mass,state->blockedDOFs);
 				cundallDamp(dt,f,fluctVel,dLinAccel);
 				state->accel+=dLinAccel;
 				Vector3r M(m);
 				// sum force on clump memebrs
 				// exactAsphericalRot enabled and clump is aspherical
-				if (exactAsphericalRot && b->isAspherical()){
+				if (exactAsphericalRot && b->isAspherical() && b->state->inertia.maxCoeff()>0){
 					FOREACH(Clump::MemberMap::value_type mm, static_cast<Clump*>(b->shape.get())->members){
 						const Body::id_t& memberId=mm.first;
 						const shared_ptr<Body>& member=Body::byId(memberId,scene); assert(member->isClumpMember());
@@ -177,11 +173,9 @@
 					leapfrogTranslate(scene,state,id,dt);
 					leapfrogAsphericalRotate(scene,state,id,dt,M);
 				} else { // exactAsphericalRot disabled or clump is spherical
-					if(b->state->blockedDOFs!=State::DOF_ALL){
-						Vector3r dAngAccel=M.cwise()/state->inertia;
-						cundallDamp(dt,M,state->angVel,dAngAccel);
-						state->angAccel+=dAngAccel;
-					}
+					Vector3r dAngAccel=computeAngAccel(M,state->inertia,state->blockedDOFs);
+					cundallDamp(dt,M,state->angVel,dAngAccel);
+					state->angAccel+=dAngAccel;
 					FOREACH(Clump::MemberMap::value_type mm, static_cast<Clump*>(b->shape.get())->members){
 						const Body::id_t& memberId=mm.first;
 						const shared_ptr<Body>& member=Body::byId(memberId,scene); assert(member->isClumpMember());
@@ -211,10 +205,7 @@
 	if(scene->isPeriodic) { prevCellSize=scene->cell->getSize(); prevVelGrad=scene->cell->velGrad; }
 }
 
-inline void NewtonIntegrator::leapfrogTranslate(Scene* scene, State* state, const Body::id_t& id, const Real& dt)
-{
-	if(state->blockedDOFs!=State::DOF_ALL) blockTranslateDOFs(state->blockedDOFs, state->accel);
-
+inline void NewtonIntegrator::leapfrogTranslate(Scene* scene, State* state, const Body::id_t& id, const Real& dt){
 	if (scene->forces.getMoveRotUsed()) state->pos+=scene->forces.getMove(id);
 	if (homoDeform==Cell::HOMO_VEL || homoDeform==Cell::HOMO_VEL_2ND) {
 		// update velocity reflecting changes in the macroscopic velocity field, making the problem homothetic.
@@ -229,15 +220,12 @@
 	} else if (homoDeform==Cell::HOMO_POS){
 		state->pos+=scene->cell->velGrad*state->pos*dt;
 	}
-	if(state->blockedDOFs!=State::DOF_ALL) state->vel+=dt*state->accel;
-	state->pos += state->vel*dt;
+	state->vel+=dt*state->accel;
+	state->pos+=state->vel*dt;
 }
 
-inline void NewtonIntegrator::leapfrogSphericalRotate(Scene* scene, State* state, const Body::id_t& id, const Real& dt )
-{
-	if(state->blockedDOFs!=State::DOF_ALL){
-		blockRotateDOFs(state->blockedDOFs, state->angAccel);
-		state->angVel+=dt*state->angAccel;}
+inline void NewtonIntegrator::leapfrogSphericalRotate(Scene* scene, State* state, const Body::id_t& id, const Real& dt ){
+	state->angVel+=dt*state->angAccel;
 	Vector3r axis = state->angVel;
 
 	if (axis!=Vector3r::Zero()) {							//If we have an angular velocity, we make a rotation

=== modified file 'pkg/dem/NewtonIntegrator.hpp'
--- pkg/dem/NewtonIntegrator.hpp	2010-12-05 17:10:06 +0000
+++ pkg/dem/NewtonIntegrator.hpp	2010-12-21 15:31:40 +0000
@@ -32,8 +32,11 @@
 	inline void leapfrogSphericalRotate(Scene* ncb, State* state, const Body::id_t& id, const Real& dt); // leap-frog rotate of spherical body
 	inline void leapfrogAsphericalRotate(Scene* ncb, State* state, const Body::id_t& id, const Real& dt, const Vector3r& M); // leap-frog rotate of aspherical body
 	Quaternionr DotQ(const Vector3r& angVel, const Quaternionr& Q);
-	inline void blockTranslateDOFs(unsigned blockedDOFs, Vector3r& v);
-	inline void blockRotateDOFs(unsigned blockedDOFs, Vector3r& v);
+
+	// compute linear and angular acceleration, respecting State::blockedDOFs
+	Vector3r computeAccel(const Vector3r& force, const Real& mass, int blockedDOFs);
+	Vector3r computeAngAccel(const Vector3r& torque, const Vector3r& inertia, int blockedDOFs);
+
 	// whether the cell has changed from the previous step
 	bool cellChanged;
 	int homoDeform; // updated from scene at every call; -1 for aperiodic simulations, otherwise equal to scene->cell->homoDeform


Follow ups