def test_reconstruction_symmetry(self, u): u = np.array(u, dtype=float) def flip(x): return x[::-1] def flip_staggered(x): return flip(np.roll(x, +1)) left_direct = weno.reconstruct_left(u) left_flipped = flip_staggered(weno.reconstruct_right(flip(u))) np.testing.assert_allclose(left_direct, left_flipped, atol=1e-6) right_direct = weno.reconstruct_right(u) right_flipped = flip_staggered(weno.reconstruct_left(flip(u))) np.testing.assert_allclose(right_direct, right_flipped, atol=1e-6)
def test_batched(self): u_batched = np.array([[0, 0, 0, 1, 2, 3, 4], [0, 0, 1, 2, 3, 4, 5]]) expected_left = np.stack([ weno.reconstruct_left(u_batched[0]), weno.reconstruct_left(u_batched[1]) ]) expected_right = np.stack([ weno.reconstruct_right(u_batched[0]), weno.reconstruct_right(u_batched[1]) ]) actual_left = weno.reconstruct_left(u_batched) actual_right = weno.reconstruct_right(u_batched) np.testing.assert_allclose(actual_left, expected_left) np.testing.assert_allclose(actual_right, expected_right)
def __call__(self, t: float, y: np.ndarray) -> np.ndarray: space_derivatives = self.poly_diff.calculate_space_derivatives(y) # replace u^- and u^+ with WENO reconstructions assert 'u_minus' in space_derivatives and 'u_plus' in space_derivatives space_derivatives['u_minus'] = np.roll(weno.reconstruct_left(y), 1) space_derivatives['u_plus'] = np.roll(weno.reconstruct_right(y), 1) time_derivative = self.equation.equation_of_motion(y, space_derivatives) return self.equation.finalize_time_derivative(t, time_derivative)
def baseline_space_derivatives(inputs: tf.Tensor, equation: equations.Equation, accuracy_order: int = None) -> tf.Tensor: """Calculate spatial derivatives using a baseline metohd.""" assert_consistent_solution(equation, inputs) spatial_derivatives_list = [] for derivative_name, derivative_order in zip(equation.DERIVATIVE_NAMES, equation.DERIVATIVE_ORDERS): if accuracy_order is None: # use the best baseline method assert equation.exact_type() is type(equation) if equation.EXACT_METHOD is equations.ExactMethod.POLYNOMIAL: grid = (0.5 + np.arange(-3, 3)) * equation.grid.solution_dx method = FINITE_VOL if equation.CONSERVATIVE else FINITE_DIFF derivative = polynomials.reconstruct(inputs, grid, method, derivative_order) elif equation.EXACT_METHOD is equations.ExactMethod.SPECTRAL: derivative = duckarray.spectral_derivative( inputs, derivative_order, equation.grid.period) elif equation.EXACT_METHOD is equations.ExactMethod.WENO: if derivative_name == 'u_minus': derivative = duckarray.roll(weno.reconstruct_left(inputs), 1, axis=-1) elif derivative_name == 'u_plus': derivative = duckarray.roll(weno.reconstruct_right(inputs), 1, axis=-1) else: assert derivative_name == 'u_x' grid = polynomials.regular_grid( grid_offset=equation.GRID_OFFSET, derivative_order=derivative_order, accuracy_order=3, dx=equation.grid.solution_dx) method = FINITE_VOL if equation.CONSERVATIVE else FINITE_DIFF derivative = polynomials.reconstruct( inputs, grid, method, derivative_order) else: # explicit accuracy order provided assert type(equation) not in equations.FLUX_EQUATION_TYPES grid = polynomials.regular_grid(grid_offset=equation.GRID_OFFSET, derivative_order=derivative_order, accuracy_order=accuracy_order, dx=equation.grid.solution_dx) method = FINITE_VOL if equation.CONSERVATIVE else FINITE_DIFF derivative = polynomials.reconstruct(inputs, grid, method, derivative_order) spatial_derivatives_list.append(derivative) return tf.stack(spatial_derivatives_list, axis=-1)
def test_reconstruct_right_discontinuity(self): u = np.array([0, 1, 2, 3, 4, -4, -3, -2, -1]) actual = weno.reconstruct_right(u) expected = [0.5, 1.5, 2.5, 3.5, -4.5, -3.5, -2.5, -1.5, -0.5] np.testing.assert_allclose(actual, expected, atol=0.005)