def test_apply_on_boundary_which_boundaries(): # 1d arr = np.ones(5) which = ((True, False), ) result = apply_on_boundary(arr, lambda x: x * 2, which_boundaries=which) assert all_equal(result, [2, 1, 1, 1, 1]) # 2d arr = np.ones((3, 5)) which = ((True, False), True) result = apply_on_boundary(arr, lambda x: x * 2, which_boundaries=which) assert all_equal(result, [[2, 2, 2, 2, 2], [2, 1, 1, 1, 2], [2, 1, 1, 1, 2]])
def test_apply_on_boundary_default(): # 1d arr = np.ones(5) result = apply_on_boundary(arr, lambda x: x * 2) assert all_equal(arr, [1, 1, 1, 1, 1]) assert all_equal(result, [2, 1, 1, 1, 2]) # 3d arr = np.ones((3, 4, 5)) result = apply_on_boundary(arr, lambda x: x * 2) true_arr = 2 * np.ones((3, 4, 5)) true_arr[1:-1, 1:-1, 1:-1] = 1 assert all_equal(result, true_arr)
def _call(self, x, out): """Mask ``x`` and store the result in ``out`` if given.""" # Find the indices of the mask min and max. The floating point # versions are also required for the linear transition. idx_min_flt = np.array(self.domain.partition.index(self.min_pt, floating=True), ndmin=1) idx_max_flt = np.array(self.domain.partition.index(self.max_pt, floating=True), ndmin=1) # To deal with coinciding boundaries we introduce an epsilon tolerance epsilon = 1e-6 idx_min = np.floor(idx_min_flt - epsilon).astype(int) idx_max = np.ceil(idx_max_flt + epsilon).astype(int) def coeffs(d): return (1.0 - (idx_min_flt[d] - idx_min[d]), 1.0 - (idx_max[d] - idx_max_flt[d])) # Need an extra level of indirection in order to capture `d` inside # the lambda expressions def fn_pair(d): return (lambda x: x * coeffs(d)[0], lambda x: x * coeffs(d)[1]) boundary_scale_fns = [fn_pair(d) for d in range(x.ndim)] slc = tuple(slice(imin, imax) for imin, imax in zip(idx_min, idx_max)) slc_inner = tuple( slice(imin + 1, imax - 1) for imin, imax in zip(idx_min, idx_max)) # Make a mask that is 1 outside the masking region, 0 inside # and has a linear transition where the region boundary does not # coincide with a cell boundary mask = np.ones_like(x) mask[slc_inner] = 0 apply_on_boundary(mask[slc], boundary_scale_fns, only_once=False, out=mask[slc]) apply_on_boundary(mask[slc], lambda x: 1.0 - x, only_once=True, out=mask[slc]) # out = masked version of x out.assign(x) with writable_array(out) as out_arr: out_arr[slc] = mask[slc] * out_arr[slc]
def test_apply_on_boundary_axis_order_2d(): arr = np.ones((3, 5)) axis_order = (-1, -2) result = apply_on_boundary(arr, [lambda x: x * 3, lambda x: x * 2], axis_order=axis_order) assert all_equal(result, [[3, 2, 2, 2, 3], [3, 1, 1, 1, 3], [3, 2, 2, 2, 3]])
def test_apply_on_boundary_which_boundaries_multiple_times_2d(): # 2d arr = np.ones((3, 5)) which = ((True, False), True) result = apply_on_boundary(arr, lambda x: x * 2, which_boundaries=which, only_once=False) assert all_equal(result, [[4, 2, 2, 2, 4], [2, 1, 1, 1, 2], [2, 1, 1, 1, 2]])
def _norm(self, x): """Return ``self.norm(x)``.""" bdry_fracs = self.partition.boundary_cell_fractions if (np.allclose(bdry_fracs, 1.0) or self.exponent == float('inf') or not getattr(self.dspace, 'is_weighted', False)): # no boundary weighting return super()._norm(x) else: # TODO: implement without copying x func_list = _scaling_func_list(bdry_fracs, exponent=self.exponent) x_arr = apply_on_boundary(x, func=func_list, only_once=False) return super()._norm(self.element(x_arr))
def _dist(self, x, y): """Return ``self.dist(x, y)``.""" bdry_fracs = self.partition.boundary_cell_fractions if (np.allclose(bdry_fracs, 1.0) or self.exponent == float('inf') or not getattr(self.dspace, 'is_weighted', False)): # no boundary weighting return super()._dist(x, y) else: # TODO: implement without copying x func_list = _scaling_func_list(bdry_fracs, exponent=self.exponent) arrs = [apply_on_boundary(vec, func=func_list, only_once=False) for vec in (x, y)] return super()._dist(self.element(arrs[0]), self.element(arrs[1]))
def test_apply_on_boundary_multiple_times_2d(): arr = np.ones((3, 5)) result = apply_on_boundary(arr, lambda x: x * 2, only_once=False) assert all_equal(result, [[4, 2, 2, 2, 4], [2, 1, 1, 1, 2], [4, 2, 2, 2, 4]])
def test_apply_on_boundary_func_sequence_2d(): arr = np.ones((3, 5)) result = apply_on_boundary(arr, [lambda x: x * 2, lambda x: x * 3]) assert all_equal(result, [[2, 2, 2, 2, 2], [3, 1, 1, 1, 3], [2, 2, 2, 2, 2]])