Beispiel #1
0
    def __init__(self, z, ind_vars, l, g, omega, real):
        self.z = [
            SCoeff([ems[0]], ind_vars, l, g, real=True),
            SCoeff([ems[0]], ind_vars, l, g, real=False)
        ]

        self.omega = omega
        self.real = real
        mfem.PyCoefficient.__init__(self)
Beispiel #2
0
    def get_init_coeff(self, engine, real=True, kfes=0):
        names = self.get_root_phys().dep_vars_base

        if not getattr(self, 'use_' + names[kfes] + '_init'): return

        f_name = self.vt3.make_value_or_expression(self)

        el = self.get_root_phys().element
        if el.startswith('H1') or el.startswith('L2'):
            ll = self.get_root_phys().vdim
        else:
            ll = self.get_root_phys().ndim

        kwargs = {}

        from petram.phys.coefficient import SCoeff, VCoeff
        if ll == 1:
            coeff = SCoeff(f_name[0],
                           self.get_root_phys().ind_vars,
                           self._local_ns,
                           self._global_ns,
                           real=real)

        else:
            coeff = VCoeff(ll,
                           f_name,
                           self.get_root_phys().ind_vars,
                           self._local_ns,
                           self._global_ns,
                           real=real)
            kwargs['vec'] = True

        return self.restrict_coeff(coeff, engine, **kwargs)
Beispiel #3
0
    def apply_essential(self, engine, gf, real=False, kfes=0):
        if kfes > 0:
            return
        c0 = self.vt.make_value_or_expression(self)[0]

        if real:
            dprint1("Apply Ess.(real)" + str(self._sel_index), 'c0', c0)
        else:
            dprint1("Apply Ess.(imag)" + str(self._sel_index), 'c0', c0)

        name = self.get_root_phys().dep_vars[0]
        fes = engine.get_fes(self.get_root_phys(), name=name)

        fec_name = fes.FEColl().Name()

        mesh = engine.get_emesh(mm=self)
        ibdr = mesh.bdr_attributes.ToList()

        bdr_attr = [0] * mesh.bdr_attributes.Max()
        for idx in self._sel_index:
            bdr_attr[idx - 1] = 1

        ess_vdofs = mfem.intArray()
        fes.GetEssentialVDofs(mfem.intArray(bdr_attr), ess_vdofs, 0)
        vdofs = np.where(np.array(ess_vdofs.ToList()) == -1)[0]
        dofs = mfem.intArray([fes.VDofToDof(i) for i in vdofs])
        fes.BuildDofToArrays()

        coeff1 = SCoeff(c0,
                        self.get_root_phys().ind_vars,
                        self._local_ns,
                        self._global_ns,
                        real=real)
        gf.ProjectCoefficient(coeff1, dofs, 0)
