Ejemplo n.º 1
0
    def add_extra_contribution(self, engine, **kwargs):
        dprint1("Add Extra contribution" + str(self._sel_index))
        fes = engine.get_fes(self.get_root_phys(), 0)

        x, y, s = self.vt.make_value_or_expression(self)

        from mfem.common.chypre import LF2PyVec, EmptySquarePyMat, HStackPyVec
        from mfem.common.chypre import Array2PyVec
        vecs = []
        for x0, y0, s0 in zip(x, y, s):
            lf1 = engine.new_lf(fes)
            d = mfem.DeltaCoefficient(x0, y0, 1.0)
            itg = mfem.DomainLFIntegrator(d)
            lf1.AddDomainIntegrator(itg)
            lf1.Assemble()
            vecs.append(LF2PyVec(lf1))

        t3 = EmptySquarePyMat(len(x))
        v1 = HStackPyVec(vecs)
        v2 = v1
        t4 = Array2PyVec(np.array(s))
        return (v1, v2, t3, t4, True)
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
    def run_postprocess(self, engine):
        dprint1("running postprocess: " + self.name())

        name = self.variables.strip()
        if name not in engine.model._variables:
            assert False, name + " is not defined"

        var1 = engine.model._variables[name]
        emesh_idx1 = var1.get_emesh_idx()
        emesh_idx = emesh_idx1[0]

        fes1 = engine.fespaces[name]
        info1 = engine.get_fes_info(fes1)
        if info1 is None:
            assert False, "fes info is not found"

        if info1['sdim'] == self.sdim:
            isDomain = True
        elif info1['sdim'] == self.sdim + 1:
            isDomain = False
        else:
            warnings.warn("Can not perform integration (skipping)",
                          RuntimeWarning)
            return

        isComplex = var1.complex
        new_lf = engine.new_lf

        cdim = 1
        if (info1['element'].startswith('ND')
                or info1['element'].startswith('RT')):
            cdim = info1['sdim']
        else:
            cdim = info1['vdim']

        from petram.helper.phys_module_util import default_lf_integrator
        if self.integrator == 'Auto':
            integrator = default_lf_integrator(info1, isDomain)
        else:
            integrator = self.integrator

        lfr = new_lf(fes1)
        self.add_integrator(lfr, engine, integrator, cdim, emesh_idx, isDomain,
                            True)
        lfr.Assemble()

        if isComplex:
            lfi = new_lf(fes1)
            self.add_integrator(lfi, engine, integrator, cdim, emesh_idx,
                                isDomain, False)
            lfi.Assemble()
        else:
            lfi = None

        from mfem.common.chypre import LF2PyVec
        V = LF2PyVec(lfr, lfi, horizontal=True)

        V1 = engine.variable2vector(var1)
        #print(V1.shape)
        #print(V.shape)
        value = np.array(V.dot(V1), copy=False)
        #value = np.array(V1.dot(V2), copy=False)
        dprint1("Integrated Value :" + self.integration_name + ":" +
                str(value))
        engine.store_pp_extra(self.integration_name, value, save_once=True)
Ejemplo n.º 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
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
    def add_extra_contribution(self, engine, **kwargs):

        from mfem.common.chypre import LF2PyVec

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

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

        fes = engine.get_fes(self.get_root_phys(), kfes)
        d = "y" if kfes == 1 else "z"
        inc_amp0 = (1, 0) if kfes == 1 else (0, 1)
        lf1 = engine.new_lf(fes)
        Ht = jwH_port(self,
                      real=True,
                      amp=inc_amp0,
                      eps=eps,
                      mur=mur,
                      ky=ky,
                      kz=kz,
                      direction=d,
                      normalize=True)
        Ht = self.restrict_coeff(Ht, engine)
        intg = mfem.BoundaryLFIntegrator(Ht)
        lf1.AddBoundaryIntegrator(intg)
        lf1.Assemble()

        lf1i = engine.new_lf(fes)
        Ht = jwH_port(self,
                      real=False,
                      amp=inc_amp0,
                      eps=eps,
                      mur=mur,
                      ky=ky,
                      kz=kz,
                      direction=d,
                      normalize=True)
        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 = E_port(self,
                    real=True,
                    amp=inc_amp0,
                    eps=eps,
                    mur=mur,
                    ky=ky,
                    kz=kz,
                    direction=d,
                    normalize=True)

        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)

        v2 = LF2PyVec(lf2, None, horizontal=True)
        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

        t4 = np.array(
            [[inc_amp[kfes - 1] * 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)