def Mult(self, x, y): globals()['max_char_speed'] = 0.; num_equation = globals()['num_equation'] # 1. Create the vector z with the face terms -<F.n(u), [w]>. self.A.Mult(x, self.z); # 2. Add the element terms. # i. computing the flux approximately as a grid function by interpolating # at the solution nodes. # ii. multiplying this grid function by a (constant) mixed bilinear form for # each of the num_equation, computing (F(u), grad(w)) for each equation. xmat = mfem.DenseMatrix(x.GetData(), self.vfes.GetNDofs(), num_equation) self.GetFlux(xmat, self.flux) for k in range(num_equation): fk = mfem.Vector(self.flux[k].GetData(), self.dim * self.vfes.GetNDofs()) o = k * self.vfes.GetNDofs() zk = self.z[o: o+self.vfes.GetNDofs()] self.Aflux.AddMult(fk, zk) # 3. Multiply element-wise by the inverse mass matrices. zval = mfem.Vector() vdofs = mfem.intArray() dof = self.vfes.GetFE(0).GetDof() zmat = mfem.DenseMatrix() ymat = mfem.DenseMatrix(dof, num_equation) for i in range(self.vfes.GetNE()): # Return the vdofs ordered byNODES vdofs = mfem.intArray(self.vfes.GetElementVDofs(i)) self.z.GetSubVector(vdofs, zval) zmat.UseExternalData(zval.GetData(), dof, num_equation) mfem.Mult(self.Me_inv[i], zmat, ymat); y.SetSubVector(vdofs, ymat.GetData())
def __init__(self, M, S, H): mfem.PyOperator.__init__(self, M.Height()) self.M = M self.S = S self.H = H self.Jacobian = None h = M.Height() self.w = mfem.Vector(h) self.z = mfem.Vector(h) self.dt = 0.0
def Mult(self, vx, vx_dt): sc = self.Height() / 2 v = mfem.Vector(vx, 0, sc) x = mfem.Vector(vx, sc, sc) dv_dt = mfem.Vector(dvx_dt, 0, sc) dx_dt = mfem.Vector(dvx_dt, sc, sc) self.H.Mult(x, z) if (self.viscosity != 0.0): S.AddMult(v, z) z.Neg() M_solver.Mult(z, dv_dt) dx_dt = v
def get_nodalvalues(solset, curl=False, grad=False, div=False): if grad: assert False, "evaluating Grad is not implemented" if div: assert False, "evaluating Div is not implemented" import petram.helper.eval_deriv as eval_deriv from collections import defaultdict nodalvalues = defaultdict(list) for meshes, s in solset: # this is MPI rank loop for name in s: gfr, gfi = s[name] m = gfr.FESpace().GetMesh() size = m.GetNV() ptx = np.vstack([m.GetVertexArray(i) for i in range(size)]) gfro, gfio = gfr, gfi if curl: gfr, gfi, extra = eval_deriv.eval_curl(gfr, gfi) dim = gfr.VectorDim() ret = np.zeros((size, dim), dtype=float) for comp in range(dim): values = mfem.Vector() gfr.GetNodalValues(values, comp + 1) ret[:, comp] = values.GetDataArray() values.StealData() if gfi is None: nodalvalues[name].append((ptx, ret, gfr)) continue ret2 = np.zeros((size, dim), dtype=float) for comp in range(dim): values = mfem.Vector() gfi.GetNodalValues(values, comp + 1) if ret2 is None: ret2 = np.zeros((values.Size(), dim), dtype=float) ret2[:, comp] = values.GetDataArray() values.StealData() ret = ret + 1j * ret2 nodalvalues[name].append((ptx, ret, gfro)) nodalvalues.default_factory = None return nodalvalues
def __init__(self, dim): num_equation = globals()['num_equation'] self.flux = mfem.DenseMatrix(num_equation, dim) self.shape = mfem.Vector() self.dshapedr = mfem.DenseMatrix() self.dshapedx = mfem.DenseMatrix() super(DomainIntegrator, self).__init__()
def ImplicitSolve(self, dt, vx, dvx_dt): sc = self.Height() / 2 v = mfem.Vector(vx, 0, sc) x = mfem.Vector(vx, sc, sc) dv_dt = mfem.Vector(dvx_dt, 0, sc) dx_dt = mfem.Vector(dvx_dt, sc, sc) # By eliminating kx from the coupled system: # kv = -M^{-1}*[H(x + dt*kx) + S*(v + dt*kv)] # kx = v + dt*kv # we reduce it to a nonlinear equation for kv, represented by the # backward_euler_oper. This equation is solved with the newton_solver # object (using J_solver and J_prec internally). self.backward_euler_oper.SetParameters(dt, v, x) zero = mfem.Vector() # empty vector is interpreted as # zero r.h.s. by NewtonSolver self.newton_solver.Mult(zero, dv_dt) add_vector(v, dt, dv_dt, dx_dt)
def Mult(self, k, y): # Extract the blocks from the input and output vectors block_offsets = self.block_offsets disp_in = k[block_offsets[0]:block_offsets[1]] pres_in = k[block_offsets[1]:block_offsets[2]] disp_out = y[block_offsets[0]:block_offsets[1]] pres_out = y[block_offsets[1]:block_offsets[2]] temp = mfem.Vector(block_offsets[1] - block_offsets[0]) temp2 = mfem.Vector(block_offsets[1] - block_offsets[0]) # Perform the block elimination for the preconditioner self.mass_pcg.Mult(pres_in, pres_out) pres_out *= -self.gamma self.jacobian.GetBlock(0, 1).Mult(pres_out, temp) mfem.subtract_vector(disp_in, temp, temp2) self.stiff_pcg.Mult(temp2, disp_out)
def SnapNodes(mesh): nodes = mesh.GetNodes() node = mfem.Vector(mesh.SpaceDimension()) for i in np.arange(nodes.FESpace().GetNDofs()): for d in np.arange(mesh.SpaceDimension()): node[d] = nodes[nodes.FESpace().DofToVDof(i, d)] node /= node.Norml2() for d in range(mesh.SpaceDimension()): nodes[nodes.FESpace().DofToVDof(i, d)] = node[d]
def __init__(self, vfes, A, A_flux): self.dim = vfes.GetFE(0).GetDim() self.vfes = vfes self.A = A self.Aflux = A_flux self.Me_inv = mfem.DenseTensor(vfes.GetFE(0).GetDof(), vfes.GetFE(0).GetDof(), vfes.GetNE()) self.state = mfem.Vector(num_equation) self.f = mfem.DenseMatrix(num_equation, self.dim) self.flux = mfem.DenseTensor(vfes.GetNDofs(), self.dim, num_equation) self.z = mfem.Vector(A.Height()) dof = vfes.GetFE(0).GetDof() Me = mfem.DenseMatrix(dof) inv = mfem.DenseMatrixInverse(Me) mi = mfem.MassIntegrator() for i in range(vfes.GetNE()): mi.AssembleElementMatrix(vfes.GetFE(i), vfes.GetElementTransformation(i), Me) inv.Factor() inv.GetInverseMatrix(self.Me_inv(i)) super(FE_Evolution, self).__init__(A.Height())
def __init__(self, rsolver, dim): self.rsolver = rsolver self.shape1 = mfem.Vector() self.shape2 = mfem.Vector() self.funval1 = mfem.Vector(num_equation) self.funval2 = mfem.Vector(num_equation) self.nor = mfem.Vector(dim) self.fluxN = mfem.Vector(num_equation) self.eip1 = mfem.IntegrationPoint() self.eip2 = mfem.IntegrationPoint() super(FaceIntegrator, self).__init__()
def __init__(self, M, K, b): mfem.PyTimeDependentOperator.__init__(self, M.Size()) self.K = K self.M = M self.b = b self.z = mfem.Vector(M.Size()) self.zp = np.zeros(M.Size()) self.M_prec = mfem.DSmoother() self.M_solver = mfem.CGSolver() self.M_solver.SetPreconditioner(self.M_prec) self.M_solver.SetOperator(M) self.M_solver.iterative_mode = False self.M_solver.SetRelTol(1e-9) self.M_solver.SetAbsTol(0.0) self.M_solver.SetMaxIter(100) self.M_solver.SetPrintLevel(0)
def __init__(self, fespace, alpha, kappa, u): mfem.PyTimeDependentOperator.__init__(self, fespace.GetTrueVSize(), 0.0) rel_tol = 1e-8 self.alpha = alpha self.kappa = kappa self.T = None self.K = None self.M = None self.fespace = fespace self.ess_tdof_list = intArray() self.Mmat = mfem.SparseMatrix() self.Kmat = mfem.SparseMatrix() self.M_solver = mfem.CGSolver() self.M_prec = mfem.DSmoother() self.T_solver = mfem.CGSolver() self.T_prec = mfem.DSmoother() self.z = mfem.Vector(self.Height()) self.M = mfem.BilinearForm(fespace) self.M.AddDomainIntegrator(mfem.MassIntegrator()) self.M.Assemble() self.M.FormSystemMatrix(self.ess_tdof_list, self.Mmat) self.M_solver.iterative_mode = False self.M_solver.SetRelTol(rel_tol) self.M_solver.SetAbsTol(0.0) self.M_solver.SetMaxIter(30) self.M_solver.SetPrintLevel(0) self.M_solver.SetPreconditioner(self.M_prec) self.M_solver.SetOperator(self.Mmat) self.T_solver.iterative_mode = False self.T_solver.SetRelTol(rel_tol) self.T_solver.SetAbsTol(0.0) self.T_solver.SetMaxIter(100) self.T_solver.SetPrintLevel(0) self.T_solver.SetPreconditioner(self.T_prec) self.SetParameters(u)
M = mVarf.SpMat() bVarf.AddDomainIntegrator(mfem.VectorFEDivergenceIntegrator()) bVarf.Assemble() bVarf.Finalize() B = bVarf.SpMat() B *= -1 BT = mfem.Transpose(B) darcyOp = mfem.BlockOperator(block_offsets) darcyOp.SetBlock(0, 0, M) darcyOp.SetBlock(0, 1, BT) darcyOp.SetBlock(1, 0, B) MinvBt = mfem.Transpose(B) Md = mfem.Vector(M.Height()) M.GetDiag(Md) for i in range(Md.Size()): MinvBt.ScaleRow(i, 1 / Md[i]) S = mfem.Mult(B, MinvBt) invM = mfem.DSmoother(M) invS = mfem.GSSmoother(S) invM.iterative_mode = False invS.iterative_mode = False darcyPrec = mfem.BlockDiagonalPreconditioner(block_offsets) darcyPrec.SetDiagonalBlock(0, invM) darcyPrec.SetDiagonalBlock(1, invS) maxIter = 500
def __init__(self): num_equation = globals()['num_equation'] self.flux1 = mfem.Vector(num_equation) self.flux2 = mfem.Vector(num_equation)
def run(order=1, static_cond=False, meshfile=def_meshfile, visualization=False): mesh = mfem.Mesh(meshfile, 1, 1) dim = mesh.Dimension() # 3. Refine the mesh to increase the resolution. In this example we do # 'ref_levels' of uniform refinement. We choose 'ref_levels' to be the # largest number that gives a final mesh with no more than 50,000 # elements. ref_levels = int(np.floor( np.log(50000. / mesh.GetNE()) / np.log(2.) / dim)) for x in range(ref_levels): mesh.UniformRefinement() #5. Define a finite element space on the mesh. Here we use vector finite # elements, i.e. dim copies of a scalar finite element space. The vector # dimension is specified by the last argument of the FiniteElementSpace # constructor. For NURBS meshes, we use the (degree elevated) NURBS space # associated with the mesh nodes. if order > 0: fec = mfem.H1_FECollection(order, dim) elif mesh.GetNodes(): fec = mesh.GetNodes().OwnFEC() prinr("Using isoparametric FEs: " + str(fec.Name())) else: order = 1 fec = mfem.H1_FECollection(order, dim) fespace = mfem.FiniteElementSpace(mesh, fec) print('Number of finite element unknowns: ' + str(fespace.GetTrueVSize())) # 5. Determine the list of true (i.e. conforming) essential boundary dofs. # In this example, the boundary conditions are defined by marking all # the boundary attributes from the mesh as essential (Dirichlet) and # converting them to a list of true dofs. ess_tdof_list = mfem.intArray() if mesh.bdr_attributes.Size() > 0: ess_bdr = mfem.intArray([1] * mesh.bdr_attributes.Max()) ess_bdr = mfem.intArray(mesh.bdr_attributes.Max()) ess_bdr.Assign(1) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) #6. Set up the linear form b(.) which corresponds to the right-hand side of # the FEM linear system, which in this case is (1,phi_i) where phi_i are # the basis functions in the finite element fespace. b = mfem.LinearForm(fespace) one = mfem.ConstantCoefficient(1.0) b.AddDomainIntegrator(mfem.DomainLFIntegrator(one)) b.Assemble() #7. Define the solution vector x as a finite element grid function # corresponding to fespace. Initialize x with initial guess of zero, # which satisfies the boundary conditions. x = mfem.GridFunction(fespace) x.Assign(0.0) #8. Set up the bilinear form a(.,.) on the finite element space # corresponding to the Laplacian operator -Delta, by adding the Diffusion # domain integrator. a = mfem.BilinearForm(fespace) a.AddDomainIntegrator(mfem.DiffusionIntegrator(one)) #9. Assemble the bilinear form and the corresponding linear system, # applying any necessary transformations such as: eliminating boundary # conditions, applying conforming constraints for non-conforming AMR, # static condensation, etc. if static_cond: a.EnableStaticCondensation() a.Assemble() A = mfem.OperatorPtr() B = mfem.Vector() X = mfem.Vector() a.FormLinearSystem(ess_tdof_list, x, b, A, X, B) print("Size of linear system: " + str(A.Height())) # 10. Solve AA = mfem.OperatorHandle2SparseMatrix(A) M = mfem.GSSmoother(AA) mfem.PCG(AA, M, B, X, 1, 200, 1e-12, 0.0) # 11. Recover the solution as a finite element grid function. a.RecoverFEMSolution(X, b, x) # 12. Save the refined mesh and the solution. This output can be viewed later # using GLVis: "glvis -m refined.mesh -g sol.gf". mesh.Print('refined.mesh', 8) x.Save('sol.gf', 8) #13. Send the solution by socket to a GLVis server. if (visualization): sol_sock = mfem.socketstream("localhost", 19916) sol_sock.precision(8) sol_sock.send_solution(mesh, x)
S0.Finalize() matB0 = B0.SpMat() matBhat = Bhat.SpMat() matSinv = Sinv.SpMat() matS0 = S0.SpMat() # 8. Set up the 1x2 block Least Squares DPG operator, B = [B0 Bhat], # the normal equation operator, A = B^t Sinv B, and # the normal equation right-hand-size, b = B^t Sinv F. B = mfem.BlockOperator(offsets_test, offsets) B.SetBlock(0, 0, matB0) B.SetBlock(0, 1, matBhat) A = mfem.RAPOperator(B, matSinv, B) SinvF = mfem.Vector(s_test) matSinv.Mult(F,SinvF) B.MultTranspose(SinvF, b) # 9. Set up a block-diagonal preconditioner for the 2x2 normal equation # # [ S0^{-1} 0 ] # [ 0 Shat^{-1} ] Shat = (Bhat^T Sinv Bhat) # # corresponding to the primal (x0) and interfacial (xhat) unknowns. # RAP_R replaces RAP, since RAP has two definition one accept # pointer and the other accept reference. From Python, two # can not be distingished.. Shat = mfem.RAP_R(matBhat, matSinv, matBhat);
''' vector_example.py demonstrate how to make mfem::Vector and assine values from numpy array ''' import numpy as np import mfem.ser as mfem import traceback as tb ## Vector Creation print("You can create mfem::Vector from numpy array") vec = np.array([1, 2, 3, 4, 5.]) v = mfem.Vector(vec) v.Print() print("Please Maks sure that you are passing float") vec = np.array([1, 2, 3, 4, 5]).astype(float) v = mfem.Vector(vec) v.Print() print("This one does not work") vec = np.array([1, 2, 3, 4, 5]) try: v = mfem.Vector(vec) except: tb.print_exc() ## Setting Vector using mfem::Vector or numpy array
def __init__(self, fespace, ess_bdr, visc, mu, K): mfem.PyTimeDependentOperator.__init__(self, 2 * fespace.GetVSize(), 0.0) rel_tol = 1e-8 skip_zero_entries = 0 ref_density = 1.0 self.z = mfem.Vector(self.Height() / 2) self.fespace = fespace self.viscosity = visc M = mfem.BilinearForm(fespace) S = mfem.BilinearForm(fespace) H = mfem.NonlinearForm(fespace) self.M = M self.H = H self.S = S rho = mfem.ConstantCoefficient(ref_density) M.AddDomainIntegrator(mfem.VectorMassIntegrator(rho)) M.Assemble(skip_zero_entries) M.EliminateEssentialBC(ess_bdr) M.Finalize(skip_zero_entries) M_solver = mfem.CGSolver() M_prec = mfem.DSmoother() M_solver.iterative_mode = False M_solver.SetRelTol(rel_tol) M_solver.SetAbsTol(0.0) M_solver.SetMaxIter(30) M_solver.SetPrintLevel(0) M_solver.SetPreconditioner(M_prec) M_solver.SetOperator(M.SpMat()) self.M_solver = M_solver self.M_prec = M_prec model = mfem.NeoHookeanModel(mu, K) H.AddDomainIntegrator(mfem.HyperelasticNLFIntegrator(model)) H.SetEssentialBC(ess_bdr) self.model = model visc_coeff = mfem.ConstantCoefficient(visc) S.AddDomainIntegrator(mfem.VectorDiffusionIntegrator(visc_coeff)) S.Assemble(skip_zero_entries) S.EliminateEssentialBC(ess_bdr) S.Finalize(skip_zero_entries) self.backward_euler_oper = BackwardEulerOperator(M, S, H) J_prec = mfem.DSmoother(1) J_minres = mfem.MINRESSolver() J_minres.SetRelTol(rel_tol) J_minres.SetAbsTol(0.0) J_minres.SetMaxIter(300) J_minres.SetPrintLevel(-1) J_minres.SetPreconditioner(J_prec) self.J_solver = J_minres self.J_prec = J_prec newton_solver = mfem.NewtonSolver() newton_solver.iterative_mode = False newton_solver.SetSolver(self.J_solver) newton_solver.SetOperator(self.backward_euler_oper) newton_solver.SetPrintLevel(1) #print Newton iterations newton_solver.SetRelTol(rel_tol) newton_solver.SetAbsTol(0.0) newton_solver.SetMaxIter(10) self.newton_solver = newton_solver
def Solve(self, xp): zero = mfem.Vector() self.newton_solver.Mult(zero, xp) if not self.newton_solver.GetConverged(): assert False, "Newton Solver did not converge."
# command-line parameter. for lev in range(ref_levels): mesh.UniformRefinement() # 5. Define the vector finite element space representing the current and the # initial temperature, u_ref. fe_coll = mfem.H1_FECollection(order, dim) fespace = mfem.FiniteElementSpace(mesh, fe_coll) fe_size = fespace.GetTrueVSize() print("Number of temperature unknowns: " + str(fe_size)) u_gf = mfem.GridFunction(fespace) # 6. Set the initial conditions for u. All boundaries are considered # natural. u_0 = InitialTemperature() u_gf.ProjectCoefficient(u_0) u = mfem.Vector() u_gf.GetTrueDofs(u) # 7. Initialize the conduction operator and the visualization. oper = ConductionOperator(fespace, alpha, kappa, u) u_gf.SetFromTrueDofs(u) mesh.PrintToFile('ex16.mesh', 8) u_gf.SaveToFile('ex16-init.gf', 8) if visualization: sout = mfem.socketstream("localhost", 19916) sout.precision(8) sout << "solution\n" << mesh << u_gf sout << "pause\n" sout.flush()
sout.flush() print("GLVis visualization paused.") print(" Press space (in the GLVis window) to resume it.") # Determine the minimum element size. hmin = 0 if (cfl > 0): hmin = min([mesh.GetElementSize(i, 1) for i in range(mesh.GetNE())]) t = 0.0 euler.SetTime(t) ode_solver.Init(euler) if (cfl > 0): # Find a safe dt, using a temporary vector. Calling Mult() computes the # maximum char speed at all quadrature points on all faces. z = mfem.Vector(A.Width()) A.Mult(sol, z) dt = cfl * hmin / ex18_common.max_char_speed / (2 * order + 1) # Integrate in time. done = False ti = 1 while not done: dt_real = min(dt, t_final - t) t, dt_real = ode_solver.Step(sol, t, dt_real) if (cfl > 0): dt = cfl * hmin / ex18_common.max_char_speed / (2 * order + 1) ti = ti + 1 done = (t >= t_final - 1e-8 * dt) if (done or ti % vis_steps == 0): print("time step: " + str(ti) + ", time: " + str(t))
ess_tdof_list = intArray() ess_bdr = intArray([1] + [0] * (mesh.bdr_attributes.Max() - 1)) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # 7. Set up the linear form b(.) which corresponds to the right-hand side of # the FEM linear system. In this case, b_i equals the boundary integral # of f*phi_i where f represents a "pull down" force on the Neumann part # of the boundary and phi_i are the basis functions in the finite element # fespace. The force is defined by the VectorArrayCoefficient object f, # which is a vector of Coefficient objects. The fact that f is non-zero # on boundary attribute 2 is indicated by the use of piece-wise constants # coefficient for its last component. f = mfem.VectorArrayCoefficient(dim) for i in range(dim - 1): f.Set(i, mfem.ConstantCoefficient(0.0)) pull_force = mfem.Vector([0] * mesh.bdr_attributes.Max()) pull_force[1] = -1.0e-2 f.Set(dim - 1, mfem.PWConstCoefficient(pull_force)) b = mfem.LinearForm(fespace) b.AddBoundaryIntegrator(mfem.VectorBoundaryLFIntegrator(f)) print('r.h.s...') b.Assemble() # 8. Define the solution vector x as a finite element grid function # corresponding to fespace. Initialize x with initial guess of zero, # which satisfies the boundary conditions. x = mfem.GridFunction(fespace) x.Assign(0.0) # 9. Set up the bilinear form a(.,.) on the finite element space # corresponding to the linear elasticity integrator with piece-wise # constants coefficient lambda and mu.