Beispiel #4
0
    def add_bf_contribution(self, engine, b, real=True, kfes=0):
        if kfes != 0: return
        if real:
            dprint1("Add BF contribution(real)" + str(self._sel_index))
        else:
            dprint1("Add BF contribution(imag)" + str(self._sel_index))

        freq, omega = self.get_root_phys().get_freq_omega()
        mode, parameters = self.vt.make_value_or_expression(self)[0]

        ind_vars = self.get_root_phys().ind_vars
        l = self._local_ns
        g = self._global_ns

        if mode == 'e/m/s':
            er, mr, s = parameters
            try:
                z = np.sqrt(
                    (1j * omega * mu0 * mr) / (s + 1j * omega * er * epsilon0))
                gamma = -1j * omega / z
                coeff = SCoeff([gamma], ind_vars, l, g, real=real)
                #assert False, "cause error"
            except:
                #import traceback
                #traceback.print_exc()
                coeff = ImpedanceByEMS(parameters, ind_vars, l, g, omega, real)

        else:
            z = parameters[0]
            try:
                gamma = -1j * omega / z
                coeff = SCoeff([gamma], ind_vars, l, g, real=real)
                #assert False, "cause error"
            except:
                #import traceback
                #traceback.print_exc()
                coeff = ImpedanceByZ(parameters, ind_vars, l, g, omega, real)

        self.add_integrator(engine, 'impedance', coeff,
                            b.AddBoundaryIntegrator,
                            mfem.VectorFEMassIntegrator)
        '''
    def apply_essential_1(self, method, real, c0, vdim, vvdim, bdr_attr):
        if vdim == 1:
            coeff1 = SCoeff(c0,
                            self.get_root_phys().ind_vars,
                            self._local_ns,
                            self._global_ns,
                            real=real)
        else:
            coeff1 = VCoeff(vdim,
                            c0,
                            self.get_root_phys().ind_vars,
                            self._local_ns,
                            self._global_ns,
                            real=real)

        assert not (vvdim != -1
                    and vdim > 1), "Wrong setting...(vvdim != -1 and vdim > 1)"
        #print vvdim, vdim, method, coeff1
        if vvdim == -1:
            method(coeff1, mfem.intArray(bdr_attr))
        else:
            for cp in vvdim:
                method(coeff1, mfem.intArray(bdr_attr), cp)
Beispiel #6
0
def Mu_Coeff(exprs, ind_vars, l, g, omega):
    # v = mu * v
    fac = mu0
    return SCoeff(exprs, ind_vars, l, g, return_complex=True, scale=fac)
Beispiel #7
0
def Sigma_Coeff(exprs, ind_vars, l, g, omega):
    # v = - 1j * self.omega * v
    fac = -1j * omega
    return SCoeff(exprs, ind_vars, l, g, return_complex=True, scale=fac)
Beispiel #8
0
def Epsilon_Coeff(exprs, ind_vars, l, g, omega):
    # - omega^2 * epsilon0 * epsilonr
    fac = -epsilon0 * omega * omega
    return SCoeff(exprs, ind_vars, l, g, return_complex=True, scale=fac)
Beispiel #9
0
    def get_coefficient_from_expression(self,
                                        c,
                                        cotype,
                                        use_dual=False,
                                        real=True,
                                        is_conj=False):
        from petram.phys.coefficient import SCoeff, VCoeff, DCoeff, MCoeff

        if self.get_root_phys().vdim > 1:
            dim = self.get_root_phys().vdim
        else:
            dim = self.get_root_phys().geom_dim

        if cotype == 'S':
            # for b in self.itg_choice():
            #   if b[0] == self.integrator: break
            # if not "S*2" in b[3]:
            if not use_dual:
                c_coeff = SCoeff(c,
                                 self.get_root_phys().ind_vars,
                                 self._local_ns,
                                 self._global_ns,
                                 real=real,
                                 conj=is_conj)
            else:  # so far this is only for an elastic integrator
                c_coeff = (SCoeff(c,
                                  self.get_root_phys().ind_vars,
                                  self._local_ns,
                                  self._global_ns,
                                  real=real,
                                  conj=is_conj,
                                  component=0),
                           SCoeff(c,
                                  self.get_root_phys().ind_vars,
                                  self._local_ns,
                                  self._global_ns,
                                  real=real,
                                  conj=is_conj,
                                  component=1))
        elif cotype == 'V':
            c_coeff = VCoeff(dim,
                             c,
                             self.get_root_phys().ind_vars,
                             self._local_ns,
                             self._global_ns,
                             real=real,
                             conj=is_conj)
        elif cotype == 'M':
            c_coeff = MCoeff(dim,
                             c,
                             self.get_root_phys().ind_vars,
                             self._local_ns,
                             self._global_ns,
                             real=real,
                             conj=is_conj)
        elif cotype == 'D':
            c_coeff = DCoeff(dim,
                             c,
                             self.get_root_phys().ind_vars,
                             self._local_ns,
                             self._global_ns,
                             real=real,
                             conj=is_conj)
        return c_coeff
Beispiel #10
0
    def add_contribution(self,
                         engine,
                         a,
                         real=True,
                         is_trans=False,
                         is_conj=False):
        c = self.vt_coeff.make_value_or_expression(self)[0]

        if real:
            dprint1(
                "Add " + self.integrator + " contribution(real)" +
                str(self._sel_index), "c", c)
        else:
            dprint1(
                "Add " + self.integrator + " contribution(imag)" +
                str(self._sel_index), "c", c)

        cotype = self.coeff_type[0]

        if self.get_root_phys().vdim > 1:
            dim = self.get_root_phys().vdim
        else:
            el_name = self.get_root_phys().element
            dim = self.get_root_phys().geom_dim
            '''
            if el_name.startswith("ND"):
                dim = self.get_root_phys().geom_dim            
            elif el_name.startswith("RT"):
                dim = self.get_root_phys().geom_dim
            else:
                dim = 1  #H1 scalar (this case does not exist..)
            '''
        if cotype == 'S':
            for b in self.itg_choice():
                if b[0] == self.integrator: break
            if not "S*2" in b[3]:
                c_coeff = SCoeff(c,
                                 self.get_root_phys().ind_vars,
                                 self._local_ns,
                                 self._global_ns,
                                 real=real,
                                 conj=is_conj)
            else:  # so far this is only for an elastic integrator
                c_coeff = (SCoeff(c,
                                  self.get_root_phys().ind_vars,
                                  self._local_ns,
                                  self._global_ns,
                                  real=real,
                                  conj=is_conj,
                                  component=0),
                           SCoeff(c,
                                  self.get_root_phys().ind_vars,
                                  self._local_ns,
                                  self._global_ns,
                                  real=real,
                                  conj=is_conj,
                                  component=1))
        elif cotype == 'V':
            c_coeff = VCoeff(dim,
                             c,
                             self.get_root_phys().ind_vars,
                             self._local_ns,
                             self._global_ns,
                             real=real,
                             conj=is_conj)
        elif cotype == 'M':
            c_coeff = MCoeff(dim,
                             c,
                             self.get_root_phys().ind_vars,
                             self._local_ns,
                             self._global_ns,
                             real=real,
                             conj=is_conj)
        elif cotype == 'D':
            c_coeff = DCoeff(dim,
                             c,
                             self.get_root_phys().ind_vars,
                             self._local_ns,
                             self._global_ns,
                             real=real,
                             conj=is_conj)

        integrator = getattr(mfem, self.integrator)
        if isinstance(self, Bdry):
            #print "Bdry Integrator"
            adder = a.AddBoundaryIntegrator
        elif isinstance(self, Domain):
            #print "Domain Integrator"
            adder = a.AddDomainIntegrator
        else:
            assert False, "this class is not supported in weakform"
        self.add_integrator(engine,
                            'c',
                            c_coeff,
                            adder,
                            integrator,
                            transpose=is_trans)
Beispiel #11
0
    def apply_essential(self, engine, gf, real=False, kfes=0):
        if kfes > 0: return
        c0, vdim0 = self.vt.make_value_or_expression(self)

        if real:
            dprint1("Apply Ess.(real)" + str(self._sel_index), 'c0, v0', c0,
                    vdim0)
        else:
            dprint1("Apply Ess.(imag)" + str(self._sel_index), 'c0, v0', c0,
                    vdim0)

        name = self.get_root_phys().dep_vars[0]
        fes = engine.get_fes(self.get_root_phys(), name=name)

        vdim = fes.GetVDim()
        vvdim = -1

        if vdim0 != 'all':
            lvdim = len(self.esse_vdim.split(","))
            #assert lvdim == 1, "Specify only one vdim"
            vvdim = [int(x) for x in self.esse_vdim.split(",")]
        else:
            vvdim = -1

        fec_name = fes.FEColl().Name()

        mesh = engine.get_emesh(mm=self)
        ibdr = mesh.bdr_attributes.ToList()

        bdr_attr = [0] * mesh.bdr_attributes.Max()
        for idx in self._sel_index:
            bdr_attr[idx - 1] = 1

        if fec_name.startswith("ND"):
            assert vdim == 1, "ND element vdim must be one"
            vdim = mesh.Dimension()
            method = gf.ProjectBdrCoefficientTangent
            self.apply_essential_1(method, real, c0, vdim, vvdim, bdr_attr)

        elif fec_name.startswith("RT"):
            assert vdim == 1, "RT element vdim must be one"
            vdim = mesh.Dimension()
            method = gf.ProjectBdrCoefficientNormal
            self.apply_essential_1(method, real, c0, vdim, vvdim, bdr_attr)

        #elif self.get_root_phys().vdim == 1:
        #    ProjectBdrCoefficient does not realy work in parallel
        #    since shadow vertex are not always set...
        #    method = gf.ProjectBdrCoefficient
        #    self.apply_essential_1(method, real, c0, vdim, vvdim, bdr_attr)

        else:  #H1 or L2
            # vector field FE.
            method = gf.ProjectCoefficient
            ess_vdofs = mfem.intArray()
            fes.GetEssentialVDofs(mfem.intArray(bdr_attr), ess_vdofs, 0)
            vdofs = np.where(np.array(ess_vdofs.ToList()) == -1)[0]
            dofs = mfem.intArray([fes.VDofToDof(i) for i in vdofs])
            fes.BuildDofToArrays()

            if self.get_root_phys().vdim == 1:
                coeff1 = SCoeff(c0,
                                self.get_root_phys().ind_vars,
                                self._local_ns,
                                self._global_ns,
                                real=real)
                gf.ProjectCoefficient(coeff1, dofs, 0)

            elif vdim0 == 'all':
                coeff1 = VCoeff(vdim,
                                c0,
                                self.get_root_phys().ind_vars,
                                self._local_ns,
                                self._global_ns,
                                real=real)
                gf.ProjectCoefficient(coeff1, dofs)
            else:
                for k, cp in enumerate(vvdim):
                    coeff1 = SCoeff(c0,
                                    self.get_root_phys().ind_vars,
                                    self._local_ns,
                                    self._global_ns,
                                    real=real,
                                    component=k)
                    gf.ProjectCoefficient(coeff1, dofs, cp)
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