Skip to content
Snippets Groups Projects

implemented derivation of gradient weights via rotation

Closed Markus Holzer requested to merge (removed):derivation_gradient into master
Compare and
2 files
+ 171
4
Preferences
Compare changes
Files
2
from collections import defaultdict
import sympy as sp
import numpy as np
import sys
from pystencils.field import Field
from pystencils.sympyextensions import multidimensional_sum, prod
@@ -170,13 +172,45 @@ class FiniteDifferenceStencilDerivation:
def as_matrix(self):
dim = len(self.stencil[0])
assert dim == 2
max_offset = max(max(abs(e) for e in direction) for direction in self.stencil)
result = sp.Matrix(2 * max_offset + 1, 2 * max_offset + 1, lambda i, j: 0)
for direction, weight in zip(self.stencil, self.weights):
result[max_offset - direction[1], max_offset + direction[0]] = weight
if dim == 2:
result = sp.Matrix(2 * max_offset + 1, 2 * max_offset + 1, lambda i, j: 0)
for direction, weight in zip(self.stencil, self.weights):
result[max_offset - direction[1], max_offset + direction[0]] = weight
elif dim == 3:
result = np.zeros((2 * max_offset + 1, 2 * max_offset + 1, 2 * max_offset + 1), dtype=object)
for direction, weight in zip(self.stencil, self.weights):
result[max_offset - direction[1], max_offset + direction[0], max_offset + direction[2]] = weight
else:
print('only 2D or 3D matrix representations are available')
sys.exit()
return result
def rotate_weights_and_apply(self, field_access: Field.Access, axis):
"""derive gradient weights of other direction with already calculated weights of one direction
via rotation and apply them to a field."""
dim = len(self.stencil[0])
rotated_weights = np.rot90(self.as_matrix(), 1, axis)
result = []
max_offset = max(max(abs(e) for e in direction) for direction in self.stencil)
for direction in self.stencil:
if dim == 2:
result.append(rotated_weights[max_offset - direction[1],
max_offset + direction[0]])
elif dim == 3:
result.append(rotated_weights[max_offset - direction[1],
max_offset + direction[0],
max_offset + direction[2]])
else:
print('only 2D or 3D matrix representations are available')
sys.exit()
f = field_access
return sum(f.get_shifted(*offset) * weight for offset, weight in zip(self.stencil, result))
def __repr__(self):
return "Finite difference stencil of accuracy {}, isotropic error: {}".format(self.accuracy,
self.is_isotropic)