def find_points_in_element(self, el, el_tolerance): from pyrticle._internal import ElementOnGrid eog = ElementOnGrid() eog.element_number = el.id points = self.backend.find_points_in_element( eog, el_tolerance * la.norm(el.map.matrix, 2)) return eog, list(points)
def prepare_with_brick_interpolation(self): class TensorProductLegendreBasisFunc: def __init__(self, n): from hedge.polynomial import LegendreFunction self.funcs = [LegendreFunction(n_i) for n_i in n] def __call__(self, x): result = 1 for f_i, x_i in zip(self.funcs, x): result *= f_i(x_i) return result def make_legendre_basis(dimensions): from pytools import generate_nonnegative_integer_tuples_below return [ TensorProductLegendreBasisFunc(n) for n in generate_nonnegative_integer_tuples_below(dimensions) ] discr = self.method.discretization backend = self.backend backend.elements_on_grid.reserve( sum(len(eg.members) for eg in discr.element_groups)) from pyrticle._internal import ElementOnGrid, BoxFloat total_points = 0 # Iterate over all elements for eg in discr.element_groups: ldis = eg.local_discretization for el in eg.members: el_bbox = BoxFloat(*el.bounding_box(discr.mesh.points)) scaled_tolerance = self.el_tolerance * la.norm( el.map.matrix, 2) el_bbox.lower -= scaled_tolerance el_bbox.upper += scaled_tolerance # For each brick, find all element nodes that lie in it for brk in backend.bricks: eog = ElementOnGrid() eog.element_number = el.id brk_bbox = brk.bounding_box() brk_and_el = brk_bbox.intersect(el_bbox) if brk_and_el.is_empty(): continue el_nodes = [] el_node_indices = [] el_slice = discr.find_el_range(el.id) el_length = el_slice.stop - el_slice.start if brk_and_el == el_bbox: # whole element in brick? fantastic. el_nodes = discr.nodes[el_slice] el_node_indices = range(el_length) else: # no? go through the nodes one by one. for i, node in enumerate(discr.nodes[el_slice]): # this containment check has to be exact, # we positively cannot have nodes belong to # two bricks if brk_bbox.contains(node, threshold=0): el_nodes.append(node) el_node_indices.append(i) idx_range = brk.index_range(brk_and_el) lb = make_legendre_basis(idx_range.upper - idx_range.lower) from hedge.polynomial import generic_vandermonde brk_and_el_points = [ brk.point(c) for c in self.iterator_type(brk, idx_range) ] svdm = generic_vandermonde(points=brk_and_el_points, functions=lb) total_points += len(brk_and_el_points) mixed_vdm_pre = generic_vandermonde(points=el_nodes, functions=lb) if len(el_nodes) < el_length: mixed_vdm = numpy.zeros((el_length, len(lb)), dtype=float) for i, vdm_row in enumerate(mixed_vdm_pre): mixed_vdm[el_node_indices[i]] = vdm_row else: mixed_vdm = mixed_vdm_pre from hedge.tools import leftsolve eog.interpolation_matrix = numpy.asarray(leftsolve( svdm, mixed_vdm), order="Fortran") #print eog.interpolation_matrix.shape #raw_input() eog.grid_nodes.extend( brk.index(c) for c in self.iterator_type(brk, idx_range)) eog.weight_factors = numpy.ones((len(eog.grid_nodes), ), dtype=numpy.float64) backend.elements_on_grid.append(eog) # we don't need no stinkin' extra points backend.extra_point_brick_starts.extend([0] * (len(backend.bricks) + 1)) # stats self.generate_point_statistics(0)
def prepare_with_brick_interpolation(self): class TensorProductLegendreBasisFunc: def __init__(self, n): from hedge.polynomial import LegendreFunction self.funcs = [LegendreFunction(n_i) for n_i in n] def __call__(self, x): result = 1 for f_i, x_i in zip(self.funcs, x): result *= f_i(x_i) return result def make_legendre_basis(dimensions): from pytools import generate_nonnegative_integer_tuples_below return [TensorProductLegendreBasisFunc(n) for n in generate_nonnegative_integer_tuples_below(dimensions)] discr = self.method.discretization backend = self.backend backend.elements_on_grid.reserve( sum(len(eg.members) for eg in discr.element_groups)) from pyrticle._internal import ElementOnGrid, BoxFloat total_points = 0 # Iterate over all elements for eg in discr.element_groups: ldis = eg.local_discretization for el in eg.members: el_bbox = BoxFloat(*el.bounding_box(discr.mesh.points)) scaled_tolerance = self.el_tolerance * la.norm(el.map.matrix, 2) el_bbox.lower -= scaled_tolerance el_bbox.upper += scaled_tolerance # For each brick, find all element nodes that lie in it for brk in backend.bricks: eog = ElementOnGrid() eog.element_number = el.id brk_bbox = brk.bounding_box() brk_and_el = brk_bbox.intersect(el_bbox) if brk_and_el.is_empty(): continue el_nodes = [] el_node_indices = [] el_slice = discr.find_el_range(el.id) el_length = el_slice.stop-el_slice.start if brk_and_el == el_bbox: # whole element in brick? fantastic. el_nodes = discr.nodes[el_slice] el_node_indices = range(el_length) else: # no? go through the nodes one by one. for i, node in enumerate(discr.nodes[el_slice]): # this containment check has to be exact, # we positively cannot have nodes belong to # two bricks if brk_bbox.contains(node, threshold=0): el_nodes.append(node) el_node_indices.append(i) idx_range = brk.index_range(brk_and_el) lb = make_legendre_basis(idx_range.upper-idx_range.lower) from hedge.polynomial import generic_vandermonde brk_and_el_points = [brk.point(c) for c in self.iterator_type(brk, idx_range)] svdm = generic_vandermonde( points=brk_and_el_points, functions=lb) total_points += len(brk_and_el_points) mixed_vdm_pre = generic_vandermonde( points=el_nodes, functions=lb) if len(el_nodes) < el_length: mixed_vdm = numpy.zeros((el_length, len(lb)), dtype=float) for i, vdm_row in enumerate(mixed_vdm_pre): mixed_vdm[el_node_indices[i]] = vdm_row else: mixed_vdm = mixed_vdm_pre from hedge.tools import leftsolve eog.interpolation_matrix = numpy.asarray( leftsolve(svdm, mixed_vdm), order="Fortran") #print eog.interpolation_matrix.shape #raw_input() eog.grid_nodes.extend(brk.index(c) for c in self.iterator_type(brk, idx_range)) eog.weight_factors = numpy.ones( (len(eog.grid_nodes),), dtype=numpy.float64) backend.elements_on_grid.append(eog) # we don't need no stinkin' extra points backend.extra_point_brick_starts.extend([0]*(len(backend.bricks)+1)) # stats self.generate_point_statistics(0)