def assemble(self, *args, **kwargs): engine = self._engine() direction = kwargs.pop("direction", 0) self.process_kwargs(engine, kwargs) x = args[0] y = args[1] if len(args)>1 else 0 z = args[2] if len(args)>2 else 0 sdim = self.fes1.GetMesh().SpaceDimension() if direction == 0: if sdim == 3: d = mfem.DeltaCoefficient(x, y, z, 1) elif sdim == 2: d = mfem.DeltaCoefficient(x, y, 1) elif sdim == 1: d = mfem.DeltaCoefficient(x, 1) else: assert False, "unsupported dimension" intg = mfem.DomainLFIntegrator(d) else: dir = mfem.Vector(direction) if sdim == 3: d = mfem.VectorDeltaCoefficient(dir, x, y, z, 1) elif sdim == 2: d = mfem.VectorDeltaCoefficient(dir, x, y, 1) elif sdim == 1: d = mfem.VectorDeltaCoefficient(dir,x, 1) else: assert False, "unsupported dimension" if self.fes1.FEColl().Name().startswith('ND'): intg = mfem.VectorFEDomainLFIntegrator(d) elif self.fes1.FEColl().Name().startswith('RT'): intg = mfem.VectorFEDomainLFIntegrator(d) else: intg = mfem.VectorDomainLFIntegrator(d) lf1 = engine.new_lf(self.fes1) lf1.AddDomainIntegrator(intg) lf1.Assemble() from mfem.common.chypre import LF2PyVec, PyVec2PyMat, MfemVec2PyVec v1 = MfemVec2PyVec(engine.b2B(lf1), None) v1 = PyVec2PyMat(v1) if not self._transpose: v1 = v1.transpose() return v1
fcoeff = fFunc(dim) fnatcoeff = f_natural() gcoeff = gFunc() ucoeff = uFunc_ex(dim) pcoeff = pFunc_ex() x = mfem.BlockVector(block_offsets) rhs = mfem.BlockVector(block_offsets) trueX = mfem.BlockVector(block_trueOffsets) trueRhs = mfem.BlockVector(block_trueOffsets) fform = mfem.ParLinearForm() fform.Update(R_space, rhs.GetBlock(0), 0) fform.AddDomainIntegrator(mfem.VectorFEDomainLFIntegrator(fcoeff)) fform.AddBoundaryIntegrator(mfem.VectorFEBoundaryFluxLFIntegrator(fnatcoeff)) fform.Assemble() fform.ParallelAssemble(trueRhs.GetBlock(0)) gform = mfem.ParLinearForm() gform.Update(W_space, rhs.GetBlock(1), 0) gform.AddDomainIntegrator(mfem.DomainLFIntegrator(gcoeff)) gform.Assemble() gform.ParallelAssemble(trueRhs.GetBlock(1)) mVarf = mfem.ParBilinearForm(R_space) bVarf = mfem.ParMixedBilinearForm(R_space, W_space) mVarf.AddDomainIntegrator(mfem.VectorFEMassIntegrator(k)) mVarf.Assemble()
def add_extra_contribution(self, engine, **kwargs): dprint1("Add Extra contribution" + str(self._sel_index)) from mfem.common.chypre import LF2PyVec, PyVec2PyMat, Array2PyVec, IdentityPyMat self.vt.preprocess_params(self) inc_amp, inc_phase, eps, mur = self.vt.make_value_or_expression(self) C_Et, C_jwHt = self.get_coeff_cls() fes = engine.get_fes(self.get_root_phys(), 0) lf1 = engine.new_lf(fes) Ht1 = C_jwHt(3, 0.0, self, real=True, eps=eps, mur=mur) Ht2 = self.restrict_coeff(Ht1, engine, vec=True) intg = mfem.VectorFEBoundaryTangentLFIntegrator(Ht2) lf1.AddBoundaryIntegrator(intg) lf1.Assemble() lf1i = engine.new_lf(fes) Ht3 = C_jwHt(3, 0.0, self, real=False, eps=eps, mur=mur) Ht4 = self.restrict_coeff(Ht3, engine, vec=True) intg = mfem.VectorFEBoundaryTangentLFIntegrator(Ht4) lf1i.AddBoundaryIntegrator(intg) lf1i.Assemble() lf2 = engine.new_lf(fes) Et = C_Et(3, self, real=True, eps=eps, mur=mur) Et = self.restrict_coeff(Et, engine, vec=True) intg = mfem.VectorFEDomainLFIntegrator(Et) lf2.AddBoundaryIntegrator(intg) lf2.Assemble() x = engine.new_gf(fes) x.Assign(0.0) arr = self.get_restriction_array(engine) x.ProjectBdrCoefficientTangent(Et, arr) t4 = np.array( [[np.sqrt(inc_amp) * np.exp(1j * inc_phase / 180. * np.pi)]]) weight = mfem.InnerProduct(engine.x2X(x), engine.b2B(lf2)) # # # v1 = LF2PyVec(lf1, lf1i) v1 *= -1 v2 = LF2PyVec(lf2, None, horizontal=True) #x = LF2PyVec(x, None) # # transfer x and lf2 to True DoF space to operate InnerProduct # # here lf2 and x is assume to be real value. # v2 *= 1. / weight v1 = PyVec2PyMat(v1) v2 = PyVec2PyMat(v2.transpose()) t4 = Array2PyVec(t4) t3 = IdentityPyMat(1) v2 = v2.transpose() ''' Format of extar (t2 is returnd as vertical(transposed) matrix) [M, t1] [ ] [ ] = [ ] [t2, t3] [t4] and it returns if Lagurangian will be saved. ''' return (v1, v2, t3, t4, True)
def assemble(self, *args, **kwargs): engine = self._engine() direction = kwargs.pop("direction", None) weight = kwargs.pop("weight", 1.0) weight = np.atleast_1d(weight) do_sum = kwargs.pop("sum", False) info1 = engine.get_fes_info(self.fes1) sdim = info1['sdim'] vdim = info1['vdim'] if (info1['element'].startswith('ND') or info1['element'].startswith('RT')): vdim = sdim if vdim > 1: if direction is None: direction = [0]*vdim direction[0] = 1 direction = np.atleast_1d(direction).astype(float, copy=False) direction = direction.reshape(-1, sdim) self.process_kwargs(engine, kwargs) pts = np.array(args[0], copy = False).reshape(-1, sdim) from mfem.common.chypre import LF2PyVec, PyVec2PyMat, MfemVec2PyVec, HStackPyVec vecs = [] for k, pt in enumerate(pts): w = float(weight[0] if len(weight) == 1 else weight[k]) if vdim == 1: if sdim == 3: x, y, z = pt d = mfem.DeltaCoefficient(x, y, z, w) elif sdim == 2: x, y = pt print("DeltaCoefficient call", type(x), type(y), type(x)) d = mfem.DeltaCoefficient(x, y, w) elif sdim == 1: x = pt d = mfem.DeltaCoefficient(x, w) else: assert False, "unsupported dimension" intg = mfem.DomainLFIntegrator(d) else: dir = direction[0] if len(direction) == 1 else direction[k] dd = mfem.Vector(dir) if sdim == 3: x, y, z = pt d = mfem.VectorDeltaCoefficient(dd, x, y, z, w) elif sdim == 2: x, y = pt d = mfem.VectorDeltaCoefficient(dd, x, y, w) elif sdim == 1: x = pt d = mfem.VectorDeltaCoefficient(dd,x, w) else: assert False, "unsupported dimension" if self.fes1.FEColl().Name().startswith('ND'): intg = mfem.VectorFEDomainLFIntegrator(d) elif self.fes1.FEColl().Name().startswith('RT'): intg = mfem.VectorFEDomainLFIntegrator(d) else: intg = mfem.VectorDomainLFIntegrator(d) if do_sum: if k == 0: lf1 = engine.new_lf(self.fes1) lf1.AddDomainIntegrator(intg) else: lf1 = engine.new_lf(self.fes1) lf1.AddDomainIntegrator(intg) lf1.Assemble() vecs.append(LF2PyVec(lf1)) if do_sum: lf1.Assemble() v1 = MfemVec2PyVec(engine.b2B(lf1), None) v1 = PyVec2PyMat(v1) else: v1 = HStackPyVec(vecs) if not self._transpose: v1 = v1.transpose() return v1
# 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 pmesh.bdr_attributes.Size(): ess_bdr = mfem.intArray(pmesh.bdr_attributes.Max()) if set_bc: ess_bdr.Assign(1) else: ess_bdr.Assign(0) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # 8. Set up the parallel linear form b(.) which corresponds to the # right-hand side of the FEM linear system, which in this case is # (f,phi_i) where f is given by the function f_exact and phi_i are the # basis functions in the finite element fespace. f = f_exact(sdim) b = mfem.ParLinearForm(fespace) b.AddDomainIntegrator(mfem.VectorFEDomainLFIntegrator(f)) b.Assemble() # 9. Define the solution vector x as a parallel finite element grid function # corresponding to fespace. Initialize x by projecting the exact # solution. Note that only values from the boundary faces will be used # when eliminating the non-homogeneous boundary condition to modify the # r.h.s. vector b. x = mfem.ParGridFunction(fespace) F = E_exact(sdim) x.ProjectCoefficient(F) # 10. Set up the parallel bilinear form corresponding to the H(div) # diffusion operator grad alpha div + beta I, by adding the div-div and # the mass domain integrators.
# converting them to a list of true dofs. ess_tdof_list = intArray() if mesh.bdr_attributes.Size(): ess_bdr = intArray(mesh.bdr_attributes.Max()) ess_bdr.Assign(1) fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list) # 8. Set up the linear form b(.) which corresponds to the right-hand side # of the FEM linear system, which in this case is (f,phi_i) where f is # given by the function f_exact and phi_i are the basis functions in the # finite element fespace. b = mfem.ParLinearForm(fespace) f = f_exact() dd = mfem.VectorFEDomainLFIntegrator(f) b.AddDomainIntegrator(dd) b.Assemble() # 9. Define the solution vector x as a finite element grid function # corresponding to fespace. Initialize x by projecting the exact # solution. Note that only values from the boundary edges will be used # when eliminating the non-homogeneous boundary condition to modify the # r.h.s. vector b. x = mfem.ParGridFunction(fespace) E = E_exact() x.ProjectCoefficient(E) # 10. Set up the bilinear form corresponding to the EM diffusion operator # curl muinv curl + sigma I, by adding the curl-curl and the mass domain