← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 1817: merge with clump branch:

 

Merge authors:
  Sergei D. <sega@think>
------------------------------------------------------------
revno: 1817 [merge]
committer: Sergei D. <sega@think>
branch nick: trunk
timestamp: Fri 2009-11-27 12:31:55 +0300
message:
  merge with clump branch:
  1. handle DOFs for new rotation alg.; 
  2. add new clump-hopper-viscoelastic script;
  3. small optimization of acc.rot.alg; fix velocity and add angVel in VTKRecorder.
added:
  scripts/test/clump-hopper-viscoelastic.py
modified:
  pkg/dem/Engine/StandAloneEngine/NewtonsDampedLaw.cpp
  pkg/dem/Engine/StandAloneEngine/NewtonsDampedLaw.hpp
  pkg/dem/Engine/StandAloneEngine/VTKRecorder.cpp


--
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 'pkg/dem/Engine/StandAloneEngine/NewtonsDampedLaw.cpp'
--- pkg/dem/Engine/StandAloneEngine/NewtonsDampedLaw.cpp	2009-11-26 12:57:26 +0000
+++ pkg/dem/Engine/StandAloneEngine/NewtonsDampedLaw.cpp	2009-11-27 09:27:08 +0000
@@ -20,6 +20,20 @@
 		acceleration       [i]*= 1 - damping*Mathr::Sign ( f[i]*(velocity       [i] + (Real) 0.5 *dt*acceleration       [i]) );
 	}
 }
+void NewtonsDampedLaw::blockTranslateDOFs(unsigned blockedDOFs, Vector3r& v) {
+	if(blockedDOFs==State::DOF_NONE) return;
+	if(blockedDOFs==State::DOF_ALL)  v = Vector3r::ZERO;
+	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 NewtonsDampedLaw::blockRotateDOFs(unsigned blockedDOFs, Vector3r& v) {
+	if(blockedDOFs==State::DOF_NONE) return;
+	if(blockedDOFs==State::DOF_ALL)  v = Vector3r::ZERO;
+	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;
+}
 void NewtonsDampedLaw::handleClumpMember(MetaBody* ncb, const body_id_t memberId, State* clumpState){
 	const shared_ptr<Body>& b=Body::byId(memberId,ncb);
 	assert(b->isClumpMember());
@@ -98,20 +112,26 @@
 			}
 
 			// blocking DOFs
-			if(state->blockedDOFs==State::DOF_NONE){
-				state->angVel+=dt*state->angAccel;
-				state->vel+=+dt*state->accel;
-			} else if(state->blockedDOFs==State::DOF_ALL){
-				/* do nothing */
-			} else {
-				// handle more complicated cases here
-				if((state->blockedDOFs & State::DOF_X)==0) state->vel[0]+=dt*state->accel[0];
-				if((state->blockedDOFs & State::DOF_Y)==0) state->vel[1]+=dt*state->accel[1];
-				if((state->blockedDOFs & State::DOF_Z)==0) state->vel[2]+=dt*state->accel[2];
-				if((state->blockedDOFs & State::DOF_RX)==0) state->angVel[0]+=dt*state->angAccel[0];
-				if((state->blockedDOFs & State::DOF_RY)==0) state->angVel[1]+=dt*state->angAccel[1];
-				if((state->blockedDOFs & State::DOF_RZ)==0) state->angVel[2]+=dt*state->angAccel[2];
-			}
+			blockTranslateDOFs( state->blockedDOFs, state->accel );
+			state->vel+=+dt*state->accel;
+
+			blockRotateDOFs( state->blockedDOFs, state->angAccel );
+			state->angVel+=dt*state->angAccel;
+
+			//if(state->blockedDOFs==State::DOF_NONE){
+				//state->angVel+=dt*state->angAccel;
+				//state->vel+=+dt*state->accel;
+			//} else if(state->blockedDOFs==State::DOF_ALL){
+				//[> do nothing <]
+			//} else {
+				//// handle more complicated cases here
+				//if((state->blockedDOFs & State::DOF_X)==0) state->vel[0]+=dt*state->accel[0];
+				//if((state->blockedDOFs & State::DOF_Y)==0) state->vel[1]+=dt*state->accel[1];
+				//if((state->blockedDOFs & State::DOF_Z)==0) state->vel[2]+=dt*state->accel[2];
+				//if((state->blockedDOFs & State::DOF_RX)==0) state->angVel[0]+=dt*state->angAccel[0];
+				//if((state->blockedDOFs & State::DOF_RY)==0) state->angVel[1]+=dt*state->angAccel[1];
+				//if((state->blockedDOFs & State::DOF_RZ)==0) state->angVel[2]+=dt*state->angAccel[2];
+			//}
 
 			// velocities are ready now, save maxima
 				if(haveBins) {velocityBins->binVelSqUse(id,VelocityBins::getBodyVelSq(state));}
@@ -141,12 +161,10 @@
 }
 
 void NewtonsDampedLaw::accurateRigidBodyRotationIntegrator(MetaBody* ncb, const shared_ptr<Body>& rb){
-	Real dt=Omega::instance().getTimeStep();
+	const Real dt=Omega::instance().getTimeStep();
 	State* state=rb->state.get();
 	const body_id_t id=rb->getId();
-
 	state->accel=state->angAccel=Vector3r::ZERO; // to make sure; should be reset in Clump::moveMembers
-
 	// sum of forces and torques
 	const Vector3r& f=ncb->bex.getForce(id); const Vector3r& m=ncb->bex.getTorque(id);
 	Vector3r F(f), M(m);
@@ -159,21 +177,23 @@
 		F+=f; M+=(bs->pos-state->pos).Cross(f)+m;
 	}
 	// translation equation
