yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #12507
[Branch ~yade-pkg/yade/git-trunk] Rev 3775: Merge pull request #47 from booncw/master
Merge authors:
booncw (booncw)
------------------------------------------------------------
revno: 3775 [merge]
committer: Jan Stránský <honzik.stransky@xxxxxxxxx>
timestamp: Mon 2016-01-18 10:00:22 +0100
message:
Merge pull request #47 from booncw/master
Commit Potential Particles: non-spherical particles for DEM
added:
examples/PotentialParticles/
examples/PotentialParticles/cubePPscaled.py
pkg/common/Gl1_PotentialParticle.cpp
pkg/common/Gl1_PotentialParticle.hpp
pkg/dem/Ig2_PP_PP_ScGeom.cpp
pkg/dem/Ig2_PP_PP_ScGeom.hpp
pkg/dem/KnKsLaw.cpp
pkg/dem/KnKsLaw.hpp
pkg/dem/PotentialParticle.cpp
pkg/dem/PotentialParticle.hpp
pkg/dem/PotentialParticle2AABB.cpp
pkg/dem/PotentialParticle2AABB.hpp
--
lp:yade
https://code.launchpad.net/~yade-pkg/yade/git-trunk
Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-pkg/yade/git-trunk/+edit-subscription
=== added directory 'examples/PotentialParticles'
=== added file 'examples/PotentialParticles/cubePPscaled.py'
--- examples/PotentialParticles/cubePPscaled.py 1970-01-01 00:00:00 +0000
+++ examples/PotentialParticles/cubePPscaled.py 2015-12-14 14:25:08 +0000
@@ -0,0 +1,296 @@
+#!/usr/local/bin/yade-trunk -x
+# -*- encoding=utf-8 -*-
+# CWBoon 2015
+
+from yade import pack
+import math
+
+
+O.engines=[
+ ForceResetter(),
+ InsertionSortCollider([PotentialParticle2AABB()],verletDist=0),
+ InteractionLoop(
+ [Ig2_PP_PP_ScGeom()],
+ [Ip2_FrictMat_FrictMat_KnKsPhys(Knormal = 1e8, Kshear = 1e8,useFaceProperties=False,calJointLength=False,twoDimension=True,unitWidth2D=1.0,viscousDamping=0.7)],
+ [Law2_SCG_KnKsPhys_KnKsLaw(label='law',neverErase=False)]
+ #[Ip2_FrictMat_FrictMat_FrictPhys()],
+ #[Law2_ScGeom_FrictPhys_CundallStrack()]
+ ),
+ #GravityEngine(gravity=[0,-10,0]),
+ #GlobalStiffnessTimeStepper(),
+ NewtonIntegrator(damping=0.0,exactAsphericalRot=False,gravity=[0,-10,0]),
+ #PotentialParticleVTKRecorder(fileName='/home/chiab/yadeNew/mosek/8Nov/BranchA/scripts2/boon/ComputersGeotechnics/vtk/1000PP',iterPeriod=100,sampleX=50,sampleY=50,sampleZ=50)
+
+]
+
+
+
+
+powderDensity = 10000
+distanceToCentre= 0.5
+meanSize = 1.0
+wallThickness = 0.5*meanSize
+O.materials.append(FrictMat(young=150e6,poisson=.4,frictionAngle=radians(0.0),density=powderDensity,label='frictionless'))
+lengthOfBase = 9.0*meanSize
+heightOfBase = 14.0*meanSize
+sp=pack.SpherePack()
+mn,mx=Vector3(-0.5*(lengthOfBase-wallThickness),0.5*meanSize,-0.5*(lengthOfBase-wallThickness)),Vector3(0.5*(lengthOfBase-wallThickness),7.0*heightOfBase,0.5*(lengthOfBase-wallThickness))
+sphereRad = sqrt(3.0)*0.5*meanSize
+sp.makeCloud(mn,mx,sphereRad,0,100,False)
+
+
+count= 0
+rPP=0.05*meanSize
+for s in sp:
+ b=Body()
+ radius=2.2
+ dynamic=True
+ wire=False
+ color=[0,0,255.0]
+ highlight=False
+ b.shape=PotentialParticle(k=0.2, r=0.05*meanSize, R=1.02*sphereRad, a=[1.0,-1.0,0.0,0.0,0.0,0.0], b=[0.0,0.0,1.0,-1.0,0.0,0.0], c=[0.0,0.0,0.0,0.0,1.0,-1.0], d=[distanceToCentre-rPP,distanceToCentre-rPP,distanceToCentre-rPP,distanceToCentre-rPP,distanceToCentre-rPP,distanceToCentre-rPP],isBoundary=False,color=color,wire=wire,highlight=highlight,minAabb=Vector3(sphereRad,sphereRad,sphereRad),maxAabb=Vector3(sphereRad,sphereRad,sphereRad),maxAabbRotated=Vector3(sphereRad,sphereRad,sphereRad),minAabbRotated=Vector3(sphereRad,sphereRad,sphereRad),AabbMinMax=False)
+ length=meanSize
+ V= 1.0
+ geomInert=(2./5.)*powderDensity*V*sphereRad**2
+ utils._commonBodySetup(b,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=s[0], noBound=False, resetState=True, fixed=False)
+ b.state.pos = s[0] #s[0] stores center
+ b.state.ori = Quaternion((random.random(),random.random(),random.random()),random.random()) #s[2]
+ O.bodies.append(b)
+ b.dynamic = True
+ count =count+1
+
+#v1 = (0, 0, 0.2) (0, 0, 1) (0,0,2.498)
+#v2 = (-0.0943, 0.1633, -0.0667) (-0.4714, 0.8165, -0.3334)
+#v3 = (0.1886 0 -0.0667) (0.9428, 0, -0.3333)
+#edge = 0.3266 1.6333 4.08
+#volume = 0.0041 0.5132 8
+
+r=0.1*wallThickness
+bbb=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+bbb.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.2*lengthOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[lengthOfBase/6.0-r,lengthOfBase/6.0-r,0.5*wallThickness-r,0.5*wallThickness-r,lengthOfBase/6.0-r,lengthOfBase/6.0-r], id=count,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),maxAabb=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),maxAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),minAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(bbb,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True, fixed=True)
+bbb.dynamic=False
+bbb.state.pos = [0.0,0,0]
+lidID = O.bodies.append(bbb)
+
+
+
+b1=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+b1.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.2*lengthOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[lengthOfBase/6.0-r,lengthOfBase/6.0-r,0.5*wallThickness-r,0.5*wallThickness-r,lengthOfBase/6.0-r,lengthOfBase/6.0-r], id=count,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),minAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(b1,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+b1.dynamic=False
+b1.state.pos = [lengthOfBase/3.0,0,lengthOfBase/3.0]
+O.bodies.append(b1)
+
+b2=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+b2.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.2*lengthOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[lengthOfBase/6.0-r,lengthOfBase/6.0-r,0.5*wallThickness-r,0.5*wallThickness-r,lengthOfBase/6.0-r,lengthOfBase/6.0-r], id=count,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),minAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(b2,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+b2.dynamic=False
+b2.state.pos = [-lengthOfBase/3.0,0,lengthOfBase/3.0]
+O.bodies.append(b2)
+
+b3=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+b3.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.2*lengthOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[lengthOfBase/6.0-r,lengthOfBase/6.0-r,0.5*wallThickness-r,0.5*wallThickness-r,lengthOfBase/6.0-r,lengthOfBase/6.0-r], id=count,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),minAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(b3,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+b3.dynamic=False
+b3.state.pos = [0.0,0,lengthOfBase/3.0]
+O.bodies.append(b3)
+
+b4=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+b4.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.2*lengthOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[lengthOfBase/6.0-r,lengthOfBase/6.0-r,0.5*wallThickness-r,0.5*wallThickness-r,lengthOfBase/6.0-r,lengthOfBase/6.0-r], id=count,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),minAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(b4,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+b4.dynamic=False
+b4.state.pos = [lengthOfBase/3.0,0,-lengthOfBase/3.0]
+O.bodies.append(b4)
+
+b5=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+b5.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.2*lengthOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[lengthOfBase/6.0-r,lengthOfBase/6.0-r,0.5*wallThickness-r,0.5*wallThickness-r,lengthOfBase/6.0-r,lengthOfBase/6.0-r], id=count,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),minAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(b5,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+b5.dynamic=False
+b5.state.pos = [0.0,0,-lengthOfBase/3.0]
+O.bodies.append(b5)
+
+
+b6=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+b6.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.2*lengthOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[lengthOfBase/6.0-r,lengthOfBase/6.0-r,0.5*wallThickness-r,0.5*wallThickness-r,lengthOfBase/6.0-r,lengthOfBase/6.0-r], id=count,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),minAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(b6,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+b6.dynamic=False
+b6.state.pos = [-lengthOfBase/3.0,0.0,-lengthOfBase/3.0]
+O.bodies.append(b6)
+
+b7=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+b7.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.2*lengthOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[lengthOfBase/6.0-r,lengthOfBase/6.0-r,0.5*wallThickness-r,0.5*wallThickness-r,lengthOfBase/6.0-r,lengthOfBase/6.0-r], id=count,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),minAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(b7,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+b7.dynamic=False
+b7.state.pos = [-lengthOfBase/3.0,0.0,0.0]
+O.bodies.append(b7)
+
+
+b8=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+b8.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.2*lengthOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[lengthOfBase/6.0-r,lengthOfBase/6.0-r,0.5*wallThickness-r,0.5*wallThickness-r,lengthOfBase/6.0-r,lengthOfBase/6.0-r], id=count,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabb=1.02*Vector3(lengthOfBase/6.0,0.4*wallThickness,lengthOfBase/6.0),maxAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0),minAabbRotated=1.02*Vector3(lengthOfBase/6.0,0.5*wallThickness,lengthOfBase/6.0))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(b8,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+b8.dynamic=False
+b8.state.pos = [lengthOfBase/3.0,0.0,0.0]
+O.bodies.append(b8)
+
+bA=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+bA.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.5*heightOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[0.5*wallThickness-r,0.5*wallThickness-r,0.5*heightOfBase-r,0.5*heightOfBase-r,0.5*lengthOfBase-r,0.5*lengthOfBase-r], id=count+1,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(0.3*wallThickness,0.5*heightOfBase,0.5*lengthOfBase),maxAabb=1.02*Vector3(0.3*wallThickness,0.5*heightOfBase,0.5*lengthOfBase),maxAabbRotated=1.02*Vector3(0.5*wallThickness,0.5*heightOfBase,0.5*lengthOfBase),minAabbRotated=1.02*Vector3(0.5*wallThickness,0.5*heightOfBase,0.5*lengthOfBase))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(bA,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+bA.dynamic=False
+bA.state.pos = [0.5*lengthOfBase,0.5*heightOfBase,0]
+O.bodies.append(bA)
+
+bB=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+bB.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.5*heightOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[0.5*wallThickness-r,0.5*wallThickness-r,0.5*heightOfBase-r,0.5*heightOfBase-r,0.5*lengthOfBase-r,0.5*lengthOfBase-r], id=count+2,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(0.3*wallThickness,0.5*heightOfBase,0.5*lengthOfBase),maxAabb=1.02*Vector3(0.3*wallThickness,0.5*heightOfBase,0.5*lengthOfBase),maxAabbRotated=1.02*Vector3(0.5*wallThickness,0.5*heightOfBase,0.5*lengthOfBase),minAabbRotated=1.02*Vector3(0.5*wallThickness,0.5*heightOfBase,0.5*lengthOfBase))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(bB,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+bB.dynamic=False
+bB.state.pos = [-0.5*lengthOfBase,0.5*heightOfBase,0]
+O.bodies.append(bB)
+
+
+bC=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+bC.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.5*heightOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[0.5*lengthOfBase-r,0.5*lengthOfBase-r,0.5*heightOfBase-r,0.5*heightOfBase-r,0.5*wallThickness-r,0.5*wallThickness-r], id=count+3,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(0.5*lengthOfBase,0.5*heightOfBase,0.3*wallThickness),maxAabb=1.02*Vector3(0.5*lengthOfBase,0.5*heightOfBase,0.3*wallThickness),maxAabbRotated=1.02*Vector3(0.5*lengthOfBase,0.5*heightOfBase,0.5*wallThickness),minAabbRotated=1.02*Vector3(0.5*lengthOfBase,0.5*heightOfBase,0.5*wallThickness))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(bC,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+bC.dynamic=False
+bC.state.pos = [0,0.5*heightOfBase,0.5*lengthOfBase]
+O.bodies.append(bC)
+
+bD=Body()
+wire=False
+color=[0,255,0]
+highlight=False
+bD.shape=PotentialParticle(k=0.1, r=0.1*wallThickness, R=0.5*heightOfBase,a=[1,-1,0,0,0,0], b=[0,0,1,-1,0,0], c=[0,0,0,0,1,-1], d=[0.5*lengthOfBase-r,0.5*lengthOfBase-r,0.5*heightOfBase-r,0.5*heightOfBase-r,0.5*wallThickness-r,0.5*wallThickness-r], id=count+4,isBoundary=True,isBoundaryPlane=[True,True,True,True,True,True],color=color ,wire=wire,highlight=highlight,AabbMinMax=True, minAabb=1.02*Vector3(0.5*lengthOfBase,0.5*heightOfBase,0.3*wallThickness),maxAabb=1.02*Vector3(0.5*lengthOfBase,0.5*heightOfBase,0.3*wallThickness),maxAabbRotated=1.02*Vector3(0.5*lengthOfBase,0.5*heightOfBase,0.5*wallThickness),minAabbRotated=1.02*Vector3(0.5*lengthOfBase,0.5*heightOfBase,0.5*wallThickness))
+length=lengthOfBase
+V=lengthOfBase*lengthOfBase*wallThickness
+geomInert=(1./6.)*V*length*wallThickness
+utils._commonBodySetup(bD,V,Vector3(geomInert,geomInert,geomInert), material='frictionless',pos=[0.0,0,0], noBound=False, resetState=True,fixed=True)
+bD.dynamic=False
+bD.state.pos = [0.0,0.5*heightOfBase,-0.5*lengthOfBase]
+O.bodies.append(bD)
+
+
+escapeNo=0
+def myAddPlotData():
+ global escapeNo
+ global wallThickness
+ global meanSize
+ uf=utils.unbalancedForce()
+ if isnan(uf):
+ uf = 1.0
+ KE = utils.kineticEnergy()
+
+ for b in O.bodies:
+ if b.state.pos[1] < -5.0*meanSize and b.dynamic==True:
+ escapeNo = escapeNo+1
+ O.bodies.erase(b.id)
+ if O.iter>12000:
+ removeLid()
+ plot.addData(timeStep1=O.iter,timeStep2=O.iter,timeStep3=O.iter,timeStep4=O.iter,time=O.time,unbalancedForce=uf,kineticEn=KE,outsideNo=escapeNo)
+
+
+from yade import plot
+plot.plots={'timeStep1':('unbalancedForce'),'timeStep2':('kineticEn'),'time':('outsideNo')}
+O.engines=O.engines+[PyRunner(iterPeriod=10,command='myAddPlotData()')]
+
+def removeLid():
+ global lidID
+ if (O.bodies[lidID]):
+ O.bodies.erase(lidID)
+
+
+
+O.engines=O.engines+[PotentialParticleVTKRecorder(fileName='/home/boon/yadeRev/trunk/examples/PotentialParticles/vtk/cubeScaled',iterPeriod=1000,sampleX=50,sampleY=50,sampleZ=50)]
+
+#for b in O.bodies:
+# b.state.blockedDOFs=['rx','ry','rz','x','z']
+
+#O.bodies[0].state.pos = [0,meanSize*10.0,0]
+#O.bodies[0].state.vel =[0,0.0,0]
+O.dt = 0.2*sqrt(O.bodies[0].state.mass*0.33333333/1.0e8)
+#from yade import qt
+#qt.Controller()
+#qt.View()
+
+#Gl1_PotentialParticle.sizeX = 30
+#Gl1_PotentialParticle.sizeY = 30
+#Gl1_PotentialParticle.sizeZ = 30
+#from yade import qt
+#qt.View()
+
+import yade.timing
+O.timingEnabled = True
+yade.timing.reset()
+#O.engines[2].geomDispatcher.functors[0].timingDeltas.data
+#yade.timing.stats()
=== added file 'pkg/common/Gl1_PotentialParticle.cpp'
--- pkg/common/Gl1_PotentialParticle.cpp 1970-01-01 00:00:00 +0000
+++ pkg/common/Gl1_PotentialParticle.cpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,610 @@
+/*CWBoon 2015 */
+#include "Gl1_PotentialParticle.hpp"
+
+//#include<lib-opengl/OpenGLWrapper.hpp>
+#include <vtkFloatArray.h>
+#include<vtkUnstructuredGrid.h>
+#include<vtkXMLUnstructuredGridWriter.h>
+#include<vtkTriangle.h>
+#include<vtkSmartPointer.h>
+#include<vtkFloatArray.h>
+#include<vtkCellArray.h>
+#include<vtkCellData.h>
+#include <vtkSampleFunction.h>
+#include <vtkStructuredPoints.h>
+#include<vtkStructuredPointsWriter.h>
+#include<vtkWriter.h>
+#include<vtkExtractVOI.h>
+#include<vtkXMLImageDataWriter.h>
+#include<vtkXMLStructuredGridWriter.h>
+#include<vtkTransformPolyDataFilter.h>
+#include<vtkTransform.h>
+
+#include <vtkContourFilter.h>
+#include <vtkPolyDataMapper.h>
+#include<vtkXMLPolyDataWriter.h>
+#include <vtkAppendPolyData.h>
+
+
+#include <vtkRenderWindowInteractor.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkPointData.h>
+#include <vtkLookupTable.h>
+#include <vtkXMLDataSetWriter.h>
+
+
+//#include<lib-opengl/OpenGLWrapper.hpp>
+#include<pkg/dem/KnKsLaw.hpp>
+#include<pkg/dem/ScGeom.hpp>
+#include<vtkLine.h>
+#include <vtkSphereSource.h>
+#include <vtkDiskSource.h>
+#include <vtkRegularPolygonSource.h>
+#include <vtkProperty.h>
+
+#include <vtkLabeledDataMapper.h>
+#include <vtkActor2D.h>
+#include <vtkVectorText.h>
+#include <vtkLinearExtrusionFilter.h>
+#include <vtkConeSource.h>
+#include <vtkCamera.h>
+//#include<pkg/dem/Clump.hpp>
+#include<pkg/common/Aabb.hpp>
+#include <vtkImplicitBoolean.h>
+#include <vtkIntArray.h>
+
+#if 0
+void Gl1_PotentialParticle::calcMinMax(const shared_ptr<Shape>& cm)
+{
+ PotentialParticle* pp = static_cast<PotentialParticle*>(cm.get());
+ int planeNo = pp->d.size();
+ Real maxD = pp->d[0];
+
+ for (int i=0; i<planeNo; ++i){
+ if (pp->d[i] > maxD) {
+ maxD = pp->d[i];
+ }
+ }
+
+ Real R = pp->R;
+ Real r = pp->r;
+ Real maxTip = R; //std::max(maxD + r, R);
+ min =-1.1*pp->minAabb; // 1.5*Vector3r(-maxTip,-maxTip,-maxTip);
+ max = 1.1*pp->maxAabb; //-1.0*min;
+
+ float dx = (max[0]-min[0])/((float)(sizeX));
+ float dy = (max[1]-min[1])/((float)(sizeY));
+ float dz = (max[2]-min[2])/((float)(sizeZ));
+
+ isoStep=Vector3r(dx,dy,dz);
+}
+
+
+void Gl1_PotentialParticle::generateScalarField(const shared_ptr<Shape>& cm)
+{
+ for(int i=0;i<sizeX;i++){
+ for(int j=0;j<sizeY;j++){
+ for(int k=0;k<sizeZ;k++)
+ {
+ scalarField[i][j][k] = 0.0;
+ }
+ }
+ }
+
+ for(int i=0;i<sizeX;i++){
+ for(int j=0;j<sizeY;j++){
+ for(int k=0;k<sizeZ;k++){
+ scalarField[i][j][k] = evaluateF(cm, min[0]+ double(i)*isoStep[0], min[1]+ double(j)*isoStep[1], min[2]+double(k)*isoStep[2]);//
+ }
+ }
+ }
+}
+
+
+
+vector<Gl1_PotentialParticle::scalarF> Gl1_PotentialParticle::SF;
+int Gl1_PotentialParticle::sizeX, Gl1_PotentialParticle::sizeY, Gl1_PotentialParticle::sizeZ;
+bool Gl1_PotentialParticle::store;
+bool Gl1_PotentialParticle::initialized;
+
+void Gl1_PotentialParticle::clearMemory(){
+SF.clear();
+}
+
+
+void Gl1_PotentialParticle::go( const shared_ptr<Shape>& cm, const shared_ptr<State>& state ,bool wire2, const GLViewInfo&){
+
+
+ PotentialParticle* pp = static_cast<PotentialParticle*>(cm.get());
+ int shapeId = pp->id;
+
+if(store == false){
+ if(SF.size()>0){SF.clear(); initialized = false; }
+ return;
+}
+
+if(initialized == false ){
+ FOREACH(const shared_ptr<Body>& b, *scene->bodies){
+ if (!b) continue;
+ const shared_ptr<Shape>& cmbody=b->shape;
+ calcMinMax(cmbody);
+ mc.init(sizeX,sizeY,sizeZ,min,max);
+ mc.resizeScalarField(scalarField,sizeX,sizeY,sizeZ);
+ SF.push_back(scalarF());
+ generateScalarField(cmbody);
+ mc.computeTriangulation(scalarField,0.0);
+ SF[b->id].triangles = mc.getTriangles();
+ SF[b->id].normals = mc.getNormals();
+ SF[b->id].nbTriangles = mc.getNbTriangles();
+ for(int i=0; i<scalarField.size(); i++){
+ for(int j=0; j<scalarField[i].size(); j++) scalarField[i][j].clear();
+ scalarField[i].clear();
+ }
+ scalarField.clear();
+ }
+ initialized = true;
+}
+
+
+//if(std::isnan(shapeId)==true){return;}
+
+ calcMinMax(cm);
+ mc.init(sizeX,sizeY,sizeZ,min,max);
+ mc.resizeScalarField(scalarField,sizeX,sizeY,sizeZ);
+
+
+
+ // FIXME : check that : one of those 2 lines are useless
+ glMaterialv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, Vector3r(cm->color[0],cm->color[1],cm->color[2]));
+ glColor3v(cm->color);
+
+
+ vector<Vector3r>& triangles = SF[shapeId].triangles; //mc.getTriangles();
+ int nbTriangles = SF[shapeId].nbTriangles; // //mc.getNbTriangles();
+ vector<Vector3r>& normals = SF[shapeId].normals; //mc.getNormals();
+
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING); // 2D
+ glEnable(GL_NORMALIZE);
+ glBegin(GL_TRIANGLES);
+
+ for(int i=0;i<3*nbTriangles;++i)
+ {
+ glNormal3v(normals[i]);
+ glVertex3v(triangles[i]);
+ glNormal3v(normals[++i]);
+ glVertex3v(triangles[i]);
+ glNormal3v(normals[++i]);
+ glVertex3v(triangles[i]);
+ }
+ glEnd();
+
+
+ return;
+
+}
+
+
+
+double Gl1_PotentialParticle::evaluateF(const shared_ptr<Shape>& cm, double x, double y, double z){
+
+ PotentialParticle* pp = static_cast<PotentialParticle*>(cm.get());
+ Real k = pp->k;
+ Real r = pp->r;
+ Real R = pp->R;
+
+
+ int planeNo = pp->a.size();
+
+ vector<double>a; vector<double>b; vector<double>c; vector<double>d; vector<double>p; Real pSum3 = 0.0;
+ for (int i=0; i<planeNo; i++){
+ a.push_back(pp->a[i]);
+ b.push_back(pp->b[i]);
+ c.push_back(pp->c[i]);
+ d.push_back(pp->d[i]);
+ Real plane = a[i]*x + b[i]*y + c[i]*z - d[i]; if (plane<pow(10,-15)){plane = 0.0;}
+ p.push_back(plane);
+ pSum3 += pow(p[i],2);
+ }
+
+
+ Real sphere = ( pow(x,2) + pow(y,2) + pow(z,2) ) ;
+ Real f = (1.0-k)*(pSum3/pow(r,2) - 1.0)+k*(sphere/pow(R,2)-1.0);
+
+ return f;
+
+}
+#endif
+
+ImpFunc * ImpFunc::New()
+{
+ // Skip factory stuff - create class
+ return new ImpFunc;
+}
+
+
+// Create the function
+ImpFunc::ImpFunc()
+{
+ clump = false;
+ // Initialize members here if you need
+}
+
+ImpFunc::~ImpFunc()
+{
+ // Initialize members here if you need
+}
+
+// Evaluate function
+double ImpFunc::FunctionValue(double x[3])
+{
+ int planeNo = a.size();
+ vector<double>p; double pSum2 = 0.0;
+ if(clump==false){
+ Eigen::Vector3d xori(x[0],x[1],x[2]);
+ Eigen::Vector3d xlocal = rotationMatrix*xori;
+ xlocal[0] = rotationMatrix(0,0)*x[0] + rotationMatrix(0,1)*x[1] + rotationMatrix(0,2)*x[2];
+ xlocal[1] = rotationMatrix(1,0)*x[0] + rotationMatrix(1,1)*x[1] + rotationMatrix(1,2)*x[2];
+ xlocal[2] = rotationMatrix(2,0)*x[0] + rotationMatrix(2,1)*x[1] + rotationMatrix(2,2)*x[2];
+ //std::cout<<"rotationMatrix: "<<endl<<rotationMatrix<<endl;
+ //x[0]=xlocal[0]; x[1]=xlocal[1]; x[2]=xlocal[2];
+
+ for (int i=0; i<planeNo; i++){
+ double plane = a[i]*xlocal[0] + b[i]*xlocal[1] + c[i]*xlocal[2] - d[i]; if (plane<pow(10,-15)){plane = 0.0;}
+ p.push_back(plane);
+ pSum2 += pow(p[i],2);
+ }
+ double sphere = ( pow(xlocal[0],2) + pow(xlocal[1],2) + pow(xlocal[2],2) ) ;
+ // Real f = (1.0-k)*(pSum2/pow(r,2) - 1.0)+k*(sphere/pow(R,2)-1.0);
+ Real f = (pSum2 - pow(r,2) );
+ return f;
+ }else if(clump==true){
+
+ Eigen::Vector3d xori(x[0],x[1],x[2]);
+ Eigen::Vector3d clumpMemberCentre(clumpMemberCentreX,clumpMemberCentreY,clumpMemberCentreZ);
+ Eigen::Vector3d xlocal = xori-clumpMemberCentre;
+ //xlocal[0] = rotationMatrix[0]*x[0] + rotationMatrix[3]*x[1] + rotationMatrix[6]*x[2];
+ //xlocal[1] = rotationMatrix[1]*x[0] + rotationMatrix[4]*x[1] + rotationMatrix[7]*x[2];
+ //xlocal[2] = rotationMatrix[2]*x[0] + rotationMatrix[5]*x[1] + rotationMatrix[8]*x[2];
+ //std::cout<<"rotationMatrix: "<<endl<<rotationMatrix<<endl;
+ //x[0]=xlocal[0]; x[1]=xlocal[1]; x[2]=xlocal[2];
+
+ for (int i=0; i<planeNo; i++){
+ double plane = a[i]*xlocal[0] + b[i]*xlocal[1] + c[i]*xlocal[2] - d[i]; if (plane<pow(10,-15)){plane = 0.0;}
+ p.push_back(plane);
+ pSum2 += pow(p[i],2);
+ }
+ //double sphere = ( pow(xlocal[0],2) + pow(xlocal[1],2) + pow(xlocal[2],2) ) ;
+ // Real f = (1.0-k)*(pSum2/pow(r,2) - 1.0)+k*(sphere/pow(R,2)-1.0);
+ Real f = (pSum2 - 1.2*pow(r,2) );
+ return f;
+ // return 0;
+ }
+ // the value of the function
+}
+
+
+
+
+
+void PotentialParticleVTKRecorder::action(){
+ if(fileName.size()==0) return;
+ vtkSmartPointer<vtkPoints> pbPos = vtkSmartPointer<vtkPoints>::New();
+ vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
+ vtkSmartPointer<vtkAppendPolyData> appendFilterID = vtkSmartPointer<vtkAppendPolyData>::New();
+ //vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
+ //vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
+
+ // interactions ###############################################
+ vtkSmartPointer<vtkPoints> intrBodyPos = vtkSmartPointer<vtkPoints>::New();
+ vtkSmartPointer<vtkCellArray> intrCells = vtkSmartPointer<vtkCellArray>::New();
+ vtkSmartPointer<vtkFloatArray> intrForceN = vtkSmartPointer<vtkFloatArray>::New();
+ intrForceN->SetNumberOfComponents(3);
+ intrForceN->SetName("forceN");
+ vtkSmartPointer<vtkFloatArray> intrAbsForceT = vtkSmartPointer<vtkFloatArray>::New();
+ intrAbsForceT->SetNumberOfComponents(1);
+ intrAbsForceT->SetName("absForceT");
+ // interactions ###############################################
+
+ // interaction contact point ###############################################
+ vtkSmartPointer<vtkPoints> pbContactPoint = vtkSmartPointer<vtkPoints>::New();
+ vtkSmartPointer<vtkCellArray> pbCellsContact = vtkSmartPointer<vtkCellArray>::New();
+ vtkSmartPointer<vtkFloatArray> pbNormalForce = vtkSmartPointer<vtkFloatArray>::New();
+ pbNormalForce->SetNumberOfComponents(3);
+ pbNormalForce->SetName("normalForce"); //Linear velocity in Vector3 form
+ vtkSmartPointer<vtkFloatArray> pbShearForce = vtkSmartPointer<vtkFloatArray>::New();
+ pbShearForce->SetNumberOfComponents(3);
+ pbShearForce->SetName("shearForce"); //Angular velocity in Vector3 form
+ // interactions contact point###############################################
+
+
+ // velocity ###################################################
+ vtkSmartPointer<vtkCellArray> pbCells = vtkSmartPointer<vtkCellArray>::New();
+ vtkSmartPointer<vtkFloatArray> pbLinVelVec = vtkSmartPointer<vtkFloatArray>::New();
+ pbLinVelVec->SetNumberOfComponents(3);
+ pbLinVelVec->SetName("linVelVec"); //Linear velocity in Vector3 form
+
+ vtkSmartPointer<vtkFloatArray> pbLinVelLen = vtkSmartPointer<vtkFloatArray>::New();
+ pbLinVelLen->SetNumberOfComponents(1);
+ pbLinVelLen->SetName("linVelLen"); //Length (magnitude) of linear velocity
+
+ vtkSmartPointer<vtkFloatArray> pbAngVelVec = vtkSmartPointer<vtkFloatArray>::New();
+ pbAngVelVec->SetNumberOfComponents(3);
+ pbAngVelVec->SetName("angVelVec"); //Angular velocity in Vector3 form
+
+ vtkSmartPointer<vtkFloatArray> pbAngVelLen = vtkSmartPointer<vtkFloatArray>::New();
+ pbAngVelLen->SetNumberOfComponents(1);
+ pbAngVelLen->SetName("angVelLen"); //Length (magnitude) of angular velocity
+ // velocity ####################################################
+
+ // bodyId ##############################################################
+ //#if 0
+ vtkSmartPointer<vtkPoints> pbPosID = vtkSmartPointer<vtkPoints>::New();
+ vtkSmartPointer<vtkCellArray> pbIdCells = vtkSmartPointer<vtkCellArray>::New();
+ vtkSmartPointer<vtkIntArray> blockId = vtkSmartPointer<vtkIntArray>::New();
+ blockId->SetNumberOfComponents(1);
+ blockId->SetName("id");
+ // bodyId ##############################################################
+ //#endif
+ int countID = 0;
+ vtkSmartPointer<vtkVectorText> textArray2[scene->bodies->size()];
+ vtkSmartPointer<vtkPolyDataMapper> txtMapper[scene->bodies->size()];
+ vtkSmartPointer<vtkLinearExtrusionFilter> extrude[scene->bodies->size()];
+ vtkSmartPointer<vtkActor> textActor[scene->bodies->size()];
+
+
+ FOREACH(const shared_ptr<Body>& b, *scene->bodies){
+ if (!b) continue;
+ if (b->isClump() == true) continue;
+ const PotentialParticle* pb=dynamic_cast<PotentialParticle*>(b->shape.get());
+ if(!pb) continue;
+
+ if(REC_ID==true){
+ //#if 0
+ blockId->InsertNextValue(b->getId());
+ vtkIdType pid[1];
+ Vector3r pos(b->state->pos);
+ pid[0] = pbPosID->InsertNextPoint(pos[0], pos[1], pos[2]);
+ pbIdCells->InsertNextCell(1,pid);
+ //#endif
+
+ countID++;
+ }
+ //vtkSmartPointer<ImpFunc> function = ImpFunc::New();
+ function->a = pb->a; function->b = pb->b; function->c = pb->c; function->d = pb->d; function->R = pb->R; function->r = pb->r; function->k = pb->k; Eigen::Matrix3d directionCos = b->state->ori.conjugate().toRotationMatrix(); int count = 0;
+ for (int i=0; i<3; i++){
+ for (int j=0; j<3; j++){
+ //function->rotationMatrix[count] = directionCos(j,i);
+ function->rotationMatrix(i,j) = directionCos(j,i);
+ count++;
+ }
+ }
+
+
+ vtkSmartPointer<vtkSampleFunction> sample = vtkSampleFunction::New();
+ sample->SetImplicitFunction(function);
+ double value = 1.05*pb->R;
+
+
+ //double xmin = -pb->halfSize.x(); double xmax = pb->halfSize.x(); double ymin = -pb->halfSize.y(); double ymax=pb->halfSize.y(); double zmin=-pb->halfSize.z(); double zmax=pb->halfSize.z();
+ //double xmin = -value; double xmax = value; double ymin = -value; double ymax=value; double zmin=-value; double zmax=value;
+ double xmin = -std::max(pb->minAabb.x(),pb->maxAabb.x()); double xmax = -xmin; double ymin = -std::max(pb->minAabb.y(),pb->maxAabb.y()); double ymax=-ymin; double zmin=-std::max(pb->minAabb.z(),pb->maxAabb.z()); double zmax=-zmin;
+ if(twoDimension==true){
+ ymax = 0.0;
+ ymin = 0.0;
+ }
+ sample->SetModelBounds(xmin, xmax, ymin, ymax, zmin, zmax);
+ //sample->SetModelBounds(pb->minAabb.x(), pb->maxAabb.x(), pb->minAabb.y(), pb->maxAabb.y(), pb->minAabb.z(), pb->maxAabb.z());
+ int sampleXno = sampleX; int sampleYno = sampleY; int sampleZno = sampleZ;
+ if(fabs(xmax-xmin)/static_cast<double>(sampleX) > maxDimension) { sampleXno = static_cast<int>(fabs(xmax-xmin)/maxDimension); }
+ if(fabs(ymax-ymin)/static_cast<double>(sampleY) > maxDimension) { sampleYno = static_cast<int>(fabs(ymax-ymin)/maxDimension); }
+ if(fabs(zmax-zmin)/static_cast<double>(sampleZ) > maxDimension) { sampleZno = static_cast<int>(fabs(zmax-zmin)/maxDimension); }
+ if(twoDimension==true){sampleYno=1;}
+ sample->SetSampleDimensions(sampleXno,sampleYno,sampleZno);
+ sample->ComputeNormalsOff();
+ //sample->Update();
+ vtkSmartPointer<vtkContourFilter> contours = vtkContourFilter::New();
+ contours->SetInput(sample->GetOutput());
+ contours->SetNumberOfContours(1);
+ contours->SetValue(0,0.0);
+ vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
+ contours->Update();
+ polydata->DeepCopy(contours->GetOutput());
+ //polydata->Update();
+
+ vtkSmartPointer<vtkUnsignedCharArray> pbColors = vtkSmartPointer<vtkUnsignedCharArray>::New();
+ pbColors->SetName("pbColors");
+ pbColors->SetNumberOfComponents(3);
+ Vector3r color = pb->color; //Vector3r(0,100,0);
+ if (b->isDynamic() == false){ color = Vector3r(157,157,157); }
+ unsigned char c[3]; //c = {color[0],color[1],color[2]};
+ c[0]=color[0];
+ c[1]=color[1];
+ c[2]=color[2];
+ int nbCells=polydata->GetNumberOfPoints();
+ for (int i=0;i<nbCells;i++){
+ pbColors->InsertNextTupleValue(c);
+ }
+ polydata->GetPointData()->SetScalars(pbColors);
+ //polydata->Update();
+
+
+
+
+ Vector3r centre (b->state->pos[0], b->state->pos[1], b->state->pos[2]);
+ Quaternionr orientation= b->state->ori; orientation.normalize();
+ AngleAxisr aa(orientation); Vector3r axis = aa.axis(); /* axis.normalize(); */ double angle = aa.angle()/3.14159*180.0; double xAxis = axis[0]; double yAxis = axis[1]; double zAxis = axis[2];
+ vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
+ transformFilter->SetInput( polydata );
+ vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
+
+ transformFilter->SetTransform( transform );
+ transform->PostMultiply();
+
+ transform->Translate (centre[0], centre[1],centre[2]);
+ //transform->RotateWXYZ(angle,xAxis, yAxis, zAxis);
+ //transformFilter->Update();
+ appendFilter->AddInputConnection(transformFilter-> GetOutputPort());
+
+
+ // ################## velocity ####################
+ if(REC_VELOCITY == true){
+ vtkIdType pid[1];
+ Vector3r pos(b->state->pos);
+ pid[0] = pbPos->InsertNextPoint(pos[0], pos[1], pos[2]);
+ pbCells->InsertNextCell(1,pid);
+ const Vector3r& vel = b->state->vel;
+ float v[3]; //v = { vel[0],vel[1],vel[2] };
+ v[0]=vel[0];
+ v[1]=vel[1];
+ v[2]=vel[2];
+ pbLinVelVec->InsertNextTupleValue(v);
+ pbLinVelLen->InsertNextValue(vel.norm());
+ const Vector3r& angVel = b->state->angVel;
+ float av[3]; //av = { angVel[0],angVel[1],angVel[2] };
+ av[0]=angVel[0];
+ av[1]=angVel[1];
+ av[2]=angVel[2];
+ pbAngVelVec->InsertNextTupleValue(av);
+ pbAngVelLen->InsertNextValue(angVel.norm());
+ }
+ // ################ velocity ###########################
+ polydata->DeleteCells();
+ sample->Delete();
+ contours->Delete();
+ //function->Delete();
+ sample = NULL;
+ contours = NULL;
+ }
+
+ if(REC_VELOCITY == true){
+ vtkSmartPointer<vtkUnstructuredGrid> pbUg = vtkSmartPointer<vtkUnstructuredGrid>::New();
+ pbUg->SetPoints(pbPos);
+ pbUg->SetCells(VTK_VERTEX, pbCells);
+ pbUg->GetPointData()->AddArray(pbLinVelVec);
+ pbUg->GetPointData()->AddArray(pbAngVelVec);
+ pbUg->GetPointData()->AddArray(pbLinVelLen);
+ pbUg->GetPointData()->AddArray(pbAngVelLen);
+ vtkSmartPointer<vtkXMLUnstructuredGridWriter> writerA = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
+ writerA->SetDataModeToAscii();
+ string fv=fileName+"vel."+std::to_string(scene->iter)+".vtu";
+ writerA->SetFileName(fv.c_str());
+ writerA->SetInput(pbUg);
+ writerA->Write();
+ //writerA->Delete();
+ //pbUg->Delete();
+ }
+
+ //###################### bodyId ###############################
+ if(REC_ID == true){
+ #if 0
+ vtkSmartPointer<vtkXMLPolyDataWriter> writerA = vtkXMLPolyDataWriter::New();
+ writerA->SetDataModeToAscii();
+ string fn=fileName+"-Id."+std::to_string(scene->iter)+".vtp";
+ writerA->SetFileName(fn.c_str());
+ writerA->SetInputConnection(appendFilterID->GetOutputPort());//(extrude->GetOutputPort());
+ writerA->Write();
+
+ writerA->Delete();
+ #endif
+ //#if 0
+ vtkSmartPointer<vtkUnstructuredGrid> pbUg = vtkSmartPointer<vtkUnstructuredGrid>::New();
+ pbUg->SetPoints(pbPosID);
+ pbUg->SetCells(VTK_VERTEX, pbIdCells);
+ pbUg->GetPointData()->AddArray(blockId);
+ vtkSmartPointer<vtkXMLUnstructuredGridWriter> writerA = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
+ writerA->SetDataModeToAscii();
+ string fv=fileName+"Id."+std::to_string(scene->iter)+".vtu";
+ writerA->SetFileName(fv.c_str());
+ writerA->SetInput(pbUg);
+ writerA->Write();
+ //writerA->Delete();
+ //pbUg->Delete();
+ //#endif
+ }
+
+
+//#if 0
+ // ################## contact point ####################
+ if(REC_INTERACTION == true){
+ int count = 0;
+ FOREACH(const shared_ptr<Interaction>& I, *scene->interactions){
+ if(!I->isReal()) {
+ continue;
+ }
+ const KnKsPhys* phys = YADE_CAST<KnKsPhys*>(I->phys.get());
+ const ScGeom* geom = YADE_CAST<ScGeom*>(I->geom.get());
+ vtkIdType pid[1];
+ Vector3r pos(geom->contactPoint);
+ pid[0] = pbContactPoint->InsertNextPoint(pos[0], pos[1], pos[2]);
+ pbCellsContact->InsertNextCell(1,pid);
+ //intrBodyPos->InsertNextPoint(geom->contactPoint[0],geom->contactPoint[1],geom->contactPoint[2]);
+ // gives _signed_ scalar of normal force, following the convention used in the respective constitutive law
+ float fn[3]={phys->normalForce[0],phys->normalForce[1], phys->normalForce[2]};
+ float fs[3]={phys->shearForce[0], phys->shearForce[1], phys->shearForce[2]};
+ pbNormalForce->InsertNextTupleValue(fn);
+ pbShearForce->InsertNextTupleValue(fs);
+ count++;
+ }
+ if(count>0){
+ vtkSmartPointer<vtkUnstructuredGrid> pbUgCP = vtkSmartPointer<vtkUnstructuredGrid>::New();
+ pbUgCP->SetPoints(pbContactPoint);
+ pbUgCP->SetCells(VTK_VERTEX, pbCellsContact);
+ pbUgCP->GetPointData()->AddArray(pbNormalForce);
+ pbUgCP->GetPointData()->AddArray(pbShearForce);
+ vtkSmartPointer<vtkXMLUnstructuredGridWriter> writerB = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
+ writerB->SetDataModeToAscii();
+ string fcontact=fileName+"contactPoint."+std::to_string(scene->iter)+".vtu";
+ writerB->SetFileName(fcontact.c_str());
+ writerB->SetInput(pbUgCP);
+ writerB->Write();
+ //writerB->Delete();
+ //pbUgCP->Delete();
+ }
+ }
+//#endif
+
+
+ // ################ contact point ###########################
+
+
+
+
+ vtkSmartPointer<vtkXMLPolyDataWriter> writer = vtkXMLPolyDataWriter::New();
+ writer->SetDataModeToAscii();
+ string fn=fileName+"-pb."+std::to_string(scene->iter)+".vtp";
+ writer->SetFileName(fn.c_str());
+ writer->SetInputConnection(appendFilter->GetOutputPort());
+ writer->Write();
+
+ writer->Delete();
+
+ //intrBodyPos->Delete();
+ //intrForceN->Delete();
+ //intrAbsForceT->Delete();
+ //pbContactPoint->Delete();
+ //pbCellsContact->Delete();
+ //pbNormalForce->Delete();
+ //pbShearForce->Delete();
+ //pbCells->Delete();
+ //pbLinVelVec->Delete();
+ //pbLinVelLen->Delete();
+ //pbAngVelVec->Delete();
+ //pbAngVelLen->Delete();
+
+}
+
+YADE_PLUGIN(/*(Gl1_PotentialParticle)*/(PotentialParticleVTKRecorder));
+
+
+//YADE_REQUIRE_FEATURE(OPENGL)
+
+
+
+
+
+
+
+
+
+
=== added file 'pkg/common/Gl1_PotentialParticle.hpp'
--- pkg/common/Gl1_PotentialParticle.hpp 1970-01-01 00:00:00 +0000
+++ pkg/common/Gl1_PotentialParticle.hpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,172 @@
+/*CWBoon 2015 */
+#pragma once
+#include<pkg/dem/PotentialParticle.hpp>
+#include<pkg/dem/PotentialParticle2AABB.hpp>
+#include<pkg/common/GLDrawFunctors.hpp>
+//#include<pkg/dem/MarchingCube.hpp>
+#include <vector>
+#include <pkg/common/PeriodicEngines.hpp>
+
+#include<vtkImplicitFunction.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderer.h>
+#include <vtkPolyData.h>
+
+#include<vtkXMLUnstructuredGridWriter.h>
+#include<vtkTriangle.h>
+#include<vtkSmartPointer.h>
+#include<vtkFloatArray.h>
+#include<vtkCellArray.h>
+#include<vtkCellData.h>
+#include <vtkSampleFunction.h>
+#include <vtkStructuredPoints.h>
+#include<vtkStructuredPointsWriter.h>
+#include<vtkWriter.h>
+#include<vtkExtractVOI.h>
+#include<vtkXMLImageDataWriter.h>
+#include<vtkXMLStructuredGridWriter.h>
+#include<vtkTransformPolyDataFilter.h>
+#include<vtkTransform.h>
+#include <vtkRenderWindowInteractor.h>
+#include<vtkXMLUnstructuredGridWriter.h>
+#include <vtkActor.h>
+#include <vtkAppendPolyData.h>
+
+#include <vtkTextActor.h>
+#include <vtkTextProperty.h>
+#include <vtkVectorText.h>
+#include <vtkLinearExtrusionFilter.h>
+#include <vtkTextActor3D.h>
+#include <vtkCylinderSource.h>
+
+
+
+class ImpFunc : public vtkImplicitFunction {
+public:
+ vtkTypeMacro(ImpFunc,vtkImplicitFunction);
+ //void PrintSelf(ostream& os, vtkIndent indent);
+
+ // Description
+ // Create a new function
+ static ImpFunc * New(void);
+ vector<double>a; vector<double>b; vector<double>c; vector<double>d;
+ double k; double r; double R; Eigen::Matrix3d rotationMatrix;
+ bool clump;
+ double clumpMemberCentreX;
+ double clumpMemberCentreY;
+ double clumpMemberCentreZ;
+ // Description
+ // Evaluate function
+ double FunctionValue(double x[3]);
+ double EvaluateFunction(double x[3]){
+ //return this->vtkImplicitFunction::EvaluateFunction(x);
+ return FunctionValue(x);
+ };
+
+ double EvaluateFunction(double x, double y, double z) {
+ return this->vtkImplicitFunction::EvaluateFunction(x, y, z);
+ };
+
+
+
+
+ // Description
+ // Evaluate gradient for function
+ void EvaluateGradient(double x[3], double n[3]){ };
+
+ // If you need to set parameters, add methods here
+
+protected:
+ ImpFunc();
+ ~ImpFunc();
+ ImpFunc(const ImpFunc&) {}
+ void operator=(const ImpFunc&) {}
+
+ // Add parameters/members here if you need
+};
+
+#if 0
+class Gl1_PotentialParticle : public GlShapeFunctor
+{
+ private :
+ MarchingCube mc;
+ Vector3r min,max;
+ vector<vector<vector<float > > > scalarField,weights;
+ void generateScalarField(const shared_ptr<Shape>& cm);
+ void calcMinMax(const shared_ptr<Shape>& cm);
+ float oldIsoValue,oldIsoSec,oldIsoThick;
+ Vector3r isoStep;
+
+
+
+ public :
+ struct Leaf{
+ Vector3r centre;
+ Leaf(Vector3r pos){centre = pos;}
+ Leaf(){centre = Vector3r(0,0,0);}
+ };
+ struct scalarF{
+ vector<vector<vector<float > > > scalarField2;
+ vector<Vector3r> triangles;
+ vector<Vector3r> normals;
+ int nbTriangles;
+ };
+ virtual void go(const shared_ptr<Shape>&, const shared_ptr<State>&,bool,const GLViewInfo&);
+ double evaluateF(const shared_ptr<Shape>& cm, double x, double y, double z);
+ static vector<scalarF> SF ;
+ void clearMemory();
+ RENDERS(PotentialParticle);
+ //YADE_CLASS_BASE_DOC_STATICATTRS(Gl1_PotentialParticle,GlShapeFunctor,"Renders :yref:`Sphere` object",
+ //(( vector<scalarF>, SF ," "))
+ //);
+ YADE_CLASS_BASE_DOC_STATICATTRS(Gl1_PotentialParticle,GlShapeFunctor,"Renders :yref:`Sphere` object",
+ ((int,sizeX,80,,"Number of divisions in the x direction for triangulation"))
+ ((int,sizeY,80,,"Number of divisions in the x direction for triangulation"))
+ ((int,sizeZ,80,,"Number of divisions in the y direction for triangulation"))
+ ((bool,store,false,,"Number of divisions in the z direction for triangulation"))
+ ((bool,initialized,false,,"Number of divisions in the z direction for triangulation"))
+
+ );
+
+
+
+};
+REGISTER_SERIALIZABLE(Gl1_PotentialParticle);
+
+
+#endif
+
+
+class PotentialParticleVTKRecorder: public PeriodicEngine{
+ public:
+ vtkSmartPointer<ImpFunc> function;
+
+ virtual void action(void);
+ YADE_CLASS_BASE_DOC_ATTRS_CTOR_PY(PotentialParticleVTKRecorder,PeriodicEngine,"Engine recording potential blocks as surfaces into files with given periodicity.",
+ ((string,fileName,,,"File prefix to save to"))
+ ((int,sampleX,30,,"size of contact point"))
+ ((int,sampleY,30,,"size of contact point"))
+ ((int,sampleZ,30,,"size of contact point"))
+ ((double,maxDimension,30,,"size of contact point"))
+ ((bool,twoDimension,false,,"size of contact point"))
+ ((bool,REC_INTERACTION,false,,"contact point and forces"))
+ ((bool,REC_COLORS,false,,"colors"))
+ ((bool,REC_VELOCITY,false,,"velocity"))
+ ((bool,REC_ID,true,,"id"))
+ ,
+ function = ImpFunc::New();
+ ,
+
+ );
+};
+REGISTER_SERIALIZABLE(PotentialParticleVTKRecorder);
+
+
+
+
+
+
+
+
+
+
=== added file 'pkg/dem/Ig2_PP_PP_ScGeom.cpp'
--- pkg/dem/Ig2_PP_PP_ScGeom.cpp 1970-01-01 00:00:00 +0000
+++ pkg/dem/Ig2_PP_PP_ScGeom.cpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,1713 @@
+/*CWBoon 2015 */
+/* C.W. Boon, G.T. Houlsby, S. Utili (2013). A new contact detection algorithm for three-dimensional non-spherical particles. Powder Technology, 248, pp 94-102. */
+/* code for calling MOSEK was for ver 6. Please uncomment if you have the licence */
+
+#include"Ig2_PP_PP_ScGeom.hpp"
+#include<pkg/dem/ScGeom.hpp>
+#include<pkg/dem/PotentialParticle.hpp>
+//#include<yade/lib-base/yadeWm3Extra.hpp>
+#include<pkg/dem/KnKsLaw.hpp>
+
+#include<core/Scene.hpp>
+#include<lib/base/Math.hpp>
+#include<pkg/common/InteractionLoop.hpp>
+#include<core/Omega.hpp>
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+
+#include<Eigen/Core>
+#include <Eigen/LU>
+#include <Eigen/QR>
+
+#include <ctime>
+#include <cstdlib>
+
+
+
+
+
+YADE_PLUGIN((Ig2_PP_PP_ScGeom)
+//#ifdef YADE_OPENGL
+// (Gl1_Ig2_PP_PP_ScGeom)
+// #endif
+);
+
+
+CREATE_LOGGER(Ig2_PP_PP_ScGeom);
+
+
+bool Ig2_PP_PP_ScGeom::go(const shared_ptr<Shape>& cm1,const shared_ptr<Shape>& cm2,const State& state1, const State& state2, const Vector3r& shift2, const bool& force,const shared_ptr<Interaction>& c)
+{
+
+
+ PotentialParticle *s1=static_cast<PotentialParticle*>(cm1.get());
+ PotentialParticle *s2=static_cast<PotentialParticle*>(cm2.get());
+
+ /* Short circuit if both particles are boundary particles */
+ if((s1->isBoundary==true)&&(s2->isBoundary==true)) {return false;}
+
+
+ bool hasGeom = false;
+ Vector3r contactPt(0,0,0);
+ shared_ptr<ScGeom> scm;
+ shared_ptr<KnKsPhys> phys;
+
+
+ double stepBisection = 0.001*std::min(s1->R,s2->R); if(stepBisection<pow(10,-6)){std::cout<<"R1: "<<s1->R<<", R2: "<<s2->R<<", stepBisection: "<<stepBisection<<", id1: "<<c->getId1()<<", id2: "<<c->getId2()<<endl;}
+
+ bool contact = false;
+
+ Real fA = 0.0;
+ Real fB = 0.0;
+ Vector3r normalP1(0.0,0.0,0.0);
+ Vector3r normalP2(0.0,0.0,0.0);
+ Vector3r avgNormal(0.0,0.0,0.0);
+ Vector3r ptOnP1(0.0,0.0,0.0);
+ Vector3r ptOnP2(0.0,0.0,0.0);
+ bool converge = false;
+
+
+ if(c->geom){
+ hasGeom = true;
+ scm=YADE_PTR_CAST<ScGeom>(c->geom);
+ if (scm->penetrationDepth>stepBisection ){ stepBisection = 0.5*scm->penetrationDepth;}
+ if(stepBisection<pow(10,-6)){std::cout<<"stepBisection: "<<stepBisection<<", penetrationDepth: "<<scm->penetrationDepth<<endl;}
+ contactPt = scm->contactPoint;
+ }else{
+ scm=shared_ptr<ScGeom>(new ScGeom());
+ c->geom=scm;
+ contactPt = 0.5*(state1.pos+state2.pos);
+
+ }
+
+ bool hasPhys=false;
+ if(c->phys){
+ phys=YADE_PTR_CAST<KnKsPhys>(c->phys); hasPhys=true;
+ }
+
+
+ converge = true;
+ fA= evaluatePP(cm1,state1, contactPt);
+ fB = evaluatePP(cm2,state2, contactPt);
+
+//Default does not have warmstart
+ //if(fA < 0.0 && fB <0.0){
+ // converge = customSolve(cm1,state1,cm2,state2,contactPt,true);
+ //}else{
+ converge = customSolve(cm1,state1,cm2,state2,contactPt,false);
+ //}
+
+
+// if you have mosek uncomment this. Mosek is more robust but slightly slower as an external library
+#if 0
+ /* Mosek */
+ if( converge==false ){
+ //std::cout<<"mosek used"<<endl;
+ contactPt = 0.5*(state1.pos+state2.pos);
+ contactPtMosekF2(cm1, state1, cm2, state2, contactPt);
+ }
+#endif
+
+
+
+
+ fA= evaluatePP(cm1,state1, contactPt);
+ fB = evaluatePP(cm2,state2, contactPt);
+
+if (fA*fB<0.0){
+std::cout<<"fA: "<<fA<<", fB: "<<fB<<endl;
+}
+
+//std::cout<<"converge: "<<converge<<", fA: "<<fA<<", fB: "<<fB<<endl;
+
+ //timingDeltas->start();
+
+ if (fA < 0.0 && fB < 0.0 && converge == true){
+ contact = true;
+ }else{
+ contact = false; contactPt = 0.5*(state1.pos+state2.pos);
+ }
+ //////////////////////////////////////////////////////////* PASS VARIABLES TO ScGeom and Phys Functor */////////////////////////////////////////////////////////////
+ //* 1. Get overlap *//
+ //* 2. Get information on active planes. If active planes are not the same as the previous, get new physical parameters. Otherwise keep the same parameters *//
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ if (contact == true || c->isReal() || force){
+ if (contact == true){
+ normalP1 = getNormal(cm1,state1,contactPt); normalP1.normalize();
+ normalP2 = getNormal(cm2,state2,contactPt); normalP2.normalize();
+ //if(s1->isBoundary==true){avgNormal=normalP1;}else if(s2->isBoundary==true){avgNormal=-normalP2;}else{avgNormal = (normalP1 - normalP2);}
+#if 0
+ if(s1->isBoundary==true){avgNormal=normalP1;}else if(s2->isBoundary==true){avgNormal=-normalP2;}else{
+
+ avgNormal = (normalP1 - normalP2);
+
+
+ }
+#endif
+ avgNormal = (normalP1 - normalP2);
+ avgNormal.normalize();
+
+ if(hasPhys == true){
+ bool calJointLength = phys->calJointLength; int smallerID = 1; bool twoD = phys->twoDimension;
+ if (twoD == true){phys->jointLength = 1.0;}
+ }
+ if(s1->fixedNormal==true){ avgNormal = s1->boundaryNormal;}
+ if(s2->fixedNormal==true){ avgNormal = -s2->boundaryNormal;}
+
+ Vector3r step = avgNormal*stepBisection;
+ int locationStuck = 2;
+ getPtOnParticle2(cm1,state1,contactPt, step, ptOnP1);
+ getPtOnParticle2(cm2,state2,contactPt, -1.0*step, ptOnP2);
+
+ vector<Vector3r> points;
+ Real penetrationDepth = (ptOnP2-ptOnP1).norm();// overlap;
+ //std::cout<<"contactpoint: "<<contactPt<<", penetrationDepth: "<<penetrationDepth<<", avgNormal: "<<avgNormal<<endl;
+
+ scm->precompute(state1,state2,scene,c,avgNormal,!(hasGeom),Vector3r(0,0,0)/*shift 2 */, false /* avoidGranularRatcheting */); //Assign contact point and normal after precompute!!!!
+ scm->contactPoint = contactPt; scm->penetrationDepth=penetrationDepth; if(isnan(avgNormal.norm())){std::cout<<"avgNormal: "<<avgNormal<<endl;}
+ scm->normal = avgNormal;
+
+
+
+ }else{
+
+ //scm->normal = Vector3r(0,0,0);
+ scm->precompute(state1,state2,scene,c,avgNormal,!(hasGeom),Vector3r(0,0,0)/*shift 2 */, false /* avoidGranularRatcheting */); //Assign contact point and normal after precompute!!!!
+ scm->contactPoint = contactPt;scm->penetrationDepth=-1.0; //scm->normal = Vector3r(0,0,0);
+ }
+
+ return true;
+ }else{
+ scm->contactPoint = contactPt;scm->penetrationDepth=-1.0;scm->normal = Vector3r(0,0,0);
+ return false;
+ }
+
+ return false;
+}
+
+
+
+void Ig2_PP_PP_ScGeom::BrentZeroSurf(const shared_ptr<Shape>& cm1, const State& state1, const Vector3r bracketA, const Vector3r bracketB, Vector3r& zero){
+
+ Real a = 0.0; Real b = 1.0;
+ Real t = pow(10,-16);
+ Real m = 0.0;
+ Real p = 0.0;
+ Real q = 0.0;
+ Real r = 0.0;
+ Real s = 0.0;
+ Real c = 0.0;
+ Real d = 0.0;
+ Real e = 0.0;
+ Vector3r bracketRange = bracketB- bracketA;
+ Real fa = evaluatePP(cm1,state1, bracketA); //evaluateFNoSphere(cm1,state1, bracketA); //
+
+ Real fb = evaluatePP(cm1,state1, bracketB); //evaluateFNoSphere(cm1,state1, bracketB); //
+
+ if(fa*fb > 0.00001){
+ std::cout<<"fa: "<<fa<<", fb: "<<fb<<endl;
+ }
+ //if(fabs(fa)<fabs(fb)){bracketRange *= -1.0; Vector3r temp = bracketA; bracketA= bracketB; bracketB = temp;}
+ Real fc = 0.0;
+
+ Real tol = 2.0*DBL_EPSILON*fabs(b) + t;
+ int counter = 0;
+ do {
+ if(counter == 0){
+ c = a; fc = fa; d = b-a; e = d;
+ if (fabs(fc) < fabs(fb) ){
+ a = b; b = c; c = a;
+ fa = fb; fb = fc; fc = fa;
+ }
+ }else{
+ if (fb*fc > 0.0){
+ c = a; fc = fa; d = b-a; e = d;
+ }
+ if(fabs(fc) < fabs(fb) ){
+ a = b; b = c; c = a;
+ fa = fb; fb = fc; fc = fa;
+ }
+ }
+ tol = 2.0*DBL_EPSILON*fabs(b) + t; m = 0.5*(c-b);
+ if (fabs(m) > tol && fabs(fb) > pow(10,-13) ){
+ if(fabs(e) < tol || fabs(fa) <= fabs(fb) ){
+ d = m;
+ e = d;
+ }else{
+ s = fb/fa;
+ if(fabs(a - c)<pow(10,-15)){
+ p = 2.0*m*s; q = 1.0 - s;
+ }else{
+ q = fa/fc; r = fb/fc;
+ p = s*(2.0*m*q*(q-r) - (b-a)*(r-1.0));
+ q = (q-1.0)*(r-1.0)*(s-1.0);
+ }
+
+ if (p > 0.0){
+ q = -q;
+ }else{
+ p = -p;
+ }
+
+ s = e; e = d;
+
+ if(( 2.0*p < (3.0*m*q - fabs(tol*q))) && (p < fabs(0.5*s*q)) ){
+ d = p/q;
+ }else{
+ d = m;
+ e = d;
+ }
+ }
+
+ a = b; fa = fb;
+ Real h = 0.0;
+ if(fabs(d) >tol){
+ h = d;
+ }else if(m > 0.0){
+ h = tol;
+ }else{
+ h = - tol;
+ }
+ b = b + h; // h*m_unitVec;
+
+ zero = bracketA + b*bracketRange;
+ fb = evaluatePP(cm1,state1, zero); //evaluateFNoSphere(cm1,state1, zero); //
+
+
+ }else{
+ zero = bracketA + b*bracketRange;
+ //std::cout<<"b: "<<b<<", m: "<<m<<", tol: "<<tol<<", c: "<<c<<", a: "<<a<<endl;
+ break;
+ }
+
+ counter++;
+ if(counter==10000){
+ std::cout<<"counter: "<<counter<<", m.norm: "<<m<<", fb: "<<fb<<endl;
+ }
+ }while(1);
+ //}while( m.norm() > tol && fabs(fb) > pow(10,-13) );
+
+}
+
+
+/* Routine to get value of function (constraint) at a particular position */
+double Ig2_PP_PP_ScGeom::evaluatePP(const shared_ptr<Shape>& cm1, const State& state1, const Vector3r newTrial){
+
+ PotentialParticle *s1=static_cast<PotentialParticle*>(cm1.get());
+ ///////////////////Transforming trial values to local frame of particles//////////////////
+ Vector3r tempP1 = newTrial - state1.pos;
+ /* Direction cosines */
+ //state1.ori.normalize();
+ Vector3r localP1 = state1.ori.conjugate()*tempP1;
+ Real x = localP1.x();
+ Real y = localP1.y();
+ Real z = localP1.z();
+ int planeNo = s1->a.size();
+ Real pSum2 = 0.0;
+ for (int i=0; i<planeNo; i++){
+ Real plane = s1->a[i]*x + s1->b[i]*y + s1->c[i]*z - s1->d[i]; if (plane<pow(10,-15)){plane = 0.0;}
+ pSum2 += pow(plane,2);
+ }
+ Real r = s1->r; Real R = s1->R; Real k = s1->k;
+ /* Additional sphere */
+ Real sphere = (pow(x,2) + pow(y,2) + pow(z,2))/pow(R,2);
+ /* Complete potential particle */
+ Real f = (1.0-k)*(pSum2/pow(r,2) - 1.0)+k*(sphere -1.0);
+ return f;
+}
+
+
+
+Vector3r Ig2_PP_PP_ScGeom::getNormal(const shared_ptr<Shape>& cm1, const State& state1, const Vector3r newTrial){
+
+ PotentialParticle *s1=static_cast<PotentialParticle*>(cm1.get());
+ ///////////////////Transforming trial values to local frame of particles//////////////////
+ Vector3r tempP1 = newTrial - state1.pos;
+
+ /* Direction cosines */
+ Vector3r localP1(0,0,0);
+ localP1 = state1.ori.conjugate()*tempP1; //the body has been rotated by state.ori. So I will need to rotate the frame by state.ori too
+ Real x = localP1[0];
+ Real y = localP1[1];
+ Real z = localP1[2];
+
+////////////////////////////// assembling potential planes particle 1//////////////////////////////
+ int planeNo = s1->a.size();
+ vector<double>p; Real pSum2 = 0.0;
+ for (int i=0; i<planeNo; i++){
+ Real plane = s1->a[i]*x + s1->b[i]*y + s1->c[i]*z -s1-> d[i]; if (plane<pow(10,-15)){plane = 0.0;}
+ p.push_back(plane);
+ pSum2 += pow(p[i],2);
+ }
+ Real r = s1->r; Real R = s1->R; Real k = s1->k;
+ /* Additional sphere */
+ Real sphere = (pow(x,2) + pow(y,2) + pow(z,2))/pow(R,2);
+ /* Complete potential particle */
+ Real f = (1.0-k)*(pSum2/pow(r,2)-1.0)+k*(sphere -1.0);
+
+ //////////////////////////////// local first derivitive particle 1 /////////////////////////////////////
+ Real pdxSum = 0.0; Real pdySum = 0.0; Real pdzSum = 0.0;
+ for (int i=0; i<planeNo; i++){
+ pdxSum += (s1->a[i]*p[i]);
+ pdySum += (s1->b[i]*p[i]);
+ pdzSum += (s1->c[i]*p[i]);
+ }
+
+ Real fdx = 2.0*(1.0-k) * pdxSum/pow(r,2) + 2.0*k*x/pow(R,2);
+ Real fdy = 2.0*(1.0-k) * pdySum/pow(r,2) + 2.0*k*y/pow(R,2);
+ Real fdz = 2.0*(1.0-k) * pdzSum/pow(r,2) + 2.0*k*z/pow(R,2);
+
+ ///////////////////// Assembling rotation matrix Qt for particle 1 //////////////////////////////
+ Matrix3r Q1=Eigen::Matrix3d::Zero();;
+ //if(state1.ori==Quaternionr(1,0,0,0)){
+ // Q1.setIdentity();
+ //}else{
+ Real q0 = state1.ori.w();
+ Real q1 = state1.ori.x();
+ Real q2 = state1.ori.y();
+ Real q3 = state1.ori.z();
+ Q1(0,0) = 2.0*pow(q0,2.0) -1.0 + 2.0*pow(q1,2.0);
+ Q1(0,1) = 2.0*q1*q2 + 2.0*q0*q3;
+ Q1(0,2) = 2.0*q1*q3 - 2.0*q0*q2;
+ Q1(1,0) = 2.0*q1*q2 - 2.0*q0*q3;
+ Q1(1,1) = 2.0*pow(q0,2.0) -1.0 + 2.0*pow(q2,2.0);
+ Q1(1,2) = 2.0*q2*q3 + 2.0*q0*q1;
+ Q1(2,0) = 2.0*q1*q3 + 2.0*q0*q2;
+ Q1(2,1) = 2.0*q2*q3 - 2.0*q0*q1;
+ Q1(2,2) = 2.0*pow(q0,2) -1.0 + 2.0*pow(q3,2.0);
+
+ //Matrix3r Q1n = state1.ori.toRotationMatrix();
+ //Matrix3r Q1c = state1.ori.conjugate().toRotationMatrix();
+ //std::cout<<"Q1: "<<endl<<Q1<<endl<<"Q1n: "<<endl<<Q1n<<endl<<"Q1c: "<<endl<<Q1c<<endl<<endl;
+ //}
+
+ ///////////////////// global first and second derivitive for particle 1 /////////////////////////
+ Real Fdx = fdx * Q1(0,0) + fdy*Q1(1,0) + fdz*Q1(2,0);
+ Real Fdy = fdx * Q1(0,1) + fdy*Q1(1,1) + fdz*Q1(2,1);
+ Real Fdz = fdx * Q1(0,2) + fdy*Q1(1,2) + fdz*Q1(2,2);
+
+ if (isnan(Fdx) == true || isnan(Fdy) == true || isnan(Fdz)==true){
+ std::cout<<"Q1(0,0): "<<Q1(0,0)<<","<<Q1(0,1)<<","<<Q1(0,2)<<","<<Q1(1,0)<<","<<Q1(1,1)<<","<<Q1(1,2)<<","<<Q1(2,0)<<","<<Q1(2,1)<<","<<Q1(2,2)<<", q:"<<q0<<","<<q1<<","<<q2<<","<<q3<<", fd: "<<fdx<<","<<fdy<<","<<fdz<<endl;
+ }
+
+ return Vector3r(Fdx,Fdy,Fdz);
+}
+
+
+
+#if 0
+bool Ig2_PP_PP_ScGeom::contactPtMosekF2(const shared_ptr<Shape>& cm1, const State& state1, const shared_ptr<Shape>& cm2, const State& state2, Vector3r &contactPt){
+
+ PotentialParticle *s1=static_cast<PotentialParticle*>(cm1.get());
+ PotentialParticle *s2=static_cast<PotentialParticle*>(cm2.get());
+ Vector3r xGlobal(0.0,0.0,0.0);
+
+
+/* Parameters for particles A and B */
+ double rA = s1->r;
+ double kA = s1->k;
+ double RA = s1->R;
+ double rB = s2->r;
+ double kB = s2->k;
+ double RB = s2->R;
+ int planeNoA = s1->a.size();
+ int planeNoB = s2->a.size();
+
+/* Variables to keep things neat */
+ double ksA = RA/sqrt(kA);
+ double kpA = rA/sqrt(1.0 - kA);
+ double ksB = RB/sqrt(kB);
+ double kpB = rB/sqrt(1.0 - kB);
+ int NUMCON = 3 + 1+ planeNoA + planeNoB;
+ int NUMVAR = 6 + 2 + planeNoA + planeNoB;
+
+/* LINEAR CONSTRAINTS */
+ MSKboundkeye bkc[NUMCON];
+ bkc[0] = MSK_BK_FX;
+ bkc[1] = MSK_BK_FX;
+ bkc[2] = MSK_BK_FX;
+ bkc[3] = MSK_BK_FX;
+ for(int i=0; i<planeNoA + planeNoB; i++ ){
+ bkc[4+i] = MSK_BK_UP;
+ };
+
+ double blc[NUMCON];
+ blc[0] = state2.pos.x() - state1.pos.x();
+ blc[1] = state2.pos.y() - state1.pos.y();
+ blc[2] = state2.pos.z() - state1.pos.z();
+ blc[3] = 0.0;
+ for(int i=0; i<planeNoA; i++ ){
+ blc[4+i] = -MSK_INFINITY;
+ };
+ for(int i=0; i<planeNoB; i++ ){
+ blc[4+planeNoA+i] = -MSK_INFINITY;
+ };
+
+ double buc[NUMCON];
+ buc[0] = state2.pos.x() - state1.pos.x();
+ buc[1] = state2.pos.y() - state1.pos.y();
+ buc[2] = state2.pos.z() - state1.pos.z();
+ buc[3] = 0.0;
+ for(int i=0; i<planeNoA; i++ ){
+ buc[4+i] = s1->d[i];
+ };
+ for(int i=0; i<planeNoB; i++ ){
+ buc[4+planeNoA+i] = s2->d[i];
+ };
+
+/* BOUNDS */
+ MSKboundkeye bkx[NUMVAR ];
+ bkx[0] = MSK_BK_FR;
+ bkx[1] = MSK_BK_FR;
+ bkx[2] = MSK_BK_FR;
+ bkx[3] = MSK_BK_FR;
+ bkx[4] = MSK_BK_FR;
+ bkx[5] = MSK_BK_FR;
+ bkx[6] = MSK_BK_FR;
+ bkx[7] = MSK_BK_FR;
+ for(int i=0; i<planeNoA + planeNoB; i++ ){
+ bkx[8+i] = MSK_BK_FR;
+ };
+
+
+ double blx[NUMVAR];
+ blx[0] = -MSK_INFINITY;
+ blx[1] = -MSK_INFINITY;
+ blx[2] = -MSK_INFINITY;
+ blx[3] = -MSK_INFINITY;
+ blx[4] = -MSK_INFINITY;
+ blx[5] = -MSK_INFINITY;
+ blx[6] = -MSK_INFINITY;
+ blx[7] = -MSK_INFINITY;
+ for(int i=0; i<planeNoA + planeNoB; i++ ){
+ blx[8+i] = -MSK_INFINITY;
+ };
+
+ double bux[NUMVAR];
+ bux[0] = +MSK_INFINITY;
+ bux[1] = +MSK_INFINITY;
+ bux[2] = +MSK_INFINITY;
+ bux[3] = +MSK_INFINITY;
+ bux[4] = +MSK_INFINITY;
+ bux[5] = +MSK_INFINITY;
+ bux[6] = +MSK_INFINITY;
+ bux[7] = +MSK_INFINITY;
+ for(int i=0; i<planeNoA + planeNoB; i++ ){
+ bux[8+i] = +MSK_INFINITY;
+ };
+
+ double c[NUMVAR];
+ c[0] = 0.0;
+ c[1] = 0.0;
+ c[2] = 0.0;
+ c[3] = 0.0;
+ c[4] = 0.0;
+ c[5] = 0.0;
+ c[6] = 1.0;
+ c[7] = 1.0;
+ for(int i=0; i<planeNoA + planeNoB; i++ ){
+ c[8+i] = 0.0;
+ };
+
+ vector<double> aval;
+ vector<MSKintt> aptrb;
+ vector<MSKintt> aptre;
+ vector<MSKidxt> asub;
+
+ Matrix3r Q1 = state1.ori.toRotationMatrix();
+ Matrix3r Q2 = state2.ori.toRotationMatrix();
+
+ int totalCount = 0;
+ /* column 0 xA*/
+ aptrb.push_back(0);
+ int count = 0;
+ if(fabs(Q1(0,0))>pow(10,-15) ){
+ aval.push_back(ksA*Q1(0,0)); asub.push_back(0); count++;
+ }
+ if(fabs(Q1(1,0) )>pow(10,-15) ){
+ aval.push_back(ksA*Q1(1,0)); asub.push_back(1); count++;
+ }
+ if(fabs(Q1(2,0) )>pow(10,-15) ){
+ aval.push_back(ksA*Q1(2,0)); asub.push_back(2); count++;
+ }
+ for(int i=0; i < planeNoA; i++){
+ if(fabs(s1->a[i]) > pow(10,-15) ){
+ aval.push_back(ksA*s1->a[i]); asub.push_back(4+i);
+ count++;
+ }
+ }
+ aptre.push_back(count);
+ totalCount += count;
+
+ /* column 1 yA*/
+ aptrb.push_back(aptre[0]);
+ count = 0;
+ if(fabs(Q1(0,1) )>pow(10,-15) ){
+ aval.push_back(ksA*Q1(0,1)); asub.push_back(0); count++;
+ }
+ if(fabs(Q1(1,1))>pow(10,-15) ){
+ aval.push_back(ksA*Q1(1,1)); asub.push_back(1); count++;
+ }
+ if(fabs(Q1(2,1) )>pow(10,-15) ){
+ aval.push_back(ksA*Q1(2,1)); asub.push_back(2); count++;
+ }
+ for(int i=0; i < planeNoA; i++){
+ if(fabs(s1->b[i]) > pow(10,-15) ){
+ aval.push_back(ksA*s1->b[i]); asub.push_back(4+i);
+ count++;
+ }
+ }
+ aptre.push_back(aptrb[1] + count);
+ totalCount += count;
+
+ /* column 2 zA*/
+ aptrb.push_back(aptre[1]);
+ count = 0;
+ if(fabs(Q1(0,2) )>pow(10,-15) ){
+ aval.push_back(ksA*Q1(0,2)); asub.push_back(0); count++;
+ }
+ if(fabs(Q1(1,2))>pow(10,-15) ){
+ aval.push_back(ksA*Q1(1,2)); asub.push_back(1); count++;
+ }
+ if(fabs(Q1(2,2) )>pow(10,-15) ){
+ aval.push_back(ksA*Q1(2,2)); asub.push_back(2); count++;
+ }
+ for(int i=0; i < planeNoA; i++){
+ if(fabs(s1->c[i]) > pow(10,-15) ){
+ aval.push_back(ksA*s1->c[i]); asub.push_back(4+i);
+ count++;
+ }
+ }
+ aptre.push_back(aptrb[2] + count);
+ totalCount += count;
+
+
+ /* column 3 xB*/
+ aptrb.push_back(aptre[2]);
+ count = 0;
+ if(fabs(Q2(0,0))>pow(10,-15) ){
+ aval.push_back(-ksB*Q2(0,0)); asub.push_back(0); count++;
+ }
+ if(fabs(Q2(1,0) )>pow(10,-15) ){
+ aval.push_back(-ksB*Q2(1,0)); asub.push_back(1); count++;
+ }
+ if(fabs(Q2(2,0) )>pow(10,-15) ){
+ aval.push_back(-ksB*Q2(2,0)); asub.push_back(2); count++;
+ }
+ for(int i=0; i < planeNoB; i++){
+ if(fabs(s2->a[i]) > pow(10,-15) ){
+ aval.push_back(ksB*s2->a[i]); asub.push_back(4+planeNoA +i);
+ count++;
+ }
+ }
+ aptre.push_back(aptrb[3] + count);
+ totalCount += count;
+
+
+ /* column 4 yB*/
+ aptrb.push_back(aptre[3]);
+ count = 0;
+ if(fabs(Q2(0,1))>pow(10,-15) ){
+ aval.push_back(-ksB*Q2(0,1)); asub.push_back(0); count++;
+ }
+ if(fabs(Q2(1,1) )>pow(10,-15) ){
+ aval.push_back(-ksB*Q2(1,1)); asub.push_back(1); count++;
+ }
+ if(fabs(Q2(2,1) )>pow(10,-15) ){
+ aval.push_back(-ksB*Q2(2,1)); asub.push_back(2); count++;
+ }
+ for(int i=0; i < planeNoB; i++){
+ if(fabs(s2->b[i]) > pow(10,-15) ){
+ aval.push_back(ksB*s2->b[i]); asub.push_back(4+planeNoA+i);
+ count++;
+ }
+ }
+ aptre.push_back(aptrb[4] + count);
+ totalCount += count;
+
+
+ /* column 5 zB*/
+ aptrb.push_back(aptre[4]);
+ count = 0;
+ if(fabs(Q2(0,2))>pow(10,-15) ){
+ aval.push_back(-ksB*Q2(0,2)); asub.push_back(0); count++;
+ }
+ if(fabs(Q2(1,2) )>pow(10,-15) ){
+ aval.push_back(-ksB*Q2(1,2)); asub.push_back(1); count++;
+ }
+ if(fabs(Q2(2,2) )>pow(10,-15) ){
+ aval.push_back(-ksB*Q2(2,2)); asub.push_back(2); count++;
+ }
+ for(int i=0; i < planeNoB; i++){
+ if(fabs(s2->c[i]) > pow(10,-15) ){
+ aval.push_back(ksB*s2->c[i]); asub.push_back(4+planeNoA+i);
+ count++;
+ }
+ }
+ aptre.push_back(aptrb[5] + count);
+ totalCount += count;
+
+
+ /*column 6 */
+ aptrb.push_back(aptre[5]);
+ aval.push_back(1.0); asub.push_back(3);
+ aptre.push_back(aptrb[6]+1);
+ totalCount += 1;
+
+
+ /*column 7 */
+ aptrb.push_back(aptre[6]);
+ aval.push_back(-1.0); asub.push_back(3);
+ aptre.push_back(aptrb[7]+1);
+ totalCount += 1;
+
+ /*column 8 + i*/
+ for(int i=0; i < planeNoA; i++){
+ aptrb.push_back(aptre[8-1+i]);
+ aval.push_back(-1.0*kpA); asub.push_back(4 + i);
+ aptre.push_back(aptrb[8+i]+1);
+ }
+ totalCount += planeNoA;
+
+ /*column 8 + planeNoA + i */
+ for(int i=0; i < planeNoB; i++){
+ aptrb.push_back(aptre[ 8 + planeNoA-1+i]);
+ aval.push_back(-1.0*kpB); asub.push_back(4 + planeNoA + i);
+ aptre.push_back(aptrb[8 + planeNoA+i]+1);
+ }
+ totalCount += planeNoB;
+
+ MSKidxt i,j,csubA[1+ 3 + planeNoA], csubB[1+ 3 + planeNoB] ;
+ double xx[NUMVAR];
+ MSKenv_t & env=mosekEnv;
+ MSKtask_t task;
+ MSKrescodee & r=mosekTaskEnv;
+
+
+ if ( r==MSK_RES_OK )
+ {
+ /* Directs the log stream to the
+ 'printstr' function. */
+ // MSK_linkfunctoenvstream(env,MSK_STREAM_LOG,NULL,NULL); //printstr
+ // MSK_linkfunctoenvstream(env,MSK_STREAM_LOG,NULL,NULL);
+ }
+
+
+
+ if ( r==MSK_RES_OK )
+ {
+ /* Create the optimization task. */
+ r = MSK_maketask(env,NUMCON,NUMVAR,&task);
+
+ if ( r==MSK_RES_OK )
+ {
+ // MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
+
+ /* Give MOSEK an estimate of the size of the input data.
+ This is done to increase the speed of inputting data.
+ However, it is optional. */
+ if (r == MSK_RES_OK)
+ r = MSK_putmaxnumvar(task,NUMVAR);
+
+ if (r == MSK_RES_OK)
+ r = MSK_putmaxnumcon(task,NUMCON);
+
+ int NUMANZ = totalCount;
+ if (r == MSK_RES_OK)
+ r = MSK_putmaxnumanz(task,NUMANZ);
+
+ /* Append 'NUMCON' empty constraints.
+ The constraints will initially have no bounds. */
+ if ( r == MSK_RES_OK )
+ r = MSK_append(task,MSK_ACC_CON,NUMCON);
+
+ /* Append 'NUMVAR' variables.
+ The variables will initially be fixed at zero (x=0). */
+ if ( r == MSK_RES_OK )
+ r = MSK_append(task,MSK_ACC_VAR,NUMVAR);
+
+ /* Optionally add a constant term to the objective. */
+ if ( r ==MSK_RES_OK )
+ r = MSK_putcfix(task,0.0);
+
+
+ for(j=0; j<NUMVAR && r == MSK_RES_OK; ++j)
+ {
+ /* Set the linear term c_j in the objective.*/
+ if(r == MSK_RES_OK)
+ r = MSK_putcj(task,j,c[j]);
+
+
+ /* Set the bounds on variable j.
+ blx[j] <= x_j <= bux[j] */
+ if(r == MSK_RES_OK)
+ r = MSK_putbound(task,
+ MSK_ACC_VAR, /* Put bounds on variables.*/
+ j, /* Index of variable.*/
+ bkx[j], /* Bound key.*/
+ blx[j], /* Numerical value of lower bound.*/
+ bux[j]); /* Numerical value of upper bound.*/
+
+
+ /* Input column j of A */
+ if(r == MSK_RES_OK)
+ r = MSK_putavec(task,
+ MSK_ACC_VAR, /* Input columns of A.*/
+ j, /* Variable (column) index.*/
+ aptre[j]-aptrb[j], /* Number of non-zeros in column j.*/
+ &asub[0]+aptrb[j], /* Pointer to row indexes of column j.*/
+ &aval[0]+aptrb[j]); /* Pointer to Values of column j.*/
+
+
+
+ }
+
+
+ /* Set the bounds on constraints.
+ for i=1, ...,NUMCON : blc[i] <= constraint i <= buc[i] */
+ for(i=0; i<NUMCON && r==MSK_RES_OK; ++i)
+{
+
+ r = MSK_putbound(task,
+ MSK_ACC_CON, /* Put bounds on constraints.*/
+ i, /* Index of constraint.*/
+ bkc[i], /* Bound key.*/
+ blc[i], /* Numerical value of lower bound.*/
+ buc[i]); /* Numerical value of upper bound.*/
+ }
+
+ if ( r==MSK_RES_OK )
+ {
+ /* Append the first cone. */
+ csubA[0] = 6;
+ csubA[1] = 0;
+ csubA[2] = 1;
+ csubA[3] = 2;
+ for(int i=0; i<planeNoA; i++){
+ csubA[4+i] = 8+i;
+ };
+ r = MSK_appendcone(task,
+ MSK_CT_QUAD,
+ 0.0, /* For future use only, can be set to 0.0 */
+
+ 1 + 3 + planeNoA,
+ csubA);
+ }
+
+ if ( r==MSK_RES_OK )
+ {
+ /* Append the second cone. */
+ csubB[0] = 7;
+ csubB[1] = 3;
+ csubB[2] = 4;
+ csubB[3] = 5;
+ for(int i=0; i<planeNoB; i++){
+ csubB[4+i] = 8 + planeNoA + i ;
+ };
+ r = MSK_appendcone(task, MSK_CT_QUAD, 0.0, 1 + 3 + planeNoB, csubB);
+ }
+
+
+ if ( r==MSK_RES_OK )
+ {
+ MSKrescodee trmcode;
+
+ r = MSK_putintparam ( task , MSK_IPAR_PRESOLVE_USE , MSK_PRESOLVE_MODE_OFF );
+ r = MSK_putintparam ( task , MSK_IPAR_CHECK_CONVEXITY, MSK_CHECK_CONVEXITY_NONE );
+ r = MSK_putintparam ( task , MSK_IPAR_INTPNT_SCALING, MSK_SCALING_NONE);
+ r = MSK_putintparam ( task , MSK_IPAR_INTPNT_SOLVE_FORM, MSK_SOLVE_DUAL );
+ r = MSK_putdouparam ( task , MSK_DPAR_INTPNT_CO_TOL_PFEAS , pow(10,-5) );
+ r = MSK_putdouparam ( task , MSK_DPAR_INTPNT_CO_TOL_DFEAS, pow(10,-5) );
+ r = MSK_putdouparam ( task , MSK_DPAR_INTPNT_CO_TOL_REL_GAP, pow(10,-8) ); //optimality
+ r = MSK_putdouparam ( task , MSK_DPAR_INTPNT_TOL_INFEAS, pow(10,-5) );
+ r = MSK_putdouparam ( task , MSK_DPAR_INTPNT_CO_TOL_MU_RED, pow(10,-8) ); //complementary
+ /* Run optimizer */
+ //MSK_writedata(task,"ig.opf.gz");
+ r = MSK_optimizetrm(task,&trmcode);
+ /* Print a summary containing information
+ about the solution for debugging purposes*/
+ //MSK_solutionsummary (task,MSK_STREAM_LOG);
+
+ if ( r==MSK_RES_OK )
+ {
+ MSKsolstae solsta;
+ MSKidxt j;
+ MSK_getsolutionstatus (task,
+ MSK_SOL_ITR,
+ NULL,
+ &solsta);
+
+ switch(solsta)
+ {
+ case MSK_SOL_STA_OPTIMAL:
+ MSK_getsolutionslice(task,
+ MSK_SOL_ITR, /* Request the interior solution. */
+ MSK_SOL_ITEM_XX,/* Which part of solution. */
+ 0, /* Index of first variable. */
+ NUMVAR, /* Index of last variable+1. */
+ xx);
+ break;
+ case MSK_SOL_STA_NEAR_OPTIMAL:
+ MSK_getsolutionslice(task,
+ MSK_SOL_ITR, /* Request the interior solution. */
+ MSK_SOL_ITEM_XX,/* Which part of solution. */
+ 0, /* Index of first variable. */
+ NUMVAR, /* Index of last variable+1. */
+ xx);
+
+ printf("Near Optimal primal solution\n");
+ // for(j=0; j<NUMVAR; ++j)
+ // printf("x[%d]: %e\n",j,xx[j]);
+
+ break;
+ case MSK_SOL_STA_DUAL_INFEAS_CER:
+ case MSK_SOL_STA_PRIM_INFEAS_CER:
+ case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
+ case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
+ printf("Primal or dual infeasibility certificate found.\n");
+ break;
+
+ case MSK_SOL_STA_UNKNOWN:
+ printf("The status of the solution could not be determined.\n");
+ //MSK_writedata(task,"mytask.opf.gz");
+ break;
+ default:
+ printf("Other solution status.");
+ break;
+ }
+
+
+ double xlocalA = xx[0]*ksA;
+ double ylocalA = xx[1]*ksA;
+ double zlocalA = xx[2]*ksA;
+ double xlocalB = xx[3]*ksB;
+ double ylocalB = xx[4]*ksB;
+ double zlocalB = xx[5]*ksB;
+ Vector3r localA = Vector3r(xlocalA,ylocalA,zlocalA);
+ Vector3r localB = Vector3r(xlocalB,ylocalB,zlocalB);
+ xGlobal = state1.ori*localA + state1.pos;
+
+
+ //printf("xA: %f \t yA: %f \nxB: %f \t yB: %f \nxgA: %f \t ygA: %f \nxgB: %f \t ygB: %f \n",xlocalA,ylocalA, xlocalB, ylocalB, xGlobalA, yGlobalA, xGlobalB, yGlobalB);
+ }
+ else
+ {
+ printf("Error while optimizing.\n");
+ }
+ }
+
+ if (r != MSK_RES_OK)
+ {
+ /* In case of an error print error code and description. */
+ char symname[MSK_MAX_STR_LEN];
+ char desc[MSK_MAX_STR_LEN];
+
+ printf("An error occurred while optimizing.\n");
+ MSK_getcodedesc (r,
+ symname,
+ desc);
+ printf("Error %s - '%s'\n",symname,desc);
+ }
+ }
+ /* Delete the task and the associated data. */
+ MSK_deletetask(&task);
+ }
+
+ /* Delete the environment and the associated data. */
+ // MSK_deleteenv(&env);
+
+ contactPt = xGlobal;
+ aval.clear();
+ asub.clear();
+
+ return ( true );
+}
+#endif
+
+
+
+
+void Ig2_PP_PP_ScGeom::getPtOnParticle2(const shared_ptr<Shape>& cm1, const State& state1, Vector3r midPoint, Vector3r normal, Vector3r& ptOnParticle){
+ PotentialParticle *s1=static_cast<PotentialParticle*>(cm1.get());
+ ptOnParticle = midPoint;
+ Real f = evaluatePP(cm1,state1, ptOnParticle);//evaluateFNoSphere(cm1,state1, ptOnParticle); //
+ Real fprevious = f;
+ int counter = 0;
+ //normal.normalize();
+ Vector3r step = normal*Mathr::Sign(f) *-1.0;
+ Vector3r bracketA(0,0,0);
+ Vector3r bracketB(0,0,0);
+
+ do{
+ ptOnParticle += step;
+ fprevious = f;
+ f = evaluatePP(cm1,state1, ptOnParticle); //evaluateFNoSphere(cm1,state1, ptOnParticle); //
+ counter++;
+ if (counter == 50000 ){
+ //LOG_WARN("Initial point searching exceeded 500 iterations!");
+ std::cout<<"ptonparticle2 search exceeded 50000 iterations! step:"<<step<<endl;
+ }
+
+ }while(Mathr::Sign(fprevious)*Mathr::Sign(f)*1.0> 0.0 );
+ bracketA = ptOnParticle;
+ bracketB = ptOnParticle -step;
+ Vector3r zero(0,0,0);
+ BrentZeroSurf(cm1,state1,bracketA, bracketB, zero);
+ ptOnParticle = zero;
+ //if( fabs(f)>0.1){std::cout<<"getInitial point f:"<<f<<endl;}
+}
+
+
+
+bool Ig2_PP_PP_ScGeom::customSolve(const shared_ptr<Shape>& cm1, const State& state1, const shared_ptr<Shape>& cm2, const State& state2, Vector3r &contactPt, bool warmstart){
+ //timingDeltas->start();
+ PotentialParticle *s1=static_cast<PotentialParticle*>(cm1.get());
+ PotentialParticle *s2=static_cast<PotentialParticle*>(cm2.get());
+ Vector3r xGlobal(0.0,0.0,0.0);
+ int iter = 0;
+ int totalIter = 0;
+
+ /* Parameters for particles A and B */
+ double rA = s1->r;double kA = s1->k;double RA = s1->R;
+ double rB = s2->r;double kB = s2->k;double RB = s2->R;
+ int planeNoA = s1->a.size();int planeNoB = s2->a.size();
+ int varNo = 3+1+planeNoA+planeNoB; int planeNoAB = planeNoA + planeNoB; int varNo2 = varNo*varNo;
+ int planeNoA3 = 3+planeNoA; int planeNoB3=3+planeNoB; int planeNoA2 =planeNoA*planeNoA; int planeNoB2=planeNoB*planeNoB;
+ Matrix3r QA = state1.ori.conjugate().toRotationMatrix(); /*direction cosine */
+
+ Matrix3r QB = state2.ori.conjugate().toRotationMatrix(); /*direction cosine */
+
+ int blas3 = 3; char blasNT = 'N'; char blasT= 'T'; int blas1planeNoA = std::max(1,planeNoA); int blas1planeNoB = std::max(1,planeNoB); int blas1planeNoAB = std::max(1,planeNoAB); double blas0 = 0.0; double blas1 = 1.0; double blasNeg1 = -1.0;
+
+ double blasQA[9]; double blasQB[9];
+ double blasPosA[3]; double blasPosB[3];
+ double blasContactPt[3];
+ double blasC[varNo];
+ for (int i=0; i<varNo; i++){
+ blasC[i] = 0.0;
+ }
+ blasC[3]= 1.0;
+ int blasCount = 0;
+ for(int i=0; i<3; i++){
+ for(int j=0; j<3; j++){
+ blasQA[blasCount]=QA(j,i);
+ blasQB[blasCount]=QB(j,i);
+ blasCount++;
+ }
+ blasPosA[i]=state1.pos[i];
+ blasPosB[i]=state2.pos[i];
+ blasContactPt[i]=contactPt[i];
+ }
+//std::cout<<"QA: "<<QA<<endl;std::cout<<"blasQA: "<<endl;
+
+//for (int i=0; i<9; i++){
+// std::cout<<blasQA[i]<<endl;
+//}
+
+ /* Variables to keep things neat */
+ double kAs = sqrt(kA)/RA;
+ double kAp = sqrt(1.0 - kA)/rA;
+ double kBs = sqrt(kB)/RB;
+ double kBp = sqrt(1.0 - kB)/rB;
+
+ /* penalty */
+ double t = 1.0; double mu=10.0; double planePert = 0.1*rA; double sPert = 1.0; //+ 10.0*planePert*(planeNoA+planeNoB)/(rA*rA);
+ if (warmstart == true){
+ t = 0.01; mu= 50.0; planePert = 0.01; sPert = 0.01; ///* pow(10,-1)+ */ sqrt(planePert*planePert*(planeNoA+planeNoB)/(rA*rA));
+ }
+ /* s */
+ double s = 0.0; double m=2.0; double NTTOL = pow(10,-8); double tol = accuracyTol/*pow(10,-4)* RA*pow(10,-6)*/; double gap =0.0;
+ /* x */
+ double blasX[varNo]; double blasNewX[varNo];
+ blasX[0] = contactPt[0]; blasX[1] = contactPt[1]; blasX[2] = contactPt[2];
+
+ //////////////////// evaluate fA and fB to initialize ////////////////////////////////
+ /* fA */
+ double blasTempP1[3]; double blasLocalP1[3];
+ for(int i=0; i<3; i++){
+ blasTempP1[i] = blasContactPt[i] - blasPosA[i];
+ }
+ char transA = 'N'; char transB = 'N'; int blasM = 3; int blasN = 3; int blasK = 3;
+ int blasLDA = 3; int blasLDB = 3; double blasAlpha = 1.0; double blasBeta = 0.0;
+ int blasLDC = 3; int incx=1; int incy=1;
+//dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasQA[0], &blasLDA, &blasTempP1[0], &incx, &blasBeta, &blasLocalP1[0], &incy);
+ dgemv_(&blasNT, &blas3, &blas3, &blas1, &blasQA[0], &blas3, &blasTempP1[0], &incx, &blas0, &blasLocalP1[0], &incy);
+
+ //Vector3r tempP1 = contactPt - posA;
+ //Vector3r localP1 = QA*tempP1;
+ /* P1Q */ //Eigen::MatrixXd P1 = Eigen::MatrixXd::Zero(planeNoA,3);
+ /*d1*/ //Eigen::MatrixXd d1 = Eigen::MatrixXd::Zero(planeNoA,1);
+
+ double blasP1[planeNoA*3];
+ double blasD1[planeNoA];
+ double blasP1Q[planeNoA*3];
+ double pertSumA2 = 0.0;
+
+ for (int i=0; i<planeNoA; i++){
+ double plane = s1->a[i]*blasLocalP1[0] + s1->b[i]*blasLocalP1[1] + s1->c[i]*blasLocalP1[2] - s1->d[i];
+ if (plane<pow(10,-15)){
+ plane = 0.0;
+ blasX[4+i] = plane + planePert;
+ }else{
+ blasX[4+i] = plane + planePert;
+ }
+ pertSumA2 += pow((plane+planePert),2);
+ blasP1[i] = s1->a[i]; blasP1[i+planeNoA] = s1->b[i]; blasP1[i+2*planeNoA] = s1->c[i];
+ blasD1[i] = s1->d[i];
+ }
+ //Eigen::MatrixXd P1Q = P1*QA;
+ //transA = 'N'; transB = 'N'; blasM = planeNoA; blasN = 3; blasK = 3;
+ // blasLDA = std::max(1,blasM); blasLDC = std::max(1,blasM); blasLDB = 3; blasAlpha=1.0; blasBeta = 0.0;
+ //dgemm_(&transA, &transB, &blasM, &blasN, &blasK, &blasAlpha, &blasP1[0], &blasLDA, &blasQA[0], &blasLDB, &blasBeta, &blasP1Q[0], &blasLDC);
+ dgemm_(&blasNT, &blasNT, &planeNoA, &blas3, &blas3, &blas1, &blasP1[0], &blas1planeNoA, &blasQA[0], &blasLDB, &blas0, &blasP1Q[0], &blas1planeNoA);
+
+ Real sphereA = (pow(blasLocalP1[0],2) + pow(blasLocalP1[1],2) + pow(blasLocalP1[2],2))/pow(RA,2);
+ Real sA = (1.0-kA)*(pertSumA2/pow(rA,2) - 1.0)+kA*(sphereA -1.0);
+
+ /* fB */
+ double blasTempP2[3]; double blasLocalP2[3];
+ for(int i=0; i<3; i++){
+ blasTempP2[i] = blasContactPt[i] - blasPosB[i];
+ }
+ //transA = 'N'; blasM = 3; blasN = 3; blasLDA = 3; blasAlpha=1.0; blasBeta = 0.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasQB[0], &blasLDA, &blasTempP2[0], &incx, &blasBeta, &blasLocalP2[0], &incy);
+ dgemv_(&blasNT, &blas3, &blas3, &blas1, &blasQB[0], &blas3, &blasTempP2[0], &incx, &blas0, &blasLocalP2[0], &incy);
+
+ // Vector3r tempP2 = contactPt - posB;
+ // Vector3r localP2 = QB*tempP2;
+ /*P2Q*/ //Eigen::MatrixXd P2 = Eigen::MatrixXd::Zero(planeNoB,3);
+ /*d2*/ //Eigen::MatrixXd d2 = Eigen::MatrixXd::Zero(planeNoB,1);
+ double blasP2[planeNoB*3];
+ double blasD2[planeNoB];
+ double blasP2Q[planeNoB*3]; double pertSumB2 = 0.0;
+ for (int i=0; i<planeNoB; i++){
+ double plane = s2->a[i]*blasLocalP2[0] + s2->b[i]*blasLocalP2[1] + s2->c[i]*blasLocalP2[2] - s2->d[i];
+ if (plane<pow(10,-15)){
+ plane = 0.0;
+ blasX[4+planeNoA+i] = plane+ planePert;
+ }else{
+ blasX[4+planeNoA+i] = plane + planePert;
+ }
+ pertSumB2 += pow((plane+planePert),2);
+ blasP2[i] = s2->a[i]; blasP2[i+planeNoB] = s2->b[i]; blasP2[i+2*planeNoB] = s2->c[i];
+ blasD2[i] = s2->d[i];
+ }
+ //Eigen::MatrixXd P2Q = P2*QB;
+ //transA = 'N'; transB = 'N'; blasM = planeNoB; blasN = 3; blasK = 3;
+ //blasLDA = std::max(1,blasM); blasLDC = std::max(1,blasM); blasLDB = 3; blasAlpha=1.0; blasBeta = 0.0;
+ // dgemm_(&transA, &transB, &blasM, &blasN, &blasK, &blasAlpha, &blasP2[0], &blasLDA, &blasQB[0], &blasLDB, &blasBeta, &blasP2Q[0], &blasLDC);
+ dgemm_(&blasNT, &blasNT, &planeNoB, &blas3, &blas3, &blasAlpha, &blasP2[0], &blas1planeNoB, &blasQB[0], &blas3, &blasBeta, &blasP2Q[0], &blas1planeNoB);
+ Real sphereB = (pow(blasLocalP2[0],2) + pow(blasLocalP2[1],2) + pow(blasLocalP2[2],2))/pow(RB,2);
+ Real sB = (1.0-kB)*(pertSumB2/pow(rB,2) - 1.0)+kB*(sphereB -1.0);
+ //sPert = fabs(fA-fB);
+
+ s = std::max(sqrt(fabs(sA+1.0)), sqrt(fabs(sB+1.0))) + sPert; //sqrt(fA+fB+2.0)+sPert; //sqrt(std::max(fabs(fA+1.0), fabs(fB+1.0))) + sPert; //
+ //x[3] = s;
+ blasX[3]= s;
+
+ /////////////////// algebra formulation of the SOCP ///////////////////
+ /* c */
+ // Eigen::MatrixXd c=Eigen::MatrixXd::Zero(varNo,1);
+ // c[3] = 1.0;
+
+ double blasA1[(3+planeNoA)*varNo]; double blasA2[(3+planeNoB)*varNo];
+ /* Second order cone constraints */
+ /* A1 */
+ //Eigen::MatrixXd A1(3+planeNoA,varNo);
+ //Matrix3r QAs=kAs*QA; //cwise()
+ double blasQAs[9]; int noElements=9; double scaleFactor = kAs;
+ dcopy_(&noElements, &blasQA[0], &incx, &blasQAs[0], &incx);
+ dscal_(&noElements, &scaleFactor, &blasQAs[0], &incx);
+
+ // A1 << QAs,Eigen::MatrixXd::Zero(3,1+planeNoAB),
+ // Eigen::MatrixXd::Zero(planeNoA,4),kAp*Eigen::MatrixXd::Identity(planeNoA, planeNoA),Eigen::MatrixXd::Zero(planeNoA,planeNoB);
+ memset(blasA1,0.0,sizeof(blasA1));
+ for (int i=0; i<3; i++){
+ blasA1[i] = blasQAs[i]; blasA1[i+planeNoA3] = blasQAs[i+3]; blasA1[i+2*planeNoA3] = blasQAs[i+6];
+ }
+ for (int i=0; i<planeNoA; i++){
+ blasA1[3+i+(planeNoA3)*(4+i)] = kAp;
+ }
+
+
+ /* A2 */
+ //Eigen::MatrixXd A2(3+planeNoB,varNo);
+ //Matrix3r QBs=kBs*QB; //cwise();
+ double blasQBs[9]; noElements=9; scaleFactor = kBs;
+ dcopy_(&noElements, &blasQB[0], &incx, &blasQBs[0], &incx);
+ dscal_(&noElements, &scaleFactor, &blasQBs[0], &incx);
+
+ // A2 << QBs,Eigen::MatrixXd::Zero(3,1+planeNoAB),
+ // Eigen::MatrixXd::Zero(planeNoB,4),Eigen::MatrixXd::Zero(planeNoB,planeNoA),kBp*Eigen::MatrixXd::Identity(planeNoB, planeNoB);
+ memset(blasA2,0.0,sizeof(blasA2));
+ for (int i=0; i<3; i++){
+ blasA2[i] = blasQBs[i]; blasA2[i+planeNoB3] = blasQBs[i+3]; blasA2[i+2*(planeNoB3)] = blasQBs[i+6];
+ }
+
+ for (int i=0; i<planeNoB; i++){
+ blasA2[3+i+(planeNoB3)*(4+planeNoA+i)] = kBp;
+ }
+
+
+
+ /*b1*/
+#if 0
+ Eigen::MatrixXd b1=Eigen::MatrixXd::Zero(3+planeNoA,1);
+ Eigen::Vector3d b1temp = QAs*posA;
+ b1[0] = -b1temp[0]; b1[1]= -b1temp[1]; b1[2] = -b1temp[2];
+#endif
+
+ double blasB1[planeNoA3]; double blasB1temp[3];
+ memset(blasB1,0.0,sizeof(blasB1));
+ // blasM = 3; blasN=3;
+// blasLDA = 3; blasAlpha = -1.0; blasBeta=0.0; blasLDC = 3;
+// dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasQAs[0], &blasLDA, &blasPosA[0], &incx, &blasBeta, &blasB1temp[0], &incy);
+ dgemv_(&blasNT, &blas3, &blas3, &blasNeg1, &blasQAs[0], &blas3, &blasPosA[0], &incx, &blas0, &blasB1temp[0], &incy);
+ blasB1[0]=blasB1temp[0]; blasB1[1]=blasB1temp[1]; blasB1[2]=blasB1temp[2];
+
+ /*b2*/
+#if 0
+ Eigen::MatrixXd b2=Eigen::MatrixXd::Zero(3+planeNoB,1);
+ Eigen::Vector3d b2temp = QBs*posB;
+ b2[0] = -b2temp[0]; b2[1]= -b2temp[1]; b2[2] = -b2temp[2];
+#endif
+
+ double blasB2[planeNoB3]; double blasB2temp[3];
+ memset(blasB2,0.0,sizeof(blasB2));
+ // blasM = 3; blasN=3; blasLDA = 3; blasAlpha=-1.0; blasBeta=0.0;
+ // dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasQBs[0], &blasLDA, &blasPosB[0], &incx, &blasBeta, &blasB2temp[0], &incy);
+ dgemv_(&blasNT, &blas3, &blas3, &blasNeg1, &blasQBs[0], &blas3, &blasPosB[0], &incx, &blas0, &blasB2temp[0], &incy);
+ blasB2[0]=blasB2temp[0]; blasB2[1]=blasB2temp[1]; blasB2[2]=blasB2temp[2];
+
+ /*AL*/
+ // Eigen::MatrixXd AL(planeNoAB,varNo);
+ // AL<<P1Q, Eigen::MatrixXd::Zero(planeNoA,1), -1.0*Eigen::MatrixXd::Identity(planeNoA,planeNoA), Eigen::MatrixXd::Zero(planeNoA,planeNoB), //cwise()
+// P2Q, Eigen::MatrixXd::Zero(planeNoB,1), Eigen::MatrixXd::Zero(planeNoB,planeNoA), -1.0*Eigen::MatrixXd::Identity(planeNoB,planeNoB);
+
+ double blasAL[planeNoAB*varNo];
+ memset(blasAL,0.0,sizeof(blasAL));
+ for (int i=0; i<planeNoA; i++){
+ blasAL[i] = blasP1Q[i]; blasAL[i+planeNoAB] = blasP1Q[i+planeNoA]; blasAL[i+2*planeNoAB] = blasP1Q[i+2*planeNoA];
+ blasAL[i+(4+i)*planeNoAB] = -1.0;
+ }
+ for (int i=0; i<planeNoB; i++){
+ blasAL[planeNoA+i] = blasP2Q[i]; blasAL[planeNoA+i+planeNoAB] = blasP2Q[i+planeNoB]; blasAL[planeNoA+i+2*planeNoAB] = blasP2Q[i+2*planeNoB];
+ blasAL[planeNoA+i+(4+planeNoA+i)*planeNoAB] = -1.0;
+ }
+
+
+
+ /*bL*/
+#if 0
+ Eigen::MatrixXd bL(planeNoAB,1);
+ Eigen::MatrixXd pos1(3,1); pos1(0,0) = posA[0]; pos1(1,0) = posA[1]; pos1(2,0)=posA[2];
+ Eigen::MatrixXd pos2(3,1); pos2(0,0) = posB[0]; pos2(1,0) = posB[1]; pos2(2,0)=posB[2];
+ Eigen::MatrixXd btempU = P1Q*pos1 + d1;
+ Eigen::MatrixXd btempL = P2Q*pos2 + d2;
+ bL<<btempU,btempL;
+#endif
+
+ double blasBL[planeNoAB]; double blasBTempU[planeNoA]; double blasBTempL[planeNoB];
+ noElements = planeNoA;
+ dcopy_(&noElements, &blasD1[0], &incx, &blasBTempU[0], &incx);
+ //transA = 'N'; blasM = planeNoA; blasN = 3;
+ //blasLDA = std::max(1,planeNoA); blasAlpha = 1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasP1Q[0], &blasLDA,&blasPosA[0], &incx, &blasBeta, &blasBTempU[0], &incy);
+ dgemv_(&blasNT, &planeNoA, &blas3, &blas1, &blasP1Q[0], &blas1planeNoA,&blasPosA[0], &incx, &blas1, &blasBTempU[0], &incy);
+ noElements = planeNoB;
+ dcopy_(&noElements, &blasD2[0], &incx, &blasBTempL[0], &incx);
+ //transA = 'N'; blasM = planeNoB; blasN = 3;
+ //blasLDA = std::max(1,planeNoB); blasAlpha = 1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasP2Q[0], &blasLDA,&blasPosB[0], &incx, &blasBeta, &blasBTempL[0], &incy);
+ dgemv_(&blasNT, &planeNoB, &blas3, &blas1, &blasP2Q[0], &blas1planeNoB,&blasPosB[0], &incx, &blas1, &blasBTempL[0], &incy);
+ for (int i=0; i<planeNoA; i++){
+ blasBL[i]=blasBTempU[i];
+ }
+ for (int i=0; i<planeNoB; i++){
+ blasBL[planeNoA+i]=blasBTempL[i];
+ }
+
+ double u1; double u2;
+ double blasCCtranspose[varNo2];
+ memset(blasCCtranspose,0.0,sizeof(blasCCtranspose));
+ blasCCtranspose[3+varNo*3]=1.0;
+
+ double blasCa1[varNo2];
+//#if 0
+ #if 0
+ Eigen::MatrixXd ca1Transpose = ccTranspose - A1.transpose()*A1;
+ Eigen::MatrixXd ca2Transpose = ccTranspose - A2.transpose()*A2;
+ #endif
+ /* ca1Transpose */
+ noElements = varNo2; incx =1; incy=1;
+ dcopy_(&noElements, &blasCCtranspose[0], &incx, &blasCa1[0], &incy);
+
+ //transA = 'T'; transB = 'N'; blasM = varNo; blasN = varNo; blasK = 3+planeNoA;
+ //blasLDA = blasK; blasLDB = blasK; blasAlpha = -1.0; blasBeta = 1.0;
+ //blasLDC = varNo;
+ //dgemm_(&transA, &transB, &blasM, &blasN, &blasK, &blasAlpha, &blasA1[0], &blasLDA, &blasA1[0], &blasLDB, &blasBeta, &blasCa1[0], &blasLDC);
+ dgemm_(&blasT, &blasNT, &varNo, &varNo, &planeNoA3, &blasNeg1, &blasA1[0], &planeNoA3, &blasA1[0], &planeNoA3, &blas1, &blasCa1[0], &varNo);
+
+
+ /* ca2Transpose */
+ double blasCa2[varNo2]; blasCount = 0;
+ dcopy_(&noElements, &blasCCtranspose[0], &incx, &blasCa2[0], &incy);
+
+ //transA = 'T'; transB = 'N'; blasM = varNo; blasN = varNo; blasK = 3+planeNoB;
+ // blasLDA = blasK; blasLDB = blasK; blasAlpha = -1.0; blasBeta = 1.0;
+ // blasLDC = varNo;
+ // dgemm_(&transA, &transB, &blasM, &blasN, &blasK, &blasAlpha, &blasA2[0], &blasLDA, &blasA2[0], &blasLDB, &blasBeta, &blasCa2[0], &blasLDC);
+ dgemm_(&blasT, &blasNT, &varNo, &varNo, &planeNoB3, &blasNeg1, &blasA2[0], &planeNoB3, &blasA2[0], &planeNoB3, &blas1, &blasCa2[0], &varNo);
+
+/* DL */
+double blasDL[planeNoAB*planeNoAB]; blasCount = 0;
+memset(blasDL,0.0,sizeof(blasDL));
+
+//#endif
+
+
+ double wLlogsum = 0.0;
+ double val = 0.0;
+ double newval = 0.0;
+ /*Linesearch */
+ double backtrack = 1.0;
+ double penalty = 1.0/t;
+
+/* LAPACK */
+ int info; char UPLO ='L'; int KD = varNo-1; int nrhs=1;
+ double gradient[varNo];
+ double HessianChol[varNo][varNo];
+
+
+ double blasGA[varNo]; double blasGB[varNo]; double blasGL[varNo];
+
+ double blasW1[3+planeNoA]; double blasW2[3+planeNoB]; double blasWL[planeNoAB]; double blasVL[planeNoAB]; double minWL=0.0;
+ double blasHA[varNo*varNo]; double blasHB[varNo*varNo]; double blasHL[varNo*varNo]; double blasADAtemp[varNo*planeNoAB];
+ noElements = varNo;
+ double blasW1dot=0.0; double blasW2dot=0.0;
+ double blasGrad[varNo]; double blasHess[varNo*varNo]; double blasStep[varNo]; double blasFprime = 0.0;
+
+#if 0
+// MAKE SURE POINTS ARE FEASIBLE //
+ /* temp variables */
+ /* w1 = A1*x + b1; */
+ noElements = 3+planeNoA;
+ dcopy_(&noElements, &blasB1[0], &incx, &blasW1[0], &incy);
+ //transA = 'N'; blasM = 3+planeNoA; blasN = varNo;
+ //blasLDA = 3+planeNoA; blasAlpha = 1.0; blasBeta = 1.0; incx =1; incy=1;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA1[0], &blasLDA, &blasX[0], &incx, &blasBeta, &blasW1[0], &incy);
+ dgemv_(&blasNT, &planeNoA3, &varNo, &blas1, &blasA1[0], &planeNoA3, &blasX[0], &incx, &blas1, &blasW1[0], &incy);
+
+ /* w2 = A2*x + b2; */
+ noElements = 3+planeNoB;
+ dcopy_(&noElements, &blasB2[0], &incx, &blasW2[0], &incy);
+ //transA = 'N'; blasM = 3+planeNoB; blasN = varNo;
+ //blasLDA = 3+planeNoB; blasAlpha = 1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA2[0], &blasLDA, &blasX[0], &incx, &blasBeta, &blasW2[0], &incy);
+ dgemv_(&blasNT, &planeNoB3, &varNo, &blas1, &blasA2[0], &planeNoB3, &blasX[0], &incx, &blas1, &blasW2[0], &incy);
+
+ /* u1 = s*s - w1.dot(w1); */
+ /* u2 = s*s - w2.dot(w2); */
+ //noElements = 3+planeNoA;
+ blasW1dot = ddot_(&planeNoA3, &blasW1[0], &incx, &blasW1[0], &incy);
+ //noElements = 3+planeNoB;
+ blasW2dot = ddot_(&planeNoB3, &blasW2[0], &incx, &blasW2[0], &incy);
+
+s = std::max(sqrt(fabs(blasW1dot)),sqrt(fabs(blasW2dot)))+0.1;
+blasX[3]=s;
+#endif
+
+//timingDeltas->checkpoint("setup");
+
+
+while(totalIter<500){
+ penalty = 1.0/t;
+ /* Newton's method */
+ /* s=x[3]; */
+ s=blasX[3];
+
+ /* temp variables */
+ /* w1 = A1*x + b1; */
+ noElements = 3+planeNoA;
+ dcopy_(&noElements, &blasB1[0], &incx, &blasW1[0], &incy);
+ //transA = 'N'; blasM = 3+planeNoA; blasN = varNo;
+ //blasLDA = 3+planeNoA; blasAlpha = 1.0; blasBeta = 1.0; incx =1; incy=1;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA1[0], &blasLDA, &blasX[0], &incx, &blasBeta, &blasW1[0], &incy);
+ dgemv_(&blasNT, &planeNoA3, &varNo, &blas1, &blasA1[0], &planeNoA3, &blasX[0], &incx, &blas1, &blasW1[0], &incy);
+
+ /* w2 = A2*x + b2; */
+ noElements = 3+planeNoB;
+ dcopy_(&noElements, &blasB2[0], &incx, &blasW2[0], &incy);
+ //transA = 'N'; blasM = 3+planeNoB; blasN = varNo;
+ //blasLDA = 3+planeNoB; blasAlpha = 1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA2[0], &blasLDA, &blasX[0], &incx, &blasBeta, &blasW2[0], &incy);
+ dgemv_(&blasNT, &planeNoB3, &varNo, &blas1, &blasA2[0], &planeNoB3, &blasX[0], &incx, &blas1, &blasW2[0], &incy);
+
+ /* u1 = s*s - w1.dot(w1); */
+ /* u2 = s*s - w2.dot(w2); */
+ //noElements = 3+planeNoA;
+ blasW1dot = ddot_(&planeNoA3, &blasW1[0], &incx, &blasW1[0], &incy);
+ //noElements = 3+planeNoB;
+ blasW2dot = ddot_(&planeNoB3, &blasW2[0], &incx, &blasW2[0], &incy);
+ u1 =s*s -blasW1dot;
+ u2 =s*s -blasW2dot;
+
+ /* wL = bL - AL*x; */
+ noElements = planeNoAB;
+ dcopy_(&noElements, &blasBL[0], &incx, &blasWL[0], &incy);
+ //transA = 'N'; blasN = varNo;
+ //blasM = planeNoAB; blasLDA = std::max(1,planeNoAB); blasAlpha = -1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasAL[0], &blasLDA, &blasX[0], &incx, &blasBeta, &blasWL[0], &incy);
+ dgemv_(&blasNT, &planeNoAB, &varNo, &blasNeg1, &blasAL[0], &blas1planeNoAB, &blasX[0], &incx, &blas1, &blasWL[0], &incy);
+
+ for (int i=0; i<planeNoAB; i++ ){
+ blasVL[i] = 1.0/blasWL[i];
+ blasDL[i*planeNoAB+i] = blasVL[i]*blasVL[i];
+ }
+
+ /* Gradient */
+//gA = -2.0/u1*(s*c - A1.transpose()*w1); //-2.0/u1*(s*c - tempG); //
+//gB = -2.0/u2*(s*c - A2.transpose()*w2); //-2.0/u2*(s*c - tempG); //
+// gL = AL.transpose()*vL; //tempG; //
+// g = (c + penalty*(gA + gB + gL) );
+
+
+ /* gA */
+ //noElements = varNo;
+ dcopy_(&varNo, &blasC[0], &incx, &blasGA[0], &incy);
+ //transA = 'T'; blasM = 3+planeNoA; blasLDA = 3+planeNoA;
+ blasAlpha = -1.0*-2.0/u1; blasBeta = 1.0*-2.0/u1*s;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA1[0], &blasLDA, &blasW1[0], &incx, &blasBeta, &blasGA[0], &incy);
+ dgemv_(&blasT, &planeNoA3, &varNo, &blasAlpha, &blasA1[0], &planeNoA3, &blasW1[0], &incx, &blasBeta, &blasGA[0], &incy);
+
+ /* gB */
+ dcopy_(&varNo, &blasC[0], &incx, &blasGB[0], &incy);
+ //transA = 'T'; blasM = 3+planeNoB; blasLDA = 3+planeNoB;
+ blasAlpha = -1.0*-2.0/u2; blasBeta = 1.0*-2.0/u2*s;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA2[0], &blasLDA, &blasW2[0], &incx, &blasBeta, &blasGB[0], &incy);
+ dgemv_(&blasT, &planeNoB3, &varNo, &blasAlpha, &blasA2[0], &planeNoB3, &blasW2[0], &incx, &blasBeta, &blasGB[0], &incy);
+
+/* gL */
+ //transA = 'T'; blasM = planeNoAB; blasLDA = std::max(1,planeNoAB); blasAlpha = 1.0; blasBeta = 0.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasAL[0], &blasLDA, &blasVL[0], &incx, &blasBeta, &blasGL[0], &incy);
+ dgemv_(&blasT, &planeNoAB, &varNo, &blas1, &blasAL[0], &blas1planeNoAB, &blasVL[0], &incx, &blas0, &blasGL[0], &incy);
+
+
+/* g */
+ for (int i = 0; i<varNo; i++){
+ blasGrad[i] = blasC[i] + penalty*(blasGA[i] + blasGB[i] + blasGL[i]);
+ }
+
+ /* Hessian */
+ /* HA */ //Eigen::MatrixXd HA = (-2.0/u1)*(ca1Transpose)+ gA*gA.transpose();
+ //noElements = varNo2;
+ dcopy_(&varNo2, &blasCa1[0], &incx, &blasHA[0], &incy);
+ //transA = 'N'; transB = 'T'; blasM = varNo; blasN = varNo; blasK = 1;blasLDA = blasM; blasLDB = blasN; blasAlpha = 1.0; blasLDC = blasM;
+ blasBeta = -2.0/(u1); blasK = 1;
+ //dgemm_(&transA, &transB, &blasM, &blasN, &blasK, &blasAlpha, &blasGA[0], &blasLDA, &blasGA[0], &blasLDB, &blasBeta, &blasHA[0], &blasLDC);
+ dgemm_(&blasNT, &blasT, &varNo, &varNo, &blasK, &blas1, &blasGA[0], &varNo, &blasGA[0], &varNo, &blasBeta, &blasHA[0], &varNo);
+
+ /* HB */ // HB = (-2.0/u2)*(ca2Transpose)+ gB*gB.transpose();
+ dcopy_(&varNo2, &blasCa2[0], &incx, &blasHB[0], &incy);
+ //transA = 'N'; transB = 'T'; blasM = varNo; blasN = varNo; blasK = 1; blasLDA = blasM; blasLDB = blasN; blasAlpha = 1.0; blasLDC = blasM;
+ blasBeta = -2.0/(u2);
+ //dgemm_(&transA, &transB, &blasM, &blasN, &blasK, &blasAlpha, &blasGB[0], &blasLDA, &blasGB[0], &blasLDB, &blasBeta, &blasHB[0], &blasLDC);
+ dgemm_(&blasNT, &blasT, &varNo, &varNo, &blasK, &blas1, &blasGB[0], &varNo, &blasGB[0], &varNo, &blasBeta, &blasHB[0], &varNo);
+
+
+ /* HL */ //Eigen::MatrixXd HL1 = AL.transpose()*DL*AL;
+ //transA = 'T'; transB = 'N'; blasM = varNo; blasN = planeNoAB; blasK = planeNoAB;
+ //blasLDA = std::max(1,blasK); blasLDB = std::max(1,blasK); blasAlpha = 1.0; blasBeta = 0.0; blasLDC = blasM;
+ //dgemm_(&transA, &transB, &blasM, &blasN, &blasK, &blasAlpha, &blasAL[0], &blasLDA, &blasDL[0], &blasLDB, &blasBeta, &blasADAtemp[0], &blasLDC);
+ dgemm_(&blasT, &blasNT, &varNo, &planeNoAB, &planeNoAB, &blas1, &blasAL[0], &blas1planeNoAB, &blasDL[0], &blas1planeNoAB, &blas0, &blasADAtemp[0], &varNo);
+ //transA = 'N'; transB = 'N'; blasM = varNo; blasN = varNo; blasK = planeNoAB;
+ //blasLDA = blasM; blasLDB = std::max(1,blasK); blasAlpha = 1.0; blasBeta = 0.0; blasLDC = blasM;
+ //dgemm_(&transA, &transB, &blasM, &blasN, &blasK, &blasAlpha, &blasADAtemp[0], &blasLDA, &blasAL[0], &blasLDB, &blasBeta, &blasHL[0], &blasLDC);
+ dgemm_(&blasNT, &blasNT, &varNo, &varNo, &planeNoAB, &blas1, &blasADAtemp[0], &varNo, &blasAL[0], &blas1planeNoAB, &blas0, &blasHL[0], &varNo);
+
+ /* H */ // H = penalty*(HA + HB + HL);
+ for (int i = 0; i<varNo2; i++){
+ blasHess[i] = penalty*(blasHA[i] + blasHB[i] + blasHL[i]);
+ }
+
+
+//timingDeltas->checkpoint("assemble H and g");
+
+//std::cout<<"before Chol, totalIter: "<<totalIter<<", s : "<<s<<", u1: "<<u1<<", u2: "<<u2<<", wLmincoeff: "<<minWL<<endl;
+
+/* Cholesky factorization */
+//#if 0
+/* L */
+ for( int j=1; j<=varNo ; j++){
+ blasStep[j-1]=-blasGrad[j-1];
+ for (int i=j; i<=j+KD && i<=varNo; i++){
+ HessianChol[j-1][1+i-j-1] = blasHess[(i-1)+varNo*(j-1)];
+ }
+ }
+//#endif
+
+#if 0
+ /* U */
+ for( int j=1; j<=varNo ; j++){
+ blasStep[j-1]=-blasGrad[j-1];
+ for (int i=std::max(1,j-KD); i<=j ; i++){
+ HessianChol[j-1][KD+1+i-j-1] = blasHess[(i-1)+varNo*(j-1)]; //H(i-1,j-1);
+ }
+ }
+#endif
+ dpbsv_( &UPLO, &varNo, &KD, &nrhs, &HessianChol[0][0], &varNo, blasStep, &varNo, &info );
+ if(info != 0){
+ std::cout<<"chol error"<<", planeA: "<<planeNoA<<", planeB: "<<planeNoB<<endl;
+ //return false;
+ /* LU factorization */
+ for (int i=0; i<varNo; i++ ){
+ blasStep[i]=-1.0*blasGrad[i]; //g[i];
+ }
+ int ipiv[varNo]; int bColNo=1;
+ dgesv_( &varNo, &bColNo, blasHess, &varNo, ipiv, blasStep, &varNo, &info);
+ }
+
+ if (info!=0){
+ std::cout<<"linear algebra error"<<endl;
+ }
+
+//timingDeltas->checkpoint("Cholesky");
+
+ //fprime = step.transpose()*g;
+ //noElements = varNo;
+ blasFprime = ddot_(&varNo, &blasStep[0], &incx, &blasGrad[0], &incy);
+
+ wLlogsum = 0.0;
+ for (int i=0; i<planeNoAB; i++){
+ //wLlogsum += log(wL[i]);
+ wLlogsum += log(blasWL[i]);
+ }
+
+ val = /* c.transpose()*/ blasX[3] -penalty*( log(u1) + log(u2) + wLlogsum );
+
+ /*Linesearch */
+ backtrack = 1.0;
+ //noElements = varNo;
+ dcopy_(&varNo, &blasX[0], &incx, &blasNewX[0], &incy);
+ daxpy_(&varNo, &backtrack, &blasStep[0], &incx, &blasNewX[0], &incy);
+
+
+
+ s = blasNewX[3];
+ // w1 = A1*x + b1;
+
+ dcopy_(&planeNoA3, &blasB1[0], &incx, &blasW1[0], &incy);
+ //transA = 'N'; blasAlpha = 1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA1[0], &blasLDA, &blasNewX[0], &incx, &blasBeta, &blasW1[0], &incy);
+ dgemv_(&blasNT, &planeNoA3, &varNo, &blas1, &blasA1[0], &planeNoA3, &blasNewX[0], &incx, &blas1, &blasW1[0], &incy);
+
+ // w2 = A2*x + b2;
+ dcopy_(&planeNoB3, &blasB2[0], &incx, &blasW2[0], &incy);
+ //transA = 'N'; blasAlpha = 1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &planeNoB3, &varNo, &blasAlpha, &blasA2[0], &planeNoB3, &blasNewX[0], &incx, &blasBeta, &blasW2[0], &incy);
+ dgemv_(&blasNT, &planeNoB3, &varNo, &blas1, &blasA2[0], &planeNoB3, &blasNewX[0], &incx, &blas1, &blasW2[0], &incy);
+
+
+ blasW1dot = ddot_(&planeNoA3, &blasW1[0], &incx, &blasW1[0], &incy);
+ blasW2dot = ddot_(&planeNoB3, &blasW2[0], &incx, &blasW2[0], &incy);
+
+ //u1 = s*s - w1.dot(w1);
+ //u2 = s*s - w2.dot(w2);
+ u1 =s*s -blasW1dot;
+ u2 =s*s -blasW2dot;
+
+ //wL = bL - AL*x;
+ dcopy_(&planeNoAB, &blasBL[0], &incx, &blasWL[0], &incy);
+ //blasAlpha = -1.0;
+ //blasM=planeNoAB; blasN=varNo; blasLDA=std::max(1,planeNoAB);
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasAL[0], &blasLDA, &blasNewX[0], &incx, &blasBeta, &blasWL[0], &incy);
+ dgemv_(&transA, &planeNoAB, &varNo, &blasNeg1, &blasAL[0], &blas1planeNoAB, &blasNewX[0], &incx, &blas1, &blasWL[0], &incy);
+
+ minWL =0.00001;
+ if(planeNoAB>0){
+ minWL = blasWL[0];
+ }
+ for(int i=0; i<planeNoAB; i++){
+ if(blasWL[i] < minWL){
+ minWL = blasWL[i];
+ }
+ }
+
+ int count = 0;
+ while(s < 0.0 || u1<0.0 || u2<0.0 || minWL < 0.0){
+ backtrack = 0.5*backtrack;
+ dcopy_(&varNo, &blasX[0], &incx, &blasNewX[0], &incy);
+ daxpy_(&varNo, &backtrack, &blasStep[0], &incx, &blasNewX[0], &incy);
+
+ s = blasNewX[3];
+ // w1 = A1*x + b1;
+
+ dcopy_(&planeNoA3, &blasB1[0], &incx, &blasW1[0], &incy);
+ //transA = 'N'; blasAlpha = 1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA1[0], &blasLDA, &blasNewX[0], &incx, &blasBeta, &blasW1[0], &incy);
+ dgemv_(&blasNT, &planeNoA3, &varNo, &blas1, &blasA1[0], &planeNoA3, &blasNewX[0], &incx, &blas1, &blasW1[0], &incy);
+
+ // w2 = A2*x + b2;
+ dcopy_(&planeNoB3, &blasB2[0], &incx, &blasW2[0], &incy);
+ //transA = 'N'; blasAlpha = 1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA2[0], &blasLDA, &blasNewX[0], &incx, &blasBeta, &blasW2[0], &incy);
+ dgemv_(&blasNT, &planeNoB3, &varNo, &blas1, &blasA2[0], &planeNoB3, &blasNewX[0], &incx, &blas1, &blasW2[0], &incy);
+ blasW1dot = ddot_(&planeNoA3, &blasW1[0], &incx, &blasW1[0], &incy);
+ blasW2dot = ddot_(&planeNoB3, &blasW2[0], &incx, &blasW2[0], &incy);
+
+ //u1 = s*s - w1.dot(w1);
+ //u2 = s*s - w2.dot(w2);
+ u1 =s*s -blasW1dot;
+ u2 =s*s -blasW2dot;
+
+ //wL = bL - AL*x;
+
+ dcopy_(&planeNoAB, &blasBL[0], &incx, &blasWL[0], &incy);
+ // blasAlpha = -1.0;
+ //blasM = planeNoAB; blasLDA = std::max(1,planeNoAB); blasN = varNo; blasAlpha = -1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasAL[0], &blasLDA, &blasNewX[0], &incx, &blasBeta, &blasWL[0], &incy);
+ dgemv_(&blasNT, &planeNoAB, &varNo, &blasNeg1, &blasAL[0], &blas1planeNoAB, &blasNewX[0], &incx, &blas1, &blasWL[0], &incy);
+ if(planeNoAB>0){
+ minWL = blasWL[0];
+ }
+ for(int i=0; i<planeNoAB; i++){
+ if(blasWL[i] < minWL){
+ minWL = blasWL[i];
+ }
+ }
+ count++;
+ //std::cout<<"count: "<<count<<", s : "<<s<<", u1: "<<u1<<", u2: "<<u2<<", wLmincoeff: "<<minWL<<endl;
+ if(count==200){
+ std::cout<<"count: "<<count<<", totalIter: "<<totalIter<<", backtrack: "<<backtrack<<"s : "<<s<<", u1: "<<u1<<", u2: "<<u2<<", wLmincoeff: "<<minWL<<endl;
+ //std::cout<<"wL: "<<endl<<wL<<endl<<endl;
+ }
+ }
+
+//timingDeltas->checkpoint("barrier search");
+
+ wLlogsum = 0.0;
+ for (int i=0; i<planeNoAB; i++){
+ wLlogsum += log(blasWL[i]);
+ }
+
+
+ newval = /*c.tranpose()*/blasNewX[3] -penalty*( log(u1) + log(u2) + wLlogsum );
+ count = 0;
+ while (newval > val + backtrack*0.01*blasFprime){
+ backtrack = 0.5*backtrack;
+ //for (int i = 0; i<varNo; i++){
+ // blasNewX[i] = blasX[i] + backtrack*blasStep[i];
+ //}
+ //noElements = varNo;
+ dcopy_(&varNo, &blasX[0], &incx, &blasNewX[0], &incy);
+ daxpy_(&varNo, &backtrack, &blasStep[0], &incx, &blasNewX[0], &incy);
+
+ s = blasNewX[3];
+ // w1 = A1*x + b1;
+ //noElements = 3+planeNoA;
+ dcopy_(&planeNoA3, &blasB1[0], &incx, &blasW1[0], &incy);
+ //transA = 'N'; blasM = 3+planeNoA; blasN = varNo;
+ //blasLDA = 3+planeNoA; blasAlpha = 1.0; blasBeta = 1.0; incx =1; incy=1;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA1[0], &blasLDA, &blasNewX[0], &incx, &blasBeta, &blasW1[0], &incy);
+ dgemv_(&blasNT, &planeNoA3, &varNo, &blas1, &blasA1[0], &planeNoA3, &blasNewX[0], &incx, &blas1, &blasW1[0], &incy);
+
+ // w2 = A2*x + b2;
+ //noElements = 3+planeNoB;
+ dcopy_(&planeNoB3, &blasB2[0], &incx, &blasW2[0], &incy);
+ //blasM = 3+planeNoB; blasLDA = 3+planeNoB; blasN = varNo;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasA2[0], &blasLDA, &blasNewX[0], &incx, &blasBeta, &blasW2[0], &incy);
+ dgemv_(&blasNT, &planeNoB3, &varNo, &blas1, &blasA2[0], &planeNoB3, &blasNewX[0], &incx, &blas1, &blasW2[0], &incy);
+
+ //noElements = 3+planeNoA;
+ blasW1dot = ddot_(&planeNoA3, &blasW1[0], &incx, &blasW1[0], &incy);
+ //noElements = 3+planeNoB;
+ blasW2dot = ddot_(&planeNoB3, &blasW2[0], &incx, &blasW2[0], &incy);
+
+ //u1 = s*s - w1.dot(w1);
+ //u2 = s*s - w2.dot(w2);
+ u1 =s*s -blasW1dot;
+ u2 =s*s -blasW2dot;
+
+ //wL = bL - AL*x;
+ //noElements = planeNoAB;
+ dcopy_(&planeNoAB, &blasBL[0], &incx, &blasWL[0], &incy);
+ //blasM = planeNoAB; blasLDA = std::max(1,planeNoAB); blasN = varNo; blasAlpha = -1.0; blasBeta = 1.0;
+ //dgemv_(&transA, &blasM, &blasN, &blasAlpha, &blasAL[0], &blasLDA, &blasNewX[0], &incx, &blasBeta, &blasWL[0], &incy);
+ dgemv_(&blasNT, &planeNoAB, &varNo, &blasNeg1, &blasAL[0], &blas1planeNoAB, &blasNewX[0], &incx, &blas1, &blasWL[0], &incy);
+
+ count++;
+ if(count==200){
+ std::cout<<"count: "<<count<<", totalIter: "<<totalIter<<", backtrack: "<<backtrack<<"s : "<<s<<", u1: "<<u1<<", u2: "<<u2<<", wLmincoeff: "<<minWL<<endl;
+ //std::cout<<"wL: "<<endl<<wL<<endl<<endl;
+ }
+
+ wLlogsum = 0.0;
+ for (int i=0; i<planeNoAB; i++){
+ wLlogsum += log(blasWL[i]);
+ }
+
+ newval = /* c.transpose()*/blasNewX[3] - penalty*( log(u1) + log(u2) + wLlogsum );
+
+ count++;
+ if(backtrack<pow(10,-11) ){
+ std::cout<<"iter: "<<iter<<", totalIter: "<<totalIter<<", backtrack: "<<backtrack<<", val: "<<val<<", newval: "<<newval<<", t: "<<t<<", fprime: "<<blasFprime<<endl;
+
+ break;
+ }
+ }
+//timingDeltas->checkpoint("line search");
+
+ noElements = varNo;
+ dcopy_(&noElements, &blasNewX[0], &incx, &blasX[0], &incy);
+
+
+ if(blasFprime >0.0){
+ std::cout<<"count: "<<count<<", totalIter: "<<totalIter<<", blasFprime: "<<blasFprime<<endl;
+ }
+
+
+ if (-blasFprime*0.5 < NTTOL){
+ gap = 2.0*m/t;
+ //if (warmstart == true){break;}
+ if (gap < tol){
+ contactPt[0] = blasX[0]; contactPt[1]=blasX[1]; contactPt[2]=blasX[2];
+ //if(warmstart==true){std::cout<<" totalIter : "<<totalIter<<endl;}
+ Real fA = evaluatePP(cm1,state1,contactPt);
+ Real fB = evaluatePP(cm2,state2,contactPt);
+ if(fabs(fA-fB)>0.001 ){std::cout<<"inside fA-fB: "<<fA-fB<<endl;}
+
+//timingDeltas->checkpoint("newton");
+ return true;
+ }
+ t = std::min(t*mu, (2.0*m+1.0)/tol);
+ iter = 0;
+ totalIter = totalIter+1;
+ }
+ if(totalIter>100){
+
+ std::cout<<"totalIter: "<<totalIter<<", t: "<<t<<", gap: "<<2.0*m/t<<", blasFprime: "<<blasFprime<<endl;
+ for (int i=0; i<varNo; i++){
+ std::cout<<"blasStep, i"<<i<<", value: "<<blasStep[i]<<endl;
+ }
+ for (int i=0; i<varNo; i++){
+ std::cout<<"blasGrad, i"<<i<<", value: "<<blasGrad[i]<<endl;
+ }
+ return false;
+ //break;
+ }
+ iter++;
+ totalIter++;
+
+//timingDeltas->checkpoint("complete");
+}
+
+
+ return ( true );
+}
+
+
+
+
+
=== added file 'pkg/dem/Ig2_PP_PP_ScGeom.hpp'
--- pkg/dem/Ig2_PP_PP_ScGeom.hpp 1970-01-01 00:00:00 +0000
+++ pkg/dem/Ig2_PP_PP_ScGeom.hpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,128 @@
+/*CWBoon 2015 */
+/* C.W. Boon, G.T. Houlsby, S. Utili (2013). A new contact detection algorithm for three-dimensional non-spherical particles. Powder Technology, 248, pp 94-102. */
+/* code for calling MOSEK was for ver 6. Please uncomment if you have the licence */
+
+#pragma once
+#include<lib/serialization/Serializable.hpp>
+#include<pkg/dem/PotentialParticle.hpp>
+#include<pkg/common/Dispatching.hpp>
+#include<pkg/common/Sphere.hpp>
+#include<Python.h>
+#include<Eigen/Core>
+#include <stdio.h>
+
+# if 0
+#include <mosek.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+
+class Ig2_PP_PP_ScGeom: public IGeomFunctor
+{
+
+ //protected:
+ //static std::ofstream output;
+#if 0
+ std::string myfile;
+ std::string Key;
+ MSKrescodee mosekTaskEnv;
+ MSKenv_t mosekEnv;
+
+#endif
+
+
+ public :
+ virtual bool go(const shared_ptr<Shape>& cm1, const shared_ptr<Shape>& cm2, const State& state1, const State& se32, const Vector3r& shift2, const bool& force, const shared_ptr<Interaction>& c);
+
+
+
+ double evaluatePP(const shared_ptr<Shape>& cm1, const State& state1, const Vector3r newTrial);
+ void getPtOnParticle2(const shared_ptr<Shape>& cm1, const State& state1, Vector3r previousPt, Vector3r normal, Vector3r& newlocalPoint);
+
+ bool contactPtMosekF2(const shared_ptr<Shape>& cm1, const State& state1, const shared_ptr<Shape>& cm2, const State& state2, Vector3r &contactPt);
+
+ bool customSolve(const shared_ptr<Shape>& cm1, const State& state1, const shared_ptr<Shape>& cm2, const State& state2, Vector3r &contactPt, bool warmstart);
+
+
+ Vector3r getNormal(const shared_ptr<Shape>& cm1, const State& state1, const Vector3r newTrial);
+
+ void BrentZeroSurf(const shared_ptr<Shape>& cm1, const State& state1, const Vector3r bracketA, const Vector3r bracketB, Vector3r& zero);
+
+
+
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+ YADE_CLASS_BASE_DOC_ATTRS_CTOR(Ig2_PP_PP_ScGeom,IGeomFunctor,"pp",
+ ((double, accuracyTol, pow(10,-7),, "accuracy desired, tolerance criteria for SOCP"))
+ ((double,interactionDetectionFactor,1.0,,"bool to avoid granular ratcheting")),
+ //((std::string,myfile,"./PotentialParticles"+"","string")),
+ //timingDeltas=shared_ptr<TimingDeltas>(new TimingDeltas);
+ //mosekTaskEnv = MSK_makeenv(&mosekEnv,NULL,NULL,NULL,NULL);
+ //mosekTaskEnv = MSK_initenv(mosekEnv);
+ );
+
+
+
+
+ FUNCTOR2D(PotentialParticle,PotentialParticle);
+ // needed for the dispatcher, even if it is symmetric
+ DEFINE_FUNCTOR_ORDER_2D(PotentialParticle,PotentialParticle);
+ DECLARE_LOGGER;
+
+
+
+
+};
+
+REGISTER_SERIALIZABLE(Ig2_PP_PP_ScGeom);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* LAPACK LU */
+ //int dgesv(int varNo, int varNo2, double *H, int varNo3, int *pivot, double* g, int varNo4, int info){
+ extern void dgesv_(const int *N, const int *nrhs, double *Hessian, const int *lda, int *ipiv, double *gradient, const int *ldb, int *info);
+ // int ans;
+ // dgesv_(&varNo, &varNo2, H, &varNo3, pivot,g, &varNo4, &ans);
+ // return ans;
+ //}
+
+/* LAPACK Cholesky */
+ extern void dpbsv_(const char *uplo, const int *n, const int *kd, const int *nrhs, double *AB, const int *ldab, double *B, const int *ldb, int *info);
+
+/* LAPACK QR */
+ extern void dgels_(const char *Trans, const int *m, const int *n, const int *nrhs, double *A, const int *lda, double *B, const int *ldb, const double *work, const int *lwork, int *info);
+
+
+/*BLAS */
+ extern void dgemm_(const char *transA, const char *transB, const int *m, const int *n, const int *k, const double *alpha, double *A, const int *lda, double *B, const int *ldb, const double *beta, double *C, const int *ldc);
+
+ extern void dgemv_(const char *trans, const int *m, const int *n, const double *alpha, double *A, const int *lda, double *x, const int *incx, const double *beta, double *y, const int *incy);
+
+ extern void dcopy_(const int *N, double *x, const int *incx, double *y, const int *incy);
+
+ extern double ddot_(const int *N, double *x, const int *incx, double *y, const int *incy);
+
+ extern void daxpy_(const int *N, const double *da, double *dx, const int *incx, double *dy, const int *incy);
+
+ extern void dscal_(const int *N, const double *alpha, double *x, const int *incx);
+
+
+ void dsyev_(const char *jobz, const char *uplo, const int *N, double *A, const int *lda, double *W, double *work, int *lwork, int *info);
+
+
+#ifdef __cplusplus
+};
+#endif
+
+
+
+
=== added file 'pkg/dem/KnKsLaw.cpp'
--- pkg/dem/KnKsLaw.cpp 1970-01-01 00:00:00 +0000
+++ pkg/dem/KnKsLaw.cpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,312 @@
+#include"KnKsLaw.hpp"
+#include<core/Scene.hpp>
+#include<pkg/dem/ScGeom.hpp>
+#include<core/Omega.hpp>
+#include<pkg/dem/PotentialParticle.hpp>
+
+YADE_PLUGIN((Law2_SCG_KnKsPhys_KnKsLaw)(Ip2_FrictMat_FrictMat_KnKsPhys)(KnKsPhys)
+
+);
+
+
+
+/********************** Law2_Dem3DofGeom_RockPMPhys_Rpm ****************************/
+CREATE_LOGGER(Law2_SCG_KnKsPhys_KnKsLaw);
+
+
+
+bool Law2_SCG_KnKsPhys_KnKsLaw::go(shared_ptr<IGeom>& ig, shared_ptr<IPhys>& ip, Interaction* contact){
+ const Real& dt = scene->dt;
+ int id1 = contact->getId1(); int id2 = contact->getId2();
+ ScGeom* geom= static_cast<ScGeom*>(ig.get());
+ KnKsPhys* phys = static_cast<KnKsPhys*>(ip.get());
+ State* de1 = Body::byId(id1,scene)->state.get();
+ State* de2 = Body::byId(id2,scene)->state.get();
+ Shape* shape1 = Body::byId(id1,scene)->shape.get();
+ Shape* shape2 = Body::byId(id2,scene)->shape.get();
+ PotentialParticle *s1=static_cast<PotentialParticle*>(shape1);
+ PotentialParticle *s2=static_cast<PotentialParticle*>(shape2);
+ Vector3r& shearForce = phys->shearForce;
+ Real un=geom->penetrationDepth;
+ TRVAR3(geom->penetrationDepth,de1->se3.position,de2->se3.position);
+
+/* Need to initialise in python. In the 1st time step. All the particles in contact (controlled by initialOverlap) are identified. The interactions are set to tensile and cohesive (tensionBroken = false and cohesionBroken = false). If there is no initial tension or cohesion, the contact law is run in a tensionless or cohesionless mode */
+
+ if(geom->penetrationDepth <0.0 ){
+ if (neverErase) {
+ phys->shearForce = Vector3r::Zero();
+ phys->normalForce = Vector3r::Zero();
+ phys->normalViscous = Vector3r::Zero();
+ geom->normal = Vector3r::Zero();
+ phys->tensionBroken = true;
+ }else{
+ scene->interactions->requestErase(id1,id2);
+ return false;
+ }
+ return true;
+ }
+
+ Vector3r shearForceBeforeRotate = shearForce;
+ Vector3r shiftVel = Vector3r(0,0,0); //scene->isPeriodic ? (Vector3r)((scene->cell->velGrad*scene->cell->Hsize)*Vector3r((Real) contact->cellDist[0],(Real) contact->cellDist[1],(Real) contact->cellDist[2])) : Vector3r::Zero();
+ geom->rotate(shearForce); //AndGetShear(shearForce,phys->prevNormal,de1,de2,dt,shiftVel,/*avoid ratcheting*/false);
+Vector3r shearForceAfterRotate = shearForce;
+ //Linear elasticity giving "trial" shear force
+ Vector3r shift2(0,0,0);
+ Vector3r incidentV = geom->getIncidentVel(de1, de2, scene->dt, shift2, shiftVel, /*preventGranularRatcheting*/false );
+ Vector3r incidentVn = geom->normal.dot(incidentV)*geom->normal; // contact normal velocity
+ Vector3r incidentVs = incidentV-incidentVn; // contact shear velocity
+ Vector3r shearIncrement=incidentVs*scene->dt;
+ phys->shearDir = shearIncrement;
+ phys->shearIncrementForCD += shearIncrement.norm();
+ double du = 0.0; double debugFn = 0.0;
+ double u_prev = fabs(phys->u_cumulative);
+ if(phys->shearDir.norm() > pow(10,-15)){
+ phys->shearDir.normalize();
+ }
+ double degradeLength = phys->brittleLength; /*jointLength = 100u_peak */
+ /* Elastic and plastic displacement can have negative signs but must be consistent throughout the simulation */
+ if(phys->initialShearDir.norm() < pow(10,-11)){
+ phys->initialShearDir = phys->shearDir;
+ du = shearIncrement.norm();
+ if(fabs(phys->mobilizedShear)>0.99999){
+ phys->u_cumulative += du;
+ phys->cumulative_us += du;
+ }else{
+ phys->u_elastic +=du;
+ }
+ }else{
+ du = Mathr::Sign(phys->initialShearDir.dot(phys->shearDir))*shearIncrement.norm(); //check cumulative shear displacement
+ if(fabs(phys->mobilizedShear) > 0.99999){
+ if(du>0.0){ //if negative it means it is unloading
+ phys->u_cumulative += du;
+ phys->cumulative_us += du;
+ }else{
+ phys->u_elastic +=du;
+ }
+ }else{
+ phys->u_elastic +=du;
+ }
+ }
+
+
+ /* Original */
+ if(phys->twoDimension) { phys->contactArea = phys->unitWidth2D*phys->jointLength;}
+ if(s1->isBoundary == true || s2->isBoundary==true){phys->tensionBroken = true; phys->cohesionBroken = true;}
+ if(!Talesnick){
+ un = un-initialOverlapDistance;
+
+ #if 0
+ if(un > 0.0 && phys->rockJointContact == true ){
+ if(phys->cohesionBroken == true && phys->intactRock == true && phys->shearForce.norm()>phys->normalForce.norm()*tan(phys->phi_r/180.0*3.14159) ){
+ phys->dilation_angle = atan(shearForce.norm()/std::max(0.00001,phys->normalForce.norm()));
+ double dilate_inc = tan( phys->dilation_angle - phys->phi_r/180.0*3.141592653589)*du; /* du could be negative */
+ phys->u_dilate += dilate_inc;
+ phys->u_dilate = std::min(phys->u_dilate,0.1);
+ }
+ //un = un+phys->u_dilate;
+ phys->kn = ((1.0 - un/phys->maxClosure)*(phys->kn_i) - (un*phys->kn_i)*(-1.0/phys->maxClosure) )/pow( (1.0-un/phys->maxClosure),2);
+ phys->prevSigma = un*phys->kn_i/(1.0 - std::min(un/phys->maxClosure,0.999) );
+ }//else{
+ #endif
+
+ if (phys->jointType==3){
+ phys->prevSigma = un*phys->kn_i/(1.0-un/phys->maxClosure);
+ }else{
+ phys->prevSigma = phys->kn*un;
+ }
+ //}
+ phys->normalForce = phys->prevSigma*std::max(pow(10,-15),phys->contactArea)*geom->normal;
+ }
+
+ phys->Knormal_area = phys->kn*std::max(pow(10,-8),phys->contactArea);
+
+ if((un <0.0 && fabs(phys->prevSigma)>phys->tension && phys->tensionBroken == false /* first time tension is broken */) || (un<0.0 && phys->tensionBroken==true)){
+ if (neverErase) {
+ phys->shearForce = Vector3r::Zero();
+ phys->normalForce = Vector3r::Zero();
+ phys->normalViscous = Vector3r::Zero();
+ geom->normal = Vector3r::Zero();
+ phys->tensionBroken = true;
+ }else {
+ return false;
+ }
+ return true;
+ }
+
+
+
+
+ /*ORIGINAL */
+ Vector3r c1x = geom->contactPoint - de1->pos;
+ Vector3r c2x = geom->contactPoint - de2->pos;
+ incidentV = (de2->vel+de2->angVel.cross(c2x)) - (de1->vel+de1->angVel.cross(c1x));
+ incidentVn = geom->normal.dot(incidentV)*geom->normal; // contact normal velocity
+ incidentVs = incidentV-incidentVn; // contact shear velocity
+ shearIncrement=incidentVs*scene->dt;
+ if(!Talesnick){
+ double Ks=0.0;
+ if(phys->jointType == 3){
+ Ks = phys->ks_i*pow(phys->prevSigma,0.6);
+ }else{
+ Ks = phys->ks;
+ }
+ shearForce -= Ks*shearIncrement*std::max(pow(10,-11),phys->contactArea);
+ }
+ phys->Kshear_area = phys->ks*std::max(pow(10,-11),phys->contactArea);
+
+
+ const shared_ptr<Body>& b1=Body::byId(id1,scene);
+ const shared_ptr<Body>& b2=Body::byId(id2,scene);
+ Real mbar = (!b1->isDynamic() && b2->isDynamic()) ? de2->mass : ((!b2->isDynamic() && b1->isDynamic()) ? de1->mass : (de1->mass*de2->mass / (de1->mass + de2->mass))); // get equivalent mass if both bodies are dynamic, if not set it equal to the one of the dynamic body
+ Real Cn_crit = 2.*sqrt(mbar*phys->Knormal_area); // Knormal_area Critical damping coefficient (normal direction)
+ Real Cs_crit = 2.*sqrt(mbar*phys->Kshear_area); // Kshear_area Critical damping coefficient (shear direction)
+ // Note: to compare with the analytical solution you provide cn and cs directly (since here we used a different method to define c_crit)
+ double cn = Cn_crit*phys->viscousDamping; // Damping normal coefficient
+ double cs = Cs_crit*phys->viscousDamping; // Damping tangential coefficient
+
+ // add normal viscous component if damping is included
+ double maxFnViscous = phys->normalForce.norm();
+ phys->normalViscous = cn*incidentVn;
+ //if(phys->normalViscous.norm() > maxFnViscous){
+ // phys->normalViscous = phys->normalViscous * maxFnViscous/phys->normalViscous.norm();
+ //}
+ phys->normalForce -= phys->normalViscous;
+ double baseElevation = geom->contactPoint.z();
+
+ /* Water pressure, heat effect */
+
+ /* strength degradation */
+ const double PI = std::atan(1.0)*4;
+ double tan_effective_phi = 0.0;
+
+
+
+ if(s1->isBoundary==true || s2->isBoundary == true || phys->jointType==2 ){ // clay layer at boundary;
+ phys->effective_phi = phys->phi_b; // - 3.25*(1.0-exp(-fabs(phys->cumulative_us)/0.4));
+ tan_effective_phi = tan(phys->effective_phi/180.0*PI);
+ }else if(phys->intactRock == true){
+
+ phys->effective_phi = phys->phi_r + (phys->phi_b-phys->phi_r)*(exp(-fabs(phys->u_cumulative)/degradeLength));
+ tan_effective_phi = tan(phys->effective_phi/180.0*PI);
+ }else{
+ phys->effective_phi = phys->phi_b;
+ tan_effective_phi = tan(phys->effective_phi/180.0*PI);
+ }
+
+
+
+ /* shear loss */
+ Vector3r dampedShearForce = shearForce;
+ double cohesiveForce = phys->cohesion*std::max(pow(10,-11),phys->contactArea);
+ Real maxFs = cohesiveForce;
+ if (un>0.0 /*compression*/){
+ double fN = phys->normalForce.norm();
+ if(phys->intactRock == true){
+ if (phys->cohesionBroken == true && allowBreakage == true){
+ maxFs = std::max( fN,0.0)*tan_effective_phi;
+ }else{
+ maxFs = cohesiveForce+std::max( fN,0.0)*tan_effective_phi;
+ }
+ }else{
+ maxFs = std::max( fN,0.0)*tan_effective_phi;
+ }
+ }
+ if( shearForce.norm() > maxFs ){
+ Real ratio = maxFs / shearForce.norm();
+ shearForce *= ratio;
+ dampedShearForce = shearForce;
+ if(allowBreakage == true){
+ phys->cohesionBroken = true;
+ }
+ phys->shearViscous = Vector3r(0,0,0);
+ }else{ /* no damping when it slides */
+ phys->shearViscous = cs*incidentVs;
+ dampedShearForce = shearForce - phys->shearViscous;
+ }
+ if(shearForce.norm() < pow(10,-11) ){phys->mobilizedShear = 1.0;}else{phys->mobilizedShear = shearForce.norm()/maxFs;}
+
+
+
+ //we need to use correct branches in the periodic case, the following apply for spheres only
+ Vector3r force = -phys->normalForce-dampedShearForce;
+ if(isnan(force.norm())){
+ std::cout<<"shearForce: "<<shearForce<<", normalForce: "<<phys->normalForce<<", debugFn: "<<debugFn<<", viscous: "<<phys->normalViscous<<", normal: "<<phys->normal<<", geom normal: "<<geom->normal<<", effective_phi: "<<phys->effective_phi<<", shearIncrement: "<<shearIncrement<<", id1: "<<id1<<", id2: "<<id2<<", shearForceBeforeRotate: "<<shearForceBeforeRotate<<", shearForceAfterRotate: " <<shearForceAfterRotate<<endl;
+ }
+ scene->forces.addForce(id1,force);
+ scene->forces.addForce(id2,-force);
+ Vector3r normal = geom->normal;
+ scene->forces.addTorque(id1,c1x.cross(force));
+ scene->forces.addTorque(id2,-(c2x).cross(force));
+
+ phys->prevNormal = geom->normal;
+
+ return true;
+
+}
+
+
+
+CREATE_LOGGER(Ip2_FrictMat_FrictMat_KnKsPhys);
+
+
+
+
+void Ip2_FrictMat_FrictMat_KnKsPhys::go(const shared_ptr<Material>& b1, const shared_ptr<Material>& b2, const shared_ptr<Interaction>& interaction){
+
+ const double PI = 3.14159265358979323846;
+ if(interaction->phys) return;
+
+ ScGeom* scg=YADE_CAST<ScGeom*>(interaction->geom.get());
+
+ assert(scg);
+
+ const shared_ptr<FrictMat>& sdec1 = YADE_PTR_CAST<FrictMat>(b1);
+ const shared_ptr<FrictMat>& sdec2 = YADE_PTR_CAST<FrictMat>(b2);
+
+ shared_ptr<KnKsPhys> contactPhysics(new KnKsPhys());
+ //interaction->interactionPhysics = shared_ptr<MomentPhys>(new MomentPhys());
+ //const shared_ptr<MomentPhys>& contactPhysics = YADE_PTR_CAST<MomentPhys>(interaction->interactionPhysics);
+
+ /* From interaction physics */
+ Real fa = sdec1->frictionAngle;
+ Real fb = sdec2->frictionAngle;
+
+
+ /* calculate stiffness */
+ Real Kn= Knormal;
+ Real Ks= Kshear;
+
+ /* Pass values calculated from above to CSPhys */
+ contactPhysics->viscousDamping = viscousDamping;
+ contactPhysics->useOverlapVol = useOverlapVol;
+ contactPhysics->kn = Kn;
+ contactPhysics->ks = Ks;
+ contactPhysics->kn_i = Kn;
+ contactPhysics->ks_i = Ks;
+ contactPhysics->u_peak = u_peak;
+ contactPhysics->maxClosure = maxClosure;
+ contactPhysics->cohesionBroken = cohesionBroken;
+ contactPhysics->tensionBroken = tensionBroken;
+ contactPhysics->unitWidth2D = unitWidth2D;
+ contactPhysics->frictionAngle = std::min(fa,fb);
+ if(!useFaceProperties){
+ contactPhysics->phi_r = std::min(fa,fb)/PI*180.0;
+ contactPhysics->phi_b = contactPhysics->phi_r;
+ }
+ contactPhysics->tanFrictionAngle = std::tan(contactPhysics->frictionAngle);
+ //contactPhysics->initialOrientation1 = Body::byId(interaction->getId1())->state->ori;
+ //contactPhysics->initialOrientation2 = Body::byId(interaction->getId2())->state->ori;
+ contactPhysics->prevNormal = scg->normal; //This is also done in the Contact Law. It is not redundant because this class is only called ONCE!
+ contactPhysics->calJointLength = calJointLength;
+ contactPhysics->twoDimension = twoDimension;
+ contactPhysics->useFaceProperties = useFaceProperties;
+ contactPhysics->brittleLength = brittleLength;
+ interaction->phys = contactPhysics;
+
+}
+
+CREATE_LOGGER(KnKsPhys);
+/* KnKsPhys */
+KnKsPhys::~KnKsPhys(){}
+
+
=== added file 'pkg/dem/KnKsLaw.hpp'
--- pkg/dem/KnKsLaw.hpp 1970-01-01 00:00:00 +0000
+++ pkg/dem/KnKsLaw.hpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,194 @@
+#pragma once
+#include<pkg/common/ElastMat.hpp>
+#include<pkg/common/Dispatching.hpp>
+#include<pkg/common/NormShearPhys.hpp>
+#include<pkg/dem/FrictPhys.hpp>
+#include<pkg/dem/ScGeom.hpp>
+#include <set>
+#include <boost/tuple/tuple.hpp>
+
+
+
+class KnKsPhys: public FrictPhys {
+
+
+
+
+ public:
+
+ virtual ~KnKsPhys();
+ YADE_CLASS_BASE_DOC_ATTRS_CTOR(KnKsPhys,FrictPhys,"Simple phys",
+ ((vector<double>,lambdaIPOPT,0.0,,"lagrane multiplier for equality constraints"))
+ ((vector<int>,cstatCPLEX,,,"lagrane multiplier for equality constraints"))
+ ((vector<int>,rstatCPLEX,,,"lagrane multiplier for equality constraints"))
+ ((Real,frictionAngle,0.0,,"fric angle"))
+ ((Real,tanFrictionAngle,0.0,,"tangent of fric angle"))
+ ((Vector3r,contactDetectionPt,Vector3r(0,0,0),,"contact detection result"))
+ ((Real, viscousDamping, 0.8, ,"viscousDamping"))
+ ((Real, unitWidth2D, 1.0, ,"viscousDamping"))
+ ((Real, maxClosure, 0.0002, ,"vmi"))
+ ((Real, u_peak, 0.05, ,"peak shear displacement"))
+ ((Real, u_elastic, 0.0, ,"elastic shear displacement"))
+ ((double, brittleLength, 5.0, ,"brittle rock"))
+ ((double, kn_i, 5.0, ,"initial normal stiffness"))
+ ((double, ks_i, 5.0, ,"initial shear stiffness"))
+ ((Vector3r, normalViscous, Vector3r(0,0,0), ,"viscousDamping"))
+ ((Vector3r, shearViscous, Vector3r(0,0,0), ,"viscousDamping"))
+ ((double, hwater, 0.0, ,"height of pore water"))
+ ((bool, rockJointContact, false, ,"brittle rock"))
+ ((bool, intactRock, false, ,"brittle rock"))
+ ((int, jointType, 0, ,"jointType"))
+ ((Real,Kshear_area,0.0,,"kshear area"))
+ ((Real,Knormal_area, 0.0,,"knormal area"))
+ ((Vector3r, shearDir, Vector3r(0,0,0), ,"shear direction"))
+ ((vector<Vector3r>, shearForces, , ,"shear direction"))
+ ((Vector3r, shear, Vector3r(0,0,0),, "shear displacement"))
+ ((Vector3r, prevNormal, Vector3r(0.0,0.0,0.0),, "previous Normal"))
+ ((Vector3r, normal, Vector3r(0.0,0.0,0.0),, " normalVector"))
+ ((vector<Vector3r>, pointsArea, ,, "intermediate contact points"))
+ ((vector<Vector3r>, pointsShear, ,, "points to calculate shear"))
+ ((vector<double>, areaShear, ,, "area to attribute shear"))
+ ((vector<double>, overlapDistances, ,, "area to attribute shear"))
+ ((Real, finalSize, 0.0,, "finalgridsize"))
+ ((int, finalGridNo, 0,, "final number of grids"))
+ ((vector<double>, dualityGap, , ,"duality gap for SOCP"))
+ ((bool, warmstart, false, ,"warmstart for SOCP"))
+ ((int, generation, 0,, "number of subdivisions"))
+ ((int, triNoMain, 24,, "number of subdivisions"))
+ ((int, triNoSub, 6,, "number of subdivisions"))
+ ((Vector3r, initial1, Vector3r(0.0,0.0,0.0),, "midpoint"))
+ ((Vector3r, ptOnP1, Vector3r(0.0,0.0,0.0),, "pt on particle"))
+ ((Vector3r, ptOnP2, Vector3r(0.0,0.0,0.0),, " pt on particle 2"))
+ ((vector<bool>, redundantA, , ,"activePlanes for interaction.id1"))
+ ((vector<bool>, redundantB, , ,"activePlanes for interaction.id1"))
+ ((vector<bool>, activePlanes1, , ,"activePlanes for interaction.id1"))
+ ((vector<bool>, activePlanes2, , ,"activePlanes for interaction.id2"))
+ ((vector<Real>, activeA1, , ,"activePlanes for interaction.id2"))
+ ((vector<Real>, activeB1, , ,"activePlanes for interaction.id2"))
+ ((vector<Real>, activeC1, , ,"activePlanes for interaction.id2"))
+ ((vector<Real>, activeD1, , ,"activePlanes for interaction.id2"))
+ ((vector<Real>, activeA2, , ,"activePlanes for interaction.id2"))
+ ((vector<Real>, activeB2, , ,"activePlanes for interaction.id2"))
+ ((vector<Real>, activeC2, , ,"activePlanes for interaction.id2"))
+ ((vector<Real>, activeD2, , ,"activePlanes for interaction.id2"))
+ ((int, noActive1, 0, ,"activePlanes for interaction.id1"))
+ ((int, noActive2,0 , ,"activePlanes for interaction.id2"))
+ ((int, smallerID,1 , ,"id of particle with smaller plane"))
+ ((Real, cumulative_us, 0.0,, "cumulative translation"))
+ ((Real, cumulativeRotation, 0.0,, "cumulative rotation"))
+ ((Real, mobilizedShear, , ,"mobilizedShear"))
+ ((Real, contactArea, 0.0, ,"contactArea"))
+ ((Real, radCurvFace, , ,"face"))
+ ((double, prevJointLength, 0.0, ,"previous joint length"))
+ ((Real, radCurvCorner, , ,"corners"))
+ ((Real, prevSigma,0.0 , ,"previous normal stress"))
+ ((vector<Real>, prevSigmaList,0.0 , ,"previous normal stress"))
+ ((bool, calJointLength, false,, "calculate joint length"))
+ ((bool, useOverlapVol, false,, "calculate overlap volume"))
+ ((bool, calContactArea, false,, "calculate contact area"))
+ ((double, jointLength, 0.0,, "approximatedJointLength"))
+ ((double, shearIncrementForCD, 0.0,, "toSeeWhether it is necessary to update contactArea"))
+ ((Real, overlappingVol,0.0 , ,"overlapping vol"))
+ ((Real, overlappingVolMulti,0.0 , ,"overlapping vol"))
+ ((double, gap_normalized, 0.0,, "distance between particles normalized by particle size. Estimated using Taubin Distance "))
+ ((double, gap, 0.0,, "distance between particles normalized by particle size. Estimated using Taubin Distance "))
+ ((bool, findCurv, false,, "to get radius of curvature"))
+ ((bool, useFaceProperties, false,,"boolean to get face properites"))
+ ((Real, cohesion, 0.0, ,"cohesion"))
+ ((Real, tension, 0.0, ,"tension"))
+ ((bool, cohesionBroken, true, ,"cohesion already broken"))
+ ((bool, tensionBroken, true, ,"tension already broken"))
+ ((bool, twoDimension, false, ,"tension already broken"))
+ ((Real, phi_b, 0.0, ,"basic friction angle (degrees)"))
+ ((Real, phi_r, 0.0, ,"residual friction angle (degrees)"))
+ ((Real, asperity, 3.0, ,"asperity height"))
+ ((Real, JRC, 0.0, ,"Joint Roughness Coefficient"))
+ ((Real, JRCmobilized, 0.0, ,"Joint Roughness Coefficient"))
+ ((Real, JCS, 0.0, ,"Joint Roughness Coefficient"))
+ ((Real, sigmaC,0.0 , ,"Joint Roughness Coefficient"))
+ ((Real, u_dilate,0.0 , ,"dilation distance"))
+ ((Real, dilation_angle,0.0 , ,"dilation distance"))
+ /* pore water pressure */
+ ((Real, lambda0,0.0 , ,"initial pore water pressure to stress ratio"))
+ ((Real, lambda_present,0.0 , ,"Voight&Faust (1992) Sitar et al. (2005)"))
+ ((Real, u_cumulative, 0.0,, "cumulative translation"))
+ ((Vector3r, prevShearDir, Vector3r(0.0,0.0,0.0),, "previous shear direction"))
+ ((Vector3r, initialShearDir, Vector3r(0.0,0.0,0.0),, "previous shear direction"))
+ ((double, delta_porePressure, 0.0,, "change in pore water pressure"))
+ ((double, porePressure, 0.0,, "pore water pressure"))
+ ((double, bandThickness, 0.1,, "clay layer thickness"))
+ ((double, heatCapacities, 0.0,, "clay layer thickness"))
+ ((double, effective_phi, 0.0,, "friction angle in clay after displacement"))
+ ((double, prevOverlap, 0.0,, "friction angle in clay after displacement"))
+ ((Real, h, 0.0,,"cd")),
+
+ //((Real, cumulativeRotation, 0.0,, "cumulative rotation"))
+ //((Quaternionr, initialOrientation1, Quaternionr(1.0,0.0,0.0,0.0),, "orientation1"))
+ //((Quaternionr, initialOrientation2, Quaternionr(1.0,0.0,0.0,0.0),, "orientation2")),
+ createIndex();
+
+ );
+
+ REGISTER_CLASS_INDEX(KnKsPhys,FrictPhys);
+ DECLARE_LOGGER;
+};
+REGISTER_SERIALIZABLE(KnKsPhys);
+
+
+
+
+class Ip2_FrictMat_FrictMat_KnKsPhys: public IPhysFunctor{
+ public:
+ virtual void go(const shared_ptr<Material>& pp1, const shared_ptr<Material>& pp2, const shared_ptr<Interaction>& interaction);
+ YADE_CLASS_BASE_DOC_ATTRS(Ip2_FrictMat_FrictMat_KnKsPhys,IPhysFunctor,"Calculation",
+ ((Real,Knormal,0.0,,"allows user to input values directly from python scripts"))
+ ((Real,Kshear,0.0,,"allows user to input values directly from python scripts"))
+ ((Real, unitWidth2D, 1.0, ,"viscousDamping"))
+ ((double, brittleLength, 3.0, ,"brittle rock"))
+ ((double, kn_i, 0.002, ,"brittle rock"))
+ ((double, ks_i, 0.002, ,"brittle rock"))
+ ((double, u_peak, -1.0, ,"brittle rock"))
+ ((double, maxClosure, 0.002, ,"brittle rock"))
+ ((Real, viscousDamping, 0.8, ,"viscousDamping"))
+ ((Real, cohesion, 0.0, ,"viscousDamping"))
+ ((Real, tension, 0.0, ,"viscousDamping"))
+ ((bool, cohesionBroken, true, ,"cohesion"))
+ ((bool, tensionBroken, true, ,"tension"))
+ ((Real, phi_b, 0.0, ,"viscousDamping"))
+ ((bool, useOverlapVol, false,, "calculate overlap volume"))
+ ((bool, useFaceProperties, false,,"boolean to get face properites"))
+ ((bool, calJointLength, false,, "calculate joint length"))
+ ((bool, twoDimension, false, ,"tension already broken"))
+ );
+ FUNCTOR2D(FrictMat,FrictMat);
+ DECLARE_LOGGER;
+};
+REGISTER_SERIALIZABLE(Ip2_FrictMat_FrictMat_KnKsPhys);
+
+
+
+class Law2_SCG_KnKsPhys_KnKsLaw: public LawFunctor{
+ public:
+
+ static Real Real0;
+ //OpenMPAccumulator<Real,&Law2_SCG_KnKsPhys_KnKsLaw::Real0> plasticDissipation;
+ virtual bool go(shared_ptr<IGeom>& _geom, shared_ptr<IPhys>& _phys, Interaction* I);
+ FUNCTOR2D(ScGeom,KnKsPhys);
+ YADE_CLASS_BASE_DOC_ATTRS_CTOR_PY(Law2_SCG_KnKsPhys_KnKsLaw,LawFunctor,"Law for linear compression, without cohesion and Mohr-Coulomb plasticity surface.\n\n.. note::\n This law uses :yref:`ScGeom`; there is also functionally equivalent :yref:`Law2_Dem3DofGeom_FrictPhys_Basic`, which uses :yref:`Dem3DofGeom` (sphere-box interactions are not implemented for the latest).",
+ ((bool,neverErase,false,,"Keep interactions even if particles go away from each other (only in case another constitutive law is in the scene, e.g. :yref:`Law2_ScGeom_CapillaryPhys_Capillarity`)"))
+ ((bool,preventGranularRatcheting,false,,"bool to avoid granular ratcheting"))
+ ((bool,traceEnergy,false,,"Define the total energy dissipated in plastic slips at all contacts."))
+ ((bool,Talesnick,false,,"Define the total energy dissipated in plastic slips at all contacts."))
+ ((double,waterLevel,0.0,,"Define the total energy dissipated in plastic slips at all contacts."))
+ ((bool, allowBreakage, false, ,"cohesion = 0, once broken"))
+ ((double,initialOverlapDistance,0.0,,"initial overlap distance"))
+ ,,
+
+ );
+
+ DECLARE_LOGGER;
+};
+REGISTER_SERIALIZABLE(Law2_SCG_KnKsPhys_KnKsLaw);
+
+
+
=== added file 'pkg/dem/PotentialParticle.cpp'
--- pkg/dem/PotentialParticle.cpp 1970-01-01 00:00:00 +0000
+++ pkg/dem/PotentialParticle.cpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,14 @@
+/*CWBoon 2015 */
+
+ //! To implement potential particles (Houlsby 2009) using sphere
+#include "PotentialParticle.hpp"
+
+YADE_PLUGIN((PotentialParticle));
+
+
+PotentialParticle::~PotentialParticle()
+{
+}
+
+
+
=== added file 'pkg/dem/PotentialParticle.hpp'
--- pkg/dem/PotentialParticle.hpp 1970-01-01 00:00:00 +0000
+++ pkg/dem/PotentialParticle.hpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,70 @@
+/*CWBoon 2015 */
+
+#pragma once
+
+#include<vector>
+#include<core/Shape.hpp>
+#include<Eigen/Core>
+#include <Eigen/LU>
+#include <Eigen/QR>
+#include<lib/base/openmp-accu.hpp>
+namespace yade{
+class PotentialParticle : public Shape
+{
+
+ public:
+
+
+ virtual ~PotentialParticle ();
+
+
+ YADE_CLASS_BASE_DOC_ATTRS_CTOR(PotentialParticle,Shape,"Geometry of PotentialParticle.",
+ ((int, id, 1,, "idNo"))
+ ((bool, isBoundary, false,, "boundary"))
+ ((bool, fixedNormal, false,, "use fixed normal"))
+ ((Vector3r, boundaryNormal, Vector3r::Zero(),,"normal direction of boundary"))
+ ((bool, AabbMinMax, false,, "aabb"))
+ ((Vector3r, minAabb, Vector3r::Zero(),,"min from box centre"))
+ ((Vector3r, maxAabb, Vector3r::Zero(),,"max frin box centre"))
+ ((Vector3r, minAabbRotated, Vector3r::Zero(),,"min from box centre"))
+ ((Vector3r, maxAabbRotated, Vector3r::Zero(),,"max frin box centre"))
+ ((Vector3r, halfSize, Vector3r::Zero(),,"max frin box centre"))
+ ((Quaternionr , oriAabb, Quaternionr::Identity(),, "r "))
+ ((Real , r, 0.1,, "r "))
+ ((Real , R, 1.0,, "R "))
+ ((Real , k, 0.1,, "k "))
+ ((vector<Vector3r>, vertices,,,"vertices"))
+ ((vector<bool> , isBoundaryPlane, ,, "whether it is a boundaryPlane "))
+ ((vector<double> , a, ,, "a "))
+ ((vector<double> , b, ,, "b "))
+ ((vector<double> , c, ,, "c "))
+ ((vector<double> , d, ,, "d "))
+ ,
+ createIndex(); /*ctor*/
+ #if 0
+ for (int i=0; i<a.size(); i++){
+ Amatrix(i,0) = a[i]; Amatrix(i,1)=b[i]; Amatrix(i,2)=c[i];
+ Dmatrix(i,0) = d[i] + r;
+ }
+ #endif
+
+ );
+ //#endif
+
+ REGISTER_CLASS_INDEX(PotentialParticle,Shape);
+
+};
+}
+using namespace yade;
+
+REGISTER_SERIALIZABLE(PotentialParticle);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void dgesv_(const int *N, const int *nrhs, double *Hessian, const int *lda, int *ipiv, double *gradient, const int *ldb, int *info);
+ void dsyev_(const char *jobz, const char *uplo, const int *N, double *A, const int *lda, double *W, double *work, int *lwork, int *info);
+#ifdef __cplusplus
+};
+#endif
+
=== added file 'pkg/dem/PotentialParticle2AABB.cpp'
--- pkg/dem/PotentialParticle2AABB.cpp 1970-01-01 00:00:00 +0000
+++ pkg/dem/PotentialParticle2AABB.cpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,56 @@
+
+/*CWBoon 2015 */
+
+#include "PotentialParticle2AABB.hpp"
+#include<pkg/dem/PotentialParticle.hpp>
+#include<pkg/common/Aabb.hpp>
+
+void PotentialParticle2AABB::go(const shared_ptr<Shape>& cm, shared_ptr<Bound>& bv, const Se3r& se3, const Body*){
+ PotentialParticle* pp = static_cast<PotentialParticle*>(cm.get());
+ if(!bv){ bv=shared_ptr<Bound>(new Aabb); }
+ Aabb* aabb = static_cast<Aabb*>(bv.get());
+ Matrix3r r = se3.orientation.toRotationMatrix();
+
+ if(pp->AabbMinMax == false){
+ Real distFromCentre = 1.05*pp->R; // std::max(maxD, pp->R);
+ halfSize = Vector3r(distFromCentre,distFromCentre,distFromCentre);
+ aabb->min = se3.position-halfSize;
+ aabb->max = se3.position+halfSize;
+ return;
+ }else{
+ Matrix3r r=se3.orientation.toRotationMatrix();
+ Vector3r halfSizeMin(Vector3r::Zero());Vector3r halfSizeMax(Vector3r::Zero());
+ if(pp->vertices.size() ==0){
+ //pp->vertices.clear();
+ pp->vertices.push_back(Vector3r(pp->maxAabbRotated[0],pp->maxAabbRotated[1],pp->maxAabbRotated[2]));
+ pp->vertices.push_back(Vector3r(pp->maxAabbRotated[0],pp->maxAabbRotated[1],-pp->minAabbRotated[2]));
+ pp->vertices.push_back(Vector3r(-pp->minAabbRotated[0],-pp->minAabbRotated[1],pp->maxAabbRotated[2]));
+ pp->vertices.push_back(Vector3r(-pp->minAabbRotated[0],-pp->minAabbRotated[1],-pp->minAabbRotated[2]));
+ pp->vertices.push_back(Vector3r(-pp->minAabbRotated[0],pp->maxAabbRotated[1],pp->maxAabbRotated[2]));
+ pp->vertices.push_back(Vector3r(-pp->minAabbRotated[0],pp->maxAabbRotated[1],-pp->minAabbRotated[2]));
+ pp->vertices.push_back(Vector3r(pp->maxAabbRotated[0],-pp->minAabbRotated[1],pp->maxAabbRotated[2]));
+ pp->vertices.push_back(Vector3r(pp->maxAabbRotated[0],-pp->minAabbRotated[1],-pp->minAabbRotated[2]));
+ }
+ Vector3r aabbMin(0,0,0);
+ Vector3r aabbMax(0,0,0);
+ for (int i=0; i<8; i++){
+ Vector3r vertex = r*(pp->oriAabb.conjugate()*pp->vertices[i]);
+ if(vertex.x() < aabbMin.x()){ aabbMin.x() = vertex.x(); }
+ if(vertex.y() < aabbMin.y()){ aabbMin.y() = vertex.y(); }
+ if(vertex.z() < aabbMin.z()){ aabbMin.z() = vertex.z(); }
+ if(vertex.x() > aabbMax.x()){ aabbMax.x() = vertex.x(); }
+ if(vertex.y() > aabbMax.y()){ aabbMax.y() = vertex.y(); }
+ if(vertex.z() > aabbMax.z()){ aabbMax.z() = vertex.z(); }
+ }
+ aabb->min= se3.position + 1.05*aabbMin;
+ aabb->max = se3.position + 1.05*aabbMax;
+ halfSizeMin = -1.0*aabbMin;
+ halfSizeMax = 1.0*aabbMax;
+
+
+ return;
+ }
+
+}
+
+YADE_PLUGIN((PotentialParticle2AABB));
=== added file 'pkg/dem/PotentialParticle2AABB.hpp'
--- pkg/dem/PotentialParticle2AABB.hpp 1970-01-01 00:00:00 +0000
+++ pkg/dem/PotentialParticle2AABB.hpp 2015-12-14 14:25:08 +0000
@@ -0,0 +1,24 @@
+/*CWBoon 2015 */
+
+#pragma once
+
+#include<pkg/common/Dispatching.hpp>
+#include<pkg/dem/PotentialParticle.hpp>
+
+class PotentialParticle2AABB : public BoundFunctor
+{
+ public :
+
+ void go(const shared_ptr<Shape>& cm, shared_ptr<Bound>& bv, const Se3r&, const Body*);
+
+ FUNCTOR1D(PotentialParticle);
+ //REGISTER_ATTRIBUTES(BoundFunctor,(aabbEnlargeFactor));
+ YADE_CLASS_BASE_DOC_ATTRS(PotentialParticle2AABB,BoundFunctor,"Functor creating :yref:`Aabb` from :yref:`Sphere`.",
+ ((Real,aabbEnlargeFactor,((void)"deactivated",-1),,"Relative enlargement of the bounding box; deactivated if negative.\n\n.. note::\n\tThis attribute is used to create distant interaction, but is only meaningful with an :yref:`InteractionGeometryFunctor` which will not simply discard such interactions: :yref:`Ig2_Sphere_Sphere_Dem3DofGeom::distFactor` / :yref:`Ig2_Sphere_Sphere_ScGeom::interactionDetectionFactor` should have the same value as :yref:`aabbEnlargeFactor<Bo1_Sphere_Aabb::aabbEnlargeFactor>`."))
+ ((Vector3r, halfSize, Vector3r::Zero(),,"halfSize"))
+
+ );
+};
+
+REGISTER_SERIALIZABLE(PotentialParticle2AABB);
+