class _Edges(): """ Internal utility class keeping track of known edges. As this is currently quite dirty and hackish, it should be treated as an internal implementation detail with an unstable interface. Maye it can be converted to a fully fledged useful :python:`Edge` class later on, but for now it simply hides most of the dirty secrets of the :class:`Node` class. """ _in_edges = WKD() _flows = WKD() def __getitem__(self, key): self._flows[key] = self._flows.get(key, WKD()) return self._flows[key] def __setitem__(self, key, value): source, target = key self._in_edges[target] = self._in_edges.get(target, WS()) self._in_edges[target].add(source) self._flows[source] = self._flows.get(source, WKD()) self._flows[source][target] = value def __call__(self, *keys): result = self for k in keys: result = result[k] return result
def ncface_values(self, ifaces=None, irs=None, gtypes=None, g=None, attr1=None, attr2=None, locs=None, knowns=None, **kwargs): if locs is None: return if g is None: g = {} if knowns is None: knowns = WKD() dtype = np.complex if self.complex else np.float ret = [None] * len(locs) for idx, xyz in enumerate(locs): ''' for n in self.dependency: g[n].local_value = knowns[g[n]][idx] # putting the dependency variable to functions global. # this may not ideal, since there is potential danger # of name conflict? self.func.func_globals[n] = g[n] ''' kwargs = {n: knowns[g[n]][idx] for n in self.dependency} ret[idx] = self.func(*xyz, **kwargs) ret = np.stack(ret).astype(dtype, copy=False) return ret
def __init__(self): self.mfem_model = None self.solfiles = None self.solvars = WKD() self.agents = {} self.physpath = '' self.init_done = False self.failed = False
def __init__(self, task_queue, result_queue, myid, rank, logfile=False): mp.Process.__init__(self) EvaluatorCommon.__init__(self) self.task_queue = task_queue self.result_queue = result_queue self.myid = myid self.rank = rank self.solvars = WKD() self.agents = {} self.logfile = logfile
def preprocess_geometry(self, battrs, emesh_idx=0, decimate=1): mesh = self.mesh()[emesh_idx] #print 'preprocess_geom', mesh, battrs self.battrs = battrs self.decimate = decimate self.knowns = WKD() self.iverts = [] if mesh.Dimension() == 3: getarray = mesh.GetBdrArray getelement = mesh.GetBdrElement elif mesh.Dimension() == 2: getarray = mesh.GetDomainArray getelement = mesh.GetElement else: assert False, "BdrNodal Evaluator is not supported for this dimension" x = [getarray(battr) for battr in battrs] if np.sum([len(xx) for xx in x]) == 0: return ibdrs = np.hstack(x).astype(int).flatten() if self.decimate != 1: ibdrs = ibdrs[::self.decimate] self.ibeles = np.array(ibdrs) def get_vertices_array(i): arr = getelement(i).GetVerticesArray() if len(arr) == 3: return arr elif len(arr) == 4: x = arr[:-1] y = np.array([arr[0], arr[2], arr[3]]) return np.vstack([x, y]) # we handle quad as two triangles iverts = np.vstack([get_vertices_array(i) for i in ibdrs]) self.iverts = iverts if len(self.iverts) == 0: return data = process_iverts2nodals(mesh, iverts) for k in list(data): setattr(self, k, data[k]) self.emesh_idx = emesh_idx
def nodal_values(self, iele=None, el2v=None, locs=None, wverts=None, elvertloc=None, g=None, knowns=None, **kwargs): # elattr = None, el2v = None, # wverts = None, locs = None, g = None if locs is None: return if g is None: g = {} if knowns is None: knowns = WKD() size = len(wverts) shape = [size] + list(self.shape) dtype = np.complex if self.complex else np.float ret = np.zeros(shape, dtype=dtype) wverts = np.zeros(size) for kk, m, loc in zip(iele, el2v, elvertloc): if kk < 0: continue for pair, xyz in zip(m, loc): idx = pair[1] ''' for n in self.dependency: g[n].local_value = knowns[g[n]][idx] # putting the dependency variable to functions global. # this may not ideal, since there is potential danger # of name conflict? self.func.func_globals[n] = g[n] ''' kwargs = {n: knowns[g[n]][idx] for n in self.dependency} ret[idx] = ret[idx] + self.func(*xyz, **kwargs) wverts[idx] = wverts[idx] + 1 ret = np.stack([x for x in ret if x is not None]) idx = np.where(wverts == 0)[0] wverts[idx] = 1.0 from petram.helper.right_broadcast import div ret = div(ret, wverts) #print("PyFunctionVariable", ret) return ret
def preprocess_geometry(self, battrs, emesh_idx=0, decimate=1): mesh = self.mesh()[emesh_idx] #print 'preprocess_geom', mesh, battrs self.battrs = battrs self.decimate = decimate self.knowns = WKD() self.iverts = [] if mesh.Dimension() == 3: getarray = mesh.GetBdrArray getelement = mesh.GetBdrElement elif mesh.Dimension() == 2: getarray = mesh.GetDomainArray getelement = mesh.GetElement else: assert False, "BdrNodal Evaluator is not supported for this dimension" x = [getarray(battr) for battr in battrs] if np.sum([len(xx) for xx in x]) == 0: return ibdrs = np.hstack(x).astype(int).flatten() if self.decimate != 1: ibdrs = ibdrs[::self.decimate] self.ibeles = np.array(ibdrs) iverts = np.stack([getelement(i).GetVerticesArray() for i in ibdrs]) self.iverts = iverts if len(self.iverts) == 0: return data = process_iverts2nodals(mesh, iverts) for k in six.iterkeys(data): setattr(self, k, data[k]) self.emesh_idx = emesh_idx
def preprocess_geometry(self, battrs, emesh_idx=0, decimate=1): # we will ignore deciamte for a moment mesh = self.mesh()[emesh_idx] self.battrs = battrs self.knowns = WKD() self.iverts = [] self.ifaces = [] if mesh.Dimension() == 3: getface = mesh.GetBdrElementFace gettrans = mesh.GetBdrElementTransformation getarray = mesh.GetBdrArray getelement = mesh.GetBdrElement getbasegeom = mesh.GetBdrElementBaseGeometry getvertices = mesh.GetBdrElementVertices getattr1 = lambda x: mesh.GetFaceElementTransformations(x).Elem1No getattr2 = lambda x: mesh.GetFaceElementTransformations(x).Elem2No elif mesh.Dimension() == 2: getface = lambda x: (x, 1) gettrans = mesh.GetElementTransformation getarray = mesh.GetDomainArray getelement = mesh.GetElement getbasegeom = mesh.GetElementBaseGeometry getvertices = mesh.GetElementVertices getattr1 = mesh.GetAttribute getattr2 = lambda x: -1 else: assert False, "NCFace Evaluator is not supported for this dimension" x = [getarray(battr) for battr in battrs] if np.sum([len(xx) for xx in x]) == 0: return ibdrs = np.hstack(x).astype(int).flatten() self.ibeles = np.array(ibdrs) ptx = [] data = [] ridx = [] ifaces = [] self.gtypes = np.zeros(len(self.ibeles), dtype=int) self.elattr1 = np.zeros(len(self.ibeles), dtype=int) self.elattr2 = np.zeros(len(self.ibeles), dtype=int) self.irs = {} gtype_st = -1 nele = 0 for k, i in enumerate(self.ibeles): verts = getvertices(i) gtype = getbasegeom(i) iface, ort = getface(i) Trs = mesh.GetFaceElementTransformations(iface) if gtype != gtype_st: RefG = GR.Refine(gtype, self.refine) ir = RefG.RefPts npt = ir.GetNPoints() ele = np.array(RefG.RefGeoms.ToList()).reshape(-1, len(verts)) gtype_st = gtype self.irs[gtype] = ir T = gettrans(i) pt = np.vstack([T.Transform(ir.IntPoint(j)) for j in range(npt)]) ptx.append(pt) ridx.append(ele + nele) nele = nele + ir.GetNPoints() ifaces.append(iface) self.gtypes[k] = gtype self.elattr1[k] = getattr1(i) self.elattr2[k] = getattr2(i) self.ptx = np.vstack(ptx) self.ridx = np.vstack(ridx) self.ifaces = np.hstack(ifaces) self.emesh_idx = emesh_idx
def preprocess_geometry(self, attrs, emesh_idx=0): self.vertices = None self.knowns = WKD() mesh = self.mesh()[emesh_idx] self.iverts = [] self.attrs = attrs if attrs[0] == 'all': eattrs = 'all' else: eattrs = attrs if mesh.Dimension() == 3: ''' from petram.mesh.find_edges import find_edges edges, bb_edges = find_edges(mesh) bb_bdrs = bb_edges.keys() iverts = [] for bb_bdr in bb_bdrs: if eattrs != 'all': check = [sorted(tuple(eattr)) == sorted(bb_bdr) for eattr in eattrs] if not any(check): continue iedges = bb_edges[bb_bdr] iverts.extend([mesh.GetEdgeVertices(ie) for ie in iedges]) print iverts ''' from petram.mesh.mesh_utils import get_extended_connectivity if not hasattr(mesh, 'extended_connectivity'): get_extended_connectivity(mesh) l2e = mesh.extended_connectivity['line2edge'] keys = l2e.keys() if eattrs == 'all' else list( np.atleast_1d(eattrs).flatten()) iedges = list(set(sum([l2e[k] for k in keys if k in l2e], []))) iverts = [mesh.GetEdgeVertices(ie) for ie in iedges] self.ibeles = None # can not use boundary variable in this evaulator elif mesh.Dimension() == 2: kbdr = mesh.GetBdrAttributeArray() if eattrs == 'all': eattrs = np.unique(kbdr) iverts = [] #d = defaultdict(list) for i in range(mesh.GetNBE()): attr = mesh.GetBdrAttribute(i) if attr in eattrs: iverts.append( list(mesh.GetBdrElement(i).GetVerticesArray())) x = np.unique([mesh.GetBdrArray(e) for e in eattrs]).astype(int, copy=False) self.ibeles = x #d[attr].extend(mesh.GetBdrElement(i).GetVerticesArray()) elif mesh.Dimension() == 1: kbdr = mesh.GetAttributeArray() if eattrs == 'all': eattrs = np.unique(kbdr) iverts = [] #d = defaultdict(list) for i in range(mesh.GetNE()): attr = mesh.GetAttribute(i) if attr in eattrs: iverts.append(list(mesh.GetElement(i).GetVerticesArray())) #d[attr].extend(mesh.GetBdrElement(i).GetVerticesArray()) x = np.unique([mesh.GetDomainArray(e) for e in eattrs]).astype(int, copy=False) self.ibeles = x else: assert False, "Unsupported dim" self.emesh_idx = emesh_idx if len(iverts) == 0: return iverts = np.stack(iverts) self.iverts = iverts if len(self.iverts) == 0: return data = process_iverts2nodals(mesh, iverts) for k in six.iterkeys(data): setattr(self, k, data[k])
def preprocess_geometry(self, attrs, emesh_idx=0, pc_type=None, pc_param=None): from petram.helper.geom import generate_pc_from_cpparam self.attrs = attrs if pc_param is not None: pc_param = self.pc_param pc_type = self.pc_type if pc_type == 'cutplane': # cutplane param = { "origin": pc_param[0], "e1": pc_param[1], "e2": pc_param[2], "x": pc_param[3], "y": pc_param[4] } cp_abc = np.cross(pc_param[1], pc_param[2]) cp_d = -np.sum(cp_abc * pc_param[0]) points = generate_pc_from_cpparam(**param) elif pc_type == 'line': sp = np.array(pc_param[0]) ep = np.array(pc_param[1]) num = pc_param[2] ii = np.linspace(0, 1., num) points = np.vstack([sp * (1 - i) + ep * i for i in ii]) elif pc_type == 'xyz': points = pc_param mesh = self.mesh()[emesh_idx] sdim = mesh.SpaceDimension() if points.shape[-1] > sdim: points = points[..., :sdim] if np.prod(points.shape) == 0: assert False, "PointCloud: Number of points = 0" return self.ans_shape = points.shape self.ans_points = points self.points = points.reshape(-1, points.shape[-1]) v = mfem.Vector() mesh.GetVertices(v) vv = v.GetDataArray() vv = vv.reshape(sdim, -1) max_mesh_ptx = np.max(vv, 1) min_mesh_ptx = np.min(vv, 1) max_ptx = np.max(self.points, 0) min_ptx = np.min(self.points, 0) out_of_range = False for i in range(len(max_mesh_ptx)): if max_mesh_ptx[i] < min_ptx[i]: out_of_range = True if min_mesh_ptx[i] > max_ptx[i]: out_of_range = True self.subset = None if pc_type == "cutplane" and sdim == 3: ### in 3D, we try to cut down the number of point query to FindPoints param = vv[0, :] * cp_abc[0] + vv[1, :] * cp_abc[1] + vv[ 2, :] * cp_abc[2] + cp_d if np.max(param) * np.min(param) == 0: out_of_range = True else: x1 = np.sum((vv.transpose() - pc_param[0]) * pc_param[1], -1) xxx = np.min(x1), np.max(x1) y1 = np.sum((vv.transpose() - pc_param[0]) * pc_param[2], -1) yyy = np.min(y1), np.max(y1) xmin, xmax, xsize = pc_param[3] ymin, ymax, ysize = pc_param[4] xxx = [ int((xxx[0] - xmin) // xsize), int((xxx[1] - xmin) // xsize) ] yyy = [ int((yyy[0] - ymin) // ysize), int((yyy[1] - ymin) // ysize) ] ss = self.ans_points.shape if xxx[0] < 0: xxx[0] = 0 if yyy[0] < 0: yyy[0] = 0 if xxx[1] >= ss[1]: xxx[1] = ss[1] - 1 if yyy[1] >= ss[0]: yyy[1] = ss[0] - 1 if xxx[0] > 0: xxx[0] = xxx[0] - 1 if yyy[0] > 0: yyy[0] = yyy[0] - 1 if xxx[1] < self.ans_points.shape[1] - 1: xxx[1] = xxx[1] + 1 if yyy[1] < self.ans_points.shape[0] - 1: yyy[1] = yyy[1] + 1 subset = np.zeros(ss[:-1], dtype=bool) subset[yyy[0]:yyy[1], xxx[0]:xxx[1]] = True ptx = self.ans_points[yyy[0]:yyy[1], :, :] ptx = ptx[:, xxx[0]:xxx[1], :] self.points = ptx.reshape(-1, self.ans_points.shape[-1]) self.subset = subset if out_of_range: counts = 0 elem_ids = np.zeros(len(self.points), dtype=int) - 1 int_points = [None] * len(self.points) print("skipping mesh") else: print("Chekcing " + str(len(self.points)) + " points") counts, elem_ids, int_points = mesh.FindPoints(self.points, warn=False) print("FindPoints found " + str(counts) + " points") attrs = [mesh.GetAttribute(id) if id != -1 else -1 for id in elem_ids] attrs = np.array([i if i in self.attrs else -1 for i in attrs]) self.elem_ids = elem_ids self.masked_attrs = attrs self.int_points = int_points self.counts = counts idx = np.where(attrs != -1)[0] self.locs = self.points[idx] self.valid_idx = idx self.emesh_idx = emesh_idx self.knowns = WKD()
def preprocess_geometry(self, battrs, emesh_idx=0, decimate=1): # we will ignore deciamte for a moment mesh = self.mesh()[emesh_idx] self.battrs = battrs self.knowns = WKD() self.iverts = [] self.ifaces = [] if mesh.Dimension() == 3: def f1(ibele): iface, o = mesh.GetBdrElementFace(ibele) e1 = mesh.GetFaceElementTransformations(iface).Elem1No return mesh.GetAttribute(e1) def f2(ibele): iface, o = mesh.GetBdrElementFace(ibele) e2 = mesh.GetFaceElementTransformations(iface).Elem2No if e2 >= 0: return mesh.GetAttribute(e2) else: return -1 getface = mesh.GetBdrElementFace gettrans = mesh.GetBdrElementTransformation getarray = mesh.GetBdrArray getelement = mesh.GetBdrElement getbasegeom = mesh.GetBdrElementBaseGeometry getvertices = mesh.GetBdrElementVertices getattr1 = f1 getattr2 = f2 elif mesh.Dimension() == 2: def getface(x): return (x, 1) gettrans = mesh.GetElementTransformation getarray = mesh.GetDomainArray getelement = mesh.GetElement getbasegeom = mesh.GetElementBaseGeometry getvertices = mesh.GetElementVertices getattr1 = mesh.GetAttribute def getattr2(x): return -1 else: assert False, "NCFace Evaluator is not supported for this dimension" x = [getarray(battr) for battr in battrs] if np.sum([len(xx) for xx in x]) == 0: return ibdrs = np.hstack(x).astype(int).flatten() self.ibeles = np.array(ibdrs) ptx = [] data = [] ridx = [] ifaces = [] self.gtypes = np.zeros(len(self.ibeles), dtype=int) self.elattr1 = np.zeros(len(self.ibeles), dtype=int) self.elattr2 = np.zeros(len(self.ibeles), dtype=int) self.irs = {} gtype_st = -1 nele = 0 p = mfem.DenseMatrix() for k, i in enumerate(self.ibeles): verts = getvertices(i) gtype = getbasegeom(i) iface, ort = getface(i) #Trs = mesh.GetFaceElementTransformations(iface) if gtype != gtype_st: RefG = GR.Refine(gtype, self.refine) ir = RefG.RefPts npt = ir.GetNPoints() ele0 = np.array(RefG.RefGeoms.ToList()).reshape(-1, len(verts)) gtype_st = gtype self.irs[gtype] = ir # we handle quad as two triangles to handle mixed element case ele = [] for eee in ele0: if len(eee) == 3: ele.append(eee) elif len(eee) == 4: x = eee[:-1] y = np.array([eee[0], eee[2], eee[3]]) ele.extend([x, y]) ele = np.array(ele) if mesh.Dimension() == 3: eir = mfem.IntegrationRule(ir.GetNPoints()) fi = mesh.GetBdrFace(i) Transf = mesh.GetFaceElementTransformations(fi) Transf.Loc1.Transform(ir, eir) Transf.Elem1.Transform(eir, p) pt = p.GetDataArray().copy().transpose() elif mesh.Dimension() == 2: T = gettrans(i) T.Transform(ir, p) pt = p.GetDataArray().copy().transpose() #pt = np.vstack([T.Transform(ir.IntPoint(j)) for j in range(npt)]) ptx.append(pt) ridx.append(ele + nele) nele = nele + ir.GetNPoints() ifaces.append(iface) self.gtypes[k] = gtype self.elattr1[k] = getattr1(i) self.elattr2[k] = getattr2(i) self.ptx = np.vstack(ptx) self.ridx = np.vstack(ridx) self.ifaces = np.hstack(ifaces) self.emesh_idx = emesh_idx
def __setitem__(self, key, value): source, target = key self._in_edges[target] = self._in_edges.get(target, WS()) self._in_edges[target].add(source) self._flows[source] = self._flows.get(source, WKD()) self._flows[source][target] = value
def forget_knowns(self): self.knowns = WKD()
def run(self, *args, **kargs): # this can not be in init, sicne it is not pickable self.solvars = WKD() if self.logfile == 'suppress': sys.stdout = open(os.devnull, 'w') elif self.logfile == 'queue': self.use_stringio = True elif self.logfile == 'log': path = os.path.expanduser('~/MPChild' + str(os.getpid()) + '.out') sys.stdout = open(path, "w") else: pass while True: time.sleep(0.01) try: task = self.task_queue.get(True) except EOFError: self.result_queue.put((-1, None)) self.task_queue.task_done() continue if task[0] == -1: self.task_queue.task_done() break try: if self.use_stringio: stringio = StringIO() org_sys_stdout = sys.stdout org_sys_stderr = sys.stderr sys.stdout = stringio sys.stderr = stringio if self.use_profiler: import cProfile pr = cProfile.Profile() pr.enable() #print("got task", task[0], self.myid, self.rank) if task[0] == 1: # (1, cls, param) = make_agents if self.solfiles is None: continue cls = task[1] params = task[2] kwargs = task[3] self.make_agents(cls, params, **kwargs) elif task[0] == 2: # (2, solfiles) = set_solfiles self.set_solfiles(task[1]) elif task[0] == 3: # (3, mfem_model) = set_model self.set_model(task[1]) elif task[0] == 4: # (4,) = load_solfiles if self.solfiles is None: continue self.load_solfiles() elif task[0] == 5: # (5,) = phys_path self.phys_path = task[1] elif task[0] == 6: # (6, attr) = process_geom if self.solfiles is None: continue self.call_preprocesss_geometry(task[1], **task[2]) elif task[0] == 7: # (7, expr) = eval if self.solfiles is None: value = (self.myid, None, None) else: value = self.eval(task[1], **task[2]) elif task[0] == 8: # (8, expr) = eval_probe value = self.eval_probe(task[1], task[2], task[3]) elif task[0] == 9: # (8, expr) = make_probe_agents cls = task[1] params = task[2] kwargs = task[3] self.make_probe_agents(cls, params, **kwargs) elif task[0] == 10: # (8, expr) = eval_pointcloud value = self.eval_pointcloud(task[1], **task[2]) except: traceback.print_exc() value = (self.myid, None, None) finally: self.task_queue.task_done() if self.use_profiler: import pstats pr.disable() ps = pstats.Stats( pr, stream=sys.stdout).sort_stats('cumulative') ps.print_stats() if task[0] == 7: self.result_queue.put(value) if task[0] == 8: self.result_queue.put(value) if task[0] == 10: self.result_queue.put(value) if self.use_stringio: output = stringio.getvalue() stringio.getvalue() sys.stdout = org_sys_stdout sys.stderr = org_sys_stderr stringio.close() self.text_queue.put(output) #end of while self.task_queue.close() self.result_queue.close()
def preprocess_geometry(self, attrs, emesh_idx=0, pc_type=None, pc_param=None): from petram.helper.geom import generate_pc_from_cpparam self.attrs = attrs if pc_param is not None: pc_param = self.pc_param pc_type = self.pc_type if pc_type == 'cutplane': # cutplane param = { "origin": pc_param[0], "e1": pc_param[1], "e2": pc_param[2], "x": pc_param[3], "y": pc_param[4] } points = generate_pc_from_cpparam(**param) elif pc_type == 'line': sp = np.array(pc_param[0]) ep = np.array(pc_param[1]) num = pc_param[2] ii = np.linspace(0, 1., num) points = np.vstack([sp * (1 - i) + ep * i for i in ii]) elif pc_type == 'xyz': points = pc_param self.ans_shape = points.shape self.ans_points = points self.points = points.reshape(-1, points.shape[-1]) mesh = self.mesh()[emesh_idx] v = mfem.Vector() mesh.GetVertices(v) vv = v.GetDataArray() vv = vv.reshape(3, -1) max_mesh_ptx = np.max(vv, 1) min_mesh_ptx = np.min(vv, 1) max_ptx = np.max(self.points, 0) min_ptx = np.min(self.points, 0) out_of_range = False for i in range(len(max_mesh_ptx)): if max_mesh_ptx[i] < min_ptx[i]: out_of_range = True if min_mesh_ptx[i] > max_ptx[i]: out_of_range = True if out_of_range: counts = 0 elem_ids = np.zeros(len(self.points), dtype=int) - 1 int_points = [None] * len(self.points) print("skipping mesh") else: counts, elem_ids, int_points = mesh.FindPoints(self.points, warn=False) print("FindPoints found " + str(counts) + " points") attrs = [mesh.GetAttribute(id) if id != -1 else -1 for id in elem_ids] attrs = np.array([i if i in self.attrs else -1 for i in attrs]) self.elem_ids = elem_ids self.masked_attrs = attrs self.int_points = int_points self.counts = counts idx = np.where(attrs != -1)[0] self.locs = self.points[idx] self.valid_idx = idx self.emesh_idx = emesh_idx self.knowns = WKD()
def __init__(self): object.__init__(self) self.mesh = None self.knowns = WKD() self.emesh_idx = -1
def __getitem__(self, key): self._flows[key] = self._flows.get(key, WKD()) return self._flows[key]
def preprocess_geometry(self, attrs, plane=None, emesh_idx=0): #from petram.sol.test import pg #return pg(self, battrs, plane = plane) self.vertices = None self.iverts = None self.knowns = WKD() mesh = self.mesh()[emesh_idx] self.iverts = [] self.attrs = attrs self.plane = plane attrs = self.attrs axyz = self.plane[:3] c = self.plane[-1] attr = mesh.GetAttributeArray() x = [np.where(attr == a)[0] for a in attrs] if np.sum([len(xx) for xx in x]) == 0: return ialleles = np.hstack(x).astype(int).flatten() ieles = [] num_tri = 0 tri_iverts = [] f_values = [] for iel in ialleles: verts = np.vstack([ mesh.GetVertexArray(i) for i in mesh.GetElement(iel).GetVerticesArray() ]) f = np.sum(verts * axyz, -1) + c ips = np.where(f > 0)[0] ims = np.where(f < 0)[0] izs = np.where(f == 0)[0] #print f, ips, ims, izs if (len(ips) == 0 or len(ims) == 0) and len(izs) != 3: continue # outside the plane ieles.append(iel) f_values.append(f) if f.prod() > 0: # cross section is quad. num_tri += 2 else: num_tri += 1 # then get unique set of elements relating to the verts. if num_tri == 0: #print "not found" return print("found " + str(num_tri) + " elements") vert2el = mesh.GetVertexToElementTable() iverts = np.array( [mesh.GetElement(iel).GetVerticesArray() for iel in ieles]) self.iverts = iverts data = process_iverts2nodals(mesh, iverts) for k in six.iterkeys(data): setattr(self, k, data[k]) iverts_f = self.iverts_f # how to interpolate nodal values... vertices = np.zeros((num_tri, 3, 3)) mat = scipy.sparse.lil_matrix((num_tri * 3, len(iverts_f))) def fill_vert_mat(vertics, mat, ivv, itri, k, i1, i2, verts, f): v1 = verts[i1] v2 = verts[i2] f1 = np.abs(f[i1]) f2 = np.abs(f[i2]) v = (v1 * f2 + v2 * f1) / (f1 + f2) vertices[itri, k, :] = v mat[itri * 3 + k, ivv[i1]] = np.abs(f2) / (f1 + f2) mat[itri * 3 + k, ivv[i2]] = np.abs(f1) / (f1 + f2) itri = 0 for iel, f in zip(ieles, f_values): iv = mesh.GetElement(iel).GetVerticesArray() verts = np.vstack([mesh.GetVertexArray(i) for i in iv]) ivv = [np.where(iverts_f == i)[0] for i in iv] ips = np.where(f > 0)[0] ims = np.where(f < 0)[0] if (len(ips) == 2 and len(ims) == 2): fill_vert_mat(vertices, mat, ivv, itri, 0, ips[0], ims[0], verts, f) fill_vert_mat(vertices, mat, ivv, itri, 1, ips[0], ims[1], verts, f) fill_vert_mat(vertices, mat, ivv, itri, 2, ips[1], ims[0], verts, f) itri += 1 fill_vert_mat(vertices, mat, ivv, itri, 0, ips[1], ims[0], verts, f) fill_vert_mat(vertices, mat, ivv, itri, 1, ips[1], ims[1], verts, f) fill_vert_mat(vertices, mat, ivv, itri, 2, ips[0], ims[1], verts, f) itri += 1 else: if len(ips) == 1: ims = np.where(f <= 0)[0] i = ips[0] ii = ims else: ips = np.where(f >= 0)[0] i = ims[0] ii = ips fill_vert_mat(vertices, mat, ivv, itri, 0, i, ii[0], verts, f) fill_vert_mat(vertices, mat, ivv, itri, 1, i, ii[1], verts, f) fill_vert_mat(vertices, mat, ivv, itri, 2, i, ii[2], verts, f) itri += 1 self.ibeles = None # can not use boundary variable in this evaulator self.vertices = vertices self.interp_mat = mat self.emesh_idx = emesh_idx