TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Champ_front_recyclage.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_front_recyclage.h>
17#include <Interprete.h>
18#include <Probleme_base.h>
19#include <TRUSTTrav.h>
20#include <Domaine_VF.h>
21#include <Equation_base.h>
22#include <communications.h>
23#include <Octree.h>
24#include <TRUSTList.h>
25#include <EFichier.h>
26#include <LecFicDiffuse.h>
27#include <EcrFicCollecte.h>
28#include <Champ_front_calc.h>
29#include <string> // For AIX
30#include <Param.h>
31
32Implemente_instanciable_sans_constructeur(Champ_front_recyclage,"Champ_front_recyclage",Ch_front_var_instationnaire_dep);
33// XD champ_front_recyclage front_field_base champ_front_recyclage INHERITS_BRACE This keyword is used on a boundary to
34// XD_CONT get a field from another boundary. NL2 It is to use, in a general way, on a boundary of a local_pb problem, a
35// XD_CONT field calculated from a linear combination of an imposed field g(x,y,z,t) with an instantaneous f(x,y,z,t)
36// XD_CONT and a spatial mean field <f>(t) or a temporal mean field <f>(x,y,z) extracted from a plane of a problem named
37// XD_CONT pb (pb may be local_pb itself): NL2 For each component i, the field F applied on the boundary will be: NL2
38// XD_CONT F_i(x,y,z,t) = alpha_i*g_i(x,y,z,t) + xsi_i*[f_i(x,y,z,t)- beta_i*<fi>]
39// XD attr pb_champ_evaluateur pb_champ_evaluateur pb_champ_evaluateur REQ not_set
40// XD attr distance_plan listf distance_plan OPT Vector which gives the distance between the boundary and the plane from
41// XD_CONT where the field F will be extracted. By default, the vector is zero, that should imply the two domains have
42// XD_CONT coincident boundaries.
43// XD attr ampli_moyenne_imposee list ampli_moyenne_imposee OPT 2|3 alpha(0) alpha(1) [alpha(2)]: alpha_i coefficients
44// XD_CONT (by default =1)
45// XD attr ampli_moyenne_recyclee list ampli_moyenne_recyclee OPT 2|3 beta(0) beta(1) [beta(2)]}: beta_i coefficients
46// XD_CONT (by default =1)
47// XD attr ampli_fluctuation list ampli_fluctuation OPT 2|3 gamma(0) gamma(1) [gamma(2)]}: gamma_i coefficients (by
48// XD_CONT default =1)
49// XD attr direction_anisotrope entier(into=[1,2,3]) direction_anisotrope OPT If an integer is given for direction (X:1,
50// XD_CONT Y:2, Z:3, by default, direction is negative), the imposed field g will be 0 for the 2 other directions.
51// XD attr moyenne_imposee moyenne_imposee_deriv moyenne_imposee OPT Value of the imposed g field.
52// XD attr moyenne_recyclee chaine moyenne_recyclee OPT Method used to perform a spatial or a temporal averaging of f
53// XD_CONT field to specify <f>. <f> can be the surface mean of f on the plane (surface option, see below) or it can be
54// XD_CONT read from several files (for example generated by the chmoy_faceperio option of the Traitement_particulier
55// XD_CONT keyword to obtain a temporal mean field). The option methode_recyc can be: surfacique, Surface mean for <f>
56// XD_CONT from f values on the plane ; Or one of the following methode_moy options applied to read a temporal mean
57// XD_CONT field <f>(x,y,z): interpolation, connexion_approchee or connexion_exacte
58// XD attr fichier chaine fichier OPT not_set
59
60// XD pb_champ_evaluateur objet_u nul NO_BRACE specifies problem name, the field name beloging to the problem and number
61// XD_CONT of field components.
62// XD attr pb ref_Pb_base pb REQ name of the problem where the source fields will be searched.
63// XD attr champ chaine champ REQ name of the field
64// XD attr ncomp entier ncomp REQ number of components
65
67{
68 int dim = Objet_U::dimension;
69 delt_dist.resize(dim,RESIZE_OPTIONS::NOCOPY_NOINIT);
70 delt_dist=0;
71 ampli_fluct_.resize(1,RESIZE_OPTIONS::NOCOPY_NOINIT);
72 ampli_fluct_ = 1.;
73 ampli_moy_imposee_.resize(1,RESIZE_OPTIONS::NOCOPY_NOINIT);
75 ampli_moy_recyclee_.resize(1,RESIZE_OPTIONS::NOCOPY_NOINIT);
77
80 ndir = -4;
81 diametre = -1.;
82 u_tau = -1.;
83 visco_cin = -1.;
84 fich_recycl_ = "??";
85 fich_impos_ = "??";
86}
87
89{
90 return os;
91}
92
93//-pb_champ_evaluateur is mandatory to specify the name of the problem
94// and the name of the unknown that will be used to initialize the reference
95// to the evaluator field. The number of components of this field must be specified.
96
98{
99 Param param(que_suis_je());
100 set_param(param);
101 param.lire_avec_accolades_depuis(is);
102 return is;
103}
104
106{
107 param.ajouter_non_std("pb_champ_evaluateur",(this),Param::REQUIRED);
108 param.ajouter_non_std("distance_plan",(this));
109 param.ajouter_non_std("ampli_fluctuation",(this));
110 param.ajouter_non_std("ampli_moyenne_imposee",(this));
111 param.ajouter_non_std("ampli_moyenne_recyclee",(this));
112 param.ajouter_non_std("moyenne_imposee",(this));
113 param.ajouter_non_std("moyenne_recyclee",(this));
114 param.ajouter("direction_anisotrope",&ndir);
115}
116
118{
119 int retval = 1;
120 if (mot=="pb_champ_evaluateur")
121 {
122 int nbcomp;
123 is >> nom_pb1 >> nom_inco1 >> nbcomp;
124 ampli_fluct_.resize(nbcomp,RESIZE_OPTIONS::NOCOPY_NOINIT);
125 ampli_moy_imposee_.resize(nbcomp,RESIZE_OPTIONS::NOCOPY_NOINIT);
126 ampli_moy_recyclee_.resize(nbcomp,RESIZE_OPTIONS::NOCOPY_NOINIT);
127 ampli_fluct_ = 1.;
130 fixer_nb_comp(nbcomp);
131 }
132 else if (mot=="distance_plan")
133 {
134 for (int i=0; i<dimension; i++) is >> delt_dist(i) ;
135 }
136 else if (mot=="ampli_fluctuation")
137 {
138 int nbcomp;
139 is >> nbcomp;
140 ampli_fluct_.resize(nbcomp);
141 for (int i=0; i<nbcomp; i++) is >> ampli_fluct_(i) ;
142 fixer_nb_comp(nbcomp);
143 }
144 else if (mot=="ampli_moyenne_imposee")
145 {
146 int nbcomp;
147 is >> nbcomp;
148 ampli_moy_imposee_.resize(nbcomp);
149 for (int i=0; i<nbcomp; i++) is >> ampli_moy_imposee_(i) ;
150 fixer_nb_comp(nbcomp);
151 }
152 else if (mot=="ampli_moyenne_recyclee")
153 {
154 int nbcomp;
155 is >> nbcomp;
156 ampli_moy_recyclee_.resize(nbcomp);
157 for (int i=0; i<nbcomp; i++) is >> ampli_moy_recyclee_(i) ;
158 fixer_nb_comp(nbcomp);
159 }
160 else if (mot=="moyenne_imposee")
161 {
163 }
164 else if (mot=="moyenne_recyclee")
165 {
167 }
168 else retval = -1;
169
170 return retval;
171}
172
173//Reading the information necessary to evaluate the imposed mean
174//-profil : to impose an analytical profile
175//-interpolation : reads from a file and builds a mean field
176// by interpolating the data read.
177// The mean is built for a preferred direction
178// (direction_anisotrope) and is 0 for the other directions
179//-connexion_approchee : reads from a file and retains the value of the
180// variable read by connection with the closest point
181// to the considered boundary face
182//-connexion_exacte : reads a geometry file containing the coordinates of points
183// located in the evaluation plane and reads from a separate
184// file the mean values. The mean values read
185// are stored when the exact correspondence between
186// facing points is verified.
187//- logarithmique : builds the mean using a wall law (logarithmic)
188//
189
190// XD moyenne_imposee_deriv objet_u moyenne_imposee_deriv INHERITS_BRACE not_set
191
192// XD moyenne_imposee_profil moyenne_imposee_deriv profil NO_BRACE To specify analytic profile for the imposed g field.
193// XD attr profile listchaine profile REQ specifies the analytic profile: 2|3 valx(x,y,z,t) valy(x,y,z,t)
194// XD_CONT [valz(x,y,z,t)]
195
196// XD moyenne_imposee_connexion_exacte moyenne_imposee_deriv connexion_exacte NO_BRACE To read the imposed field from
197// XD_CONT two files.
198// XD attr fichier chaine(into=["fichier"]) fichier REQ not_set
199// XD attr file1 chaine file1 REQ first file, contains the points coordinates (which should be the same as the
200// XD_CONT coordinates of the boundary faces). The format of this file is:NL2 N NL2 1 x(1) y(1) [z(1)] NL2 2 x(2) y(2)
201// XD_CONT [z(2)] NL2 ... NL2 N x(N) y(N) [z(N)]
202// XD attr file2 chaine file2 OPT second file, contains the mean values. The format of this file is: NL2 N NL2 1 valx(1)
203// XD_CONT valy(1) [valz(1)] NL2 2 valx(2) valy(2) [valz(2)] NL2 ... NL2 N valx(N) valy(N) [valz(N)]
204
205// XD moyenne_imposee_connexion_approchee moyenne_imposee_deriv connexion_approchee NO_BRACE To read the imposed field
206// XD_CONT from a file where positions and values are given (it is not necessary that the coordinates of points match
207// XD_CONT the coordinates of the boundary faces, indeed, the nearest point of each face of the boundary will be used).
208// XD attr fichier chaine(into=["fichier"]) fichier REQ not_set
209// XD attr file1 chaine file1 REQ filename. The format of the file is: NL2 N NL2 x(1) y(1) [z(1)] valx(1) valy(1)
210// XD_CONT [valz(1)] NL2 x(2) y(2) [z(2)] valx(2) valy(2) [valz(2)] NL2 ... NL2 x(N) y(N) [z(N)] valx(N) valy(N)
211// XD_CONT [valz(N)]
212
213// XD moyenne_imposee_interpolation moyenne_imposee_deriv interpolation NO_BRACE To create an imposed field built by
214// XD_CONT interpolation of values read from a file. The imposed field is applied on the direction given by the keyword
215// XD_CONT direction_anisotrope (the field is zero for the other directions).
216// XD attr fichier chaine(into=["fichier"]) fichier REQ The format of the file is: NL2 pos(1) val(1) NL2 pos(2) val(2)
217// XD_CONT NL2 ... NL2 pos(N) val(N) NL2 If direction given by direction\_anisotrope is 1 (or 2 or 3), then pos will be
218// XD_CONT X (or Y or Z) coordinate and val will be X value (or Y value, or Z value) of the imposed field.
219// XD attr file1 chaine file1 REQ name of geom_face_perio
220
221// XD moyenne_imposee_logarithmique moyenne_imposee_deriv logarithmique NO_BRACE To specify the imposed field (in this
222// XD_CONT case, velocity) by an analytical logarithmic law of the wall: NL2 g(x,y,z) = u_tau * (
223// XD_CONT log(0.5*diametre*u_tau/visco_cin)/Kappa + 5.1 ) NL2 with g(x,y,z)=u(x,y,z) if direction is set to 1,
224// XD_CONT g=v(x,y,z) if direction is set to 2 and g=w(w,y,z) if it is set to 3
225// XD attr diametre chaine(into=["diametre"]) diametre REQ not_set
226// XD attr val floattant val REQ diameter
227// XD attr u_tau chaine(into=["u_tau"]) u_tau REQ not_set
228// XD attr val_u_tau floattant val_u_taul REQ value of u_tau
229// XD attr visco_cin chaine(into=["visco_cin"]) visco_cin REQ not_set
230// XD attr val_visco_cin floattant val_visco_cin REQ value of visco_cin
231// XD attr direction chaine(into=["direction"]) direction REQ not_set
232// XD attr val_direction entier val_direction REQ direction
233
235{
236 int methode = -1;;
237 Motcle choix,motlu;
238 Motcles les_mots(5);
239 {
240 les_mots[0] = "profil";
241 les_mots[1] = "interpolation";
242 les_mots[2] = "connexion_approchee";
243 les_mots[3] = "connexion_exacte";
244 les_mots[4] = "logarithmique";
245 }
246
247 is >> choix;
248 int rang = les_mots.search(choix);
249 switch(rang)
250 {
251
252 case 0 :
253 {
254 methode = 1;
255 int nc;
256 is >> nc;
257 fcts_xyz.dimensionner(nc);
258 for (int i=0; i<nc; i++)
259 is >> fcts_xyz[i];
260 break;
261 }
262 case 1 :
263 {
264 methode = 2;
265 break;
266 }
267 case 2 :
268 {
269 methode = 3;
270 break;
271 }
272 case 3 :
273 {
274 methode = 4;
275 break;
276 }
277 case 4 :
278 {
279 int compt_mot_lu = 0;
280 while (compt_mot_lu!=4)
281 {
282 is >> motlu;
283 if (motlu=="diametre")
284 is >> diametre;
285 else if (motlu=="u_tau")
286 is >> u_tau;
287 else if (motlu=="visco_cin")
288 is >> visco_cin;
289 else if (motlu=="direction")
290 is >> ndir;
291 else
292 {
293 Cerr<<"The keyword "<<motlu<<" is not recognized."<<finl;
294 }
295 compt_mot_lu += 1;
296 }
297 if (diametre<=0.)
298 {
299 Cerr<<"Champ_front_recyclage : a positive diameter must be specified when a logarithmique injected averaged is used."<<finl;
300 exit();
301 }
302 if (u_tau<=0.)
303 {
304 Cerr<<"Champ_front_recyclage : a positive shear velocity must be specified when a logarithmique injected averaged is used."<<finl;
305 exit();
306 }
307 if (visco_cin<=0.)
308 {
309 Cerr<<"Champ_front_recyclage : a positive kinematic viscosity must be specified when a logarithmique injected averaged is used."<<finl;
310 exit();
311 }
312 if (ndir<-3)
313 {
314 Cerr<<"Champ_front_recyclage : the direction must be specified when a logarithmique injected averaged is used."<<finl;
315 exit();
316 }
317 methode = 5;
318 break;
319 }
320
321 default :
322 {
323 Cerr<<"Champ_front_recyclage::lire_info_moyenne_imposee : keyword "<<choix<<" is not recognized."<<finl;
324 Cerr<<"The recognized keywords are :"<<les_mots<<finl;
325 exit();
326 }
327 }
328
329 if ((methode == 2) || (methode == 3))
330 {
331 Nom nom_fich;
332 is >> motlu;
333 if (motlu!="fichier")
334 {
335 Cerr<<"Champ_front_recyclage::lire_info_moyenne_imposee : at least one file must be provided for this method."<<finl;
336 exit();
337 }
338 else
339 is >> nom_fich;
340 fich_impos_ = nom_fich;
341 }
342
343 if (methode == 4)
344 {
345 Nom nom_fich;
346 is >> motlu;
347 if (motlu!="fichier")
348 {
349 Cerr<<"Champ_front_recyclage::lire_info_moyenne_imposee : at least one file must be provided for this method."<<finl;
350 exit();
351 }
352 else
353 is >> nom_fich;
354 fich_maillage_ = nom_fich;
355 is >> nom_fich;
356 fich_impos_ = nom_fich;
357 }
358
359 if (methode==-1)
360 {
361 Cerr<<"Champ_front_recyclage::lire_info_moyenne_imposee : no method to make average evaluation has been given."<<finl;
362 Cerr<<"Choose among the following keywords : les_mots"<<finl;
363 exit();
364 }
365
366 return methode;
367}
368
369//Reading the information necessary to evaluate the recycled mean
370//-surfacique : surface average of the recycled values
371// (the average is computed on bord2 where the values are retrieved)
372//-interpolation connexion_approchee connexion_exacte (see lire_info_moyenne_imposee)
373//
375{
376 int methode = -1;
377 Motcle choix,motlu;
378 Motcles les_mots(4);
379 {
380 les_mots[0] = "surfacique";
381 les_mots[1] = "interpolation";
382 les_mots[2] = "connexion_approchee";
383 les_mots[3] = "connexion_exacte";
384 }
385 is >> choix;
386 int rang = les_mots.search(choix);
387
388 switch(rang)
389 {
390 case 0 :
391 {
392 methode = 1;
393 break;
394 }
395 case 1 :
396 {
397 methode = 2;
398 break;
399 }
400 case 2 :
401 {
402 methode = 3;
403 break;
404 }
405 case 3 :
406 {
407 methode = 4;
408 break;
409 }
410
411 default :
412 {
413 Cerr<<"Champ_front_recyclage::lire_info_moyenne_recyclee keyword "<<choix<<" is not recognized."<<finl;
414 Cerr<<"The recognized keywords are :"<<les_mots<<finl;
415 exit();
416 }
417 }
418
419 if ((methode == 2) || (methode == 3) || (methode == 4))
420 {
421 Nom nom_fich;
422 is >> motlu;
423 if (motlu!="fichier")
424 {
425 Cerr<<"Champ_front_recyclage::lire_info_moyenne_recyclee : a file must be provided for this method."<<finl;
426 exit();
427 }
428 else
429 is >> nom_fich;
430
431 fich_recycl_ = nom_fich;
432 if (methode == 4)
433 is >> nom_fich;
434 fich_maillage_ = nom_fich;
435 }
436
437 if (methode==-1)
438 {
439 Cerr<<"Champ_front_recyclage::lire_info_moyenne_recyclee : no method to make average evaluation has been given."<<finl;
440 Cerr<<"Choose among the following keywords : les_mots"<<finl;
441 exit();
442 }
443
444 return methode;
445}
446
447//Initialization of the reference to the evaluator field (l_inconnue1)
448void Champ_front_recyclage::associer_champ_evaluateur(const Nom& un_nom_pb1,const Motcle& un_nom_inco1)
449{
450 Objet_U& ob1 = Interprete::objet(un_nom_pb1);
452 OBS_PTR(Champ_base) rch1;
453
454 if(sub_type(Probleme_base,ob1))
455 {
456 pb1 = ref_cast(Probleme_base,ob1);
457 }
458 else
459 {
460 Cerr <<"No problem named "<< un_nom_pb1 <<" has been found."<< finl;
461 exit();
462 }
463 rch1 = pb1->get_champ(un_nom_inco1);
464
465 if(sub_type(Champ_Inc_base,rch1.valeur()))
466 l_inconnue1 = ref_cast(Champ_Inc_base,rch1.valeur()) ;
467 else
468 {
469 Cerr<<pb1->le_nom()<<" has no unknown field named "<<un_nom_inco1<<finl;
470 exit();
471 }
472}
473
474//Evaluation of the location of points (coords)
475//where l_inconnue1 must evaluate the values to be recycled
476//coords = xv2(faces_bor2) + delt_dist
477//
479 DoubleTab& coords,
480 const DoubleVect& delt_dist)
481{
482 const Front_VF& fr_vf2 = ref_cast(Front_VF,fr_vf);
483 const Domaine_VF& le_dom2 = ref_cast(Domaine_VF,fr_vf2.domaine_dis());
484 const DoubleTab& xv2 = le_dom2.xv();
485 const int nb_faces2 = fr_vf2.nb_faces();
486 const int ndeb2 = fr_vf2.num_premiere_face();
487 const int dim = xv2.dimension(1);
488
489 coords.resize(nb_faces2,dim);
490 for (int i = 0; i < nb_faces2; i++)
491 for (int j = 0; j < dim; j++)
492 coords(i,j) = xv2(i+ndeb2,j) + delt_dist(j);
493}
494
495//-call to Champ_front_calc::initialiser(...)
496//-dimensioning of moyenne_imposee_ and moyenne_recyclee_ by nb_faces_bord2 and nb_compo_
497//-construction of the structures ensuring parallelism:
498// inconnues1_coords_to_eval_ inconnues1_elems_ inconnues2_faces_
499//-initialization of moyenne_imposee_ and moyenne_recyclee_
500//
502{
504 return 0;
505
506 // 1: remote
507 // 2: local
508 const Front_VF& fr_vf2 = ref_cast(Front_VF,la_frontiere_dis.valeur());
509 const Nom& nom_bord2 = fr_vf2.frontiere().le_nom();
510 int nb_faces_bord2 = fr_vf2.nb_faces();
512
513 moyenne_imposee_.resize(nb_faces_bord2,nb_compo_,RESIZE_OPTIONS::COPY_INIT);
514 moyenne_recyclee_.resize(nb_faces_bord2,nb_compo_,RESIZE_OPTIONS::COPY_INIT);
515
516 if (ampli_fluct_.size()!=nb_compo_)
517 {
518 Cerr<<"The number of fluctuation amplification factors is not coherent with the component number of the field "<<nom_inco1<<finl;
519 Cerr<<"This field has "<<nb_compo_<<" components and there is "<<ampli_fluct_.size()<<" amplification factors defined."<<finl;
520 Cerr<<"Please check that ampli_fluctuation is well specified in your data set."<<finl;
521 exit();
522 }
523
524 if (ampli_moy_imposee_.size()!=nb_compo_)
525 {
526 Cerr<<"The number of the amplification factors for the fixed average is not coherent with the component number of the field "<<nom_inco1<<finl;
527 Cerr<<"This field has "<<nb_compo_<<" components and there is "<<ampli_moy_imposee_.size()<<" amplification factors defined."<<finl;
528 Cerr<<"Please check that ampli_moyenne_imposee is well specified in your data set."<<finl;
529 exit();
530 }
531
532 if (ampli_moy_recyclee_.size()!=nb_compo_)
533 {
534 Cerr<<"The number of the amplification factors for the recycled average is not coherent with the component number of the field "<<nom_inco1<<finl;
535 Cerr<<"This field has "<<nb_compo_<<" components and there is "<<ampli_moy_recyclee_.size()<<" amplification factors defined."<<finl;
536 Cerr<<"Please check that ampli_moyenne_recyclee is well specified in your data set."<<finl;
537 exit();
538 }
539
540 Cerr << "Initializing Champ_front_recyclage on the boundary: " << nom_bord2 << finl;
541
542 // For each point in remote_coord, find the processor whose domain1 contains this point,
543 // and the index of the element:
544
545 const int nprocs = nproc();
546 const int moi = me();
547
548 // Filling remote_coords[i]: coordinates of the face centres of boundary nom_bord2
549 // (destination boundary) + delt_dist
550 // of processor i (all procs hold the same remote_coords array)
551 // Build a DoubleTabs containing the coordinates of the remote faces on domaine 1 for each processor
552 DoubleTabs remote_coords(nprocs);
553 /*
554 if (nom_bord!="??") // Improve this test
555 {
556 const Front_VF& fr_vf1 = ref_cast(Front_VF,front_dis());
557 get_coord_faces(fr_vf1,remote_coords[moi],delt_dist);
558 }
559 else */
560 get_coord_faces(fr_vf2,remote_coords[moi],delt_dist);
561
562 for (int pe = 0; pe < nprocs; pe++)
563 envoyer_broadcast(remote_coords[pe],pe);
564
565 // Size the 3 arrays:
566 inconnues1_coords_to_eval_.dimensionner(nprocs);
567 inconnues1_elems_.dimensionner(nprocs);
568 inconnues2_faces_.dimensionner(nprocs);
569
570 ArrsOfInt indexes_to_recv(nprocs);
571
572 // tmp array for octree results:
573 ArrOfInt elem_list;
574
575
576 const Domaine& domaine1 = l_inconnue1->equation().domaine_dis().domaine();
577 const int nb_elem_domaine1 = domaine1.nb_elem();
578 const int dim = remote_coords[moi].dimension(1);
579
580 const Domaine_dis_base& zdis = l_inconnue1->equation().domaine_dis();
581 const Domaine_VF& zvf = ref_cast(Domaine_VF,zdis);
582 const DoubleTab& xp = zvf.xp();
583 DoubleVect remote_point(3);
584 const OctreeRoot& octree = domaine1.construit_octree();
585 // Loop on processes
586 for (int pe = 0; pe < nprocs; pe++)
587 {
588 // Remote coordinates of the local faces:
589 const DoubleTab& remote_coords_on_pe = remote_coords[pe];
590 int nb_faces_on_pe = remote_coords_on_pe.dimension(0);
591 elem_list.resize_tab(nb_faces_on_pe,RESIZE_OPTIONS::NOCOPY_NOINIT);
592
593 ArrOfInt elem_list_par_pos;
594 // Loop on local faces on the process pe:
595 for (int ind_face=0; ind_face<nb_faces_on_pe; ind_face++)
596 {
597 for (int j=0; j<dimension; j++)
598 remote_point(j) = remote_coords_on_pe(ind_face,j);
599
600 // Fill elem_list_par_pos by elements surrounding the remote point:
601 octree.rang_elems_sommet(elem_list_par_pos,remote_point(0),remote_point(1),remote_point(2));
602 int size_elem_list = elem_list_par_pos.size_array();
603
604 if (size_elem_list==0)
605 elem_list[ind_face] = -1;
606 else
607 {
608 DoubleTrav coord_elems(size_elem_list,dimension);
609 IntList elems;
610 // Fill a list elems and coordinates of the elems
611 for (int ind_elem=0; ind_elem<size_elem_list; ind_elem++)
612 {
613 int elem = elem_list_par_pos[ind_elem];
614 elems.add_if_not(elem);
615 for (int dir=0; dir<dimension; dir++)
616 coord_elems(ind_elem,dir) = xp(elem,dir);
617 }
618 int elem_identifie;
619 if (size_elem_list==1)
620 {
621 // Easy, one element in the list
622 elem_identifie = elems[0];
623 }
624 else if (size_elem_list==2 && norme_array(delt_dist)==0)
625 {
626 // Check first if it is not 2 elements surrounding 2 internal superposed boundary faces, in this
627 // case, discards the element linked to the local boundary face
628 int local_face = fr_vf2.num_premiere_face()+ind_face;
629 int local_elem = zvf.face_voisins(local_face,0);
630 if (local_elem==-1) local_elem = zvf.face_voisins(local_face,1);
631 //Cerr << "[" << Process::me() << "<->" << pe << "] nb_faces=" << fr_vf2.nb_faces() << " face= " << ind_face << " " << local_elem << " " << elems[0] << " " << elems[1] << finl;
632 if (elems[0]==local_elem)
633 elem_identifie=elems[1]; // Remote elem
634 else if (elems[1]==local_elem)
635 elem_identifie=elems[0]; // Remote elem
636 else
637 {
638 // Surely 2 elements surrounding an internal face so select one element:
639 elem_identifie = Domaine::identifie_item_unique(elems,coord_elems,remote_point);
640 }
641 }
642 else
643 {
644 // Find a unic remote elem:
645 elem_identifie = Domaine::identifie_item_unique(elems,coord_elems,remote_point);
646 }
647 elem_list[ind_face] = (elem_identifie < nb_elem_domaine1 ? elem_identifie : -1);
648 }
649 }
650
651 // We fill these three arrays:
652 DoubleTab& coord1 = inconnues1_coords_to_eval_[pe];
653
654 ArrOfInt& num_elem = inconnues1_elems_[pe];
655
656 ArrOfInt& index_to_recv = indexes_to_recv[pe];
657
658
659 int nb_remote_faces = 0;
660 // Loop on local faces on the process pe:
661 for (int face = 0; face < nb_faces_on_pe; face++)
662 {
663 const int elem = elem_list[face];
664 if (elem < 0 || elem >= nb_elem_domaine1)
665 {
666 // This coordinate is not on this processor...
667 }
668 else
669 {
670 coord1.resize(nb_remote_faces + 1, dim);
671 for (int j = 0; j < dim; j++)
672 coord1(nb_remote_faces, j) = remote_coords_on_pe(face, j);
673 nb_remote_faces++;
674 num_elem.append_array(elem);
675 index_to_recv.append_array(face);
676 }
677 }
678 }
679
680 // Send index_to_recv data to each processor
681 envoyer_all_to_all(indexes_to_recv, inconnues2_faces_);
682
683 // Check that each coordinate is received from at least one processor:
684 const int nb_faces2 = remote_coords[moi].dimension(0);
685 ArrOfDouble count(nb_faces2);
686 for (int pe = 0; pe < nprocs; pe++)
687 {
688 const ArrOfInt index_to_recv = inconnues2_faces_[pe];
689 const int n = index_to_recv.size_array();
690 for (int i = 0; i < n; i++)
691 count[index_to_recv[i]] ++;
692 //Cerr << index_to_recv << finl;
693 }
694 bool error_1 = false, error_2 = false;
695 for (int i = 0; i < nb_faces2; i++)
696 {
697 if (count[i] < 1)
698 {
699 Journal() << "Champ_front_recyclage : error face (number "<< i<< ") " << remote_coords[moi](i, 0) << " " << remote_coords[moi](i, 1) << " "
700 << ((dim==3)?remote_coords[moi](i, 2):0.) << " no matching element found" << finl;
701 error_1 = true;
702 }
703 else if (count[i]>1)
704 {
705 Journal() << "Champ_front_recyclage : error face (number "<< i<< ") " << remote_coords[moi](i, 0) << " " << remote_coords[moi](i, 1) << " "
706 << ((dim==3)?remote_coords[moi](i, 2):0.) << " " << count[i] << " corresponding points" << finl;
707 error_2 = true;
708 }
709
710 }
711 if (mp_or(error_1))
712 {
713 Cerr << "Error in Champ_front_recyclage.\n"
714 << "No matching source element found for some faces of boundary " << nom_bord2
715 << " (see log files)." << finl;
716 Cerr << "If you are sure that boundary faces match with faces of the other domain, try adding this keyword:" << finl;
717 Cerr << "PrecisionGeom 1.e-6" << finl;
718 Cerr << "Just after the following keyword in your data file:" << finl;
719 Cerr << "dimension " << Objet_U::dimension << finl;
720 barrier();
721 exit();
722 }
723
724 if (mp_or(error_2))
725 {
726 Cerr << "Error in Champ_front_recyclage.\n"
727 << "At least two elements match for some faces of boundary " << nom_bord2
728 << " (see log files)." << finl;
729
730 barrier();
731 exit();
732 }
733
736 mettre_a_jour(temps);
737
738 return 1;
739
740}
741
742//-Evaluation of the values of l_inconnue1 at the points located
743// in plane1 (xv(faces_bord2) + delt_dist)
744//-Exchange of data between processors
745//-Computation of moyenne_imposee_ and moyenne_recyclee_ if time-dependent evaluation
746// (done by the local processor on bord2 from data received from other
747// processors or specified in the data set)
748//
750{
751
752 DoubleTab& tab = valeurs_au_temps(temps);
753 const int nprocs = nproc();
754 DoubleTabs values_to_send(nprocs);
755 DoubleTabs values_to_recv(nprocs);
756 // temporary array (because valeur_aux_elems wants intvect and not arrofint)
757 IntVect elems;
758
759
760 for (int pe = 0; pe < nprocs; pe++)
761 {
762 elems.resize(inconnues1_elems_[pe].size_array());
763 elems.inject_array(inconnues1_elems_[pe]);
764
765 const int n = elems.size_array();
766 values_to_send[pe].resize(n,nb_compo_);
767 l_inconnue1->valeur_aux_elems(inconnues1_coords_to_eval_[pe],
768 elems,
769 values_to_send[pe]);
770
771 }
772 envoyer_all_to_all(values_to_send, values_to_recv);
773 for (int pe = 0; pe < nprocs; pe++)
774 {
775 const DoubleTab& values = values_to_recv[pe];
776 const ArrOfInt index_to_recv = inconnues2_faces_[pe];
777 const int n = index_to_recv.size_array();
778 for (int i = 0; i < n; i++)
779 {
780 const int idx = index_to_recv[i];
781 for (int j = 0; j < nb_compo_; j++)
782 tab(idx, j) = values(i, j);
783 }
784 }
785
786 const Front_VF& fr_vf2 = ref_cast(Front_VF,la_frontiere_dis.valeur());
787 int nb_faces2 = fr_vf2.nb_faces();
788
789 calcul_moyenne_imposee(tab,temps);
790 calcul_moyenne_recyclee(tab,temps);
791
792 for (int i=0; i<nb_faces2; i++)
793 for (int dir=0; dir<nb_compo_; dir++)
794 tab(i,dir) = ampli_moy_imposee_(dir)*moyenne_imposee_(i,dir) + ampli_fluct_(dir)*(tab(i,dir)-ampli_moy_recyclee_(dir)*moyenne_recyclee_(i,dir));
795
797
798}
799
800//Building data necessary for estimating moyenne_imposee_
801//according to the chosen evaluation method (methode_moy_impos_)
802//
804{
805
806 const Front_VF& fr_vf2 = ref_cast(Front_VF,la_frontiere_dis.valeur());
807
808 if (methode_moy_impos_==1)
809 {
810 profil_2.dimensionner(nb_compo_);
811 for (int i=0; i<nb_compo_; i++)
812 {
813 profil_2[i].setNbVar(4);
814 profil_2[i].setString(fcts_xyz[i]);
815 profil_2[i].addVar("t");
816 profil_2[i].addVar("x");
817 profil_2[i].addVar("y");
818 profil_2[i].addVar("z");
819 profil_2[i].parseString();
820 }
821 }
822 else if (methode_moy_impos_==2)
823 {
825 }
826 else if (methode_moy_impos_==3)
827 {
829 }
830 else if (methode_moy_impos_==4)
831 {
833 }
834 else if (methode_moy_impos_==5)
835 {
836 const Domaine_dis_base& domaine_dis2 = fr_vf2.domaine_dis();
837 const Domaine_VF& le_dom2 = ref_cast(Domaine_VF,domaine_dis2);
838 const DoubleTab& xv2 = le_dom2.xv();
839
840 double Kappa = 0.41;
841 double d_paroi,y_plus,U_log;
842
843 int nbface2 = fr_vf2.nb_faces();
844 int num1 = fr_vf2.num_premiere_face();
845 int num2 = num1 + nbface2;
846 int num_face_loc;
847
848 for (int num_face2=num1; num_face2<num2; num_face2++)
849 {
850 num_face_loc = num_face2-num1;
851 d_paroi = diametre/2.;
852
853 if(dimension==3)
854 {
855 if(abs(ndir)==1) d_paroi -= sqrt(xv2(num_face2,1)*xv2(num_face2,1) + xv2(num_face2,2)*xv2(num_face2,2));
856 if(abs(ndir)==2) d_paroi -= sqrt(xv2(num_face2,0)*xv2(num_face2,0) + xv2(num_face2,2)*xv2(num_face2,2));
857 if(abs(ndir)==3) d_paroi -= sqrt(xv2(num_face2,0)*xv2(num_face2,0) + xv2(num_face2,1)*xv2(num_face2,1));
858 }
859 else
860 {
861 if(abs(ndir)==1) d_paroi -= sqrt(xv2(num_face2,1)*xv2(num_face2,1));
862 if(abs(ndir)==2) d_paroi -= sqrt(xv2(num_face2,0)*xv2(num_face2,0));
863 }
864
865 y_plus = d_paroi*u_tau/visco_cin;
866 U_log = (1./Kappa)*log(y_plus) + 5.1;
867 U_log *= u_tau;
868 U_log *= ndir/abs(ndir);
869
870 for (int dir=0; dir<nb_compo_; dir++)
871 moyenne(num_face_loc,dir) = ((dir+1)==abs(ndir))*U_log;
872 }
873 }
874}
875
876//Building data necessary for estimating moyenne_recyclee_
877//according to the chosen evaluation method (methode_moy_recycl_)
878//
880{
881 const Front_VF& fr_vf2 = ref_cast(Front_VF,la_frontiere_dis.valeur());
882 if (methode_moy_recycl_==2)
883 {
885 }
886 else if (methode_moy_recycl_==3)
887 {
889 }
890 else if (methode_moy_recycl_==4)
891 {
893 }
894}
895
896
897//Evaluation of moyenne_imposee_ according to the chosen evaluation method
898//-methode_moy_impos_==1 : analytical profile
899//-methode_moy_impos_==2 : no update (see initialiser_moyenne_imposee())
900// read at initialization and interpolation of data read
901//-methode_moy_impos_==3 : no update (see initialiser_moyenne_imposee())
902// read at initialization to perform connexion_approchee
903//-methode_moy_impos_==4 : no update (see initialiser_moyenne_imposee())
904// read at initialization to perform connexion_exacte
905//-methode_moy_impos_==5 : no update (see initialiser_moyenne_imposee())
906// built at initialization using a log law:
907// U_log = ndir/abs(ndir)*u_tau*(1./Kappa)*log(y_plus) + 5.1;
908//
909void Champ_front_recyclage::calcul_moyenne_imposee(const DoubleTab& tab,double temps)
910{
911 if (methode_moy_impos_==1)
912 {
913 const Front_VF& fr_vf2 = ref_cast(Front_VF,la_frontiere_dis.valeur());
914 const Domaine_dis_base& domaine_dis2 = fr_vf2.domaine_dis();
915 const Domaine_VF& le_dom2 = ref_cast(Domaine_VF,domaine_dis2);
916 const DoubleTab& xv2 = le_dom2.xv();
917 int nb_faces_bord2 = fr_vf2.nb_faces();
918 int ndeb = fr_vf2.num_premiere_face();
919
920 for (int i=0; i<nb_faces_bord2; i++)
921 for (int j=0; j<nb_compo_; j++)
922 {
923 profil_2[j].setVar(0,temps);
924 for (int d=0; d<dimension; d++)
925 profil_2[j].setVar(d+1,xv2(ndeb+i,d));
926 moyenne_imposee_(i,j) = profil_2[j].eval();
927 }
928 }
929 else if (methode_moy_impos_==2)
930 {
931 }
932 else if (methode_moy_impos_==3)
933 {
934 }
935 else if (methode_moy_impos_==4)
936 {
937 }
938 else if (methode_moy_impos_==5)
939 {
940 }
941 else if (methode_moy_impos_!=-1)
942 {
943 Cerr<<"The method used to calculate moyenne_imposee_ is not definded."<<finl;
944 exit();
945 }
946}
947
948//Evaluation of moyenne_recyclee_ according to the chosen evaluation method
949//-methode_moy_recycl_==1 : surface average on bord2 of the values estimated
950// by l_inconnue1 in plan1
951//-methode_moy_recycl_==2 : no update (see initialiser_moyenne_recyclee)
952// read at initialization and interpolation of data read
953//-methode_moy_recycl_==3 : no update (see initialiser_moyenne_recyclee())
954// read at initialization to perform connexion_approchee
955//-methode_moy_recycl_==4 : no update (see initialiser_moyenne_recyclee())
956// read at initialization to perform connexion_exacte
957//
958void Champ_front_recyclage::calcul_moyenne_recyclee(const DoubleTab& tab,double temps)
959{
960 if (methode_moy_recycl_==1)
961 {
962 const Front_VF& fr_vf2 = ref_cast(Front_VF,la_frontiere_dis.valeur());
963 int nb_faces_bord2 = fr_vf2.nb_faces();
964 DoubleVect face_surfaces;
965 const Faces& les_faces_bord = fr_vf2.frontiere().faces();
966 les_faces_bord.calculer_surfaces(face_surfaces);
967
968 DoubleVect moyenne(nb_compo_);
969 double somme_si = 0.;
970 moyenne = 0.;
971 for (int i=0; i<nb_faces_bord2; i++)
972 {
973 for (int j=0; j<nb_compo_; j++)
974 moyenne(j) += tab(i,j)*face_surfaces(i);
975
976 somme_si += face_surfaces(i);
977 }
978 somme_si = mp_sum(somme_si);
979
980 for (int j=0; j<nb_compo_; j++)
981 moyenne(j) = mp_sum(moyenne(j));
982 moyenne /= somme_si;
983
984 for (int i=0; i<nb_faces_bord2; i++)
985 for (int j=0; j<nb_compo_; j++)
986 moyenne_recyclee_(i,j) = moyenne(j);
987 }
988 else if (methode_moy_recycl_==2)
989 {
990 }
991 else if (methode_moy_recycl_==3)
992 {
993 }
994 else if (methode_moy_recycl_==4)
995 {
996 }
997 else if (methode_moy_recycl_!=-1)
998 {
999 Cerr<<"The method used to calculate moyenne_recyclee_ is not defined."<<finl;
1000 exit();
1001 }
1002}
1003
1004//-Reading the file to dimension y_Pb2 and U_Pb2
1005//-Using the data read from the file for the three points
1006// with coordinates closest to y in order to interpolate
1007// the associated variable
1008//
1009double Champ_front_recyclage::UPb(double y,Nom nom_fich)
1010{
1011
1012 int nb_pts;
1013 DoubleVect y_Pb2;
1014 DoubleVect U_Pb2;
1015 int l=0;
1016
1018 {
1019 EFichier fich_Pb2(nom_fich);
1020 while (!fich_Pb2.eof())
1021 {
1022 y_Pb2.resize(l+1);
1023 U_Pb2.resize(l+1);
1024 fich_Pb2 >> y_Pb2(l) >> U_Pb2(l);
1025 l++;
1026 }
1027 fich_Pb2.close();
1028 }
1029
1030 envoyer_broadcast(l,0);
1031 if (!(Process::je_suis_maitre()))
1032 {
1033 y_Pb2.resize(l);
1034 U_Pb2.resize(l);
1035 }
1036 envoyer_broadcast(y_Pb2,0);
1037 envoyer_broadcast(U_Pb2,0);
1038
1039 nb_pts=l-1;
1040 y_Pb2.resize(nb_pts);
1041 U_Pb2.resize(nb_pts);
1042
1043 l=0;
1044 int l_deb;
1045
1046 while ((y>y_Pb2(l)) && (l<nb_pts))
1047 {
1048 l++;
1049 }
1050
1051 if (l<2)
1052 {
1053 l_deb=0;
1054 }
1055 else
1056 {
1057 if (l>(nb_pts-2))
1058 {
1059 l_deb=nb_pts-3;
1060 }
1061 else
1062 {
1063 if ( (y-y_Pb2(l-1)) > (y_Pb2(l)-y) )
1064 {
1065 l_deb=l-2;
1066 }
1067 else
1068 {
1069 l_deb=l-1;
1070 }
1071 }
1072 }
1073
1074 double ya=y_Pb2(l_deb);
1075 double Ua=U_Pb2(l_deb);
1076 double yb=y_Pb2(l_deb+1);
1077 double Ub=U_Pb2(l_deb+1);
1078 double yc=y_Pb2(l_deb+2);
1079 double Uc=U_Pb2(l_deb+2);
1080 double U;
1081
1082 U=(y-ya)*(y-yb)/(yc-ya)/(yc-yb)*Uc;
1083 U+=(y-yb)*(y-yc)/(ya-yb)/(ya-yc)*Ua;
1084 U+=(y-yc)*(y-ya)/(yb-yc)/(yb-ya)*Ub;
1085
1086 return U;
1087
1088}
1089
1090//-Determine a direction orthogonal to the anisotropic direction
1091//-For each evaluation point located in plane1:
1092// Estimate its coordinate y in the orthogonal direction
1093// Initialize the mean (in the anisotropic direction) from
1094// the UPb function for coordinate y
1095//
1097 const Frontiere_dis_base& fr_vf,
1098 const Nom& nom_fich)
1099{
1100 const Front_VF& fr_vf2 = ref_cast(Front_VF,fr_vf);
1101 DoubleTab coords;
1102 get_coord_faces(fr_vf2,coords,delt_dist);
1103 const int nb_faces2 = coords.dimension(0);
1104
1105 int dir_ortho = -1;
1106 if ((ndir==1) || (ndir==2))
1107 dir_ortho = ndir;
1108 else if (ndir==3)
1109 dir_ortho = 0;
1110 else
1111 {
1112 Cerr<<"For this method the anisotropic direction mut be 1 2 or 3"<<finl;
1113 exit();
1114 }
1115
1116 for (int i=0; i<nb_faces2; i++)
1117 {
1118 double y = coords(i,dir_ortho);
1119 moyenne(i,ndir-1) = UPb(y,nom_fich);
1120 }
1121}
1122
1123//-For each face of bord2 (coordinates x2 y2 z2):
1124// Read from file nom_fich the coordinates of points (x1 y1 z1)
1125// and the value(s) of the associated variable var1 [var2] [var3]
1126// Initialize the mean (in the anisotropic direction if specified,
1127// or for all components otherwise) from var1 [var2] [var3]
1128// associated to point x1 y1 z1 which is at the smallest distance from x2 y2 z2
1129//
1130// Possible parallel issue if (x1 y1 z1) do not cover the virtual parts
1131// or if two points are at equal distance from a point (x2 y2 z2)
1132//
1134 const Frontiere_dis_base& fr_vf,
1135 const Nom& nom_fich)
1136{
1137
1138 int N1;
1139 int num_face1, indice_compo;
1140 int num_face2, num_face2_loc;
1141 double x1,y1,z1;
1142 double x2,y2,z2;
1143 z2 = 0.;
1144 DoubleVect val(nb_compo_);
1145
1146 // Read the file and keep in memory
1147 ifstream fic_Utargtest(nom_fich); // test
1148 if (!fic_Utargtest)
1149 {
1150 Cerr <<"No file of name : "<<nom_fich<<" is available."<<finl;
1151 exit();
1152 }
1153 LecFicDiffuse fic_Utarg(nom_fich, ios::in);
1154 fic_Utarg >> N1;
1155 ArrOfDouble fich_buffer(N1*(nb_compo_+dimension));
1156 fic_Utarg.get(fich_buffer.addr(), fich_buffer.size_array());
1157 fic_Utarg.close();
1158
1159 const Front_VF& fr_vf2 = ref_cast(Front_VF,fr_vf);
1160 int num1 = fr_vf2.num_premiere_face();
1161 int num2 = num1 + fr_vf2.nb_faces();
1162 const Domaine_dis_base& domaine_dis2 = fr_vf2.domaine_dis();
1163 const Domaine_VF& zvf2 = ref_cast(Domaine_VF,domaine_dis2);
1164 const DoubleTab& xv2 = zvf2.xv();
1165
1166 for (num_face2=num1; num_face2<num2; num_face2++)
1167 {
1168 x2 = xv2(num_face2,0);
1169 y2 = xv2(num_face2,1);
1170 if (dimension==3) z2 = xv2(num_face2,2);
1171 num_face2_loc = num_face2-num1;
1172
1173 double dist = 1.E6;
1174 double dist_eval;
1175
1176 for (num_face1=0; num_face1<N1; num_face1++)
1177 {
1178 x1 = fich_buffer[num_face1*(nb_compo_+dimension)];
1179 y1 = fich_buffer[num_face1*(nb_compo_+dimension)+1];
1180 if(dimension==3) z1 = fich_buffer[num_face1*(nb_compo_+dimension)+2];
1181 dist_eval = (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
1182 if (dimension==3) dist_eval+=(z2-z1)*(z2-z1);
1183
1184 if(dist_eval<dist)
1185 {
1186 for (indice_compo=0; indice_compo<nb_compo_; indice_compo++)
1187 val(indice_compo) = fich_buffer[num_face1*(nb_compo_+dimension)+dimension+indice_compo];
1188 dist = dist_eval;
1189 if ((abs(ndir)<4) && (abs(ndir)>0))
1190 moyenne(num_face2_loc,abs(ndir)-1) = val(abs(ndir)-1);
1191 else
1192 for (indice_compo=0; indice_compo<nb_compo_; indice_compo++)
1193 moyenne(num_face2_loc,indice_compo) = val(indice_compo);
1194 }
1195 }
1196 }
1197}
1198
1199//-For each face of bord2 (coordinates x2 y2 z2):
1200// Read from file nom_fich2 the coordinates of points (x1 y1 z1)
1201// Read from file nom_fich1 the values of the associated variable
1202// and initialize the mean from these values. Reading stops
1203// when the values associated to point x1 y1 z1 that is in exact
1204// connection with x2 y2 z2 along the anisotropic direction are read
1205//
1207 const Frontiere_dis_base& fr_vf,
1208 const Nom& nom_fich1,const Nom& nom_fich2)
1209{
1210 int Nbfaces,trouve,compteur;
1211 int num_face2,num_face2_loc;
1212 double x1=0.,y1=0.,z1=0.;
1213 double x2=0.,y2=0.,z2=0.;
1214 double eps=1.e-4;
1215
1216 Nom fichier = "VERIF_face_perio.";
1217 fichier += nom_pb1;
1218 EcrFicCollecte fic(fichier);
1219
1220 ifstream fic_geom_test(nom_fich2);
1221 if (!fic_geom_test)
1222 {
1223 Cerr <<"No file of name : "<<nom_fich2<<" is available."<<finl;
1224 exit();
1225 }
1226
1227 ifstream fic_Umoy_test(nom_fich1);
1228 if (!fic_Umoy_test)
1229 {
1230 Cerr <<"No file of name : "<<nom_fich1<<" is available."<<finl;
1231 exit();
1232 }
1233
1234 if (abs(ndir)!=1 && abs(ndir)!=2 && abs(ndir)!=3)
1235 {
1236 Cerr << finl;
1237 Cerr << "Error while reading the boundary condition " << fr_vf.le_nom() << finl;
1238 Cerr << "You must define the keyword \"direction_anisotrope\"" << finl;
1239 exit();
1240 }
1241
1242 if (abs(ndir)==3 && dimension==2)
1243 {
1244 Cerr << finl;
1245 Cerr << "Error while reading the boundary condition " << fr_vf.le_nom() << finl;
1246 Cerr << "You must define the keyword \"direction_anisotrope\" with a direction different than 'z' in 2D" << finl;
1247 exit();
1248 }
1249
1250 const Front_VF& fr_vf2 = ref_cast(Front_VF,fr_vf);
1251 int num1 = fr_vf2.num_premiere_face();
1252 int num2 = num1 + fr_vf2.nb_faces();
1253 const Domaine_dis_base& domaine_dis2 = fr_vf2.domaine_dis();
1254 const Domaine_VF& zvf2 = ref_cast(Domaine_VF,domaine_dis2);
1255 const DoubleTab& xv2 = zvf2.xv();
1256
1257 // Reading and buffering the two input files
1258 LecFicDiffuse fic_geom(nom_fich2);
1259 LecFicDiffuse fic_Umoy(nom_fich1);
1260 fic_geom >> Nbfaces;
1261 fic_Umoy >> Nbfaces; // useless but we must read it
1262 ArrOfDouble fich_geom_buffer(Nbfaces*(dimension+1));
1263 ArrOfDouble fich_Umoy_buffer(Nbfaces*(dimension+1));
1264 fic_geom.get(fich_geom_buffer.addr(), fich_geom_buffer.size_array());
1265 fic_Umoy.get(fich_Umoy_buffer.addr(), fich_Umoy_buffer.size_array());
1266 fic_geom.close();
1267 fic_Umoy.close();
1268
1269 for (num_face2=num1; num_face2<num2; num_face2++)
1270 {
1271 x2 = xv2(num_face2,0);
1272 y2 = xv2(num_face2,1);
1273 if (dimension==3) z2 = xv2(num_face2,2);
1274 num_face2_loc = num_face2-num1;
1275
1276 trouve = 0;
1277 compteur = 0;
1278
1279 // Looking for (x2,y2[,z2]) into (x1,y1[,z1])
1280 while (compteur<Nbfaces)
1281 {
1282 x1 = fich_geom_buffer[compteur*(dimension+1)+1];
1283 y1 = fich_geom_buffer[compteur*(dimension+1)+2];
1284 if (dimension==3)
1285 {
1286 z1 = fich_geom_buffer[compteur*(dimension+1)+3];
1287 if(abs(ndir)==1 && (est_egal(y1,y2,eps)) && (est_egal(z1,z2,eps))) trouve=1;
1288 if(abs(ndir)==2 && (est_egal(x1,x2,eps)) && (est_egal(z1,z2,eps))) trouve=1;
1289 if(abs(ndir)==3 && (est_egal(x1,x2,eps)) && (est_egal(y1,y2,eps))) trouve=1;
1290 }
1291 else
1292 {
1293 if(abs(ndir)==1 && (est_egal(y1,y2,eps))) trouve=1;
1294 if(abs(ndir)==2 && (est_egal(x1,x2,eps))) trouve=1;
1295 }
1296 if (trouve)
1297 {
1298 moyenne(num_face2_loc,0) = fich_Umoy_buffer[compteur*(dimension+1)+1];
1299 moyenne(num_face2_loc,1) = fich_Umoy_buffer[compteur*(dimension+1)+2];
1300 if (dimension==3) moyenne(num_face2_loc,2) = fich_Umoy_buffer[compteur*(dimension+1)+3];
1301 break;
1302 }
1303 compteur++;
1304 }
1305
1306 if (trouve==0)
1307 {
1308 Cerr << " the face "<<num_face2<<" with coordinates : x="<<x2<<" y="<<y2;
1309 if (dimension==3)
1310 Cerr << " z="<<z2;
1311 Cerr << "\n has no corresponding faces in "<<nom_fich2<<finl;
1312 exit();
1313 }
1314
1315 if (dimension==3)
1316 {
1317 fic <<" num_face1 " << fich_geom_buffer[compteur*(dimension+1)] << " " << x1 << " " << y1 << " " << z1 << finl;
1318 fic <<" num_face2 " << num_face2 << " " << x2 << " " << y2 << " " << z2 << finl;
1319 fic <<" " << finl;
1320 }
1321 else
1322 {
1323 fic <<" num_face1 " << fich_geom_buffer[compteur*(dimension+1)] << " " << x1 << " " << y1 << finl;
1324 fic <<" num_face2 " << num_face2 << " " << x2 << " " << y2 << finl;
1325 fic <<" " << finl;
1326 }
1327
1328 }
1329 fic.close();
1330}
class Ch_front_var_instationnaire_dep This abstract class represents a field on a boundary,
int initialiser(double temps, const Champ_Inc_base &inco) override
Initialization at the beginning of calculation.
Class Champ_Inc_base.
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
Champ_front_recyclage.
void calcul_moyenne_recyclee(const DoubleTab &tab, double temps)
void calcul_moyenne_imposee(const DoubleTab &tab, double temps)
void initialiser_moyenne_imposee(DoubleTab &moyenne)
int initialiser(double temps, const Champ_Inc_base &inco) override
Initialization at the beginning of calculation.
void lire_fichier_format2(DoubleTab &moyenne, const Frontiere_dis_base &fr_vf, const Nom &nom_fich)
int lire_info_moyenne_recyclee(Entree &is)
void associer_champ_evaluateur(const Nom &, const Motcle &)
void lire_fichier_format1(DoubleTab &moyenne, const Frontiere_dis_base &fr_vf, const Nom &nom_fich)
void initialiser_moyenne_recyclee(DoubleTab &moyenne)
int lire_info_moyenne_imposee(Entree &is)
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
OBS_PTR(Champ_Inc_base) l_inconnue1
void set_param(Param &param) const override
void mettre_a_jour(double temps) override
DOES NOTHING, to override.
double UPb(double y, Nom nom_fich)
static void get_coord_faces(const Frontiere_dis_base &fr_vf, DoubleTab &coords, const DoubleVect &delt_dist)
void lire_fichier_format3(DoubleTab &moyenne, const Frontiere_dis_base &fr_vf, const Nom &nom_fich1, const Nom &nom_fich2)
DoubleTab & valeurs_au_temps(double temps) override
Returns the values at the desired time.
const OctreeRoot_t & construit_octree() const
Definition Domaine.cpp:816
static int identifie_item_unique(IntList &item_possible, DoubleTab &coord_possible, const DoubleVect &coord_ref)
int_t nb_elem() const
Definition Domaine.h:131
class Domaine_VF
Definition Domaine_VF.h:44
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
double xp(int num_elem, int k) const
Definition Domaine_VF.h:77
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
File for reading. This class is to the C++ ifstream class what the Entree class is to the.
Definition EFichier.h:29
Writing to a file. This class implements the operators and virtual methods of the SFichier class as f...
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
void calculer_surfaces(DoubleVect_t &surf) const
Computes the surface area of the faces.
Definition Faces.cpp:487
virtual void fixer_nb_comp(int i)
Sets the number of components of the field.
int nb_compo_
Definition Field_base.h:95
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
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Frontiere.h:49
const Faces_t & faces() const
Definition Frontiere.h:54
class Frontiere_dis_base Class representing a discretized boundary.
const Frontiere & frontiere() const
Returns the associated geometric boundary.
const Domaine_dis_base & domaine_dis() const
const Nom & le_nom() const override
Returns the name of the geometric boundary.
static Objet_U & objet(const Nom &)
See Interprete_bloc::objet_global(). BM: the Interprete class is not the best place for this.
This class implements the operators and virtual methods of the EFichier class as follows: The file to...
int get(int *ob, std::streamsize n) override
A character string (Nom) in uppercase.
Definition Motcle.h:26
An array of Motcle objects.
Definition Motcle.h:63
int search(const Motcle &t) const
Definition Motcle.cpp:319
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
Base class for TRUST objects (Objet_U).
Definition Objet_U.h:68
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
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
void rang_elems_sommet(SmallArrOfTID_t &, double x, double y=0, double z=0) const
Definition Octree.cpp:1003
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
@ REQUIRED
Definition Param.h:115
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Definition Param.cpp:489
class Probleme_base It is a Probleme_U that is not a coupling.
static bool mp_or(bool)
Definition Process.cpp:427
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 void barrier()
Synchronizes all processors in the current group (waits until all processors have reached the barrier...
Definition Process.cpp:133
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
Base class for output streams.
Definition Sortie.h:52
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
_TYPE_ * addr()
virtual void resize_tab(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTVect.tpp:91
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
void resize(int i)