TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Champ_Inc_base.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 <EcritureLectureSpecial.h>
17#include <Scalaire_impose_paroi.h>
18#include <Domaine_Cl_dis_base.h>
19#include <Schema_Temps_base.h>
20#include <Champ_Inc_P0_base.h>
21#include <Champ_Inc_P1_base.h>
22#include <Neumann_val_ext.h>
23#include <MD_Vector_tools.h>
24#include <Champ_Inc_base.h>
25#include <Equation_base.h>
26#include <Probleme_base.h>
27#include <TRUST_2_PDI.h>
28#include <Domaine_VF.h>
29#include <YAML_data.h>
30#include <Dirichlet.h>
31#include <Domaine.h>
32
33Implemente_base_sans_constructeur(Champ_Inc_base,"Champ_Inc_base",Champ_base);
34
37
38/*! @brief Fixe le nombre de valeurs temporelles a conserver.
39 *
40 * (un nombre different suivant le schema en temps utilise)
41 * Appelle Roue::fixer_nb_cases(int)
42 *
43 * @param (int i) le nombre de valeurs temporelles a conserver
44 * @return (int) le nombre de valeurs temporelles a conserver
45 */
47{
48 return les_valeurs->fixer_nb_cases(i);
49}
50
51/*! @brief Renvoie le nombre de valeurs temporelles actuellement conservees.
52 *
53 * Cette valeur est stockee par la Roue du Champ_Inc_base
54 *
55 * @return (int) le nombre de valeurs temporelles actuellement conservees
56 */
58{
59 return les_valeurs->nb_cases();
60}
61
62/*! @brief Lit les valeurs du champs a partir d'un flot d'entree.
63 *
64 * Format de lecture:
65 * int [LE NOMBRE DE VALEURS A LIRE]
66 * [LIRE LE NOMBRE DE VALEUR VOULUES]
67 *
68 * @param (Entree& is) le flot d'entree
69 * @return (int) renvoie 1 si la lecture est correcte
70 * @throws le nombre de valeur a lire est incorrect
71 */
73{
74 int n;
75 is >> n;
76 if (n != les_valeurs->valeurs().size())
77 {
78 Cerr << " the file does not contain the correct number of values to fill the field" << finl;
80 }
81 DoubleVect& tab = les_valeurs->valeurs();
82 for (int i = 0; i < n; i++)
83 is >> tab[i];
84 return 1;
85}
86
88{
89 Cerr << "Internal error in Champ_Inc_base::fixer_nb_valeurs_nodales: method has not been implemented for class " << que_suis_je() << finl;
91 return nb_noeuds;
92}
93
94void Champ_Inc_base::creer_tableau_distribue(const MD_Vector& md, RESIZE_OPTIONS opt)
95{
96 const int n = nb_valeurs_temporelles();
97 for (int i = 0; i < n; i++)
98 {
99 DoubleTab& tab = futur(i);
100 // Note B.M: Ce test n'est pas symetrique avec Champ_Fonc_base => incoherence de nb_dim
101 // pour les champs "multiscalaires" a une composante.
102 if (tab.size_array() == 0 && (!tab.get_md_vector()))
103 {
104 // Note B.M.: les methodes fixer_nb_valeurs_nodales sont appelees a tort et a travers.
105 // Ne rien faire si le tableau a deja la bonne structure
106 tab.resize(0, nb_compo_);
107 }
108 if (!(tab.get_md_vector() == md))
109 {
110 if (tab.get_md_vector())
111 {
112 Cerr << "Internal error in Champ_Inc_base::creer_tableau_distribue:\n" << " array has alreary a (wrong) parallel descriptor" << finl;
114 }
116 }
117 }
118}
119
120/*! @brief Returns the number of "real" geometric positions of the degrees of freedom, or -1 if not applicable (fields with multiple localisations)
121 *
122 */
124{
125 int n;
126 const DoubleTab& v = valeurs();
127 if (v.size_reelle_ok())
128 n = v.dimension(0);
129 else
130 n = -1;
131 return n;
132}
133
134/*! @brief Renvoie les valeurs du champs a l'instant temps.
135 *
136 * @param (double temps) le temps auquel on veut les valeurs du champ
137 * @return (DoubleTab&) les valeurs du champs a l'instant temps
138 */
139// WEC : Attention dans le cas de Pb_Couple on utilisait le fait que cette fonction renvoyait le present quand elle ne trouvait
140// pas un temps superieur a tous les temps disponibles!!!
141// Le comportement est maintenant plus explicite : un WARNING est affiche des que le present est renvoye a la place du temps demande.
142DoubleTab& Champ_Inc_base::valeurs(double tps)
143{
144 if (temps() == tps)
145 return valeurs();
146 else
147 {
148 Roue& la_roue = les_valeurs.valeur();
149 if (temps() < tps)
150 {
151 for (int i = 0; i < nb_valeurs_temporelles(); i++)
152 {
153 if (la_roue.futur(i).temps() == tps)
154 return la_roue.futur(i).valeurs();
155 else if (la_roue.futur(i).temps() < temps())
156 break;
157 }
158 }
159 else if (temps() > tps)
160 {
161 for (int i = 0; i < nb_valeurs_temporelles(); i++)
162 {
163 if (la_roue.passe(i).temps() == tps)
164 return la_roue.passe(i).valeurs();
165 else if (la_roue.passe(i).temps() > temps())
166 break;
167 }
168 }
169 }
170 Cerr << "ERROR : in Champ_Inc_base::valeurs(double), time " << tps << " not found, returns the present?" << finl;
171 Cerr << "Contact TRUST support." << finl;
173 return valeurs();
174}
175
176/*! @brief Renvoie les valeurs du champs a l'instant temps.
177 *
178 * @param (double temps) le temps auquel on veut les valeurs du champ
179 * @return (DoubleTab&) les valeurs du champs a l'instant temps
180 */
181const DoubleTab& Champ_Inc_base::valeurs(double tps) const
182// See above !
183{
184 if (temps() == tps)
185 return valeurs();
186 else
187 {
188 const Roue& la_roue = les_valeurs.valeur();
189
190 if (temps() < tps)
191 {
192 // Futur ?
193 for (int i = 0; i < nb_valeurs_temporelles(); i++)
194 {
195 if (la_roue.futur(i).temps() == tps)
196 return la_roue.futur(i).valeurs();
197 else if (la_roue.futur(i).temps() < temps())
198 break;
199 }
200 }
201 else if (temps() > tps)
202 {
203 // Passe ?
204 for (int i = 1; i < nb_valeurs_temporelles(); i++)
205 {
206 if (la_roue.passe(i).temps() == tps)
207 return la_roue.passe(i).valeurs();
208 else if (la_roue.passe(i).temps() > temps())
209 break;
210 }
211 }
212 }
213 Cerr << "ERROR : in Champ_Inc_base::valeurs(double), time " << tps << " not found, returns the present?" << finl;
214 Cerr << "Contact TRUST support." << finl;
216 return valeurs();
217}
218
219/*! @brief Avance le pointeur courant de i pas de temps, dans la liste des valeurs temporelles conservees.
220 *
221 * @param (int i) le nombre de pas de temps dont on avance
222 * @return (Champ_Inc_base&) renvoie *this, le champ au pas de temps voulu
223 */
225{
226 while (i--)
227 les_valeurs->avancer(les_valeurs);
228 temps_ = les_valeurs->temps();
229 return *this;
230}
231
232/*! @brief Recule le pointeur courant de i pas de temps, dans la liste des valeurs temporelles conservees.
233 *
234 * @param (int i) le nombre de pas de temps dont on recule
235 * @return (Champ_Inc_base&) renvoie *this, le champ au pas de temps voulu
236 */
238{
239 while (i--)
240 les_valeurs->reculer(les_valeurs);
241 temps_ = les_valeurs->temps();
242 return *this;
243}
244
245/*! @brief Effectue une mise a jour en temps du champ inconnue.
246 *
247 * WEC : Maintenant si on l'appelle 2 fois de suite avec le meme
248 * argument, la 2eme ne fait rien.
249 *
250 * @param (double temps) le nouveau temps
251 */
252void Champ_Inc_base::mettre_a_jour(double un_temps)
253{
254 // Champ a plusieurs valeurs temporelle :
255 // On avance a la bonne valeur temporelle.
256 if (les_valeurs->nb_cases() > 1)
257 {
258 for (int i = 0; i < les_valeurs->nb_cases(); i++)
259 {
260 if (les_valeurs[i].temps() == un_temps)
261 {
262 avancer(i);
263 temps_ = un_temps;
264 //Inutile:
265 //valeurs().echange_espace_virtuel();
266 if (fonc_calc_)
268 /* premier calcul d'un Champ_Fonc_Calc -> on copie les valeurs calculees dans toutes les cases */
270 for (int j = 1; j < les_valeurs->nb_cases(); j++, fonc_calc_init_ = 1)
271 les_valeurs[j].valeurs() = valeurs();
272 return;
273 }
274 }
275 Cerr << "In Champ_Inc_base::mettre_a_jour(double), " << finl;
276 Cerr << "time " << un_temps << " not found in field " << le_nom() << finl;
277 Cerr << "The times available are :" << finl;
278 for (int i = 0; i < les_valeurs->nb_cases(); i++)
279 Cerr << " " << les_valeurs[i].temps() << finl;
281 }
282 // Champ a une seule valeur temporelle :
283 // On change le temps associe.
284 else
285 {
286 changer_temps(un_temps);
287 if (fonc_calc_)
289 //Inutile:
290 //valeurs().echange_espace_virtuel();
291 }
292}
293
294/*! @brief Fixe le temps du ieme champ futur.
295 *
296 * @param (double t, int i) le nouveau temps
297 * @return (double) le nouveau temps
298 */
300{
301 Roue& la_roue = les_valeurs.valeur();
302 la_roue.futur(i).changer_temps(t);
303 return t;
304}
305
306/*! @brief Fixe le temps du ieme champ passe.
307 *
308 * @param (double t, int i) le nouveau temps
309 * @return (double) le nouveau temps
310 */
312{
313 Roue& la_roue = les_valeurs.valeur();
314 la_roue.passe(i).changer_temps(t);
315 return t;
316}
317
318/*! @brief Retourne le temps du ieme champ futur.
319 *
320 * @param (int i) le temps
321 * @return (double) le temps
322 */
324{
325 const Roue& la_roue = les_valeurs.valeur();
326 return la_roue.futur(i).temps();
327}
328
329/*! @brief Retourne le temps du ieme champ passe.
330 *
331 * @param (int i) le temps
332 * @return (double) le temps
333 */
335{
336 const Roue& la_roue = les_valeurs.valeur();
337 return la_roue.passe(i).temps();
338}
339/*! @brief for PDI IO: retrieve the name of the HDF5 dataset in which the field will be saved or be restored from
340 */
342{
343 Nom name = PDI_dname_;
344 if(name == "??")
345 {
347 name = equation().probleme().le_nom() + "_" + le_nom();
348 else
349 {
350 // Sometimes (with Champ_fonc_reprise), the equation has not been associated yet so we can't prefix the name of the dataset with the name of the problem
351 Cerr << "Champ_Inc_base::get_PDI_dname equation has not been associated yet. Please set the dataset name with Champ_Inc_base::set_PDI_dname()." << finl;
353 }
354 }
355 return (Motcle)name;
356}
357
358/*! @brief for PDI IO: retrieve name, type and dimensions of the field to save/restore.
359 */
360std::vector<YAML_data> Champ_Inc_base::data_a_sauvegarder() const
361{
362 const Nom& name = get_PDI_dname();
363 int nb_dim = valeurs().nb_dim();
364 YAML_data d(name.getString(), "double", nb_dim);
366 std::vector<YAML_data> data;
367 data.push_back(d);
368 return data;
369}
370
371/*! @brief Sauvegarde le champ inconnue sur un flot de sortie.
372 *
373 * Ecrit un identifiant, les valeurs du champs, et la date (le temps au moment de la sauvegarde).
374 *
375 * @param (Sortie& fich) un flot de sortie
376 * @return (int) returns the size of array
377 */
379{
380 // en mode ecriture special seul le maitre ecrit l'entete
381 int a_faire, special;
383
384 if (a_faire)
385 {
386 Nom mon_ident(nom_);
387 mon_ident += que_suis_je();
388 mon_ident += equation().probleme().domaine().le_nom();
389 mon_ident += Nom(temps_, "%e");
390 fich << mon_ident << finl;
391 fich << que_suis_je() << finl;
392 fich << temps_ << finl;
393 }
394 int bytes = 0;
395 if (special)
396 bytes = EcritureLectureSpecial::ecriture_special(*this, fich);
398 {
399 bytes = 8 * valeurs().size_array();
400
401 // Sharing the dimensions of the unknown field with PDI
402 TRUST_2_PDI pdi_interface;
403 const Nom& name = get_PDI_dname();
404 pdi_interface.share_TRUSTTab_dimensions(valeurs(), name, 1 /*write mode*/);
405
407 pdi_interface.share_type(name, que_suis_je());
408
409 // Sharing the unknown field with PDI
410 if( valeurs().dimension_tot(0) )
411 pdi_interface.TRUST_start_sharing(name.getString(), valeurs().addr());
412 else
413 {
414 // if the dimension is null in a direction - might happen in parallel - sharing an empty array
415 ArrOfDouble garbage( valeurs().nb_dim() );
416 pdi_interface.TRUST_start_sharing(name.getString(), garbage.addr());
417 }
418 }
419 else
420 {
421 bytes = 8 * valeurs().size_array();
422 valeurs().ecrit(fich);
423 }
424
425 if (a_faire)
426 {
427 // fich << flush ; Ne flushe pas en binaire !
428 fich.flush();
429 }
430 Cerr << "Backup of the field " << nom_ << " performed on time : " << Nom(temps_, "%e") << finl;
431 if (!est_egal(temps_, equation().probleme().schema_temps().temps_courant()))
432 {
433 Cerr.precision(12);
434 Cerr << "Problem in Champ_Inc_base::sauvegarder, temps_=" << temps_ << " temps_courant()=" << equation().probleme().schema_temps().temps_courant() << finl;
436 }
437 // Return the number of bytes written
438 return bytes;
439}
440
441/*! @brief Lecture d'un champ inconnue a partir d'un flot d'entree en vue d'une reprise.
442 *
443 * @param (Entree& fich) un flot d'entree
444 * @return (int) renvoie toujours 1
445 */
447{
448 double un_temps;
450 if (nom_ != Nom("anonyme")) // lecture pour reprise
451 {
452 Cerr << "Resume of the field " << nom_ << finl;
454 {
455 TRUST_2_PDI pdi_interface;
456 const Nom& name = get_PDI_dname();
457 pdi_interface.share_TRUSTTab_dimensions(valeurs(), name, 0 /*read mode*/);
458 if( valeurs().dimension_tot(0) )
459 pdi_interface.read(name.getChar(), valeurs().addr());
460 else
461 {
462 ArrOfDouble garbage( valeurs().nb_dim() );
463 pdi_interface.read(name.getChar(), garbage.addr());
464 }
465 }
466 else
467 {
468 int nb_val_nodales_old = nb_valeurs_nodales();
469 fich >> un_temps;
470 if (special)
472 else
473 valeurs().lit(fich);
474
475 if (nb_val_nodales_old != nb_valeurs_nodales())
476 {
477 Cerr << finl << "Problem in the resumption " << finl;
478 Cerr << "The field wich is read, does not have same number of nodal values" << finl;
479 Cerr << "that the field created by the discretization " << finl;
481 }
482 }
483 Cerr << " performed." << finl;
484 }
485 else // lecture pour sauter le bloc
486 {
488 {
489 Cerr << finl << "Problem in the resumption " << finl;
490 Cerr << "PDI format does not require to navigate through file..." << finl;
492 }
493 BigDoubleTab tempo;
494 fich >> un_temps;
495 tempo.jump(fich);
496 }
497 return 1;
498}
499
500/*! @brief Calcule les valeurs du champs inconnue aux positions specifiees.
501 *
502 * @param (DoubleTab& positions) les positions ou l'ont doit calculer le champ inconnues
503 * @param (DoubleTab& valeurs) le tableau des valeurs du champ inconnue aux positions voulues
504 * @return (DoubleTab&) le tableau des valeurs du champ inconnue aux positions voulues
505 */
506DoubleTab& Champ_Inc_base::valeur_aux(const DoubleTab& positions, DoubleTab& tab_valeurs) const
507{
508 const Domaine& domaine = domaine_dis_base().domaine();
509 IntTrav les_polys;
510 domaine.chercher_elements(positions, les_polys);
511
512 return valeur_aux_elems(positions, les_polys, tab_valeurs);
513}
514
515/*! @brief Calcule les valeurs du champs inconnue aux positions specifiees, pour une certaine composante du champ.
516 *
517 * @param (DoubleTab& positions) les positions ou l'ont doit calculer le champ inconnues
518 * @param (DoubleTab& les_valeurs) le tableau des valeurs du champ inconnue aux positions voulues
519 * @param (int) l'index de la composante du champ a calculer
520 * @return (DoubleVect&) le tableau des valeurs de la composante du champ specifiee aux positions voulues
521 */
522DoubleVect& Champ_Inc_base::valeur_aux_compo(const DoubleTab& positions, DoubleVect& tab_valeurs, int ncomp) const
523{
524 const Domaine& domaine = domaine_dis_base().domaine();
525 IntTrav les_polys;
526 domaine.chercher_elements(positions, les_polys);
527 return valeur_aux_elems_compo(positions, les_polys, tab_valeurs, ncomp);
528}
529
530/*! @brief Calcule la valeur du champs inconnue a la position specifiee.
531 *
532 * @param (DoubleVect& position) la position a laquelle on veut calculer le champ
533 * @param (DoubleVect& les_valeurs) la valeur du champ inconnue a la position specifiee
534 * @return (DoubleVect&) la valeur du champ inconnue a la position specifiee
535 */
536DoubleVect& Champ_Inc_base::valeur_a(const DoubleVect& position, DoubleVect& tab_valeurs) const
537{
538 const Domaine& domaine = domaine_dis_base().domaine();
539 IntVect le_poly(1);
540 domaine.chercher_elements(position, le_poly);
541 return valeur_a_elem(position, tab_valeurs, le_poly(0));
542}
543
544/*! @brief Affectation d'un OWN_PTR(Champ_base) generique (Champ_base) dans un champ inconnue.
545 *
546 * @param (Champ_base& ch) le champ partie droite de l'affectation
547 * @return (Champ_base&) le resultat de l'affectation (*this)
548 */
550{
551 DoubleTab noeuds;
552 remplir_coord_noeuds(noeuds);
553
554 if (valeurs().size_reelle_ok())
555 {
556 // Modif B.M. pour ne pas faire d'interpolation sur les cases virtuelles
557 const int n = valeurs().dimension(0);
558 DoubleTab pos, val;
559 pos.ref_tab(noeuds, 0, n);
560 val.ref_tab(valeurs(), 0, n);
561 ch.valeur_aux(pos, val);
562 //copie dans toutes les cases
564 for (int i = 1; i < les_valeurs->nb_cases(); i++)
565 les_valeurs[i].valeurs() = valeurs();
566 }
567 else
568 {
569 Cerr << "Champ_Inc_base::affecter_ not coded if size_reelle_ok()==0" << finl;
571 }
572 return *this;
573}
574
575//-Cas CL periodique : assure que les valeurs sur des faces periodiques
576// en vis a vis sont identiques. Pour cela on prend la demi somme des deux valeurs.
577//La methode est a surcharger pour des champs discretises aux faces.
581
582/*! @brief Affectation d'une composante d'un OWN_PTR(Champ_base) quelconque (Champ_base) dans une composante d'un champ inconnue
583 *
584 * @param (Champ_base& ch) la partie droite de l'affectation
585 * @param (int compo) l'index de la composante a affecter
586 * @return (Champ_base&) le resultat de l'affectation (avec upcast)
587 */
589{
590 DoubleTab noeuds;
591 IntVect polys;
592 if (!remplir_coord_noeuds_et_polys_compo(noeuds, polys, compo))
593 {
594 remplir_coord_noeuds_compo(noeuds, compo);
595 ch.valeur_aux_compo(noeuds, valeurs(), compo);
596 }
597 else
598 ch.valeur_aux_elems_compo(noeuds, polys, valeurs(), compo);
599 return *this;
600}
601
602/*! @brief voir Champ_base Cas particulier (malheureusement) du Champ_P0_VDF :
603 *
604 * Si la frontiere est un raccord, le resultat est calcule sur le raccord associe. Dans ce cas, le DoubleTab x doit etre
605 * dimensionne sur le raccord associe.
606 *
607 */
608DoubleTab& Champ_Inc_base::trace(const Frontiere_dis_base&, DoubleTab& x, double tps, int distant) const
609{
610 Cerr << que_suis_je() << "did not overloaded Champ_Inc_base::trace" << finl;
611 return x;
612}
613
614/*! @brief NE FAIT RIEN Methode a surcharger
615 *
616 * @param (DoubleTab&)
617 * @param (IntVect&)
618 * @return (int) renvoie toujours 0
619 */
621{
622 return 0;
623}
624
625/*! @brief Simple appel a Champ_Inc_base::remplir_coord_noeuds(DoubleTab&)
626 *
627 * @param (DoubleTab& coord) coordonnees des noeuds a modifier
628 * @param (int) l'index de la composante a modifier
629 * @return (DoubleTab&)
630 */
631DoubleTab& Champ_Inc_base::remplir_coord_noeuds_compo(DoubleTab& coord, int) const
632{
633 return remplir_coord_noeuds(coord);
634}
635
636/*! @brief Simple appel a: Champ_Inc_base::remplir_coord_noeuds_et_polys(DoubleTab&,IntVect& poly)
637 *
638 * @param (DoubleTab& coord)
639 * @param (IntVect& poly)
640 * @param (int)
641 * @return (int) code de retour propage
642 */
643int Champ_Inc_base::remplir_coord_noeuds_et_polys_compo(DoubleTab& coord, IntVect& poly, int) const
644{
645 return remplir_coord_noeuds_et_polys(coord, poly);
646}
647
648const Domaine& Champ_Inc_base::domaine() const
649{
650 return domaine_dis_base().domaine();
651}
652
653int Champ_Inc_base::imprime(Sortie& os, int ncomp) const
654{
655 Cerr << que_suis_je() << "::imprime not coded." << finl;
657 return 1;
658}
659
660double Champ_Inc_base::integrale_espace(int ncomp) const
661{
662 Cerr << que_suis_je() << "::integrale_espace not coded." << finl;
664 return 0.;
665}
666
667/*! @brief Fixe le temps du champ.
668 *
669 * @param (double t) le nouveau temps
670 * @return (double) le nouveau temps
671 */
672double Champ_Inc_base::changer_temps(const double t)
673{
674 les_valeurs->changer_temps(t);
675 return temps_ = t;
676}
677
678/*!
679 * See comments in Probleme_base_interface_proto::resetTime_impl().
680 * Here we force a new time value.
681 */
683{
684 changer_temps(time);
685}
686
687/*! @brief Associe le champ a l'equation dont il represente une inconnue.
688 *
689 * Simple appel a MorEqn::associer_eqn(const Equation_base&)
690 *
691 * @param (Equation_base& eqn) l'equation auquel le champ doit s'associer
692 */
697
699{
700 mon_dom_cl_dis = zcl;
701}
702
704{
705 le_dom_VF = ref_cast(Domaine_VF, z_dis);
706}
707
709{
710 if (!mon_dom_cl_dis)
711 return equation().domaine_Cl_dis();
712 else
713 return mon_dom_cl_dis.valeur();
714}
715
717{
718 if (!mon_dom_cl_dis)
719 return equation().domaine_Cl_dis();
720 else
721 return mon_dom_cl_dis.valeur();
722}
723
724void Champ_Inc_base::init_champ_calcule(const Objet_U& obj, fonc_calc_t fonc)
725{
726 obj_calc_ = obj, fonc_calc_ = fonc, fonc_calc_init_ = 0;
728}
729
731{
732 val_bord_.resize(ref_cast(Domaine_VF, domaine_dis_base()).xv_bord().dimension_tot(0), valeurs().line_size());
733}
734
736{
738 {
739 DoubleTab result;
740 result.ref(val_bord_);
741 return result;
742 }
743 //sinon, calcul a partir des CLs
744 const Domaine_VF& domaine = ref_cast(Domaine_VF, domaine_dis_base());
745 const IntTab& f_e = domaine.face_voisins(), &f_s = domaine.face_sommets();
746 DoubleTrav result(domaine.xv_bord().dimension_tot(0), valeurs().line_size());
747
749 int j, k, f, fb, s, n, N = result.line_size(), is_p = (le_nom().debute_par("pression") || le_nom().debute_par("pressure")), n_som;
750 for (const auto& itr : cls)
751 {
752 const Front_VF& fr = ref_cast(Front_VF, itr->frontiere_dis());
753 //valeur au bord imposee, sauf si c'est une paroi (dans ce cas, la CL peut avoir moins de composantes que le champ -> Energie_Multiphase)
754 if (is_p ? sub_type(Neumann, itr.valeur()) : (sub_type(Dirichlet, itr.valeur()) && !sub_type(Scalaire_impose_paroi, itr.valeur())))
755 for (j = 0; j < fr.nb_faces_tot(); j++)
756 for (f = fr.num_face(j), fb = domaine.fbord(f), n = 0; n < N; n++)
757 result(fb, n) = is_p ? ref_cast(Neumann, itr.valeur()).flux_impose(j, n) : ref_cast(Dirichlet, itr.valeur()).val_imp(j, n);
758 else if (sub_type(Neumann_val_ext, itr.valeur())) //valeur externe imposee
759 for (j = 0; j < fr.nb_faces_tot(); j++)
760 for (f = fr.num_face(j), fb = domaine.fbord(f), n = 0; n < N; n++)
761 result(fb, n) = ref_cast(Neumann_val_ext, itr.valeur()).val_ext(j, n);
762 else if (sub_type(Champ_Inc_P0_base, *this))
763 for (j = 0; j < fr.nb_faces_tot(); j++) //Champ P0 : on peut prendre la valeur en l'element
764 for (f = fr.num_face(j), fb = domaine.fbord(f), n = 0; n < N; n++)
765 result(fb, n) = valeurs()(f_e(f, f_e(f, 0) == -1), n);
766 else if (sub_type(Champ_Inc_P1_base, *this))
767 for (j = 0; j < fr.nb_faces_tot(); j++) //Champ P1 : moyenne des valeurs aux sommets
768 {
769 f = fr.num_face(j), fb = domaine.fbord(f);
770 for (n_som = 0; n_som < f_s.dimension(1) && f_s(f, n_som) >= 0;)
771 n_som++;
772 for (n = 0; n < N; n++)
773 result(fb, n) = 0;
774 for (k = 0; k < n_som; k++)
775 for (s = f_s(f, k), n = 0; n < N; n++)
776 result(fb, n) += valeurs()(s, n) / n_som;
777 }
778 else if (que_suis_je() == "Champ_P1NC")
779 for (j = 0; j < fr.nb_faces_tot(); j++)
780 for (f = fr.num_face(j), fb = domaine.fbord(f), n = 0; n < N; n++)
781 result(fb, n) = valeurs()(f, n);
782 else
783 Process::exit("Champ_Inc_base::valeur_aux_bords() : must code something!");
784 }
785 return result;
786}
: class Champ_Inc_P0_base
Classe Champ_Inc_base.
const Domaine & domaine() const
void associer_domaine_dis_base(const Domaine_dis_base &) override
virtual int remplir_coord_noeuds_et_polys(DoubleTab &, IntVect &) const
NE FAIT RIEN Methode a surcharger.
virtual void creer_tableau_distribue(const MD_Vector &, RESIZE_OPTIONS=RESIZE_OPTIONS::COPY_INIT)
DoubleTab & futur(int i=1) override
Renvoie les valeurs du champs a l'instant t+i.
int fixer_nb_valeurs_nodales(int) override
int lire_donnees(Entree &)
Lit les valeurs du champs a partir d'un flot d'entree.
virtual void associer_domaine_cl_dis(const Domaine_Cl_dis_base &)
virtual int fixer_nb_valeurs_temporelles(int)
Fixe le nombre de valeurs temporelles a conserver.
void init_champ_calcule(const Objet_U &obj, fonc_calc_t fonc)
virtual int nb_valeurs_temporelles() const
Renvoie le nombre de valeurs temporelles actuellement conservees.
DoubleVect & valeur_aux_compo(const DoubleTab &positions, DoubleVect &valeurs, int ncomp) const override
Calcule les valeurs du champs inconnue aux positions specifiees, pour une certaine composante du cham...
const Domaine_Cl_dis_base & domaine_Cl_dis() const
void mettre_a_jour(double temps) override
Effectue une mise a jour en temps du champ inconnue.
virtual DoubleTab & remplir_coord_noeuds_compo(DoubleTab &, int) const
Simple appel a Champ_Inc_base::remplir_coord_noeuds(DoubleTab&).
void resetTime(double time) override
const Domaine_dis_base & domaine_dis_base() const override
double changer_temps(const double temps) override
Fixe le temps du champ.
virtual std::vector< YAML_data > data_a_sauvegarder() const
for PDI IO: retrieve name, type and dimensions of the field to save/restore.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual void associer_eqn(const Equation_base &)
Associe le champ a l'equation dont il represente une inconnue.
virtual int remplir_coord_noeuds_et_polys_compo(DoubleTab &, IntVect &, int) const
Simple appel a: Champ_Inc_base::remplir_coord_noeuds_et_polys(DoubleTab&,IntVect& poly).
virtual void verifie_valeurs_cl()
fonc_calc_t fonc_calc_
int sauvegarder(Sortie &) const override
Sauvegarde le champ inconnue sur un flot de sortie.
Champ_Inc_base & avancer(int i=1)
Avance le pointeur courant de i pas de temps, dans la liste des valeurs temporelles conservees.
double changer_temps_passe(double, int i=1)
Fixe le temps du ieme champ passe.
virtual double integrale_espace(int ncomp) const
int nb_valeurs_nodales() const override
Returns the number of "real" geometric positions of the degrees of freedom, or -1 if not applicable (...
DoubleVect & valeur_a(const DoubleVect &position, DoubleVect &valeurs) const override
Calcule la valeur du champs inconnue a la position specifiee.
double recuperer_temps_passe(int i=1) const
Retourne le temps du ieme champ passe.
virtual DoubleTab & remplir_coord_noeuds(DoubleTab &) const =0
Champ_Inc_base & reculer(int i=1)
Recule le pointeur courant de i pas de temps, dans la liste des valeurs temporelles conservees.
int reprendre(Entree &) override
Lecture d'un champ inconnue a partir d'un flot d'entree en vue d'une reprise.
DoubleTab & trace(const Frontiere_dis_base &, DoubleTab &, double, int distant) const override
voir Champ_base Cas particulier (malheureusement) du Champ_P0_VDF :
DoubleTab & valeur_aux(const DoubleTab &positions, DoubleTab &valeurs) const override
Calcule les valeurs du champs inconnue aux positions specifiees.
Champ_base & affecter_compo(const Champ_base &, int compo) override
Affectation d'une composante d'un OWN_PTR(Champ_base) quelconque (Champ_base) dans une composante d'u...
Champ_base & affecter_(const Champ_base &) override
Affectation d'un OWN_PTR(Champ_base) generique (Champ_base) dans un champ inconnue.
Nom get_PDI_dname() const
for PDI IO: retrieve the name of the HDF5 dataset in which the field will be saved or be restored fro...
DoubleTab val_bord_
int imprime(Sortie &, int) const override
DoubleTab valeur_aux_bords() const override
renvoie la valeur du champ aux faces de bord
double recuperer_temps_futur(int i=1) const
Retourne le temps du ieme champ futur.
double changer_temps_futur(double, int i=1)
Fixe le temps du ieme champ futur.
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
double temps_
Definition Champ_base.h:123
Champ_base()
Constructeur par defaut d'un Champ_base.
virtual DoubleVect & valeur_aux_elems_compo(const DoubleTab &positions, const IntVect &les_polys, DoubleVect &valeurs, int ncomp) const
provoque une erreur ! doit etre surchargee par les classes derivees
double temps() const
Renvoie le temps du champ.
virtual DoubleTab & valeur_aux(const DoubleTab &positions, DoubleTab &valeurs) const
Provoque une erreur ! Doit etre surchargee par les classes derivees.
virtual DoubleTab & valeur_aux_elems(const DoubleTab &positions, const IntVect &les_polys, DoubleTab &valeurs) const
provoque une erreur ! doit etre surchargee par les classes derivees
virtual DoubleVect & valeur_a_elem(const DoubleVect &position, DoubleVect &valeurs, int le_poly) const
provoque une erreur ! doit etre surchargee par les classes derivees
virtual DoubleVect & valeur_aux_compo(const DoubleTab &positions, DoubleVect &valeurs, int ncomp) const
Idem que valeur_aux(const DoubleTab &, DoubleTab &), mais calcule uniquement la composante compo du c...
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
Definition Dirichlet.h:31
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VF
Definition Domaine_VF.h:44
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
const Domaine & domaine() const
static int is_ecriture_special(int &special, int &a_faire)
indique si le format special a ete demande en lecture active par sauvegarde xyz .
static int is_lecture_special()
indique si le format special a ete demande en lecture active par reprise xyz .
static int ecriture_special(const Champ_base &ch, Sortie &fich)
simple appel a EcritureLectureSpecial::ecriture_special (const Domaine_VF& zvf,Sortie& fich,...
static void lecture_special(Champ_base &ch, Entree &fich)
simple appel a EcritureLectureSpecial::lecture_special (const Domaine_VF& zvf,Entree& fich,...
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 Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
const Nom & le_nom() const override
Renvoie le nom du champ.
int nb_compo_
Definition Field_base.h:95
class Front_VF
Definition Front_VF.h:36
int nb_faces_tot() const
Definition Front_VF.h:58
int num_face(const int) const
Definition Front_VF.h:68
classe Frontiere_dis_base Classe representant une frontiere discretisee.
static void creer_tableau_distribue(const MD_Vector &, Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
transforme v en un tableau parallele ayant la structure md.
: Cette classe est un OWN_PTR mais l'objet pointe est partage entre plusieurs
Definition MD_Vector.h:48
int mon_equation_non_nul() const
Definition MorEqn.h:85
void associer_eqn(const Equation_base &)
Associe une equation a l'objet.
Definition MorEqn.cpp:28
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
Classe Neumann_val_ext Cette classe est la classe de base de la hierarchie des conditions.
Classe Neumann Cette classe est la classe de base de la hierarchie des conditions aux limites de type...
Definition Neumann.h:31
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const char * getChar() const
Definition Nom.h:91
virtual int debute_par(const char *const n) const
Definition Nom.cpp:319
const std::string & getString() const
Definition Nom.h:92
friend class Entree
Definition Objet_U.h:76
friend class Sortie
Definition Objet_U.h:75
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
Objet_U()
Constructeur par defaut : attribue un numero d'identifiant unique a l'objet (object_id_),...
Definition Objet_U.cpp:55
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
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
const Domaine & domaine() const
Renvoie le domaine associe au probleme.
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe Roue utilisee dans Champ_Inc_Base.
Definition Roue.h:86
double temps() const
Retoune la valeur du temps de la Roue.
Definition Roue.h:169
double changer_temps(const double t)
Change le temps de la Roue.
Definition Roue.h:180
const DoubleTab & valeurs() const
Retourne le tableau des valeurs de la Roue.
Definition Roue.h:149
const Roue & futur(int i=1) const
Retourne la Roue correspondant a la ieme case future.
Definition Roue.cpp:132
const Roue & passe(int i=1) const
Retourne la Roue correspondant a la ieme case passee.
Definition Roue.cpp:164
classe Scalaire_impose_paroi Impose un scalaire a la paroi dans une equation de type Convection-Difus...
double temps_courant() const
Renvoie le temps courant.
Classe de base des flux de sortie.
Definition Sortie.h:52
virtual Sortie & flush()
Definition Sortie.cpp:138
_SIZE_ size_array() const
_TYPE_ * addr()
void jump(Entree &) override
Definition TRUSTTab.tpp:701
virtual void ref(const TRUSTTab &)
Definition TRUSTTab.tpp:308
void lit(Entree &, bool resize_and_read=true) override
Definition TRUSTTab.tpp:710
int nb_dim() const
Definition TRUSTTab.h:199
virtual void ref_tab(TRUSTTab &, _SIZE_ start_line=0, _SIZE_ nb_lines=-1)
Definition TRUSTTab.tpp:345
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
void ecrit(Sortie &) const override
Definition TRUSTTab.tpp:688
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67
_SIZE_ size_reelle_ok() const
Definition TRUSTVect.tpp:38
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
classe TRUST_2_PDI Encapsulation of PDI methods (library used for IO operations). See the website pdi...
Definition TRUST_2_PDI.h:59
void share_type(const Nom &name, const Nom &type)
Generic method to share the type of a TRUST object.
void read(const std::string &name, void *data)
static int is_PDI_checkpoint()
static int is_PDI_restart()
void share_TRUSTTab_dimensions(const DoubleTab &tab, const Nom &name, int write)
Generic method to share the dimensions of a TRUST DoubleTab with PDI.
void TRUST_start_sharing(const std::string &name, const void *data)
classe YAML_data : collection of all needed information for data to save/restore in order to write th...
Definition YAML_data.h:26
void set_save_field_type(bool b)
Definition YAML_data.h:40