def vt(self): root_phys = self.get_root_phys() if not isinstance(root_phys, PhysModule): data = (('esse_value', VtableElement(None, type="array", guilabel="dummy", default="0.0", tip="dummy")), ) return Vtable(data) dep_vars = self.get_root_phys().dep_vars if not hasattr(self, '_dep_var_bk'): self._dep_var_bk = "" if self._dep_var_bk != dep_vars: dep_var = dep_vars[0] data = (('esse_value', VtableElement("esse_value", type="array", guilabel=dep_var, default="0.0", tip="Reference for disance measurement")), ) vt = Vtable(data) self._vt1 = vt self._dep_var_bk = dep_vars self.update_attribute_set() else: vt = self._vt1 return vt
class WF_common(object): can_timedpendent = True @property def vt3(self): names = self.get_root_phys().dep_vars_base names2 = [n + '_init' for n in names] data = [] if hasattr(self, '_vt3'): vt3 = self._vt3 if vt3.keys() == names2: return vt3 data = [(n + '_init', VtableElement(n + '_init', type='array', guilabel=n + '(init)', default="0.0", tip="initial value", chkbox=True)) for n in names] self._vt3 = Vtable(data) v = {} self._vt3.attribute_set(v) self.do_update_attribute_set(v) return self._vt3 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)
class EM3D_H(EM3D_Bdry): is_essential = False vt = Vtable(data) def has_lf_contribution(self, kfes=0): if kfes != 0: return False return True def add_lf_contribution(self, engine, b, real=True, kfes=0): if kfes != 0: return if real: dprint1("Add LF contribution(real)" + str(self._sel_index)) else: dprint1("Add LF contribution(imag)" + str(self._sel_index)) from .em3d_const import mu0, epsilon0 freq, omega = self.get_root_phys().get_freq_omega() h = self.vt.make_value_or_expression(self) coeff1 = Ht(3, h[0], self.get_root_phys().ind_vars, self._local_ns, self._global_ns, real=real, omega=omega) self.add_integrator(engine, 'H', coeff1, b.AddBoundaryIntegrator, mfem.VectorFEBoundaryTangentLFIntegrator) '''
class DoFProjection(Pair, Phys): vt = Vtable(data) def __init__(self, **kwargs): super(DoFProjection, self).__init__(**kwargs) Phys.__init__(self) def attribute_set(self, v): v = super(DoFProjection, self).attribute_set(v) v['prj_fes_idx'] = 0 return v def panel1_param(self): import wx names = self.get_root_phys().dep_vars ll = [["FESpace", "S", 4, {"style": wx.CB_READONLY, "choices": names}]] param = self.vt.panel_param(self) ll.extend(param) return ll def import_panel1_value(self, v): idx = self.get_root_phys().dep_vars.index(v[0]) self.prj_fes_idx = idx return self.vt.import_panel_value(self, v[1:]) def get_panel1_value(self): val = [self.get_root_phys().dep_vars[self.prj_fes_idx]] val.extend(self.vt.get_panel_value(self)) return val def panel1_tip(self): pass def assemble_matrix(self): raise NotImplementedError("subclass must implement this")
class EM1D_PEC(EM1D_Bdry): has_essential = True nlterms = [] vt = Vtable(data) def get_essential_idx(self, kfes): if kfes == 1: return self._sel_index elif kfes == 2: return self._sel_index else: return [] def apply_essential(self, engine, gf, real = False, kfes = 0): if kfes == 0: return if real: dprint1("Apply Ess.(real)" + str(self._sel_index)) else: dprint1("Apply Ess.(imag)" + str(self._sel_index)) Erphiz = self.vt.make_value_or_expression(self) mesh = engine.get_mesh(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 coeff = PhysConstant(0.0) gf.ProjectBdrCoefficient(coeff, mfem.intArray(bdr_attr))
class EM3D_ExtJ(EM3D_Domain): is_secondary_condition = True has_3rd_panel = False vt = Vtable(data) def has_lf_contribution(self, kfes = 0): if kfes != 0: return False return True def add_lf_contribution(self, engine, b, real = True, kfes = 0): if kfes != 0: return if real: dprint1("Add LF contribution(real)" + str(self._sel_index)) else: dprint1("Add LF contribution(imag)" + str(self._sel_index)) freq, omega = self.get_root_phys().get_freq_omega() f_name = self.vt.make_value_or_expression(self) coeff1 = Jext(3, f_name[0], self.get_root_phys().ind_vars, self._local_ns, self._global_ns, real = real, omega = omega) self.add_integrator(engine, 'jext', coeff1, b.AddDomainIntegrator, mfem.VectorFEDomainLFIntegrator) '''
class RevolveMesh(GmshMeshActionBase): vt = Vtable(edata) def add_meshcommand(self, mesher): gid, dst_id, src_id, nlayers, hint = self.vt.make_value_or_expression( self) gid, dst_id, src_id = self.eval_enitity_id(gid, dst_id, src_id) kwargs = process_hint_rv(hint) mesher.add('revolve_face', gid, src_id, dst_id, nlayers=nlayers, **kwargs) def get_element_selection(self): self.vt.preprocess_params(self) ret, mode = self.element_selection_empty() try: dest = [int(x) for x in self.dst_id.split(',')] src = [int(x) for x in self.src_id.split(',')] ret['face'] = dest + src except: pass return ret, 'face'
class EM2D_Bdry(Bdry, Phys): has_3rd_panel = True vt3 = Vtable(data) def __init__(self, **kwargs): super(EM2D_Bdry, self).__init__(**kwargs) Phys.__init__(self) def attribute_set(self, v): super(EM2D_Bdry, self).attribute_set(v) v['sel_readonly'] = False v['sel_index'] = [] return v def get_init_coeff(self, engine, real=True, kfes=0): if kfes > 2: return if not self.use_Einit: return f_name = self.vt3.make_value_or_expression(self) if kfes == 0: coeff = Einit_xy(2, f_name[0], self.get_root_phys().ind_vars, self._local_ns, self._global_ns, real=real) return self.restrict_coeff(coeff, engine, vec=True) else: coeff = Einit_z(f_name[0], self.get_root_phys().ind_vars, self._local_ns, self._global_ns, real=real) return self.restrict_coeff(coeff, engine)
def vt_array(self): if not hasattr(self, 'aux_connection'): self._vt_array = [] return self._vt_array if not hasattr(self, '_vt_array'): self._vt_array = [] for key in self.aux_connection: if len(self._vt_array) > key: continue sidx = str(key) data = [ ("oprt1_" + sidx, VtableElement( "oprt1_" + sidx, type='any', guilabel="operator1", default="", tip="oprator (horizontal)", )), ("oprt2_" + sidx, VtableElement( "oprt2_" + sidx, type='any', guilabel="operator2", default="", tip="oprator (vertical)", )), ] vt = Vtable(data) self._vt_array.append(vt) return self._vt_array
class CopyFace(GmshMeshActionBase): vt = Vtable(data) def add_meshcommand(self, mesher): gid, src_id, hint, cp_cl = self.vt.make_value_or_expression(self) gid = self.eval_enitity_id(gid) kwargs = process_hint_ex(hint) kwargs['copy_cl'] = cp_cl print( 'adding here', src_id, gid, ) mesher.add('copyface', src_id, gid, **kwargs) def get_element_selection(self): self.vt.preprocess_params(self) ret, mode = self.element_selection_empty() try: dest = [int(x) for x in self.geom_id.split(',')] src = [int(x) for x in self.src_id.split(',')] ret['face'] = dest + src except: pass return ret, 'face'
class EM3D_SurfJ(EM3D_Bdry): is_essential = False vt = Vtable(data) def has_lf_contribution(self, kfes=0): if kfes != 0: return False return True def add_lf_contribution(self, engine, b, real=True, kfes=0): if kfes != 0: return if real: dprint1("Add LF contribution(real)" + str(self._sel_index)) else: dprint1("Add LF contribution(imag)" + str(self._sel_index)) freq, omega = self.get_root_phys().get_freq_omega() f_name = self.vt.make_value_or_expression(self) coeff1 = Jsurf( 3, f_name[0], self.get_root_phys().ind_vars, self._local_ns, self._global_ns, real=real, omega=omega, ) self.add_integrator(engine, 'surfJ', coeff1, b.AddBoundaryIntegrator, mfem.VectorFEDomainLFIntegrator) '''
class FreeFace(GmshMeshActionBase): vt = Vtable(data) def add_meshcommand(self, mesher): gid, clmax, clmin, res, embed_l, embed_p = self.vt.make_value_or_expression( self) gid, embed_l, embed_p = self.eval_enitity_id(gid, embed_l, embed_p) mesher.add('freeface', gid, maxsize=clmax, minsize=clmin, resolution=res, embed_l=embed_l, embed_p=embed_p) def get_element_selection(self): self.vt.preprocess_params(self) ret, mode = self.element_selection_empty() try: ret['face'] = [int(x) for x in self.geom_id.split(',')] except: pass return ret, 'face' def get_embed(self): gid, clmax, clmin, embed_l, embed_p = self.vt.make_value_or_expression( self) ll = [str(x) for x in embed_l.split(',')] pp = [str(x) for x in embed_p.split(',')] return [], ll, pp
class Coeff2D_Essential(Coeff2D_Bdry): has_essential = True nlterms = [] vt = Vtable(data) def __init__(self, **kwargs): super(Coeff2D_Essential, self).__init__(**kwargs) def get_essential_idx(self, kfes): if kfes == 0: return self._sel_index else: return [] def apply_essential(self, engine, gf, real=False, kfes=0): if kfes > 0: return if real: dprint1("Apply Ess.(real)" + str(self._sel_index)) else: dprint1("Apply Ess.(imag)" + str(self._sel_index)) u0 = self.vt.make_value_or_expression(self) mesh = engine.get_mesh(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 coeff1 = U0(u0, self.get_root_phys().ind_vars, self._local_ns, self._global_ns, real=real) gf.ProjectBdrCoefficient(coeff1, mfem.intArray(bdr_attr))
class EM3D_DefBdry(EM3D_Bdry): can_delete = False is_essential = False nlterms = [] vt = Vtable(data2) def __init__(self, **kwargs): super(EM3D_DefBdry, self).__init__(**kwargs) Phys.__init__(self) def attribute_set(self, v): super(EM3D_DefBdry, self).attribute_set(v) v['sel_readonly'] = False v['sel_index'] = ['remaining'] return v ''' def panel1_param(self): return [['Default Bdry (PMC)', "Ht = 0", 2, {}],] def get_panel1_value(self): return None def import_panel1_value(self, v): pass def panel1_tip(self): return None ''' def get_possible_bdry(self): return []
class EM3D_PEC(EM3D_Bdry): has_essential = True nlterms = [] vt = Vtable(data) def get_essential_idx(self, kfes): if kfes == 0: return self._sel_index else: return [] def apply_essential(self, engine, gf, kfes, real=False, **kwargs): mesh = engine.get_mesh(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 kfes == 0: coeff1 = mfem.VectorArrayCoefficient(3) coeff1.Set(0, mfem.ConstantCoefficient(0.0)) coeff1.Set(1, mfem.ConstantCoefficient(0.0)) coeff1.Set(2, mfem.ConstantCoefficient(0.0)) gf.ProjectBdrCoefficientTangent(coeff1, mfem.intArray(bdr_attr))
class RecombineSurface(GmshMeshActionBase): vt = Vtable(rsdata) def add_meshcommand(self, mesher): gid = self.vt.make_value_or_expression(self)[0] gid = self.eval_enitity_id(gid) mesher.add('recombine_surface', gid)
class CompoundCurve(GmshMeshActionBase): vt = Vtable(data) def add_meshcommand(self, mesher): gid = self.vt.make_value_or_expression(self)[0] gid = self.eval_enitity_id(gid) # generate something like... Compound Curve{1, 5, 10}; text = "Compound Curve{ " + gid + "};" mesher.add('mergetxt', text=text, dim=[True, False, False, False])
def vt3(self): names = self.get_root_phys().dep_vars_base names2 = [n + '_init' for n in names] data = [] if hasattr(self, '_vt3'): vt3 = self._vt3 if vt3.keys() == names2: return vt3 data = [(n + '_init', VtableElement(n + '_init', type='array', guilabel=n + '(init)', default="0.0", tip="initial value", chkbox=True)) for n in names] self._vt3 = Vtable(data) v = {} self._vt3.attribute_set(v) self.do_update_attribute_set(v) return self._vt3
def vt(self): root_phys = self.get_root_phys() if not isinstance(root_phys, PhysModule): data = (('esse_value', VtableElement(None, type="array", guilabel="dummy", default="0.0", tip="dummy")), ) return Vtable(data) dep_vars = self.get_root_phys().dep_vars if not hasattr(self, '_dep_var_bk'): self._dep_var_bk = "" if self._dep_var_bk != dep_vars: dep_var = dep_vars[0] data = ( ('esse_value', VtableElement("esse_value", type="array", guilabel=dep_var, default="0.0", tip="Essentail BC")), ( 'esse_vdim', VtableElement( "esse_vdim", type="string", guilabel="vdim (0-base)", default="all", #readonly = True, tip="vdim (not supported)")), ) vt = Vtable(data) self._vt1 = vt self._dep_var_bk = dep_vars self.update_attribute_set() else: vt = self._vt1 return vt
class EM2D_Domain(Domain, Phys): has_3rd_panel = True vt3 = Vtable(data) def __init__(self, **kwargs): super(EM2D_Domain, self).__init__(**kwargs) Phys.__init__(self) def attribute_set(self, v): super(EM2D_Domain, self).attribute_set(v) v['sel_readonly'] = False v['sel_index'] = [] return v def get_init_coeff(self, engine, real=True, kfes=0): if kfes > 2: return if not self.use_Einit: return f_name = self.vt3.make_value_or_expression(self) if kfes == 0: coeff = Einit_xy(2, f_name[0], self.get_root_phys().ind_vars, self._local_ns, self._global_ns, real=real) return self.restrict_coeff(coeff, engine, vec=True) else: coeff = Einit_z(f_name[0], self.get_root_phys().ind_vars, self._local_ns, self._global_ns, real=real) return self.restrict_coeff(coeff, engine) def has_pml(self): from .em2d_pml import EM2D_PML for obj in self.walk(): if isinstance(obj, EM2D_PML) and obj.enabled: return True def get_pml(self): from .em2d_pml import EM2D_PML return [ obj for obj in self.walk() if isinstance(obj, EM2D_PML) and obj.enabled ] def make_PML_coeff(self, coeff): pmls = self.get_pml() if len(pmls) > 2: assert False, "Multiple PML is set" coeff1 = pmls[0].make_PML_coeff(coeff) return coeff1
class Coeff2D_PointValue(Coeff2D_Point): vt = Vtable(data) _sel_index = [-1] def panel2_param(self): return [] def import_panel2_value(self, v): self.sel_index = 'all' def verify_setting(self): x, y, s = self.vt.make_value_or_expression(self) if len(x) != len(y): return False, "Invalid x, y, s", "number of x and y must be the same" if len(x) != len(s): return False, "Invalid x, y, s", "number of x and s must be the same" return True, "", "" def has_extra_DoF(self, kfes): if kfes != 0: return False return True def get_exter_NDoF(self): x, y, s = self.vt.make_value_or_expression(self) return len(x) def postprocess_extra(self, sol, flag, sol_extra): name = self.name() sol_extra[name] = sol.toarray() 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)
def _add_vt_array(self, sidx): data = [ ("oprt1_" + sidx, VtableElement( "oprt1_" + sidx, type='any', guilabel="operator1", default="", tip="oprator (horizontal)", )), ("oprt2_" + sidx, VtableElement( "oprt2_" + sidx, type='any', guilabel="operator2", default="", tip="oprator (vertical)", )), ] vt = Vtable(data) self._vt_array.append(vt) vt.preprocess_params(self)
class EM3D_Impedance(EM3D_Bdry): is_essential = False vt = Vtable(data3) def has_bf_contribution(self, kfes=0): if kfes != 0: return False return True 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) '''
class CharacteristicLength(GmshMeshActionBase): vt = Vtable(data) def add_meshcommand(self, mesher): gid, cl = self.vt.make_value_or_expression(self) gid = self.eval_enitity_id(gid) mesher.add('cl', gid, cl) def get_element_selection(self): self.vt.preprocess_params(self) ret, mode = self.element_selection_empty() try: ret['point'] = [int(x) for x in self.geom_id.split(',')] except: pass return ret, 'point'
class EM2Da_DefBdry(EM2Da_Bdry): can_delete = False is_essential = False nlterms = [] vt = Vtable(data2) def __init__(self, **kwargs): super(EM2Da_DefBdry, self).__init__(**kwargs) Phys.__init__(self) def attribute_set(self, v): super(EM2Da_DefBdry, self).attribute_set(v) v['sel_readonly'] = False v['sel_index'] = ['remaining'] return v def get_possible_bdry(self): return []
class TransfiniteLine(GmshMeshActionBase): vt = Vtable(data) def add_meshcommand(self, mesher): gid, nseg, p, b = self.vt.make_value_or_expression(self) gid = self.eval_enitity_id(gid) mesher.add('transfinite_edge', gid, nseg=nseg, progression=p, bump=b) def get_element_selection(self): self.vt.preprocess_params(self) ret, mode = self.element_selection_empty() try: ret['edge'] = [int(x) for x in self.geom_id.split(',')] except: pass return ret, 'edge'
class Coeff2D_Zero(Coeff2D_Essential): vt = Vtable(data) def apply_essential(self, engine, gf, real=False, kfes=0): if kfes > 0: return if real: dprint1("Apply Ess.(real)" + str(self._sel_index)) else: dprint1("Apply Ess.(imag)" + str(self._sel_index)) mesh = engine.get_mesh(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 coeff1 = mfem.ConstantCoefficient(0.0) gf.ProjectBdrCoefficient(coeff1, mfem.intArray(bdr_attr))
class TransfiniteSurface(GmshMeshActionBase): vt = Vtable(data) def add_meshcommand(self, mesher): gid, e1, e2, e3, e4 = self.vt.make_value_or_expression(self) gid = self.eval_enitity_id(gid) c = [int(x) for x in (e1, e2, e3, e4) if x.strip() != ''] mesher.add('transfinite_surface', gid, corner=c) def get_element_selection(self): self.vt.preprocess_params(self) ret, mode = self.element_selection_empty() try: ret['face'] = [int(x) for x in self.geom_id.split(',')] except: pass return ret, 'face'
class WF_Natural(Bdry, Phys): has_essential = False nlterms = [] can_timedpendent = False has_3rd_panel = True vt = Vtable(data) def __init__(self, **kwargs): super(WF_Natural, self).__init__(**kwargs) def attribute_set(self, v): Bdry.attribute_set(self, v) Phys.attribute_set(self, v) v['sel_readonly'] = False v['sel_index'] = [] return v def get_essential_idx(self, kfes): return []
class Coeff2D_Absorption(Coeff2D_Domain): vt = Vtable(data) def has_bf_contribution(self, kfes): return True def add_bf_contribution(self, engine, a, real=True, kfes=0): a = self.vt.make_value_or_expression(self) if real: dprint1("Add absorption contribution(real)" + str(self._sel_index)) else: dprint1("Add absorption contribution(imag)" + str(self._sel_index)) a_coeff = FCoeff(a[0], self.get_root_phys().ind_vars, self._local_ns, self._global_ns, real=real) self.add_integrator(engine, 'p', a_coeff, a.AddDomainIntegrator, mfem.MassIntegrator)