Peano
Loading...
Searching...
No Matches
SolverMatrixInterpolator.py
Go to the documentation of this file.
1import numpy as np
2import scipy.sparse as sp
3import os
4
5from exahype2.solvers.LagrangeBasis import render_tensor_1
6
7def lineariseIndex(index, max):
8 result = 0
9 weight = 1
10 for d in range(3):
11 result += weight * index[d]
12 weight *= max
13 return result
14
16 def __init__(self, source_patch_size, destination_patch_size, source_halo_size, destination_halo_size):
17 self.source_patch_size = source_patch_size
18 self.destination_patch_size = destination_patch_size
19 self.source_halo_size = source_halo_size
20 self.destination_halo_size = destination_halo_size
21
22 def generateData(self, directory_path = "./"):
23 self.filepath = directory_path + "matrixdata/Interpolator_" + str(self.source_patch_size) + "_" + str(self.destination_patch_size) + ".h"
24 if not os.path.isfile(self.filepath):
25 self.generateMatrix()
26 self.writeMatrixToFile(directory_path)
27
28 def generateMatrix(self):
29 source_dimensions = np.full((3), self.source_patch_size + 2 * self.source_halo_size)
30 destination_dimensions = np.full((3), self.destination_patch_size + 2 * self.destination_halo_size)
31 matrix = np.zeros((np.prod(destination_dimensions), np.prod(source_dimensions)))
32
33 for i in range(destination_dimensions[0]):
34 for j in range(destination_dimensions[1]):
35 for k in range(destination_dimensions[2]):
36 destinationVolume = np.array([i, j, k])
37 linearised_destination = lineariseIndex(destinationVolume, self.destination_patch_size + 2 * self.destination_halo_size)
38
39 corner_source_volume = (np.floor((destinationVolume - np.full((3), self.destination_halo_size)) * self.source_patch_size / self.destination_patch_size + np.full((3), self.source_halo_size)) - np.full((3), 1)).astype(int)
40 np.maximum(corner_source_volume, 0, corner_source_volume)
41
42 for l in range(corner_source_volume[0], corner_source_volume[0] + 4):
43 for n in range(corner_source_volume[1], corner_source_volume[1] + 4):
44 for m in range(corner_source_volume[2], corner_source_volume[2] + 4):
45 source_volume = np.array([l, n, m])
46 if (np.max(source_volume) >= self.source_patch_size + 2 * self.source_halo_size):
47 break
48
49 axisWithSourceOutsidePatch = 0
50 for d in range(3):
51 if source_volume[d] < self.source_halo_size:
52 axisWithSourceOutsidePatch += 1
53 if source_volume[d] >= self.source_patch_size + self.source_halo_size:
54 axisWithSourceOutsidePatch += 1
55 isFromUnitialisedDiagonal = (axisWithSourceOutsidePatch > 1)
56
57 normalised_source_position = (source_volume + np.full((3), - self.source_halo_size)) / self.source_patch_size
58 normalised_destination_position = (destinationVolume + np.full((3), - self.destination_halo_size)) / self.destination_patch_size
59
60 weight = 1.0
61 for d in range(3):
62 distance = np.abs(normalised_destination_position[d] - normalised_source_position[d])
63 distance = 1.0 - distance * self.source_patch_size
64 weight *= np.maximum(distance, 0.0)
65
66 if isFromUnitialisedDiagonal:
67 for d in range(3):
68 source_volume[d] = np.maximum(source_volume[d], self.source_halo_size)
69 source_volume[d] = np.minimum(source_volume[d], self.source_halo_size + self.source_patch_size - 1)
70
71 linearised_source = lineariseIndex(source_volume, self.source_patch_size + 2 * self.source_halo_size)
72 matrix[linearised_destination, linearised_source] += weight
73 self.csr_matrix = sp.csr_matrix(matrix)
74
75 def writeMatrixToFile(self, directory_path):
76 contents = """#pragma once
77class InterpolationMatrixData{
78public:
79"""
80 contents += """ static constexpr double Data[] = {};\n""".format(render_tensor_1(tensor=self.csr_matrix.data))
81 contents += """ static constexpr int Indices[] = {};\n""".format(render_tensor_1(tensor=self.csr_matrix.indices))
82 contents += """ static constexpr int Indptr[] = {};\n""".format(render_tensor_1(tensor=self.csr_matrix.indptr))
83 contents += "};"
84
85 if not os.path.isdir(directory_path + "matrixdata/"):
86 os.makedirs(directory_path + "matrixdata/")
87 file = open(self.filepath, 'w')
88 file.write(contents)
89 file.close()
__init__(self, source_patch_size, destination_patch_size, source_halo_size, destination_halo_size)