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 __init__(self, exprs, ind_vars, l, g, real=True): ''' this is complicated.... elemental (or array) form [1,a,3] (a is namespace variable) is given as [[1, a (valued), 3]] single box 1+1j is given as '(1+1j)' (string) matrix given as string like '[0, 1, 2, 3, 4]' if variable is used it is become string element '['=variable', 1, 2, 3, 4]' if =Varialbe in matrix form, it is passed as [['Variable']] ''' flag, exprs = try_eval(exprs, l, g) #print("after try_eval", flag, exprs) if not flag: if isinstance(exprs, str): exprs = [exprs] #elif isinstance(exprs, float): # exprs = [exprs] #elif isinstance(exprs, long): # exprs = [exprs] elif isinstance(exprs, numbers.Number): exprs = [exprs] else: pass if isinstance(exprs, list) and isinstance(exprs[0], list): exprs = exprs[0] #dprint1("final exprs", exprs) self.l = {} #### TODO g must be copied since some may passs _global_ns. #### (I don't do it now since it requires a substantial testing) self.g = g for key in l.keys(): self.g[key] = l[key] self.real = real self.variables = [] self.co = [] for expr in exprs: if isinstance(expr, str): st = parser.expr(expr.strip()) code= st.compile('<string>') names = code.co_names for n in names: if (n in g and isinstance(g[n], NativeCoefficientGenBase)): coeff_var = CoefficientVariable(g[n], l, g) self.variables.append((n, coeff_var)) elif n in g and isinstance(g[n], Variable): self.variables.append((n, g[n])) for nn in g[n].dependency: self.variables.append((nn, g[nn])) else: pass self.co.append(code) else: self.co.append(expr) # 'x, y, z' -> 'x', 'y', 'z' self.ind_vars = [x.strip() for x in ind_vars.split(',')] self.exprs = exprs self.flags = [isinstance(co, types.CodeType) for co in self.co] self.variables_dd = dict(self.variables)
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