TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Op_Correlation.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Champ_Generique_refChamp.h>
17#include <Discretisation_base.h>
18#include <Schema_Temps_base.h>
19#include <Op_Correlation.h>
20
21Implemente_instanciable(Op_Correlation, "Op_Correlation", Operateur_Statistique_tps_base);
22
24{
25 return s << que_suis_je() << " " << le_nom();
26}
27
29{
30 return s;
31}
32
33void Op_Correlation::completer(const Probleme_base& Pb, const Nom& prefix)
34{
35 const OBS_PTR(Champ_Generique_base)& a = la_moyenne_a().integrale().le_champ();
36 const OBS_PTR(Champ_Generique_base)& b = la_moyenne_b().integrale().le_champ();
37 integrale_tps_a_ = la_moyenne_a().integrale();
38 integrale_tps_b_ = la_moyenne_b().integrale();
39
40 // On recupere le domaine discretise
41 const Domaine_dis_base& domaine = a->get_ref_domaine_dis_base();
42
43 // Dimensionnement du champ integrale_champ a la meme taille que mon_champ
44 const DoubleTab& tab_a = valeurs_a();
45 const DoubleTab& tab_b = valeurs_b();
46
47 OWN_PTR(Champ_base) espace_stockage_source_a, espace_stockage_source_b;
48 const Champ_base& source_a = a->get_champ(espace_stockage_source_a);
49 const Champ_base& source_b = b->get_champ(espace_stockage_source_b);
50
51 const int nb_compo_a = source_a.nb_comp();
52 const int nb_compo_b = source_b.nb_comp();
53
54 //Pour utiliser nom_cible uniquement si a et b sont des Champ_Generique_refChamp
55 //pour pouvoir reproduire le nom des variables dans le lml
56 Noms noms_a, noms_b;
57
58 if (!(sub_type(Champ_Generique_refChamp,a.valeur()) && (sub_type(Champ_Generique_refChamp, b.valeur()))))
59 {
60 noms_a = a->get_property("nom");
61 noms_b = b->get_property("nom");
62 }
63 else
64 {
65 noms_a = a->get_property("nom_cible");
66 noms_b = b->get_property("nom_cible");
67 }
68
69 const Nom nom_a = noms_a[0];
70 const Nom nom_b = noms_b[0];
71
72 //Cas particulier si a et b sont des Champ_Generique_refChamp
73 //pour pouvoir reproduire le nom des variables dans le lml
74 Noms compo_a, compo_b;
75
76 if (!(sub_type(Champ_Generique_refChamp,a.valeur()) && (sub_type(Champ_Generique_refChamp, b.valeur()))))
77 {
78 compo_a = a->get_property("composantes");
79 compo_b = b->get_property("composantes");
80 }
81 else
82 {
83 compo_a = source_a.noms_compo();
84 compo_b = source_b.noms_compo();
85 }
86
87 const Noms unites_a = a->get_property("unites");
88 const Noms unites_b = b->get_property("unites");
89
90 int nb_valeurs_nodales = -1;
91
92 // Note B.M.: integrale_tps_ab_ est deja type dans Correlation::associer
93 // En revanche fixer_nb_valeurs_nodales n'est pas fait.
94
95 if ((tab_a.get_md_vector() != tab_b.get_md_vector())
96 || (tab_a.dimension_tot(0) != tab_b.dimension_tot(0))
97 || (nb_compo_a > 1 && (tab_a.nb_dim() == 1 || tab_a.dimension(1) != nb_compo_a))
98 || (nb_compo_b > 1 && (tab_b.nb_dim() == 1 || tab_b.dimension(1) != nb_compo_b)))
99 {
100 // Support different pour les champs a et b ou pour leurs composantes
101 // Alors on ramene aux elements en creant un Champ_Fonc_PO_VDF ou VEF
102 integrale_tps_ab_.support_different() = 1;
103 Nom Champ_Fonc_P0 = "Champ_Fonc_P0_";
104 Champ_Fonc_P0 += Pb.discretisation().que_suis_je().substr_old(1, 3);
105 integrale_tps_ab_.typer_champ(Champ_Fonc_P0);
106 nb_valeurs_nodales = domaine.nb_elem();
107 }
108 else
109 {
110 // Meme support pour les champs a et b
111 integrale_tps_ab_.support_different() = 0;
112 if (tab_a.size_reelle_ok())
113 nb_valeurs_nodales = tab_a.dimension(0);
114 else
115 nb_valeurs_nodales = -1; // B.M.: quoi donner a fixer_nb_valeurs_nodales ???
116 }
117 int nb_comp = nb_compo_a * nb_compo_b;
118 DoubleTab& val = valeurs_ab();
119 Noms noms_composantes;
120 if (nb_compo_a == 1)
121 if (nb_compo_b == 1)
122 {
123 // A et B champs scalaires
124 }
125 else
126 {
127 // A champ scalaire, B champ vectoriel
128 noms_composantes.dimensionner(nb_comp);
129 Nom debut("Correlation_");
130 debut += nom_a + "_";
131 for (int i = 0; i < nb_comp; i++)
132 noms_composantes[i] = debut + compo_b[i];
133 }
134 else if (nb_compo_b == 1)
135 {
136 // A champ vectoriel, B champ scalaire
137 noms_composantes.dimensionner(nb_comp);
138 Nom debut("Correlation_");
139 debut += nom_b + "_";
140 for (int i = 0; i < nb_comp; i++)
141 noms_composantes[i] = debut + compo_a[i];
142 }
143 else
144 {
145 // A et B champs vectoriels
146 noms_composantes.dimensionner(nb_comp);
147 Nom debut("Correlation_");
148 for (int i = 0; i < nb_compo_a; i++)
149 for (int j = 0; j < nb_compo_b; j++)
150 noms_composantes[i * nb_compo_b + j] = debut + compo_a[i] + "_" + compo_b[j];
151 }
152
153 if (nb_comp > 1)
154 val.resize(0, nb_comp);
155
156 Nom nom_pour_post = "Correlation_";
157 nom_pour_post += nom_a + "_" + nom_b;
158 integrale_tps_ab_.le_champ_calcule().nommer(nom_pour_post);
159
160 Nom pdi_name = prefix + nom_pour_post;
161 integrale_tps_ab_.le_champ_calcule().set_pdi_name(pdi_name);
162
163 integrale_tps_ab_.le_champ_calcule().associer_domaine_dis_base(domaine);
164 integrale_tps_ab_.le_champ_calcule().fixer_nb_comp(nb_comp);
165
166 // BM: le parametre de fixer_nb_valeurs_nodales est inutile,
167 // le champ sait determiner tout seul combien de ddl il a, mais
168 // il y a un test sur le parametre: il faut que la valeur soit la bonne.
169 integrale_tps_ab_.le_champ_calcule().fixer_nb_valeurs_nodales(nb_valeurs_nodales);
170
171 // On fixe les unites
172 Nom unite(unites_a[0]);
173 unite += ".";
174 unite += unites_b[0];
175
176 if (nb_comp == 1)
177 integrale_tps_ab_.le_champ_calcule().fixer_unite(unite);
178 else
179 {
180 Noms unites(nb_comp);
181 for (int i = 0; i < unites.size(); i++)
182 unites[i] = unite;
183 integrale_tps_ab_.le_champ_calcule().fixer_noms_compo(noms_composantes);
184 integrale_tps_ab_.le_champ_calcule().fixer_unites(unites);
185 }
186 integrale_tps_ab_.le_champ_calcule().changer_temps(Pb.schema_temps().temps_courant());
187}
188
190{
192 const double dt_ab = dt_integration_ab();
193 if (dt_ab > 0)
194 {
195 // On calcule Moyenne(a'b')=Moyenne(ab)-Moyenne(a)*Moyenne(b)
196 correlation.le_champ_calcule().valeurs() /= dt_ab;
197 const double dt_a = dt_integration_a();
198 const double dt_b = dt_integration_b();
199 assert(est_egal(dt_a, dt_ab));
200 assert(est_egal(dt_b, dt_ab));
201 correlation.ajoute_produit_tensoriel(-1 / (dt_a * dt_b), integrale_tps_a_->le_champ_calcule(), integrale_tps_b_->le_champ_calcule());
202 }
203 return correlation.le_champ_calcule().valeurs();
204}
205
206int Op_Correlation::completer_post_statistiques(const Domaine& dom, const int is_axi, Format_Post_base& format)
207{
208 return 1;
209}
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
class Champ_Generique_base
Classe de champ particuliere qui encapsule une reference a un champ volumique de TRUST de type Champ_...
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual int nb_comp() const
Definition Field_base.h:56
const Noms & noms_compo() const
Renvoie le tableau des noms des composantes du champ.
Classe de base des formats de postraitements pour les champs (lata, med, cgns, lml,...
const Champ_Fonc_base & le_champ_calcule() const
classe Integrale_tps_produit_champs Cette classe represente l'integrale en temps d'un produit de 2 ch...
void ajoute_produit_tensoriel(double, const Champ_base &, const Champ_base &)
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
Nom substr_old(const int, const int) const
Retourne un nom selon la commande usuelle substr ATTENTION : deb = 1 => premier caractere de la chain...
Definition Nom.cpp:473
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
double dt_integration_b() const
Integrale_tps_produit_champs integrale_tps_ab_
DoubleTab calculer_valeurs() const override
const Op_Moyenne & la_moyenne_b() const
double dt_integration_a() const
double dt_integration_ab() const
int completer_post_statistiques(const Domaine &dom, const int is_axi, Format_Post_base &format) override
const Op_Moyenne & la_moyenne_a() const
const DoubleTab & valeurs_b() const
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
OBS_PTR(Op_Moyenne) la_moyenne_a_
const DoubleTab & valeurs_a() const
DoubleTab & valeurs_ab()
void completer(const Probleme_base &, const Nom &) override
const Integrale_tps_Champ & integrale() const override
Definition Op_Moyenne.h:32
classe Operateur_Statistique_tps_base Represente des operations statistiques sur les champs.
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Discretisation_base & discretisation() const
Renvoie la discretisation associee au probleme.
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
double temps_courant() const
Renvoie le temps courant.
Classe de base des flux de sortie.
Definition Sortie.h:52
int nb_dim() const
Definition TRUSTTab.h:199
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size_reelle_ok() const
Definition TRUSTVect.tpp:38
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123