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)
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)
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)
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)
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)
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)
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)
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
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)
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