TrioCFD 1.9.9_beta
TrioCFD documentation
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 // Retrieve the discretized domain
41 const Domaine_dis_base& domaine = a->get_ref_domaine_dis_base();
42
43 // Size the integrale_champ field to the same size as 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 // Use nom_cible only if both a and b are Champ_Generique_refChamp,
55 // so that the variable names can be reproduced in the lml output.
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 // Special case when a and b are Champ_Generique_refChamp,
73 // so that the variable names can be reproduced in the lml output.
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_ is already typed in Correlation::associer,
93 // but fixer_nb_valeurs_nodales has not yet been called.
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 // Different support for fields a and b or for their components:
101 // bring everything to elements by creating a Champ_Fonc_P0_VDF or 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 // Same support for fields a and 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 and B are scalar fields
124 }
125 else
126 {
127 // A is a scalar field, B is a vector field
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 is a vector field, B is a scalar field
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 and B are vector fields
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 // The field can determine on its own how many DOFs it has, but
168 // there is a check on the parameter: the value must be correct.
169 integrale_tps_ab_.le_champ_calcule().fixer_nb_valeurs_nodales(nb_valeurs_nodales);
170
171 // Set the units
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 // Compute Mean(a'b') = Mean(ab) - Mean(a)*Mean(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
Overrides Champ_base::valeurs() Returns the array of values.
class Champ_Generique_base
Special field class that encapsulates a reference to a volume field of TRUST of type Champ_base.
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
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
Returns the array of names of the field components.
Base class for post-processing output formats for fields (lata, med, cgns, lml, single_lata).
const Champ_Fonc_base & le_champ_calcule() const
class Integrale_tps_produit_champs
void ajoute_produit_tensoriel(double, const Champ_base &, const Champ_base &)
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
Nom substr_old(const int, const int) const
Returns a name using the usual substr command. NOTE: deb = 1 means the first character of the string.
Definition Nom.cpp:466
An array of character strings (VECT(Nom)).
Definition Noms.h:26
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
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
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this 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
class Operateur_Statistique_tps_base
class Probleme_base It is a Probleme_U that is not a coupling.
const Discretisation_base & discretisation() const
Returns the discretization associated with the problem.
const Schema_Temps_base & schema_temps() const
Returns the time scheme associated with the problem.
double temps_courant() const
Returns the current time.
Base class for output streams.
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