def _init_eval(self, value): gg = self.root()['General']._global_ns.copy() from petram.helper.variables import var_g ll = var_g.copy() return eval(value, gg, ll)
def eval_on_faces(obj, expr, solvars, phys): ''' evaluate nodal valus based on preproceessed geometry data to be done : obj should be replaced by a dictionary ''' from petram.helper.variables import Variable, var_g if len(obj.ifaces) == 0: return None variables = [] st = parser.expr(expr) code = st.compile('<string>') names = code.co_names g = {} for key in phys._global_ns.keys(): g[key] = phys._global_ns[key] for key in solvars.keys(): g[key] = solvars[key] ll_name = [] ll_value = [] var_g2 = var_g.copy() new_names = [] for n in names: if (n in g and isinstance(g[n], Variable)): new_names.extend(g[n].dependency) new_names.append(n) for n in new_names: if (n in g and isinstance(g[n], Variable)): if not g[n] in obj.knowns: obj.knowns[g[n]] = (g[n].ncface_values( ifaces=obj.ifaces, irs=obj.irs, gtypes=obj.gtypes, locs=obj.ptx, attr1=obj.elattr1, attr2=obj.elattr2, g=g, knowns=obj.knowns, mesh=obj.mesh()[obj.emesh_idx])) ll_name.append(n) ll_value.append(obj.knowns[g[n]]) elif (n in g): var_g2[n] = g[n] if len(ll_value) > 0: val = np.array([ eval(code, var_g2, dict(zip(ll_name, v))) for v in zip(*ll_value) ]) else: # if expr does not involve Varialbe, evaluate code once # and generate an array val = np.array([eval(code, var_g2)] * len(obj.ptx)) return val
import traceback from petram.helper.variables import var_g ll = var_g.copy() from petram.model import Model class InitSetting(Model): has_2nd_panel = False def attribute_set(self, v): v = super(InitSetting, self).attribute_set(v) v["phys_model"] = '' v["init_mode"] = 0 v["init_value_txt"] = '0.0' v["init_path"] = '' return v def panel1_param(self): from petram.pi.widget_init import InitSettingPanel return [ [ "physics model", self.phys_model, 0, {}, ], [ None, None, 99, { 'UI': InitSettingPanel, 'validator': self.init_validator
def eval_at_points(self, expr, solvars, phys): from petram.helper.variables import Variable, var_g, NativeCoefficientGenBase, CoefficientVariable variables = [] 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] ll_name = [] ll_value = [] var_g2 = var_g.copy() new_names = [] name_translation = {} for n in names: if (n in g and isinstance(g[n], NativeCoefficientGenBase)): g[n + "_coeff"] = CoefficientVariable(g[n], g) new_names.append(n + "_coeff") name_translation[n + "_coeff"] = n if (n in g and isinstance(g[n], Variable)): new_names.extend(g[n].dependency) new_names.append(n) name_translation[n] = n elif n in g: new_names.append(n) name_translation[n] = n for n in new_names: if (n in g and isinstance(g[n], Variable)): if not g[n] in self.knowns: self.knowns[g[n]] = g[n].point_values( counts=self.counts, locs=self.locs, attrs=self.masked_attrs, elem_ids=self.elem_ids, mesh=self.mesh()[self.emesh_idx], int_points=self.int_points, g=g, knowns=self.knowns) #ll[n] = self.knowns[g[n]] ll_name.append(name_translation[n]) ll_value.append(self.knowns[g[n]]) elif (n in g): var_g2[n] = g[n] if len(ll_value) > 0: val = np.array([ eval(code, var_g2, dict(zip(ll_name, v))) for v in zip(*ll_value) ]) else: # if expr does not involve Varialbe, evaluate code once # and generate an array val = np.array([eval(code, var_g2)] * len(self.locs)) return val
def eval_ns(self): chain = self.get_ns_chain() l = self.get_default_ns() from petram.helper.variables import var_g g = var_g.copy() if self.root() is self: self._variables = {} else: self._local_ns = self.root()._variables if len(chain) == 0: raise ValueError("namespace chain is not found") # step1 (fill ns using upstream + constant (no expression) if chain[-1] is not self: if len(l.keys()) == 0: self._global_ns = chain[-1]._global_ns #self._local_ns = chain[-1]._local_ns else: self._global_ns = g for k in l.keys(): g[k] = l[k] for k in chain[-1].keys(): g[k] = chain[-1]._global_ns[k] #self._local_ns = {} elif len(chain) > 1: # step 1-1 evaluate NS chain except for self and store dataset to # g including mine self._global_ns = g for p in chain[:-1]: #self.parents: if not isinstance(p, NS_mixin): continue ll = p.get_default_ns() if (p.ns_string == '' or p.ns_string is None and len(ll.keys()) == 0): continue for k in ll.keys(): g[k] = ll[k] if p.ns_name is not None: try: if p.dataset is not None: for k in p.dataset.keys(): g[k] = p.dataset[k] for k in p.attribute_mirror_ns(): g[k] = chain[-2]._global_ns[k] ll = {} if (p.ns_string != '' and p.ns_string is not None): exec p.ns_string in g, ll for k in ll.keys(): g[k] = ll[k] except Exception as e: assert False, e.message if self.dataset is not None: for k in self.dataset.keys(): g[k] = self.dataset[k] else: self._global_ns = g for k in l.keys(): g[k] = l[k] if self.dataset is not None: for k in self.dataset.keys(): g[k] = self.dataset[k] # step2 eval attribute using upstream + non-expression result, invalid = self.eval_attribute_expr() for k in result.keys(): setattr(self, k, result[k]) # step 3 copy attributes to ns attrs = self.attribute_mirror_ns() for a in attrs: if not a in invalid: g[a] = getattr(self, a) # step 4 run namespace scripts otherise exit for k in l.keys(): g[k] = l[k] # copying default ns try: l = {} if (self.ns_string != '' and self.ns_string is not None): exec self.ns_string in g, l else: pass ###return except Exception as e: assert False, e.message for k in l.keys(): g[k] = l[k] # step 5 re-eval attribute with self-namespace # passing previous invalid as a list of variables # to evaluate result, invalid = self.eval_attribute_expr(invalid) for k in result.keys(): setattr(self, k, result[k]) # if something is still not known,,, raise if len(invalid) != 0: raise ValueError("failed to evaluate variable " + ', '.join(invalid))
def eval_at_nodals(obj, expr, solvars, phys): ''' evaluate nodal valus based on preproceessed geometry data to be done : obj should be replaced by a dictionary ''' from petram.helper.variables import Variable, var_g, NativeCoefficientGenBase, CoefficientVariable if len(obj.iverts) == 0: return None variables = [] st = parser.expr(expr) code = st.compile('<string>') names = code.co_names g = {} for key in phys._global_ns.keys(): g[key] = phys._global_ns[key] for key in solvars.keys(): g[key] = solvars[key] ll_name = [] ll_value = [] var_g2 = var_g.copy() new_names = [] name_translation = {} for n in names: if (n in g and isinstance(g[n], NativeCoefficientGenBase)): g[n + "_coeff"] = CoefficientVariable(g[n], g) new_names.append(n + "_coeff") name_translation[n + "_coeff"] = n if (n in g and isinstance(g[n], Variable)): new_names.extend(g[n].dependency) new_names.append(n) name_translation[n] = n elif n in g: new_names.append(n) name_translation[n] = n for n in new_names: if (n in g and isinstance(g[n], Variable)): if not g[n] in obj.knowns: obj.knowns[g[n]] = (g[n].nodal_values( iele=obj.ieles, ibele=obj.ibeles, elattr=obj.elattr, el2v=obj.elvert2facevert, locs=obj.locs, elvertloc=obj.elvertloc, wverts=obj.wverts, mesh=obj.mesh()[obj.emesh_idx], iverts_f=obj.iverts_f, g=g, knowns=obj.knowns)) #ll[n] = self.knowns[g[n]] ll_name.append(name_translation[n]) ll_value.append(obj.knowns[g[n]]) elif (n in g): var_g2[n] = g[n] if len(ll_value) > 0: val = np.array([ eval(code, var_g2, dict(zip(ll_name, v))) for v in zip(*ll_value) ]) else: # if expr does not involve Varialbe, evaluate code once # and generate an array val = np.array([eval(code, var_g2)] * len(obj.locs)) return val
# # this file is not used anymore... # from petram.helper.variables import var_g g = var_g.copy() def eval_value(value): return eval(value, g, {}) def validator(value, param, ctrl): try: x = eval_value(value) except: return False return True
def eval_ns(self): chain = self.get_ns_chain() l = self.get_default_ns() from petram.helper.variables import var_g g = var_g.copy() import mfem if mfem.mfem_mode == 'serial': g['mfem'] = mfem.ser elif mfem.mfem_mode == 'parallel': g['mfem'] = mfem.par else: assert False, "PyMFEM is not loaded" import numpy g['np'] = numpy from petram.helper.variables import variable, coefficient g['variable'] = variable g['coefficient'] = coefficient if self.root() is self: if not hasattr(self.root(), "_variables"): from petram.helper.variables import Variables self.root()._variables = Variables() else: self._local_ns = self.root()._variables if len(chain) == 0: raise ValueError("namespace chain is not found") # step1 (fill ns using upstream + constant (no expression) if chain[-1] is not self: if len(l) == 0: self._global_ns = chain[-1]._global_ns #self._local_ns = chain[-1]._local_ns else: self._global_ns = g for k in l: g[k] = l[k] for k in chain[-1]._global_ns: g[k] = chain[-1]._global_ns[k] #self._local_ns = {} elif len(chain) > 1: # step 1-1 evaluate NS chain except for self and store dataset to # g including mine self._global_ns = g for p in chain[:-1]: #self.parents: if not isinstance(p, NS_mixin): continue ll = p.get_default_ns() if (p.ns_string == '' or p.ns_string is None and len(ll) == 0): continue for k in ll: g[k] = ll[k] if p.ns_name is not None: try: if p.dataset is not None: for k in p.dataset: g[k] = p.dataset[k] for k in p.attribute_mirror_ns(): g[k] = chain[-2]._global_ns[k] if (p.ns_string != '' and p.ns_string is not None): exec(p.ns_string, g, ll) for k in ll: g[k] = ll[k] except Exception as e: import traceback assert False, traceback.format_exc() if self.dataset is not None: for k in self.dataset: g[k] = self.dataset[k] else: self._global_ns = g for k in l: g[k] = l[k] if self.dataset is not None: for k in self.dataset: g[k] = self.dataset[k] # step2 eval attribute using upstream + non-expression result, invalid = self.eval_attribute_expr() for k in result: setattr(self, k, result[k]) # step 3 copy attributes to ns attrs = self.attribute_mirror_ns() for a in attrs: if not a in invalid: g[a] = getattr(self, a) # step 4 run namespace scripts otherise exit for k in l: g[k] = l[k] # copying default ns try: l = {} if (self.ns_string != '' and self.ns_string is not None): #exec(self.ns_string, g, l) exec(self.ns_string, g) else: pass ###return except Exception as e: import traceback assert False, traceback.format_exc() # 2021.08.25. passing g only above allows for list comprehension to work. # for k in l: # g[k] = l[k] # step 5 re-eval attribute with self-namespace # passing previous invalid as a list of variables # to evaluate result, invalid = self.eval_attribute_expr(invalid) for k in result: setattr(self, k, result[k]) #if self is not self.root()["General"] (Let's set it in General too) from petram.helper.dot_dict import DotDict g['general'] = DotDict(self.root()["General"]._global_ns) # if something is still not known,,, raise if len(invalid) != 0: raise ValueError("failed to evaluate variable " + ', '.join(invalid))
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