-	state->accel=F/state->mass;
-	state->vel+=dt*state->accel;
-	state->pos+=state->vel*dt;//+ncb->bex.getMove(id);
+	state->accel=F/state->mass; blockTranslateDOFs( state->blockedDOFs, state->accel );
+	state->vel+=dt*state->accel; state->pos+=state->vel*dt+ncb->bex.getMove(id);
 	// rotation equation
-	Vector3r l_n = state->prevAngMom + dt/2 * M; // global angular momentum at time n
-	Vector3r l_b_n = state->ori.Conjugate().Rotate(l_n); // local angular momentum at time n
-	Vector3r angVel_b_n = diagDiv(l_b_n,state->inertia); // local angular velocity at time n
-	Quaternionr dotQ_n=DotQ(angVel_b_n,state->ori); // dQ/dt at time n
-	Quaternionr Q_half = state->ori + dt/2 * dotQ_n; // Q at time n+1/2
+	Matrix3r A; state->ori.Conjugate().ToRotationMatrix(A); // rotation matrix from global to local r.f.
+	const Vector3r l_n = state->prevAngMom + dt/2 * M; // global angular momentum at time n
+	//Vector3r l_b_n = state->ori.Conjugate().Rotate(l_n); // local angular momentum at time n
+	const Vector3r l_b_n = A*l_n; // local angular momentum at time n
+	const Vector3r angVel_b_n = diagDiv(l_b_n,state->inertia); // local angular velocity at time n
+	const Quaternionr dotQ_n=DotQ(angVel_b_n,state->ori); // dQ/dt at time n
+	const Quaternionr Q_half = state->ori + dt/2 * dotQ_n; // Q at time n+1/2
 	state->prevAngMom+=dt*M; // global angular momentum at time n+1/2
-	Vector3r l_b_half = state->ori.Conjugate().Rotate(state->prevAngMom); // local angular momentum at time n+1/2
+	//Vector3r l_b_half = state->ori.Conjugate().Rotate(state->prevAngMom); // local angular momentum at time n+1/2
+	const Vector3r l_b_half = A*state->prevAngMom; // local angular momentum at time n+1/2
 	Vector3r angVel_b_half = diagDiv(l_b_half,state->inertia); // local angular velocity at time n+1/2
