TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Echange_contact_Correlation_VDF.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 <Echange_contact_Correlation_VDF.h>
17#include <Domaine_Cl_dis_base.h>
18#include <Champ_front_calc.h>
19#include <communications.h>
20#include <Champ_Uniforme.h>
21#include <Probleme_base.h>
22#include <Milieu_base.h>
23#include <Domaine_VDF.h>
24#include <Conduction.h>
25#include <Solv_TDMA.h>
26#include <SFichier.h>
27#include <Param.h>
28
29Implemente_instanciable(Echange_contact_Correlation_VDF,"Paroi_Echange_contact_Correlation_VDF",Echange_global_impose);
30// XD paroi_echange_contact_correlation_vdf condlim_base paroi_echange_contact_correlation_vdf BRACE Class to define a
31// XD_CONT thermohydraulic 1D model which will apply to a boundary of 2D or 3D domain. NL2 Warning : For parallel
32// XD_CONT calculation, the only possible partition will be according the axis of the model with the keyword Tranche.
33
34Sortie& Echange_contact_Correlation_VDF::printOn(Sortie& s ) const { return s << que_suis_je() << finl; }
35
37{
38 if (app_domains.size() == 0) app_domains = { Motcle("Thermique") };
39
40 Param param(que_suis_je());
42 dt_impr = 1e10;
43 set_param(param);
44 param.lire_avec_accolades_depuis(is);
45
46 le_champ_front.typer("Champ_front_fonc");
48 h_imp_.typer("Champ_front_fonc");
49 h_imp_->fixer_nb_comp(1);
50 return is;
51}
52
54{
55 param.ajouter("dir",&dir); // XD_ADD_P entier
56 // XD_CONT Direction (0 : axis X, 1 : axis Y, 2 : axis Z) of the 1D model.
57 param.ajouter_condition("(value_of_dir_ge_0)_AND_(value_of_dir_le_2)", "La direction doit etre 0, 1 ou 2 dans Echange_contact_Correlation_VDF");
58 param.ajouter("Tinf",&Tinf); // XD_ADD_P floattant
59 // XD_CONT Inlet fluid temperature of the 1D model (oC or K).
60 param.ajouter("Tsup",&Tsup); // XD_ADD_P floattant
61 // XD_CONT Outlet fluid temperature of the 1D model (oC or K).
62 param.ajouter_non_std("lambda",(this)); // XD_ADD_P chaine
63 // XD_CONT Thermal conductivity of the fluid (W.m-1.K-1).
64 param.ajouter_non_std("rho",(this)); // XD_ADD_P chaine
65 // XD_CONT Mass density of the fluid (kg.m-3) which may be a function of the temperature T.
66 param.ajouter("dt_impr",&dt_impr); // XD_ADD_P floattant
67 // XD_CONT Printing period in name_of_data_file_time.dat files of the 1D model results.
68 param.ajouter("Cp",&Cp); // XD_ADD_P floattant
69 // XD_CONT Calorific capacity value at a constant pressure of the fluid (J.kg-1.K-1).
70 param.ajouter_non_std("mu",(this)); // XD_ADD_P chaine
71 // XD_CONT Dynamic viscosity of the fluid (kg.m-1.s-1) which may be a function of thetemperature T.
72 param.ajouter("debit",&debit); // XD_ADD_P floattant
73 // XD_CONT Surface flow rate (kg.s-1.m-2) of the fluid into the channel.
74 param.ajouter("Dh",&diam); // XD_ADD_P floattant
75 // XD_CONT Hydraulic diameter may be a function f(x) with x position along the 1D axis (xinf <= x <= xsup)
76 param.ajouter_non_std("volume",(this)); // XD_ADD_P chaine
77 // XD_CONT Exact volume of the 1D domain (m3) which may be a function of the hydraulic diameter (Dh) and the lateral
78 // XD_CONT surface (S) of the meshed boundary.
79 param.ajouter_non_std("Nu",(this)); // XD_ADD_P chaine
80 // XD_CONT Nusselt number which may be a function of the Reynolds number (Re) and the Prandtl number (Pr).
81 // Rajout Cyril MALOD (14/09/2006)
82 param.ajouter_flag("Reprise_correlation",&Reprise_temperature); // XD_ADD_P rien
83 // XD_CONT Keyword in the case of a resuming calculation with this correlation.
84}
85
87{
88 int retval = 1;
89
90 if (mot=="lambda")
91 {
92 Nom tmp;
93 is >> tmp;
94 lambda_T.setNbVar(1);
95 lambda_T.setString(tmp);
96 lambda_T.addVar("T");
97 lambda_T.parseString();
98 }
99 else if (mot=="rho")
100 {
101 Nom tmp;
102 is >> tmp;
103 rho_T.setNbVar(1);
104 rho_T.setString(tmp);
105 rho_T.addVar("T");
106 rho_T.parseString();
107 }
108 else if (mot=="mu")
109 {
110 Nom tmp;
111 is >> tmp;
112 mu_T.setNbVar(1);
113 mu_T.setString(tmp);
114 mu_T.addVar("T");
115 mu_T.parseString();
116 }
117 else if (mot=="volume")
118 {
119 Nom tmp;
120 is >> tmp;
121 fct_vol.setNbVar(2);
122 fct_vol.setString(tmp);
123 fct_vol.addVar("Dh");
124 fct_vol.addVar("S");
125 fct_vol.parseString();
126 }
127 else if (mot=="Nu")
128 {
129 Nom tmp;
130 is >> tmp;
131 fct_Nu.setNbVar(2);
132 fct_Nu.setString(tmp);
133 fct_Nu.addVar("Re");
134 fct_Nu.addVar("Pr");
135 fct_Nu.parseString();
136 }
137 else retval = -1;
138
139 return retval;
140}
141
142
143/**
144 * Calcule le coeff d echange local dans la maille solide.
145 */
147{
148 // forcement local
149 const Equation_base& mon_eqn = domaine_Cl_dis().equation();
150 const Milieu_base& mon_milieu = mon_eqn.milieu();
151 const Domaine_VDF& ma_zvdf = ref_cast(Domaine_VDF,domaine_Cl_dis().domaine_dis());
152 const Front_VF& ma_front_vf = ref_cast(Front_VF,frontiere_dis());
153 calculer_h_solide(tab,mon_eqn,ma_zvdf,ma_front_vf,mon_milieu);
154}
155
156
157
158/**
159 * Complete et initialise les attributs de la classe
160 */
162{
164 trier_coord();
165 T=std::min(Tinf,Tsup);
167 if (T(0)==Tinf)
168 U=debit/rho(0);
169 else U = debit/rho(N-1);
170
171 for (int i=0; i<N; i++)
173
174 DoubleTab& mon_h= h_imp_->valeurs();
175 // calculer_h_mon_pb(mon_h);
176
177
178 const Front_VF& ma_front_vf = ref_cast(Front_VF,frontiere_dis());
179 const int nb_faces_bord = ma_front_vf.nb_faces();
180 DoubleTab& Text_valeurs = T_ext().valeurs();
181 Text_valeurs.resize(nb_faces_bord,1);
182
183 mon_h.resize(nb_faces_bord,1);
184
185 for (int ii=0; ii<nb_faces_bord; ii++)
186 {
188 Text_valeurs(ii,0) = T(correspondance_solide_fluide(ii));
189 }
190
192
193 //Mise a jour car pas de dependance a des donnees d un autre probleme
194 //dans le cas de probleme couple
195 //Methode completer() peut etre a remplacer par methode initialiser()
197 const double temps = mon_eqn.schema_temps().temps_courant();
198 mettre_a_jour(temps);
199}
200
201/**
202 * Initialise le tab tab_ech pour le parallele
203 */
205{
206 DoubleVect y_envoye(2);
207 DoubleVect y_recu(2);
208 y_envoye(0) = coord(1); // y_min
209 y_envoye(1) = coord(N-2); // y_max
210
211
212 const Joints& joints = domaine_Cl_dis().domaine().faces_joint();
213 const int nb_voisins = joints.size();
214
215 const int ME=Process::me();
217 tab_ech=-1;
218 for (int i=0; i<nb_voisins; i++)
219 {
220 int mon_voisin = joints[i].PEvoisin();
221 Cerr << " Echange_contact_Correlation_VDF::init_tab_echange() A verifier pour envoi blocant" << finl;
222 exit();
223 envoyer(y_envoye,ME,mon_voisin,ME);
224
225 recevoir(y_recu,mon_voisin,ME,mon_voisin);
226 if (y_recu(1)<coord(1))
227 {
228 tab_ech(mon_voisin,ME)=1; // mon_voisin m'enverra le max
229 }
230 else if (y_recu(0)>coord(N-2))
231 {
232 tab_ech(mon_voisin,ME)=0; // mon_voisin m'enverra le min
233 }
234 }
235}
236
237
238/**
239 * Calcule rho, mu et lambda du fluide pour la temperature courante
240 */
242{
243 for (int i=0; i<N; i++)
244 {
245 rho_T.setVar("T",T(i));
246 mu_T.setVar("T",T(i));
247 lambda_T.setVar("T",T(i));
248 rho(i) = rho_T.eval();
249 mu(i) = mu_T.eval();
250 lambda(i) = lambda_T.eval();
251 }
252}
253
254/**
255 * Calcule le coeff d echange suivant la correlation entree dans le jdd
256 */
258{
259 double Re,Pr;
260 Re = std::fabs(getQh()*getDh()/getMu(i));
261 Pr = getMu(i)*getCp()/getLambda(i);
262 fct_Nu.setVar("Re",Re);
263 fct_Nu.setVar("Pr",Pr);
264 return fct_Nu.eval()*getLambda(i)/getDh();
265}
266
267/**
268 * Calcul du terme source de puissance volumique dans l'equation d'energie 1D fluide.
269 */
271{
272 const Domaine_VDF& ma_zvdf = ref_cast(Domaine_VDF,domaine_Cl_dis().domaine_dis());
273 const Front_VF& ma_front_vf = ref_cast(Front_VF,frontiere_dis());
274 const int ndeb = ma_front_vf.num_premiere_face();
275 const int nb_faces_bord = ma_front_vf.nb_faces();
276 const DoubleVect& surfaces = ma_zvdf.face_surfaces();
277 const IntTab& face_voisins = ma_zvdf.face_voisins();
279 DoubleTab& Ts = inco.valeurs();
280 DoubleTab& mon_h= h_imp_->valeurs();
281
282
283 Qvol=0.;
284 for(int iface=0; iface<nb_faces_bord; iface++)
285 {
286 int corresp = correspondance_solide_fluide(iface);
287 int elem = face_voisins(ndeb+iface,0);
288 if(elem == -1)
289 elem = face_voisins(ndeb+iface,1);
290 Qvol(corresp)+=mon_h(iface,0)*(Ts(elem)-T(corresp))*surfaces(ndeb+iface);
291 }
292 for (int i=0; i<N; i++)
293 Qvol(i)/=vol(i);
294}
295
296
297
299{
300 const Domaine_VDF& ma_zvdf = ref_cast(Domaine_VDF,domaine_Cl_dis().domaine_dis());
301 const DoubleVect& surfaces = ma_zvdf.face_surfaces();
302 const Front_VF& ma_front_vf = ref_cast(Front_VF,frontiere_dis());
303
304 const int ndeb = ma_front_vf.num_premiere_face();
305 const int nb_faces_bord = ma_front_vf.nb_faces();
306
307 IntVect face_triee(nb_faces_bord);
308 const DoubleTab& xv = ma_zvdf.xv();
309 int i, j ,tmp;
310
311 // On trie les faces par coordonnees croissante (selon la coordonnee correspondante a la direction du tube)
312 if (nb_faces_bord>1)
313 {
314 for(i=0; i<nb_faces_bord; i++)
315 face_triee(i) = ndeb+i;
316
317 for(i=1; i<nb_faces_bord; i++)
318 {
319 j=i-1;
320 tmp = face_triee(i);
321 while ( j>=0 && xv(face_triee(j),dir)>xv(tmp,dir))
322 {
323 face_triee(j+1) = face_triee(j);
324 j--;
325 }
326 face_triee(j+1) = tmp;
327 }
328 }
329 // On determine le nb de mailles 1D dans le fluide fictif
330 // et on remplit les correspondances elements solides -> elements fluides
331 correspondance_solide_fluide.resize(nb_faces_bord);
332 N=3; // on rajoute les noeuds des bords
333 correspondance_solide_fluide(face_triee(0)-ndeb) = 1;
334 for(i=1; i<nb_faces_bord; i++)
335 {
336 if (xv(face_triee(i),dir) != xv(face_triee(i-1),dir))
337 N++;
338 correspondance_solide_fluide(face_triee(i)-ndeb) = N-2;
339 }
340
341 U.resize(N);
342 T.resize(N);
343 Qvol.resize(N);
344 rho.resize(N);
345 mu.resize(N);
346 lambda.resize(N);
347 vol.resize(N);
348 coord.resize(N);
349 h_correlation.resize(N);
350
351
352
353 // calcul des volumes des tranches
354 DoubleVect surf(N);
355 surf=0.;
356 vol=0.;
357 surf(0) = surf(N-1) = 0.; // ne sert pas
358 for(int iface=0; iface<nb_faces_bord; iface++)
359 {
360 int corresp = correspondance_solide_fluide(iface);
361 surf(corresp)+=surfaces(ndeb+iface);
362 coord(corresp) = xv(ndeb+iface,dir);
363 }
364 coord(0) = coord(1)-0.5*(coord(2)-coord(1)); // le premier point du maillage
365 coord(N-1) = coord(N-2)+0.5*(coord(N-2)-coord(N-3)); // le dernier point du maillage
366 for (i=1; i<N-1; i++)
367 {
368 vol(i)=volume(surf(i),diam);
369 }
370 vol(0) = vol(N-1) = 1.; // ne sert pas mais evite une division par zero dans le calcul de Qvol.
371}
372
373
374
375/**
376 * Calcule le volume d'une tranche de la section de surface laterale s et de diametre hydraulique d.
377 */
379{
380 fct_vol.setVar("Dh",d);
381 fct_vol.setVar("S",s);
382
383 return fct_vol.eval();
384}
385
386
387/**
388 * Calcule les CL a appliquer sur l'equation d'energie
389 */
391{
392 const int ME=Process::me();
393
394 const Joints& joints = domaine_Cl_dis().domaine().faces_joint();
395 const int nb_voisins = joints.size();
396
397 DoubleVect les_cl_envoyees(2);
398 DoubleVect les_cl_recues(2);
399 les_cl_envoyees(0) = T(1);
400 les_cl_envoyees(1) = T(N-2);
401
402 T_CL0=Tinf;
403 T_CL1=Tsup;
404 for (int i=0; i<nb_voisins; i++)
405 {
406 int mon_voisin = joints[i].PEvoisin();
407
408 Cerr << " Echange_contact_Correlation_VDF::calculer_CL() A verifier pour envoi blocant" << finl;
409 exit();
410 envoyer(les_cl_envoyees,ME,mon_voisin,ME);
411
412 recevoir(les_cl_recues,mon_voisin,ME,mon_voisin);
413 if (tab_ech(mon_voisin,ME) == 1)
414 {
415 T_CL0 = 0.5*(les_cl_recues(1)+T(1));
416 T(0) = T_CL0;
417 }
418 else if (tab_ech(mon_voisin,ME) == 0)
419 {
420 T_CL1 = 0.5*(les_cl_recues(0)+T(N-2));
421 T(N-1) = T_CL1;
422 }
423 else
424 {
425 Cerr << "Erreur de communication entre les processeurs " <<ME<< " et " <<mon_voisin << finl;
426 Cerr << "dans Echange_contact_Correlation_VDF::calculer_CL" << finl;
427 if (Process::is_parallel()) Cerr << "Verifier que votre decoupage est bien en tranches selon l'axe du modele 1D." << finl;
428 exit();
429
430 }
431 }
432}
433
434
435/**
436 * Calcule la vitesse par conservation de la masse
437 */
439{
440 for (int i=0; i<N; i++)
441 U(i) = debit/rho(i);
442}
443
444
445/**
446 * Calcule la temperature 1D dans le fluide en resolvant la conservation de l'energie
447 */
449{
450 const Equation_base& mon_eqn = domaine_Cl_dis().equation();
451 const double dt = mon_eqn.schema_temps().pas_de_temps();
452 DoubleVect ma(N); // diagonale
453 DoubleVect mb(N-1); // sous-diagonale
454 DoubleVect mc(N-1); // sur-diagonale
455 DoubleVect sm(N);
456 const int sgn = (debit>0) ? 1 : -1; // schema amont pour le transport
457
458
459 ma(0) = 1.;
460 ma(N-1) = 1.;
461 sm(0) = T_CL0;
462 sm(N-1) = T_CL1;
463 mc(0) = 0.;
464 mb(N-2) = 0.;
465 int i;
466 for (i=1; i<N-1; i++)
467 {
468 const double dtrhoCp = dt/rho(i)/Cp;
469 const double dz1 = coord(i+1)-coord(i);
470 const double dz2 = coord(i)-coord(i-1);
471 const double l1 = 0.5*(lambda(i+1)+lambda(i));
472 const double l2 = 0.5*(lambda(i)+lambda(i-1));
473
474 ma(i)=1+dtrhoCp*(sgn*Cp*debit/dz1+2*(l1/dz1+l2/dz2)/(dz1+dz2));
475
476 sm(i) = T(i)+dtrhoCp*Qvol(i);
477
478 mc(i) = dtrhoCp*(0.5*(1-sgn)*Cp*debit/dz1-2*l1/dz1/(dz1+dz2));
479
480 mb(i-1) = dtrhoCp*(-2*l2/dz2/(dz1+dz2));
481 mb(i-1) += dtrhoCp*(-0.5*(1+sgn)*Cp*debit/dz1);
482 }
483
484
485
486
487 DoubleVect xx(N);
488 xx=0.;
489 Solv_TDMA::resoudre(ma,mb,mc,sm,xx,N);
490 for (i=0; i<N; i++)
491 T(i) = xx(i);
492}
493
494
495
496
497/**
498 * Mise a jour de la vitesse, temperature fluide et coeff d'echange
499 */
501{
502
503 // Nom des fichiers de sauvegarde
504 Nom Fichier_sauv_nom=domaine_Cl_dis().equation().probleme().le_nom();
505 Fichier_sauv_nom+="_";
506 Fichier_sauv_nom+=frontiere_dis().frontiere().le_nom();
507 Fichier_sauv_nom+=".sauv";
508
509 // Operation de reprise du champ de temperature dans le fluide
510 const int ME = Process::me();
511 const int nbproc = Process::nproc();
512 FILE *Fichier_sauv;
514 {
515 if (nbproc>1)
516 {
517 Cerr << "A verifier pour envoi blocant" << finl;
518 exit();
519 envoyer(T,ME,0,ME); // J'envoie T pour connaitre la dimension de son tableau
520 if (je_suis_maitre())
521 {
522 double temps_lu=0., Temperature_reprise=0.;
523 char tmp_lu;
524 //int code;
525 Fichier_sauv=fopen(Fichier_sauv_nom,"r"); // J'ouvre le fichier de sauvgarde en lecture seule
526 if (Fichier_sauv!=nullptr)
527 {
528 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // Je lis le premier mot "Temps" pour rien
529 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // Je lis le deuxieme mot "=" pour rien
530 if (!fscanf(Fichier_sauv,"%lf",&temps_lu)) exit(); // Je lis le temps et je le mets dans temps_lu
531 if (temps_lu==temps)
532 {
533 for (int p=0; p<nbproc; p++) // Je boucle sur le nombre de processeur
534 {
535 Cerr << "Reprise du champs de temperature (" << Fichier_sauv_nom << ") pour la correlation sur le processeur " << p << "...";
536 DoubleVect T_tmp;
537 recevoir(T_tmp,p,0,p); // Je recupere T pour connaitre la dimension de son tableau au niveau du processeur maitre.
538 for (int i=0; i<T_tmp.size(); i++) // Je boucle sur le nombre de temperature a definir
539 {
540 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // Je lis le mot "T(i)" pour rien
541 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // Je lis le mot "=" pour rien
542 if (!fscanf(Fichier_sauv,"%lf",&Temperature_reprise)) exit();// Je lis la valeur de la temperature et je la mets dans Temperature_reprise
543 T_tmp(i) = Temperature_reprise; // J'egale la variable du calcul T(i) a Temperature_reprise
544 }
545 envoyer(T_tmp,0,p,0); // J'envoie T_tmp a tous les processeurs
546 Cerr << " OK!" << finl;
547 }
548 fclose(Fichier_sauv);
549 }
550 else
551 {
552 Cerr << "\nLe temps indique dans le fichier \""<< Fichier_sauv_nom << "\" "<< temps_lu << finl;
553 Cerr << "est different du temps de reprise du calcul "<< temps << " !!!" << finl << finl;
554 Cerr << "Vous ne pouvez pas faire de reprise pour la correlation. Supprimez" << finl;
555 Cerr << "dans la correlation le mot clef \"Reprise\". La phase transitoire" << finl;
556 Cerr << "du calcul sera fausse, mais l'etat stationnaire sera juste." << finl << finl;
557 fclose(Fichier_sauv);
558 exit();
559 }
560 }
561 else
562 {
563 Cerr << "\nLa reprise ne peut pas etre faite : Le fichier \"" << Fichier_sauv_nom << "\" est manquant !!!" << finl << finl;
564 exit();
565 }
566 }
567 recevoir(T,0,ME,0); // Je recupere T=T_tmp au niveau de chaque processeur
568 }
569 else
570 {
571 Fichier_sauv=fopen(Fichier_sauv_nom,"r");
572 double temps_lu=0., Temperature_reprise=0.;
573 char tmp_lu;
574
575 if (Fichier_sauv!=nullptr)
576 {
577 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // Je lis le premier mot "Temps" pour rien
578 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // Je lis le deuxieme mot "=" pour rien
579 if (!fscanf(Fichier_sauv,"%lf",&temps_lu)) exit(); // Je lis le temps et je le mets dans temps_lu
580 if (temps_lu==temps)
581 {
582 Cerr << "Reprise du champs de temperature (" << Fichier_sauv_nom << ") pour la correlation...";
583 for (int i=0; i<N; i++)
584 {
585 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // Je lis le mot "T(i)" pour rien
586 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // Je lis le mot "=" pour rien
587 if (!fscanf(Fichier_sauv,"%lf",&Temperature_reprise)) exit();// Je lis la valeur de la temperature et je la mets dans Temperature_reprise
588 T(i) = Temperature_reprise; // J'egale la variable du calcul T(i) a Temperature_reprise
589 }
590 fclose(Fichier_sauv);
591 Cerr << " OK!" << finl;
592 }
593 else
594 {
595 Cerr << "\nLe temps indique dans le fichier \""<< Fichier_sauv_nom << "\" "<< temps_lu << finl;
596 Cerr << "est different du temps de reprise du calcul "<< temps << " !!!" << finl << finl;
597 Cerr << "Vous ne pouvez pas faire de reprise pour la correlation. Supprimez" << finl;
598 Cerr << "dans la correlation le mot clef \"Reprise\". La phase transitoire" << finl;
599 Cerr << "du calcul sera fausse, mais l'etat stationnaire sera juste." << finl << finl;
600 fclose(Fichier_sauv);
601 exit();
602 }
603 }
604 else
605 {
606 Cerr << "\nLa reprise ne peut pas etre faite : Le fichier \"" << Fichier_sauv_nom << "\" est manquant !!!" << finl << finl;
607 exit();
608 }
609 }
611 }
612
613 calculer_CL();
615 calculer_Q();
618
619
620
621 for (int i=0; i<N; i++)
623
624
625
626
627 DoubleTab& mon_h= h_imp_->valeurs();
628 calculer_h_mon_pb(mon_h);
629 const int taille=mon_h.dimension(0);
630 DoubleTab& Text_valeurs = T_ext().valeurs();
631
632 for (int ii=0; ii<taille; ii++)
633 {
634 mon_h(ii,0) = 1./(1./mon_h(ii,0)+1./h_correlation(correspondance_solide_fluide(ii)));
635 Text_valeurs(ii,0) = T(correspondance_solide_fluide(ii));
636 }
637
638 const Equation_base& mon_eqn = domaine_Cl_dis().equation();
639
640 if (limpr(temps,mon_eqn.schema_temps().pas_de_temps())) imprimer(temps);
641
643
644 // Operation de sauvegarde du champ de temperature dans le fluide en vue d'une reprise
645 if (nbproc>1)
646 {
647 envoyer(T,ME,0,ME); // J'envoie T au processeur maitre
648 if (je_suis_maitre())
649 {
650 Fichier_sauv=fopen(Fichier_sauv_nom,"w"); // J'ouvre le fichier de sauvegarde en ecriture
651 fprintf(Fichier_sauv,"Temps\t=\t%f\n",temps); // J'imprime le temps
652 int j=0;
653 for (int p=0; p<nbproc; p++) // Je boucle sur le nombre de processeur
654 {
655 DoubleVect T_tmp;
656 recevoir(T_tmp,p,0,p); // Je recupere les temperature de chaque processeur
657 for (int i=0; i<T_tmp.size(); i++)
658 {
659 fprintf(Fichier_sauv,"T(%i)\t=\t%f\n",(int)j,T_tmp(i)); // J'imprime les temperatures dans le fichier de sauvegarde
660 j=j+1;
661 }
662 }
663 fclose(Fichier_sauv);
664 }
665 }
666 else
667 {
668 Fichier_sauv=fopen(Fichier_sauv_nom,"w");
669 fprintf(Fichier_sauv,"Temps\t=\t%f\n",temps);
670 for (int i=0; i<N; i++)
671 {
672 fprintf(Fichier_sauv,"T(%i)\t=\t%f\n",(int)i,T(i));
673 }
674 fclose(Fichier_sauv);
675 }
676}
677
678void Echange_contact_Correlation_VDF::calculer_h_solide(DoubleTab& tab,const Equation_base& une_eqn,const Domaine_VDF& zvdf_2,const Front_VF& front_vf,const Milieu_base& le_milieu)
679{
680 DoubleVect e;
681 const IntTab& face_voisins = zvdf_2.face_voisins();
682 int i;
683 int nb_comp = le_milieu.conductivite().nb_comp();
684 int ndeb = front_vf.num_premiere_face();
685 int nfin = ndeb + front_vf.nb_faces();
686
687 e.resize(front_vf.nb_faces());
688
689 for (int face=ndeb; face<nfin; face++)
690 e(face-ndeb) = zvdf_2.dist_norm_bord(face);
691
692 // Calcul de tab = 1/(e/lambda + 1/h_paroi) =1/(e/lambda+invhparoi)
693 if(!sub_type(Champ_Uniforme,le_milieu.conductivite()))
694 {
695 //Cerr << "raccord local homogene et conductivite non uniforme" << finl;
696 const DoubleTab& tab_lambda = le_milieu.conductivite().valeurs();
697 for (int face=ndeb; face<nfin; face++)
698 {
699 int elem = face_voisins(face,0);
700 if (elem == -1)
701 elem = face_voisins(face,1);
702 for(i=0; i<nb_comp; i++)
703 {
704 assert(le_milieu.conductivite().valeurs()(elem,i)!=0.);
705 tab(face-ndeb,i) = tab_lambda(elem,i)/e(face-ndeb);
706 }
707 }
708 }
709 else // la conductivite est un OWN_PTR(Champ_base) uniforme
710 {
711 for (int face=ndeb; face<nfin; face++)
712 {
713 for(i=0; i<nb_comp; i++)
714 {
715 assert(le_milieu.conductivite().valeurs()(0,i)!=0.);
716 tab(face-ndeb,i) = le_milieu.conductivite().valeurs()(0,i)/e(face-ndeb);
717 }
718 }
719 }
720}
721
722
723/**
724 * Teste si l'impression est demandee
725 */
726int Echange_contact_Correlation_VDF::limpr(double temps_courant,double dt) const
727{
729 // Test un peu tordu, mais ca fonctionne !!!! (CM 05/07/2007)
730 if (dt_impr<=dt || ((sch.temps_max()<=temps_courant || sch.nb_pas_dt_max()<=(sch.nb_pas_dt()+1) || (temps_courant!=sch.temps_courant() && sch.nb_pas_dt()==0)) && dt_impr!=1e10))
731 return 1;
732 else
733 {
734 // Voir Schema_Temps_base::limpr pour information sur epsilon et modf
735 static const double epsilon = 1.e-9;
736 double i, j;
737 modf(temps_courant/dt_impr + epsilon, &i);
738 modf((temps_courant-dt)/dt_impr + epsilon, &j);
739 return ( i>j );
740 }
741}
742
743
744/**
745 * Imprime les resultats
746 */
748{
749 const int ME = Process::me();
750 const int nbproc = Process::nproc();
751
752 if (nbproc>1)
753 {
754 envoyer(coord,ME,0,ME);
755 envoyer(T,ME,0,ME);
756 envoyer(U,ME,0,ME);
757 envoyer(h_correlation,ME,0,ME);
758 envoyer(rho,ME,0,ME);
759 envoyer(mu,ME,0,ME);
760 envoyer(lambda,ME,0,ME);
761 envoyer(Qvol,ME,0,ME);
762 envoyer(vol,ME,0,ME);
763
764 if (je_suis_maitre())
765 {
766 Nom nom_bord=frontiere_dis().frontiere().le_nom();
767 nom_bord+="_";
768 nom_bord+=Nom(temps);
769 nom_bord+=".dat";
770 SFichier fic(nom_bord);
771 fic.precision(domaine_Cl_dis().equation().schema_temps().precision_impr());
772 fic.setf(ios::scientific);
773 double Qt=0.;
774 fic << "# X T U h rho mu lambda Q[W]" << finl;
775
776 for (int p=0; p<nbproc; p++)
777 {
778 DoubleVect coord_tmp;
779 DoubleVect T_tmp;
780 DoubleVect U_tmp;
781 DoubleVect h_tmp;
782 DoubleVect rho_tmp;
783 DoubleVect mu_tmp;
784 DoubleVect lambda_tmp;
785 DoubleVect Qvol_tmp;
786 DoubleVect vol_tmp;
787
788 recevoir(coord_tmp,p,0,p);
789 recevoir(T_tmp,p,0,p);
790 recevoir(U_tmp,p,0,p);
791 recevoir(h_tmp,p,0,p);
792 recevoir(rho_tmp,p,0,p);
793 recevoir(mu_tmp,p,0,p);
794 recevoir(lambda_tmp,p,0,p);
795 recevoir(Qvol_tmp,p,0,p);
796 recevoir(vol_tmp,p,0,p);
797
798 for (int i =0; i<coord_tmp.size(); i++)
799 {
800 fic << coord_tmp(i) << " \t" << T_tmp(i) << " \t" << U_tmp(i) << " \t" << h_tmp(i) << " \t" << rho_tmp(i);
801 fic << " \t" << mu_tmp(i) << " \t" << lambda_tmp(i) << " \t" << Qvol_tmp(i)*vol_tmp(i) << finl;
802 Qt+=Qvol_tmp(i)*vol_tmp(i);
803 }
804
805 }
806
807
808 fic << "# Q total[W] = " << Qt << finl;
809 fic << finl;
810 }
811 }
812 else
813 {
814 Nom nom_bord=frontiere_dis().frontiere().le_nom();
815 nom_bord+="_";
816 nom_bord+=Nom(temps);
817 nom_bord+=".dat";
818 SFichier fic(nom_bord);
819 fic.precision(domaine_Cl_dis().equation().schema_temps().precision_impr());
820 fic.setf(ios::scientific);
821 double Qt=0.;
822 fic << "# X T U h rho mu lambda Q[W]" << finl;
823 for (int i =0; i<N; i++)
824 {
825 fic << coord(i) << " \t" << T(i) << " \t" << U(i) << " \t" << h_correlation(i) << " \t" << rho(i);
826 fic << " \t" << mu(i) << " \t" << lambda(i) << " \t" << Qvol(i)*vol(i) << finl;
827 Qt+=Qvol(i)*vol(i);
828 }
829 fic << "# Q total[W] = " << Qt << finl;
830 fic << finl;
831
832 }
833}
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
Classe Champ_Inc_base.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
virtual DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ.
Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limites discretisee dont l'objet fait partie.
virtual void completer()
NE FAIT RIEN A surcharger dans les classes derivees.
std::vector< Motcle > app_domains
virtual Frontiere_dis_base & frontiere_dis()
Renvoie la frontiere discretisee a laquelle les conditions aux limites s'appliquent.
Joints_t & faces_joint()
Definition Domaine.h:265
class Domaine_VDF
Definition Domaine_VDF.h:64
double dist_norm_bord(int num_face) const override
virtual const DoubleVect & face_surfaces() const
Definition Domaine_VF.h:51
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
void set_param(Param &param) const override
virtual double volume(double s, double d)
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.
void calculer_h_solide(DoubleTab &, const Equation_base &, const Domaine_VDF &, const Front_VF &, const Milieu_base &)
Classe Echange_global_impose Cette classe represente le cas particulier de la classe.
void mettre_a_jour(double temps) override
Effectue une mise a jour en temps de la condition aux limites.
virtual Champ_front_base & T_ext()
Renvoie le champ T_ext de temperature imposee a la frontiere.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual const Milieu_base & milieu() const =0
virtual const Champ_Inc_base & inconnue() const =0
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
virtual void fixer_nb_comp(int i)
Fixe le nombre de composantes du champ.
virtual int nb_comp() const
Definition Field_base.h:56
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 Frontiere & frontiere() const
Renvoie la frontiere geometrique associee.
classe Milieu_base Cette classe est la base de la hierarchie des milieux (physiques)
Definition Milieu_base.h:50
virtual const Champ_Don_base & conductivite() const
Renvoie la conductivite du milieu.
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
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
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
Definition Param.cpp:474
void ajouter_condition(const char *condition, const char *message, const char *name=0)
Declare a post-read logical condition that must hold on the parameter values.
Definition Param.cpp:496
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
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
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
static bool is_parallel()
Definition Process.cpp:110
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
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
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
class Schema_Temps_base
double temps_courant() const
Renvoie le temps courant.
double temps_max() const
Renvoie une reference sur le temps maximum.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
int nb_pas_dt() const
Renvoie le nombre de pas de temps effectues.
int nb_pas_dt_max() const
Renvoie une reference sur le nombre de pas maxi.
static void resoudre(const DoubleVect &ma, const DoubleVect &mb, const DoubleVect &mc, const DoubleVect &sm, DoubleVect &vi, int M)
Definition Solv_TDMA.cpp:19
void precision(int pre) override
void setf(IOS_FORMAT code) override
Classe de base des flux de sortie.
Definition Sortie.h:52
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTVect.tpp:91