def warp_factor(n, output_nodes, scaled=True): """Compute warp function at order *n* and evaluate it at the nodes *output_nodes*. """ from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes warped_nodes = legendre_gauss_lobatto_nodes(n) equi_nodes = np.linspace(-1, 1, n+1) from modepy.matrices import vandermonde from modepy.modes import simplex_onb basis = simplex_onb(1, n) Veq = vandermonde(basis, equi_nodes) # noqa # create interpolator from equi_nodes to output_nodes eq_to_out = la.solve(Veq.T, vandermonde(basis, output_nodes).T).T # compute warp factor warp = np.dot(eq_to_out, warped_nodes - equi_nodes) if scaled: zerof = (abs(output_nodes) < 1.0-1.0e-10) sf = 1.0 - (zerof*output_nodes)**2 warp = warp/sf + warp*(zerof-1) return warp
def warp_factor(n, output_nodes, scaled=True): """Compute warp function at order *n* and evaluate it at the nodes *output_nodes*. """ from modepy.quadrature.jacobi_gauss import legendre_gauss_lobatto_nodes warped_nodes = legendre_gauss_lobatto_nodes(n) equi_nodes = np.linspace(-1, 1, n + 1) from modepy.matrices import vandermonde from modepy.modes import simplex_onb basis = simplex_onb(1, n) Veq = vandermonde(basis, equi_nodes) # noqa # create interpolator from equi_nodes to output_nodes eq_to_out = la.solve(Veq.T, vandermonde(basis, output_nodes).T).T # compute warp factor warp = np.dot(eq_to_out, warped_nodes - equi_nodes) if scaled: zerof = (abs(output_nodes) < 1.0 - 1.0e-10) sf = 1.0 - (zerof * output_nodes)**2 warp = warp / sf + warp * (zerof - 1) return warp
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 test_pkdo_orthogonality(dims, order, ebound): """Test orthogonality of simplicial bases using Grundmann-Moeller cubature.""" from modepy.quadrature.grundmann_moeller import GrundmannMoellerSimplexQuadrature from modepy.modes import simplex_onb cub = GrundmannMoellerSimplexQuadrature(order, dims) basis = simplex_onb(dims, order) maxerr = 0 for i, f in enumerate(basis): for j, g in enumerate(basis): if i == j: true_result = 1 else: true_result = 0 result = cub(lambda x: f(x)*g(x)) err = abs(result-true_result) print((maxerr, err)) maxerr = max(maxerr, err) if err > ebound: print("bad", order, i, j, err) assert err < ebound
def test_pkdo_orthogonality(dims, order, ebound): """Test orthogonality of simplicial bases using Grundmann-Moeller cubature.""" from modepy.quadrature.grundmann_moeller import GrundmannMoellerSimplexQuadrature from modepy.modes import simplex_onb cub = GrundmannMoellerSimplexQuadrature(order, dims) basis = simplex_onb(dims, order) maxerr = 0 for i, f in enumerate(basis): for j, g in enumerate(basis): if i == j: true_result = 1 else: true_result = 0 result = cub(lambda x: f(x) * g(x)) err = abs(result - true_result) print((maxerr, err)) maxerr = max(maxerr, err) if err > ebound: print("bad", order, i, j, err) assert err < ebound
def warp_and_refine_until_resolved(unwarped_mesh_or_refiner, warp_callable, est_rel_interp_tolerance): """Given an original ("unwarped") :class:`meshmode.mesh.Mesh` and a warping function *warp_callable* that takes and returns a mesh and a tolerance to which the mesh should be resolved by the mapping polynomials, this function will iteratively refine the *unwarped_mesh* until relative interpolation error estimates on the warped version are smaller than *est_rel_interp_tolerance* on each element. :returns: The refined, unwarped mesh. .. versionadded:: 2018.1 """ from modepy.modes import simplex_onb from modepy.matrices import vandermonde from modepy.modal_decay import simplex_interp_error_coefficient_estimator_matrix from meshmode.mesh.refinement import Refiner, RefinerWithoutAdjacency if isinstance(unwarped_mesh_or_refiner, (Refiner, RefinerWithoutAdjacency)): refiner = unwarped_mesh_or_refiner unwarped_mesh = refiner.get_current_mesh() else: unwarped_mesh = unwarped_mesh_or_refiner refiner = Refiner(unwarped_mesh) iteration = 0 while True: refine_flags = np.zeros(unwarped_mesh.nelements, dtype=bool) warped_mesh = warp_callable(unwarped_mesh) # test whether there are invalid values in warped mesh if not np.isfinite(warped_mesh.vertices).all(): raise FloatingPointError( "Warped mesh contains non-finite vertices " "(NaN or Inf)") for group in warped_mesh.groups: if not np.isfinite(group.nodes).all(): raise FloatingPointError( "Warped mesh contains non-finite nodes " "(NaN or Inf)") for egrp in warped_mesh.groups: dim, nunit_nodes = egrp.unit_nodes.shape interp_err_est_mat = simplex_interp_error_coefficient_estimator_matrix( egrp.unit_nodes, egrp.order, n_tail_orders=1 if warped_mesh.dim > 1 else 2) vdm_inv = la.inv( vandermonde(simplex_onb(dim, egrp.order), egrp.unit_nodes)) mapping_coeffs = np.einsum("ij,dej->dei", vdm_inv, egrp.nodes) mapping_norm_2 = np.sqrt(np.sum(mapping_coeffs**2, axis=-1)) interp_error_coeffs = np.einsum("ij,dej->dei", interp_err_est_mat, egrp.nodes) interp_error_norm_2 = np.sqrt( np.sum(interp_error_coeffs**2, axis=-1)) # max over dimensions est_rel_interp_error = np.max(interp_error_norm_2 / mapping_norm_2, axis=0) refine_flags[ egrp.element_nr_base: egrp.element_nr_base+egrp.nelements] = \ est_rel_interp_error > est_rel_interp_tolerance nrefined_elements = np.sum(refine_flags.astype(np.int32)) if nrefined_elements == 0: break logger.info( "warp_and_refine_until_resolved: " "iteration %d -> splitting %d/%d elements", iteration, nrefined_elements, unwarped_mesh.nelements) unwarped_mesh = refiner.refine(refine_flags) iteration += 1 return unwarped_mesh
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), ): all_nodes.append(plot_nodes + [stretch_factor*i, stretch_factor*j]) all_triangles.append(tri_subtriangles + node_count) all_values.append(basis_func(eval_nodes)) node_count += len(plot_nodes) all_nodes = np.vstack(all_nodes) all_triangles = np.vstack(all_triangles) all_values = np.hstack(all_values) # plot import mayavi.mlab as mlab fig = mlab.figure(bgcolor=(1, 1, 1)) mlab.triangular_mesh(
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), ): all_nodes.append(plot_nodes + [stretch_factor * i, stretch_factor * j]) all_triangles.append(tri_subtriangles + node_count) all_values.append(basis_func(eval_nodes)) node_count += len(plot_nodes) all_nodes = np.vstack(all_nodes) all_triangles = np.vstack(all_triangles) all_values = np.hstack(all_values) # plot import mayavi.mlab as mlab fig = mlab.figure(bgcolor=(1, 1, 1)) mlab.triangular_mesh(all_nodes[:, 0], all_nodes[:, 1], 0.2 * all_values,
def warp_and_refine_until_resolved( unwarped_mesh_or_refiner, warp_callable, est_rel_interp_tolerance): """Given an original ("un-warped") :class:`meshmode.mesh.Mesh` and a warping function *warp_callable* that takes and returns a mesh and a tolerance to which the mesh should be resolved by the mapping polynomials, this function will iteratively refine the *unwarped_mesh* until relative interpolation error estimates on the warped version are smaller than *est_rel_interp_tolerance* on each element. :returns: The refined, un-warped mesh. .. versionadded:: 2018.1 """ from modepy.modes import simplex_onb from modepy.matrices import vandermonde from modepy.modal_decay import simplex_interp_error_coefficient_estimator_matrix from meshmode.mesh.refinement import Refiner, RefinerWithoutAdjacency if isinstance(unwarped_mesh_or_refiner, (Refiner, RefinerWithoutAdjacency)): refiner = unwarped_mesh_or_refiner unwarped_mesh = refiner.get_current_mesh() else: unwarped_mesh = unwarped_mesh_or_refiner refiner = Refiner(unwarped_mesh) iteration = 0 while True: refine_flags = np.zeros(unwarped_mesh.nelements, dtype=np.bool) warped_mesh = warp_callable(unwarped_mesh) # test whether there are invalid values in warped mesh if not np.isfinite(warped_mesh.vertices).all(): raise FloatingPointError("Warped mesh contains non-finite vertices " "(NaN or Inf)") for group in warped_mesh.groups: if not np.isfinite(group.nodes).all(): raise FloatingPointError("Warped mesh contains non-finite nodes " "(NaN or Inf)") for egrp in warped_mesh.groups: dim, nunit_nodes = egrp.unit_nodes.shape interp_err_est_mat = simplex_interp_error_coefficient_estimator_matrix( egrp.unit_nodes, egrp.order, n_tail_orders=1 if warped_mesh.dim > 1 else 2) vdm_inv = la.inv( vandermonde(simplex_onb(dim, egrp.order), egrp.unit_nodes)) mapping_coeffs = np.einsum("ij,dej->dei", vdm_inv, egrp.nodes) mapping_norm_2 = np.sqrt(np.sum(mapping_coeffs**2, axis=-1)) interp_error_coeffs = np.einsum( "ij,dej->dei", interp_err_est_mat, egrp.nodes) interp_error_norm_2 = np.sqrt(np.sum(interp_error_coeffs**2, axis=-1)) # max over dimensions est_rel_interp_error = np.max(interp_error_norm_2/mapping_norm_2, axis=0) refine_flags[ egrp.element_nr_base: egrp.element_nr_base+egrp.nelements] = \ est_rel_interp_error > est_rel_interp_tolerance nrefined_elements = np.sum(refine_flags.astype(np.int32)) if nrefined_elements == 0: break logger.info("warp_and_refine_until_resolved: " "iteration %d -> splitting %d/%d elements", iteration, nrefined_elements, unwarped_mesh.nelements) unwarped_mesh = refiner.refine(refine_flags) iteration += 1 return unwarped_mesh