Example #1
0
def InnerProductComplex(A, B):
    import mfem.par as mfem
    R_A, I_A = A
    R_B, I_B = B
    if I_A is None and I_B is None:
        return mfem.InnerProduct(R_A, R_B)
    elif I_A is None:
        r = mfem.InnerProduct(R_A, R_B)
        i = mfem.InnerProduct(R_A, I_B)
    elif I_B is None:
        r = mfem.InnerProduct(R_A, R_B)
        i = mfem.InnerProduct(I_A, R_B)
    else:
        r = mfem.InnerProduct(R_A, R_B) - mfem.InnerProduct(I_A, I_B)
        i = mfem.InnerProduct(R_A, I_B) + mfem.InnerProduct(I_A, R_B)
    return r + 1j * i
Example #2
0
pcg = mfem.CGSolver(MPI.COMM_WORLD)
pcg.SetOperator(A)
pcg.SetPreconditioner(P)
pcg.SetRelTol(1e-6)
pcg.SetMaxIter(200)
pcg.SetPrintLevel(1)
pcg.Mult(b, x)

LSres = mfem.HypreParVector(test_space)
tmp = mfem.HypreParVector(test_space)

B.Mult(x, LSres)
LSres -= trueF
matSinv.Mult(LSres, tmp)

res = sqrt(mfem.InnerProduct(LSres, tmp))

if (myid == 0):
    print("\n|| B0*x0 + Bhat*xhat - F ||_{S^-1} = " + str(res))

x0.Distribute(x.GetBlock(x0_var))

# 13. Save the refined mesh and the solution in parallel. This output can
#     be viewed later using GLVis: "glvis -np <np> -m mesh -g sol".
smyid = '{:0>6d}'.format(myid)
mesh_name = "mesh." + smyid
sol_name = "sol." + smyid
pmesh.PrintToFile(mesh_name, 8)
x0.SaveToFile(sol_name, 8)

# 14. Send the solution by socket to a GLVis server.
Example #3
0
    def add_extra_contribution(self, engine, **kwargs):
        from mfem.common.chypre import LF2PyVec

        kfes = kwargs.pop('kfes', 0)
        dprint1("Add Extra contribution" + str(self._sel_index))

        self.vt.preprocess_params(self)
        inc_amp, inc_phase, eps, mur = self.vt.make_value_or_expression(self)

        Erz, Ephi = self.get_e_coeff_cls()
        Hrz, Hphi = self.get_h_coeff_cls()
        fes = engine.get_fes(self.get_root_phys(), kfes)
        '''
        if (kfes == 0 and self.mode == 'TE'):
           lf1 = engine.new_lf(fes)
           Ht = Hrz(2, 0.0, self, real = True)
           Ht = self.restrict_coeff(Ht, engine, vec = True)
           intg =  mfem.VectorFEDomainLFIntegrator(Ht)
           #intg = mfem.VectorFEBoundaryTangentLFIntegrator(Ht)
           lf1.AddBoundaryIntegrator(intg)
           lf1.Assemble()
           lf1i = engine.new_lf(fes)
           Ht = Hrz(2, 0.0, self, real = False)
           Ht = self.restrict_coeff(Ht, engine, vec = True)
           intg =  mfem.VectorFEDomainLFIntegrator(Ht)           
           #intg = mfem.VectorFEBoundaryTangentLFIntegrator(Ht)           
           lf1i.AddBoundaryIntegrator(intg)
           lf1i.Assemble()

           from mfem.common.chypre import LF2PyVec
           v1 = LF2PyVec(lf1, lf1i)
           v1 *= -1
           # output formats of InnerProduct
           # are slightly different in parallel and serial
           # in serial numpy returns (1,1) array, while in parallel
           # MFEM returns a number. np.sum takes care of this.
           return (v1, None, None, None, False)
        '''
        if (kfes == 1 and self.mode == 'TE'):

            lf1 = engine.new_lf(fes)
            Ht = Hphi(0.0, self, real=True, eps=eps, mur=mur)
            Ht = self.restrict_coeff(Ht, engine)
            intg = mfem.BoundaryLFIntegrator(Ht)
            lf1.AddBoundaryIntegrator(intg)
            lf1.Assemble()

            lf1i = engine.new_lf(fes)
            Ht = Hphi(0.0, self, real=False, eps=eps, mur=mur)
            Ht = self.restrict_coeff(Ht, engine)
            intg = mfem.BoundaryLFIntegrator(Ht)
            lf1i.AddBoundaryIntegrator(intg)
            lf1i.Assemble()

            from mfem.common.chypre import LF2PyVec, PyVec2PyMat, Array2PyVec, IdentityPyMat

            v1 = LF2PyVec(lf1, lf1i)
            v1 *= -1

            lf2 = engine.new_lf(fes)
            Et = Ephi(self, real=True, eps=eps, mur=mur)
            Et = self.restrict_coeff(Et, engine)
            intg = mfem.DomainLFIntegrator(Et)
            lf2.AddBoundaryIntegrator(intg)
            lf2.Assemble()

            x = engine.new_gf(fes)
            x.Assign(0.0)
            arr = self.get_restriction_array(engine)
            x.ProjectBdrCoefficient(Et, arr)

            weight = mfem.InnerProduct(engine.x2X(x), engine.b2B(lf2))
            v2 = LF2PyVec(lf2, None, horizontal=True)
            v2 *= -1 / weight / 2.0

            #x  = LF2PyVec(x, None)
            # output formats of InnerProduct
            # are slightly different in parallel and serial
            # in serial numpy returns (1,1) array, while in parallel
            # MFEM returns a number. np.sum takes care of this.
            #tmp = np.sum(v2.dot(x))
            #v2 *= -1/tmp/2.

            t4 = np.array([[inc_amp * np.exp(1j * inc_phase / 180. * np.pi)]])

            # convert to a matrix form
            v1 = PyVec2PyMat(v1)
            v2 = PyVec2PyMat(v2.transpose())
            t4 = Array2PyVec(t4)
            t3 = IdentityPyMat(1)

            v2 = v2.transpose()

            #return (None, v2, t3, t4, True)
            return (v1, v2, t3, t4, True)
