Peano
Loading...
Searching...
No Matches
ContextCurvilinear.h
Go to the documentation of this file.
1#pragma once
2
3#include "../Numerics/idx.h"
5
6#include "toolbox/curvi/Coordinate.h"
7#include "toolbox/curvi/geometry/Block.h"
8#include "toolbox/curvi/interface/Interface.h"
9#include "toolbox/curvi/kdTree/Root.h"
10
11template <class Shortcuts, int basisSize, int numberOfData, typename T>
13
14public:
16 std::string& topography_string,
17 int coarsestMeshLevel,
18 double coarsestMeshSize,
19 double maxAdaptiveDepth,
20 tarch::la::Vector<DIMENSIONS,double> _domainOffset,
21 tarch::la::Vector<DIMENSIONS,double> _domainSize,
22 T* _nodes,
23 T* _dudx
24 ):
25 meshLevel(coarsestMeshLevel){
26 std::copy_n(_nodes, basisSize , nodes);
27 for(int i=0; i<basisSize; i++){
28 for(int j=0; j<basisSize; j++){
29 dudx[i][j] = _dudx[j*basisSize+i];
30 }
31 }
32
33 max_dx = coarsestMeshSize * std::pow(1 / 3.0, maxAdaptiveDepth);
34
35 domainOffset[0] = _domainOffset[0];
36 domainOffset[1] = _domainOffset[1];
37 domainOffset[2] = _domainOffset[2];
38
39 uint elements_l[3];
40 elements_l[toolbox::curvi::Coordinate::X] = std::round(_domainSize[0] / coarsestMeshSize);
41 elements_l[toolbox::curvi::Coordinate::Y] = std::round(_domainSize[1] / coarsestMeshSize);
42 elements_l[toolbox::curvi::Coordinate::Z] = std::round(_domainSize[2] / coarsestMeshSize);
43
44 double size[3];
45 size[toolbox::curvi::Coordinate::X] = _domainSize[0];
46 size[toolbox::curvi::Coordinate::Y] = _domainSize[1];
47 size[toolbox::curvi::Coordinate::Z] = _domainSize[2];
48
49 double offset[3];
50 offset[toolbox::curvi::Coordinate::X] = domainOffset[0];
51 offset[toolbox::curvi::Coordinate::Y] = domainOffset[1];
52 offset[toolbox::curvi::Coordinate::Z] = domainOffset[2];
53
54 interface = new toolbox::curvi::Interface(topography_string, offset, size, elements_l, basisSize - 1);
55
56 interface->initTree();
57
58 }
59
60 toolbox::curvi::Root* getRoot() { return interface->getRoot(); }
61
63 delete interface;
64 }
65
67 T* luh,
68 const tarch::la::Vector<DIMENSIONS, double>& center,
69 const tarch::la::Vector<DIMENSIONS, double>& dx,
70 double t,
71 double dt,
72 std::function<void(
73 const T* const x,
74 const tarch::la::Vector<DIMENSIONS,double>& center,
75 const double t,
76 const double dt,
77 T* Q
78 )> initUnknownsPointwise
79 ) {
80
81 if (tarch::la::equals(t, 0.0)) {
82 // int numberOfData = Shortcuts::NumberOfUnknowns + Shortcuts::NumberOfAuxiliaryVariables;
83 kernels::idx4 id_xyzf(basisSize, basisSize, basisSize, numberOfData);
84 kernels::idx3 id_xyz(basisSize, basisSize, basisSize);
85
86 int ex = std::round((center[0] - domainOffset[0] - dx[0] / 2.0) / dx[0]);
87 int ey = std::round((center[1] - domainOffset[1] - dx[1] / 2.0) / dx[1]);
88 int ez = std::round((center[2] - domainOffset[2] - dx[2] / 2.0) / dx[2]);
89
90#ifndef QUICK_IDENTITY
91 toolbox::curvi::Block element = interface->getElement(nodes, ex, ey, ez);
92 int index_offset[3];
93 element.getIndexOffset(index_offset);
94
95 for (int k = 0; k < basisSize; k++) {
96 int e_k = index_offset[toolbox::curvi::Coordinate::Z] + k;
97 for (int j = 0; j < basisSize; j++) {
98 int e_j = index_offset[toolbox::curvi::Coordinate::Y] + j;
99 for (int i = 0; i < basisSize; i++) {
100 int e_i = index_offset[toolbox::curvi::Coordinate::X] + i;
101
102 // x,y,z
103 luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 0)] = element(
104 toolbox::curvi::Coordinate::X,
105 toolbox::curvi::Coordinate::Z, e_k,
106 toolbox::curvi::Coordinate::Y, e_j,
107 toolbox::curvi::Coordinate::X, e_i
108 );
109 luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 1)] = element(
110 toolbox::curvi::Coordinate::Y,
111 toolbox::curvi::Coordinate::Z, e_k,
112 toolbox::curvi::Coordinate::Y, e_j,
113 toolbox::curvi::Coordinate::X, e_i
114 );
115 luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 2)] = element(
116 toolbox::curvi::Coordinate::Z,
117 toolbox::curvi::Coordinate::Z, e_k,
118 toolbox::curvi::Coordinate::Y, e_j,
119 toolbox::curvi::Coordinate::X, e_i
120 );
121
122 }
123 }
124 }
125
126#else
127 for (int k = 0; k < basisSize; k++) {
128 for (int j = 0; j < basisSize; j++) {
129 for (int i = 0; i < basisSize; i++) {
130 luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 0)] = nodes[i] * dx[0] + center[0] - dx[0] / 2;
131 luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 1)] = nodes[j] * dx[1] + center[1] - dx[1] / 2;
132 luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 2)] = nodes[k] * dx[2] + center[2] - dx[2] / 2;
133 }
134 }
135 }
136#endif
137
138 T derivatives[basisSize * basisSize * basisSize * 10];
139 std::fill_n(derivatives, basisSize * basisSize * basisSize * 10, 0.0);
140 kernels::idx4 id_der(basisSize, basisSize, basisSize, 10);
141
142 // compute metric derivatives//
143#ifdef QUICK_IDENTITY
144
145 for (int k = 0; k < basisSize; k++) {
146 for (int j = 0; j < basisSize; j++) {
147 for (int i = 0; i < basisSize; i++) {
148 derivatives[id_der(k, j, i, 0)] = 1.0;
149 derivatives[id_der(k, j, i, 1)] = 1.0;
150 derivatives[id_der(k, j, i, 5)] = 1.0;
151 derivatives[id_der(k, j, i, 9)] = 1.0;
152 }
153 }
154 }
155#else
157#endif
158
159 for (int k = 0; k < basisSize; k++) {
160 for (int j = 0; j < basisSize; j++) {
161 for (int i = 0; i < basisSize; i++) {
162 std::copy_n(derivatives + id_der(k, j, i, 0), 10, luh + id_xyzf(k, j, i, Shortcuts::jacobian));
163 }
164 }
165 }
166
167 tarch::la::Vector<DIMENSIONS, double> curv_center;
168 getElementCenter(luh, curv_center);
169 for (int k = 0; k < basisSize; k++) {
170 for (int j = 0; j < basisSize; j++) {
171 for (int i = 0; i < basisSize; i++) {
172 T coords[3] = {
173 luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 0)],
174 luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 1)],
175 luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 2)]};
176
177 initUnknownsPointwise(
178 coords, curv_center, t, dt, luh + id_xyzf(k, j, i, 0)
179 );
180
181 }
182 }
183 }
184
185 for (int k = 0; k < basisSize; k++) {
186 for (int j = 0; j < basisSize; j++) {
187 for (int i = 0; i < basisSize; i++) {
188 for (int m = 0; m < numberOfData; m++) {
189 assertion5(std::isfinite(luh[id_xyzf(k, j, i, m)]), k, j, i, m, meshLevel);
190 }
191 }
192 }
193 }
194 }
195 }
196
197 void correctPointSourceLocation(double pointSourceLocation[][3]){
198
199 for (int p = 0; p < 1; p++) {
200 double coords[3];
201 // invert coordinates as curvi order is zyx
202 coords[toolbox::curvi::Coordinate::X] = pointSourceLocation[p][0];
203 coords[toolbox::curvi::Coordinate::Y] = pointSourceLocation[p][1];
204 coords[toolbox::curvi::Coordinate::Z] = pointSourceLocation[p][2];
205
206 pointSourceLocation[p][0] = this->interface->invertProjection(toolbox::curvi::Coordinate::X, coords);
207 pointSourceLocation[p][1] = this->interface->invertProjection(toolbox::curvi::Coordinate::Y, coords);
208 pointSourceLocation[p][2] = this->interface->invertProjection(toolbox::curvi::Coordinate::Z, coords);
209 }
210 }
211
212 void getElementSize(const T* const luh, tarch::la::Vector<DIMENSIONS, double>& dx) {
213
214 // int numberOfData = Shortcuts::NumberOfUnknowns + Shortcuts::NumberOfAuxiliaryVariables;
215 kernels::idx4 id_xyzf(basisSize, basisSize, basisSize, numberOfData);
216
217 dx[0] = 0;
218 dx[1] = 0;
219 dx[2] = 0;
220
221 for (int i = 0; i < basisSize; i++) {
222 for (int j = 0; j < basisSize; j++) {
223 dx[0] = std::max(
224 dx[0], luh[id_xyzf(i, j, basisSize - 1, Shortcuts::curve_grid + 0)] - luh[id_xyzf(i, j, 0, Shortcuts::curve_grid + 0)]
225 );
226 dx[1] = std::max(
227 dx[1], luh[id_xyzf(i, basisSize - 1, j, Shortcuts::curve_grid + 1)] - luh[id_xyzf(i, 0, j, Shortcuts::curve_grid + 1)]
228 );
229 dx[2] = std::max(
230 dx[2], luh[id_xyzf(basisSize - 1, i, j, Shortcuts::curve_grid + 2)] - luh[id_xyzf(0, i, j, Shortcuts::curve_grid + 2)]
231 );
232 }
233 }
234 }
235
236 void getElementCenter(const T* const luh, tarch::la::Vector<DIMENSIONS, double>& center) {
237 int center_i1 = int(std::ceil(basisSize / 2.0));
238 int center_i2 = int(std::floor(basisSize / 2.0));
239
240 // int numberOfData = Shortcuts::NumberOfUnknowns + Shortcuts::NumberOfAuxiliaryVariables;
241 kernels::idx4 id_xyzf(basisSize, basisSize, basisSize, numberOfData);
242
243 center[0] = (luh[id_xyzf(center_i1, center_i1, center_i1, Shortcuts::curve_grid + 0)]
244 + luh[id_xyzf(center_i2, center_i2, center_i2, Shortcuts::curve_grid + 0)])
245 / 2.0;
246 center[1] = (luh[id_xyzf(center_i1, center_i1, center_i1, Shortcuts::curve_grid + 1)]
247 + luh[id_xyzf(center_i2, center_i2, center_i2, Shortcuts::curve_grid + 1)])
248 / 2.0;
249 center[2] = (luh[id_xyzf(center_i1, center_i1, center_i1, Shortcuts::curve_grid + 2)]
250 + luh[id_xyzf(center_i2, center_i2, center_i2, Shortcuts::curve_grid + 2)])
251 / 2.0;
252 }
253
254 toolbox::curvi::Interface* getInterface(){
255 return interface;
256 }
257
258
259 double max_dx;
260
261protected:
262 toolbox::curvi::Interface* interface;
263
264 double nodes[basisSize];
265 double dudx[basisSize][basisSize];
266
267 double domainOffset[3];
268 const int meshLevel;
269
270};
toolbox::curvi::Root * getRoot()
double nodes[basisSize]
ContextCurvilinear(std::string &topography_string, int coarsestMeshLevel, double coarsestMeshSize, double maxAdaptiveDepth, tarch::la::Vector< DIMENSIONS, double > _domainOffset, tarch::la::Vector< DIMENSIONS, double > _domainSize, T *_nodes, T *_dudx)
void getElementSize(const T *const luh, tarch::la::Vector< DIMENSIONS, double > &dx)
void initUnknownsPatch(T *luh, const tarch::la::Vector< DIMENSIONS, double > &center, const tarch::la::Vector< DIMENSIONS, double > &dx, double t, double dt, std::function< void(const T *const x, const tarch::la::Vector< DIMENSIONS, double > &center, const double t, const double dt, T *Q)> initUnknownsPointwise)
void getElementCenter(const T *const luh, tarch::la::Vector< DIMENSIONS, double > &center)
void correctPointSourceLocation(double pointSourceLocation[][3])
double dudx[basisSize][basisSize]
toolbox::curvi::Interface * interface
toolbox::curvi::Interface * getInterface()
static void metricDerivatives(double dudx[][num_nodes], const T *const coordinates, const double *const dx, T *derivatives)