From 5b15fd470c9ddb4c1bb4b7ad459b51de653d47a2 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Keck <Jean-Baptiste.Keck@imag.fr> Date: Thu, 28 Jul 2016 14:16:29 +0200 Subject: [PATCH] finite differences --- hysop/numerics/finite_differences.py | 50 +++++++++++++++++++++++++++- hysop/numerics/stencil.py | 13 ++++++-- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/hysop/numerics/finite_differences.py b/hysop/numerics/finite_differences.py index 6ae41654b..7c0d3e221 100644 --- a/hysop/numerics/finite_differences.py +++ b/hysop/numerics/finite_differences.py @@ -49,6 +49,7 @@ Note from abc import ABCMeta, abstractmethod from hysop.constants import debug from hysop.numerics.stencil import Stencil, StencilGenerator +from hysop.numerics.stencil import CenteredStencil, CenteredStencilGenerator import hysop.tools.numpywrappers as npw import numpy as np @@ -215,6 +216,45 @@ class FiniteDifference(object): size as result. """ +class FDkCp(FiniteDifference): + """ + k-th derivative, centered scheme, p-th order. + + """ + + def __init__(self,k,p,*args,**kargs): + super(FDkCp,self).__init__(*args,**kargs) + + csg = CenteredStencilGenerator() + stencil = csg.generate_exact_stencil(order=p,derivative=k) + + lghosts = stencil.L + rghosts = stencil.R + + self.stencil = stencil + self.right_ghost_layer_size = rghosts + self.left_ghosts_layer_size = lghosts + self.ghosts_layer_size = np.maximum(lghosts, rghosts) + + def __call__(self, tab, cdir, result): + stencil = self.stencil + svars = {stencil.dx:self._step[cdir]} + + self.output_indices = [idx for idx in self.output_indices] + result[self.output_indices] = 0 + for (offset,coeff) in self.stencil.iteritems(svars): + result[self.output_indices] += coeff*tab[self._indices(offset)] + return result + + def _compute_indices(self, step): + pass + + def compute_and_add(self): + pass + def compute_and_add_abs(self): + pass + + class FDC2(FiniteDifference): """ @@ -225,7 +265,6 @@ class FDC2(FiniteDifference): ghosts_layer_size = 1 def _compute_indices(self, step): - print 'lol' self._coeff = npw.asarray(1. / (2. * step)) self._m1 = [] @@ -509,3 +548,12 @@ class FDC4(FiniteDifference): np.add(wk[self.output_indices], result[self.output_indices], result[self.output_indices]) return result + +if __name__ == '__main__': + N = np.asarray((16,16,16)) + A = np.random.rand(*N) + dx = 1.0/(N-1) + indices = np.ndindex(*N) + + diff = FDkCp(2,2,step=dx,indices=indices) + diff(A,0,A) diff --git a/hysop/numerics/stencil.py b/hysop/numerics/stencil.py index c28ab1ec1..a0514b1be 100644 --- a/hysop/numerics/stencil.py +++ b/hysop/numerics/stencil.py @@ -114,7 +114,7 @@ class Stencil(object): def _update_attributes(self): self.dim = self.coeffs.ndim self.shape = self.coeffs.shape - self.L = self.origin + self.L = np.asarray([self.origin] if np.isscalar(self.origin) else self.origin) self.R = self.shape-self.origin-1 def _delete_zeros(self, coeffs): @@ -200,7 +200,7 @@ class Stencil(object): raise RuntimeError('Stencil is not 2d !') return sp.sparse.coo_matrix(self.coeffs,shape=self.shape,dtype=self.dtype) - def iteritems(self): + def iteritems(self,svars={},include_factor=True): """ Return an (offset,coefficient) iterator iterating on all **non zero** coefficients. Offset is taken from origin. @@ -210,8 +210,15 @@ class Stencil(object): it : itertools.iterator Zipped offset and coefficient iterator. """ + factor = self.factor if include_factor else 1 + def mapfun(x): + offset = x-self.origin + value = factor*self.coeffs[x] + if isinstance(value, sm.Expr): + value = value.xreplace(svars) + return (offset,value) iterator = np.ndindex(self.shape) - iterator = it.imap(lambda x: (x-self.origin,self.coeffs[x]), iterator) + iterator = it.imap(mapfun, iterator) iterator = it.ifilter(lambda x: x[1]!=0, iterator) return iterator -- GitLab