TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
IJK_tools.cpp
1/****************************************************************************
2 * Copyright (c) 2023, CEA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9 *
10 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13 *
14 *****************************************************************************/
15
16#include <IJK_tools.h>
17#include <Parser.h>
18#include <IJK_ptr.h>
19#include <EChaine.h>
20#include <SChaine.h>
21#include <Interprete_bloc.h>
22
23static void extend_array(const Domaine_IJK& geom1, const int direction, const int ncells, ArrOfDouble& delta, double& origin)
24{
25 delta = geom1.get_delta(direction);
26 origin = geom1.get_origin(direction);
27
28 if (geom1.get_periodic_flag(direction))
29 {
30 // On cree des mailles supplementaires au debut et a la fin,
31 // on decale l'origine vers la "gauche"
32 const int n = delta.size_array(); // nombre de mailles initial
33 delta.resize_array(n + 2 * ncells);
34 int i;
35 // On decale les mailles vers la droite dans delta, de ncells:
36 for (i = n - 1; i >= 0; i--)
37 delta[i + ncells] = delta[i];
38 // On duplique les mailles dont on a besoin:
39 if (n < ncells)
40 {
41 Cerr << "Error in build_extended_splitting, direction " << direction << " extension of " << ncells << " not possible because we only have " << n << " cells in the domain." << finl;
43 }
44 for (i = 0; i < ncells; i++)
45 {
46 // Copie des mailles de droite a gauche:
47 delta[i] = delta[i + n];
48 // Decalage de l'origine:
49 origin -= delta[i];
50 // Copie des mailles de gauche a droite:
51 delta[ncells + i + n] = delta[ncells + i];
52 }
53 }
54}
55
56// split1 : Maillage d'origine sur lequel sont resolues les equations de NS.
57// split2 : Resultat etendu contenant le domaine ou vivent les interfaces.
58// n_cells : Nombre de cellules supplementaires crees de chaque cote.
59// (doit etre inferieur au nombre de mailles dans le domaine decoupee).
60void build_extended_splitting(const Domaine_IJK& geom1, Domaine_IJK& split2, int n_cells)
61{
62 double origin_x, origin_y, origin_z;
63 ArrOfDouble dx, dy, dz;
64 extend_array(geom1, DIRECTION_I, n_cells, dx, origin_x);
65 extend_array(geom1, DIRECTION_J, n_cells, dy, origin_y);
66 extend_array(geom1, DIRECTION_K, n_cells, dz, origin_z);
67
68 // Le domaine etendu n'est pas periodique: le champ n'est pas continu
69 // entre les bords opposes du domaine etendu.
70 Domaine_IJK geom2;
71 Nom n(geom1.le_nom());
72 geom2.nommer(n + "_EXT");
73 geom2.initialize_origin_deltas(origin_x, origin_y, origin_z, dx, dy, dz, geom1.get_periodic_flag(0), geom1.get_periodic_flag(1), geom1.get_periodic_flag(2));
74 // Construction du decoupage parallele: on utilise les memes parametres
75 // de decoupage que pour le maillage d'origine:
76 split2.initialize_splitting(geom2, geom1.get_nprocessor_per_direction(DIRECTION_I), geom1.get_nprocessor_per_direction(DIRECTION_J), geom1.get_nprocessor_per_direction(DIRECTION_K));
77}
78
79Probleme_base& creer_domaine_vdf(const Domaine_IJK& geom, const Nom& nom_domaine)
80{
81 // On va construire une partie de jdd a faire interpreter:
82 const double x0 = geom.get_origin(DIRECTION_I);
83 const double y0 = geom.get_origin(DIRECTION_J);
84 const double z0 = geom.get_origin(DIRECTION_K);
85 const double lx = geom.get_domain_length(DIRECTION_I);
86 const double ly = geom.get_domain_length(DIRECTION_J);
87 const double lz = geom.get_domain_length(DIRECTION_K);
88 const int nslicek = geom.get_nprocessor_per_direction(DIRECTION_K);
89 const int nslicej = geom.get_nprocessor_per_direction(DIRECTION_J);
90 const int nslicei = geom.get_nprocessor_per_direction(DIRECTION_I);
91 const int ni = geom.get_nb_elem_tot(DIRECTION_I) + 1; // number of nodes
92 const int nj = geom.get_nb_elem_tot(DIRECTION_J) + 1;
93 const int nk = geom.get_nb_elem_tot(DIRECTION_K) + 1;
94
95 char fonction_coord_x[300];
96 snprintf(fonction_coord_x, 300, "%.16g+x*%.16g", x0, lx);
97 char fonction_coord_y[300];
98 snprintf(fonction_coord_y, 300, "%.16g+y*%.16g", y0, ly);
99 char fonction_coord_z[300];
100 snprintf(fonction_coord_z, 300, "%.16g+z*%.16g", z0, lz);
101
102 SChaine instructions;
103 instructions << "Dimension 3 " << finl;
104 instructions << "Domaine " << nom_domaine << finl;
105 instructions << "MaillerParallel" << finl;
106 instructions << "{" << finl;
107 instructions << " domain " << nom_domaine << finl;
108 instructions << " nb_nodes 3 " << ni << " " << nj << " " << nk << finl;
109 instructions << " splitting 3 " << nslicei << " " << nslicej << " " << nslicek << finl;
110 instructions << " ghost_thickness 1" << finl;
111 instructions << " function_coord_x " << fonction_coord_x << finl;
112 instructions << " function_coord_y " << fonction_coord_y << finl;
113 instructions << " function_coord_z " << fonction_coord_z << finl;
114 instructions << " boundary_xmin xmin" << finl;
115 instructions << " boundary_xmax xmax" << finl;
116 instructions << " boundary_ymin ymin" << finl;
117 instructions << " boundary_ymax ymax" << finl;
118 instructions << " boundary_zmin zmin" << finl;
119 instructions << " boundary_zmax zmax" << finl;
120 const int np = Process::nproc();
121 instructions << " mapping " << finl;
122
123 IntTab map(np, 3);
124 map = -1;
125 for (int k = 0; k < nslicek; k++)
126 for (int j = 0; j < nslicej; j++)
127 for (int i = 0; i < nslicei; i++)
128 {
129 int p = geom.get_processor_by_ijk(i, j, k);
130 map(p, 0) = i;
131 map(p, 1) = j;
132 map(p, 2) = k;
133 }
134
135 if (min_array(map) < 0)
136 {
137 Cerr << "Error in creer_domaine_vdf: there are unused processors in the ijk splitting" << finl;
138 }
139 Nom pb_name = Nom("pb_") + nom_domaine;
140 instructions << map << finl;
141 instructions << "}" << finl;
142 instructions << "Probleme_FT_Disc_gen " << pb_name << finl;
143 instructions << "Associer " << pb_name << " " << nom_domaine << finl;
144 instructions << "VDF dis" << nom_domaine << finl;
145 instructions << "Schema_Euler_explicite sch" << nom_domaine << " Lire sch" << nom_domaine << " { nb_pas_dt_max 1 }" << finl;
146 instructions << "Associer " << pb_name << " sch" << nom_domaine << finl;
147 instructions << "Discretiser " << pb_name << " dis" << nom_domaine << finl;
148 Cerr << "Interpretation of the following string:" << finl << instructions.get_str();
149
150 EChaine is(instructions.get_str());
151 Interprete_bloc::interprete_courant().interpreter_bloc(is, Interprete_bloc::BLOC_EOF, 0 /* flag verifie sans interpreter */);
152
153 // Il faut construire une structure de donnees du Domaine_VF qui n'est pas construite par defaut:
155 Domaine& domaine = pb.domaine_dis().domaine();
157
158 return pb;
159}
160
161// Interpolate the "field" at the requested "coordinates" (array with 3 columns), and stores into "result"
162static void ijk_interpolate_implementation(const IJK_Field_double& field, const DoubleTab& coordinates, ArrOfDouble& result, int skip_unknown_points, double value_for_bad_points)
163{
164 const int ghost = field.ghost();
165 const int ni = field.ni();
166 const int nj = field.nj();
167 const int nk = field.nk();
168
169 const Domaine_IJK& geom = field.get_domaine();
170 const double dx = geom.get_constant_delta(DIRECTION_I);
171 const double dy = geom.get_constant_delta(DIRECTION_J);
172 const double dz = geom.get_constant_delta(DIRECTION_K);
174 // L'origine est sur un noeud. Donc que la premiere face en I est sur get_origin(DIRECTION_I)
175 double origin_x = geom.get_origin(DIRECTION_I) + ((loc == Domaine_IJK::FACES_J || loc == Domaine_IJK::FACES_K || loc == Domaine_IJK::ELEM) ? (dx * 0.5) : 0.);
176 double origin_y = geom.get_origin(DIRECTION_J) + ((loc == Domaine_IJK::FACES_K || loc == Domaine_IJK::FACES_I || loc == Domaine_IJK::ELEM) ? (dy * 0.5) : 0.);
177 double origin_z = geom.get_origin(DIRECTION_K) + ((loc == Domaine_IJK::FACES_I || loc == Domaine_IJK::FACES_J || loc == Domaine_IJK::ELEM) ? (dz * 0.5) : 0.);
178 const int nb_coords = coordinates.dimension(0);
179 result.resize_array(nb_coords);
180 for (int idx = 0; idx < nb_coords; idx++)
181 {
182 const double x = coordinates(idx, 0);
183 const double y = coordinates(idx, 1);
184 const double z = coordinates(idx, 2);
185 const double x2 = (x - origin_x) / dx;
186 const double y2 = (y - origin_y) / dy;
187 const double z2 = (z - origin_z) / dz;
188 const int index_i = (int) (floor(x2)) - geom.get_offset_local(DIRECTION_I);
189 const int index_j = (int) (floor(y2)) - geom.get_offset_local(DIRECTION_J);
190 const int index_k = (int) (floor(z2)) - geom.get_offset_local(DIRECTION_K);
191 // Coordonnes barycentriques du points dans la cellule :
192 const double xfact = x2 - floor(x2);
193 const double yfact = y2 - floor(y2);
194 const double zfact = z2 - floor(z2);
195
196 // is point in the domain ? (ghost cells ok...)
197 bool ok = (index_i >= -ghost && index_i < ni + ghost - 1) && (index_j >= -ghost && index_j < nj + ghost - 1) && (index_k >= -ghost && index_k < nk + ghost - 1);
198 if (!ok)
199 {
200 if (skip_unknown_points)
201 {
202 result[idx] = value_for_bad_points;
203 continue; // go to next point
204 }
205 else
206 {
207 // Error!
208 Cerr << "Error in ijk_interpolate_implementation: request interpolation of point " << x << " " << y << " " << z << " which is outside of the domain on processor " << Process::me()
209 << finl;
211 }
212 }
213
214 double r = (((1. - xfact) * field(index_i, index_j, index_k) + xfact * field(index_i + 1, index_j, index_k)) * (1. - yfact)
215 + ((1. - xfact) * field(index_i, index_j + 1, index_k) + xfact * field(index_i + 1, index_j + 1, index_k)) * (yfact)) * (1. - zfact)
216 + (((1. - xfact) * field(index_i, index_j, index_k + 1) + xfact * field(index_i + 1, index_j, index_k + 1)) * (1. - yfact)
217 + ((1. - xfact) * field(index_i, index_j + 1, index_k + 1) + xfact * field(index_i + 1, index_j + 1, index_k + 1)) * (yfact)) * (zfact);
218 result[idx] = r;
219 }
220}
221
222void ijk_interpolate_skip_unknown_points(const IJK_Field_double& field, const DoubleTab& coordinates, ArrOfDouble& result, const double value_for_bad_points)
223{
224 ijk_interpolate_implementation(field, coordinates, result, 1 /* yes:skip unknown points */, value_for_bad_points);
225}
226
227void ijk_interpolate(const IJK_Field_double& field, const DoubleTab& coordinates, ArrOfDouble& result)
228{
229 ijk_interpolate_implementation(field, coordinates, result, 0 /* skip unknown points=no */, 0.);
230}
231
232// Interpolate the "field" at the requested coordinate and returns the result
233static double ijk_interpolate_one_value(const IJK_Field_double& field, const Vecteur3& coordinates, int skip_unknown_points, double value_for_bad_points)
234{
235 const int ghost = field.ghost();
236 const int ni = field.ni();
237 const int nj = field.nj();
238 const int nk = field.nk();
239
240 const Domaine_IJK& geom = field.get_domaine();
241 const double dx = geom.get_constant_delta(DIRECTION_I);
242 const double dy = geom.get_constant_delta(DIRECTION_J);
243 const double dz = geom.get_constant_delta(DIRECTION_K);
245 // L'origine est sur un noeud. Donc que la premiere face en I est sur get_origin(DIRECTION_I)
246 double origin_x = geom.get_origin(DIRECTION_I) + ((loc == Domaine_IJK::FACES_J || loc == Domaine_IJK::FACES_K || loc == Domaine_IJK::ELEM) ? (dx * 0.5) : 0.);
247 double origin_y = geom.get_origin(DIRECTION_J) + ((loc == Domaine_IJK::FACES_K || loc == Domaine_IJK::FACES_I || loc == Domaine_IJK::ELEM) ? (dy * 0.5) : 0.);
248 double origin_z = geom.get_origin(DIRECTION_K) + ((loc == Domaine_IJK::FACES_I || loc == Domaine_IJK::FACES_J || loc == Domaine_IJK::ELEM) ? (dz * 0.5) : 0.);
249 const double x = coordinates[0];
250 const double y = coordinates[1];
251 const double z = coordinates[2];
252 const double x2 = (x - origin_x) / dx;
253 const double y2 = (y - origin_y) / dy;
254 const double z2 = (z - origin_z) / dz;
255 const int index_i = (int) (floor(x2)) - geom.get_offset_local(DIRECTION_I);
256 const int index_j = (int) (floor(y2)) - geom.get_offset_local(DIRECTION_J);
257 const int index_k = (int) (floor(z2)) - geom.get_offset_local(DIRECTION_K);
258 // Coordonnes barycentriques du points dans la cellule :
259 const double xfact = x2 - floor(x2);
260 const double yfact = y2 - floor(y2);
261 const double zfact = z2 - floor(z2);
262
263 // is point in the domain ? (ghost cells ok...)
264 bool ok = (index_i >= -ghost && index_i < ni + ghost - 1) && (index_j >= -ghost && index_j < nj + ghost - 1) && (index_k >= -ghost && index_k < nk + ghost - 1);
265 if (!ok)
266 {
267 if (skip_unknown_points)
268 {
269 return value_for_bad_points;
270 }
271 else
272 {
273 // Error!
274 Cerr << "Error in ijk_interpolate_implementation: request interpolation of point " << x << " " << y << " " << z << " which is outside of the domain on processor " << Process::me()
275 << finl;
277 }
278 }
279
280 double r = (((1. - xfact) * field(index_i, index_j, index_k) + xfact * field(index_i + 1, index_j, index_k)) * (1. - yfact)
281 + ((1. - xfact) * field(index_i, index_j + 1, index_k) + xfact * field(index_i + 1, index_j + 1, index_k)) * (yfact)) * (1. - zfact)
282 + (((1. - xfact) * field(index_i, index_j, index_k + 1) + xfact * field(index_i + 1, index_j, index_k + 1)) * (1. - yfact)
283 + ((1. - xfact) * field(index_i, index_j + 1, index_k + 1) + xfact * field(index_i + 1, index_j + 1, index_k + 1)) * (yfact)) * (zfact);
284 return r;
285}
286
287double ijk_interpolate_skip_unknown_points(const IJK_Field_double& field, const Vecteur3& coordinates, const double value_for_bad_points)
288{
289 return ijk_interpolate_one_value(field, coordinates, 1 /* yes:skip unknown points */, value_for_bad_points);
290}
291
292double ijk_interpolate(const IJK_Field_double& field, const Vecteur3& coordinates)
293{
294 return ijk_interpolate_one_value(field, coordinates, 0 /* skip unknown points=no */, 0.);
295}
296
297// build local coordinates of discretisation nodes for the given field
298// (used in set_field_data() )
299void build_local_coords(const IJK_Field_double& f, ArrOfDouble& coord_i, ArrOfDouble& coord_j, ArrOfDouble& coord_k)
300{
301 const Domaine_IJK& geom = f.get_domaine();
302 const int i_offset = f.get_domaine().get_offset_local(DIRECTION_I);
303 const int j_offset = f.get_domaine().get_offset_local(DIRECTION_J);
304 const int k_offset = f.get_domaine().get_offset_local(DIRECTION_K);
305
306 const ArrOfDouble& nodes_i = geom.get_node_coordinates(0);
307 const ArrOfDouble& nodes_j = geom.get_node_coordinates(1);
308 const ArrOfDouble& nodes_k = geom.get_node_coordinates(2);
309 const int ni = f.ni();
310 const int nj = f.nj();
311 const int nk = f.nk();
312 coord_i.resize_array(ni);
313 coord_j.resize_array(nj);
314 coord_k.resize_array(nk);
315
317 {
318 for (int i = 0; i < ni; i++)
319 coord_i[i] = nodes_i[i + i_offset];
320 }
321 else
322 {
323 for (int i = 0; i < ni; i++)
324 coord_i[i] = (nodes_i[i + i_offset] + nodes_i[i + i_offset + 1]) * 0.5;
325 }
327 {
328 for (int i = 0; i < nj; i++)
329 coord_j[i] = nodes_j[i + j_offset];
330 }
331 else
332 {
333 for (int i = 0; i < nj; i++)
334 coord_j[i] = (nodes_j[i + j_offset] + nodes_j[i + j_offset + 1]) * 0.5;
335 }
337 {
338 for (int i = 0; i < nk; i++)
339 coord_k[i] = nodes_k[i + k_offset];
340 }
341 else
342 {
343 for (int i = 0; i < nk; i++)
344 coord_k[i] = (nodes_k[i + k_offset] + nodes_k[i + k_offset + 1]) * 0.5;
345 }
346}
347
348// Initialize field with specified function of x,y,z
349void set_field_data(IJK_Field_double& f, double func(double, double, double))
350{
351 ArrOfDouble coord_i, coord_j, coord_k;
352 build_local_coords(f, coord_i, coord_j, coord_k);
353
354 const int ni = f.ni();
355 const int nj = f.nj();
356 const int nk = f.nk();
357
358 for (int k = 0; k < nk; k++)
359 {
360 double z = coord_k[k];
361 for (int j = 0; j < nj; j++)
362 {
363 double y = coord_j[j];
364 for (int i = 0; i < ni; i++)
365 {
366 double x = coord_i[i];
367 f(i, j, k) = func(x, y, z);
368 }
369 }
370 }
372}
373
374// GAB, Vy_initial non nul en reprise
375// field with specified string expression (must be understood by Parser class)
376void compose_field_data(IJK_Field_double& f, const Nom& parser_expression_of_x_y_z)
377{
378 ArrOfDouble coord_i, coord_j, coord_k;
379 build_local_coords(f, coord_i, coord_j, coord_k);
380
381 const int ni = f.ni();
382 const int nj = f.nj();
383 const int nk = f.nk();
384
385 std::string expr(parser_expression_of_x_y_z);
386 Parser parser;
387 parser.setString(expr);
388 parser.setNbVar(3);
389 parser.addVar("x");
390 parser.addVar("y");
391 parser.addVar("z");
392 parser.parseString();
393 for (int k = 0; k < nk; k++)
394 {
395 double z = coord_k[k];
396 parser.setVar(2, z);
397 for (int j = 0; j < nj; j++)
398 {
399 double y = coord_j[j];
400 parser.setVar(1, y);
401 for (int i = 0; i < ni; i++)
402 {
403 double x = coord_i[i];
404 parser.setVar((int) 0, x);
405 f(i, j, k) += parser.eval();
406 }
407 }
408 }
410}
411//
412
413// Initialize field with specified string expression (must be understood by Parser class)
414void set_field_data(IJK_Field_double& f, const Nom& parser_expression_of_x_y_z)
415{
416 ArrOfDouble coord_i, coord_j, coord_k;
417 build_local_coords(f, coord_i, coord_j, coord_k);
418
419 const int ni = f.ni();
420 const int nj = f.nj();
421 const int nk = f.nk();
422
423 std::string expr(parser_expression_of_x_y_z);
424 Parser parser;
425 parser.setString(expr);
426 parser.setNbVar(3);
427 parser.addVar("x");
428 parser.addVar("y");
429 parser.addVar("z");
430 parser.parseString();
431 for (int k = 0; k < nk; k++)
432 {
433 double z = coord_k[k];
434 parser.setVar(2, z);
435 for (int j = 0; j < nj; j++)
436 {
437 double y = coord_j[j];
438 parser.setVar(1, y);
439 for (int i = 0; i < ni; i++)
440 {
441 double x = coord_i[i];
442 parser.setVar((int) 0, x);
443 f(i, j, k) = parser.eval();
444 }
445 }
446 }
448}
449
450void set_field_data(IJK_Field_double& f, const Nom& parser_expression_of_x_y_z_and_t, const double current_time)
451{
452 ArrOfDouble coord_i, coord_j, coord_k;
453 build_local_coords(f, coord_i, coord_j, coord_k);
454
455 const int ni = f.ni();
456 const int nj = f.nj();
457 const int nk = f.nk();
458
459 std::string expr(parser_expression_of_x_y_z_and_t);
460 Parser parser;
461 parser.setString(expr);
462 parser.setNbVar(4);
463 parser.addVar("x");
464 parser.addVar("y");
465 parser.addVar("z");
466 parser.addVar("t");
467 parser.parseString();
468 parser.setVar(3, current_time);
469 for (int k = 0; k < nk; k++)
470 {
471 double z = coord_k[k];
472 parser.setVar(2, z);
473 for (int j = 0; j < nj; j++)
474 {
475 double y = coord_j[j];
476 parser.setVar(1, y);
477 for (int i = 0; i < ni; i++)
478 {
479 double x = coord_i[i];
480 parser.setVar((int) 0, x);
481 f(i, j, k) = parser.eval();
482 }
483 }
484 }
486}
487
488void set_field_data(IJK_Field_double& f, const Nom& parser_expression_of_x_y_z_and_t, const IJK_Field_double& input_f, const double current_time)
489{
490 ArrOfDouble coord_i, coord_j, coord_k;
491 build_local_coords(f, coord_i, coord_j, coord_k);
492
493 const int ni = f.ni();
494 const int nj = f.nj();
495 const int nk = f.nk();
496
497 std::string expr(parser_expression_of_x_y_z_and_t);
498 Parser parser;
499 parser.setString(expr);
500 parser.setNbVar(5);
501 parser.addVar("x");
502 parser.addVar("y");
503 parser.addVar("z");
504 parser.addVar("t");
505 parser.addVar("ff");
506 parser.parseString();
507 parser.setVar(3, current_time);
508 for (int k = 0; k < nk; k++)
509 {
510 double z = coord_k[k];
511 parser.setVar(2, z);
512 for (int j = 0; j < nj; j++)
513 {
514 double y = coord_j[j];
515 parser.setVar(1, y);
516 for (int i = 0; i < ni; i++)
517 {
518 double x = coord_i[i];
519 parser.setVar((int) 0, x);
520 parser.setVar(4, input_f(i, j, k));
521 f(i, j, k) = parser.eval();
522 }
523 }
524 }
526}
527
528void set_field_data(IJK_Field_double& f, const Nom& parser_expression_of_x_y_z_and_t, const IJK_Field_double& input_f1, const IJK_Field_double& input_f2, const double current_time)
529{
530 ArrOfDouble coord_i, coord_j, coord_k;
531 build_local_coords(f, coord_i, coord_j, coord_k);
532
533 const int ni = f.ni();
534 const int nj = f.nj();
535 const int nk = f.nk();
536
537 std::string expr(parser_expression_of_x_y_z_and_t);
538 Parser parser;
539 parser.setString(expr);
540 parser.setNbVar(6);
541 parser.addVar("x");
542 parser.addVar("y");
543 parser.addVar("z");
544 parser.addVar("t");
545 parser.addVar("f1");
546 parser.addVar("ff");
547 parser.parseString();
548 parser.setVar(3, current_time);
549 for (int k = 0; k < nk; k++)
550 {
551 double z = coord_k[k];
552 parser.setVar(2, z);
553 for (int j = 0; j < nj; j++)
554 {
555 double y = coord_j[j];
556 parser.setVar(1, y);
557 for (int i = 0; i < ni; i++)
558 {
559 double x = coord_i[i];
560 parser.setVar((int) 0, x);
561 parser.setVar(4, input_f1(i, j, k));
562 parser.setVar(5, input_f2(i, j, k));
563 f(i, j, k) = parser.eval();
564 }
565 }
566 }
568}
569
570
571void complex_to_trig(const double re, const double im, double& modul, double& arg)
572{
573 modul = sqrt(re * re + im * im);
574 if (re > 0)
575 {
576 arg = atan(im / re);
577 }
578 else if (re == 0)
579 {
580 if (im > 0)
581 arg = M_PI / 2.;
582 else
583 arg = -M_PI / 2.;
584 Cerr << "watchout!" << finl;
585 }
586 else
587 {
588 arg = M_PI + atan(im / re);
589 }
590 return;
591}
592
593void squared_3x3(double& a11, double& a12, double& a13, double& a21, double& a22, double& a23, double& a31, double& a32, double& a33)
594{
595 double aa11 = a11 * a11 + a12 * a21 + a13 * a31;
596 double aa12 = a11 * a12 + a12 * a22 + a13 * a32;
597 double aa13 = a11 * a13 + a12 * a23 + a13 * a33;
598 double aa21 = a21 * a11 + a22 * a21 + a23 * a31;
599 double aa22 = a21 * a12 + a22 * a22 + a23 * a32;
600 double aa23 = a21 * a13 + a22 * a23 + a23 * a33;
601 double aa31 = a31 * a11 + a32 * a21 + a33 * a31;
602 double aa32 = a31 * a12 + a32 * a22 + a33 * a32;
603 double aa33 = a31 * a13 + a32 * a23 + a33 * a33;
604
605 a11 = aa11;
606 a12 = aa12;
607 a13 = aa13;
608 a21 = aa21;
609 a22 = aa22;
610 a23 = aa23;
611 a31 = aa31;
612 a32 = aa32;
613 a33 = aa33;
614
615}
616
617
618void interpolate_to_center(IJK_Field_vector3_double& cell_center_field, const IJK_Field_vector3_double& face_field)
619{
620 // We are not changing the const semantic of the field to update ghost cells:
621 IJK_Field_vector3_double& face_fld_non_const = const_cast<IJK_Field_vector3_double&>(face_field);
622 face_fld_non_const.echange_espace_virtuel();
623 /* Interpole le champ face_field aux centres des elements et le stocke dans cell_center_field */
624 const int kmax = cell_center_field[0].nk();
625 const int jmax = cell_center_field[0].nj();
626 const int imax = cell_center_field[0].ni();
627 for (int k = 0; k < kmax; k++)
628 for (int j = 0; j < jmax; j++)
629 for (int i = 0; i < imax; i++)
630 {
631 cell_center_field[0](i,j,k) = (face_field[0](i,j,k) + face_field[0](i+1, j, k)) * 0.5;
632 cell_center_field[1](i,j,k) = (face_field[1](i,j,k) + face_field[1](i, j+1, k)) * 0.5;
633 cell_center_field[2](i,j,k) = (face_field[2](i,j,k) + face_field[2](i, j, k+1)) * 0.5;
634 }
635}
636
637void interpolate_to_center_compo(IJK_Field_double& cell_center_field_compo, const IJK_Field_double& face_field_compo)
638{
639 Domaine_IJK::Localisation loc = face_field_compo.get_localisation();
640 assert(loc != Domaine_IJK::ELEM && loc != Domaine_IJK::NODES);
641 const int kmax = cell_center_field_compo.nk(),
642 jmax = cell_center_field_compo.nj(),
643 imax = cell_center_field_compo.ni();
644 int ci = (int)loc == Domaine_IJK::FACES_I;
645 int cj = (int)loc == Domaine_IJK::FACES_J;
646 int ck = (int)loc == Domaine_IJK::FACES_K;
647
648 for (int k = 0; k < kmax; k++)
649 for (int j = 0; j < jmax; j++)
650 for (int i = 0; i < imax; i++)
651 cell_center_field_compo(i,j,k) = (face_field_compo(i,j,k) + face_field_compo(i+ci, j+cj, k+ck)) * 0.5;
652}
653
654
void construire_elem_virt_pe_num()
Definition Domaine.cpp:704
This class encapsulates all the information related to the eulerian mesh for TrioIJK.
Definition Domaine_IJK.h:47
int get_offset_local(int direction) const
Returns the local offset in requested direction.
int get_processor_by_ijk(const FixedVector< int, 3 > &slice) const
Return the global index of the processor according to its position.
bool get_periodic_flag(int direction) const
Method returns true if periodic in this direction.
double get_domain_length(int direction) const
Returns the length of the entire domain in requested direction.
int get_nprocessor_per_direction(int direction) const
Returns the number of slices in the given direction.
double get_constant_delta(int direction) const
Returns the size of cells in a direction.
const ArrOfDouble & get_delta(int direction) const
Returns the array of mesh cell sizes in requested direction.
double get_origin(int direction) const
Returns the coordinate of the first node (global) of the mesh in the requested direction.
void initialize_splitting(Domaine_IJK &dom, int nproc_i, int nproc_j, int nproc_k, int process_grouping_i=1, int process_grouping_j=1, int process_grouping_k=1)
Buils a splitting of the given deometry on the requested number of processors in each direction.
int get_nb_elem_tot(int direction) const
Returns the total (global) number of mesh cells in requested direction.
const ArrOfDouble & get_node_coordinates(int direction) const
Returns an array with the coordinates of all nodes in the mesh in requested direction.
void initialize_origin_deltas(double x0, double y0, double z0, const ArrOfDouble &delta_x, const ArrOfDouble &delta_y, const ArrOfDouble &delta_z, bool perio_x, bool perio_y, bool perio_z)
Initializes class elements given dataset's parameters.
Localisation
Localisation sub class.
Definition Domaine_IJK.h:53
void nommer(const Nom &nom) override
Donne un nom a l'Objet_U Methode virtuelle a surcharger.
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
const Domaine & domaine() const
Une entree dont la source est une chaine de caracteres.
Definition EChaine.h:31
void echange_espace_virtuel(int ghost)
Exchange data over "ghost" number of cells.
Domaine_IJK::Localisation get_localisation() const
const Domaine_IJK & get_domaine() const
Entree & interpreter_bloc(Entree &is, Bloc_Type bloc_type, int verifier_sans_interpreter)
Interpretation d'un bloc d'instructions prises dans l'entree is.
static Interprete_bloc & interprete_courant()
renvoie l'interprete_bloc en train d'etre lu dans le jeu de donnees.
static Objet_U & objet_global(const Nom &nom)
cherche l'objet demande dans l'Interprete_bloc courant (Interprete_bloc::interprete_courant()) et dan...
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
Representation des donnees de la classe Parser.
Definition Parser.h:39
void addVar(const char *)
Definition Parser.cpp:565
virtual void setNbVar(int nvar)
Definition Parser.cpp:116
void setVar(const char *sv, double val)
Definition Parser.h:73
double eval()
Definition Parser.h:68
void setString(const std::string &s)
Definition Parser.h:102
virtual void parseString()
Definition Parser.cpp:124
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Domaine_dis_base & domaine_dis() const
Renvoie le domaine discretise associe au probleme.
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Cette classe derivee de Sortie empile ce qu'on lui envoie dans une chaine de caracteres.
Definition SChaine.h:26
const char * get_str() const
returns a copy of the string stored by the SChaine
Definition SChaine.cpp:72
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133