def try_add_line(d1, d2): try: result.append(( node_dict[add_tuples(current, d1)], node_dict[add_tuples(current, d2)], )) except KeyError: pass
def nd_quad_submesh(node_tuples): """Return a list of tuples of indices into the node list that generate a tesselation of the reference element. :arg node_tuples: A list of tuples *(i, j, ...)* of integers indicating node positions inside the unit element. The returned list references indices in this list. :func:`pytools.generate_nonnegative_integer_tuples_below` may be used to generate *node_tuples*. See also :func:`modepy.tools.simplex_submesh`. """ from pytools import single_valued, add_tuples dims = single_valued(len(nt) for nt in node_tuples) node_dict = dict( (ituple, idx) for idx, ituple in enumerate(node_tuples)) from pytools import generate_nonnegative_integer_tuples_below as gnitb result = [] for current in node_tuples: try: result.append(tuple( node_dict[add_tuples(current, offset)] for offset in gnitb(2, dims))) except KeyError: pass return result
def nd_quad_submesh(node_tuples): """Return a list of tuples of indices into the node list that generate a tesselation of the reference element. :arg node_tuples: A list of tuples *(i, j, ...)* of integers indicating node positions inside the unit element. The returned list references indices in this list. :func:`pytools.generate_nonnegative_integer_tuples_below` may be used to generate *node_tuples*. See also :func:`modepy.tools.simplex_submesh`. """ from pytools import single_valued, add_tuples dims = single_valued(len(nt) for nt in node_tuples) node_dict = dict((ituple, idx) for idx, ituple in enumerate(node_tuples)) from pytools import generate_nonnegative_integer_tuples_below as gnitb result = [] for current in node_tuples: try: result.append( tuple(node_dict[add_tuples(current, offset)] for offset in gnitb(2, dims))) except KeyError: pass return result
def _(shape: Hypercube, node_tuples): node_tuple_to_index = {nt: i for i, nt in enumerate(node_tuples)} # NOTE: this can't use mp.submesh_for_shape because VTK vertex order is # counterclockwise instead of z order el_offsets = { 1: [(0,), (1,)], 2: [(0, 0), (1, 0), (1, 1), (0, 1)], 3: [ (0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0), (0, 0, 1), (1, 0, 1), (1, 1, 1), (0, 1, 1), ] }[shape.dim] from pytools import add_tuples elements = [] for origin in node_tuples: try: elements.append(tuple( node_tuple_to_index[add_tuples(origin, offset)] for offset in el_offsets )) except KeyError: pass return elements
def _(meg: _ModepyElementGroup): shape = meg._modepy_shape space = type(meg._modepy_space)(meg.dim, 2) ref_vertices = mp.node_tuples_for_space(space) ref_vertices_to_index = {rv: i for i, rv in enumerate(ref_vertices)} from pytools import add_tuples space = type(meg._modepy_space)(meg.dim, 1) orig_vertices = tuple( [add_tuples(vt, vt) for vt in mp.node_tuples_for_space(space)]) orig_vertex_indices = [ref_vertices_to_index[vt] for vt in orig_vertices] midpoints = _get_ref_midpoints(shape, ref_vertices) midpoint_indices = [ref_vertices_to_index[mp] for mp in midpoints] midpoint_to_vertex_pairs = { midpoint: (i, j) for i, ivt in enumerate(orig_vertices) for j, jvt in enumerate(orig_vertices) for midpoint in [_midpoint_tuples(ivt, jvt)] if i < j and midpoint in midpoints } # ensure order matches the one in midpoint_indices midpoint_vertex_pairs = [midpoint_to_vertex_pairs[m] for m in midpoints] return ElementTesselationInfo( ref_vertices=ref_vertices, children=np.array(mp.submesh_for_shape(shape, ref_vertices)), orig_vertex_indices=np.array(orig_vertex_indices), midpoint_indices=np.array(midpoint_indices), midpoint_vertex_pairs=midpoint_vertex_pairs, )
def vtk_lagrange_triangle_node_tuples(order): nodes = [] offset = (0, 0) if order < 0: return nodes while order >= 0: if order == 0: nodes += [offset] break # y # ^ # | # 2 # |`\ # | `\ # | `\ # | `\ # | `\ # 0----------1 --> x # add vertices vertices = [(0, 0), (order, 0), (0, order)] nodes += add_tuple_to_list(vertices, offset) if order == 1: break # add faces face_ids = range(1, order) faces = ( # vertex 0 -> 1 [(i, 0) for i in face_ids] # vertex 1 -> 2 + [(order - i, i) for i in face_ids] # vertex 2 -> 0 + [(0, order - i) for i in face_ids]) nodes += add_tuple_to_list(faces, offset) order = order - 3 offset = add_tuples(offset, (1, 1)) return nodes
def _(shape: Hypercube, node_tuples): from pytools import single_valued, add_tuples dims = single_valued(len(nt) for nt in node_tuples) # NOTE: nodes use "first coordinate varies faster" (see node_tuples_for_space) from pytools import generate_nonnegative_integer_tuples_below as gnitb vertex_node_tuples = [nt[::-1] for nt in gnitb(2, dims)] result = [] node_dict = {ituple: idx for idx, ituple in enumerate(node_tuples)} for current in node_tuples: try: result.append(tuple( node_dict[add_tuples(current, offset)] for offset in vertex_node_tuples )) except KeyError: pass return result
def _get_ref_midpoints(shape, ref_vertices): r"""The reference element is considered to be, e.g. for a 2-simplex:: F | \ | \ D----E | /| \ | / | \ A----B----C where the midpoints are ``(B, E, D)``. The same applies to other shapes and higher dimensions. :arg ref_vertices: a :class:`list` of node index :class:`tuple`\ s on :math:`[0, 2]^d`. """ from pytools import add_tuples space = mp.space_for_shape(shape, 1) orig_vertices = [ add_tuples(vt, vt) for vt in mp.node_tuples_for_space(space) ] return [rv for rv in ref_vertices if rv not in orig_vertices]
def add_tuple_to_list(ary, x): return [add_tuples(x, y) for y in ary]
def vtk_lagrange_tetrahedron_node_tuples(order): nodes = [] offset = (0, 0, 0) while order >= 0: if order == 0: nodes += [offset] break # z # ,/ # 3 # ,/|`\ # ,/ | `\ # ,/ '. `\ # ,/ | `\ # ,/ | `\ # 0-----------'.--------2---> y # `\. | ,/ # `\. | ,/ # `\. '. ,/ # `\. |/ # `1 # `. # x vertices = [(0, 0, 0), (order, 0, 0), (0, order, 0), (0, 0, order)] nodes += add_tuple_to_list(vertices, offset) if order == 1: break # add edges edge_ids = range(1, order) edges = ( # vertex 0 -> 1 [(i, 0, 0) for i in edge_ids] # vertex 1 -> 2 + [(order - i, i, 0) for i in edge_ids] # vertex 2 -> 0 + [(0, order - i, 0) for i in edge_ids] # vertex 0 -> 3 + [(0, 0, i) for i in edge_ids] # vertex 1 -> 3 + [(order - i, 0, i) for i in edge_ids] # vertex 2 -> 3 + [(0, order - i, i) for i in edge_ids]) nodes += add_tuple_to_list(edges, offset) # add faces face_ids = add_tuple_to_list( vtk_lagrange_triangle_node_tuples(order - 3), (1, 1)) faces = ( # face between vertices (0, 2, 3) [(i, 0, j) for i, j in face_ids] # face between vertices (1, 2, 3) + [(j, order - (i + j), i) for i, j in face_ids] # face between vertices (0, 1, 3) + [(0, j, i) for i, j in face_ids] # face between vertices (0, 1, 2) + [(j, i, 0) for i, j in face_ids]) nodes += add_tuple_to_list(faces, offset) order = order - 4 offset = add_tuples(offset, (1, 1, 1)) return nodes