-	Quaternionr dotQ_half=DotQ(angVel_b_half,Q_half); // dQ/dt at time n+1/2
-	state->ori+=dt*dotQ_half; // Q at time n+1
-	state->ori.Normalize();
+	blockRotateDOFs( state->blockedDOFs, angVel_b_half );
+	const Quaternionr dotQ_half=DotQ(angVel_b_half,Q_half); // dQ/dt at time n+1/2
+	state->ori+=dt*dotQ_half; state->ori.Normalize(); // Q at time n+1
 	state->angVel=state->ori.Rotate(angVel_b_half); // global angular velocity at time n+1/2
 	//if(rb->isClump()) static_cast<Clump*>(rb.get())->moveMembers();
 	static_cast<Clump*>(rb.get())->moveMembers();

=== modified file 'pkg/dem/Engine/StandAloneEngine/NewtonsDampedLaw.hpp'
--- pkg/dem/Engine/StandAloneEngine/NewtonsDampedLaw.hpp	2009-11-26 12:57:26 +0000
+++ pkg/dem/Engine/StandAloneEngine/NewtonsDampedLaw.hpp	2009-11-27 09:27:08 +0000
@@ -43,6 +43,9 @@
 	bool haveBins;
 	void accurateRigidBodyRotationIntegrator(MetaBody* ncb, const shared_ptr<Body>& rb);
 	Quaternionr DotQ(const Vector3r& angVel, const Quaternionr& Q);
+	inline void blockTranslateDOFs(unsigned blockedDOFs, Vector3r& v);
+	inline void blockRotateDOFs(unsigned blockedDOFs, Vector3r& v);
+
 	public:
 		///damping coefficient for Cundall's non viscous damping
 		Real damping;

=== modified file 'pkg/dem/Engine/StandAloneEngine/VTKRecorder.cpp'
--- pkg/dem/Engine/StandAloneEngine/VTKRecorder.cpp	2009-11-26 12:57:26 +0000
+++ pkg/dem/Engine/StandAloneEngine/VTKRecorder.cpp	2009-11-27 07:01:33 +0000
@@ -60,13 +60,16 @@
 	vtkSmartPointer<vtkCellArray> spheresCells = vtkSmartPointer<vtkCellArray>::New();
 	vtkSmartPointer<vtkFloatArray> radii = vtkSmartPointer<vtkFloatArray>::New();
 	radii->SetNumberOfComponents(1);
-	radii->SetName("Radii");
+	radii->SetName("radii");
 	vtkSmartPointer<vtkFloatArray> spheresColors = vtkSmartPointer<vtkFloatArray>::New();
 	spheresColors->SetNumberOfComponents(3);
-	spheresColors->SetName("Colors");
+	spheresColors->SetName("colors");
 	vtkSmartPointer<vtkFloatArray> spheresVelocity = vtkSmartPointer<vtkFloatArray>::New();
 	spheresVelocity->SetNumberOfComponents(3);
 	spheresVelocity->SetName("velocity");
+	vtkSmartPointer<vtkFloatArray> sphAngVel = vtkSmartPointer<vtkFloatArray>::New();
+	sphAngVel->SetNumberOfComponents(3);
+	sphAngVel->SetName("angVel");
 
 	// facets
 	vtkSmartPointer<vtkPoints> facetsPos = vtkSmartPointer<vtkPoints>::New();
