TrioCFD 1.9.8
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> // Pour 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 est obligatoire pour specifier le nom du probleme
94// et le nom de l inconnue qui vont servir a initialiser la reference
95// vers le champ evaluateur. Le nombre de composantes de ce champ doit etre specifie.
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//Lecture des informations necessaires pour evaluer la moyenne imposee
174//-profil : pour imposer un profil analytique
175//-interpolation : lecture dans un fichier et construction d un champ moyen
176// en realisant une interpolation des donnees lues.
177// La moyenne est construite pour une direction privilegiee
178// (direction_anisotrope) et vaut 0 pour les autres directions
179//-connexion_approchee : lecture dans un fichier et on retient la valeur de la
180// variable lue par connexion avec le point le plus proche
181// de la face de bord consideree
182//-connexion_exacte : lecture dans un fichier geometrie des coordonnees de points
183// situes dans le plan d evaluation et lecture dans un fichier
184// distinct des valeurs moyennes. Les valeurs moyennes lues
185// sont stockees quand la correspondance exacte entre les points
186// en vis a vis est verifiee.
187//- logarithmique : construction de la moyenne par une loi de paroi (logarithmique)
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//Lecture des informations necessaires pour evaluer la moyenne recyclee
370//-surfacique : moyenne surfacique des valeurs recyclees
371// (la moyenne est faite sur le bord2 ou l on recupere les valeurs)
372//-interpolation connexion_approchee connexion_exacte (voir 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//Initialisation de la reference au champ evaluateur (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 de la localisation des points (coords)
475//ou l_inconnue1 doit evaluer les valeurs a recycler
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//-appel a Champ_front_calc::initialiser(...)
496//-dimensionnement de moyenne_imposee_ et moyenne_recyclee_ par nb_faces_bord2 et nb_compo_
497//-constructon des structures assurant le parallelisme :
498// inconnues1_coords_to_eval_ inconnues1_elems_ inconnues2_faces_
499//-initialisation de moyenne_imposee_ et 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 // Pour chaque point de remote_coord, chercher le processeur dont le domaine1 contient ce point,
543 // et l'indice de l'element:
544
545 const int nprocs = nproc();
546 const int moi = me();
547
548 // Remplissage de remote_coords[i]: coordonnees des centres des faces du bord nom_bord2
549 // (bord destination) + delt_dist
550 // du processeur i (tous les procs possedent le meme tableau remote_coords)
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 des valeurs de l_inconnue1 aux points situes
743// dans le plan1 (xv(faces_bord2) + delt_dist)
744//-Echange des donnees entre processeurs
745//-Calcul de moyenne_imposee_ et moyenne_recyclee_ si evaluation dependante du temps
746// (faite par le processeur local sur le bord2 a partir de donnees recues d autres
747// processeurs ou specifiees dans le jeu de donnees)
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//Construction de donnees necessaires a l estimation de moyenne_imposee_
801//en fonction de la methode d evaluation retenue (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//Construction de donnees necessaires a l estimation de moyenne_recyclee_
877//en fonction de la methode d evaluation retenue (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 de moyenne_imposee_ en fonction de la methode d evaluation retenue
898//-methode_moy_impos_==1 : profil analytique
899//-methode_moy_impos_==2 : pas d actualisation (voir initialiser_moyenne_imposee())
900// lecture a l initialisation et interpolation des donnees lues
901//-methode_moy_impos_==3 : pas d actualisation (voir initialiser_moyenne_imposee())
902// lecture a l initialisation pour realiser une connexion_approchee
903//-methode_moy_impos_==4 : pas d actualisation (voir initialiser_moyenne_imposee())
904// lecture a l initialisation pour realiser une connexion_exacte
905//-methode_moy_impos_==5 : pas d actualisation (voir initialiser_moyenne_imposee())
906// construction a l initialisation d une loi log :
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 de moyenne_recyclee_ en fonction de la methode d evaluation retenue
949//-methode_moy_recycl_==1 : moyenne surfacique sur le bord2 des valeurs estimees
950// par l_inconnue1 dans plan1
951//-methode_moy_recycl_==2 : pas d actualisation (voir initialiser_moyenne_recyclee)
952// lecture a l initialisation et interpolation des donnees lues
953//-methode_moy_recycl_==3 : pas d actualisation (voir initialiser_moyenne_recyclee())
954// lecture a l initialisation pour realiser une connexion_approchee
955//-methode_moy_recycl_==4 : pas d actualisation (voir initialiser_moyenne_recyclee())
956// lecture a l initialisation pour realiser une 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//-Lecture du fichier pour dimensionner y_Pb2 et U_Pb2
1005//-Utilisation des donnees lues dans le fichier pour les trois points
1006// possedant les cotes les plus proches de y afin de faire une interpolation
1007// de la variable associee
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//-On determine une direction orthogonale a la direction d anisotropie
1091//-Pour chaque point d evaluation se trouvant dans le plan1 :
1092// Estimation de sa cote y dans la direction orthogonale
1093// Initialisation de moyenne (dans la direction anisotrope) a partir de
1094// la fonction UPb pur la cote 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//-Pour chaque face du bord2 (coordonnes x2 y2 z2):
1124// Lecture dans le fichier nom_fich des coordonnes de points (x1 y1 z1)
1125// et de(s) valeur(s) de la variable associee var1 [var2] [var3]
1126// Initialisation de moyenne (dans la direction anisotrope si celle_ci est specifiee
1127// ou pour toutes les composantes sinon) a partir de var1 [var2] [var3]
1128// associe au point x1 y1 z1 qui est a la plus petite distance de x2 y2 z2
1129//
1130// Defaut de parallelisme eventuel si (x1 y1 z1) ne parcourent pas les parties virtuels
1131// ou si deux points sont a egale distance d un 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//-Pour chaque face du bord2 (coordonnes x2 y2 z2) :
1200// Lecture dans le fichier nom_fch2 des coordonnes de points (x1 y1 z1)
1201// Lecture dans le fichier nom_fich1 des valeurs de la variable associee
1202// et initialisation de moyenne a partir de ces valeurs. La lecture est stoppee
1203// quand on a lu les valeurs associees au point x1 y1 z1 qui est en connexion
1204// exacte avec x2 y2 z2 suivant la direction d anisotropie
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}
classe Ch_front_var_instationnaire_dep Cette classe abstraite represente un champ sur une frontiere,
int initialiser(double temps, const Champ_Inc_base &inco) override
Initialisation en debut de calcul.
Classe Champ_Inc_base.
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
classe 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
Initialisation en debut de calcul.
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
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
OBS_PTR(Champ_Inc_base) l_inconnue1
void set_param(Param &param) const override
void mettre_a_jour(double temps) override
NE FAIT RIEN, a surcharger.
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
Renvoie les valeurs au temps desire.
const OctreeRoot_t & construit_octree() const
Definition Domaine.cpp:817
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
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
Fichier en lecture Cette classe est a la classe C++ ifstream ce que la classe Entree est a la.
Definition EFichier.h:29
Ecriture dans un fichier Cette classe implemente les operateurs et les methodes virtuelles de la clas...
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
Calcule la surface des faces.
Definition Faces.cpp:495
virtual void fixer_nb_comp(int i)
Fixe le nombre de composantes du champ.
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
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Frontiere.h:49
const Faces_t & faces() const
Definition Frontiere.h:54
classe Frontiere_dis_base Classe representant une frontiere discretisee.
const Frontiere & frontiere() const
Renvoie la frontiere geometrique associee.
const Domaine_dis_base & domaine_dis() const
const Nom & le_nom() const override
Renvoie le nom de la frontiere geometrique.
static Objet_U & objet(const Nom &)
Voir Interprete_bloc::objet_global() BM: la classe Interprete n'est pas le meilleur endroit pour cett...
Cette classe implemente les operateurs et les methodes virtuelles de la classe EFichier de la facon s...
int get(int *ob, std::streamsize n) override
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
Un tableau d'objets de la classe Motcle.
Definition Motcle.h:63
int search(const Motcle &t) const
Definition Motcle.cpp:321
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
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
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
static bool mp_or(bool)
Definition Process.cpp:418
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
Definition Process.cpp:588
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
Definition Process.cpp:136
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Classe de base des flux de sortie.
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)