ExaDG
Loading...
Searching...
No Matches
interpolation.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2021 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef EXADG_POSTPROCESSOR_SPECTRAL_ANALYSIS_INTERPOLATION_H_
23#define EXADG_POSTPROCESSOR_SPECTRAL_ANALYSIS_INTERPOLATION_H_
24
25// std
26#include <mpi.h>
27#include <stdlib.h>
28
29// deal.II
30#include <deal.II/base/aligned_vector.h>
31#include <deal.II/base/point.h>
32#include <deal.II/base/quadrature_lib.h>
33#include <deal.II/base/utilities.h>
34#include <deal.II/fe/fe_dgq.h>
35#include <deal.II/fe/fe_values.h>
36#include <deal.II/matrix_free/evaluation_kernels.h>
37
38// ExaDG
39#include <exadg/postprocessor/spectral_analysis/setup.h>
40
41namespace dealspectrum
42{
48{
49public:
50 MPI_Comm const comm;
51 // reference to DEAL.SPECTRUM setup
52 Setup & s;
53 // is initialized?
54 bool initialized;
55 // source vector (values to be interpolated)
56 double * src = NULL;
57 // destination vector (interpolated values)
58 double * dst = NULL;
59 // shape function (gauss lobatto to equidistant)
60 dealii::AlignedVector<double> shape_values;
61 // number of cells in each direction
62 int cells;
63 // dimensions
64 int DIM;
65 // process local cell range on sfc
66 int start;
67 int end;
68 // points in each direction in cell & points per cell for source...
69 unsigned int points_source;
70 int dofs_source;
71 // ... and for target
72 unsigned int points_target;
73 int dofs_target;
74
79 Interpolator(MPI_Comm const & comm, Setup & s) : comm(comm), s(s), initialized(false)
80 {
81 }
82
83 virtual ~Interpolator()
84 {
85 // not initialized -> nothing to clean up
86 if(not initialized)
87 return;
88
89 delete[] src;
90 delete[] dst;
91 }
92
93 template<typename MAPPING>
94 void
95 init(MAPPING & MAP)
96 {
97 int start, end;
98 MAP.getLocalRange(start, end);
99
100 init(start, end);
101 }
102
103 void
104 init(int start, int end)
105 {
106 // check if already initialized
107 if(this->initialized)
108 return;
109 this->initialized = true;
110
111 // get cell range...
112 this->start = start;
113 this->end = end;
114 // ...number of local cells
115 cells = end - start;
116
117 // get dimensions
118 DIM = s.dim;
119
120 // number of Gauss-Lobatto points:
121 points_source = s.points_src;
122 // ... of equidistant points:
123 points_target = s.points_dst;
124
125 // number of Gauss-Lobatto points per cell and ...
126 dofs_source = dealii::Utilities::pow(points_source, DIM);
127 // ...number of equidistant points per cell
128 dofs_target = dealii::Utilities::pow(points_target, DIM);
129
130 // allocate memory for source (only needed if values are read by IO)...
131 src = new double[cells * dofs_source * DIM];
132 // ... and target
133 dst = new double[cells * dofs_target * DIM];
134
135 // fill shape values
136 fill_shape_values(shape_values);
137 }
138
145 std::vector<dealii::Point<1>>
146 get_equidistant_inner(unsigned int const n_points)
147 {
148 std::vector<dealii::Point<1>> points(n_points);
149
150 for(unsigned int i = 0; i < n_points; i++)
151 points[i][0] = (i + 0.5) / n_points;
152
153 return points;
154 }
155
161 void
162 fill_shape_values(dealii::AlignedVector<double> & shape_values)
163 {
164 // determine coefficients with deal.II functions
165 dealii::FE_DGQ<1> fe(points_source - 1);
166 dealii::FullMatrix<double> matrix(points_target, points_source);
167 dealii::FE_DGQArbitraryNodes<1>(dealii::Quadrature<1>(get_equidistant_inner(points_target)))
168 .get_interpolation_matrix(fe, matrix);
169
170 // ... and convert to linearized format
171 shape_values.resize(points_source * points_target);
172 for(unsigned int i = 0; i < points_source; ++i)
173 for(unsigned int q = 0; q < points_target; ++q)
174 shape_values[i * points_target + q] = matrix(q, i);
175 }
176
181 void
183 {
184 double const * src = this->src;
185 interpolate(src);
186 }
187
195 void
196 interpolate(double const *& src)
197 {
198 // allocate dst- and src-vector
199 dealii::AlignedVector<double> temp1(MAX(dofs_source, dofs_target));
200 dealii::AlignedVector<double> temp2(MAX(dofs_source, dofs_target));
201
202 // get start point of arrays
203 double const * src_ = src;
204 double * dst_ = dst;
205 // loop over all cells
206 for(int c = 0; c < cells; c++)
207 {
208 // loop over all velocity directions
209 for(int d = 0; d < DIM; d++)
210 {
211 // perform interpolation
212 if(DIM == 2)
213 {
214 // ... 2D
215 dealii::internal::
216 EvaluatorTensorProduct<dealii::internal::evaluate_general, 2, 0, 0, double>
217 eval_val(shape_values, shape_values, shape_values, points_source, points_target);
218 eval_val.template values<0, true, false>(src_, temp2.begin());
219 eval_val.template values<1, true, false>(temp2.begin(), temp1.begin());
220 }
221 else
222 {
223 // ... 3D
224 dealii::internal::
225 EvaluatorTensorProduct<dealii::internal::evaluate_general, 3, 0, 0, double>
226 eval_val(shape_values, shape_values, shape_values, points_source, points_target);
227 eval_val.template values<0, true, false>(src_, temp1.begin());
228 eval_val.template values<1, true, false>(temp1.begin(), temp2.begin());
229 eval_val.template values<2, true, false>(temp2.begin(), temp1.begin());
230 }
231 // write interpolated data permuted into destination vector
232 for(int i = 0; i < dofs_target; i++)
233 dst_[i * DIM + d] = temp1[i];
234 // go to next dimension
235 src_ += dofs_source;
236 }
237 // go to next cell
238 dst_ += dofs_target * DIM;
239 }
240 }
241
247 void
249 {
251 }
252
261 void
262 interpolate_simple(double *& src)
263 {
264 double * src_ = src;
265 double * dst_ = dst;
266
267 // loop over all cells
268 for(int c = 0; c < cells; c++)
269 {
270 // loop over all velocity directions
271 for(int d = 0; d < DIM; d++)
272 {
273 // write data permuted into destination vector
274 for(int i = 0; i < dofs_target; i++)
275 dst_[i * DIM + d] = src_[i];
276 // go to next dimension
277 src_ += dofs_source;
278 }
279 // go to next cell
280 dst_ += dofs_target * DIM;
281 }
282 }
283
289 void
290 deserialize(char const * filename)
291 {
292 deserialize(filename, src);
293 }
294
301 void
302 deserialize(char const * filename, double *& src)
303 {
304 io(0, filename, src);
305 }
306
312 void
313 serialize(char const * filename)
314 {
315 double const * src = this->src;
316 serialize(filename, src);
317 }
318
325 void
326 serialize(char const * filename, double const *& src)
327 {
328 io(1, filename, src);
329 }
330
338 template<typename VEC>
339 void
340 io(int type, char const * filename, VEC & src)
341 {
342 // dofs to read/write per field
343 unsigned long int dofs = cells * dofs_source;
344 // local displacement in file (in bytes)
345 MPI_Offset disp =
346 8 * sizeof(int) + static_cast<unsigned long int>(start) * dofs_source * sizeof(double) * DIM;
347
348 // create view
349 MPI_Datatype stype;
350 MPI_Type_contiguous(dofs, MPI_DOUBLE, &stype);
351 MPI_Type_commit(&stype);
352
353 // ooen file ...
354 MPI_File fh;
355 if(type == 0)
356 MPI_File_open(comm, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
357 else
358 MPI_File_open(comm, filename, MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
359
360 // ... set view
361 MPI_File_set_view(fh, disp, MPI_DOUBLE, MPI_DOUBLE, "native", MPI_INFO_NULL);
362
363 if(type == 0)
364 // ... read file
365 MPI_File_read_all(fh, (void *)src, dofs * DIM, MPI_DOUBLE, MPI_STATUSES_IGNORE);
366 else
367 // ... write file
368 MPI_File_write_all(fh, src, dofs * DIM, MPI_DOUBLE, MPI_STATUSES_IGNORE);
369
370 // ... close file
371 MPI_File_close(&fh);
372
373 // clean up
374 MPI_Type_free(&stype);
375 }
376};
377
378} // namespace dealspectrum
379
380#endif /* EXADG_POSTPROCESSOR_SPECTRAL_ANALYSIS_INTERPOLATION_H_ */
Definition interpolation.h:48
std::vector< dealii::Point< 1 > > get_equidistant_inner(unsigned int const n_points)
Definition interpolation.h:146
void interpolate(double const *&src)
Definition interpolation.h:196
void deserialize(char const *filename, double *&src)
Definition interpolation.h:302
Interpolator(MPI_Comm const &comm, Setup &s)
Definition interpolation.h:79
void serialize(char const *filename, double const *&src)
Definition interpolation.h:326
void interpolate()
Definition interpolation.h:182
void serialize(char const *filename)
Definition interpolation.h:313
void interpolate_simple()
Definition interpolation.h:248
void deserialize(char const *filename)
Definition interpolation.h:290
void interpolate_simple(double *&src)
Definition interpolation.h:262
void io(int type, char const *filename, VEC &src)
Definition interpolation.h:340
void fill_shape_values(dealii::AlignedVector< double > &shape_values)
Definition interpolation.h:162
Definition setup.h:56