TrioCFD 1.9.9_beta
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 Sets the number of temporal values to keep.
39 *
40 * (a different number depending on the time scheme used)
41 * Calls Roue::fixer_nb_cases(int)
42 *
43 * @param (int i) the number of temporal values to keep
44 * @return (int) the number of temporal values to keep
45 */
47{
48 return les_valeurs->fixer_nb_cases(i);
49}
50
51/*! @brief Returns the number of temporal values currently kept.
52 *
53 * This value is stored by the Roue of Champ_Inc_base
54 *
55 * @return (int) the number of temporal values currently kept
56 */
58{
59 return les_valeurs->nb_cases();
60}
61
62/*! @brief Reads the field values from an input stream.
63 *
64 * Reading format:
65 * int [THE NUMBER OF VALUES TO READ]
66 * [READ THE NUMBER OF VALUES WANTED]
67 *
68 * @param (Entree& is) the input stream
69 * @return (int) returns 1 if the reading is correct
70 * @throws the number of values to read is 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: This test is not symmetric with Champ_Fonc_base => inconsistency in nb_dim
101 // for "multi-scalar" fields with one component.
102 if (tab.size_array() == 0 && (!tab.get_md_vector()))
103 {
104 // Note B.M.: the fixer_nb_valeurs_nodales methods are called haphazardly.
105 // Do nothing if the array already has the correct 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 Returns the field values at time instant.
135 *
136 * @param (double temps) the time at which we want the values of the field
137 * @return (DoubleTab&) the field values at time instant
138 */
139// WEC : Warning in the case of Pb_Couple we used the fact that this function returned the present when it didn't find
140// a time greater than all available times!!!
141// The behavior is now more explicit : a WARNING is displayed as soon as the present is returned instead of the requested time.
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 Returns the field values at time instant.
177 *
178 * @param (double temps) the time at which we want the values of the field
179 * @return (DoubleTab&) the field values at time instant
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 // Future?
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 // Past?
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 Advances the current pointer by i time steps, in the list of kept temporal values.
220 *
221 * @param (int i) the number of time steps to advance
222 * @return (Champ_Inc_base&) returns *this, the field at the desired time step
223 */
225{
226 while (i--)
227 les_valeurs->avancer(les_valeurs);
228 temps_ = les_valeurs->temps();
229 return *this;
230}
231
232/*! @brief Rewinds the current pointer by i time steps, in the list of kept temporal values.
233 *
234 * @param (int i) the number of time steps to rewind
235 * @return (Champ_Inc_base&) returns *this, the field at the desired time step
236 */
238{
239 while (i--)
240 les_valeurs->reculer(les_valeurs);
241 temps_ = les_valeurs->temps();
242 return *this;
243}
244
245/*! @brief Performs a time update of the unknown field.
246 *
247 * WEC : Now if we call it 2 times in a row with the same
248 * argument, the 2nd one does nothing.
249 *
250 * @param (double temps) the new time
251 */
252void Champ_Inc_base::mettre_a_jour(double un_temps)
253{
254 // Field with multiple temporal values:
255 // Advance to the correct temporal value.
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 //Useless:
265 //valeurs().echange_espace_virtuel();
266 if (fonc_calc_)
268 /* first calculation of a Champ_Fonc_Calc -> copy the calculated values to all 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 // Field with a single temporal value:
283 // Change the associated time.
284 else
285 {
286 changer_temps(un_temps);
287 if (fonc_calc_)
289 //Useless:
290 //valeurs().echange_espace_virtuel();
291 }
292}
293
294/*! @brief Sets the time of the i-th future field.
295 *
296 * @param (double t, int i) the new time
297 * @return (double) the new time
298 */
300{
301 Roue& la_roue = les_valeurs.valeur();
302 la_roue.futur(i).changer_temps(t);
303 return t;
304}
305
306/*! @brief Sets the time of the i-th past field.
307 *
308 * @param (double t, int i) the new time
309 * @return (double) the new time
310 */
312{
313 Roue& la_roue = les_valeurs.valeur();
314 la_roue.passe(i).changer_temps(t);
315 return t;
316}
317
318/*! @brief Returns the time of the i-th future field.
319 *
320 * @param (int i) the time
321 * @return (double) the time
322 */
324{
325 const Roue& la_roue = les_valeurs.valeur();
326 return la_roue.futur(i).temps();
327}
328
329/*! @brief Returns the time of the i-th past field.
330 *
331 * @param (int i) the time
332 * @return (double) the time
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 Saves the unknown field to an output stream.
372 *
373 * Writes an identifier, the field values, and the date (the time at the moment of saving).
374 *
375 * @param (Sortie& fich) an output stream
376 * @return (int) returns the size of array
377 */
379{
380 // in special write mode only the master writes the header
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 ; Does not flush in binary mode!
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 Reads an unknown field from an input stream for a restart.
442 *
443 * @param (Entree& fich) an input stream
444 * @return (int) always returns 1
445 */
447{
448 double un_temps;
450 if (nom_ != Nom("anonyme")) // reading for restart
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 // reading to skip the block
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 Computes the values of the unknown field at the specified positions.
501 *
502 * @param (DoubleTab& positions) the positions where the unknown field must be computed
503 * @param (DoubleTab& valeurs) the array of unknown field values at the desired positions
504 * @return (DoubleTab&) the array of unknown field values at the desired positions
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 Computes the values of the unknown field at the specified positions, for a given component of the field.
516 *
517 * @param (DoubleTab& positions) the positions where the unknown field must be computed
518 * @param (DoubleTab& les_valeurs) the array of unknown field values at the desired positions
519 * @param (int) the index of the field component to compute
520 * @return (DoubleVect&) the array of values of the specified field component at the desired positions
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 Computes the value of the unknown field at the specified position.
531 *
532 * @param (DoubleVect& position) the position at which the field is to be computed
533 * @param (DoubleVect& les_valeurs) the value of the unknown field at the specified position
534 * @return (DoubleVect&) the value of the unknown field at the specified position
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 Assignment of a generic OWN_PTR(Champ_base) (Champ_base) to an unknown field.
545 *
546 * @param (Champ_base& ch) the field on the right side of the assignment
547 * @return (Champ_base&) the result of the assignment (*this)
548 */
550{
551 DoubleTab noeuds;
552 remplir_coord_noeuds(noeuds);
553
554 if (valeurs().size_reelle_ok())
555 {
556 // Modif B.M. to avoid interpolation on virtual cells
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 //copy to all 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//-Periodic BC case: ensures that the values on opposing periodic faces
576// are identical. To do so, we take the half sum of the two values.
577//The method must be overridden for fields discretized at faces.
581
582/*! @brief Assignment of a component of a generic OWN_PTR(Champ_base) (Champ_base) to a component of an unknown field
583 *
584 * @param (Champ_base& ch) the right side of the assignment
585 * @param (int compo) the index of the component to assign
586 * @return (Champ_base&) the result of the assignment (with 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 See Champ_base. Special case (unfortunately) of Champ_P0_VDF:
603 *
604 * If the boundary is a connector, the result is computed on the associated connector. In this case, the DoubleTab x must be
605 * dimensioned on the associated connector.
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 DOES NOTHING. Method to override
615 *
616 * @param (DoubleTab&)
617 * @param (IntVect&)
618 * @return (int) always returns 0
619 */
621{
622 return 0;
623}
624
625/*! @brief Simple call to Champ_Inc_base::remplir_coord_noeuds(DoubleTab&)
626 *
627 * @param (DoubleTab& coord) coordinates of the nodes to modify
628 * @param (int) the index of the component to modify
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 call to: 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) propagated return code
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 Sets the time of the field.
668 *
669 * @param (double t) the new time
670 * @return (double) the new time
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 Associates the field with the equation of which it represents an unknown.
688 *
689 * Simple call to MorEqn::associer_eqn(const Equation_base&)
690 *
691 * @param (Equation_base& eqn) the equation to which the field must be associated
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 //otherwise, compute from the BCs
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 //imposed boundary value, except if it is a wall (in which case the BC may have fewer components than the field -> 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())) //externally imposed value
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++) //P0 field: we can take the value at the 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++) //P1 field: average of vertex values
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
Class 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
DOES NOTHING. Method to override.
virtual void creer_tableau_distribue(const MD_Vector &, RESIZE_OPTIONS=RESIZE_OPTIONS::COPY_INIT)
DoubleTab & futur(int i=1) override
Returns field values at instant t+i.
int fixer_nb_valeurs_nodales(int) override
int lire_donnees(Entree &)
Reads the field values from an input stream.
virtual void associer_domaine_cl_dis(const Domaine_Cl_dis_base &)
virtual int fixer_nb_valeurs_temporelles(int)
Sets the number of temporal values to keep.
void init_champ_calcule(const Objet_U &obj, fonc_calc_t fonc)
virtual int nb_valeurs_temporelles() const
Returns the number of temporal values currently kept.
DoubleVect & valeur_aux_compo(const DoubleTab &positions, DoubleVect &valeurs, int ncomp) const override
Computes the values of the unknown field at the specified positions, for a given component of the fie...
const Domaine_Cl_dis_base & domaine_Cl_dis() const
void mettre_a_jour(double temps) override
Performs a time update of the unknown field.
virtual DoubleTab & remplir_coord_noeuds_compo(DoubleTab &, int) const
Simple call to 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
Sets the time of the field.
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
Returns the array of field values at the current time.
virtual void associer_eqn(const Equation_base &)
Associates the field with the equation of which it represents an unknown.
virtual int remplir_coord_noeuds_et_polys_compo(DoubleTab &, IntVect &, int) const
Simple call to: 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
Saves the unknown field to an output stream.
Champ_Inc_base & avancer(int i=1)
Advances the current pointer by i time steps, in the list of kept temporal values.
double changer_temps_passe(double, int i=1)
Sets the time of the i-th past field.
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
Computes the value of the unknown field at the specified position.
double recuperer_temps_passe(int i=1) const
Returns the time of the i-th past field.
virtual DoubleTab & remplir_coord_noeuds(DoubleTab &) const =0
Champ_Inc_base & reculer(int i=1)
Rewinds the current pointer by i time steps, in the list of kept temporal values.
int reprendre(Entree &) override
Reads an unknown field from an input stream for a restart.
DoubleTab & trace(const Frontiere_dis_base &, DoubleTab &, double, int distant) const override
See Champ_base. Special case (unfortunately) of Champ_P0_VDF:
DoubleTab & valeur_aux(const DoubleTab &positions, DoubleTab &valeurs) const override
Computes the values of the unknown field at the specified positions.
Champ_base & affecter_compo(const Champ_base &, int compo) override
Assignment of a component of a generic OWN_PTR(Champ_base) (Champ_base) to a component of an unknown ...
Champ_base & affecter_(const Champ_base &) override
Assignment of a generic OWN_PTR(Champ_base) (Champ_base) to an unknown field.
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
Returns the field value at the boundary faces.
double recuperer_temps_futur(int i=1) const
Returns the time of the i-th future field.
double changer_temps_futur(double, int i=1)
Sets the time of the i-th future field.
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
double temps_
Definition Champ_base.h:123
Champ_base()
Default constructor of a Champ_base.
virtual DoubleVect & valeur_aux_elems_compo(const DoubleTab &positions, const IntVect &les_polys, DoubleVect &valeurs, int ncomp) const
Causes an error! Must be overridden by derived classes.
double temps() const
Returns the time of the field.
virtual DoubleTab & valeur_aux(const DoubleTab &positions, DoubleTab &valeurs) const
Causes an error! Must be overridden by derived classes.
virtual DoubleTab & valeur_aux_elems(const DoubleTab &positions, const IntVect &les_polys, DoubleTab &valeurs) const
Causes an error! Must be overridden by derived classes.
virtual DoubleVect & valeur_a_elem(const DoubleVect &position, DoubleVect &valeurs, int le_poly) const
Causes an error! Must be overridden by derived classes.
virtual DoubleVect & valeur_aux_compo(const DoubleTab &positions, DoubleVect &valeurs, int ncomp) const
Same as valeur_aux(const DoubleTab &, DoubleTab &), but computes only the component compo of the fiel...
class Conds_lim This class represents a vector of boundary conditions.
Definition Conds_lim.h:32
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
Definition Dirichlet.h:31
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_VF
Definition Domaine_VF.h:44
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
const Domaine & domaine() const
static int is_ecriture_special(int &special, int &a_faire)
Indicates whether the special format was requested in active writing by xyz save.
static int is_lecture_special()
Indicates whether the special format was requested in active reading by xyz restart.
static int ecriture_special(const Champ_base &ch, Sortie &fich)
Simple call to EcritureLectureSpecial::ecriture_special (const Domaine_VF& zvf,Sortie& fich,...
static void lecture_special(Champ_base &ch, Entree &fich)
Simple call to 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
class Equation_base The role of an equation is the calculation of one or more fields....
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the discretized boundary condition domain associated with the equation.
Probleme_base & probleme()
Returns the problem associated with the equation.
const Nom & le_nom() const override
Returns the name of the field.
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
class Frontiere_dis_base Class representing a discretized boundary.
static void creer_tableau_distribue(const MD_Vector &, Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Transforms v into a parallel array having the structure md.
: This class is an OWN_PTR but the pointed object is shared among multiple
Definition MD_Vector.h:48
int mon_equation_non_nul() const
Definition MorEqn.h:85
void associer_eqn(const Equation_base &)
Associates an equation with the object.
Definition MorEqn.cpp:28
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
Classe Neumann_val_ext This class is the base class of the hierarchy of.
Classe Neumann This class is the base class of the hierarchy of Neumann-type boundary conditions.
Definition Neumann.h:31
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
const char * getChar() const
Definition Nom.h:91
virtual int debute_par(const char *const n) const
Definition Nom.cpp:314
const std::string & getString() const
Definition Nom.h:92
friend class Entree
Definition Objet_U.h:71
friend class Sortie
Definition Objet_U.h:70
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
Objet_U()
Default constructor: assigns a unique identifier to the object (object_id_) and registers the object ...
Definition Objet_U.cpp:54
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
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
const Domaine & domaine() const
Returns the domain associated with the problem.
const Schema_Temps_base & schema_temps() const
Returns the time scheme associated with the problem.
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Roue class used in Champ_Inc_Base.
Definition Roue.h:86
double temps() const
Returns the time value of the Roue.
Definition Roue.h:169
double changer_temps(const double t)
Changes the time of the Roue.
Definition Roue.h:180
const DoubleTab & valeurs() const
Returns the value array of the Roue.
Definition Roue.h:149
const Roue & futur(int i=1) const
Returns the Roue corresponding to the i-th future slot.
Definition Roue.cpp:136
const Roue & passe(int i=1) const
Returns the Roue corresponding to the i-th past slot.
Definition Roue.cpp:168
Scalaire_impose_paroi Imposes a scalar at the wall in a Convection-Diffusion equation for a scalar.
double temps_courant() const
Returns the current time.
Base class for output streams.
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")
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)
YAML_data class: collection of all needed information for data to save/restore in order to write the ...
Definition YAML_data.h:26
void set_save_field_type(bool b)
Definition YAML_data.h:40