TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Integrer_champ_med.cpp
1/****************************************************************************
2* Copyright (c) 2025, 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 <Integrer_champ_med.h>
17#include <Param.h>
18#include <Champ_Fonc_MED.h>
19#include <SFichier.h>
20
21Implemente_instanciable(Integrer_champ_med,"Integrer_champ_med",Interprete);
22// XD integrer_champ_med interprete integrer_champ_med BRACE his keyword is used to calculate a flow rate from a
23// XD_CONT velocity MED field read before. The method is either debit_total to calculate the flow rate on the whole
24// XD_CONT surface, either integrale_en_z to calculate flow rates between z=zmin and z=zmax on nb_tranche surfaces. The
25// XD_CONT output file indicates first the flow rate for the whole surface and then lists for each tranche : the height
26// XD_CONT z, the surface average value, the surface area and the flow rate. For the debit_total method, only one
27// XD_CONT tranche is considered.NL2 file :z Sum(u.dS)/Sum(dS) Sum(dS) Sum(u.dS)
28
29/*! @brief Simple appel a: Interprete::printOn(Sortie&)
30 *
31 * @param (Sortie& os) un flot de sortie
32 * @return (Sortie&) le flot de sortie modifie
33 */
35{
36 return Interprete::printOn(os);
37}
38
39/*! @brief Simple appel a: Interprete::readOn(Entree&)
40 *
41 * @param (Entree& is) un flot d'entree
42 * @return (Entree&) le flot d'entree modifie
43 */
45{
46 return Interprete::readOn(is);
47}
48
49void calcul_normal_norme(const ArrOfDouble& org,const ArrOfDouble& point1, const ArrOfDouble& point2,ArrOfDouble& normal);
50double calcul_surface_triangle(const ArrOfDouble& origine,const ArrOfDouble& point1, const ArrOfDouble& point2)
51{
52 double normal0=(point1[1]-origine[1])*(point2[2]-origine[2])-((point2[1]-origine[1])*(point1[2]-origine[2]));
53
54 double normal1=(point1[2]-origine[2])*(point2[0]-origine[0])-((point2[2]-origine[2])*(point1[0]-origine[0]));
55 double normal2=(point1[0]-origine[0])*(point2[1]-origine[1])-((point2[0]-origine[0])*(point1[1]-origine[1]));
56 double res=normal0*normal0+ normal1*normal1 + normal2*normal2 ;
57
58 return sqrt(res)/2.;
59}
60
61double portion_surface_elem(const ArrOfDouble& pointA,const ArrOfDouble& pointB, const ArrOfDouble& pointC,const double z)
62{
63 if (z<=pointA[2]) return 0;
64 if (z>pointC[2]) return calcul_surface_triangle(pointA,pointB,pointC);
65 ArrOfDouble pointD(3);
66 // le point D est sur AC a hauteur de B.
67 pointD[2]=pointB[2];
68 double lambda=(pointB[2]-pointA[2])/(pointC[2]-pointA[2]);
69 for (int i=0; i<2; i++)
70 pointD[i]=pointA[i]+lambda*(pointC[i]-pointA[i]);
71 if (z<=pointB[2])
72 {
73 // on calcul la surface du triangle inferieur
74 // et on prend la proportion...
75 double surf_inf=calcul_surface_triangle(pointA,pointB,pointD);
76 double rap=1;
77 if (pointB[2]!=pointA[2])
78 rap=(z-pointA[2])/(pointB[2]-pointA[2]);
79 return surf_inf*rap*rap;
80 }
81 else
82 {
83 // on calcul la surface du triangle inferieur
84 // et on prend la proportion...
85 // et on retire a la surface totale
86 double surf_sup=calcul_surface_triangle(pointB,pointD,pointC);
87 double rap=(z-pointC[2])/(pointB[2]-pointC[2]);
88 double surf_tot=calcul_surface_triangle(pointA,pointB,pointC);
89 return surf_tot-surf_sup*rap*rap;
90 }
91
92}
93
94double portion_surface(const ArrOfDouble& point0,const ArrOfDouble& point1, const ArrOfDouble& point2,const double zmin,const double zmax)
95{
96 return portion_surface_elem(point0,point1,point2,zmax)- portion_surface_elem(point0,point1,point2,zmin);
97}
98
99/*! @brief Fonction principale de l'interprete.
100 *
101 * @param (Entree& is) un flot d'entree
102 * @return (Entree&) le flot d'entree
103 */
105{
106 Motcle nom_methode;
107 Nom nom_fichier("integrale");
108 Nom nom_champ_fonc_med;
109
110 double zmin=0,zmax=0;
111 int nb_tranche=1;
112 Param param(que_suis_je());
113
114 param.ajouter("champ_med",&nom_champ_fonc_med,Param::REQUIRED); // XD attr champ_med ref_champ_fonc_med champ_med REQ not_set
115 param.ajouter("methode",&nom_methode,Param::REQUIRED); // XD attr methode chaine(into=["integrale_en_z","debit_total"]) methode REQ to choose between the integral following z or over the entire height (debit_total corresponds to zmin=-DMAXFLOAT, ZMax=DMAXFLOAT, nb_tranche=1)
116 param.ajouter("zmin",&zmin); // XD attr zmin floattant zmin OPT not_set
117 param.ajouter("zmax",&zmax); // XD attr zmax floattant zmax OPT not_set
118 param.ajouter("nb_tranche",&nb_tranche); // XD attr nb_tranche entier nb_tranche OPT not_set
119 param.ajouter("fichier_sortie",&nom_fichier); // XD attr fichier_sortie chaine fichier_sortie OPT name of the output
120 // XD_CONT file, by default: integrale.
122 if ((nom_methode!="integrale_en_z")&&(nom_methode!="debit_total"))
123 {
124 Cerr<<"method "<<nom_methode <<" not coded yet "<<finl;
125 }
126 // on recupere le domaine
127 if(! sub_type(Champ_Fonc_MED, objet(nom_champ_fonc_med)))
128 {
129 Cerr << nom_champ_fonc_med << " type is " << objet(nom_champ_fonc_med).que_suis_je() << finl;
130 Cerr << "only the objects of type Champ_Fonc_MED can be meshed" << finl;
131 exit();
132 }
133 Champ_Fonc_MED& champ=ref_cast(Champ_Fonc_MED, objet(nom_champ_fonc_med));
134 const Domaine& domaine=champ.domaine_dis_base().domaine();
135 const DoubleTab& coord=domaine.les_sommets();
136 // on fait une coie pour les modifier
137 IntTab les_elems_mod=domaine.les_elems();
138 const IntTab& les_elems=domaine.les_elems();
139
140 ArrOfDouble normal(3);
141
142
143 const DoubleTab& valeurs= champ.valeurs();
144 assert(valeurs.dimension(0)==domaine.nb_elem());
145 assert(valeurs.dimension(1)==3);
146 double dz=(zmax-zmin)/nb_tranche;
147 ArrOfDouble res(nb_tranche),pos(nb_tranche),surface(nb_tranche);
148 int nb_elem=les_elems.dimension(0);
149 Cerr<<" Field integration using the method "<<nom_methode<<" on the domain "<<domaine.le_nom() <<finl;
150 if (nom_methode=="debit_total")
151 {
152 nb_tranche=1;
153 zmax=DMAXFLOAT/2.;
154 zmin=-zmax;
155 dz=(zmax-zmin);
156 pos[0]=0;
157
158 }
159 //if (nom_methode=="integrale_en_z")
160 {
161 // Etape 1 on reordonne les triangles pour classeren z les sommets
162
163 for (int elem=0; elem<nb_elem; elem++)
164 {
165 ArrOfInt zz(3);
166 for (int i=0; i<3; i++)
167 zz[i] = les_elems(elem,i);
168 std::sort(zz.begin(), zz.end(), [&](int a, int b)
169 {
170 return (coord(a,2)<coord(b,2));
171 });
172 for (int i=0; i<3; i++)
173 {
174 int ss=zz[i];
175 les_elems_mod(elem,i)=ss;
176 }
177 }
178
179 ArrOfDouble point0(3),point1(3),point2(3);
180 for (int elem=0; elem<nb_elem; elem++)
181 {
182
183 for (int i=0; i<3; i++)
184 {
185 point0[i]=coord(les_elems(elem,0),i);
186 point1[i]=coord(les_elems(elem,1),i);
187 point2[i]=coord(les_elems(elem,2),i);
188 }
189 calcul_normal_norme(point0,point1, point2, normal);
190 for (int i=0; i<3; i++)
191 {
192 point0[i]=coord(les_elems_mod(elem,0),i);
193 point1[i]=coord(les_elems_mod(elem,1),i);
194 point2[i]=coord(les_elems_mod(elem,2),i);
195 }
196 for (int tranche=0; tranche<nb_tranche; tranche++)
197 {
198
199 double zminl=(zmin)+(zmax-zmin)/nb_tranche*tranche;
200 double zmaxl=zminl+dz;
201 pos[tranche]=(zminl+zmaxl)/2.;
202 double z0=coord(les_elems_mod(elem,0),2);
203 if (z0<=zmaxl)
204 {
205
206 double z2=coord(les_elems_mod(elem,2),2);
207 if (z2>=zminl)
208 {
209
210
211 double portion=portion_surface(point0,point1,point2,zminl,zmaxl);
212 double prod_scal=0;
213
214 for (int i=0; i<3; i++)
215 prod_scal+=valeurs(elem,i)*normal[i];
216 res[tranche]+=portion*prod_scal;
217 surface[tranche]+=portion;
218 }
219 }
220
221 }
222 }
223 }
224
225 double trace=0;
226 SFichier so(nom_fichier);
227 for (int nb=0; nb<nb_tranche; nb++)
228 {
229 trace+=res[nb];
230 if (surface[nb]!=0)
231 res[nb]/=surface[nb];
232 else assert(res[nb]==0);
233 }
234 Cout<<"# overall balance "<<trace<<finl;
235 so<<"# bilan global "<<trace<<finl;
236 so<<"# position, valeur moyenne, surface, flux"<<finl;
237 for (int nb=0; nb<nb_tranche; nb++)
238 so << pos[nb]<<" "<<res[nb]<<" "<<surface[nb]<<" "<<res[nb]*surface[nb]<<finl;
239
240 return is;
241
242}
243
244
245
246
247
classe Champ_Fonc_MED Load a field from a MED file for a given time.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Classe Integrer_champ_med Lecture d'un fichier.
Entree & interpreter(Entree &) override
Fonction principale de l'interprete.
Classe de base des objets "interprete".
Definition Interprete.h:38
static Objet_U & objet(const Nom &)
Voir Interprete_bloc::objet_global() BM: la classe Interprete n'est pas le meilleur endroit pour cett...
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const Nom & le_nom() const override
Renvoie *this;.
Definition Nom.cpp:563
friend class Entree
Definition Objet_U.h:76
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
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
@ REQUIRED
Definition Param.h:115
int lire_avec_accolades_depuis(Entree &is)
Parse the parameter block { ... } from is.
Definition Param.cpp:32
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
Classe de base des flux de sortie.
Definition Sortie.h:52
Iterator_ end()
Definition TRUSTArray.h:112
Iterator_ begin()
Definition TRUSTArray.h:111
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133