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 _vis_connectivity(self): """ :return: an array of shape ``(vis_discr.nelements,nsubelements,primitive_element_size)`` """ # Assume that we're using modepy's default node ordering. from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \ as gnitstam, single_valued vis_order = single_valued(group.order for group in self.vis_discr.groups) node_tuples = list(gnitstam(vis_order, self.vis_discr.dim)) from modepy.tools import submesh el_connectivity = np.array(submesh(node_tuples), dtype=np.intp) nelements = sum(group.nelements for group in self.vis_discr.groups) vis_connectivity = np.empty((nelements, ) + el_connectivity.shape, dtype=np.intp) el_nr_base = 0 for group in self.vis_discr.groups: assert len(node_tuples) == group.nunit_nodes vis_connectivity[el_nr_base:el_nr_base + group.nelements] = ( np.arange(el_nr_base * group.nunit_nodes, (el_nr_base + group.nelements) * group.nunit_nodes, group.nunit_nodes)[:, np.newaxis, np.newaxis] + el_connectivity) el_nr_base += group.nelements return vis_connectivity
def _vis_connectivity(self): """ :return: an array of shape ``(vis_discr.nelements,nsubelements,primitive_element_size)`` """ # Assume that we're using modepy's default node ordering. from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \ as gnitstam, single_valued vis_order = single_valued( group.order for group in self.vis_discr.groups) node_tuples = list(gnitstam(vis_order, self.vis_discr.dim)) from modepy.tools import submesh el_connectivity = np.array( submesh(node_tuples), dtype=np.intp) nelements = sum(group.nelements for group in self.vis_discr.groups) vis_connectivity = np.empty( (nelements,) + el_connectivity.shape, dtype=np.intp) el_nr_base = 0 for group in self.vis_discr.groups: assert len(node_tuples) == group.nunit_nodes vis_connectivity[el_nr_base:el_nr_base+group.nelements] = ( np.arange( el_nr_base*group.nunit_nodes, (el_nr_base+group.nelements)*group.nunit_nodes, group.nunit_nodes )[:, np.newaxis, np.newaxis] + el_connectivity) el_nr_base += group.nelements return vis_connectivity
def estimate_lebesgue_constant(n, nodes, visualize=False): """Estimate the `Lebesgue constant <https://en.wikipedia.org/wiki/Lebesgue_constant_(interpolation)>`_ of the *nodes* at polynomial order *n*. :arg nodes: an array of shape *(dims, nnodes)* as returned by :func:`modepy.warp_and_blend_nodes`. :arg visualize: visualize the function that gives rise to the returned Lebesgue constant. (2D only for now) :return: the Lebesgue constant, a scalar .. versionadded:: 2013.2 """ from modepy.matrices import vandermonde from modepy.modes import simplex_onb dims = len(nodes) basis = simplex_onb(dims, n) vdm = vandermonde(basis, nodes) from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \ as gnitstam huge_n = 30*n equi_node_tuples = list(gnitstam(huge_n, dims)) tons_of_equi_nodes = ( np.array(equi_node_tuples, dtype=np.float64) / huge_n * 2 - 1).T eq_vdm = vandermonde(basis, tons_of_equi_nodes) eq_to_out = la.solve(vdm.T, eq_vdm.T).T lebesgue_worst = np.sum(np.abs(eq_to_out), axis=1) lebesgue_constant = np.max(lebesgue_worst) if visualize: print("Lebesgue constant: %g" % lebesgue_constant) from modepy.tools import submesh import mayavi.mlab as mlab mlab.figure(bgcolor=(1, 1, 1)) mlab.triangular_mesh( tons_of_equi_nodes[0], tons_of_equi_nodes[1], lebesgue_worst / lebesgue_constant, submesh(equi_node_tuples)) x, y = np.mgrid[-1:1:20j, -1:1:20j] mlab.mesh(x, y, 0*x, representation="wireframe", color=(0.4, 0.4, 0.4), line_width=0.6) mlab.show() return lebesgue_constant
def _vis_connectivity(self): """ :return: a list of :class:`_VisConnectivityGroup` instances. """ # Assume that we're using modepy's default node ordering. from pytools import ( generate_nonnegative_integer_tuples_summing_to_at_most as gnitstam, generate_nonnegative_integer_tuples_below as gnitb) from meshmode.mesh import TensorProductElementGroup, SimplexElementGroup result = [] from pyvisfile.vtk import ( VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VTK_QUAD, VTK_HEXAHEDRON) subel_nr_base = 0 for group in self.vis_discr.groups: if isinstance(group.mesh_el_group, SimplexElementGroup): node_tuples = list(gnitstam(group.order, group.dim)) from modepy.tools import submesh el_connectivity = np.array( submesh(node_tuples), dtype=np.intp) vtk_cell_type = { 1: VTK_LINE, 2: VTK_TRIANGLE, 3: VTK_TETRA, }[group.dim] elif isinstance(group.mesh_el_group, TensorProductElementGroup): node_tuples = list(gnitb(group.order+1, group.dim)) node_tuple_to_index = dict( (nt, i) for i, nt in enumerate(node_tuples)) def add_tuple(a, b): return tuple(ai+bi for ai, bi in zip(a, b)) 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), ] }[group.dim] el_connectivity = np.array([ [ node_tuple_to_index[add_tuple(origin, offset)] for offset in el_offsets] for origin in gnitb(group.order, group.dim)]) vtk_cell_type = { 1: VTK_LINE, 2: VTK_QUAD, 3: VTK_HEXAHEDRON, }[group.dim] else: raise NotImplementedError("visualization for element groups " "of type '%s'" % type(group.mesh_el_group).__name__) assert len(node_tuples) == group.nunit_nodes vis_connectivity = ( group.node_nr_base + np.arange( 0, group.nelements*group.nunit_nodes, group.nunit_nodes )[:, np.newaxis, np.newaxis] + el_connectivity).astype(np.intp) vgrp = _VisConnectivityGroup( vis_connectivity=vis_connectivity, vtk_cell_type=vtk_cell_type, subelement_nr_base=subel_nr_base) result.append(vgrp) subel_nr_base += vgrp.nsubelements return result
from __future__ import absolute_import import numpy as np from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \ as gnitstam from six.moves import zip # prepare plot and eval nodes on triangle dims = 2 node_n = 40 node_tuples = list(gnitstam(node_n, dims)) plot_nodes = np.array(node_tuples, dtype=np.float64) / node_n eval_nodes = 2*(plot_nodes - 0.5).T # get triangle submesh from modepy.tools import submesh tri_subtriangles = np.array(submesh(node_tuples)) # evaluate each basis function, build global tri mesh node_count = 0 all_nodes = [] all_triangles = [] all_values = [] from modepy.modes import simplex_onb p = 3 stretch_factor = 1.5 for (i, j), basis_func in zip( gnitstam(p, dims), simplex_onb(dims, p),
import numpy as np from pytools import generate_nonnegative_integer_tuples_summing_to_at_most \ as gnitstam # prepare plot and eval nodes on triangle dims = 2 node_n = 40 node_tuples = list(gnitstam(node_n, dims)) plot_nodes = np.array(node_tuples, dtype=np.float64) / node_n eval_nodes = 2 * (plot_nodes - 0.5).T # get triangle submesh from modepy.tools import submesh tri_subtriangles = np.array(submesh(node_tuples)) # evaluate each basis function, build global tri mesh node_count = 0 all_nodes = [] all_triangles = [] all_values = [] from modepy.modes import simplex_onb p = 3 stretch_factor = 1.5 for (i, j), basis_func in zip( gnitstam(p, dims), simplex_onb(dims, p), ):
def _vis_connectivity(self): """ :return: a list of :class:`_VisConnectivityGroup` instances. """ # Assume that we're using modepy's default node ordering. from pytools import ( generate_nonnegative_integer_tuples_summing_to_at_most as gnitstam, generate_nonnegative_integer_tuples_below as gnitb) from meshmode.mesh import TensorProductElementGroup, SimplexElementGroup result = [] from pyvisfile.vtk import (VTK_LINE, VTK_TRIANGLE, VTK_TETRA, VTK_QUAD, VTK_HEXAHEDRON) subel_nr_base = 0 for group in self.vis_discr.groups: if isinstance(group.mesh_el_group, SimplexElementGroup): node_tuples = list(gnitstam(group.order, group.dim)) from modepy.tools import submesh el_connectivity = np.array(submesh(node_tuples), dtype=np.intp) vtk_cell_type = { 1: VTK_LINE, 2: VTK_TRIANGLE, 3: VTK_TETRA, }[group.dim] elif isinstance(group.mesh_el_group, TensorProductElementGroup): node_tuples = list(gnitb(group.order + 1, group.dim)) node_tuple_to_index = dict( (nt, i) for i, nt in enumerate(node_tuples)) def add_tuple(a, b): return tuple(ai + bi for ai, bi in zip(a, b)) 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), ] }[group.dim] el_connectivity = np.array([[ node_tuple_to_index[add_tuple(origin, offset)] for offset in el_offsets ] for origin in gnitb(group.order, group.dim)]) vtk_cell_type = { 1: VTK_LINE, 2: VTK_QUAD, 3: VTK_HEXAHEDRON, }[group.dim] else: raise NotImplementedError("visualization for element groups " "of type '%s'" % type(group.mesh_el_group).__name__) assert len(node_tuples) == group.nunit_nodes vis_connectivity = ( group.node_nr_base + np.arange(0, group.nelements * group.nunit_nodes, group.nunit_nodes)[:, np.newaxis, np.newaxis] + el_connectivity).astype(np.intp) vgrp = _VisConnectivityGroup(vis_connectivity=vis_connectivity, vtk_cell_type=vtk_cell_type, subelement_nr_base=subel_nr_base) result.append(vgrp) subel_nr_base += vgrp.nsubelements return result