def setUpPDE(self): """ Return the underlying PDE. :rtype: `LinearPDE` """ if self.__pde is None: dom=self.__domain x = dom.getX() DIM=dom.getDim() q=whereZero(x[DIM-1]-inf(x[DIM-1])) for i in range(DIM-1): xi=x[i] q+=whereZero(xi-inf(xi))+whereZero(xi-sup(xi)) pde=LinearPDE(dom, numEquations=1) pde.getSolverOptions().setTolerance(self.__tol) pde.setSymmetryOn() A=pde.createCoefficient('A') X=pde.createCoefficient('X') pde.setValue(A=A, X=X, q=q) else: pde=self.__pde pde.resetRightHandSideCoefficients() return pde
def __init__(self, domain, pml_condition=None, frequency=None, vp=None, fix_boundary=True): """ Initialise the class with domain, boundary conditions and frequency. Setup PDE :param domain: the domain : setup with Dirac points :type domain: `Domain` :param pml_condition: :type pml_condition: :param frequency: :type frequency: :param vp: velocity field :type vp: `Data` :param fix_boundary: if true fix all the boundaries except the top :type fix_boundary: `bool` """ Dim=domain.getDim() self.pde=LinearPDE(domain, numEquations=1, numSolutions=1, isComplex=True) self.pde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) self.pml=pml_condition if not self.pml: self.pde.setValue(A=kronecker(domain)) self.J=1. if fix_boundary: x=domain.getX() q=whereZero(x[Dim-1]-inf(x[Dim-1])) for i in range(Dim-1): q+=whereZero(x[i]-inf(x[i]))+whereZero(x[i]-sup(x[i])) self.pde.setValue(q=q) self.setFrequency(frequency) self.setVp(vp)
def test_PDE2D(self): dx_tests = 0.1 sigma0 = 1. electrodes = [(0.5 - 2 * dx_tests, 1.), (0.5 - dx_tests, 1.), (0.5 + dx_tests, 1.), (0.5 + 2 * dx_tests, 1.)] domain = finRectangle(20, 20, d1=mpisize, diracPoints=electrodes, diracTags=["sl0", "sl1", "sr0", "sr1"]) loc = Locator(domain, electrodes[2:]) # this creates some reference Data: x = domain.getX() q = whereZero(x[0] - inf(x[0])) + whereZero( x[0] - sup(x[0])) + whereZero(x[1] - inf(x[1])) ppde = LinearPDE(domain, numEquations=1) s = Scalar(0., DiracDeltaFunctions(domain)) s.setTaggedValue("sl0", 1.) s.setTaggedValue("sl1", -1.) ppde.setValue(A=kronecker(2) * sigma0, q=q, y_dirac=s) pp = ppde.getSolution() uu = loc(pp) # arguments for DcRes current = 10. sourceInfo = ["sl0", "sl1"] sampleTags = [("sr0", "sr1")] sigmaPrimary = 7. phiPrimary = pp * current * sigma0 / sigmaPrimary uuscale = 1 - current * sigma0 / sigmaPrimary delphi_in = [(uu[1] - uu[0]) * uuscale] acw = DcRes(domain, loc, delphi_in, sampleTags, phiPrimary, sigmaPrimary) self.assertLess(Lsup(phiPrimary - acw.getPrimaryPotential()), 1.e-10 * Lsup(acw.getPrimaryPotential())) SIGMA = 10. # matches current args0 = acw.getArguments(SIGMA) p = args0[0] u = args0[1] # true secondary potential pps = pp - phiPrimary self.assertLess(Lsup(p - pps), 1.e-6 * Lsup(pps)) # test return values at electrodes: self.assertLess(abs(u[0] - uu[0] * uuscale), 1.e-6 * abs(uu[0] * uuscale)) self.assertLess(abs(u[1] - uu[1] * uuscale), 1.e-6 * abs(uu[1] * uuscale)) # this sould be zero dd = acw.getDefect(SIGMA, *args0) self.assertTrue(dd >= 0.) self.assertTrue(dd <= 1e-7)
def __init__(self, domain): super(SlippingFault, self).__init__(self) self.domain = domain self.__pde_u = LinearPDE(domain, numEquations=self.domain.getDim(), numSolutions=self.domain.getDim()) self.__pde_u.setSymmetryOn()
def doInitialization(self): """ initialize model """ if not self.displacement: self.displacement = Vector(0., ContinuousFunction(self.domain)) if not self.velocity: self.velocity = Vector(0., ContinuousFunction(self.domain)) if not self.stress: self.stress = Tensor(0., ContinuousFunction(self.domain)) if not self.internal_force: self.internal_force = Data() if not self.external_force: self.external_force = Data() if not self.prescribed_velocity: self.prescribed_velocity = Data() if not self.location_prescribed_velocity: self.location_prescribed_velocity = Data() # save the old values: self.__stress_safe = self.stress self.__temperature_safe = self.temperature self.__displacement_safe = self.displacement self.__velocity_safe = self.velocity self.__velocity_old = None self.__old_dt = None self.__very_old_dt = None # get node cooridnates and apply initial displacement self.__x = self.domain.getX() self.domain.setX(self.__x + self.displacement) # open PDE: self.__pde = LinearPDE(self.domain) self.__pde.setSolverMethod(self.__pde.DIRECT) self.__solver_options = self.__pde.getSolverOptions() self.__solver_options.setSolverMethod(self.__solver_options.DIRECT) self.__solver_options.setVerbosity(self.debug)
def wavePropagation(domain, h, tend, lam, mu, rho, xc, src_radius, U0): # lists to collect displacement at point source ts, u_pc0, u_pc1, u_pc2 = [], [], [], [] x = domain.getX() # ... open new PDE ... mypde = LinearPDE(domain) mypde.getSolverOptions().setSolverMethod(SolverOptions.HRZ_LUMPING) kron = kronecker(mypde.getDim()) dunit = numpy.array([1., 0., 0.]) # defines direction of point source mypde.setValue(D=kron * rho, q=whereNegative(length(x - xc) - src_radius) * dunit) # ... set initial values .... n = 0 # for first two time steps u = Vector(0., Solution(domain)) u_last = Vector(0., Solution(domain)) t = 0 # define the location of the point source L = Locator(domain, xc) # find potential at point source u_pc = L.getValue(u) print("u at point charge = %s" % u_pc) ts.append(t) u_pc0.append(u_pc[0]), u_pc1.append(u_pc[1]), u_pc2.append(u_pc[2]) while t < tend: t += h # ... get current stress .... g = grad(u) stress = lam * trace(g) * kron + mu * (g + transpose(g)) # ... get new acceleration .... amplitude = U0 * (4 * (t - t0)**3 / alpha**3 - 6 * (t - t0) / alpha) * sqrt(2.) / alpha**2 * exp( 1. / 2. - (t - t0)**2 / alpha**2) mypde.setValue(X=-stress, r=dunit * amplitude) a = mypde.getSolution() # ... get new displacement ... u_new = 2 * u - u_last + h**2 * a # ... shift displacements .... u_last = u u = u_new n += 1 print("time step %d, t = %s" % (n, t)) u_pc = L.getValue(u) print("u at point charge = %s" % u_pc) ts.append(t) u_pc0.append(u_pc[0]), u_pc1.append(u_pc[1]), u_pc2.append(u_pc[2]) # ... save current acceleration in units of gravity and displacements if n == 1 or n % 10 == 0: saveVTK("./data/usoln.%i.vtu" % (n / 10), acceleration=length(a) / 9.81, displacement=length(u), tensor=stress, Ux=u[0]) return ts, u_pc0, u_pc1, u_pc2
def getPotential(self): """ returns a list containing 3 lists one for each the primary, secondary and total potential. """ primCon=self.primaryConductivity coords=self.domain.getX() pde=LinearPDE(self.domain, numEquations=1) tol=1e-8 pde.getSolverOptions().setTolerance(tol) pde.setSymmetryOn() DIM=self.domain.getDim() x=self.domain.getX() q=whereZero(x[DIM-1]-inf(x[DIM-1])) for i in xrange(DIM-1): xi=x[i] q+=whereZero(xi-inf(xi))+whereZero(xi-sup(xi)) A = self.secondaryConductivity * kronecker(self.domain) pde.setValue(A=A,q=q) delPhiSecondary = [] delPhiPrimary = [] delPhiTotal = [] if(len(self.electrodes[0])==3): for i in range(self.numElectrodes-1): analyticRs=Data(0,(3,),ContinuousFunction(self.domain)) analyticRs[0]=(coords[0]-self.electrodes[i][0]) analyticRs[1]=(coords[1]-self.electrodes[i][1]) analyticRs[2]=(coords[2]) rsMag=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**0.5 analyticPrimaryPot=(self.current*(1./primCon))/(2*pi*(rsMag+(whereZero(rsMag)*0.0000001))) #the magic number 0.0000001 is to avoid devide by 0 analyticRsPolePower=(analyticRs[0]**2+analyticRs[1]**2+analyticRs[2]**2)**1.5 analyticRsPolePower = analyticRsPolePower+(whereZero(analyticRsPolePower)*0.0000001) gradUPrimary = Data(0,(3,),ContinuousFunction(self.domain)) gradUPrimary[0] =(self.current/(2*pi*primCon)) * (analyticRs[0]/analyticRsPolePower) gradUPrimary[1] =(self.current/(2*pi*primCon)) * (analyticRs[1]/analyticRsPolePower) gradUPrimary[2] =(self.current/(2*pi*primCon)) * (analyticRs[2]/analyticRsPolePower) gradUPrimary=-gradUPrimary X=(primCon-self.secondaryConductivity) * gradUPrimary pde.setValue(X=X) u=pde.getSolution() loc=Locator(self.domain,self.electrodes[i+1]) delPhiSecondary.append(loc.getValue(u)) delPhiPrimary.append(loc.getValue(analyticPrimaryPot)) else: raise NotImplementedError("2d forward model is not yet implemented") self.delPhiSecondary = delPhiSecondary self.delPhiPrimary = delPhiPrimary for i in range(len(delPhiPrimary)): delPhiTotal.append(delPhiPrimary[i] + delPhiSecondary[i]) self.delPhiTotal=delPhiTotal return [delPhiPrimary, delPhiSecondary, delPhiTotal]
def __init__(self,domain,dim,ng=1,useMPI=False,np=1,rho=2.35e3,mIds=False,\ FEDENodeMap=False,DE_ext=False,FEDEBoundMap=False,conf=False): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param rho: type float, density of material :param mIds: a list contains membrane node IDs :param FEDENodeMap: a dictionary with FE and DE boundary node IDs in keys and values :param DE_ext: name of file which saves initial state of exterior DE domain :param FEDEBoundMap: a dictionary with FE and DE boundary element IDs in keys and values (deprecated) :param conf: type float, conf pressure on membrane """ self.__domain = domain self.__pde = LinearPDE(self.__domain, numEquations=dim, numSolutions=dim) self.__pde.getSolverOptions().setSolverMethod( SolverOptions.HRZ_LUMPING) self.__pde.setSymmetryOn() self.__numGaussPoints = ng self.__rho = rho self.__mIds = mIds self.__FEDENodeMap = FEDENodeMap self.__FEDEBoundMap = FEDEBoundMap self.__conf = conf self.__pool = get_pool(mpi=useMPI, threads=np) self.__scenes = self.__pool.map(initLoad, range(ng)) self.__strain = escript.Tensor(0, escript.Function(self.__domain)) self.__stress = escript.Tensor(0, escript.Function(self.__domain)) self.__u = escript.Vector(0, escript.Solution(self.__domain)) self.__u_last = escript.Vector(0, escript.Solution(self.__domain)) self.__u_t = escript.Vector(0, escript.Solution(self.__domain)) self.__dt = 0 # ratio between timesteps in internal DE and FE domain self.__nsOfDE_int = 1 # if FEDENodeMap is given, employ exterior DE domain if self.__FEDENodeMap: self.__sceneExt = self.__pool.apply(initLoadExt, (DE_ext, )) # ratio between timesteps in external DE and FE domain self.__nsOfDE_ext = 1 # get interface nodal forces as boundary condition self.__FEf = self.__pool.apply( initNbc, (self.__sceneExt, self.__conf, mIds, FEDENodeMap)) """ # get interface nodal tractions as boundary condition (deprecated) self.__Nbc=escript.Vector(0,escript.Solution(self.__domain)) FENbc = self.__pool.apply(initNbc,(self.__sceneExt,self.__conf,mIds,FEDENodeMap)) for FEid in FENbc.keys(): self.__Nbc.setValueOfDataPoint(FEid,FENbc[FEid]) """ # get stress tensor at material points s = self.__pool.map(getStress2D, self.__scenes) for i in xrange(ng): self.__stress.setValueOfDataPoint(i, s[i])
def __init__(self,domain,debug=False): super(StokesProblem, self).__init__(self,debug) self.domain=domain self.__pde_u=LinearPDE(domain,numEquations=self.domain.getDim(),numSolutions=self.domain.getDim()) self.__pde_u.setSymmetryOn() self.__pde_p=LinearPDE(domain) self.__pde_p.setReducedOrderOn() self.__pde_p.setSymmetryOn()
def __init__(self, domain, phi_f=None, phi=None, L_g=None, perm_f_0=None, perm_f_1=None, perm_f_2=None, k_w =None, k_g=None, mu_w =None, mu_g =None, rho_w =None, rho_g=None, sigma=0, A_mg=0, f_rg=1., wells=[], g=9.81*U.m/U.sec**2): """ set up :param domain: domain :type domain: `esys.escript.Domain` :param phi_f: porosity of the fractured rock as function of the gas pressure :type phi_f: `MaterialPropertyWithDifferential` :param phi: total porosity if None phi=1. :type phi: scalar or None :param L_g: gas adsorption as function of gas pressure :type L_g: `MaterialPropertyWithDifferential` :param S_fg: gas saturation in the fractured rock as function of the capillary pressure p_fc=S_fg- p_f :type S_fg: `MaterialPropertyWithDifferential` :param perm_f_0: permeability in the x_0 direction in the fractured media :type perm_f_0: scalar :param perm_f_1: permeability in the x_1 direction in the fractured media :type perm_f_1: scalar :param perm_f_2: permeability in the x_2 direction in the fractured media :type perm_f_2: scalar :param k_w: relative permeability of water as function of water saturation :type k_w: `MaterialProperty` :param k_g: relative permeability of gas as function of gas saturation :type k_g: `MaterialProperty` :param mu_w: viscosity of water as function of water pressure :type mu_w: `MaterialProperty` :param mu_g: viscosity of gas as function of gas pressure :type mu_g: `MaterialProperty` :param rho_w: density of water as function of water pressure :type rho_w: `MaterialPropertyWithDifferential` :param rho_g: density of gas as function of gas pressure :type rho_g: `MaterialPropertyWithDifferential` :param wells : list of wells :type wells: list of `Well` :param sigma: shape factor for gas matrix diffusion :param A_mg: diffusion constant for gas adsorption :param f_rg: gas re-adsorption factor """ DualPorosity.__init__(self, domain, phi_f=phi_f, phi_m=None, phi=phi, S_fg=None, S_mg=None, perm_f_0=perm_f_0, perm_f_1=perm_f_1, perm_f_2=perm_f_2, perm_m_0=None , perm_m_1=None, perm_m_2=None, k_w =k_w, k_g=k_g, mu_w =mu_w, mu_g =mu_g, rho_w =rho_w, rho_g=rho_g, wells=wells, g=g) self.L_g=L_g self.sigma = sigma self.A_mg = A_mg self.f_rg = f_rg self.__pde=LinearPDE(self.domain, numEquations=3, numSolutions =3)
def __update(self, tag, tag_value, value): if self.__pde == None: self.__pde = LinearPDE(self.domain, numSolutions=1) mask = Scalar(0., Function(self.domain)) mask.setTaggedValue(tag, 1.) self.__pde.setValue(Y=mask) mask = wherePositive(abs(self.__pde.getRightHandSide())) value *= (1. - mask) value += tag_value * mask return value
def __init__(self, domain, debug=False): super(StokesProblem, self).__init__(self, debug) self.domain = domain self.__pde_u = LinearPDE(domain, numEquations=self.domain.getDim(), numSolutions=self.domain.getDim()) self.__pde_u.setSymmetryOn() self.__pde_p = LinearPDE(domain) self.__pde_p.setReducedOrderOn() self.__pde_p.setSymmetryOn()
def __init__(self,domain): super(SimpleStokesProblem, self).__init__(self) self.__pde_u=LinearPDE(domain) self.__pde_u.setSymmetryOn() self.__pde_u.setValue(A=identityTensor4(dom)) self.__pde_p=LinearPDE(domain) self.__pde_p.setReducedOrderOn() self.__pde_p.setSymmetryOn() self.__pde_p.setValue(D=1.)
def __init__(self, domain, pore0=0., perm=1.e-5, kf=2.2e9, dt=0.001, ng=1, useMPI=False, np=1, rtol=1.e-2): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param pore0: type float, initial pore pressure :param perm: type float, d^2/(150 mu_f) in KC equation :param kf: type float, bulk modulus of the fluid :param dt: type float, time step for calculation :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param rtol: type float, relevative tolerance for global convergence """ self.__domain = domain self.__upde = LinearPDE(domain, numEquations=domain.getDim(), numSolutions=domain.getDim()) self.__ppde = LinearPDE(domain, numEquations=1, numSolutions=1) # use reduced interpolation for pore pressure self.__ppde.setReducedOrderOn() self.__upde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) self.__ppde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) self.__upde.setSymmetryOn() self.__ppde.setSymmetryOn() self.__dt = dt self.__bulkFluid = kf self.__numGaussPoints = ng self.__rtol = rtol self.__stress = escript.Tensor(0, escript.Function(domain)) self.__S = escript.Tensor4(0, escript.Function(domain)) self.__pool = get_pool(mpi=useMPI, threads=np) self.__scenes = self.__pool.map(initLoad, range(ng)) st = self.__pool.map(getStressAndTangent2D, self.__scenes) for i in xrange(ng): self.__stress.setValueOfDataPoint(i, st[i][0]) self.__S.setValueOfDataPoint(i, st[i][1]) self.__strain = escript.Tensor(0, escript.Function(domain)) self.__pore = escript.Scalar(pore0, escript.ReducedSolution(domain)) self.__pgauss = util.interpolate(pore0, escript.Function(domain)) self.__permeability = perm self.__meanStressRate = escript.Scalar(0, escript.Function(domain)) self.__r = escript.Vector( 0, escript.Solution(domain)) #Dirichlet BC for u
def __init__(self, domain): super(SimpleStokesProblem, self).__init__(self) self.__pde_u = LinearPDE(domain) self.__pde_u.setSymmetryOn() self.__pde_u.setValue(A=identityTensor4(dom)) self.__pde_p = LinearPDE(domain) self.__pde_p.setReducedOrderOn() self.__pde_p.setSymmetryOn() self.__pde_p.setValue(D=1.)
def __init__(self, domain, ng=1, useMPI=False, np=1, random=False, rtol=1.e-2, verbose=False): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param random: type boolean, if or not use random density field :param rtol: type float, relevant tolerance for global convergence :param verbose: type boolean, if or not print messages during calculation """ self.__domain = domain self.__pde = LinearPDE(domain, numEquations=self.__domain.getDim(), numSolutions=self.__domain.getDim()) try: self.__pde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) except: #import time print( "=======================================================================" ) print( "For better performance compile python-escript with direct solver method" ) print( "=======================================================================" ) input("Press Enter to continue...") #time.sleep(5) self.__pde.setSymmetryOn() #self.__pde.getSolverOptions().setTolerance(rtol**2) #self.__pde.getSolverOptions().setPackage(SolverOptions.UMFPACK) self.__numGaussPoints = ng self.__rtol = rtol self.__verbose = verbose self.__pool = get_pool(mpi=useMPI, threads=np) self.__scenes = self.__pool.map(initLoad, list(range(ng))) self.__strain = escript.Tensor(0, escript.Function(self.__domain)) self.__stress = escript.Tensor(0, escript.Function(self.__domain)) self.__S = escript.Tensor4(0, escript.Function(self.__domain)) st = self.__pool.map(getStressAndTangent, self.__scenes) for i in range(ng): self.__stress.setValueOfDataPoint(i, st[i][0]) self.__S.setValueOfDataPoint(i, st[i][1])
def __init__(self, domain, ng=1, useMPI=False, np=1, random=False, rtol=1.e-2, usePert=False, pert=-2.e-6, verbose=False): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param random: type boolean, if or not use random density field :param rtol: type float, relevative tolerance for global convergence :param usePert: type boolean, if or not use perturbation method :param pert: type float, perturbated strain applied to DEM to obtain tangent operator :param verbose: type boolean, if or not print messages during calculation """ self.__domain = domain self.__pde = LinearPDE(domain, numEquations=self.__domain.getDim(), numSolutions=self.__domain.getDim()) self.__pde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) self.__pde.setSymmetryOn() #self.__pde.getSolverOptions().setTolerance(rtol**2) #self.__pde.getSolverOptions().setPackage(SolverOptions.UMFPACK) self.__numGaussPoints = ng self.__rtol = rtol self.__usepert = usePert self.__pert = pert self.__verbose = verbose self.__pool = get_pool(mpi=useMPI, threads=np) self.__scenes = self.__pool.map(initLoad, range(ng)) self.__strain = escript.Tensor(0, escript.Function(self.__domain)) self.__stress = escript.Tensor(0, escript.Function(self.__domain)) self.__S = escript.Tensor4(0, escript.Function(self.__domain)) if self.__usepert: s = self.__pool.map(getStressTensor, self.__scenes) t = self.__pool.map(getTangentOperator, zip(self.__scenes, repeat(pert))) for i in xrange(ng): self.__stress.setValueOfDataPoint(i, s[i]) self.__S.setValueOfDataPoint(i, t[i]) else: st = self.__pool.map(getStressAndTangent2D, self.__scenes) for i in xrange(ng): self.__stress.setValueOfDataPoint(i, st[i][0]) self.__S.setValueOfDataPoint(i, st[i][1])
def test_PDE2D(self): dx_tests=0.1 sigma0=1. electrodes=[(0.5-2*dx_tests,1.), (0.5-dx_tests,1.), (0.5+dx_tests,1.), (0.5+2*dx_tests,1.)] domain=finRectangle(20,20, d1=mpisize, diracPoints=electrodes, diracTags=["sl0", "sl1", "sr0", "sr1"] ) loc=Locator(domain,electrodes[2:]) # this creates some reference Data: x=domain.getX() q=whereZero(x[0]-inf(x[0]))+whereZero(x[0]-sup(x[0]))+whereZero(x[1]-inf(x[1])) ppde=LinearPDE(domain, numEquations=1) s=Scalar(0.,DiracDeltaFunctions(domain)) s.setTaggedValue("sl0" ,1.) s.setTaggedValue("sl1",-1.) ppde.setValue(A=kronecker(2)*sigma0, q=q, y_dirac=s) pp=ppde.getSolution() uu=loc(pp) # arguments for DcRes current = 10. sourceInfo = [ "sl0", "sl1" ] sampleTags = [ ("sr0", "sr1") ] sigmaPrimary=7. phiPrimary=pp*current*sigma0/sigmaPrimary uuscale=1-current*sigma0/sigmaPrimary delphi_in = [ (uu[1]-uu[0]) * uuscale] acw=DcRes(domain, loc, delphi_in, sampleTags, phiPrimary, sigmaPrimary) self.assertLess(Lsup(phiPrimary-acw.getPrimaryPotential()), 1.e-10 * Lsup(acw.getPrimaryPotential())) SIGMA=10. # matches current args0=acw.getArguments(SIGMA) p=args0[0] u=args0[1] # true secondary potential pps=pp-phiPrimary self.assertLess(Lsup(p-pps), 1.e-6*Lsup(pps)) # test return values at electrodes: self.assertLess(abs(u[0]-uu[0]*uuscale), 1.e-6 * abs(uu[0]*uuscale)) self.assertLess(abs(u[1]-uu[1]*uuscale), 1.e-6 * abs(uu[1]*uuscale)) # this sould be zero dd=acw.getDefect(SIGMA, *args0) self.assertTrue( dd >= 0.) self.assertTrue( dd <= 1e-7 )
def getMaxEigenvalue(self): """ return the max eigenvalue of the model type: float """ dom = self.getDomain() dim = dom.getDim() pdeKu_P = LinearPDE(dom,numEquations=dim,numSolutions=dim) T = self.getCurrentTangent() pdeKu_P.setValue(A=T) pdeKu_P.getOperator().saveMM('tempMTX.mtx') mtx = mmread('tempMTX.mtx') maxEigVal = max(eigs(mtx,k=1,return_eigenvectors=False,which='LR')) return maxEigVal.real
def __init__(self,domain,pore0=0.,perm=1.e-5,kf=2.2e9,dt=0.001,ng=1,useMPI=False,np=1,rtol=1.e-2): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param pore0: type float, initial pore pressure :param perm: type float, d^2/(150 mu_f) in KC equation :param kf: type float, bulk modulus of the fluid :param dt: type float, time step for calculation :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param rtol: type float, relevative tolerance for global convergence """ self.__domain=domain self.__upde=LinearPDE(domain,numEquations=domain.getDim(),numSolutions=domain.getDim()) self.__ppde=LinearPDE(domain,numEquations=1,numSolutions=1) # use reduced interpolation for pore pressure self.__ppde.setReducedOrderOn() try: self.__upde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) self.__ppde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) except: #import time print("=======================================================================") print("For better performance compile python-escript with direct solver method") print("=======================================================================") input("Press Enter to continue...") #time.sleep(5) self.__upde.setSymmetryOn() self.__ppde.setSymmetryOn() self.__dt=dt self.__bulkFluid=kf self.__numGaussPoints=ng self.__rtol=rtol self.__stress=escript.Tensor(0,escript.Function(domain)) self.__S=escript.Tensor4(0,escript.Function(domain)) self.__pool=get_pool(mpi=useMPI,threads=np) self.__scenes=self.__pool.map(initLoad,list(range(ng))) st = self.__pool.map(getStressAndTangent2D,self.__scenes) for i in range(ng): self.__stress.setValueOfDataPoint(i,st[i][0]) self.__S.setValueOfDataPoint(i,st[i][1]) self.__strain=escript.Tensor(0,escript.Function(domain)) self.__pore=escript.Scalar(pore0,escript.ReducedSolution(domain)) self.__pgauss=util.interpolate(pore0,escript.Function(domain)) self.__permeability=perm self.__meanStressRate=escript.Scalar(0,escript.Function(domain)) self.__r=escript.Vector(0,escript.Solution(domain)) #Dirichlet BC for u
def doInitialization(self): """ initialize model """ if not self.displacement: self.displacement=Vector(0.,ContinuousFunction(self.domain)) if not self.velocity: self.velocity=Vector(0.,ContinuousFunction(self.domain)) if not self.stress: self.stress=Tensor(0.,ContinuousFunction(self.domain)) if not self.internal_force: self.internal_force = Data() if not self.external_force: self.external_force = Data() if not self.prescribed_velocity: self.prescribed_velocity = Data() if not self.location_prescribed_velocity: self.location_prescribed_velocity =Data() # save the old values: self.__stress_safe=self.stress self.__temperature_safe=self.temperature self.__displacement_safe=self.displacement self.__velocity_safe=self.velocity self.__velocity_old=None self.__old_dt=None self.__very_old_dt=None # get node cooridnates and apply initial displacement self.__x=self.domain.getX() self.domain.setX(self.__x+self.displacement) # open PDE: self.__pde=LinearPDE(self.domain) self.__pde.setSolverMethod(self.__pde.DIRECT) self.__solver_options=self.__pde.getSolverOptions() self.__solver_options.setSolverMethod(self.__solver_options.DIRECT) self.__solver_options.setVerbosity(self.debug)
def getPDE(self, system): dim = self.domain.getDim() if system: pde=LinearPDE(self.domain, numEquations=dim) else: pde=LinearPDE(self.domain, numEquations=1) self._setCoefficients(pde, system) so = pde.getSolverOptions() so.setPackage(self.package) so.setSolverMethod(self.method) so.setPreconditioner(self.preconditioner) so.setTolerance(self.SOLVER_TOL) so.setVerbosity(self.SOLVER_VERBOSE) self._setSolverOptions(so) return pde, self._getSolution(system), self._getGrad(system)
def __init__(self,domain,ng=1,useMPI=False,np=1,random=False,rtol=1.e-2,verbose=False): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param random: type boolean, if or not use random density field :param rtol: type float, relevant tolerance for global convergence :param verbose: type boolean, if or not print messages during calculation """ self.__domain=domain self.__pde=LinearPDE(domain,numEquations=self.__domain.getDim(),numSolutions=self.__domain.getDim()) self.__pde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) self.__pde.setSymmetryOn() #self.__pde.getSolverOptions().setTolerance(rtol**2) #self.__pde.getSolverOptions().setPackage(SolverOptions.UMFPACK) self.__numGaussPoints=ng self.__rtol=rtol self.__verbose=verbose self.__pool=get_pool(mpi=useMPI,threads=np) self.__scenes=self.__pool.map(initLoad,range(ng)) self.__strain=escript.Tensor(0,escript.Function(self.__domain)) self.__stress=escript.Tensor(0,escript.Function(self.__domain)) self.__S=escript.Tensor4(0,escript.Function(self.__domain)) st = self.__pool.map(getStressAndTangent,self.__scenes) for i in xrange(ng): self.__stress.setValueOfDataPoint(i,st[i][0]) self.__S.setValueOfDataPoint(i,st[i][1])
def getPDE(self, system): dim = self.domain.getDim() if system: pde = LinearPDE(self.domain, numEquations=dim) else: pde = LinearPDE(self.domain, numEquations=1) self._setCoefficients(pde, system) so = pde.getSolverOptions() so.setPackage(self.package) so.setSolverMethod(self.method) so.setPreconditioner(self.preconditioner) so.setTolerance(self.SOLVER_TOL) so.setVerbosity(self.SOLVER_VERBOSE) self._setSolverOptions(so) return pde, self._getSolution(system), self._getGrad(system)
def __update(self,tag,tag_value,value): if self.__pde==None: self.__pde=LinearPDE(self.domain,numSolutions=1) mask=Scalar(0.,Function(self.domain)) mask.setTaggedValue(tag,1.) self.__pde.setValue(Y=mask) mask=wherePositive(abs(self.__pde.getRightHandSide())) value*=(1.-mask) value+=tag_value*mask return value
def __init__(self,domain,ng=1,np=1,random=False,rtol=1.e-2,usePert=False,pert=-2.e-6,verbose=False): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param ng: type integer, number of Gauss points :param np: type integer, number of processors :param random: type boolean, if or not use random density field :param rtol: type float, relevative tolerance for global convergence :param usePert: type boolean, if or not use perturbation method :param pert: type float, perturbated strain applied to DEM to obtain tangent operator :param verbose: type boolean, if or not print messages during calculation """ self.__domain=domain self.__pde=LinearPDE(domain,numEquations=self.__domain.getDim(),numSolutions=self.__domain.getDim()) self.__pde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) #self.__pde.getSolverOptions().setTolerance(rtol**2) #self.__pde.getSolverOptions().setPackage(SolverOptions.UMFPACK) self.__numGaussPoints=ng self.__rtol=rtol self.__usepert=usePert self.__pert=pert self.__verbose=verbose self.__pool=Pool(processes=np) self.__scenes=self.__pool.map(initLoad,range(ng))#where is initLoad???from simDEM.py,to load RVEs; map(function, iterable) self.__strain=escript.Tensor(0,escript.Function(self.__domain)) '''Tensor(value=0., what=FunctionSpace(), expanded=False) returns a Data object of shape (d,d) in the FunctionSpace what, where d is the spatial dimension of the Domain of what. Values are initialized with value, a double precision quantity(here is 0). If expanded is True the Data object is represented in expanded form. ''' self.__stress=escript.Tensor(0,escript.Function(self.__domain)) #Function(domain): returns the general FunctionSpace on the Domain domain. Data objects in this type of general FunctionSpace are defined over the whole geometric region defined by domain. self.__S=escript.Tensor4(0,escript.Function(self.__domain)) #Tensor4 is similar to Tensor, which returns a Data object of shape (d,d,d,d) #simDEM part if self.__usepert: #here usepert=false, so this is not invoked. s = self.__pool.map(getStressTensor,self.__scenes) #getstresstensor is defined in simDEM, but here it is not invoked. t = self.__pool.map(getTangentOperator,zip(self.__scenes,repeat(pert)))#to get initial D and sigma for i in xrange(ng): self.__stress.setValueOfDataPoint(i,s[i]) self.__S.setValueOfDataPoint(i,t[i]) else: st = self.__pool.map(getStressAndTangent2D,self.__scenes) for i in xrange(ng): self.__stress.setValueOfDataPoint(i,st[i][0]) self.__S.setValueOfDataPoint(i,st[i][1])
def __init__(self,domain,dim,ng=1,useMPI=False,np=1,rho=2.35e3,mIds=False,\ FEDENodeMap=False,DE_ext=False,FEDEBoundMap=False,conf=False): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param rho: type float, density of material :param mIds: a list contains membrane node IDs :param FEDENodeMap: a dictionary with FE and DE boundary node IDs in keys and values :param DE_ext: name of file which saves initial state of exterior DE domain :param FEDEBoundMap: a dictionary with FE and DE boundary element IDs in keys and values (deprecated) :param conf: type float, conf pressure on membrane """ self.__domain=domain self.__pde=LinearPDE(self.__domain,numEquations=dim,numSolutions=dim) self.__pde.getSolverOptions().setSolverMethod(SolverOptions.HRZ_LUMPING) self.__pde.setSymmetryOn() self.__numGaussPoints=ng self.__rho=rho self.__mIds=mIds self.__FEDENodeMap=FEDENodeMap self.__FEDEBoundMap=FEDEBoundMap self.__conf=conf self.__pool=get_pool(mpi=useMPI,threads=np) self.__scenes=self.__pool.map(initLoad,range(ng)) self.__strain=escript.Tensor(0,escript.Function(self.__domain)) self.__stress=escript.Tensor(0,escript.Function(self.__domain)) self.__u=escript.Vector(0,escript.Solution(self.__domain)) self.__u_last=escript.Vector(0,escript.Solution(self.__domain)) self.__u_t=escript.Vector(0,escript.Solution(self.__domain)) self.__dt=0 # ratio between timesteps in internal DE and FE domain self.__nsOfDE_int=1 # if FEDENodeMap is given, employ exterior DE domain if self.__FEDENodeMap: self.__sceneExt=self.__pool.apply(initLoadExt,(DE_ext,)) # ratio between timesteps in external DE and FE domain self.__nsOfDE_ext=1 # get interface nodal forces as boundary condition self.__FEf = self.__pool.apply(initNbc,(self.__sceneExt,self.__conf,mIds,FEDENodeMap)) """ # get interface nodal tractions as boundary condition (deprecated) self.__Nbc=escript.Vector(0,escript.Solution(self.__domain)) FENbc = self.__pool.apply(initNbc,(self.__sceneExt,self.__conf,mIds,FEDENodeMap)) for FEid in FENbc.keys(): self.__Nbc.setValueOfDataPoint(FEid,FENbc[FEid]) """ # get stress tensor at material points s = self.__pool.map(getStress2D,self.__scenes) for i in xrange(ng): self.__stress.setValueOfDataPoint(i,s[i])
def __init__(self,domain,ng=1,useMPI=False,np=1,random=False,rtol=1.e-2,usePert=False,pert=-2.e-6,verbose=False): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param random: type boolean, if or not use random density field :param rtol: type float, relevative tolerance for global convergence :param usePert: type boolean, if or not use perturbation method :param pert: type float, perturbated strain applied to DEM to obtain tangent operator :param verbose: type boolean, if or not print messages during calculation """ self.__domain=domain self.__pde=LinearPDE(domain,numEquations=self.__domain.getDim(),numSolutions=self.__domain.getDim()) try: self.__pde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) except: #import time print("=======================================================================") print("For better performance compile python-escript with direct solver method") print("=======================================================================") input("Press Enter to continue...") #time.sleep(5) self.__pde.setSymmetryOn() #self.__pde.getSolverOptions().setTolerance(rtol**2) #self.__pde.getSolverOptions().setPackage(SolverOptions.UMFPACK) self.__numGaussPoints=ng self.__rtol=rtol self.__usepert=usePert self.__pert=pert self.__verbose=verbose self.__pool=get_pool(mpi=useMPI,threads=np) self.__scenes=self.__pool.map(initLoad,list(range(ng))) self.__strain=escript.Tensor(0,escript.Function(self.__domain)) self.__stress=escript.Tensor(0,escript.Function(self.__domain)) self.__S=escript.Tensor4(0,escript.Function(self.__domain)) if self.__usepert: s = self.__pool.map(getStressTensor,self.__scenes) t = self.__pool.map(getTangentOperator,list(zip(self.__scenes,repeat(pert)))) for i in range(ng): self.__stress.setValueOfDataPoint(i,s[i]) self.__S.setValueOfDataPoint(i,t[i]) else: st = self.__pool.map(getStressAndTangent2D,self.__scenes) for i in range(ng): self.__stress.setValueOfDataPoint(i,st[i][0]) self.__S.setValueOfDataPoint(i,st[i][1])
def getMaxEigenvalue(self): """ return the max eigenvalue of the model type: float """ dom = self.getDomain() dim = dom.getDim() pdeKu_P = LinearPDE(dom, numEquations=dim, numSolutions=dim) T = self.getCurrentTangent() pdeKu_P.setValue(A=T) pdeKu_P.getOperator().saveMM('tempMTX.mtx') mtx = mmread('tempMTX.mtx') maxEigVal = max(eigs(mtx, k=1, return_eigenvectors=False, which='LR')) return maxEigVal.real
def gzpot(p, y, x, *args): #rho, rhox, rhoy, R = p rhox = args[0] / 2. rhoy = args[1] / 2. rho, R, z = p #Domain related. mx = args[0] my = args[1] #PDE related G = 6.67300 * 10E-11 #DOMAIN CONSTRUCTION domain = ReadGmsh('data/example10m/example10m.msh', 2) domx = Solution(domain).getX() mask = wherePositive(R - length(domx - rholoc)) rhoe = rho * mask kro = kronecker(domain) q = whereZero(domx[1] - my) + whereZero(domx[1]) + whereZero( domx[0]) + whereZero(domx[0] - mx) #ESCRIPT PDE CONSTRUCTION mypde = LinearPDE(domain) mypde.setValue(A=kro, Y=4. * np.pi * G * rhoe, q=q, r=0.0) mypde.setSymmetryOn() sol = mypde.getSolution() g_field = grad(sol) #The graviational accelleration g. g_fieldz = g_field * [0, 1] #The vertical component of the g field. gz = length(g_fieldz) #The magnitude of the vertical component. #MODEL SIZE SAMPLING sol_escgz = [] sol_escx = [] for i in range(0, len(x)): sol_escgz.append([x[i], rhoy + z]) sample = [] # array to hold values rec = Locator(gz.getFunctionSpace(), sol_escgz) #location to record psol = rec.getValue(gz) err = np.sum((np.array(y) - np.array(psol))**2.) print("Lsup= ", Lsup(np.array(psol) - np.array(sol_angz)) / Lsup(np.array(psol))) return err
def gzpot(p, y, x, *args): #rho, rhox, rhoy, R = p rhox=args[0]/2.; rhoy=args[1]/2. rho, R, z =p #Domain related. mx = args[0]; my = args[1]; #PDE related G=6.67300*10E-11 #DOMAIN CONSTRUCTION domain=ReadGmsh('data/example10m/example10m.msh',2) domx=Solution(domain).getX() mask=wherePositive(R-length(domx-rholoc)) rhoe=rho*mask kro=kronecker(domain) q=whereZero(domx[1]-my)+whereZero(domx[1])+whereZero(domx[0])+whereZero(domx[0]-mx) #ESCRIPT PDE CONSTRUCTION mypde=LinearPDE(domain) mypde.setValue(A=kro,Y=4.*np.pi*G*rhoe,q=q,r=0.0) mypde.setSymmetryOn() sol=mypde.getSolution() g_field=grad(sol) #The graviational accelleration g. g_fieldz=g_field*[0,1] #The vertical component of the g field. gz=length(g_fieldz) #The magnitude of the vertical component. #MODEL SIZE SAMPLING sol_escgz=[] sol_escx=[] for i in range(0,len(x)): sol_escgz.append([x[i],rhoy+z]) sample=[] # array to hold values rec=Locator(gz.getFunctionSpace(),sol_escgz) #location to record psol=rec.getValue(gz) err = np.sum((np.array(y) - np.array(psol))**2.) print("Lsup= ",Lsup(np.array(psol)-np.array(sol_angz))/Lsup(np.array(psol))) return err
class SlippingFault(SaddlePointProblem): """ simple example of saddle point problem """ def __init__(self,domain): super(SlippingFault, self).__init__(self) self.domain=domain self.__pde_u=LinearPDE(domain,numEquations=self.domain.getDim(),numSolutions=self.domain.getDim()) self.__pde_u.setSymmetryOn() def initialize(self,density=1.,lmbd=1., mu=1., traction=Data(),fixed_u_mask=Data(), slip=0.): d=self.domain.getDim() self.slip=slip A =self.__pde_u.createCoefficientOfGeneralPDE("A") for i in range(self.domain.getDim()): for j in range(self.domain.getDim()): A[i,j,j,i] += mu A[i,j,i,j] += mu A[i,i,j,j] += lmbd self.__pde_u.setValue(A=A,q=fixed_u_mask,Y=-kronecker(Function(self.domain))[d-1]*g*density,y=traction) def inner(self,p0,p1): return integrate(inner(p0,p1),FunctionOnContactZero(self.domain)) def solve_f(self,u,p,tol=1.e-8): self.__pde_u.setTolerance(tol) self.__pde_u.setValue(y_contact=-p) # print "p:",inf(p),sup(p) # print "u:",inf(u),sup(u) self.__pde_u.setValue(y_contact=-p) return self.__pde_u.getSolution() def solve_g(self,u,tol=1.e-8): dp=Vector(0.,FunctionOnContactZero(self.domain)) h=FunctionOnContactZero(self.domain).getSize() # print jump(u)-self.slip dp[0]=(self.slip[0]-jump(u[0]))*lam_mu/h dp[1]=(self.slip[1]-jump(u[1]))*lam_mu/h dp[2]=(self.slip[2]-jump(u[2]))*lam_mu/h return dp
res=1000.0 con=1/res cur=10. ################################################ESTABLISHING PARAMETERS #the folder to put our outputs in, leave blank "" for script path save_path= os.path.join("data","example11") #ensure the dir exists mkDir(save_path) ####################################################DOMAIN CONSTRUCTION domain = Rectangle(l0=mx,l1=my,n0=ndx, n1=ndy) x=Solution(domain).getX() kro=kronecker(domain) source1=[mx/4.,0]; source2=[3.*mx/4.,0] sourceg=length(exp(-length(x-source1)/(100.)))+length(exp(-length(x-source2)/(100.))) sourceg=sourceg/integrate(sourceg) q=whereZero(x[1]-my)+whereZero(x[0])+whereZero(x[0]-mx) ###############################################ESCRIPT PDE CONSTRUCTION mypde=LinearPDE(domain) mypde.setValue(A=kro*con,Y=sourceg,q=q,r=0) mypde.setSymmetryOn() sol=mypde.getSolution() # Save the output to file. saveVTK(os.path.join(save_path,"ex11a.vtu"),source=sourceg,res_pot=sol)
class Mechanics(Model): """ base class for mechanics models in updated lagrangean framework :note: Instance variable domain - domain (in) :note: Instance variable internal_force - =Data() :note: Instance variable external_force - =Data() :note: Instance variable prescribed_velocity - =Data() :note: Instance variable location_prescribed_velocity - =Data() :note: Instance variable temperature - = None :note: Instance variable expansion_coefficient - = 0. :note: Instance variable bulk_modulus - =1. :note: Instance variable shear_modulus - =1. :note: Instance variable rel_tol - =1.e-3 :note: Instance variable abs_tol - =1.e-15 :note: Instance variable max_iter - =10 :note: Instance variable displacement - =None :note: Instance variable stress - =None """ SAFTY_FACTOR_ITERATION = 1. / 100. def __init__(self, **kwargs): """ set up the model :keyword debug: debug flag :type debug: ``bool`` """ super(Mechanics, self).__init__(self, **kwargs) self.declareParameter(domain=None, \ displacement=None, \ stress=None, \ velocity=None, \ internal_force=None, \ external_force=None, \ prescribed_velocity=None, \ location_prescribed_velocity=None, \ temperature = None, \ expansion_coefficient = 0., \ bulk_modulus=2., \ shear_modulus=1., \ rel_tol=1.e-3,abs_tol=1.e-15,max_iter=10) self.__iter = 0 def doInitialization(self): """ initialize model """ if not self.displacement: self.displacement = Vector(0., ContinuousFunction(self.domain)) if not self.velocity: self.velocity = Vector(0., ContinuousFunction(self.domain)) if not self.stress: self.stress = Tensor(0., ContinuousFunction(self.domain)) if not self.internal_force: self.internal_force = Data() if not self.external_force: self.external_force = Data() if not self.prescribed_velocity: self.prescribed_velocity = Data() if not self.location_prescribed_velocity: self.location_prescribed_velocity = Data() # save the old values: self.__stress_safe = self.stress self.__temperature_safe = self.temperature self.__displacement_safe = self.displacement self.__velocity_safe = self.velocity self.__velocity_old = None self.__old_dt = None self.__very_old_dt = None # get node cooridnates and apply initial displacement self.__x = self.domain.getX() self.domain.setX(self.__x + self.displacement) # open PDE: self.__pde = LinearPDE(self.domain) self.__pde.setSolverMethod(self.__pde.DIRECT) self.__solver_options = self.__pde.getSolverOptions() self.__solver_options.setSolverMethod(self.__solver_options.DIRECT) self.__solver_options.setVerbosity(self.debug) # self.__pde.setSymmetryOn() def doStepPreprocessing(self, dt): """ step up pressure iteration if run within a time dependend problem extrapolation of pressure from previous time steps is used to get an initial guess (that needs some work!!!!!!!) """ # reset iteration counters: self.__iter = 0 self.__diff = self.UNDEF_DT # set initial guesses for the iteration: self.displacement = self.__displacement_safe self.stress = self.__stress_safe self.velocity = self.__velocity_safe # update geometry self.domain.setX(self.__x + self.displacement) def doStep(self, dt): """ """ self.__iter += 1 k3 = kronecker(self.domain) # set new thermal stress increment if self.temperature == None: self.deps_th = 0. else: self.deps_th = self.expansion_coefficient * ( self.temperature - self.__temperature_safe) # set PDE coefficients: self.__pde.setValue(A=self.S) self.__pde.setValue(X=-self.stress - self.bulk_modulus * self.deps_th * k3) if self.internal_force: self.__pde.setValue(Y=self.internal_force) if self.external_force: self.__pde.setValue(y=self.external_force) self.__pde.setValue(q=self.location_prescribed_velocity, \ r=Data()) if not self.prescribed_velocity.isEmpty() and self.__iter == 1: self.__pde.setValue(r=dt * self.prescribed_velocity) # solve the PDE: self.__solver_options.setTolerance(self.rel_tol**2) self.du = self.__pde.getSolution() # update geometry self.displacement = self.displacement + self.du self.domain.setX(self.__x + self.displacement) self.velocity = (self.displacement - self.__displacement_safe) / dt if self.debug: for i in range(self.domain.getDim()): self.trace("du %d range %e:%e" % (i, inf(self.du[i]), sup(self.du[i]))) for i in range(self.domain.getDim()): self.trace( "displacement %d range %e:%e" % (i, inf(self.displacement[i]), sup(self.displacement[i]))) for i in range(self.domain.getDim()): self.trace("velocity %d range %e:%e" % (i, inf(self.velocity[i]), sup(self.velocity[i]))) self.__stress_last = self.stress def terminateIteration(self): """iteration is terminateIterationd if relative pressure change is less than rel_tol""" if self.__iter > self.max_iter: raise IterationDivergenceError( "Maximum number of iterations steps reached") if self.__iter == 0: self.__diff = self.UNDEF_DT else: self.__diff, diff_safe = Lsup(self.stress - self.__stress_last), self.__diff s_sup = Lsup(self.stress) self.trace("stress max and increment :%e, %e" % (s_sup, self.__diff)) if self.__iter > 2 and diff_safe < self.__diff: raise IterationDivergenceError( "no improvement in stress iteration") return self.__diff <= self.rel_tol * self.SAFTY_FACTOR_ITERATION * s_sup + self.abs_tol def doStepPostprocessing(self, dt): """ accept all the values: """ self.__displacement_safe = self.displacement self.__temperature_safe = self.temperature self.__stress_safe = self.stress self.__velocity_safe = self.velocity def getSafeTimeStepSize(self, dt): """ returns new step size """ a = sup(length(self.velocity) / self.domain.getSize()) if a > 0: return 1. / a else: return self.UNDEF_DT
# surface bblock = PlaneSurface(bblockloop) ################################################CREATE MESH FOR ESCRIPT # Create a Design which can make the mesh d=Design(dim=2, element_size=200) # Add the subdomains and flux boundaries. d.addItems(PropertySet("top",tblock),PropertySet("bottom",bblock),\ PropertySet("linebottom",l12)) # Create the geometry, mesh and Escript domain d.setScriptFileName(os.path.join(save_path,"example05.geo")) d.setMeshFileName(os.path.join(save_path,"example05.msh")) domain=MakeDomain(d, optimizeLabeling=True) print("Domain has been generated ...") ##############################################################SOLVE PDE mypde=LinearPDE(domain) mypde.getSolverOptions().setVerbosityOn() mypde.setSymmetryOn() kappa=Scalar(0,Function(domain)) kappa.setTaggedValue("top",2.0*W/m/K) kappa.setTaggedValue("bottom",4.0*W/m/K) mypde.setValue(A=kappa*kronecker(domain)) x=Solution(domain).getX() mypde.setValue(q=whereZero(x[1]-sup(x[1])),r=Ttop) qS=Scalar(0,FunctionOnBoundary(domain)) qS.setTaggedValue("linebottom",qin) mypde.setValue(y=qS) print("PDE has been generated ...") ###########################################################GET SOLUTION T=mypde.getSolution() print("PDE has been solved ...")
tend = 0.5 * day # - time to end simulation outputs = 200 # number of time steps required. h = (tend - t) / outputs #size of time step #user warning statement print("Expected Number of time outputs is: ", (tend - t) / h) i = 0 #loop counter #the folder to put our outputs in, leave blank "" for script path save_path = os.path.join("data", "example02") #ensure the dir exists mkDir(save_path, os.path.join(save_path, "tempT")) ####################################################DOMAIN CONSTRUCTION rod = Rectangle(l0=mx, l1=my, n0=ndx, n1=ndy) x = Solution(rod).getX() ###############################################ESCRIPT PDE CONSTRUCTION mypde = LinearPDE(rod) A = zeros((2, 2)) A[0, 0] = kappa q = whereZero(x[0]) mypde.setValue(A=A, D=rhocp / h, q=q, r=T0) # ... set initial temperature .... T = T0 * whereZero(x[0]) + Tref * (1 - whereZero(x[0])) # ... open a collector for the time marks and corresponding total energy t_list = [] E_list = [] # ... convert solution points for plotting plx = x.toListOfTuples() plx = np.array(plx) #convert to tuple to numpy array plx = plx[:, 0] #extract x locations ########################################################START ITERATION
from esys.escript.linearPDEs import LinearPDE try: from esys.finley import Rectangle HAVE_FINLEY = True except ImportError: HAVE_FINLEY = False from esys.weipa import saveVTK if not HAVE_FINLEY: print("Finley module not available") else: #... set some parameters ... kappa=1. omega=0.1 eta=10. #... generate domain ... mydomain = Rectangle(l0=5.,l1=1.,n0=50, n1=10) #... open PDE and set coefficients ... mypde=LinearPDE(mydomain) mypde.setSymmetryOn() n=mydomain.getNormal() x=mydomain.getX() mypde.setValue(A=kappa*kronecker(mydomain),D=omega,Y=omega*x[0], \ d=eta,y=kappa*n[0]+eta*x[0]) #... calculate error of the PDE solution ... u=mypde.getSolution() print("error is ",Lsup(u-x[0])) # output should be similar to "error is 1.e-7" saveVTK("x0.vtu",sol=u)
#~ tester=tester.toListOfTuples() #~ tester=np.reshape(tester,(ndx+1,ndy+1)) #~ pl.clf() #~ pl.imshow(tester) #~ pl.colorbar() #~ pl.savefig("tester3.png") abcT = abc.toListOfTuples() abcT = np.reshape(abcT, (ndx + 1, ndy + 1)) pl.clf() pl.imshow(abcT) pl.colorbar() pl.savefig("abc.png") # ... open new PDE ... mypde = LinearPDE(domain) #mypde.setSolverMethod(LinearPDE.LUMPING) mypde.setSymmetryOn() kmat = kronecker(domain) mypde.setValue(D=kmat * rho) # define small radius around point xc # Lsup(x) returns the maximum value of the argument x src_radius = 50 #2*Lsup(domain.getSize()) print("src_radius = ", src_radius) #dunit=numpy.array([0.,1.]) # defines direction of point source dunit = (x - xc) absrc = length(dunit) dunit = dunit / maximum(absrc, 1e-10)
pl.clf() pl.plot(source) #pl.plot(time,decay1);pl.plot(time,decay2); #pl.plot(time,tdecay) pl.savefig(os.path.join(savepath, 'source.png')) # will introduce a spherical source at middle left of bottom face xc = [mx / 2, 0] ####################################################DOMAIN CONSTRUCTION domain = Rectangle(l0=mx, l1=my, n0=ndx, n1=ndy, order=2) # create the domain x = domain.getX() # get the locations of the nodes in the domani ##########################################################ESTABLISH PDE mypde = LinearPDE(domain) # create pde mypde.setSymmetryOn() # turn symmetry on # turn lumping on for more efficient solving mypde.getSolverOptions().setSolverMethod(SolverOptions.HRZ_LUMPING) kmat = kronecker( domain) # create the kronecker delta function of the domain mypde.setValue(D=kmat * rho) #set the general form value D ##########################################################ESTABLISH ABC # Define where the boundary decay will be applied. bn = 50. bleft = xstep * bn bright = mx - (xstep * bn) bbot = my - (ystep * bn) # btop=ystep*bn # don't apply to force boundary!!!
# Join line segments to create domain boundary. c = CurveLoop(l01, l12, l23, l30) # surface rec = PlaneSurface(c) #############################################EXPORTING MESH FOR ESCRIPT # Create a Design which can make the mesh d = Design(dim=2, element_size=200 * m) # Add the subdomains and flux boundaries. d.addItems(rec, PropertySet("linebottom", l12)) d.addItems(l01, l23, l30) # just in case we need them #############################################MAKE THE DOMAIN domain = MakeDomain(d, optimizeLabeling=True) print("Domain has been generated ...") ##############################################################SOLVE PDE mypde = LinearPDE(domain) mypde.getSolverOptions().setVerbosityOn() mypde.setSymmetryOn() mypde.setValue(A=kappa * kronecker(domain)) x = Solution(domain).getX() mypde.setValue(q=whereZero(x[1] - sup(x[1])), r=Ttop) qS = Scalar(0, FunctionOnBoundary(domain)) qS.setTaggedValue("linebottom", qin) mypde.setValue(y=-qS) print("PDE has been generated ...") ###########################################################GET SOLUTION T = mypde.getSolution() print("PDE has been solved ...") ########################################################### xi, yi, zi = toRegGrid(T, nx=50, ny=50) pl.matplotlib.pyplot.autumn()
#~ tester=np.reshape(tester,(ndx+1,ndy+1)) #~ pl.clf() #~ pl.imshow(tester) #~ pl.colorbar() #~ pl.savefig("tester2.png") #~ #~ tester=fbottom*wherePositive(bottom) #~ tester=tester.toListOfTuples() #~ tester=np.reshape(tester,(ndx+1,ndy+1)) #~ pl.clf() #~ pl.imshow(tester) #~ pl.colorbar() #~ pl.savefig("tester3.png") # ... open new PDE ... mypde = LinearPDE(domain) print(mypde.isUsingLumping()) print(mypde.getSolverOptions()) #mypde.getSolverOptions().setSolverMethod(SolverOptions.LUMPING) mypde.setSymmetryOn() kmat = kronecker(domain) mypde.setValue(D=kmat * rho) # define small radius around point xc # Lsup(x) returns the maximum value of the argument x src_radius = 50 #2*Lsup(domain.getSize()) print("src_radius = ", src_radius) dunit = numpy.array([0., 1.]) # defines direction of point source #~ dunit=(x-xc) #~ absrc=length(dunit)
def wavePropagation(dom, rho, mu, lmbd, eta): x = Function(dom).getX() # ... open new PDE ... mypde = LinearPDE(dom) mypde.setSolverMethod(LinearPDE.LUMPING) k = kronecker(Function(dom)) mypde.setValue(D=k * rho) dt = (1. / 5.) * inf(dom.getSize() / sqrt((2 * mu + lmbd) / rho)) if output: print("time step size = ", dt) # ... set initial values .... n = 0 t = 0 t_write = 0. n_write = 0 # initial value of displacement at point source is constant (U0=0.01) # for first two time steps u = Vector(0., Solution(dom)) v = Vector(0., Solution(dom)) a = Vector(0., Solution(dom)) a2 = Vector(0., Solution(dom)) v = Vector(0., Solution(dom)) if not os.path.isdir(WORKDIR): os.mkdir(WORKDIR) starttime = time.clock() while t < t_end and n < n_end: if output: print(n + 1, "-th time step t ", t + dt, " max u and F: ", Lsup(u), end=' ') # prediction: u_pr = u + dt * v + (dt**2 / 2) * a + (dt**3 / 6) * a2 v_pr = v + dt * a + (dt**2 / 2) * a2 a_pr = a + dt * a2 # ... get current stress .... eps = symmetric(grad(u_pr)) stress = lmbd * trace(eps) * k + 2 * mu * eps # ... force due to event: if abs(t - tc) < 5 * tc_length: F = exp(-((t - tc) / tc_length)**2) * exp(-(length(x - xc) / src_radius)**2) * event if output: print(Lsup(F)) else: if output: print(0.) # ... get new acceleration .... mypde.setValue(X=-stress, Y=F - eta * v_pr) a = mypde.getSolution() # ... get new displacement ... da = a - a_pr u = u_pr + (dt**2 / 12.) * da v = v_pr + (5 * dt / 12.) * da a2 += da / dt # ... save current acceleration in units of gravity and displacements if output: if t >= t_write: saveVTK(os.path.join(WORKDIR, "disp.%i.vtu" % n_write), displacement=u, amplitude=length(u)) t_write += dt_write n_write += 1 t += dt n += 1 endtime = time.clock() totaltime = endtime - starttime global netotal print(">>number of elements: %s, total time: %s, per time step: %s <<" % (netotal, totaltime, totaltime / n))
class StokesProblem(SaddlePointProblem): """ simple example of saddle point problem """ def __init__(self,domain,debug=False): super(StokesProblem, self).__init__(self,debug) self.domain=domain self.__pde_u=LinearPDE(domain,numEquations=self.domain.getDim(),numSolutions=self.domain.getDim()) self.__pde_u.setSymmetryOn() self.__pde_p=LinearPDE(domain) self.__pde_p.setReducedOrderOn() self.__pde_p.setSymmetryOn() def initialize(self,f=Data(),fixed_u_mask=Data(),eta=1): self.eta=eta A =self.__pde_u.createCoefficientOfGeneralPDE("A") for i in range(self.domain.getDim()): for j in range(self.domain.getDim()): A[i,j,j,i] += self.eta A[i,j,i,j] += self.eta self.__pde_p.setValue(D=1/self.eta) self.__pde_u.setValue(A=A,q=fixed_u_mask,Y=f) def inner(self,p0,p1): return integrate(p0*p1,Function(self.__pde_p.getDomain())) def solve_f(self,u,p,tol=1.e-8): self.__pde_u.setTolerance(tol) g=grad(u) self.__pde_u.setValue(X=self.eta*symmetric(g)+p*kronecker(self.__pde_u.getDomain())) return self.__pde_u.getSolution() def solve_g(self,u,tol=1.e-8): self.__pde_p.setTolerance(tol) self.__pde_p.setValue(X=-u) dp=self.__pde_p.getSolution() return dp
def __init__(self,domain): super(SlippingFault, self).__init__(self) self.domain=domain self.__pde_u=LinearPDE(domain,numEquations=self.domain.getDim(),numSolutions=self.domain.getDim()) self.__pde_u.setSymmetryOn()
class MultiScale(object): """ problem description: -(A_{ijkl} u_{k,l})_{,j} = -X_{ij,j} + Y_i Neumann boundary: n_j A_{ijkl} u_{k,l} = n_j X_{ij} + y_i Dirichlet boundary: u_i = r_i where q_i > 0 :var u: unknown vector, displacement :var A: elastic tensor / tangent operator :var X: old/current stress tensor :var Y: vector, body force :var y: vector, Neumann bc traction :var q: vector, Dirichlet bc mask :var r: vector, Dirichlet bc value """ def __init__(self, domain, ng=1, useMPI=False, np=1, random=False, rtol=1.e-2, verbose=False): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param random: type boolean, if or not use random density field :param rtol: type float, relevant tolerance for global convergence :param verbose: type boolean, if or not print messages during calculation """ self.__domain = domain self.__pde = LinearPDE(domain, numEquations=self.__domain.getDim(), numSolutions=self.__domain.getDim()) self.__pde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) self.__pde.setSymmetryOn() #self.__pde.getSolverOptions().setTolerance(rtol**2) #self.__pde.getSolverOptions().setPackage(SolverOptions.UMFPACK) self.__numGaussPoints = ng self.__rtol = rtol self.__verbose = verbose self.__pool = get_pool(mpi=useMPI, threads=np) self.__scenes = self.__pool.map(initLoad, range(ng)) self.__strain = escript.Tensor(0, escript.Function(self.__domain)) self.__stress = escript.Tensor(0, escript.Function(self.__domain)) self.__S = escript.Tensor4(0, escript.Function(self.__domain)) st = self.__pool.map(getStressAndTangent, self.__scenes) for i in xrange(ng): self.__stress.setValueOfDataPoint(i, st[i][0]) self.__S.setValueOfDataPoint(i, st[i][1]) def initialize(self, b=escript.Data(), f=escript.Data(), specified_u_mask=escript.Data(), specified_u_val=escript.Data()): """ initialize the model for each time step, e.g. assign parameters :param b: type vector, body force on FunctionSpace, e.g. gravity :param f: type vector, boundary traction on FunctionSpace (FunctionOnBoundary) :param specified_u_mask: type vector, mask of location for Dirichlet boundary :param specified_u_val: type vector, specified displacement for Dirichlet boundary """ self.__pde.setValue(Y=b, y=f, q=specified_u_mask, r=specified_u_val) def getDomain(self): """ return model domain """ return self.__domain def getRelTolerance(self): """ return relative tolerance for convergence type float """ return self.__rtol def getCurrentPacking(self, pos=(), time=0, prefix=''): if len(pos) == 0: # output all Gauss points packings self.__pool.map(outputPack, zip(self.__scenes, repeat(time), repeat(prefix))) else: # output selected Gauss points packings scene = [self.__scenes[i] for i in pos] self.__pool.map(outputPack, zip(scene, repeat(time), repeat(prefix))) def getLocalVoidRatio(self): void = escript.Scalar(0, escript.Function(self.__domain)) e = self.__pool.map(getVoidRatio, self.__scenes) for i in xrange(self.__numGaussPoints): void.setValueOfDataPoint(i, e[i]) return void def getLocalAvgRotation(self): rot = escript.Vector(0, escript.Function(self.__domain)) r = self.__pool.map(avgRotation, self.__scenes) for i in xrange(self.__numGaussPoints): rot.setValueOfDataPoint(i, r[i]) return rot def getLocalFabric(self): fabric = escript.Tensor(0, escript.Function(self.__domain)) f = self.__pool.map(getFabric, self.__scenes) for i in xrange(self.__numGaussPoints): fabric.setValueOfDataPoint(i, f[i]) return fabric def getCurrentTangent(self): """ return current tangent operator type Tensor4 on FunctionSpace """ return self.__S def getCurrentStress(self): """ return current stress type: Tensor on FunctionSpace """ return self.__stress def getCurrentStrain(self): """ return current strain type: Tensor on FunctionSpace """ return self.__strain def exitSimulation(self): """finish the whole simulation, exit""" self.__pool.close() 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 """ apply strain to DEM packing, get stress and tangent operator (including two methods) """ def applyStrain_getStressTangentDEM(self, st=escript.Data()): st = st.toListOfTuples() st = numpy.array(st).reshape(-1, 9) stress = escript.Tensor(0, escript.Function(self.__domain)) S = escript.Tensor4(0, escript.Function(self.__domain)) scenes = self.__pool.map(shear, zip(self.__scenes, st)) st = self.__pool.map(getStressAndTangent, scenes) for i in xrange(self.__numGaussPoints): stress.setValueOfDataPoint(i, st[i][0]) S.setValueOfDataPoint(i, st[i][1]) return stress, S, scenes
class MultiScale(object): """ problem description: -(A_{ijkl} u_{k,l})_{,j} = -X_{ij,j} + Y_i Neumann boundary: n_j A_{ijkl} u_{k,l} = n_j X_{ij} + y_i Dirichlet boundary: u_i = r_i where q_i > 0 :var u: unknown vector, displacement :var A: elastic tensor / tangent operator :var X: old/current stress tensor :var Y: vector, body force :var y: vector, Neumann bc traction :var q: vector, Dirichlet bc mask :var r: vector, Dirichlet bc value """ def __init__(self,domain,ng=1,useMPI=False,np=1,random=False,rtol=1.e-2,usePert=False,pert=-2.e-6,verbose=False): """ initialization of the problem, i.e. model constructor :param domain: type Domain, domain of the problem :param ng: type integer, number of Gauss points :param useMPI: type boolean, use MPI or not :param np: type integer, number of processors :param random: type boolean, if or not use random density field :param rtol: type float, relevative tolerance for global convergence :param usePert: type boolean, if or not use perturbation method :param pert: type float, perturbated strain applied to DEM to obtain tangent operator :param verbose: type boolean, if or not print messages during calculation """ self.__domain=domain self.__pde=LinearPDE(domain,numEquations=self.__domain.getDim(),numSolutions=self.__domain.getDim()) self.__pde.getSolverOptions().setSolverMethod(SolverOptions.DIRECT) self.__pde.setSymmetryOn() #self.__pde.getSolverOptions().setTolerance(rtol**2) #self.__pde.getSolverOptions().setPackage(SolverOptions.UMFPACK) self.__numGaussPoints=ng self.__rtol=rtol self.__usepert=usePert self.__pert=pert self.__verbose=verbose self.__pool=get_pool(mpi=useMPI,threads=np) self.__scenes=self.__pool.map(initLoad,range(ng)) self.__strain=escript.Tensor(0,escript.Function(self.__domain)) self.__stress=escript.Tensor(0,escript.Function(self.__domain)) self.__S=escript.Tensor4(0,escript.Function(self.__domain)) if self.__usepert: s = self.__pool.map(getStressTensor,self.__scenes) t = self.__pool.map(getTangentOperator,zip(self.__scenes,repeat(pert))) for i in xrange(ng): self.__stress.setValueOfDataPoint(i,s[i]) self.__S.setValueOfDataPoint(i,t[i]) else: st = self.__pool.map(getStressAndTangent2D,self.__scenes) for i in xrange(ng): self.__stress.setValueOfDataPoint(i,st[i][0]) self.__S.setValueOfDataPoint(i,st[i][1]) def initialize(self, b=escript.Data(), f=escript.Data(), specified_u_mask=escript.Data(), specified_u_val=escript.Data()): """ initialize the model for each time step, e.g. assign parameters :param b: type vector, body force on FunctionSpace, e.g. gravity :param f: type vector, boundary traction on FunctionSpace (FunctionOnBoundary) :param specified_u_mask: type vector, mask of location for Dirichlet boundary :param specified_u_val: type vector, specified displacement for Dirichlet boundary """ self.__pde.setValue(Y=b,y=f,q=specified_u_mask,r=specified_u_val) def getDomain(self): """ return model domain """ return self.__domain def getRelTolerance(self): """ return relative tolerance for convergence type float """ return self.__rtol def getCurrentPacking(self,pos=(),time=0,prefix=''): if len(pos) == 0: # output all Gauss points packings self.__pool.map(outputPack,zip(self.__scenes,repeat(time),repeat(prefix))) else: # output selected Gauss points packings scene = [self.__scenes[i] for i in pos] self.__pool.map(outputPack,zip(scene,repeat(time),repeat(prefix))) def getLocalVoidRatio(self): void=escript.Scalar(0,escript.Function(self.__domain)) e = self.__pool.map(getVoidRatio2D,self.__scenes) for i in xrange(self.__numGaussPoints): void.setValueOfDataPoint(i,e[i]) return void def getLocalAvgRotation(self): rot=escript.Scalar(0,escript.Function(self.__domain)) r = self.__pool.map(avgRotation2D,self.__scenes) for i in xrange(self.__numGaussPoints): rot.setValueOfDataPoint(i,r[i]) return rot def getLocalFabric(self): fabric=escript.Tensor(0,escript.Function(self.__domain)) f = self.__pool.map(getFabric2D,self.__scenes) for i in xrange(self.__numGaussPoints): fabric.setValueOfDataPoint(i,f[i]) return fabric """ used for clumped particle model only def getLocalParOriFab(self): fabric=escript.Tensor(0,escript.Function(self.__domain)) f = self.__pool.map(getParOriFabric,self.__scenes) for i in xrange(self.__numGaussPoints): fabric.setValueOfDataPoint(i,f[i]) return fabric """ """ used for cohesive particle model only def getLocalBondBreakage(self,oriIntr=[]): debond = escript.Scalar(0,escript.Function(self.__domain)) num = self.__pool.map(getDebondingNumber,zip(self.__scenes,repeat(oriIntr))) for i in xrange(self.__numGaussPoints): debond.setValueOfDataPoint(i,num[i]) return debond """ def getCurrentTangent(self): """ return current tangent operator type Tensor4 on FunctionSpace """ return self.__S def getCurrentStress(self): """ return current stress type: Tensor on FunctionSpace """ return self.__stress def getCurrentStrain(self): """ return current strain type: Tensor on FunctionSpace """ return self.__strain def exitSimulation(self): """finish the whole simulation, exit""" self.__pool.close() 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 """ apply strain to DEM packing, get stress and tangent operator (including two methods) """ def applyStrain_getStressTangentDEM(self,st=escript.Data()): st = st.toListOfTuples() st = numpy.array(st).reshape(-1,4) stress = escript.Tensor(0,escript.Function(self.__domain)) S = escript.Tensor4(0,escript.Function(self.__domain)) scenes = self.__pool.map(shear2D,zip(self.__scenes,st)) if self.__usepert: s = self.__pool.map(getStressTensor,scenes) t = self.__pool.map(getTangentOperator,zip(scenes,repeat(self.__pert))) for i in xrange(self.__numGaussPoints): stress.setValueOfDataPoint(i,s[i]) S.setValueOfDataPoint(i,t[i]) else: ST = self.__pool.map(getStressAndTangent2D,scenes) for i in xrange(self.__numGaussPoints): stress.setValueOfDataPoint(i,ST[i][0]) S.setValueOfDataPoint(i,ST[i][1]) return stress,S,scenes
domain = Brick(l0=mx,l1=my,n0=ndx, n1=ndy,l2=mz,n2=ndz) x=Solution(domain).getX() x=x-[mx/2,my/2,mz/2] domain.setX(interpolate(x, ContinuousFunction(domain))) mask=wherePositive(100-length(x-rholoc)) rho=rho*mask kro=kronecker(domain) mass=rho*vol(domain) ipot=FunctionOnBoundary(domain) xb=ipot.getX() q=whereZero(x[2]-inf(x[2])) ###############################################ESCRIPT PDE CONSTRUCTION mypde=LinearPDE(domain) mypde.setValue(A=kro,Y=4.*3.1415*G*rho,q=q,r=0) mypde.setSymmetryOn() sol=mypde.getSolution() saveVTK(os.path.join(save_path,"ex10b.vtu"),\ grav_pot=sol,\ g_field=-grad(sol),\ g_fieldz=-grad(sol)*[0,0,1],\ gz=length(-grad(sol)*[0,0,1])) ################################################MODEL SIZE SAMPLING sampler=[] for i in range(-250,250,1): sampler.append([i,0,250]) sample=[] # array to hold values
# data recording times rtime = 0.0 # first time to record rtime_inc = tend / 20.0 # time increment to record #Check to make sure number of time steps is not too large. print("Time step size= ", h, "Expected number of outputs= ", tend / h) U0 = 0.005 # amplitude of point source # want a spherical source in the middle of area xc = [500, 500] # with reference to mx,my this is the source location ####################################################DOMAIN CONSTRUCTION mydomain = Rectangle(l0=mx, l1=my, n0=ndx, n1=ndy) # create the domain x = mydomain.getX() # get the node locations of the domain ##########################################################ESTABLISH PDE mypde = LinearPDE(mydomain) # create pde mypde.setSymmetryOn() # turn symmetry on mypde.setValue(D=1.) # set the value of D in the general form to 1. ############################################FIRST TIME STEPS AND SOURCE # define small radius around point xc src_radius = 30 print("src_radius = ", src_radius) # set initial values for first two time steps with source terms u = U0 * (cos(length(x - xc) * 3.1415 / src_radius) + 1) * whereNegative(length(x - xc) - src_radius) u_m1 = u #plot source shape cut_loc = [] #where the cross section of the source along x will be src_cut = [] #where the cross section of the source will be # create locations for source cross section
slip_max=1. mydomain = Rectangle(l0=1.,l1=1.,n0=16, n1=16) # n1 need to be multiple of 4!!! # .. create the fault system fs=FaultSystem(dim=2) fs.addFault(V0=[0.5,0.25], strikes=90*DEG, ls=0.5, tag=1) # ... create a slip distribution on the fault: p, m=fs.getParametrization(mydomain.getX(),tag=1) p0,p1= fs.getW0Range(tag=1) s=m*(p-p0)*(p1-p)/((p1-p0)/2)**2*slip_max*[0.,1.] # ... calculate stress according to slip: D=symmetric(grad(s)) chi, d=fs.getSideAndDistance(D.getFunctionSpace().getX(),tag=1) sigma_s=(mu*D+lam*trace(D)*kronecker(mydomain))*chi #... open symmetric PDE ... mypde=LinearPDE(mydomain) mypde.setSymmetryOn() #... set coefficients ... C=Tensor4(0.,Function(mydomain)) for i in range(mydomain.getDim()): for j in range(mydomain.getDim()): C[i,i,j,j]+=lam C[j,i,j,i]+=mu C[j,i,i,j]+=mu # ... fix displacement in normal direction x=mydomain.getX() msk=whereZero(x[0])*[1.,0.] + whereZero(x[0]-1.)*[1.,0.] \ +whereZero(x[1])*[0.,1.] + whereZero(x[1]-1.)*[0.,1.] mypde.setValue(A=C,X=-0.5*sigma_s,q=msk) #... solve pde ... mypde.getSolverOptions().setVerbosityOn()
x = domain.getX() # get the locations of the nodes in the domain lam = Scalar(0, Function(domain)) mu = Scalar(0, Function(domain)) rho = Scalar(0, Function(domain)) #Setting parameters for each layer in the model. for i in range(0, nlayers): rho.setTaggedValue("volume_%d" % i, rhoc + i * 100.) lamc = (vel + i * 100.)**2. * (rhoc + i * 100.) / 2. muc = (vel + i * 100.)**2. * (rhoc + i * 100.) / 4. lam.setTaggedValue("volume_%d" % i, lamc) mu.setTaggedValue("volume_%d" % i, muc) ##########################################################ESTABLISH PDE mypde = LinearPDE(domain) # create pde mypde.setSymmetryOn() # turn symmetry on # turn lumping on for more efficient solving #mypde.getSolverOptions().setSolverMethod(SolverOptions.HRZ_LUMPING) kmat = kronecker( domain) # create the kronecker delta function of the domain mypde.setValue(D=rho * kmat) #set the general form value D ############################################FIRST TIME STEPS AND SOURCE # define small radius around point xc src_rad = 20 print("src radius= ", src_rad) # set initial values for first two time steps with source terms xb = FunctionOnBoundary(domain).getX() yx = (cos(length(xb - xc) * 3.1415 / src_rad) + 1) * whereNegative(length(xb - xc) - src_rad)
mydomain = Rectangle(l0=1., l1=1., n0=16, n1=16) # n1 need to be multiple of 4!!! # .. create the fault system fs = FaultSystem(dim=2) fs.addFault(V0=[0.5, 0.25], strikes=90 * DEG, ls=0.5, tag=1) # ... create a slip distribution on the fault: p, m = fs.getParametrization(mydomain.getX(), tag=1) p0, p1 = fs.getW0Range(tag=1) s = m * (p - p0) * (p1 - p) / ((p1 - p0) / 2)**2 * slip_max * [0., 1.] # ... calculate stress according to slip: D = symmetric(grad(s)) chi, d = fs.getSideAndDistance(D.getFunctionSpace().getX(), tag=1) sigma_s = (mu * D + lam * trace(D) * kronecker(mydomain)) * chi #... open symmetric PDE ... mypde = LinearPDE(mydomain) mypde.setSymmetryOn() #... set coefficients ... C = Tensor4(0., Function(mydomain)) for i in range(mydomain.getDim()): for j in range(mydomain.getDim()): C[i, i, j, j] += lam C[j, i, j, i] += mu C[j, i, i, j] += mu # ... fix displacement in normal direction x = mydomain.getX() msk=whereZero(x[0])*[1.,0.] + whereZero(x[0]-1.)*[1.,0.] \ +whereZero(x[1])*[0.,1.] + whereZero(x[1]-1.)*[0.,1.] mypde.setValue(A=C, X=-0.5 * sigma_s, q=msk) #... solve pde ... mypde.getSolverOptions().setVerbosityOn()
res.setTaggedValue("volume_2",res3) res.setTaggedValue("volume_3",res4) con=1/res x=Solution(domain).getX() kro=kronecker(domain) source1=[3.*mx/8.,my/2,0]; source2=[5.*mx/8.,my/2,0] c1=length(exp(-length(x-source1)/(10.))); c1=c1/integrate(c1) c2=-length(exp(-length(x-source2)/(10.))); c2=c2/integrate(c2) sourceg=cur*(c1-c2) q=whereZero(x[1]-my)+whereZero(x[1])+whereZero(x[0])+whereZero(x[0]-mx)+whereZero(x[2]-mz) ###############################################ESCRIPT PDE CONSTRUCTION mypde=LinearPDE(domain) mypde.setValue(A=con*kro,Y=sourceg,q=q,r=0) #mypde.setSymmetryOn() sol=mypde.getSolution() res.expand() # Save the output to file. saveVTK(os.path.join(save_path,"ex11c.vtu"),\ source=sourceg,\ res_pot=sol,\ res=res,\ curden=-con*grad(sol),\ abscd=length(-con*grad(sol)),\ efield=-grad(sol))
L0=1.;L1=1. # location, size and value of heat source xc=[0.3,0.4]; r=0.1; Qc=3000 # material parameter k=1; rhocp=100; # bottom temperature: T_bot=100 # generate domain: mydomain=Rectangle(l0=L0,l1=L1,n0=20,n1=20) x=mydomain.getX() # set boundray temperature: T_D=T_bot/L1*(L1-x[1]) # set heat source: Q=Qc*whereNegative(length(x-xc)-r) # generate domain: mypde=LinearPDE(mydomain) mypde.setSymmetryOn() # set PDE coefficients: mypde.setValue(A=dt*k*kronecker(mydomain), D=dt*rhocp, r=T_D, q=whereZero(x[1])+whereZero(x[1]-L1)) # initial temperature T=T_D # step counter and time marker: N=0; t=0 # stop when t_end is reached: while t<t_end: print("time step %d, t=%s"%(N,t)) # update PDE coefficient: mypde.setValue(Y=dt*rhocp*T+dt*Q) # new temperature: T=mypde.getSolution()
def runTest(dom, n=1, a=0, b=0): print("================== TEST : n= %s a=%s b=%s ================" % (n, a, b)) DIM = dom.getDim() normal = dom.getNormal() mypde = LinearPDE(dom, numEquations=n, numSolutions=n) x = dom.getX() A = mypde.createCoefficient("A") D = mypde.createCoefficient("D") Y = mypde.createCoefficient("Y") y = mypde.createCoefficient("y") q = mypde.createCoefficient("q") if n == 1: u_ref = Scalar(0., Solution(dom)) for j in range(DIM): q += whereZero(x[j]) A[j, j] = 1 y += sin(sqrt(2.)) * normal[0] Y += b * x[0] * sin(sqrt(2.)) D += b u_ref = x[0] * sin(sqrt(2.)) else: u_ref = Data(0., (n, ), Solution(dom)) for i in range(n): for j in range(DIM): q[i] += whereZero(x[j]) A[i, j, i, j] = 1 if j == i % DIM: y[i] += sin(i + sqrt(2.)) * normal[j] for j in range(n): if i == j: D[i, i] = b + (n - 1) * a Y[i] += b * x[i % DIM] * sin(i + sqrt(2.)) else: D[i, j] = -a Y[i] += a * (x[i % DIM] * sin(i + sqrt(2.)) - x[j % DIM] * sin(j + sqrt(2.))) u_ref[i] = x[i % DIM] * sin(i + sqrt(2.)) # - u_{j,ii} + b*u_i+ a*sum_{k<>j} (u_i-u_k) = F_j mypde.setValue(A=A, D=D, y=y, q=q, r=u_ref, Y=Y) mypde.getSolverOptions().setVerbosityOn() mypde.getSolverOptions().setTolerance(TOL) mypde.setSymmetryOn() u = mypde.getSolution() error = Lsup(u - u_ref) / Lsup(u_ref) print("error = ", error) if error > 10 * TOL: print( "XXXXXXXXXX Error to large ! XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
save_path = os.path.join("data", "example10") #ensure the dir exists mkDir(save_path) ####################################################DOMAIN CONSTRUCTION domain = Rectangle(l0=mx, l1=my, n0=ndx, n1=ndy) x = Solution(domain).getX() mask = wherePositive(10 - length(x - rholoc)) rho = rho * mask kro = kronecker(domain) q = whereZero(x[1] - my) + whereZero(x[1]) + whereZero( x[0]) + whereZero(x[0] - mx) ###############################################ESCRIPT PDE CONSTRUCTION mypde = LinearPDE(domain) mypde.setValue(A=kro, Y=4. * 3.1415 * G * rho) mypde.setValue(q=q, r=0) mypde.setSymmetryOn() sol = mypde.getSolution() g_field = grad(sol) #The gravitational acceleration g. g_fieldz = g_field * [0, 1] #The vertical component of the g field. gz = length(g_fieldz) #The magnitude of the vertical component. # Save the output to file. saveVTK(os.path.join(save_path,"ex10a.vtu"),\ grav_pot=sol,g_field=g_field,g_fieldz=g_fieldz,gz=gz) ##################################################REGRIDDING & PLOTTING xi, yi, zi = toRegGrid(sol, nx=50, ny=50)
domain = MakeDomain(d, optimizeLabeling=True) x = domain.getX() print("Domain has been generated ...") lam = Scalar(0, Function(domain)) lam.setTaggedValue("top", lam1) lam.setTaggedValue("bottom", lam2) mu = Scalar(0, Function(domain)) mu.setTaggedValue("top", mu1) mu.setTaggedValue("bottom", mu2) rho = Scalar(0, Function(domain)) rho.setTaggedValue("top", rho1) rho.setTaggedValue("bottom", rho2) ##########################################################ESTABLISH PDE mypde = LinearPDE(domain) # create pde mypde.setSymmetryOn() # turn symmetry on # turn lumping on for more efficient solving # mypde.getSolverOptions().setSolverMethod(SolverOptions.LUMPING) kmat = kronecker(domain) # create the kronecker delta function of the domain mypde.setValue(D=rho * kmat) # set the general form value D ##########################################################ESTABLISH ABC # Define where the boundary decay will be applied. bn = 20.0 bleft = xstep * bn bright = width - (xstep * bn) bbot = depth - (ystep * bn) # btop=ystep*bn # don't apply to force boundary!!! # locate these points in the domain
class TemperatureAdvection(Model): """ The conservation of internal heat energy is given by *rho c_p ( dT/dt+v[j] * grad(T)[j])-grad(\kappa grad(T)_{,i}=Q* *n_i \kappa T_{,i}=0* it is assummed that *\rho c_p* is constant in time. solved by Taylor Galerkin method """ def __init__(self,**kwargs): super(TemperatureAdvection, self).__init__(**kwargs) self.declareParameter(domain=None, \ temperature=1., \ velocity=numpy.zeros([3]), density=1., \ heat_capacity=1., \ thermal_permabilty=1., \ # reference_temperature=0., \ # radiation_coefficient=0., \ thermal_source=0., \ fixed_temperature=0., location_fixed_temperature=Data(), safety_factor=0.1) def doInitialization(self): self.__pde=LinearPDE(self.domain) self.__pde.setSymmetryOn() self.__pde.setReducedOrderOn() self.__pde.getSolverOptions().setSolverMethod(SolverOptions.LUMPING) self.__pde.setValue(D=self.heat_capacity*self.density) def getSafeTimeStepSize(self,dt): """ returns new step size """ h=self.domain.getSize() return self.safety_factor*inf(h**2/(h*abs(self.heat_capacity*self.density)*length(self.velocity)+self.thermal_permabilty)) def G(self,T,alpha): """ tangential operator for taylor galerikin """ g=grad(T) self.__pde.setValue(X=-self.thermal_permabilty*g, \ Y=self.thermal_source-self.__rhocp*inner(self.velocity,g), \ r=(self.__fixed_T-self.temperature)*alpha,\ q=self.location_fixed_temperature) return self.__pde.getSolution() def doStepPostprocessing(self,dt): """ perform taylor galerkin step """ T=self.temperature self.__rhocp=self.heat_capacity*self.density self.__fixed_T=self.fixed_temperature self.temperature=dt*self.G(dt/2*self.G(T,1./dt)+T,1./dt)+T self.trace("Temperature range is %e %e"%(inf(self.temperature),sup(self.temperature)))
#~ pl.clf() #~ pl.imshow(tester) #~ pl.colorbar() #~ pl.savefig("tester2.png") #~ #~ tester=fbottom*wherePositive(bottom) #~ tester=tester.toListOfTuples() #~ tester=np.reshape(tester,(ndx+1,ndy+1)) #~ pl.clf() #~ pl.imshow(tester) #~ pl.colorbar() #~ pl.savefig("tester3.png") # ... open new PDE ... mypde=LinearPDE(domain) print(mypde.isUsingLumping()) print(mypde.getSolverOptions()) #mypde.getSolverOptions().setSolverMethod(SolverOptions.LUMPING) mypde.setSymmetryOn() kmat = kronecker(domain) mypde.setValue(D=kmat*rho) # define small radius around point xc # Lsup(x) returns the maximum value of the argument x src_radius = 50#2*Lsup(domain.getSize()) print("src_radius = ",src_radius) dunit=numpy.array([0.,1.]) # defines direction of point source #~ dunit=(x-xc) #~ absrc=length(dunit)
def doInitialization(self): self.__pde=LinearPDE(self.domain) self.__pde.setSymmetryOn() self.__pde.setReducedOrderOn() self.__pde.getSolverOptions().setSolverMethod(SolverOptions.LUMPING) self.__pde.setValue(D=self.heat_capacity*self.density)