from esys.lsm import *
from esys.lsm.util import *

class Loading (Runnable):
  def __init__(self,lsm,dx,t0,t1):
    Runnable.__init__(self)
    self.theLSM=lsm
    self.dx=dx
    self.ddx=self.dx/(t1-t0)
    self.t1=t1
    self.t0=0
    self.count=0
    
  def run(self):
    self.count=self.count+1
    if (self.count>self.t0):
      if (self.count<self.t1):
        cdx=self.ddx*(self.count-self.t0)
	self.theLSM.moveWallBy("lowerWall",Vec3(0.0,cdx,0.0))
	self.theLSM.moveWallBy("upperWall",Vec3(0.0,-1.0*cdx,0.0))
      else:
        self.theLSM.moveWallBy("lowerWall",Vec3(0.0,self.dx,0.0))
	self.theLSM.moveWallBy("upperWall",Vec3(0.0,-1.0*self.dx,0.0))
    if ((self.count%1000)==0):
      print self.count

def runSimulation():
  nt=1000
  dt_snap=100
  t0=0
  t1=500
  dt=0.04
  v=0.0005
  
#  setVerbosity(True)
  mySim=LsmMpi(
    numWorkerProcesses=2,
    mpiDimList=[1,2,0]
  )
  
  mySim.initNeighbourSearch (
    particleType = "RotSphere",
    gridSpacing=2.2,
    verletDist=0.1
  )
  
  mySim.initNeighbourSearch (
    particleType="RotSphere",
    gridSpacing=2.2,
    verletDist=0.1
  )
  
  mySim.setTimeStepSize(dt)
  
  mySim.readGeometry("box30.0.geo")
  
  mySim.createWall (
    name="lowerWall",
    posn=Vec3(0.0,0.0,0.0),
    normal=Vec3(0.0,1.0,0.0)
  )
  
  mySim.createWall (
    name="upperWall",
    posn=Vec3(0.0,30.0,0.0),
    normal=Vec3(0.0,-1.0,0.0)
  )
  
  k=2.0
  kbreak=10.0
  bip=RotBondPrms (
    name="bonded",
    normalK=k*0.5,
    shearK=k*0.15,
    torsionK=k*0.04,
    bendingK=k*0.017,
    normalBrkForce=kbreak*0.00025,
    shearBrkForce=kbreak*0.00125,
    torsionBrkForce=kbreak*0.000125,
    bendingBrkForce=kbreak*0.000125,
    tag=0,
    scaling=True
  )
  
  fip=RotFrictionPrms (
    name="friction",
    normalK=1.0,
    dynamicMu=0.6,
    staticMu=0.6,
    shearK=1.0,
    scaling=True
  )
  
  dip=LinDampingPrms (
    name="damping1",
    viscosity=0.01,
    maxIterations=50
  )
  
  rdip=RotDampingPrms (
    name="damping2",
    viscosity=0.01,
    maxIterations=50
  )
  
  mySim.createInteractionGroup(bip)
  mySim.createInteractionGroup(dip)
  mySim.createInteractionGroup(rdip)
  mySim.createInteractionGroup(fip)
  
  mySim.createExclusion("bonded","friction")
  
  wp1=NRotElasticWallPrms (
    name="upperWallInteraction",
    wallName="upperWall",
    normalK=1.0
  )
  
  wp2=NRotElasticWallPrms (
    name="lowerWallInteraction",
    wallName="lowerWall",
    normalK=1.0
  )
  
  mySim.createInteractionGroup(wp1)
  mySim.createInteractionGroup(wp2)
  
  nb_prm=InteractionScalarFieldSaverPrms (
    interactionName="bonded",
    fieldName="count",
    fileName="nbons.dat",
    fileFormat="SUM",
    beginTimeStep=0,
    endTimeStep=nt,
    timeStepIncr=1
  )
  
  mySim.createFieldSaver(nb_prm)
  
  
  
  pot_file_name="epot.dat"
  ep_prm=InteractionScalarFieldSaverPrms (
    interactionName="bonded",
    fieldName="potential_energy",
    fileName=pot_file_name,
    fileFormat="SUM",
    beginTimeStep=0,
    endTimeStep=nt,
    timeStepIncr=1
  )
  mySim.createFieldSaver(ep_prm)
  
  
  kin_file_name="ekin.dat"
  ek_prm=ParticleScalarFieldSaverPrms (
    fieldName="e_kin",
    fileName=kin_file_name,
    fileFormat="SUM",
    beginTimeStep=0,
    endTimeStep=nt,
    timeStepIncr=1
  )
  mySim.createFieldSaver(ek_prm)
  
  
  wf_file_name="wf.dat"
  mySim.createFieldSaver (
    WallVectorFieldSaverPrms (
      fileName=wf_file_name,
      fieldName="Force",
      wallName=["lowerWall","upperWall"],
      fileFormat="RAW_SERIES",
      beginTimeStep=0,
      endTimeStep=nt,
      timeStepIncr=1
    )
  )
  
  wp_file_name="wp.dat"
  mySim.createFieldSaver (
    WallVectorFieldSaverPrms (
      fileName=wp_file_name,
      fieldName="Position",
      wallName=["lowerWall","upperWall"],
      fileFormat="RAW_SERIES",
      beginTimeStep=0,
      endTimeStep=nt,
      timeStepIncr=1
    )
  )
  
  cp=CheckPointPrms (
    fileNamePrefix="cpt/cpt",
    beginTimeStep = 0,
    endTimeStep = nt,
    timeStepIncr = dt_snap
  )
  
  mySim.createCheckPointer (cp)
  
  lf=Loading(mySim,v*dt,t0,t1)
  mySim.addPreTimeStepRunnable(lf)
  
  mySim.setNumTimeSteps(nt)
  
  mySim.run()
  
if (__name__=="__main__"):
  runSimulation()
  
