def unit_nodes(self): dim = self.mesh_el_group.dim result = mp.equidistant_nodes(dim, self.order) dim2, nunit_nodes = result.shape assert dim2 == dim return result
def unit_nodes(self): dim = self.mesh_el_group.dim result = mp.equidistant_nodes(dim, self.order) dim2, nunit_nodes = result.shape assert dim2 == dim return result
def plot_element_values(n, nodes, values, resample_n=None, node_tuples=None, show_nodes=False): dims = len(nodes) orig_nodes = nodes orig_values = values if resample_n is not None: import modepy as mp basis = mp.simplex_onb(dims, n) fine_nodes = mp.equidistant_nodes(dims, resample_n) values = np.dot(mp.resampling_matrix(basis, fine_nodes, nodes), values) nodes = fine_nodes n = resample_n from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \ as gnitstam if dims == 1: import matplotlib.pyplot as pt pt.plot(nodes[0], values) if show_nodes: pt.plot(orig_nodes[0], orig_values, "x") pt.show() elif dims == 2: import mayavi.mlab as mlab mlab.triangular_mesh( nodes[0], nodes[1], values, submesh(list(gnitstam(n, 2)))) if show_nodes: mlab.points3d(orig_nodes[0], orig_nodes[1], orig_values, scale_factor=0.05) mlab.show() else: raise RuntimeError("unsupported dimensionality %d" % dims)
def make_group_from_vertices(vertices, vertex_indices, order): el_vertices = vertices[:, vertex_indices] el_origins = el_vertices[:, :, 0][:, :, np.newaxis] # ambient_dim, nelements, nspan_vectors spanning_vectors = ( el_vertices[:, :, 1:] - el_origins) nspan_vectors = spanning_vectors.shape[-1] dim = nspan_vectors # dim, nunit_nodes if dim <= 3: unit_nodes = mp.warp_and_blend_nodes(dim, order) else: unit_nodes = mp.equidistant_nodes(dim, order) unit_nodes_01 = 0.5 + 0.5*unit_nodes nodes = np.einsum( "si,des->dei", unit_nodes_01, spanning_vectors) + el_origins # make contiguous nodes = nodes.copy() from meshmode.mesh import SimplexElementGroup return SimplexElementGroup( order, vertex_indices, nodes, unit_nodes=unit_nodes)
def __init__(self, order, vertex_indices, nodes, element_nr_base=None, node_nr_base=None, unit_nodes=None, dim=None): """ :arg order: the maximum total degree used for interpolation. :arg nodes: ``[ambient_dim, nelements, nunit_nodes]`` The nodes are assumed to be mapped versions of *unit_nodes*. :arg unit_nodes: ``[dim, nunit_nodes]`` The unit nodes of which *nodes* is a mapped version. If unspecified, the nodes from :func:`modepy.warp_and_blend_nodes` for *dim* are assumed. These must be in unit coordinates as defined in :mod:`modepy`. :arg dim: only used if *unit_nodes* is None, to get the default unit nodes. Do not supply *element_nr_base* and *node_nr_base*, they will be automatically assigned. """ if unit_nodes is None: if dim is None: raise TypeError("'dim' must be passed " "if 'unit_nodes' is not passed") if dim <= 3: unit_nodes = mp.warp_and_blend_nodes(dim, order) else: unit_nodes = mp.equidistant_nodes(dim, order) dims = unit_nodes.shape[0] if vertex_indices is not None: if not issubclass(vertex_indices.dtype.type, np.integer): raise TypeError("vertex_indices must be integral") if vertex_indices.shape[-1] != dims+1: raise ValueError("vertex_indices has wrong number of vertices per " "element. expected: %d, got: %d" % (dims+1, vertex_indices.shape[-1])) super().__init__(order, vertex_indices, nodes, element_nr_base, node_nr_base, unit_nodes, dim)
def __init__(self, order, vertex_indices, nodes, element_nr_base=None, node_nr_base=None, unit_nodes=None, dim=None): """ :arg order: the mamximum total degree used for interpolation. :arg nodes: ``[ambient_dim, nelements, nunit_nodes]`` The nodes are assumed to be mapped versions of *unit_nodes*. :arg unit_nodes: ``[dim, nunit_nodes]`` The unit nodes of which *nodes* is a mapped version. If unspecified, the nodes from :func:`modepy.warp_and_blend_nodes` for *dim* are assumed. These must be in unit coordinates as defined in :mod:`modepy.nodes`. :arg dim: only used if *unit_nodes* is None, to get the default unit nodes. Do not supply *element_nr_base* and *node_nr_base*, they will be automatically assigned. """ if not issubclass(vertex_indices.dtype.type, np.integer): raise TypeError("vertex_indices must be integral") if unit_nodes is None: if dim is None: raise TypeError("'dim' must be passed " "if 'unit_nodes' is not passed") if dim <= 3: unit_nodes = mp.warp_and_blend_nodes(dim, order) else: unit_nodes = mp.equidistant_nodes(dim, order) dims = unit_nodes.shape[0] if vertex_indices.shape[-1] != dims+1: raise ValueError("vertex_indices has wrong number of vertices per " "element. expected: %d, got: %d" % (dims+1, vertex_indices.shape[-1])) super(SimplexElementGroup, self).__init__(order, vertex_indices, nodes, element_nr_base, node_nr_base, unit_nodes, dim)
def make_group_from_vertices(vertices, vertex_indices, order, group_cls=None, unit_nodes=None, group_factory=None): if group_factory is not None: from warnings import warn warn("'group_factory' is deprecated, use 'group_cls' instead", DeprecationWarning, stacklevel=2) if group_cls is not None: raise ValueError("cannot set both 'group_cls' and 'group_factory'") group_cls = group_factory # shape: (ambient_dim, nelements, nvertices) ambient_dim = vertices.shape[0] el_vertices = vertices[:, vertex_indices] from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup if group_cls is None: group_cls = SimplexElementGroup if issubclass(group_cls, SimplexElementGroup): if order < 1: raise ValueError("can't represent simplices with mesh order < 1") el_origins = el_vertices[:, :, 0][:, :, np.newaxis] # ambient_dim, nelements, nspan_vectors spanning_vectors = (el_vertices[:, :, 1:] - el_origins) nspan_vectors = spanning_vectors.shape[-1] dim = nspan_vectors # dim, nunit_nodes if unit_nodes is None: if dim <= 3: unit_nodes = mp.warp_and_blend_nodes(dim, order) else: unit_nodes = mp.equidistant_nodes(dim, order) unit_nodes_01 = 0.5 + 0.5 * unit_nodes nodes = np.einsum("si,des->dei", unit_nodes_01, spanning_vectors) + el_origins elif issubclass(group_cls, TensorProductElementGroup): nelements, nvertices = vertex_indices.shape dim = nvertices.bit_length() - 1 if nvertices != 2**dim: raise ValueError("invalid number of vertices for tensor-product " "elements, must be power of two") if unit_nodes is None: from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes unit_nodes = mp.tensor_product_nodes( dim, legendre_gauss_lobatto_nodes(order)) # shape: (dim, nnodes) unit_nodes_01 = 0.5 + 0.5 * unit_nodes _, nnodes = unit_nodes.shape from pytools import generate_nonnegative_integer_tuples_below as gnitb id_tuples = list(gnitb(2, dim)) assert len(id_tuples) == nvertices vdm = np.empty((nvertices, nvertices)) for i, vertex_tuple in enumerate(id_tuples): for j, func_tuple in enumerate(id_tuples): vertex_ref = np.array(vertex_tuple, dtype=np.float64) vdm[i, j] = np.prod(vertex_ref**func_tuple) # shape: (ambient_dim, nelements, nvertices) coeffs = np.empty((ambient_dim, nelements, nvertices)) for d in range(ambient_dim): coeffs[d] = la.solve(vdm, el_vertices[d].T).T vdm_nodes = np.zeros((nnodes, nvertices)) for j, func_tuple in enumerate(id_tuples): vdm_nodes[:, j] = np.prod(unit_nodes_01**np.array(func_tuple).reshape( -1, 1), axis=0) nodes = np.einsum("ij,dej->dei", vdm_nodes, coeffs) else: raise ValueError(f"unsupported value for 'group_cls': {group_cls}") # make contiguous nodes = nodes.copy() return group_cls(order, vertex_indices, nodes, unit_nodes=unit_nodes)
def make_group_from_vertices(vertices, vertex_indices, order, group_factory=None): # shape: (dim, nelements, nvertices) el_vertices = vertices[:, vertex_indices] from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup if group_factory is None: group_factory = SimplexElementGroup if issubclass(group_factory, SimplexElementGroup): el_origins = el_vertices[:, :, 0][:, :, np.newaxis] # ambient_dim, nelements, nspan_vectors spanning_vectors = ( el_vertices[:, :, 1:] - el_origins) nspan_vectors = spanning_vectors.shape[-1] dim = nspan_vectors # dim, nunit_nodes if dim <= 3: unit_nodes = mp.warp_and_blend_nodes(dim, order) else: unit_nodes = mp.equidistant_nodes(dim, order) unit_nodes_01 = 0.5 + 0.5*unit_nodes nodes = np.einsum( "si,des->dei", unit_nodes_01, spanning_vectors) + el_origins elif issubclass(group_factory, TensorProductElementGroup): nelements, nvertices = vertex_indices.shape dim = 0 while True: if nvertices == 2**dim: break if nvertices < 2**dim: raise ValueError("invalid number of vertices for tensor-product " "elements, must be power of two") dim += 1 from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes from modepy.nodes import tensor_product_nodes unit_nodes = tensor_product_nodes(dim, legendre_gauss_lobatto_nodes(order)) # shape: (dim, nnodes) unit_nodes_01 = 0.5 + 0.5*unit_nodes _, nnodes = unit_nodes.shape from pytools import generate_nonnegative_integer_tuples_below as gnitb id_tuples = list(gnitb(2, dim)) assert len(id_tuples) == nvertices vdm = np.empty((nvertices, nvertices)) for i, vertex_tuple in enumerate(id_tuples): for j, func_tuple in enumerate(id_tuples): vertex_ref = np.array(vertex_tuple, dtype=np.float64) vdm[i, j] = np.prod(vertex_ref**func_tuple) # shape: (dim, nelements, nvertices) coeffs = np.empty((dim, nelements, nvertices)) for d in range(dim): coeffs[d] = la.solve(vdm, el_vertices[d].T).T vdm_nodes = np.zeros((nnodes, nvertices)) for j, func_tuple in enumerate(id_tuples): vdm_nodes[:, j] = np.prod( unit_nodes_01 ** np.array(func_tuple).reshape(-1, 1), axis=0) nodes = np.einsum("ij,dej->dei", vdm_nodes, coeffs) else: raise ValueError("unsupported value for 'group_factory': %s" % group_factory) # make contiguous nodes = nodes.copy() return group_factory( order, vertex_indices, nodes, unit_nodes=unit_nodes)
def make_group_from_vertices(vertices, vertex_indices, order, group_factory=None): # shape: (dim, nelements, nvertices) el_vertices = vertices[:, vertex_indices] from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup if group_factory is None: group_factory = SimplexElementGroup if issubclass(group_factory, SimplexElementGroup): el_origins = el_vertices[:, :, 0][:, :, np.newaxis] # ambient_dim, nelements, nspan_vectors spanning_vectors = ( el_vertices[:, :, 1:] - el_origins) nspan_vectors = spanning_vectors.shape[-1] dim = nspan_vectors # dim, nunit_nodes if dim <= 3: unit_nodes = mp.warp_and_blend_nodes(dim, order) else: unit_nodes = mp.equidistant_nodes(dim, order) unit_nodes_01 = 0.5 + 0.5*unit_nodes nodes = np.einsum( "si,des->dei", unit_nodes_01, spanning_vectors) + el_origins elif issubclass(group_factory, TensorProductElementGroup): nelements, nvertices = vertex_indices.shape dim = 0 while True: if nvertices == 2**dim: break if nvertices < 2**dim: raise ValueError("invalid number of vertices for tensor-product " "elements, must be power of two") dim += 1 from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes from modepy.nodes import tensor_product_nodes unit_nodes = tensor_product_nodes(dim, legendre_gauss_lobatto_nodes(order)) # shape: (dim, nnodes) unit_nodes_01 = 0.5 + 0.5*unit_nodes _, nnodes = unit_nodes.shape from pytools import generate_nonnegative_integer_tuples_below as gnitb id_tuples = list(gnitb(2, dim)) assert len(id_tuples) == nvertices vdm = np.empty((nvertices, nvertices)) for i, vertex_tuple in enumerate(id_tuples): for j, func_tuple in enumerate(id_tuples): vertex_ref = np.array(vertex_tuple, dtype=np.float64) vdm[i, j] = np.prod(vertex_ref**func_tuple) # shape: (dim, nelements, nvertices) coeffs = np.empty((dim, nelements, nvertices)) for d in range(dim): coeffs[d] = la.solve(vdm, el_vertices[d].T).T vdm_nodes = np.zeros((nnodes, nvertices)) for j, func_tuple in enumerate(id_tuples): vdm_nodes[:, j] = np.prod( unit_nodes_01 ** np.array(func_tuple).reshape(-1, 1), axis=0) nodes = np.einsum("ij,dej->dei", vdm_nodes, coeffs) else: raise ValueError("unsupported value for 'group_factory': %s" % group_factory) # make contiguous nodes = nodes.copy() return group_factory( order, vertex_indices, nodes, unit_nodes=unit_nodes)