Ejemplo n.º 1
0
 def parse_matrix_items_map(m,
                            default,
                            new2old,
                            item_types=(bool, str, int, float)):
     # Default value for all items if map is None
     if m is None:
         m = [default for _ in new2old]
         return m
     m = list(flatten(m)) if isinstance(m, list) else m
     # Check on single item of type in item_types
     for t in item_types:
         if isinstance(t, list):  # list of ...
             if isinstance(m, list):
                 if all(isinstance(m2, t2) for t2 in t for m2 in m):
                     m = [m for _ in new2old]
                     return m
         elif isinstance(m, t):  # non list types
             m = [m for _ in new2old]
             return m
     # Old list to new list
     if isinstance(m, list):
         m = [m[old_i] for old_i in new2old]
         return m
     else:  # Something wrong
         raise ValueError(m)
Ejemplo n.º 2
0
 def parse_layers_block_map(m, default, new2old, item_types=()):
     # Default value for all items if map is None
     if m is None:
         m = [default for _ in new2old]
         return m
     m = list(flatten(m)) if isinstance(m, list) else m
     # Check on single item of type in item_types
     for t in item_types:
         if isinstance(t, list) and isinstance(m, list):  # list of ...
             if all(isinstance(ti, mi) for ti in t for mi in m):
                 m = [m for _ in new2old]
                 return m
         elif isinstance(m, t):  # non list types
             m = [m for _ in new2old]
             return m
     # Old list to new list
     if isinstance(m, list):
         m = [m[x[0]] if x is not None else default for x in new2old]
         return m
     else:  # Something wrong
         raise ValueError(m)
