Ejemplo n.º 1
0
    def solve(self, iter_max=100):
        """
      solve the equation using Newton-Ralphson scheme
      """
        iterate = 0
        rtol = self.getRelTolerance()
        stress = self.getCurrentStress()
        s = self.getCurrentTangent()
        x_safe = self.__domain.getX()
        self.__pde.setValue(A=s, X=-stress)
        #residual0=util.L2(self.__pde.getRightHandSide()) # using force error
        u = self.__pde.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 = 1.0  # initial error before iteration
        converged = (err < rtol)
        while (not converged) and (iterate < iter_max):
            if self.__verbose:
                print(
                    "Not converged after %d iteration(s)! Relative error: %e" %
                    (iterate, err))
            iterate += 1
            self.__domain.setX(x_safe + u)
            self.__pde.setValue(A=update_s, X=-update_stress, r=escript.Data())
            #residual=util.L2(self.__pde.getRightHandSide())
            du = self.__pde.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 * 0.001:  # 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)

            #if err>err_safe: # to ensure consistent convergence, however this may not be achieved due to fluctuation!
            #   raise RuntimeError,"No improvement of convergence with iterations! Relative error: %e"%err
        """
      update 'domain geometry', 'stress', 'tangent operator',
      'accumulated strain' and 'simulation scenes'.
      """
        self.__domain.setX(x_safe + u)
        self.__stress = update_stress
        self.__S = update_s
        self.__strain += D
        self.__scenes = update_scenes
        if self.__verbose:
            print(
                "Convergence reached after %d iteration(s)! Relative error: %e"
                % (iterate, err))
        return u
Ejemplo n.º 2
0
   def solve(self, iter_max=100):
      """
      solve the equation using Newton-Ralphson scheme
      """
      iterate=0
      rtol=self.getRelTolerance()
      stress=self.getCurrentStress()
      s=self.getCurrentTangent()
      x_safe=self.__domain.getX()
      self.__pde.setValue(A=s, X=-stress)
      #residual0=util.L2(self.__pde.getRightHandSide()) # using force error
      u=self.__pde.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=1.0 # initial error before iteration
      converged=(err<rtol)
      while (not converged) and (iterate<iter_max):
         if self.__verbose:
            print "Not converged after %d iteration(s)! Relative error: %e"%(iterate,err)
         iterate+=1
         self.__domain.setX(x_safe+u)
         self.__pde.setValue(A=update_s,X=-update_stress,r=escript.Data())
         #residual=util.L2(self.__pde.getRightHandSide())
         du=self.__pde.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*0.001: # 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)

         #if err>err_safe: # to ensure consistent convergence, however this may not be achieved due to fluctuation!
         #   raise RuntimeError,"No improvement of convergence with iterations! Relative error: %e"%err
      """
      update 'domain geometry', 'stress', 'tangent operator',
      'accumulated strain' and 'simulation scenes'.
      """
      self.__domain.setX(x_safe+u)
      self.__stress=update_stress
      self.__S=update_s
      self.__strain+=D
      self.__scenes=update_scenes
      if self.__verbose:
         print "Convergence reached after %d iteration(s)! Relative error: %e"%(iterate,err)
      return u
Ejemplo n.º 3
0
 def getCurrentFlux(self):
    """
    return current Darcy flux
    type: Vector on FunctionSpace
    """
    n=self.getEquivalentPorosity()
    perm=self.__permeability*n**3/(1.-n)**2
    flux=-perm*util.grad(self.__pore)
    return flux
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
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
Ejemplo n.º 6
0
   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
Ejemplo n.º 7
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
Ejemplo n.º 8
0
   def solve(self, iter_max=100):
      """
      solve the equation using Newton-Ralphson scheme ??where is the equation
      """
      iterate=0
      rtol=self.getRelTolerance()
      stress=self.getCurrentStress()
      s=self.getCurrentTangent()
      x_safe=self.__domain.getX()
      self.__pde.setValue(A=s, X=-stress)#stress is negative,here uses - to change to positive
      #residual0=util.L2(self.__pde.getRightHandSide()) # using force error
      u=self.__pde.getSolution()  # trial solution, displacement
      D=util.grad(u)              # trial strain tensor (obtained from FEM part)

      #fout1=open('./result/gradU.dat','w')
      #fout1.write(str(D)+'\n')

      # !!!!!! following steps: obtain stress and tangent operator from DEM part
      update_stress,update_s,update_scenes=self.applyStrain_getStressTangentDEM(st=D)#input grad(u) from FEM to DEM to get D&sigma
      #fout2=open('./result/stress&tangOper.dat','w')
      #fout2.write('tangent'+'\n'+str(update_s)+'\n'+'stress'+'\n'+str(update_stress))
      #saveGauss2D(name='./result/gradU+stress+tangent.dat',gradU=D, stress=update_stress, tangent=update_s) 
      #print(type(D))  gradU is a <class 'esys.escriptcore.escriptcpp.Data'> how to transfer to a list to output
      err=1.0 # initial error before iteration
      converged=(err<rtol)
      while not converged:
         if self.__verbose:
            print "Not converged after %d iteration(s)! Relative error: %e"%(iterate,err)
         if iterate>50:
            rtol = 0.05 #enlarge rtol from 0.01(default) to 0.05 when iterate > 50
         if iterate>iter_max:
            raise RuntimeError,"Convergence not reached after %s steps."%(iter_max)
         iterate+=1
         self.__domain.setX(x_safe+u)#update nodal displacement to do the following calculation
         self.__pde.setValue(A=update_s,X=-update_stress,r=escript.Data())
         #residual=util.L2(self.__pde.getRightHandSide())
         du=self.__pde.getSolution() #we do NR iteration to get du
         u+=du
         l,d=util.L2(u),util.L2(du) #to get the l2 norm of u and du
         err=d/l # displacement error, alternatively using force error 'residual'
         converged=(err<rtol)
         if err>rtol*0.001: # only update DEM parts when error is large enough???why times 0.001?
         #it seems whether or not it is converged, the lines below 'if' will always be excuted. So why do we need if? can we just remove it 
            self.__domain.setX(x_safe) #x_safe is constant in this part 'solve' and is not updated.
            D=util.grad(u)
            update_stress,update_s,update_scenes=self.applyStrain_getStressTangentDEM(st=D)#DEM calculation!!
            
            '''
	    fout.write('iterate='+str(iterate)+'\n'+'scenes='+'\n'+str(update_scenes)+'\n')
	    '''

         
         #if err>err_safe: # to ensure consistent convergence, however this may not be achieved due to fluctuation!
         #   raise RuntimeError,"No improvement of convergence with iterations! Relative error: %e"%err
      """
      update 'domain geometry', 'stress', 'tangent operator',
      'accumulated strain' and 'simulation scenes'.
      """
      self.__domain.setX(x_safe+u)
      
      
      self.__stress=update_stress
      self.__S=update_s
      self.__strain+=D
      self.__scenes=update_scenes
      

      if self.__verbose:
         print "Convergence reached after %d iteration(s)! Relative error: %e"%(iterate,err)
      return u