Peano
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 
11 template <class Shortcuts, int basisSize, int numberOfData, typename T>
13 
14 public:
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];
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 ez = std::round((center[2] - domainOffset[2] - dx[2] / 2.0) / dx[2]);
87  int ey = std::round((center[1] - domainOffset[1] - dx[1] / 2.0) / dx[1]);
88  int ex = std::round((center[0] - domainOffset[0] - dx[0] / 2.0) / dx[0]);
89 
90 #ifndef QUICK_IDENTITY
91  toolbox::curvi::Block element = interface->getElement(nodes, ez, ey, ex);
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  2,
105  toolbox::curvi::Coordinate::Z, e_k,
108  );
109  luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 1)] = element(
110  1,
111  toolbox::curvi::Coordinate::Z, e_k,
114  );
115  luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 2)] = element(
116  0,
117  toolbox::curvi::Coordinate::Z, e_k,
120  );
121  }
122  }
123  }
124 
125 #else
126  for (int k = 0; k < basisSize; k++) {
127  for (int j = 0; j < basisSize; j++) {
128  for (int i = 0; i < basisSize; i++) {
129  luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 0)] = nodes[i] * dx[0] + center[0] - dx[0] / 2;
130  luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 1)] = nodes[j] * dx[1] + center[1] - dx[1] / 2;
131  luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 2)] = nodes[k] * dx[2] + center[2] - dx[2] / 2;
132  }
133  }
134  }
135 #endif
136 
137  T derivatives[basisSize * basisSize * basisSize * 10];
138  std::fill_n(derivatives, basisSize * basisSize * basisSize * 10, 0.0);
139  kernels::idx4 id_der(basisSize, basisSize, basisSize, 10);
140 
141  // compute metric derivatives//
142 #ifdef QUICK_IDENTITY
143 
144  for (int k = 0; k < basisSize; k++) {
145  for (int j = 0; j < basisSize; j++) {
146  for (int i = 0; i < basisSize; i++) {
147  derivatives[id_der(k, j, i, 0)] = 1.0;
148  derivatives[id_der(k, j, i, 1)] = 1.0;
149  derivatives[id_der(k, j, i, 5)] = 1.0;
150  derivatives[id_der(k, j, i, 9)] = 1.0;
151  }
152  }
153  }
154 #else
156 #endif
157 
158  for (int k = 0; k < basisSize; k++) {
159  for (int j = 0; j < basisSize; j++) {
160  for (int i = 0; i < basisSize; i++) {
161  std::copy_n(derivatives + id_der(k, j, i, 0), 10, luh + id_xyzf(k, j, i, Shortcuts::jacobian));
162  }
163  }
164  }
165 
166  tarch::la::Vector<DIMENSIONS, double> curv_center;
167  getElementCenter(luh, curv_center);
168  for (int k = 0; k < basisSize; k++) {
169  for (int j = 0; j < basisSize; j++) {
170  for (int i = 0; i < basisSize; i++) {
171  T coords[3] = {
172  luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 0)],
173  luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 1)],
174  luh[id_xyzf(k, j, i, Shortcuts::curve_grid + 2)]};
175 
176  initUnknownsPointwise(
177  coords, curv_center, t, dt, luh + id_xyzf(k, j, i, 0)
178  );
179 
180  }
181  }
182  }
183 
184  for (int k = 0; k < basisSize; k++) {
185  for (int j = 0; j < basisSize; j++) {
186  for (int i = 0; i < basisSize; i++) {
187  for (int m = 0; m < numberOfData; m++) {
188  assertion5(std::isfinite(luh[id_xyzf(k, j, i, m)]), k, j, i, m, meshLevel);
189  }
190  }
191  }
192  }
193  }
194  }
195 
196  void correctPointSourceLocation(double pointSourceLocation[][3]){
197 
198  for (int p = 0; p < 1; p++) {
199  toolbox::curvi::Coordinate dir_top = static_cast<toolbox::curvi::Coordinate>(_TOP);
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][_TOP] = this->interface->invertProjection(dir_top, coords);
207  }
208  }
209 
210  void getElementSize(const T* const luh, tarch::la::Vector<DIMENSIONS, double>& dx) {
211 
212  // int numberOfData = Shortcuts::NumberOfUnknowns + Shortcuts::NumberOfAuxiliaryVariables;
213  kernels::idx4 id_xyzf(basisSize, basisSize, basisSize, numberOfData);
214 
215  dx[0] = 0;
216  dx[1] = 0;
217  dx[2] = 0;
218 
219  for (int i = 0; i < basisSize; i++) {
220  for (int j = 0; j < basisSize; j++) {
221  dx[0] = std::max(
222  dx[0], luh[id_xyzf(i, j, basisSize - 1, Shortcuts::curve_grid + 0)] - luh[id_xyzf(i, j, 0, Shortcuts::curve_grid + 0)]
223  );
224  dx[1] = std::max(
225  dx[1], luh[id_xyzf(i, basisSize - 1, j, Shortcuts::curve_grid + 1)] - luh[id_xyzf(i, 0, j, Shortcuts::curve_grid + 1)]
226  );
227  dx[2] = std::max(
228  dx[2], luh[id_xyzf(basisSize - 1, i, j, Shortcuts::curve_grid + 2)] - luh[id_xyzf(0, i, j, Shortcuts::curve_grid + 2)]
229  );
230  }
231  }
232  }
233 
234  void getElementCenter(const T* const luh, tarch::la::Vector<DIMENSIONS, double>& center) {
235  int center_i1 = int(std::ceil(basisSize / 2.0));
236  int center_i2 = int(std::floor(basisSize / 2.0));
237 
238  // int numberOfData = Shortcuts::NumberOfUnknowns + Shortcuts::NumberOfAuxiliaryVariables;
239  kernels::idx4 id_xyzf(basisSize, basisSize, basisSize, numberOfData);
240 
241  center[0] = (luh[id_xyzf(center_i1, center_i1, center_i1, Shortcuts::curve_grid + 0)]
242  + luh[id_xyzf(center_i2, center_i2, center_i2, Shortcuts::curve_grid + 0)])
243  / 2.0;
244  center[1] = (luh[id_xyzf(center_i1, center_i1, center_i1, Shortcuts::curve_grid + 1)]
245  + luh[id_xyzf(center_i2, center_i2, center_i2, Shortcuts::curve_grid + 1)])
246  / 2.0;
247  center[2] = (luh[id_xyzf(center_i1, center_i1, center_i1, Shortcuts::curve_grid + 2)]
248  + luh[id_xyzf(center_i2, center_i2, center_i2, Shortcuts::curve_grid + 2)])
249  / 2.0;
250  }
251 
252 
253  double max_dx;
254 
255 protected:
256  toolbox::curvi::Interface* interface;
257 
258  double nodes[basisSize];
259  double dudx[basisSize][basisSize];
260 
261  double domainOffset[3];
262  const int meshLevel;
263 
264 };
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
static void metricDerivatives(double dudx[][num_nodes], const T *const coordinates, const double *const dx, T *derivatives)
size
Definition: euler.py:44
j
Definition: euler.py:95
offset
Definition: euler.py:45