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
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
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
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 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
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 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
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