Beispiel #1
0
    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
Beispiel #2
0
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()
Beispiel #3
0
    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)
Beispiel #4
0
    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
Beispiel #5
0
#    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.
Beispiel #6
0
#    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