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