def solve(self, damp=.2, dynRelax=False):
        """
      solve the equation of motion in centeral difference scheme
      """
        # get initial coordinate
        x = self.getDomain().getX()
        # density matrix
        kron = util.kronecker(self.getDomain().getDim())
        rho = self.__rho * kron
        # stress at (n) time step
        stress_last = self.getCurrentStress()
        # set coefficients for ODE
        self.__pde.setValue(D=rho)
        self.setRHS(X=-stress_last)
        # solve acceleration at (n) time step from ODE
        u_tt = self.__pde.getSolution()
        # update velocity at (n+1/2) time step
        self.__u_t = 1. / (2. + damp * self.__dt) * (
            (2. - damp * self.__dt) * self.__u_t + 2. * self.__dt * u_tt)
        # get displacement increment
        du = self.__dt * self.__u_t
        # update strain
        D = util.grad(du)
        self.__strain += D
        # update displacement and domain geometry at (n+1) time step
        self.__u += du
        self.__domain.setX(x + du)

        # !!!!!! apply displacement increment and get boundary force from DE exterior domain, if any
        if self.__FEDENodeMap:
            DEdu = self.getBoundaryDisplacement(du)
            """
         # apply boundary velocity and get boundary traction (deprecated)
         self.__Nbc,self.__sceneExt=self.applyDisplIncrement_getTractionDEM(DEdu=DEdu)
         """
            # apply boundary velocity and return an asynResult object
            arFEfAndSceneExt = self.applyDisplIncrement_getForceDEM(
                DEdu=DEdu, dynRelax=dynRelax)

        # !!!!!! update stress and scenes from DEM part using strain at (n+1) time step
        self.__stress, self.__scenes = self.applyStrain_getStressDEM(
            st=D, dynRelax=dynRelax)
        """
      # !!!!!! update scenes and return asynResult objects (deprecated)
      arScenes = self.applyStrain(st=D)
		# !!!!!! retrieve data from asyncResults
      # update interior DE scenes
      self.__scenes = arScenes.get()
      # assign new stresses to gauss points from interior DE scenes
      s = self.__pool.map(getStress2D,self.__scenes)
      for i in xrange(self.__numGaussPoints):
         self.__stress.setValueOfDataPoint(i,s[i])
      """
        # if exterior DE domain is given, update scene and boundary force
        if self.__FEDENodeMap:
            self.__FEf, self.__sceneExt = arFEfAndSceneExt.get()
        return self.__u, self.__u_t
   def solve(self,damp=.2,dynRelax=False):
      """
      solve the equation of motion in centeral difference scheme
      """
      # get initial coordinate
      x = self.getDomain().getX()
      # density matrix
      kron = util.kronecker(self.getDomain().getDim())
      rho = self.__rho*kron
      # stress at (n) time step
      stress_last = self.getCurrentStress()
      # set coefficients for ODE
      self.__pde.setValue(D=rho)
      self.setRHS(X=-stress_last)
      # solve acceleration at (n) time step from ODE
      u_tt = self.__pde.getSolution()
      # update velocity at (n+1/2) time step
      self.__u_t = 1./(2.+damp*self.__dt)*((2.-damp*self.__dt)*self.__u_t + 2.*self.__dt*u_tt)
      # get displacement increment
      du = self.__dt*self.__u_t
      # update strain
      D = util.grad(du)
      self.__strain += D
      # update displacement and domain geometry at (n+1) time step
      self.__u += du
      self.__domain.setX(x+du)

      # !!!!!! apply displacement increment and get boundary force from DE exterior domain, if any
      if self.__FEDENodeMap:
         DEdu = self.getBoundaryDisplacement(du)
         """
         # apply boundary velocity and get boundary traction (deprecated)
         self.__Nbc,self.__sceneExt=self.applyDisplIncrement_getTractionDEM(DEdu=DEdu)
         """
         # apply boundary velocity and return an asynResult object
         arFEfAndSceneExt=self.applyDisplIncrement_getForceDEM(DEdu=DEdu,dynRelax=dynRelax)

      # !!!!!! update stress and scenes from DEM part using strain at (n+1) time step
      self.__stress,self.__scenes = self.applyStrain_getStressDEM(st=D,dynRelax=dynRelax)
      """
      # !!!!!! update scenes and return asynResult objects (deprecated)
      arScenes = self.applyStrain(st=D)
		# !!!!!! retrieve data from asyncResults
      # update interior DE scenes
      self.__scenes = arScenes.get()
      # assign new stresses to gauss points from interior DE scenes
      s = self.__pool.map(getStress2D,self.__scenes)
      for i in xrange(self.__numGaussPoints):
         self.__stress.setValueOfDataPoint(i,s[i])
      """
       # if exterior DE domain is given, update scene and boundary force
      if self.__FEDENodeMap:
         self.__FEf,self.__sceneExt = arFEfAndSceneExt.get()
      return self.__u, self.__u_t