Ejemplo n.º 3
0
 def evaluate_map(self, block):
     dt2zs = {}
     new2olds = get_boolean_new2olds()
     vs_dt = gmsh.model.getEntities(3)
     v2b = get_volume2block()
     uvs = get_unregistered_volumes()
     e2vs = {}
     e2bb = {}
     for vi, v_dt in enumerate(vs_dt):  # Volumes
         e2bb[v_dt] = v_dt
         tree = DataTree([v_dt])
         v_t = v_dt[1]
         old_vts = new2olds.get(v_t, [v_t])
         bs = [v2b[x] for x in old_vts]
         v_zs = [b.volume_zone for b in bs]
         if len(v_zs) > 1:
             bls = [b.boolean_level for b in bs]
             max_bls_ids = np.argwhere(bls == np.max(bls))
             v_zs = [v_zs[x[0]] for x in max_bls_ids]
         v_z = self.self_separator.join(sorted(set(v_zs)))
         dt2zs.setdefault(v_dt, []).append(v_z)
         if 2 in self.dims:  # Surfaces
             for si, ss_cs_ps_dt in enumerate(tree.vs_ss_cs_ps_dt[0]):
                 s_dt = tree.vs_ss_dt[0][si]
                 s_dt = (s_dt[0], abs(s_dt[1]))  # TODO Use undirected surface?
                 ss_ps = set(flatten(ss_cs_ps_dt))
                 ss_ps_cs = [tree.ps_dt_to_cs[x] for x in ss_ps]
                 s_bb = np.append(np.min(ss_ps_cs, axis=0),
                                  np.max(ss_ps_cs, axis=0))
                 # s_bb = gmsh.model.getBoundingBox(*s_dt)
                 # print(s_bb)
                 e2bb[s_dt] = s_bb
                 n = gmsh.model.getNormal(s_dt[1], [0.5, 0.5])  # Normal
                 # TODO Check what nan and empty means
                 if any(np.isnan(x) for x in n) or len(n) == 0:
                     s_zs = ['X', 'Y', 'Z']
                 else:
                     weights = [[np.dot(n, y) for y in x]
                                for x in self.zones_directions]
                     agr_weights = [np.mean(x) for x in weights]
                     max_weight_ids = np.argwhere(
                         np.logical_or(
                             np.isclose(agr_weights, np.min(agr_weights)),
                             np.isclose(agr_weights, np.max(agr_weights))))
                     s_zs = [self.zones[x[0]] for x in max_weight_ids]
                 # Correct TODO direction detection?
                 s_zs = [x if x != 'NX' else 'X' for x in s_zs]
                 s_zs = [x if x != 'NY' else 'Y' for x in s_zs]
                 s_zs = [x if x != 'NZ' else 'Z' for x in s_zs]
                 s_z = self.self_separator.join(sorted(set(s_zs)))
                 dt2zs.setdefault(s_dt, []).append(s_z)
                 e2vs.setdefault(s_dt, []).append(v_dt)
     # Sort values
     z2vs = {}
     dt2v = {}
     for dt, zs in dt2zs.items():
         dim, tag = dt
         bb = e2bb[dt]  # min x, min y, min z, max x, max y, max Z
         for z in zs:
             if dim == 2:
                 v = None
                 if 'X' in z.split(self.self_separator):
                     v = bb[0] if v is None else min([v, bb[0]])
                 if 'Y' in z.split(self.self_separator):
                     v = bb[1] if v is None else min([v, bb[1]])
                 if 'Z' in z.split(self.self_separator):
                     v = bb[2] if v is None else min([v, bb[2]])
                 if v is None:
                     continue
                 v = round(v, POINT_TOL)
                 z2vs.setdefault(z, set()).add(v)
                 dt2v[dt] = v
             else:
                 continue
     # Zone value to index map
     z2v2i = {}
     for z, vs in z2vs.items():
         z2v2i[z] = {x: i for i, x in enumerate(sorted(vs))}
     # Update zones
     for dt, zs in dt2zs.items():
         for zi, z in enumerate(zs):
             v2i = z2v2i.get(z, None)
             if v2i is None:
                 continue
             min_i, max_i = min(v2i.values()), max(v2i.values()),
             if z is None:
                 continue
             v = dt2v.get(dt, None)
             if v is None:
                 continue
             i = v2i.get(v, None)
             if i is None:
                 continue
             if any(['X' in z.split(self.self_separator),
                     'Y' in z.split(self.self_separator),
                     'Z' in z.split(self.self_separator)]):
                 if i == min_i:
                     dt2zs[dt][zi] = f'N{z}'
                 elif i == max_i:
                     dt2zs[dt][zi] = z
                 else:
                     dt2zs[dt][zi] = f'{z}{i}'
             else:
                 dt2zs[dt][zi] = f'{z}{i}'
     # Surfaces TODO Add curves and points
     for e_dt, vs_dt in e2vs.items():
         dim, tag = e_dt
         vs_us = [x[1] in uvs for x in vs_dt]  # Are volumes unregistered?
         vs_zs = [dt2zs[x][0] for x in vs_dt]
         e_zs = dt2zs[e_dt]
         do_join_entities = False
         for j in self.join_interfaces:
             if isinstance(j[0], list):
                 v_zs_j, e_z_j = j
             else:
                 v_zs_j, e_z_j = j, None
             if all(x in vs_zs for x in v_zs_j):
                 if e_z_j is None:
                     do_join_entities = True
                 else:
                     e_szs = [y for x in e_zs
                              for y in x.split(self.self_separator)]
                     do_join_entities = True
                     for z in e_z_j:
                         if z[-1] == '*':  # In string
                             z = z[:-1]
                             for sz in e_szs:
                                 if z not in sz:
                                     do_join_entities = False
                         else:  # String
                             if z not in e_szs:
                                 do_join_entities = False
         v_z = self.inter_separator.join(sorted(set(vs_zs)))
         if not do_join_entities:
             e_z = self.intra_separator.join(sorted(set(e_zs)))
             z = self.intra_separator.join([v_z, e_z])
         else:
             z = v_z
         if all(vs_us):  # All volumes are unregistered
             dt2zs.pop(e_dt, None)
         elif any(vs_us):  # Some volumes are unregistered
             if dim == 2:  # Surface
                 if len(vs_us) == 1:  # Unregistered
                     dt2zs.pop(e_dt, None)
                 elif len(vs_us) == 2:  # Boundary from Interface
                     dt2zs[e_dt] = [z]
         else:  # No volumes are unregistered
             if dim == 2:  # Surface
                 if len(vs_us) == 1:  # Boundary
                     dt2zs[e_dt] = [z]
                 elif len(vs_us) == 2:  # Interface
                     if 2 in self.dims_interfaces:
                         dt2zs[e_dt] = [z]
                     else:
                         dt2zs.pop(e_dt, None)
                 else:
                     raise ValueError(e_dt, vs_dt)
     # Remove unregistered volumes zones
     for dt in list(dt2zs.keys()):
         dim, tag = dt
         if dim == 3 and tag in uvs:
             dt2zs.pop(dt, None)
     return dt2zs