Example #4
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)
def do_integration(expr, solvars, phys, mesh, kind, attrs,
                   order, num):
    from petram.helper.variables import (Variable,
                                         var_g,
                                         NativeCoefficientGenBase,
                                         CoefficientVariable)
    from petram.phys.coefficient import SCoeff

    st = parser.expr(expr)
    code= st.compile('<string>')
    names = code.co_names

    g = {}
    #print solvars.keys()
    for key in phys._global_ns.keys():
       g[key] = phys._global_ns[key]
    for key in solvars.keys():
       g[key] = solvars[key]

    l = var_g.copy()

    ind_vars = ','.join(phys.get_independent_variables())

    if kind == 'Domain':
        size = max(max(mesh.attributes.ToList()), max(attrs))
    else:
        size = max(max(mesh.bdr_attributes.ToList()), max(attrs))
        
    arr = [0]*(size)
    for k in attrs:
        arr[k-1] = 1
    flag = mfem.intArray(arr)

    s = SCoeff(expr, ind_vars, l, g, return_complex=False)

    ## note L2 does not work for boundary....:D
    if kind == 'Domain':
        fec = mfem.L2_FECollection(order, mesh.Dimension())
    else:
        fec = mfem.H1_FECollection(order, mesh.Dimension())

    fes = mfem.FiniteElementSpace(mesh, fec)
    one = mfem.ConstantCoefficient(1)

    gf = mfem.GridFunction(fes)
    gf.Assign(0.0)

    if kind == 'Domain':
        gf.ProjectCoefficient(mfem.RestrictedCoefficient(s, flag))
    else:
        gf.ProjectBdrCoefficient(mfem.RestrictedCoefficient(s, flag), flag)

    b = mfem.LinearForm(fes)
    one = mfem.ConstantCoefficient(1)
    if kind == 'Domain':
        itg = mfem.DomainLFIntegrator(one)
        b.AddDomainIntegrator(itg)
    else:
        itg = mfem.BoundaryLFIntegrator(one)
        b.AddBoundaryIntegrator(itg)

    b.Assemble()

    from petram.engine import SerialEngine
    en = SerialEngine()
    ans = mfem.InnerProduct(en.x2X(gf), en.b2B(b))
    
    if not np.isfinite(ans):
        print("not finite", ans, arr)
        print(size, mesh.bdr_attributes.ToList())
        from mfem.common.chypre import LF2PyVec, PyVec2PyMat, Array2PyVec, IdentityPyMat
        #print(list(gf.GetDataArray()))
        print(len(gf.GetDataArray()), np.sum(gf.GetDataArray()))
        print(np.sum(list(b.GetDataArray())))
    return ans