TrioCFD 1.9.9_beta
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)", "The direction must be 0, 1 or 2 in 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 // Added by 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 * @brief Computes the local heat exchange coefficient in the solid cell.
145 */
147{
148 // necessarily 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 * @brief Completes and initializes the class attributes.
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 //Update because there is no dependency on data from another problem
194 //in the case of coupled problems.
195 //The completer() method may need to be replaced by the initialiser() method.
197 const double temps = mon_eqn.schema_temps().temps_courant();
198 mettre_a_jour(temps);
199}
200
201/**
202 * @brief Initializes the tab_ech array for parallel execution.
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() To check for blocking send" << 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 * @brief Computes rho, mu and lambda of the fluid at the current temperature.
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 * @brief Computes the heat exchange coefficient using the correlation entered in the data file.
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 * @brief Computes the volumetric power source term in the 1D fluid energy equation.
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 // Sort faces by increasing coordinate (along the coordinate corresponding to the tube direction)
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 // Determine the number of 1D cells in the fictitious fluid
330 // and fill the solid-to-fluid element correspondence array
331 correspondance_solide_fluide.resize(nb_faces_bord);
332 N=3; // add the boundary nodes
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 // Compute slice volumes
354 DoubleVect surf(N);
355 surf=0.;
356 vol=0.;
357 surf(0) = surf(N-1) = 0.; // not used
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)); // the first mesh point
365 coord(N-1) = coord(N-2)+0.5*(coord(N-2)-coord(N-3)); // the last mesh point
366 for (i=1; i<N-1; i++)
367 {
368 vol(i)=volume(surf(i),diam);
369 }
370 vol(0) = vol(N-1) = 1.; // not used, but avoids a division by zero in the Qvol computation.
371}
372
373
374
375/**
376 * @brief Computes the volume of a slice with lateral surface area s and hydraulic diameter d.
377 * @param s Lateral surface area of the slice.
378 * @param d Hydraulic diameter.
379 * @return Volume of the slice.
380 */
382{
383 fct_vol.setVar("Dh",d);
384 fct_vol.setVar("S",s);
385
386 return fct_vol.eval();
387}
388
389
390/**
391 * @brief Computes the boundary conditions to apply to the energy equation.
392 */
394{
395 const int ME=Process::me();
396
397 const Joints& joints = domaine_Cl_dis().domaine().faces_joint();
398 const int nb_voisins = joints.size();
399
400 DoubleVect les_cl_envoyees(2);
401 DoubleVect les_cl_recues(2);
402 les_cl_envoyees(0) = T(1);
403 les_cl_envoyees(1) = T(N-2);
404
405 T_CL0=Tinf;
406 T_CL1=Tsup;
407 for (int i=0; i<nb_voisins; i++)
408 {
409 int mon_voisin = joints[i].PEvoisin();
410
411 Cerr << " Echange_contact_Correlation_VDF::calculer_CL() To check for blocking send" << finl;
412 exit();
413 envoyer(les_cl_envoyees,ME,mon_voisin,ME);
414
415 recevoir(les_cl_recues,mon_voisin,ME,mon_voisin);
416 if (tab_ech(mon_voisin,ME) == 1)
417 {
418 T_CL0 = 0.5*(les_cl_recues(1)+T(1));
419 T(0) = T_CL0;
420 }
421 else if (tab_ech(mon_voisin,ME) == 0)
422 {
423 T_CL1 = 0.5*(les_cl_recues(0)+T(N-2));
424 T(N-1) = T_CL1;
425 }
426 else
427 {
428 Cerr << "Communication error between processors " <<ME<< " and " <<mon_voisin << finl;
429 Cerr << "in Echange_contact_Correlation_VDF::calculer_CL" << finl;
430 if (Process::is_parallel()) Cerr << "Verify that your partition is in slices along the axis of the 1D model." << finl;
431 exit();
432
433 }
434 }
435}
436
437
438/**
439 * @brief Computes the velocity from mass conservation.
440 */
442{
443 for (int i=0; i<N; i++)
444 U(i) = debit/rho(i);
445}
446
447
448/**
449 * @brief Computes the 1D temperature in the fluid by solving energy conservation.
450 */
452{
453 const Equation_base& mon_eqn = domaine_Cl_dis().equation();
454 const double dt = mon_eqn.schema_temps().pas_de_temps();
455 DoubleVect ma(N); // diagonal
456 DoubleVect mb(N-1); // sub-diagonal
457 DoubleVect mc(N-1); // super-diagonal
458 DoubleVect sm(N);
459 const int sgn = (debit>0) ? 1 : -1; // upwind scheme for transport
460
461
462 ma(0) = 1.;
463 ma(N-1) = 1.;
464 sm(0) = T_CL0;
465 sm(N-1) = T_CL1;
466 mc(0) = 0.;
467 mb(N-2) = 0.;
468 int i;
469 for (i=1; i<N-1; i++)
470 {
471 const double dtrhoCp = dt/rho(i)/Cp;
472 const double dz1 = coord(i+1)-coord(i);
473 const double dz2 = coord(i)-coord(i-1);
474 const double l1 = 0.5*(lambda(i+1)+lambda(i));
475 const double l2 = 0.5*(lambda(i)+lambda(i-1));
476
477 ma(i)=1+dtrhoCp*(sgn*Cp*debit/dz1+2*(l1/dz1+l2/dz2)/(dz1+dz2));
478
479 sm(i) = T(i)+dtrhoCp*Qvol(i);
480
481 mc(i) = dtrhoCp*(0.5*(1-sgn)*Cp*debit/dz1-2*l1/dz1/(dz1+dz2));
482
483 mb(i-1) = dtrhoCp*(-2*l2/dz2/(dz1+dz2));
484 mb(i-1) += dtrhoCp*(-0.5*(1+sgn)*Cp*debit/dz1);
485 }
486
487
488
489
490 DoubleVect xx(N);
491 xx=0.;
492 Solv_TDMA::resoudre(ma,mb,mc,sm,xx,N);
493 for (i=0; i<N; i++)
494 T(i) = xx(i);
495}
496
497
498
499
500/**
501 * @brief Updates the velocity, fluid temperature and heat exchange coefficient.
502 */
504{
505
506 // Name of the backup files
507 Nom Fichier_sauv_nom=domaine_Cl_dis().equation().probleme().le_nom();
508 Fichier_sauv_nom+="_";
509 Fichier_sauv_nom+=frontiere_dis().frontiere().le_nom();
510 Fichier_sauv_nom+=".sauv";
511
512 // Resume operation for the fluid temperature field
513 const int ME = Process::me();
514 const int nbproc = Process::nproc();
515 FILE *Fichier_sauv;
517 {
518 if (nbproc>1)
519 {
520 Cerr << "To check for blocking send" << finl;
521 exit();
522 envoyer(T,ME,0,ME); // send T to know its array dimension
523 if (je_suis_maitre())
524 {
525 double temps_lu=0., Temperature_reprise=0.;
526 char tmp_lu;
527 //int code;
528 Fichier_sauv=fopen(Fichier_sauv_nom,"r"); // open the backup file in read-only mode
529 if (Fichier_sauv!=nullptr)
530 {
531 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // read the first word "Temps" (discarded)
532 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // read the second word "=" (discarded)
533 if (!fscanf(Fichier_sauv,"%lf",&temps_lu)) exit(); // read the time and store it in temps_lu
534 if (temps_lu==temps)
535 {
536 for (int p=0; p<nbproc; p++) // loop over the number of processors
537 {
538 Cerr << "Resuming temperature field (" << Fichier_sauv_nom << ") for the correlation on processor " << p << "...";
539 DoubleVect T_tmp;
540 recevoir(T_tmp,p,0,p); // retrieve T to know its array dimension at the master processor level
541 for (int i=0; i<T_tmp.size(); i++) // loop over the number of temperatures to define
542 {
543 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // read the word "T(i)" (discarded)
544 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // read the word "=" (discarded)
545 if (!fscanf(Fichier_sauv,"%lf",&Temperature_reprise)) exit();// read the temperature value and store it in Temperature_reprise
546 T_tmp(i) = Temperature_reprise; // assign the computation variable T(i) to Temperature_reprise
547 }
548 envoyer(T_tmp,0,p,0); // send T_tmp to all processors
549 Cerr << " OK!" << finl;
550 }
551 fclose(Fichier_sauv);
552 }
553 else
554 {
555 Cerr << "\nThe time indicated in the file \""<< Fichier_sauv_nom << "\" "<< temps_lu << finl;
556 Cerr << "differs from the restart time of the computation "<< temps << " !!!" << finl << finl;
557 Cerr << "You cannot resume with this correlation. Remove" << finl;
558 Cerr << "the keyword \"Reprise\" from the correlation. The transient phase" << finl;
559 Cerr << "of the computation will be wrong, but the steady state will be correct." << finl << finl;
560 fclose(Fichier_sauv);
561 exit();
562 }
563 }
564 else
565 {
566 Cerr << "\nThe resume cannot be performed: the file \"" << Fichier_sauv_nom << "\" is missing !!!" << finl << finl;
567 exit();
568 }
569 }
570 recevoir(T,0,ME,0); // retrieve T=T_tmp at each processor level
571 }
572 else
573 {
574 Fichier_sauv=fopen(Fichier_sauv_nom,"r");
575 double temps_lu=0., Temperature_reprise=0.;
576 char tmp_lu;
577
578 if (Fichier_sauv!=nullptr)
579 {
580 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // read the first word "Temps" (discarded)
581 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // read the second word "=" (discarded)
582 if (!fscanf(Fichier_sauv,"%lf",&temps_lu)) exit(); // read the time and store it in temps_lu
583 if (temps_lu==temps)
584 {
585 Cerr << "Resuming temperature field (" << Fichier_sauv_nom << ") for the correlation...";
586 for (int i=0; i<N; i++)
587 {
588 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // read the word "T(i)" (discarded)
589 if (!fscanf(Fichier_sauv,"%s",&tmp_lu)) exit(); // read the word "=" (discarded)
590 if (!fscanf(Fichier_sauv,"%lf",&Temperature_reprise)) exit();// read the temperature value and store it in Temperature_reprise
591 T(i) = Temperature_reprise; // assign the computation variable T(i) to Temperature_reprise
592 }
593 fclose(Fichier_sauv);
594 Cerr << " OK!" << finl;
595 }
596 else
597 {
598 Cerr << "\nThe time indicated in the file \""<< Fichier_sauv_nom << "\" "<< temps_lu << finl;
599 Cerr << "differs from the restart time of the computation "<< temps << " !!!" << finl << finl;
600 Cerr << "You cannot resume with this correlation. Remove" << finl;
601 Cerr << "the keyword \"Reprise\" from the correlation. The transient phase" << finl;
602 Cerr << "of the computation will be wrong, but the steady state will be correct." << finl << finl;
603 fclose(Fichier_sauv);
604 exit();
605 }
606 }
607 else
608 {
609 Cerr << "\nThe resume cannot be performed: the file \"" << Fichier_sauv_nom << "\" is missing !!!" << finl << finl;
610 exit();
611 }
612 }
614 }
615
616 calculer_CL();
618 calculer_Q();
621
622
623
624 for (int i=0; i<N; i++)
626
627
628
629
630 DoubleTab& mon_h= h_imp_->valeurs();
631 calculer_h_mon_pb(mon_h);
632 const int taille=mon_h.dimension(0);
633 DoubleTab& Text_valeurs = T_ext().valeurs();
634
635 for (int ii=0; ii<taille; ii++)
636 {
637 mon_h(ii,0) = 1./(1./mon_h(ii,0)+1./h_correlation(correspondance_solide_fluide(ii)));
638 Text_valeurs(ii,0) = T(correspondance_solide_fluide(ii));
639 }
640
641 const Equation_base& mon_eqn = domaine_Cl_dis().equation();
642
643 if (limpr(temps,mon_eqn.schema_temps().pas_de_temps())) imprimer(temps);
644
646
647 // Save operation for the fluid temperature field for a future restart
648 if (nbproc>1)
649 {
650 envoyer(T,ME,0,ME); // send T to the master processor
651 if (je_suis_maitre())
652 {
653 Fichier_sauv=fopen(Fichier_sauv_nom,"w"); // open the backup file in write mode
654 fprintf(Fichier_sauv,"Temps\t=\t%f\n",temps); // print the time
655 int j=0;
656 for (int p=0; p<nbproc; p++) // loop over the number of processors
657 {
658 DoubleVect T_tmp;
659 recevoir(T_tmp,p,0,p); // retrieve temperatures from each processor
660 for (int i=0; i<T_tmp.size(); i++)
661 {
662 fprintf(Fichier_sauv,"T(%i)\t=\t%f\n",(int)j,T_tmp(i)); // print the temperatures in the backup file
663 j=j+1;
664 }
665 }
666 fclose(Fichier_sauv);
667 }
668 }
669 else
670 {
671 Fichier_sauv=fopen(Fichier_sauv_nom,"w");
672 fprintf(Fichier_sauv,"Temps\t=\t%f\n",temps);
673 for (int i=0; i<N; i++)
674 {
675 fprintf(Fichier_sauv,"T(%i)\t=\t%f\n",(int)i,T(i));
676 }
677 fclose(Fichier_sauv);
678 }
679}
680
681void 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)
682{
683 DoubleVect e;
684 const IntTab& face_voisins = zvdf_2.face_voisins();
685 int i;
686 int nb_comp = le_milieu.conductivite().nb_comp();
687 int ndeb = front_vf.num_premiere_face();
688 int nfin = ndeb + front_vf.nb_faces();
689
690 e.resize(front_vf.nb_faces());
691
692 for (int face=ndeb; face<nfin; face++)
693 e(face-ndeb) = zvdf_2.dist_norm_bord(face);
694
695 // Compute tab = 1/(e/lambda + 1/h_paroi) =1/(e/lambda+invhparoi)
696 if(!sub_type(Champ_Uniforme,le_milieu.conductivite()))
697 {
698 //Cerr << "raccord local homogene et conductivite non uniforme" << finl;
699 const DoubleTab& tab_lambda = le_milieu.conductivite().valeurs();
700 for (int face=ndeb; face<nfin; face++)
701 {
702 int elem = face_voisins(face,0);
703 if (elem == -1)
704 elem = face_voisins(face,1);
705 for(i=0; i<nb_comp; i++)
706 {
707 assert(le_milieu.conductivite().valeurs()(elem,i)!=0.);
708 tab(face-ndeb,i) = tab_lambda(elem,i)/e(face-ndeb);
709 }
710 }
711 }
712 else // the conductivity is a uniform OWN_PTR(Champ_base)
713 {
714 for (int face=ndeb; face<nfin; face++)
715 {
716 for(i=0; i<nb_comp; i++)
717 {
718 assert(le_milieu.conductivite().valeurs()(0,i)!=0.);
719 tab(face-ndeb,i) = le_milieu.conductivite().valeurs()(0,i)/e(face-ndeb);
720 }
721 }
722 }
723}
724
725
726/**
727 * @brief Tests whether printing is requested.
728 */
729int Echange_contact_Correlation_VDF::limpr(double temps_courant,double dt) const
730{
732 // Slightly convoluted test, but it works !!!! (CM 05/07/2007)
733 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))
734 return 1;
735 else
736 {
737 // See Schema_Temps_base::limpr for information on epsilon and modf
738 static const double epsilon = 1.e-9;
739 double i, j;
740 modf(temps_courant/dt_impr + epsilon, &i);
741 modf((temps_courant-dt)/dt_impr + epsilon, &j);
742 return ( i>j );
743 }
744}
745
746
747/**
748 * @brief Prints the results.
749 */
751{
752 const int ME = Process::me();
753 const int nbproc = Process::nproc();
754
755 if (nbproc>1)
756 {
757 envoyer(coord,ME,0,ME);
758 envoyer(T,ME,0,ME);
759 envoyer(U,ME,0,ME);
760 envoyer(h_correlation,ME,0,ME);
761 envoyer(rho,ME,0,ME);
762 envoyer(mu,ME,0,ME);
763 envoyer(lambda,ME,0,ME);
764 envoyer(Qvol,ME,0,ME);
765 envoyer(vol,ME,0,ME);
766
767 if (je_suis_maitre())
768 {
769 Nom nom_bord=frontiere_dis().frontiere().le_nom();
770 nom_bord+="_";
771 nom_bord+=Nom(temps);
772 nom_bord+=".dat";
773 SFichier fic(nom_bord);
774 fic.precision(domaine_Cl_dis().equation().schema_temps().precision_impr());
775 fic.setf(ios::scientific);
776 double Qt=0.;
777 fic << "# X T U h rho mu lambda Q[W]" << finl;
778
779 for (int p=0; p<nbproc; p++)
780 {
781 DoubleVect coord_tmp;
782 DoubleVect T_tmp;
783 DoubleVect U_tmp;
784 DoubleVect h_tmp;
785 DoubleVect rho_tmp;
786 DoubleVect mu_tmp;
787 DoubleVect lambda_tmp;
788 DoubleVect Qvol_tmp;
789 DoubleVect vol_tmp;
790
791 recevoir(coord_tmp,p,0,p);
792 recevoir(T_tmp,p,0,p);
793 recevoir(U_tmp,p,0,p);
794 recevoir(h_tmp,p,0,p);
795 recevoir(rho_tmp,p,0,p);
796 recevoir(mu_tmp,p,0,p);
797 recevoir(lambda_tmp,p,0,p);
798 recevoir(Qvol_tmp,p,0,p);
799 recevoir(vol_tmp,p,0,p);
800
801 for (int i =0; i<coord_tmp.size(); i++)
802 {
803 fic << coord_tmp(i) << " \t" << T_tmp(i) << " \t" << U_tmp(i) << " \t" << h_tmp(i) << " \t" << rho_tmp(i);
804 fic << " \t" << mu_tmp(i) << " \t" << lambda_tmp(i) << " \t" << Qvol_tmp(i)*vol_tmp(i) << finl;
805 Qt+=Qvol_tmp(i)*vol_tmp(i);
806 }
807
808 }
809
810
811 fic << "# Q total[W] = " << Qt << finl;
812 fic << finl;
813 }
814 }
815 else
816 {
817 Nom nom_bord=frontiere_dis().frontiere().le_nom();
818 nom_bord+="_";
819 nom_bord+=Nom(temps);
820 nom_bord+=".dat";
821 SFichier fic(nom_bord);
822 fic.precision(domaine_Cl_dis().equation().schema_temps().precision_impr());
823 fic.setf(ios::scientific);
824 double Qt=0.;
825 fic << "# X T U h rho mu lambda Q[W]" << finl;
826 for (int i =0; i<N; i++)
827 {
828 fic << coord(i) << " \t" << T(i) << " \t" << U(i) << " \t" << h_correlation(i) << " \t" << rho(i);
829 fic << " \t" << mu(i) << " \t" << lambda(i) << " \t" << Qvol(i)*vol(i) << finl;
830 Qt+=Qvol(i)*vol(i);
831 }
832 fic << "# Q total[W] = " << Qt << finl;
833 fic << finl;
834
835 }
836}
DoubleTab & valeurs() override
Overrides Champ_base::valeurs() Returns the array of values.
Class Champ_Inc_base.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
Champ_Uniforme Represents a field that is constant in space and time.
virtual DoubleTab & valeurs() override
Returns the array of field values.
Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the domain of discretized boundary conditions to which the object belongs.
virtual void completer()
DOES NOTHING must be overridden in derived classes.
std::vector< Motcle > app_domains
virtual Frontiere_dis_base & frontiere_dis()
Returns the discretized boundary to which the boundary conditions apply.
Joints_t & faces_joint()
Definition Domaine.h:265
class Domaine_VDF
Definition Domaine_VDF.h:61
double dist_norm_bord(int num_face) const override
Returns the normal distance for a boundary face (Cartesian coordinates).
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
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
void calculer_Q()
Computes the volumetric power source term in the 1D fluid energy equation.
void calculer_CL()
Computes the boundary conditions to apply to the energy equation.
void set_param(Param &param) const override
void calculer_h_mon_pb(DoubleTab &)
Computes the local heat exchange coefficient in the solid cell.
virtual double volume(double s, double d)
Computes the volume of a slice with lateral surface area s and hydraulic diameter d.
void init_tab_echange()
Initializes the tab_ech array for parallel execution.
virtual double calculer_coefficient_echange(int i)
Computes the heat exchange coefficient using the correlation entered in the data file.
void calculer_prop_physique()
Computes rho, mu and lambda of the fluid at the current temperature.
void calculer_Vitesse()
Computes the velocity from mass conservation.
void mettre_a_jour(double) override
Updates the velocity, fluid temperature and heat exchange coefficient.
void completer() override
Completes and initializes the class attributes.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
void calculer_h_solide(DoubleTab &, const Equation_base &, const Domaine_VDF &, const Front_VF &, const Milieu_base &)
virtual void imprimer(double) const
Prints the results.
virtual int limpr(double, double) const
Tests whether printing is requested.
void calculer_Tfluide()
Computes the 1D temperature in the fluid by solving energy conservation.
Classe Echange_global_impose This class represents the special case of the class.
void mettre_a_jour(double temps) override
Performs a time update of the boundary condition.
virtual Champ_front_base & T_ext()
Returns the T_ext field of temperature imposed at the boundary.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Equation_base The role of an equation is the calculation of one or more fields....
virtual const Milieu_base & milieu() const =0
virtual const Champ_Inc_base & inconnue() const =0
Probleme_base & probleme()
Returns the problem associated with the equation.
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
virtual void fixer_nb_comp(int i)
Sets the number of components of the field.
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
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Frontiere.h:49
const Frontiere & frontiere() const
Returns the associated geometric boundary.
Milieu_base This class is the base of the (physical) medium hierarchy.
Definition Milieu_base.h:50
virtual const Champ_Don_base & conductivite() const
Returns the conductivity of the medium (const version).
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
A character string (Nom) in uppercase.
Definition Motcle.h:26
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
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
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
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Probleme_U.h:109
static bool is_parallel()
Definition Process.cpp:108
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 int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
Definition Process.cpp:122
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
Definition SFichier.h:29
class Schema_Temps_base
double temps_courant() const
Returns the current time.
double temps_max() const
Returns a reference to the maximum time.
double pas_de_temps() const
Returns the current time step (delta_t).
int nb_pas_dt() const
Returns the number of time steps performed.
int nb_pas_dt_max() const
Returns a reference to the maximum number of time steps.
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
Base class for output streams.
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