Beispiel #3
0
 def solve(self, globalIter=10, solidIter=50):
     """
   solve the coupled PDE using fixed-stress split method,
   call solveSolid to get displacement
   """
     rtol = self.__rtol
     x_safe = self.__domain.getX()
     k = util.kronecker(self.__domain)
     kdr = util.inner(k, util.tensor_mult(self.__S, k)) / 4.
     n = self.getEquivalentPorosity()
     perm = self.__permeability * n**3 / (1. - n)**2 * k
     kf = self.__bulkFluid
     dt = self.__dt
     self.__ppde.setValue(A=perm,
                          D=(n / kf + 1. / kdr) / dt,
                          Y=(n / kf + 1. / kdr) / dt * self.__pgauss -
                          self.__meanStressRate / kdr)
     p_iter_old = self.__ppde.getSolution()
     p_iter_gauss = util.interpolate(p_iter_old,
                                     escript.Function(self.__domain))
     u_old, D, sig, s, scene = self.solveSolid(p_iter_gauss=p_iter_gauss,
                                               iter_max=solidIter)
     converge = False
     iterate = 0
     while (not converge) and (iterate < globalIter):
         iterate += 1
         self.__ppde.setValue(Y=n / kf / dt * self.__pgauss +
                              1. / kdr / dt * p_iter_gauss -
                              util.trace(D) / dt)
         p_iter = self.__ppde.getSolution()
         p_err = util.L2(p_iter - p_iter_old) / util.L2(p_iter)
         p_iter_old = p_iter
         p_iter_gauss = util.interpolate(p_iter,
                                         escript.Function(self.__domain))
         u, D, sig, s, scene = self.solveSolid(p_iter_gauss=p_iter_gauss,
                                               iter_max=solidIter)
         u_err = util.L2(u - u_old) / util.L2(u)
         u_old = u
         converge = (u_err <= rtol and p_err <= rtol * .1)
     self.__meanStressRate = (util.trace(sig - self.__stress) / 2. -
                              p_iter_gauss + self.__pgauss) / dt
     self.__pore = p_iter_old
     self.__pgauss = p_iter_gauss
     self.__domain.setX(x_safe + u_old)
     self.__strain += D
     self.__stress = sig
     self.__S = s
     self.__scenes = scene
     return u_old
Beispiel #4
0
 def solveSolid(self, p_iter_gauss=escript.Data(), iter_max=50):
     """
   solve the pde for displacement using Newton-Ralphson scheme
   """
     k = util.kronecker(self.__domain)
     p = p_iter_gauss * k
     iterate = 0
     rtol = self.__rtol
     stress_safe = self.__stress
     s_safe = self.__S
     x_safe = self.__domain.getX()
     self.__upde.setValue(A=s_safe, X=-stress_safe + p, r=self.__r)
     #residual0=util.L2(self.__pde.getRightHandSide()) # using force error
     u = self.__upde.getSolution()  # trial solution, displacement
     D = util.grad(u)  # trial strain tensor
     # !!!!!! obtain stress and tangent operator from DEM part
     update_stress, update_s, update_scenes = self.applyStrain_getStressTangentDEM(
         st=D)
     err = util.Lsup(u)  # initial error before iteration
     converged = (err < 1.e-12)
     while (not converged) and (iterate < iter_max):
         #if iterate>iter_max:
         #   raise RuntimeError,"Convergence for Newton-Raphson failed after %s steps."%(iter_max)
         iterate += 1
         self.__domain.setX(x_safe + u)
         self.__upde.setValue(A=update_s,
                              X=-update_stress + p,
                              r=escript.Data())
         #residual=util.L2(self.__pde.getRightHandSide())
         du = self.__upde.getSolution()
         u += du
         l, d = util.L2(u), util.L2(du)
         err = d / l  # displacement error, alternatively using force error 'residual'
         converged = (err < rtol)
         if err > rtol**3:  # only update DEM parts when error is large enough
             self.__domain.setX(x_safe)
             D = util.grad(u)
             update_stress, update_s, update_scenes = self.applyStrain_getStressTangentDEM(
                 st=D)
     """reset domain geometry to original until global convergence"""
     self.__domain.setX(x_safe)
     return u, D, update_stress, update_s, update_scenes
