def test_invalid_acc_raises_exception(self): with self.assertRaises(ValueError): coefficients(deriv=1, acc=3) with self.assertRaises(ValueError): coefficients(deriv=1, acc=0) with self.assertRaises(ValueError): coefficients_non_uni(1, 3, None, None) with self.assertRaises(ValueError): coefficients_non_uni(1, 0, None, None)
def diff_non_uni(self, y, coords, **kwargs): """The core function to take a partial derivative on a non-uniform grid""" if "acc" in kwargs: acc = kwargs["acc"] elif self.acc is not None: acc = self.acc else: acc = 2 order, dim = self.order, self.axis coef_list = [] for i in range(len(coords)): coef_list.append(coefficients_non_uni(order, acc, coords, i)) yd = np.zeros_like(y) ndims = len(y.shape) multi_slice = [slice(None, None)] * ndims ref_multi_slice = [slice(None, None)] * ndims for i, x in enumerate(coords): coefs = coef_list[i] weights = coefs["coefficients"] offsets = coefs["offsets"] ref_multi_slice[dim] = i for off, w in zip(offsets, weights): multi_slice[dim] = i + off yd[tuple(ref_multi_slice)] += w * y[tuple(multi_slice)] return yd
def _matrix_nonuniform(self, shape, coords, acc): coords = coords[self.axis] siz = np.prod(shape) long_inds = np.arange(siz).reshape(shape) short_inds = [np.arange(shape[k]) for k in range(len(shape))] short_inds = list(itertools.product(*short_inds)) coef_dicts = [] for i in range(len(coords)): coef_dicts.append(coefficients_non_uni(self.order, acc, coords, i)) mat = sparse.lil_matrix((siz, siz)) for base_ind_long, base_ind_short in enumerate(short_inds): cd = coef_dicts[base_ind_short[self.axis]] cs, os = cd['coefficients'], cd['offsets'] for c, o in zip(cs, os): off_short = np.zeros(len(shape), dtype=np.int) off_short[self.axis] = int(o) off_ind_short = np.array(base_ind_short, dtype=np.int) + off_short off_long = long_inds[tuple(off_ind_short)] mat[base_ind_long, off_long] += c return mat
def _determine_coefs(self): """Calculates the finite difference coefficients for the requested partial derivatives""" for axis, deriv in self.derivs.items(): coefs = [] for i in range(len(deriv["coords"])): coefs.append(coefficients_non_uni(deriv["order"], self.acc, deriv["coords"], i)) self.derivs[axis]["coefs"] = coefs
def apply(self, fd, u): for axis, order in self.derivs.items(): if self.spac: u = fd.diff(u, self.spac[axis], order, axis, coefficients(order, fd.acc)) else: coefs = [] for i in range(len(self.coords[axis])): coefs.append(coefficients_non_uni(order, fd.acc, self.coords[axis], i)) u = fd.diff_non_uni(u, self.coords[axis], axis, coefs) return u
def test_non_uniform(self): x = np.linspace(0, 10, 100) dx = x[1] - x[0] c_uni = coefficients(deriv=2, acc=2) coefs_uni = c_uni["center"]["coefficients"] / dx**2 c_non_uni = coefficients_non_uni(deriv=2, acc=2, coords=x, idx=5) coefs_non_uni = c_non_uni["coefficients"] np.testing.assert_array_almost_equal(coefs_non_uni, coefs_uni)
def test_invalid_deriv_raises_exception(self): with self.assertRaises(ValueError): coefficients(-1, 2) with self.assertRaises(ValueError): coefficients_non_uni(-1, 2, None, None)