Ejemplo n.º 4
0
 def __call__(self, block):
     if not self.do_structure:
         return
     v_dts = gmsh.model.getEntities(3)
     new_olds = get_boolean_new2olds()
     for vi, v_dt in enumerate(v_dts):  # Volumes
         # print(v_dt)
         # Check
         dt = DataTree([v_dt])
         vs_ps = set(flatten(dt.vs_ss_cs_ps_dt[0]))  # Points
         if len(vs_ps) != 8:  # 8 points in volume
             continue
         if len(dt.vs_ss_dt[0]) != 6:  # 6 surfaces in volume
             continue
         ss_st, ss_cs_st = [], []  # Surfaces, Surfaces curves structures
         ss_qu = []  # Surfaces quadrates
         # vs_ps_dt = set()  # Volume points dim-tags
         do_structure = True
         for si, cs_ps_dt in enumerate(dt.vs_ss_cs_ps_dt[0]):  # Surfaces
             if len(dt.vs_ss_cs_dt[0][si]) != 4:  # 4 curves on surface
                 do_structure = False
                 break
             cs_st = []  # Curves structures
             ss_ps_dt = set()  # Surfaces points dim-tags
             for ci, ps_dt in enumerate(cs_ps_dt):  # Curves
                 ss_ps_dt.update(ps_dt)
                 c_dt = dt.vs_ss_cs_dt[0][si][ci]
                 if c_dt[1] > 0:
                     ps_cs = [dt.ps_dt_to_cs[x] for x in ps_dt]
                 else:
                     ps_cs = [dt.ps_dt_to_cs[x] for x in ps_dt[::-1]]
                 c_ps = [Point(list(x)) for x in ps_cs]  # Curves points
                 c_st = get_curve_structure(c_ps)
                 if c_st is None:
                     do_structure = False
                     break
                 cs_st.append(c_st)
             if not do_structure:
                 break
             # vs_ps_dt.update(ss_ps_dt)
             ss_cs_st.append(cs_st)
             ss_ps_cs = [dt.ps_dt_to_cs[x] for x in ss_ps_dt]
             s_ps = [Point(list(x)) for x in ss_ps_cs]
             s_st = get_surface_structure(s_ps)  # Surfaces points
             ss_st.append(s_st)
             if s_st is None:
                 do_structure = False
                 break
             if self.do_quadrate:
                 s_qu = get_surface_quadrate(s_ps)
                 ss_qu.append(s_qu)
         if not do_structure:
             continue
         # Too long
         # if len(vs_ps_dt) != 8:  # 8 points in volume
         #     continue
         # vs_ps_cs = [dt.ps_dt_to_cs[x] for x in vs_ps_dt]
         # v_ps = [Point(list(x)) for x in vs_ps_cs]  # Volume points
         # v_st = timeit(get_volume_structure)(v_ps)  # Volume structure
         v_t = v_dt[1]
         old_vts = new_olds.get(v_t, None)
         if old_vts is None:
             old_vt = v_t
         else:
             old_vt = v_t if v_t in old_vts else None
         if v_t is not None:
             v_st = get_volume_structure(old_vt)  # Volume structure
             if v_st is None:
                 continue
             # print(v_t, old_vts)
             # Do structure
             v = Volume(tag=v_dt[1], structure=v_st)
             register_structure_volume(v)
             for si, s_st in enumerate(ss_st):
                 s_dt = dt.vs_ss_dt[0][si]
                 s = Surface(tag=s_dt[1], structure=s_st)
                 register_structure_surface(s)
                 if self.do_quadrate:
                     s_qu = ss_qu[si]
                     s = Surface(tag=s_dt[1], quadrate=s_qu)
                     register_quadrate_surface(s)
                 for ci, c_st in enumerate(ss_cs_st[si]):
                     c_dt = dt.vs_ss_cs_dt[0][si][ci]
                     c = Curve(tag=c_dt[1], structure=c_st)
                     register_structure_curve(c)