Beispiel #5
0
 def solve(self, globalIter=10, solidIter=50):
    """
    solve the coupled PDE using fixed-stress split method,
    call solveSolid to get displacement
    """
    rtol=self.__rtol
    x_safe=self.__domain.getX()
    k=util.kronecker(self.__domain)
    kdr=util.inner(k,util.tensor_mult(self.__S,k))/4.
    n=self.getEquivalentPorosity()
    perm=self.__permeability*n**3/(1.-n)**2*k
    kf=self.__bulkFluid
    dt=self.__dt
    self.__ppde.setValue(A=perm,D=(n/kf+1./kdr)/dt,Y=(n/kf+1./kdr)/dt*self.__pgauss-self.__meanStressRate/kdr)
    p_iter_old=self.__ppde.getSolution()
    p_iter_gauss=util.interpolate(p_iter_old,escript.Function(self.__domain))
    u_old,D,sig,s,scene=self.solveSolid(p_iter_gauss=p_iter_gauss,iter_max=solidIter)
    converge=False
    iterate=0
    while (not converge) and (iterate<globalIter):
       iterate += 1
       self.__ppde.setValue(Y=n/kf/dt*self.__pgauss+1./kdr/dt*p_iter_gauss-util.trace(D)/dt)
       p_iter=self.__ppde.getSolution()
       p_err=util.L2(p_iter-p_iter_old)/util.L2(p_iter)
       p_iter_old=p_iter
       p_iter_gauss=util.interpolate(p_iter,escript.Function(self.__domain))
       u,D,sig,s,scene=self.solveSolid(p_iter_gauss=p_iter_gauss,iter_max=solidIter)
       u_err=util.L2(u-u_old)/util.L2(u)
       u_old=u
       converge=(u_err<=rtol and p_err <= rtol*.1)
    self.__meanStressRate=(util.trace(sig-self.__stress)/2.-p_iter_gauss+self.__pgauss)/dt
    self.__pore=p_iter_old
    self.__pgauss=p_iter_gauss
    self.__domain.setX(x_safe+u_old)
    self.__strain+=D
    self.__stress=sig
    self.__S=s
    self.__scenes=scene
    return u_old
Beispiel #6
0
 def solveSolid(self, p_iter_gauss=escript.Data(), iter_max=50):
    """
    solve the pde for displacement using Newton-Ralphson scheme
    """
    k=util.kronecker(self.__domain)
    p=p_iter_gauss*k
    iterate=0
    rtol=self.__rtol
    stress_safe=self.__stress
    s_safe=self.__S
    x_safe=self.__domain.getX()
    self.__upde.setValue(A=s_safe, X=-stress_safe+p, r=self.__r)
    #residual0=util.L2(self.__pde.getRightHandSide()) # using force error
    u=self.__upde.getSolution()  # trial solution, displacement
    D=util.grad(u)               # trial strain tensor
    # !!!!!! obtain stress and tangent operator from DEM part
    update_stress,update_s,update_scenes=self.applyStrain_getStressTangentDEM(st=D)
    err=util.Lsup(u) # initial error before iteration
    converged=(err<1.e-12)
    while (not converged) and (iterate<iter_max):
       #if iterate>iter_max:
       #   raise RuntimeError,"Convergence for Newton-Raphson failed after %s steps."%(iter_max)
       iterate+=1
       self.__domain.setX(x_safe+u)
       self.__upde.setValue(A=update_s,X=-update_stress+p,r=escript.Data())
       #residual=util.L2(self.__pde.getRightHandSide())
       du=self.__upde.getSolution()
       u+=du
       l,d=util.L2(u),util.L2(du)
       err=d/l # displacement error, alternatively using force error 'residual'
       converged=(err<rtol)
       if err>rtol**3: # only update DEM parts when error is large enough
          self.__domain.setX(x_safe)
          D=util.grad(u)
          update_stress,update_s,update_scenes=self.applyStrain_getStressTangentDEM(st=D)
    """reset domain geometry to original until global convergence"""
    self.__domain.setX(x_safe)
    return u,D,update_stress,update_s,update_scenes