@@ -147,7 +150,16 @@
 					spheresColors->InsertNextTupleValue(c);
 				}
 				if(recActive[REC_VELOCITY]){
-					spheresVelocity->InsertNextTupleValue((float*)(&b->state->vel));
+					const Vector3r& vel = b->state->vel;
+					float v[3] = { vel[0],vel[1],vel[2] };
+					spheresVelocity->InsertNextTupleValue(v);
+
+					const Vector3r& angVel = b->state->angVel;
+					float av[3] = { angVel[0],angVel[1],angVel[2] };
+					sphAngVel->InsertNextTupleValue(av);
+
+					//spheresVelocity->InsertNextTupleValue((float*)(&b->state->vel));
+					//sphAngVel->InsertNextTupleValue((float*)(&b->state->angVel));
 				}
 				if (recActive[REC_CPM]) {
 					cpmDamage->InsertNextValue(YADE_PTR_CAST<CpmState>(b->state)->normDmg);
@@ -199,7 +211,10 @@
 		spheresUg->SetCells(VTK_VERTEX, spheresCells);
 		spheresUg->GetPointData()->AddArray(radii);
 		if (recActive[REC_COLORS]) spheresUg->GetPointData()->AddArray(spheresColors);
-		if (recActive[REC_VELOCITY]) spheresUg->GetPointData()->AddArray(spheresVelocity);
+		if (recActive[REC_VELOCITY]) {
+			spheresUg->GetPointData()->AddArray(spheresVelocity);
+			spheresUg->GetPointData()->AddArray(sphAngVel);
+		}
 		if (recActive[REC_CPM]) {
 			spheresUg->GetPointData()->AddArray(cpmDamage);
 			spheresUg->GetPointData()->AddArray(cpmSigma);

=== added file 'scripts/test/clump-hopper-viscoelastic.py'
--- scripts/test/clump-hopper-viscoelastic.py	1970-01-01 00:00:00 +0000
+++ scripts/test/clump-hopper-viscoelastic.py	2009-11-27 09:27:08 +0000
@@ -0,0 +1,87 @@
+# -*- coding: utf-8
+
+from yade import utils,pack,export,qt
+import gts,os,random,itertools
+from numpy import *
+import yade.log 
+
+#yade.log.setLevel('NewtonsDampedLaw',yade.log.TRACE)
+
+# Parameters
+tc=0.001# collision time 
+en=.3  # normal restitution coefficient
+es=.3  # tangential restitution coefficient
+frictionAngle=radians(35)# 
+density=2700
+# facets material
+params=utils.getViscoelasticFromSpheresInteraction(10e3,tc,en,es)
+facetMat=O.materials.append(SimpleViscoelasticMat(frictionAngle=frictionAngle,**params)) # **params sets kn, cn, ks, cs
+# default spheres material
+dfltSpheresMat=O.materials.append(SimpleViscoelasticMat(density=density,frictionAngle=frictionAngle)) 
+
+O.dt=.1*tc # time step
+
+Rs=0.05 # particle radius
+
+# Create geometry
+
+x0=0.; y0=0.; z0=0.; ab=.7; at=2.; h=1.; hl=h; al=at*3
+
+zb=z0;   x0b=x0-ab/2.; y0b=y0-ab/2.; x1b=x0+ab/2.; y1b=y0+ab/2.
+zt=z0+h; x0t=x0-at/2.; y0t=y0-at/2.; x1t=x0+at/2.; y1t=y0+at/2.
+zl=z0-hl;x0l=x0-al/2.; y0l=y0-al/2.; x1l=x0+al/2.; y1l=y0+al/2.
+
+left = pack.sweptPolylines2gtsSurface([[Vector3(x0b,y0b,zb),Vector3(x0t,y0t,zt),Vector3(x0t,y1t,zt),Vector3(x0b,y1b,zb)]],capStart=True,capEnd=True)
+lftIds=O.bodies.append(pack.gtsSurface2Facets(left.faces(),material=facetMat,color=(0,1,0)))
+
+right = pack.sweptPolylines2gtsSurface([[Vector3(x1b,y0b,zb),Vector3(x1t,y0t,zt),Vector3(x1t,y1t,zt),Vector3(x1b,y1b,zb)]],capStart=True,capEnd=True)
+rgtIds=O.bodies.append(pack.gtsSurface2Facets(right.faces(),material=facetMat,color=(0,1,0)))
+
+near = pack.sweptPolylines2gtsSurface([[Vector3(x0b,y0b,zb),Vector3(x0t,y0t,zt),Vector3(x1t,y0t,zt),Vector3(x1b,y0b,zb)]],capStart=True,capEnd=True)
+nearIds=O.bodies.append(pack.gtsSurface2Facets(near.faces(),material=facetMat,color=(0,1,0)))
+
+far = pack.sweptPolylines2gtsSurface([[Vector3(x0b,y1b,zb),Vector3(x0t,y1t,zt),Vector3(x1t,y1t,zt),Vector3(x1b,y1b,zb)]],capStart=True,capEnd=True)
+farIds=O.bodies.append(pack.gtsSurface2Facets(far.faces(),material=facetMat,color=(0,1,0)))
+
+table = pack.sweptPolylines2gtsSurface([[Vector3(x0l,y0l,zl),Vector3(x0l,y1l,zl),Vector3(x1l,y1l,zl),Vector3(x1l,y0l,zl)]],capStart=True,capEnd=True)
+tblIds=O.bodies.append(pack.gtsSurface2Facets(table.faces(),material=facetMat,color=(0,1,0)))
+
+# Create clumps...
+for k,l in itertools.product(arange(0,10),arange(0,10)):
+	clpId,sphId=O.bodies.appendClumped([utils.sphere(Vector3(x0t+Rs*(k*4+2),y0t+Rs*(l*4+2),i*Rs*2+zt),Rs,color=(0,0,1),material=dfltSpheresMat) for i in xrange(4)])
+	for id in sphId:
+		s=O.bodies[id]
+		p=utils.getViscoelasticFromSpheresInteraction(s.state['mass'],tc,en,es)
+		s.mat['kn'],s.mat['cn'],s.mat['ks'],s.mat['cs']=p['kn'],p['cn'],p['ks'],p['cs']
+	#O.bodies[clpId].state.blockedDOFs=['rx','ry','rz']
+	#O.bodies[clpId].state.blockedDOFs=['x','y']
+
+# ... and spheres
+for k,l in itertools.product(arange(0,9),arange(0,9)):
+	sphAloneId=O.bodies.append( [utils.sphere( Vector3(x0t+Rs*(k*4+4),y0t+Rs*(l*4+4),i*Rs*2.3+zt),Rs,color=(0,1,0),material=dfltSpheresMat) for i in xrange(4) ] )
+	for id in sphAloneId:
+		s=O.bodies[id]
+		p=utils.getViscoelasticFromSpheresInteraction(s.state['mass'],tc,en,es)
+		s.mat['kn'],s.mat['cn'],s.mat['ks'],s.mat['cs']=p['kn'],p['cn'],p['ks'],p['cs']
+		#s.state.blockedDOFs=['rx','ry','rz']
+		#s.state.blockedDOFs=['x','y']
+
+# Create engines
+O.engines=[
+	BexResetter(),
+	BoundingVolumeMetaEngine([InteractingSphere2AABB(),InteractingFacet2AABB()]),
+	InsertionSortCollider(),
+	InteractionDispatchers(
+		[InteractingSphere2InteractingSphere4SpheresContactGeometry(), InteractingFacet2InteractingSphere4SpheresContactGeometry()],
+		[Ip2_SimleViscoelasticMat_SimpleViscoelasticMat_SimpleViscoelasticPhys()],
+		[Law2_Spheres_Viscoelastic_SimpleViscoelastic()],
+	),
+	GravityEngine(gravity=[0,0,-9.81]),
+	NewtonsDampedLaw(damping=0,accRigidBodyRot=True),
+	#VTKRecorder(virtPeriod=0.01,fileName='/tmp/',recorders=['spheres','velocity','facets'])
+]
+
+renderer = qt.Renderer()
+qt.View()
+O.saveTmp()
+