| 12 | import pymesh |
| 13 | |
| 14 | class Formula: |
| 15 | def __init__(self, mesh): |
| 16 | self.mesh = mesh; |
| 17 | self.field_parser = re.compile("\{\w+\}"); |
| 18 | self.__load_default_fields(); |
| 19 | |
| 20 | def __load_default_fields(self): |
| 21 | self.index = np.arange(self.mesh.num_elements, dtype=int); |
| 22 | if self.mesh.num_voxels == 0: |
| 23 | self.mesh.add_attribute("face_centroid"); |
| 24 | elem_centers = self.mesh.get_attribute("face_centroid"); |
| 25 | elem_centers = elem_centers.reshape( |
| 26 | (self.mesh.num_faces, self.mesh.dim)); |
| 27 | else: |
| 28 | self.mesh.add_attribute("voxel_centroid"); |
| 29 | elem_centers = self.mesh.get_attribute("voxel_centroid"); |
| 30 | elem_centers = elem_centers.reshape( |
| 31 | (self.mesh.num_voxels, self.mesh.dim)); |
| 32 | bbox_min, bbox_max = self.mesh.bbox; |
| 33 | self.x = elem_centers[:, 0].ravel(); |
| 34 | self.x_p = (self.x - bbox_min[0]) / (bbox_max[0] - bbox_min[0]); |
| 35 | self.y = elem_centers[:, 1].ravel(); |
| 36 | self.y_p = (self.y - bbox_min[1]) / (bbox_max[1] - bbox_min[1]); |
| 37 | if self.mesh.dim == 3: |
| 38 | self.z = elem_centers[:, 2].ravel(); |
| 39 | self.z_p = (self.z - bbox_min[2]) / (bbox_max[2] - bbox_min[2]); |
| 40 | |
| 41 | def eval_formula(self, formula): |
| 42 | self.formula = formula; |
| 43 | field_names = self.field_parser.findall(formula); |
| 44 | for name in field_names: |
| 45 | field_name = name[1:-1]; |
| 46 | if hasattr(self, field_name): |
| 47 | escaped_name = field_name; |
| 48 | else: |
| 49 | escaped_name = self.load_field(field_name); |
| 50 | self.formula = self.formula.replace(name, |
| 51 | "self.{}".format(escaped_name)); |
| 52 | |
| 53 | st = parser.expr(self.formula); |
| 54 | code = st.compile("file.py"); |
| 55 | return eval(code); |
| 56 | |
| 57 | def load_field(self, name): |
| 58 | if hasattr(self, name): return name; |
| 59 | assert(self.mesh.has_attribute(name)); |
| 60 | value = self.mesh.get_attribute(name); |
| 61 | escaped_name = name.replace(" ", "_") |
| 62 | setattr(self, name, value); |
| 63 | return escaped_name |
| 64 | |
| 65 | def parse_args(): |
| 66 | parser = argparse.ArgumentParser(description=__doc__); |