TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Sonde.cpp
1/****************************************************************************
2* Copyright (c) 2026, 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 <Champ_Generique_Interpolation.h>
17#include <Champ_Generique_refChamp.h>
18#include <Domaine_Cl_dis_base.h>
19#include <Entree_complete.h>
20
21#include <Process.h>
22#include <Champ_Inc_base.h>
23#include <Postraitement.h>
24#include <Domaine_VF.h>
25#include <sys/stat.h>
26#include <Sonde.h>
27
28Implemente_instanciable_sans_constructeur_ni_destructeur(Sonde,"Sonde",Objet_U);
29// XD sonde objet_lecture nul NO_BRACE Keyword is used to define the probes. Observations: the probe coordinates should
30// XD_CONT be given in Cartesian coordinates (X, Y, Z), including axisymmetric.
31// XD attr nom_sonde chaine nom_sonde REQ Name of the file in which the values taken over time will be saved. The
32// XD_CONT complete file name is nom_sonde.son.
33// XD attr special chaine(into=["grav","som","nodes","chsom","gravcl"]) special OPT Option to change the positions of
34// XD_CONT the probes. Several options are available: NL2 grav : each probe is moved to the nearest cell center of the
35// XD_CONT mesh; NL2 som : each probe is moved to the nearest vertex of the mesh NL2 nodes : each probe is moved to the
36// XD_CONT nearest face center of the mesh; NL2 chsom : only available for P1NC sampled field. The values of the probes
37// XD_CONT are calculated according to P1-Conform corresponding field. NL2 gravcl : Extend to the domain face boundary a
38// XD_CONT cell-located segment probe in order to have the boundary condition for the field. For this type the extreme
39// XD_CONT probe point has to be on the face center of gravity.
40// XD attr nom_inco chaine nom_inco REQ Name of the sampled field.
41// XD attr mperiode chaine(into=["periode"]) mperiode REQ Keyword to set the sampled field measurement frequency.
42// XD attr prd floattant prd REQ Period value. Every prd seconds, the field value calculated at the previous time step
43// XD_CONT is written to the nom_sonde.son file.
44// XD attr type sonde_base type REQ Type of probe.
45
46// XD sonde_base objet_lecture sonde_base NO_BRACE Basic probe. Probes refer to sensors that allow a value or several
47// XD_CONT points of the domain to be monitored over time. The probes may be a set of points defined one by one (keyword
48// XD_CONT Points) or a set of points evenly distributed over a straight segment (keyword Segment) or arranged according
49// XD_CONT to a layout (keyword Plan) or according to a parallelepiped (keyword Volume). The fields allow all the values
50// XD_CONT of a physical value on the domain to be known at several moments in time.
51
52// XD segmentfacesx sonde_base segmentfacesx NO_BRACE Segment probe where points are moved to the nearest x faces
53// XD attr nbr entier nbr REQ Number of probe points of the segment, evenly distributed.
54// XD attr point_deb un_point point_deb REQ First outer probe segment point.
55// XD attr point_fin un_point point_fin REQ Second outer probe segment point.
56
57// XD segmentfacesy sonde_base segmentfacesy NO_BRACE Segment probe where points are moved to the nearest y faces
58// XD attr nbr entier nbr REQ Number of probe points of the segment, evenly distributed.
59// XD attr point_deb un_point point_deb REQ First outer probe segment point.
60// XD attr point_fin un_point point_fin REQ Second outer probe segment point.
61
62// XD segmentfacesz sonde_base segmentfacesz NO_BRACE Segment probe where points are moved to the nearest z faces
63// XD attr nbr entier nbr REQ Number of probe points of the segment, evenly distributed.
64// XD attr point_deb un_point point_deb REQ First outer probe segment point.
65// XD attr point_fin un_point point_fin REQ Second outer probe segment point.
66
67// XD radius sonde_base radius NO_BRACE not_set
68// XD attr nbr entier nbr REQ Number of probe points of the segment, evenly distributed.
69// XD attr point_deb un_point point_deb REQ First outer probe segment point.
70// XD attr radius floattant radius REQ not_set
71// XD attr teta1 floattant teta1 REQ not_set
72// XD attr teta2 floattant teta2 REQ not_set
73
74// XD un_point objet_lecture nul NO_BRACE A point.
75// XD attr pos listf pos REQ Point coordinates.
76
77// XD listpoints listobj nul NO_BRACE un_point NO_COMMA Points.
78// XD points sonde_base points NO_BRACE Keyword to define the number of probe points. The file is arranged in columns.
79// XD attr points listpoints points REQ Probe points.
80
81// XD numero_elem_sur_maitre sonde_base numero_elem_sur_maitre NO_BRACE Keyword to define a probe at the special
82// XD_CONT element. Useful for min/max sonde.
83// XD attr numero entier numero REQ element number
84
85// XD segmentpoints points segmentpoints NO_BRACE This keyword is used to define a probe segment from specifics points.
86// XD_CONT The nom_champ field is sampled at ns specifics points.
87
88// XD position_like sonde_base position_like NO_BRACE Keyword to define a probe at the same position of another probe
89// XD_CONT named autre_sonde.
90// XD attr autre_sonde chaine autre_sonde REQ Name of the other probe.
91
92// XD plan sonde_base plan NO_BRACE Keyword to set the number of probe layout points. The file format is type .lml
93// XD attr nbr entier nbr REQ Number of probes in the first direction.
94// XD attr nbr2 entier nbr2 REQ Number of probes in the second direction.
95// XD attr point_deb un_point point_deb REQ First point defining the angle. This angle should be positive.
96// XD attr point_fin un_point point_fin REQ Second point defining the angle. This angle should be positive.
97// XD attr point_fin_2 un_point point_fin_2 REQ Third point defining the angle. This angle should be positive.
98
99// XD volume sonde_base volume NO_BRACE Keyword to define the probe volume in a parallelepiped passing through 4 points
100// XD_CONT and the number of probes in each direction.
101// XD attr nbr entier nbr REQ Number of probes in the first direction.
102// XD attr nbr2 entier nbr2 REQ Number of probes in the second direction.
103// XD attr nbr3 entier nbr3 REQ Number of probes in the third direction.
104// XD attr point_deb un_point point_deb REQ Point of origin.
105// XD attr point_fin un_point point_fin REQ Point defining the first direction (from point of origin).
106// XD attr point_fin_2 un_point point_fin_2 REQ Point defining the second direction (from point of origin).
107// XD attr point_fin_3 un_point point_fin_3 REQ Point defining the third direction (from point of origin).
108
109// XD circle sonde_base circle NO_BRACE Keyword to define several probes located on a circle.
110// XD attr nbr entier nbr REQ Number of probes between teta1 and teta2 (angles given in degrees).
111// XD attr point_deb un_point point_deb REQ Center of the circle.
112// XD attr direction entier(into=[0,1,2]) direction OPT Axis normal to the circle plane (0:x axis, 1:y axis, 2:z axis).
113// XD attr radius floattant radius REQ Radius of the circle.
114// XD attr theta1 floattant theta1 REQ First angle.
115// XD attr theta2 floattant theta2 REQ Second angle.
116
117// XD circle_3 sonde_base circle_3 NO_BRACE Keyword to define several probes located on a circle (in 3-D space).
118// XD attr nbr entier nbr REQ Number of probes between teta1 and teta2 (angles given in degrees).
119// XD attr point_deb un_point point_deb REQ Center of the circle.
120// XD attr direction entier(into=[0,1,2]) direction REQ Axis normal to the circle plane (0:x axis, 1:y axis, 2:z axis).
121// XD attr radius floattant radius REQ Radius of the circle.
122// XD attr theta1 floattant theta1 REQ First angle.
123// XD attr theta2 floattant theta2 REQ Second angle.
124
125static int fichier_sondes_cree=0;
126static SFichier fichier_sondes;
127
128/*! @brief Constructor for a probe, given its name.
129 *
130 * @param nom the name of the probe to construct
131 */
132Sonde::Sonde(const Nom& nom) :
133 nom_(nom),
134 dim(-1),
135 ncomp(-1),
136 numero_elem_(-1),
137 periode(1.e10), // default period initialization
138 nb_bip(0.),
140{}
141
142/*! @brief Default constructor for a probe.
143 *
144 */
146 Sonde(Nom()) // thank you C++11
147{}
148
149/*! @brief Prints the type of the object to an output stream.
150 *
151 * @param (Sortie& s) an output stream
152 * @return (Sortie&) the modified output stream
153 */
154Sortie& Sonde::printOn(Sortie& s ) const
155{
156 return s << que_suis_je();
157}
158
160{
161 // Recherche du champ sonde
162 // Remplissage de la reference au champ
163 Cerr << "Reading of the probe: " << nom_ << " on the field: " << nom_champ_lu_ << finl;
164 //We should access the domain through the generic field
165 //But the reference has not been made yet
166 Probleme_base& Pb = mon_post->probleme();
167 const Motcle nom_domaine = mon_post->domaine()->le_nom();
168 Motcle nom_champ_ref;
169 Motcle nom_macro=nom_champ_lu_;
170 Motcle nom_macro_test, nom1("_not_def"), nom2("_not_def");
171 const Motcles& noms_champs_postraitables = mon_post->les_sondes().get_noms_champs_postraitables();
172 if (!(noms_champs_postraitables.contient_(nom_champ_lu_)||mon_post->comprend_champ_post(nom_champ_lu_)))
173 {
174 if (nom_champ_lu_.debute_par("MOYENNE_"))
175 nom_macro = nom_macro.suffix("MOYENNE_");
176 else if (nom_champ_lu_.debute_par("ECART_TYPE_"))
177 nom_macro = nom_macro.suffix("ECART_TYPE_");
178
179 if (nom_champ_lu_.debute_par("CORRELATION_"))
180 {
181 nom_macro_test = nom_champ_lu_;
182 nom_macro_test = nom_macro_test.suffix("CORRELATION_");
183 for (auto& itr : noms_champs_postraitables)
184 {
185 nom_macro_test = nom_macro_test.suffix(itr);
186 if (nom_macro_test.debute_par("_"))
187 {
188 nom1 = itr;
189 nom2 = nom_macro_test.suffix("_");
190 }
191 }
192 }
193 }
194
195 if (noms_champs_postraitables.contient_(nom_macro))
196 {
197 if (nom_macro==Motcle(nom_champ_lu_))
198 {
199 OBS_PTR(Champ_base) champ_ref = Pb.get_champ(nom_champ_lu_);
200 const Nom& nom_champ_base = champ_ref->le_nom();
201 const Noms& compos_base = champ_ref->noms_compo();
202 int ncomposante = Champ_Generique_base::composante(nom_champ_lu_,nom_champ_base,compos_base,champ_ref->get_synonyms());
203
204 if (ncomposante==-1)
205 nom_champ_ref = nom_champ_base +"_natif_"+ nom_domaine;
206 else
207 {
208 Nom nume(ncomposante);
209 nom_champ_ref = nom_champ_base+"_natif_"+ nom_domaine+nume;
210 }
211 }
212 else
213 nom_champ_ref = nom_champ_lu_+"_natif_"+nom_domaine;
214 }
215 else
216 {
217 //Case of correlations
218 if ((noms_champs_postraitables.contient_(nom1)) && (noms_champs_postraitables.contient_(nom2)))
219 {
220 nom_champ_ref = "Correlation_";
221 nom_champ_ref += nom1+"_natif_"+nom_domaine+"_"+nom2+"_natif_"+nom_domaine;
222 }
223 else
224 //Case of a general generic field
225 nom_champ_ref = nom_champ_lu_;
226 }
227
228 mon_champ = mon_post->get_champ_post(nom_champ_ref);
229
230 // Filling the ncomp attribute (its default value is -1)
231
232 const Noms nom_champ = mon_champ->get_property("nom");
233 const Noms noms_comp = mon_champ->get_property("composantes");
234 ncomp = Champ_Generique_base::composante(nom_champ_ref,nom_champ[0],noms_comp,mon_champ->get_property("synonyms"));
235
236 initialiser();
237}
238/*! @brief Reads the specifications of a probe from an input stream.
239 *
240 * Format:
241 * Sondes
242 * {
243 * [nom_sonde nom_champ Periode dts Points n x1 y1 [z1] ... xn yn [zn]
244 * [nom_sonde nom_champ Periode dts Segment ns x1 y1 [z1] x2 y2 [z2]
245 * ...
246 * }
247 *
248 * @param (Entree& is) an input stream
249 * @return (Entree&) the modified input stream
250 * @throws probe data not defined
251 * @throws format error, unknown keyword
252 * @throws probe data not correctly defined
253 */
255{
256 assert(mon_post);
257 Motcle motlu;
258 //Motcle accolade_ouverte("{");
259 Motcle accolade_fermee("}");
260 int nbre_points;
261
262 is >> motlu;
263 // Reading a keyword that is not the field
264 if (motlu=="nodes")
265 {
266 nodes = true;
267 is >> motlu;
268 }
269 else if (motlu=="chsom")
270 {
271 chsom = true;
272 is >> motlu;
273 }
274 else if (motlu=="grav")
275 {
276 grav = true;
277 is >> motlu;
278 }
279 else if (motlu=="gravcl")
280 {
281 gravcl = true;
282 is >> motlu;
283 }
284 else if (motlu=="som")
285 {
286 som = true;
287 is >> motlu;
288 }
289 // Assign the field name
290 nom_champ_lu_ = motlu;
291
293 create_champ_generique(is, motlu);
294
295 // Reading the probe characteristics
296 IntVect fait(2);
297
298 Motcles les_motcles(16);
299 {
300 les_motcles[0] = "periode";
301 les_motcles[1] = "point";
302 les_motcles[2] = "points";
303 les_motcles[3] = "segment";
304 les_motcles[4] = "plan";
305 les_motcles[5] = "volume";
306 les_motcles[6] = "segmentxdx";
307 les_motcles[7] = "planxdxdy";
308 les_motcles[8] = "circle";
309 les_motcles[9] = "position_like";
310 les_motcles[10] = "numero_elem_sur_maitre";
311 les_motcles[11] = "segmentpoints";
312 les_motcles[12] = "segmentfacesx";
313 les_motcles[13] = "segmentfacesy";
314 les_motcles[14] = "segmentfacesz";
315 les_motcles[15] = "radius";
316 }
317
318 while ((fait(0) != 1) || (fait(1) != 1))
319 {
320 is >> motlu;
321 if (motlu == accolade_fermee)
322 {
323 Cerr << "Error while reading the probe " << nom_ <<finl;
324 Cerr << "The data of the probe were not defined" << finl;
325 exit();
326 }
327 int rang=les_motcles.search(motlu);
328 if (rang == -1)
329 {
330 Cerr << "Error while reading the probe " << nom_ <<finl;
331 Cerr << motlu << " is not understood; the keywords understood are : " << finl;
332 Cerr << les_motcles;
333 exit();
334 }
335
336 if(rang != 0)
337 validate_type(motlu); // restrict valid localisation for IJK notably
338
339 switch(rang)
340 {
341 case 0:
342 {
343 is >> periode;
344 break;
345 }
346 case 1:
347 case 2:
348 case 11:
349 {
350 type_ = les_motcles[rang];
351 rang = 1;
352 dim = 0;
353 is >> nbre_points;
354 les_positions_sondes_initiales_.resize(nbre_points,dimension);
355
356 for (int i=0; i<nbre_points; i++)
357 for (int j=0; j<dimension; j++)
359
360 break;
361 }
362 case 10:
363 {
364 type_ = les_motcles[rang];
365 rang=1;
366 dim=0;
367 gravcl = false;
368 is >> numero_elem_;
370 break;
371 }
372 case 3:
373 case 6:
374 case 12:
375 case 13:
376 case 14:
377 {
378 type_ = les_motcles[rang];
379 int rang2=rang;
380 rang = 1;
381 dim = 1;
382 if (rang2==12 || rang2==13 || rang2==14)
383 {
384 nodes = true;
385 grav = false;
386 gravcl = false;
387 som = false;
388 }
389 const Motcle mot = type_.getSuffix("SEGMENTFACES");
390 Motcles nom_dir(3);
391
392 nom_dir[0] = "X";
393 nom_dir[1] = "Y";
394 nom_dir[2] = "Z";
395
396 orientation_faces_ = nom_dir.search(mot);
397
398 DoubleVect origine(dimension);
399 DoubleVect extremite(dimension);
400 DoubleVect dx(dimension);
401 is >> nbre_points;
402 les_positions_sondes_initiales_.resize(nbre_points,dimension);
403
404 for (int i=0; i<dimension; i++)
405 {
406 is >> origine(i);
407 type_+=" ";
408 type_+=(Nom)origine(i);
409 }
410 for (int i=0; i<dimension; i++)
411 {
412 is >> extremite(i);
413 type_+=" ";
414 type_+=(Nom)extremite(i);
415 }
416 for (int i=0; i<dimension; i++)
417 if (rang2==6)
418 dx(i)=(extremite(i))/(nbre_points-1);
419 else
420 dx(i)=(extremite(i)-origine(i))/(nbre_points-1);
421 for (int i=0; i<nbre_points; i++)
422 for (int j=0; j<dimension; j++)
423 les_positions_sondes_initiales_(i,j)=origine(j)+i*dx(j);
424 break;
425 }
426 case 4:
427 case 7:
428 {
429 type_ = les_motcles[rang];
430 int rang2=rang;
431 rang = 1;
432 dim = 2;
433 gravcl = false;
434 DoubleVect origine(dimension);
435 DoubleVect extremite1(dimension);
436 DoubleVect extremite2(dimension);
437 DoubleVect dx1(dimension);
438 DoubleVect dx2(dimension);
439 is >> nbre_points1;
440 is >> nbre_points2;
441 nbre_points=nbre_points1*nbre_points2;
442 les_positions_sondes_initiales_.resize(nbre_points,dimension);
443
444 for (int i=0; i<dimension; i++)
445 is >> origine(i);
446 for (int i=0; i<dimension; i++)
447 is >> extremite1(i);
448 for (int i=0; i<dimension; i++)
449 is >> extremite2(i);
450 if (rang2==7)
451 {
452 for (int i=0; i<dimension; i++)
453 dx1(i)=(extremite1(i))/(nbre_points1-1);
454 for (int i=0; i<dimension; i++)
455 dx2(i)=(extremite2(i))/(nbre_points2-1);
456 }
457 else
458 {
459 for (int i=0; i<dimension; i++)
460 dx1(i)=(extremite1(i)-origine(i))/(nbre_points1-1);
461 for (int i=0; i<dimension; i++)
462 dx2(i)=(extremite2(i)-origine(i))/(nbre_points2-1);
463 }
464 for (int i=0; i<nbre_points1; i++)
465 for (int j=0; j<nbre_points2; j++)
466 for (int k=0; k<dimension; k++)
467 les_positions_sondes_initiales_(i*nbre_points2+j,k)=origine(k)+i*dx1(k)+j*dx2(k);
468 break;
469 }
470
471 case 5:
472 {
473 type_ = les_motcles[rang];
474 rang = 1;
475 dim = 3;
476 gravcl = false;
477 ArrOfDouble origine(dimension);
478 ArrOfDouble extremite1(dimension);
479 ArrOfDouble extremite2(dimension);
480 ArrOfDouble extremite3(dimension);
481 ArrOfDouble dx1(dimension);
482 ArrOfDouble dx2(dimension);
483 ArrOfDouble dx3(dimension);
484 is >> nbre_points1;
485 is >> nbre_points2;
486 is >> nbre_points3;
488 les_positions_sondes_initiales_.resize(nbre_points,dimension);
489
490 for (int i=0; i<dimension; i++)
491 is >> origine[i];
492 for (int i=0; i<dimension; i++)
493 is >> extremite1[i];
494 for (int i=0; i<dimension; i++)
495 is >> extremite2[i];
496 for (int i=0; i<dimension; i++)
497 is >> extremite3[i];
498 for (int i=0; i<dimension; i++)
499 dx1[i]=(extremite1[i]-origine[i])/(nbre_points1-1);
500 for (int i=0; i<dimension; i++)
501 dx2[i]=(extremite2[i]-origine[i])/(nbre_points2-1);
502 for (int i=0; i<dimension; i++)
503 dx3[i]=(extremite3[i]-origine[i])/(nbre_points3-1);
504 for (int i=0; i<nbre_points1; i++)
505 for (int j=0; j<nbre_points2; j++)
506 for (int m=0; m<nbre_points3; m++)
507 for (int k=0; k<dimension; k++)
508 les_positions_sondes_initiales_(i+j*nbre_points1+m*nbre_points1*nbre_points2,k)=origine[k]+i*dx1[k]+j*dx2[k]+m*dx3[k];
509 break;
510 }
511 case 8:
512 {
513 type_ = les_motcles[rang];
514 // circle nbre_points x0 y0 [z0 dir] radius teta1 teta2
515 rang = 1;
516 dim = 1;
517 gravcl = false;
518 int dir;
519 double radius, teta1, teta2;
520 DoubleVect origine(dimension);
521 is >> nbre_points;
522 les_positions_sondes_initiales_.resize(nbre_points,dimension);
523 for (int i=0; i<dimension; i++)
524 is >> origine(i);
525 if (dimension==3) is >> dir;
526 is >> radius >> teta1 >> teta2;
527 // Adding information
528 for (int i=0; i<dimension; i++)
529 {
530 type_+=" ";
531 type_+=(Nom)origine(i);
532 }
533 type_+=" ";
534 type_+=(Nom)radius;
535 type_+=" ";
536 type_+=(Nom)teta1;
537 type_+=" ";
538 type_+=(Nom)teta2;
539 // We calculate the positions
540 for (int i=0; i<nbre_points; i++)
541 {
542 double angle=teta1+(teta2-teta1)*i/(nbre_points-1);
543 angle*=M_PI/180;
544 if (dimension==2)
545 {
546 les_positions_sondes_initiales_(i,0)=origine(0)+radius*cos(angle);
547 les_positions_sondes_initiales_(i,1)=origine(1)+radius*sin(angle);
548 }
549 else if (dimension==3)
550 {
551 if (dir==0)
552 {
553 les_positions_sondes_initiales_(i,0)=origine(0);
554 les_positions_sondes_initiales_(i,1)=origine(1)+radius*cos(angle);
555 les_positions_sondes_initiales_(i,2)=origine(2)+radius*sin(angle);
556 }
557 else if (dir==1)
558 {
559 les_positions_sondes_initiales_(i,0)=origine(0)+radius*cos(angle);
560 les_positions_sondes_initiales_(i,1)=origine(1);
561 les_positions_sondes_initiales_(i,2)=origine(2)+radius*sin(angle);
562 }
563 else if (dir==2)
564 {
565 les_positions_sondes_initiales_(i,0)=origine(0)+radius*cos(angle);
566 les_positions_sondes_initiales_(i,1)=origine(1)+radius*sin(angle);
567 les_positions_sondes_initiales_(i,2)=origine(2);
568 }
569 }
570 }
571 break;
572 }
573 case 15:
574 {
575 assert(dimension==3);
576 type_ = les_motcles[rang];
577 // radius nbre_points x0 y0 z0 theta radius1 radius2
578 rang = 1;
579 dim = 1;
580 gravcl = false;
581 double theta, radius1, radius2;
582 DoubleVect origine(dimension);
583 is >> nbre_points;
584 les_positions_sondes_initiales_.resize(nbre_points,dimension);
585 for (int i=0; i<dimension; i++)
586 is >> origine(i);
587 is >> theta >> radius1 >> radius2;
588 // Adding information
589 for (int i=0; i<dimension; i++)
590 {
591 type_+=" ";
592 type_+=(Nom)origine(i);
593 }
594 type_+=" ";
595 type_+=(Nom)theta;
596 type_+=" ";
597 type_+=(Nom)radius1;
598 type_+=" ";
599 type_+=(Nom)radius2;
600 // We calculate the positions
601 theta*=M_PI/180;
602 for (int i=0; i<nbre_points; i++)
603 {
604 double radius = radius1+(radius2-radius1)*i/(nbre_points-1);
605 les_positions_sondes_initiales_(i,0)=origine(0)+radius*cos(theta);
606 les_positions_sondes_initiales_(i,1)=origine(1)+radius*sin(theta);
607 les_positions_sondes_initiales_(i,2)=origine(2);
608 }
609 break;
610 }
611 case 9:
612 {
613 Motcle autre_sonde;
614 is >> autre_sonde;
615 // on cherche la sonde correspondante
616 int m=-1;
617 const Sondes& les_sondes=mon_post->les_sondes();
618 for (int i=0; i<les_sondes.size(); i++)
619 if (les_sondes(i)->get_nom()==autre_sonde)
620 {
621 m=i;
622 break;
623 }
624 //else Cerr<<les_sondes(i).get_nom()<<finl;
625 if (m==-1)
626 {
627 Cerr<<" The probe name "<<autre_sonde<< " was not found"<<finl;
628 exit();
629 }
630 // on recupere les_positions_
631 const Sonde& la_sonde_ref=les_sondes(m);
632 type_ = la_sonde_ref.get_type();
634 dim = la_sonde_ref.get_dim();
635 rang=1;
636 break;
637 }
638 default:
639 {
640 Cerr << motlu <<"is not yet understood!" << finl;
641 exit();
642 }
643 }
644 fait(rang) = 1;
645 }
646 if ( (fait[0] == 0) || (fait[1] == 0) || (dim==-1))
647 {
648 Cerr << "Error while reading the probe " << nom_ << finl;
649 Cerr << "The data of the probe have not been properly defined" << finl;
650 exit();
651 }
652
653 // Build the file name associated with the probe
655 nom_fichier_+= "_";
657 if (dim==2)
658 nom_fichier_+= ".plan";
659 else
660 nom_fichier_+= ".son";
661
663 {
664 // Adding the probe file name to the file listing probes
665 // This file will be used by Run_sonde
666 // SFichier fichier_sondes;
667 Nom nom_fich = nom_du_cas();
668 nom_fich += ".sons";
669 if (!fichier_sondes.is_open())
670 {
671 if (!fichier_sondes_cree)
672 fichier_sondes.ouvrir(nom_fich);
673 else
674 fichier_sondes.ouvrir(nom_fich, ios::app);
675 }
676 fichier_sondes << nom_fichier_ << finl;
677 fichier_sondes_cree = 1;
678 }
679 return is;
680}
681
682/** Creation of Champ_Generique_refChamp objects needed for initializing the REF to Champ_Generique_base.
683 * If the requested field is a Champ_base known to the problem, the corresponding Champ_Generique_refChamp is created.
684 */
686{
687 Probleme_base& Pb = mon_post->probleme();
688 const Motcles& noms_champs_postraitables = mon_post->les_sondes().get_noms_champs_postraitables();
689 if (noms_champs_postraitables.contient_(nom_champ_lu_))
690 {
692 //We will create a Champ_Generique_refChamp whose name is based on
693 //the name of the field it references, not a component of that field
694 OBS_PTR(Champ_base) champ_ref = Pb.get_champ(nom_champ_lu_);
695 const Nom& le_nom_champ = champ_ref->le_nom();
696 const Motcle nom_domaine = mon_post->domaine()->le_nom();
697 Motcle identifiant;
698
699 identifiant = Motcle(le_nom_champ)+"_natif_"+nom_domaine;
700 if (!mon_post->comprend_champ_post(identifiant))
701 {
702 mon_post->creer_champ_post(le_nom_champ,"natif",is);
703 }
704 }
705 else
706 {
707 Nom expression;
708 int is_champ_predefini = Pb.expression_predefini(motlu,expression);
709 if ((is_champ_predefini) && (!mon_post->comprend_champ_post(nom_champ_lu_)))
710 {
711 OWN_PTR(Champ_Generique_base) champ;
712 Entree_complete s_complete(expression,is);
713 s_complete>>champ;
714 mon_post->complete_champ(champ,nom_champ_lu_);
715 }
716 }
717}
718
719/*! @brief Associates the post-processing object with the probe.
720 *
721 * @param (Postraitement& le_post) the post-processing object to associate
722 */
724{
725 mon_post=le_post;
726 if (mon_post->noms_fichiers_sondes().contient(nom_)==0)
727 mon_post->noms_fichiers_sondes().add(nom_);
728 else
729 {
730 Cerr << "The filename " << nom_ << " is used several times for probes." << finl;
731 Cerr << "A probe must have a unique filename to avoid writing conflicts." << finl;
732 exit();
733 }
734}
735
736const Domaine& Sonde::get_domaine_geom() const
737{
738 return mon_champ->get_ref_domain();
739}
740
742{
743 return mon_champ->get_property("nom");
744}
745
747{
748 const Noms noms_comp = mon_champ->get_property("composantes");
749 Motcle directive = mon_champ->get_directive_pour_discr();
750 int nb_comp = (directive == "champ_Fonc_Quad_DG" || directive == "champ_elem_DG") ? 1 : noms_comp.size();
751 return nb_comp;
752}
753
755{
756 // TODO ABN : when is it different from Pb::temps_courant ?? Inc fields maybe ?
757 return mon_champ->get_time();
758}
759
761{
762 int nbre_points_tot = les_positions_sondes_.dimension(0);
763 DoubleTab coords_bords(2,dimension);
764 for (int idim=0; idim<dimension; idim++)
765 {
766 coords_bords(0,idim) = les_positions_sondes_(0,idim);
767 coords_bords(1,idim) = les_positions_sondes_(nbre_points_tot-1,idim);
768 }
769
770 Cerr<<"The location of the probe named "<<nom_<<" are modified (to centers of gravity). Check the .log files to see the new location."<<finl;
771 const Domaine_VF& domaineVF = ref_cast(Domaine_VF,mon_champ->get_ref_domaine_dis_base());
772 const DoubleTab& xp = domaineVF.xp();
773 for (int i=0; i<nbre_points_tot; i++)
774 {
775 if(elem_[i]!=-1)
776 {
777 Journal()<<"The point " << i << " of the probe "<<nom_<<" is moved:";
778 for (int dir=0; dir<dimension; dir++)
779 {
780 Journal() << " x(" << dir << "): " << les_positions_sondes_(i,dir) << " -> " << xp(elem_[i],dir);
781 les_positions_sondes_(i,dir)=xp(elem_[i],dir);
782 }
783 Journal() << finl;
784 }
785 }
786 if (gravcl)
787 ajouter_bords(coords_bords);
788}
789
790/*! @brief Initialises the probe.
791 *
792 * Sizes the value arrays, and checks that the specified points lie within the computation domain.
793 *
794 * @param domaine_geom the computation domain to be probed
795 * @throws probe point outside the computation domain
796 */
798{
799 // Compute exact positions from the initial probe positions:
801 // Dimension the elem_ array:
802 int nbre_points_tot = les_positions_sondes_.dimension(0);
803 if(elem_.size() != nbre_points_tot)
804 elem_.resize(nbre_points_tot);
805
806 const Domaine& domaine_geom = get_domaine_geom();
807
808 if (numero_elem_==-1)
809 {
810 // Location of probes is given by coordinates in the les_positions_ array:
811 int nb_coord = les_positions_sondes_.dimension(1);
812 if (nb_coord != Objet_U::dimension)
813 {
814 Cerr << "You can't specify the probe named " << nom_ << " with "<< nb_coord << " coordinates on the domain named " <<domaine_geom.le_nom()<<finl;
815 Cerr << "which has spatial dimension " << Objet_U::dimension << finl;
816 Cerr << "Change the probe coordinates or use numero_elem_sur_maitre keyword (see documentation)" << finl;
817 Cerr << "to specify a cell containing the probe and not its coordinates." << finl;
818 // [ABN] : we should exit, otherwise we just don't see the warning:
820 }
821 // Fill the elem_ array (which list real cells containing all the probes):
823 }
824 else
825 {
826 // Location of the probe is given by an element number:
828 const IntTab& les_elems=mon_champ->get_ref_domaine_dis_base().domaine().les_elems();
829 if (numero_elem_<les_elems.dimension_tot(0))
830 {
831 const DoubleTab& coord=mon_champ->get_ref_domaine_dis_base().domaine().les_sommets();
832 int nb_som=les_elems.dimension(1);
833 // Fill les_positions_ with the cog of the cell numero_elem_
834 for (int s=0; s<nb_som; s++)
835 {
836 int soml=les_elems(numero_elem_,s);
837 if (soml>-1)
838 for (int dir=0; dir<dimension; dir++)
839 les_positions_sondes_(0,dir)+=coord(soml,dir)/nb_som;
840 }
841 }
842 else
843 {
844 if (je_suis_maitre())
845 {
846 Cerr<<" On the probe named " << nom_ << " , the element number "<<numero_elem_<<" does not exist on the master processor, we put the position to zero"<<finl;
848 }
849 elem_[0]=-1;
850 }
851 }
852 // Check if some probes are outside the domain:
853 ArrOfDouble tmp(nbre_points_tot);
854 for (int i=0; i<nbre_points_tot; i++)
855 tmp[i] = elem_[i];
857 for (int i=0; i<nbre_points_tot; i++)
858 if (tmp[i]==-1)
859 Cerr << "WARNING: The point number " << i+1 << " of the probe named " << nom_ << " is outside the computational domain " << domaine_geom.le_nom() << finl;
860
861 const Noms noms_champ = get_noms_champ();
862
863 if (grav || gravcl)
865 else if (nodes)
866 {
867 const Domaine_VF& domaineVF = ref_cast(Domaine_VF,mon_champ->get_ref_domaine_dis_base());
868 const DoubleTab& xv = domaineVF.xv();
869 const IntTab& elem_faces = domaineVF.elem_faces();
870 if (mp_max(elem_faces.size_array())==0)
871 {
872 Cerr << "Error: the domain " << domaineVF.domaine().le_nom() << " is not discretized." << finl;
873 exit();
874 }
875 if (sub_type(Champ_Generique_Interpolation,mon_champ.valeur()))
876 {
877 Motcle dom_interp=mon_champ->get_ref_domain().le_nom();
878 Cerr << finl;
879 Cerr << "Error in your probe : " << nom_ << finl;
880 Cerr << "You can not project to nodes, the field " << noms_champ[0] << finl;
881 Cerr << "which is interpolated on the domain " << dom_interp << finl;
882 exit();
883 }
884 Cerr<<"The location of the probe named "<<nom_<<" are modified (to faces). Check the .log files to see the new location."<<finl;
885 const int nfaces_par_element = domaine_geom.nb_faces_elem() ;
886 for (int i=0; i<nbre_points_tot; i++)
887 {
888 double dist_min=DMAXFLOAT;
889 int face_min=-1;
890 if(elem_[i]!=-1)
891 {
892 Journal()<<"The point " << i << " of the probe "<<nom_<<" is moved:";
893 for(int fac=0; fac<nfaces_par_element; fac++)
894 {
895 int face=elem_faces(elem_[i],fac);
896 // segmentfaces probe type: search only among faces oriented along
897 // orientation_faces_
898 if (face >= 0 &&
900 {
901 double dist=0.;
902
903 for (int dir=0; dir<dimension; dir++)
904 dist+=(xv(face,dir)-les_positions_sondes_(i,dir))*(xv(face,dir)-les_positions_sondes_(i,dir));
905
906 if(dist<=dist_min)
907 {
908 dist_min=dist;
909 face_min=face;
910 }
911 }
912 }
913
914 for (int dir=0; dir<dimension; dir++)
915 {
916 Journal() << " x(" << dir << "): " << les_positions_sondes_(i,dir) << " -> " << xv(face_min,dir);
917 les_positions_sondes_(i,dir)=xv(face_min,dir);
918 }
919 Journal() << " (" << (face_min < domaineVF.premiere_face_int() ? "boundary face " : "internal face ") << face_min<<")" << finl;
920 }
921 }
922 }
923 else if (som)
924 {
925 if (sub_type(Champ_Generique_Interpolation,mon_champ.valeur()))
926 {
927 Motcle dom_interp=mon_champ->get_ref_domain().le_nom();
928 Cerr << finl;
929 Cerr << "Error in your probe : " << nom_ << finl;
930 Cerr << "You can not project to vertexes, the field " << noms_champ[0] << finl;
931 Cerr << "which is interpolated on the domain " << dom_interp << finl;
932 exit();
933 }
934 Cerr<<"The location of the probe named "<<nom_<<" are modified (to vertexes). Check the .log files to see the new location."<<finl;
935 const IntTab& sommet_elem = domaine_geom.les_elems();
936 const int sommets_par_element = domaine_geom.les_elems().dimension(1);
937 const DoubleTab& coord = domaine_geom.les_sommets();
938 for (int i=0; i<nbre_points_tot; i++)
939 {
940 double dist_min=DMAXFLOAT;
941 int sommet_min=-1;
942 if(elem_[i]!=-1)
943 {
944 Journal()<<"The point " << i << " of the probe "<<nom_<<" is moved:";
945 for(int isom=0, sommet; isom<sommets_par_element && (sommet = sommet_elem(elem_[i],isom)) >= 0; isom++)
946 {
947 double dist=0.;
948 for (int dir=0; dir<dimension; dir++)
949 dist+=(coord(sommet,dir)-les_positions_sondes_(i,dir))*(coord(sommet,dir)-les_positions_sondes_(i,dir));
950
951 if(dist<=dist_min)
952 {
953 dist_min=dist;
954 sommet_min=sommet;
955 }
956 }
957
958 for (int dir=0; dir<dimension; dir++)
959 {
960 Journal() << " x(" << dir << "): " << les_positions_sondes_(i,dir) << " -> " << coord(sommet_min,dir);
961 les_positions_sondes_(i,dir)=coord(sommet_min,dir);
962 }
963 Journal() << finl;
964 }
965 }
966 }
967
968 // See if some positions should be modified (to elem with "grav" for instance)
969 // Should be done before supprime_doublons, because it may create duplicated values.
971
972 bool supprime_doublons = true; // New in 1.8.4 (uniqueness of probe points)
973 if (mon_post->DeprecatedKeepDuplicatedProbes) supprime_doublons = false; // option to keep as P-E needs to preserve duplicated probes in 1.9.3
974 ArrOfInt doublon(elem_.size_array());
975 if (supprime_doublons)
976 {
977 int doublons=0;
978 int size = elem_.size();
979 for (int i=0; i<size; i++)
980 {
981 for (int j=i+1; j<size; j++)
982 {
983 bool same = true;
984 if (elem_[i]!=elem_[j])
985 same = false;
986 else
987 for (int dir = 0; dir < dimension; dir++)
988 if (les_positions_sondes_(i, dir) != les_positions_sondes_(j, dir))
989 {
990 same = false;
991 break;
992 }
993 if (same)
994 {
995 doublon[i] = 1;
996 doublons++;
997 break;
998 }
999 }
1000 }
1001 if (doublons)
1002 Cerr << "We remove " << doublons << " duplicated points from the probe " << nom_ << finl;
1003 }
1004
1005 // each processor has checked if it holds the point
1006 // the master builds a table (prop) that determines which processor will provide the value to the master
1007 // the master also builds the ArrsOfInt participant
1008 // giving for a proc the various elements it owns
1009 IntVect prop(elem_);
1010 if (je_suis_maitre())
1011 {
1012 ArrOfInt elems2(elem_);
1013 prop=0; // By default the master is the owner (especially for probes outside the domain)
1014 ArrOfInt elem_recu, doublon_recu;
1015 DoubleTab positions_recu;
1016 int nbproc=Process::nproc();
1017 for(int p=1; p<nbproc; p++)
1018 {
1019 recevoir(doublon_recu,p,2003+p);
1020 recevoir(elem_recu,p,0,2002+p);
1021 recevoir(positions_recu,p,0,2001+p);
1022 for (int el=0; el<nbre_points_tot; el++)
1023 if (elems2[el]==-1 && elem_recu[el]!=-1)
1024 {
1025 elems2[el]=elem_recu[el];
1026 doublon[el]=doublon_recu[el];
1027 prop[el]=p;
1028 for (int j=0; j<dimension; j++)
1029 les_positions_sondes_(el,j)=positions_recu(el,j);
1030 }
1031 }
1032 // OK the prop table has been filled;
1033 // the master sizes participant;
1034 participant.dimensionner(nbproc);
1035 for(int p=0; p<nbproc; p++)
1036 {
1037 int size=0;
1038 for (int el=0; el<nbre_points_tot; el++)
1039 if (prop[el]==p&&!doublon[el]) size++;
1040 participant[p].resize_array(size);
1041 participant[p]=-1;
1042 int pos=0;
1043 int pt=0;
1044 for (int el=0; el<nbre_points_tot; el++)
1045 if (!doublon[el])
1046 {
1047 if (prop[el] == p)
1048 {
1049 participant[p][pos] = pt;
1050 pos++;
1051 }
1052 pt++;
1053 }
1054 assert((size==0)||(min_array(participant[p])>-1));
1055 }
1056 }
1057 else
1058 {
1059 envoyer(doublon, Process::me(),0,2003+Process::me());
1060 envoyer(elem_,Process::me(),0,2002+Process::me());
1061 envoyer(les_positions_sondes_,Process::me(),0,2001+Process::me());
1062 }
1063 envoyer_broadcast(prop, 0);
1064 //
1065 // resize arrays to local size from prop, removing duplicates
1066 int nbre_points=0;
1067 nbre_points_tot=0;
1069 for (int el=0; el<prop.size(); el++)
1070 {
1071 if (!doublon[el])
1072 {
1073 if (prop(el) == me())
1074 {
1075 elem_(nbre_points) = elem_(el);
1076 for (int dir = 0; dir < dimension; dir++)
1077 les_positions_(nbre_points, dir) = les_positions_(el, dir);
1078 nbre_points++;
1079 }
1080 for (int dir = 0; dir < dimension; dir++)
1081 les_positions_sondes_(nbre_points_tot, dir) = les_positions_sondes_(el, dir);
1082 nbre_points_tot++;
1083 }
1084 }
1085#ifndef NDEBUG
1086 int test = static_cast<int>(mp_sum(nbre_points));
1087 //cerr << "Remove " << Process::me() << " " << nbre_points << " " << nbre_points_tot << " = " << test << endl;
1088 if (je_suis_maitre()) assert(test==nbre_points_tot);
1089#endif
1090 elem_.resize(nbre_points);
1091 les_positions_.resize(nbre_points, dimension);
1092 if (je_suis_maitre()) // Array only on the master:
1093 les_positions_sondes_.resize(nbre_points_tot, dimension);
1094 else
1095 les_positions_sondes_.resize(0,0);
1096 // Sizing valeurs_sur_maitre
1097 if (je_suis_maitre()&&(nproc()>1))
1098 {
1099 if (ncomp == -1)
1100 {
1101 int nb_comp = get_nb_compo_champ();
1102 valeurs_sur_maitre.resize(nbre_points_tot,nb_comp);
1103 }
1104 else
1105 valeurs_sur_maitre.resize(nbre_points_tot, 1);
1106 }
1107 // Sizing valeurs_locales
1108 if (ncomp == -1)
1109 {
1110 int nb_comp = get_nb_compo_champ();
1111 valeurs_locales.resize(nbre_points,nb_comp);
1112 }
1113 else
1114 valeurs_locales.resize(nbre_points, 1);
1115}
1116
1117
1118/*! @brief Opens the file associated with the probe.
1119 *
1120 * (*.son)
1121 *
1122 */
1124{
1125 if (je_suis_maitre() && !le_fichier_.is_open())
1126 {
1127 struct stat f;
1128 int reprise = !stat(nom_fichier_, &f) && mon_post->probleme().reprise_effectuee();
1129 if (reprise)
1130 {
1131 // Restarting a computation, appending to file:
1132 le_fichier_.ouvrir(nom_fichier_, ios::app);
1133 le_fichier_.setf(ios::scientific);
1134 le_fichier_.precision(8);
1135 }
1136 else
1137 {
1138 // Starting computation or file does not exist:
1139 le_fichier_.ouvrir(nom_fichier_);
1140 le_fichier_.setf(ios::scientific);
1141 le_fichier_.precision(8);
1142 // Write header:
1143 SFichier& s = le_fichier_;
1144 // Write the header of the probe files:
1145 if (dim == 0 || dim == 1)
1146 {
1147 const DoubleTab& p = les_positions_sondes();
1148 int nbre_points = les_positions_sondes_.dimension(0);
1149 s << "# " << nom_fichier_ << finl;
1150 s << "# Temps";
1151 for (int i = 0; i < nbre_points; i++)
1152 {
1153 s << " x= " << p(i, 0) << " y= " << p(i, 1);
1154 if (dimension == 3) fichier() << " z= " << p(i, 2);
1155 }
1156 s << finl;
1157 if (mon_champ)
1158 {
1159 const Noms unites = mon_champ->get_property("unites");
1160 s << "# Champ " << nom_champ_lu_ << " [" << unites[ncomp == -1 ? 0 : ncomp] << "]" << finl;
1161 }
1162 else
1163 s << "# Champ " << nom_champ_lu_ << " [??]" << finl;
1164 s << "# Type " << get_type() << finl;
1165 }
1166 // Write the header of the plan files:
1167 else
1168 {
1169 s << "TRUST Version1 01/09/96" << finl;
1170 s << nom_du_cas() << finl;
1171 s << "TRUST" << finl;
1172 s << "GRILLE";
1173 const DoubleTab& p = les_positions_sondes();
1174 // Nouveau on ajoute des informations pour Run_sonde
1175 s << " " << get_type() << " " << nom_champ_lu_ << " " << nbre_points1 << " " << nbre_points2;
1176 for (int j = 0; j < dimension; j++) s << " " << p(0, j);
1177 for (int j = 0; j < dimension; j++) s << " " << p((nbre_points1 - 1) * nbre_points2, j);
1178 for (int j = 0; j < dimension; j++) s << " " << p(nbre_points2 - 1, j);
1179 s << finl;
1180 Nom nom_grille("Grille");
1181 Nom nom_topologie("Topologie");
1182 nom_grille += "_";
1183 nom_grille += nom_;
1184 nom_topologie += "_";
1185 nom_topologie += nom_;
1186 int k, kn;
1187 int nbre_points = les_positions_sondes_.dimension(0);
1188 if (dim == 2)
1189 {
1190 double xn = 0., yn = 0., zn = 0., norme = 0.;
1191 int p1 = 1, p_nbre_points2 = nbre_points2;
1192 while (p(0, 0) == p(p1, 0) && p(0, 1) == p(p1, 1) && p(0, 2) == p(p1, 2))
1193 {
1194 p1 += 1;
1195 assert(p1 < nbre_points);
1196 }
1197 while (p(0, 0) == p(p_nbre_points2, 0) && p(0, 1) == p(p_nbre_points2, 1) &&
1198 p(0, 2) == p(p_nbre_points2, 2))
1199 {
1200 p_nbre_points2 += 1;
1201 assert(p_nbre_points2 < nbre_points);
1202 }
1203 while (p(p1, 0) == p(p_nbre_points2, 0) && p(p1, 1) == p(p_nbre_points2, 1) &&
1204 p(p1, 2) == p(p_nbre_points2, 2))
1205 {
1206 p_nbre_points2 += 1;
1207 assert(p_nbre_points2 < nbre_points);
1208 }
1209
1210 if (dimension == 3)
1211 {
1212 xn = (p(p1, 2) - p(0, 2)) * (p(p_nbre_points2, 1) - p(0, 1))
1213 - (p(p1, 1) - p(0, 1)) * (p(p_nbre_points2, 2) - p(0, 2));
1214 yn = (p(p1, 0) - p(0, 0)) * (p(p_nbre_points2, 2) - p(0, 2))
1215 - (p(p1, 2) - p(0, 2)) * (p(p_nbre_points2, 0) - p(0, 0));
1216 }
1217 else if (dimension == 2)
1218 {
1219 xn = 0.;
1220 yn = 0.;
1221 }
1222 zn = (p(p1, 1) - p(0, 1)) * (p(p_nbre_points2, 0) - p(0, 0))
1223 - (p(p1, 0) - p(0, 0)) * (p(p_nbre_points2, 1) - p(0, 1));
1224 norme = std::fabs(xn) + std::fabs(yn) + std::fabs(zn);
1225 xn /= norme;
1226 yn /= norme;
1227 zn /= norme;
1228 s << nom_grille << " 3 " << 2 * nbre_points << finl;
1229 int i;
1230 for (i = 0; i < nbre_points; i++)
1231 {
1232 s << p(i, 0) << " " << p(i, 1);
1233 if (dimension == 3) fichier() << " " << p(i, 2) << finl;
1234 else if (dimension == 2) s << " 0." << finl;
1235 }
1236 for (i = 0; i < nbre_points; i++)
1237 {
1238 s << p(i, 0) + xn << " " << p(i, 1) + yn;
1239 if (dimension == 3) s << " " << p(i, 2) + zn << finl;
1240 else if (dimension == 2) s << " " << zn << finl;
1241 }
1242 s << "TOPOLOGIE" << finl;
1243 s << nom_topologie << " " << nom_grille << finl;
1244 s << "MAILLE" << finl;
1245 s << (nbre_points1 - 1) * (nbre_points2 - 1) << finl;
1246 for (int j = 0; j < nbre_points2 - 1; j++)
1247 for (i = 0; i < nbre_points1 - 1; i++)
1248 {
1249 k = j * nbre_points1 + i + 1;
1250 kn = k + nbre_points;
1251 s << "VOXEL8 " << k << " " << k + 1 << " ";
1252 s << k + nbre_points1 << " " << k + nbre_points1 + 1;
1253 s << " " << kn << " " << kn + 1 << " " << kn + nbre_points1;
1254 s << " " << kn + nbre_points1 + 1 << finl;
1255 }
1256 s << "FACE" << finl;
1257 s << "0" << finl;
1258 }
1259 else if (dim == 3)
1260 {
1261 const DoubleTab& pbis = les_positions_sondes();
1262 s << nom_grille << " 3 " << nbre_points << finl;
1263 int i;
1264 for (i = 0; i < nbre_points; i++)
1265 {
1266 s << pbis(i, 0) << " " << pbis(i, 1);
1267 s << " " << pbis(i, 2) << finl;
1268 }
1269 s << "TOPOLOGIE" << finl;
1270 s << nom_topologie << " " << nom_grille << finl;
1271 s << "MAILLE" << finl;
1272 s << (nbre_points1 - 1) * (nbre_points2 - 1) * (nbre_points3 - 1) << finl;
1273 for (int m = 0; m < nbre_points3 - 1; m++)
1274 for (int j = 0; j < nbre_points2 - 1; j++)
1275 for (i = 0; i < nbre_points1 - 1; i++)
1276 {
1277 k = m * nbre_points2 * nbre_points1 + j * nbre_points1 + i + 1;
1278 kn = k + nbre_points2 * nbre_points1;
1279 s << "VOXEL8 " << k << " " << k + 1 << " ";
1280 s << k + nbre_points1 << " " << k + nbre_points1 + 1;
1281 s << " " << kn << " " << kn + 1 << " " << kn + nbre_points1;
1282 s << " " << kn + nbre_points1 + 1 << finl;
1283 }
1284 s << "FACE" << finl;
1285 s << "0" << finl;
1286 }
1287 }
1288 }
1289 }
1290}
1291
1292void Sonde::update_source(double un_temps)
1293{
1294 // Cache mechanism for the source field behind the post-processed field (mon_champ)
1295 // Implemented at the Sondes level
1296 OBS_PTR(Champ_base) ma_source = mon_post->les_sondes().get_from_cache(mon_champ, nom_champ_lu_);
1297 ma_source->mettre_a_jour(un_temps);
1298}
1299
1300/*! @brief Updates the probe in time and performs the post-processing.
1301 *
1302 * @param un_temps the update time
1303 * @param tinit the initial time of the probe
1304 */
1305void Sonde::mettre_a_jour(double un_temps, double tinit)
1306{
1307 double temps_courant = get_temps_champ();
1308 double dt=mon_post->probleme().schema_temps().pas_de_temps();
1309 double nb;
1310
1311 // The *(1+Objet_U::precision_geom) factor avoids rounding errors depending on the machine
1312 // 21/01/25: replaced Objet_U::precision_geom with 1e-15 (from M3D patch, bttrust #242895)
1313 // because precision_geom is a user-settable parameter via the data file
1314 if (periode<=dt)
1315 nb=nb_bip+1.;
1316 else
1317 modf(temps_courant*(1+1e-15)/periode, &nb);
1318
1319 // Time to write the probes
1320 if (nb>nb_bip)
1321 {
1322 update_source(un_temps);
1323
1324 // Si le maillage est deformable il faut reconstruire les sondes
1325 if (mon_post->les_sondes().get_update_positions())
1326 {
1327 if (mon_post->probleme().domaine().deformable())
1328 initialiser();
1329 }
1330 nb_bip=nb;
1331 postraiter();
1332 }
1333}
1334
1335
1337{
1338 // Cache mechanism for the source field behind the post-processed field (mon_champ)
1339 // Implemented at the Sondes level
1340 OBS_PTR(Champ_base) ma_source = mon_post->les_sondes().get_from_cache(mon_champ, nom_champ_lu_);
1341 if (chsom)
1342 {
1343 Champ_base& ma_source_mod =ref_cast_non_const(Champ_base,ma_source.valeur());
1344 if (ncomp == -1)
1346 else
1348 }
1349 else
1350 {
1351 if (ncomp == -1)
1352 ma_source->valeur_aux_elems(les_positions(),elem_, valeurs_locales);
1353 else
1354 ma_source->valeur_aux_elems_compo(les_positions(),elem_,valeurs_locales, ncomp);
1355 }
1356}
1357
1358/*! @brief Performs post-processing.
1359 *
1360 * Computes field values at the requested positions and writes them to the associated file.
1361 *
1362 */
1364{
1366
1367 if (gravcl)
1369 const int N = valeurs_locales.line_size();
1370
1371 // the master reconstructs the values array from the various contributors
1372 if(je_suis_maitre())
1373 {
1375 int nbproc = Process::nproc();
1376 DoubleTab valeurs_pe;
1377 DoubleTab& valeurs=(nbproc==1?valeurs_locales:valeurs_sur_maitre);
1378 if (nbproc==1) { /* Do nothing */} //valeurs=valeurs_locales;
1379 else
1380 {
1381 int nb_val = valeurs_locales.dimension(0);
1382 for (int i = 0; i < nb_val; i++)
1383 for (int n = 0; n < N; n++)
1384 valeurs(participant[0][i], n) = valeurs_locales(i, n);
1385 }
1386 for(int p=1; p<nbproc; p++)
1387 {
1388 // le message n'est envoye que si le proc participe
1389 if (participant[p].size_array()!=0)
1390 {
1391 recevoir(valeurs_pe,p,0,2002+p);
1392 int nb_val1=valeurs_pe.dimension(0);
1393 assert(N == valeurs_pe.line_size());
1394 for(int i=0; i<nb_val1; i++)
1395 for(int n = 0; n < N; n++)
1396 {
1397 valeurs(participant[p][i], n)=valeurs_pe(i, n);
1398 // val_max = std::max(std::fabs(valeurs(i,k)),std::fabs(valeurs_pe(i,k)));
1399 // if(val_max==(std::fabs(valeurs_pe(i,k))))
1400 // valeurs(i,k)=valeurs_pe(i,k);
1401 }
1402 }
1403 }
1404
1405 double temps_courant = mon_post->probleme().schema_temps().temps_courant();
1406
1407 if (dim==0 || dim==1)
1408 {
1409 fichier() << temps_courant;
1410 for(int i=0; i<valeurs.dimension(0); i++)
1411 for(int k=0; k<N; k++)
1412 fichier() << " " << valeurs(i,k);
1413 fichier() << finl;
1414 }
1415 // For plan-type probes, output in lml format:
1416 // num_sommet comp1 [comp2] [comp3]
1417 // and in the third direction:
1418 else if (dim==2 || dim==3)
1419 {
1420 Nom nom_post;
1421 int nbre_points = valeurs.dimension(0);
1422 const Noms noms_comp = mon_champ->get_property("composantes");
1423 int nb_comp = noms_comp.size();
1424 const Noms unites = mon_champ->get_property("unites");
1425 if (ncomp==-1)
1426 {
1427 const Noms noms_champ = mon_champ->get_property("nom");
1428 nom_post = noms_champ[0];
1429 }
1430 else
1431 nom_post = noms_comp[ncomp];
1432
1433 Nom nom_topologie("Topologie");
1434 nom_topologie += "_";
1435 nom_topologie += nom_;
1436
1437 fichier() << "TEMPS " << temps_courant << "\n";
1438 fichier() << "CHAMPPOINT " << nom_post << " " << nom_topologie
1439 << " " << temps_courant << "\n";
1440 fichier() << nom_post << " " << nb_comp << " " << unites[0] << "\n";
1441
1442 int nbp=nbre_points;
1443 if (dim==2) nbp*=2;
1444 if (nb_comp>1)
1445 fichier() << "type1 " << nbp << "\n";
1446 else fichier() << "type0 " << nbp << "\n";
1447 int i;
1448 for(i=0; i<nbre_points; i++)
1449 {
1450 fichier() << i+1;
1451 for(int j=0; j<N; j++)
1452 fichier() << " " << valeurs(i,j);
1453 // Pour ne pas flusher :
1454 fichier() << "\n";
1455 }
1456 // For 2D, add an extra direction
1457 if (dim==2)
1458 {
1459 for(i=0; i<nbre_points; i++)
1460 {
1461 fichier() << nbre_points+i+1;
1462 for(int j=0; j<N; j++)
1463 fichier() << " " << valeurs(i,j);
1464 // Pour ne pas flusher :
1465 fichier() << "\n";
1466 }
1467 }
1468 }
1469 fichier().flush();
1470 }
1471 else
1472 {
1473 // the processor sends a message only if it contributes
1474 if (valeurs_locales.dimension(0)!=0)
1475 envoyer(valeurs_locales,Process::me(),0,2002+Process::me());
1476 }
1477}
1478
1480{
1481 if (!gravcl)
1482 return;
1483
1484 const int nbf = faces_bords_.size_array();
1485 rang_cl_.resize(nbf);
1486
1487 if (sub_type(Champ_Generique_refChamp,mon_champ.valeur()))
1488 {
1489 Probleme_base& Pb = mon_post->probleme();
1491 const Champ_Inc_base& ch_inc = ref_cast(Champ_Inc_base,chref.valeur());
1492 const Domaine_Cl_dis_base& zcl = ch_inc.domaine_Cl_dis();
1493
1494 for (int iface=0; iface<nbf; iface++)
1495 {
1496 int face = faces_bords_[iface];
1497 for (int icl=0; icl<zcl.nb_cond_lim(); icl++)
1498 {
1499 const Cond_lim& cl = zcl.les_conditions_limites(icl);
1500 const Front_VF& le_bord = ref_cast(Front_VF,cl->frontiere_dis());
1501 const int ndeb = le_bord.num_premiere_face();
1502 const int nfin = ndeb + le_bord.nb_faces();
1503 for (int i=ndeb; i<nfin; i++)
1504 {
1505 if (i==face)
1506 rang_cl_[iface] = icl;
1507 }
1508 }
1509 }
1510 }
1511}
1512
1513void Sonde::ajouter_bords(const DoubleTab& coords_bords)
1514{
1515 double eps = mon_champ->get_ref_domain().epsilon();
1516 const Domaine_VF& domaineVF = ref_cast(Domaine_VF,mon_champ->get_ref_domaine_dis_base());
1517
1518 const DoubleTab& xv = domaineVF.xv();
1519 const IntTab& e_f = domaineVF.elem_faces(), &f_e = domaineVF.face_voisins();
1520 int nbre_points = les_positions_sondes_.dimension(0), face;
1521
1522
1523
1524 IntTab tmp(2);
1525 tmp[0] = 0;
1526 tmp[1] = nbre_points-1;
1527
1528 for (int i = 0; i<coords_bords.dimension(0); i++)
1529 {
1530 int e = tmp[i];
1531 int elem = elem_[e];
1532 if (elem !=-1)
1533 {
1534 for (int j = 0; j < e_f.dimension(1) && (face = e_f(elem, j)) >= 0; j++)
1535 {
1536 if(f_e(face, 1) == -1 || f_e(face, 0) == -1)
1537 {
1538 double dist=0.;
1539 for (int idim=0; idim<dimension; idim++)
1540 dist+=((xv(face,idim)-coords_bords(i,idim))*(xv(face,idim)-coords_bords(i,idim)));
1541
1542 if (sqrt(dist) < eps)
1543 {
1544 faces_bords_.append_array(face);
1545 for (int idim=0; idim<dimension; idim++)
1546 les_positions_sondes_(e,idim) = coords_bords(i,idim);
1547 }
1548 }
1549 }
1550 }
1551 }
1552// [ABN] skiping the assert below. On funny shaped domains (e.g. U-shape) a probe might
1553// re-enter the domain, and hence hit more than two faces overall:
1554// assert(mp_sum(faces_bords_.size_array())<=2);
1555}
1556
1558{
1559 if (sub_type(Champ_Generique_refChamp,mon_champ.valeur()))
1560 {
1561 Probleme_base& Pb = mon_post->probleme();
1563 const Champ_Inc_base& ch_inc = ref_cast(Champ_Inc_base,chref.valeur());
1564 const Domaine_Cl_dis_base& zcl = ch_inc.domaine_Cl_dis();
1565 const DoubleTab& vals_ch = ch_inc.valeurs();
1566 const Domaine_VF& domaineVF = ref_cast(Domaine_VF,mon_champ->get_ref_domaine_dis_base());
1567 const IntTab& face_voisins = domaineVF.face_voisins();
1568
1569 int nbval = valeurs_locales.dimension(0);
1570
1571 for (int iface=0; iface<faces_bords_.size_array(); iface++)
1572 {
1573 int face = faces_bords_[iface];
1574 int icl = rang_cl_[iface];
1575 const Cond_lim& cl = zcl.les_conditions_limites(icl);
1576 const Front_VF& le_bord = ref_cast(Front_VF,cl->frontiere_dis());
1577 const int ndeb = le_bord.num_premiere_face();
1578 DoubleVect valcl;
1579 cl->champ_front().valeurs_face(face-ndeb,valcl);
1580
1581 if (valcl.size() == 0)
1582 {
1583 int elem0 = face_voisins(face,0);
1584 int elem1 = face_voisins(face,1);
1585
1586 if (elem0 != -1)
1587 valeurs_locales(nbval-1) = vals_ch[elem0];
1588 else
1589 valeurs_locales(0) = vals_ch[elem1];
1590 }
1591 else
1592 {
1593 if (face_voisins(face,0) != -1)
1594 valeurs_locales(nbval-1) = valcl[0];
1595 else
1596 valeurs_locales(0) = valcl[0];
1597 }
1598 }
1599 }
1600}
A generic field constructed as an interpolation of another generic field (interpolation at vertices o...
class Champ_Generique_base
static int composante(const Nom &nom_test, const Nom &nom, const Noms &composantes, const Noms &synonyms)
Special field class that encapsulates a reference to a volume field of TRUST of type Champ_base.
Class Champ_Inc_base.
const Domaine_Cl_dis_base & domaine_Cl_dis() const
DoubleTab & valeurs() override
Returns the array of field values at the current time.
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
virtual DoubleVect & valeur_aux_elems_compo_smooth(const DoubleTab &positions, const IntVect &les_polys, DoubleVect &valeurs, int ncomp)
virtual DoubleTab & valeur_aux_elems_smooth(const DoubleTab &positions, const IntVect &les_polys, DoubleTab &valeurs)
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Searches for the elements containing the points whose coordinates are specified.
Definition Domaine.cpp:404
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
int nb_faces_elem(int=0) const
Returns the number of faces of type i of the geometric elements that make up the domain.
Definition Domaine.h:484
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
int nb_cond_lim() const
Returns the number of boundary conditions.
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_VF
Definition Domaine_VF.h:44
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
int elem_faces(int i, int j) const
Returns the index of the i-th face of element num_elem; the face numbering convention is.
Definition Domaine_VF.h:542
double xp(int num_elem, int k) const
Definition Domaine_VF.h:77
virtual int orientation_si_definie(int) const
Definition Domaine_VF.h:653
int premiere_face_int() const
A face is internal if and only if it separates two elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
const Domaine & domaine() const
This class behaves like EChaine until the end of the string is reached.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
A character string (Nom) in uppercase.
Definition Motcle.h:26
int debute_par(const char *const n) const override
Definition Motcle.cpp:307
An array of Motcle objects.
Definition Motcle.h:63
int contient_(const char *const ch) const
Definition Motcle.cpp:331
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
Nom & suffix(const char *const)
Suffix extraction: Nom x("azerty");.
Definition Nom.cpp:266
const Nom & le_nom() const override
Returns *this.
Definition Nom.cpp:555
An array of character strings (VECT(Nom)).
Definition Noms.h:26
Base class for TRUST objects (Objet_U).
Definition Objet_U.h:68
friend class Entree
Definition Objet_U.h:71
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
static const Nom & nom_du_cas()
Returns a constant reference to the case name. This method is static.
Definition Objet_U.cpp:145
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
class Postraitement. The class holds -a list of generic fields champs_post_complet_ containing
class Probleme_base It is a Probleme_U that is not a coupling.
void creer_champ(const Motcle &motlu) override
const Champ_base & get_champ(const Motcle &nom) const override
virtual int expression_predefini(const Motcle &motlu, Nom &expression)
static void mp_max_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
Definition Process.cpp:197
static double mp_max(double)
Definition Process.cpp:379
static Sortie & Journal(int message_level=0)
Returns a static Sortie object used as an event journal.
Definition Process.cpp:592
static int nproc()
Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current...
Definition Process.cpp:102
static double mp_sum(double)
Computes the sum of x over all processors in the current group.
Definition Process.cpp:145
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
Definition Process.cpp:122
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
Definition SFichier.h:29
class Sonde. This class allows tracking the evolution of a field over time.
Definition Sonde.h:41
void associer_post(const Postraitement &)
Associates the post-processing object with the probe.
Definition Sonde.cpp:723
virtual void create_champ_generique(Entree &is, const Motcle &motlu)
Definition Sonde.cpp:685
DoubleTab valeurs_locales
Definition Sonde.h:120
int orientation_faces_
Definition Sonde.h:126
double periode
sampling period
Definition Sonde.h:112
virtual void mettre_a_jour_bords()
Definition Sonde.cpp:1557
virtual int get_nb_compo_champ() const
Definition Sonde.cpp:746
IntTab rang_cl_
for a given face, index of the CL that this face bears
Definition Sonde.h:130
const DoubleTab & les_positions() const
Definition Sonde.h:190
virtual void validate_type(const Motcle &loc) const
Definition Sonde.h:85
DoubleTab les_positions_sondes_initiales_
coordinates of the initial point probes
Definition Sonde.h:107
const int & get_dim() const
Definition Sonde.h:66
Nom nom_fichier_
the name of the file containing the probe
Definition Sonde.h:100
Motcle nom_champ_lu_
Definition Sonde.h:123
const DoubleTab & les_positions_sondes_initiales() const
Returns the array of positions of the field that are probed.
Definition Sonde.h:180
virtual void ajouter_bords(const DoubleTab &coords_bords)
Definition Sonde.cpp:1513
DoubleTab les_positions_
coordinates of probes local to each proc
Definition Sonde.h:109
virtual void update_source(double un_temps)
Definition Sonde.cpp:1292
virtual double get_temps_champ() const
Definition Sonde.cpp:754
ArrsOfInt participant
Definition Sonde.h:124
bool som
Definition Sonde.h:119
virtual const Noms get_noms_champ() const
Definition Sonde.cpp:741
SFichier le_fichier_
Definition Sonde.h:122
int dim
the dimension of the probe (point:0,segment:1,plan:2,volume:3)
Definition Sonde.h:101
int ncomp
Definition Sonde.h:106
bool chsom
Definition Sonde.h:116
virtual void fix_probe_position()
Definition Sonde.h:90
const DoubleTab & les_positions_sondes() const
Definition Sonde.h:185
IntVect elem_
elements containing the local point probes
Definition Sonde.h:111
virtual void completer()
Definition Sonde.cpp:159
int nbre_points1
Definition Sonde.h:131
virtual void validate_position() const
Definition Sonde.h:87
DoubleTab valeurs_sur_maitre
valeurs_locales: values on each proc, valeurs_sur_maitre: values gathered on the master
Definition Sonde.h:120
bool grav
Definition Sonde.h:117
const Nom & get_nom() const
Definition Sonde.h:64
virtual void initialiser()
Initialises the probe.
Definition Sonde.cpp:797
int nbre_points3
used to create sonde_segment, sonde_plan, etc...
Definition Sonde.h:131
ArrOfInt faces_bords_
array containing the indices of the boundary faces hit by the probe
Definition Sonde.h:129
Nom type_
Definition Sonde.h:125
int nbre_points2
Definition Sonde.h:131
int numero_elem_
equals -1 if undefined, otherwise the element number on the master
Definition Sonde.h:110
Nom nom_
the probe name
Definition Sonde.h:99
virtual void fill_local_values()
Definition Sonde.cpp:1336
SFichier & fichier()
Returns an output file stream pointing to the output file used by the probe.
Definition Sonde.h:209
virtual void fix_probe_position_grav()
Definition Sonde.cpp:760
virtual void postraiter()
Performs post-processing.
Definition Sonde.cpp:1363
virtual const Domaine & get_domaine_geom() const
Definition Sonde.cpp:736
const Nom & get_type() const
Definition Sonde.h:65
bool gravcl
Definition Sonde.h:118
virtual void init_bords()
Definition Sonde.cpp:1479
DoubleTab les_positions_sondes_
coordinates of probes across the whole domain after displacement (master only)
Definition Sonde.h:108
Sonde()
Default constructor for a probe.
Definition Sonde.cpp:145
bool nodes
Definition Sonde.h:115
void ouvrir_fichier()
Opens the file associated with the probe.
Definition Sonde.cpp:1123
virtual void mettre_a_jour(double temps, double tinit)
Updates the probe in time and performs the post-processing.
Definition Sonde.cpp:1305
double nb_bip
Definition Sonde.h:121
OBS_PTR(Postraitement) mon_post
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
Sortie & flush() override
Forces the data in the buffer to be written to disk. Uses the ofstream class implementation.
Base class for output streams.
Definition Sortie.h:52
_SIZE_ size_array() const
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
int line_size() const
Definition TRUSTVect.tpp:67