TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Source_Neutronique.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 <Source_Neutronique.h>
17#include <Probleme_base.h>
18#include <Milieu_base.h>
19#include <Champ_Uniforme.h>
20#include <Equation_base.h>
21#include <Schema_Temps_base.h>
22#include <EChaine.h>
23#include <Motcle.h>
24#include <SFichier.h>
25#include <Param.h>
26
27Implemente_base(Source_Neutronique,"Source_Neutronique",Source_base);
28
30{
31 return s << que_suis_je() ;
32}
33
35{
36 Param param(que_suis_je());
37 EChaine ec("Champ_Uniforme 1 1");
38 ec >> la_puissance;
39 f_xyz = "1.";
40 n_ssz="defaut";
41 faire_un_pas_de_temps = &Source_Neutronique::faire_un_pas_de_temps_RK;
42 set_param(param);
43 param.lire_avec_accolades_depuis(is);
44 return is;
45}
46
48{
49 param.ajouter("N",&N,Param::REQUIRED);
50 param.ajouter_non_std("lambda",(this));
51 param.ajouter("Tvie",&Tvie);
52 param.ajouter("beta",&beta);
53 param.ajouter("P0",&P0);
54 param.ajouter("dt_impr",&dt_impr);
55 param.ajouter_non_std("schema_temps",(this));
56 param.ajouter_non_std("rho",(this));
57 param.ajouter_non_std("repartition",(this));
58 param.ajouter_non_std("Ci0",(this));
59}
60
62{
63 int retval = 1;
64
65 if (mot=="lambda")
66 {
67 if (N<1)
68 {
69 Cerr << "Il faut rentrer le nb de groupes N avant lambda dans " << que_suis_je() << finl;
70 exit();
71 }
72 lambda.resize(N);
73 for (int i=0; i<N; i++) is>>lambda(i);
74 }
75 else if (mot=="beta")
76 {
77 if (N<1)
78 {
79 Cerr << "Il faut rentrer le nb de groupes N avant beta dans " << que_suis_je() << finl;
80 exit();
81
82 }
83 beta.resize(N);
84 beta_som=0.;
85 for (int i=0; i<N; i++)
86 {
87 is>>beta(i);
88 beta_som+=beta(i);
89 }
90 }
91 else if (mot=="schema_temps")
92 {
93 Motcle nom_sch;
94 is >> nom_sch;
95 if (nom_sch == "euler_explicite")
96 {
97 faire_un_pas_de_temps = &Source_Neutronique::faire_un_pas_de_temps_EE;
98 }
99 else if (nom_sch == "runge_kutta")
100 {
101 faire_un_pas_de_temps = &Source_Neutronique::faire_un_pas_de_temps_RK;
102 }
103 else
104 {
105 Cerr << "On ne comprend le mot : " << mot << "dans " << que_suis_je() << finl;
106 exit();
107 }
108 }
109 else if (mot=="rho")
110 {
111 Nom tmp;
112 is >> tmp;
113 Cerr << "Lecture de la reactivite " << tmp << finl;
114 fct_tT.setNbVar(2);
115 fct_tT.setString(tmp);
116 fct_tT.addVar("t");
117 fct_tT.addVar("T");
118 fct_tT.parseString();
119 }
120 else if (mot=="repartition")
121 {
122 is >> f_xyz;
123 is >> n_ssz;
124 }
125 else if (mot=="Ci0")
126 {
127 if (N<1)
128 {
129 Cerr << "Il faut rentrer le nb de groupes N avant les Ci initiaux dans " << que_suis_je() << finl;
130 exit();
131 }
132 Ci0_ok = 1;
133 Ci0.resize(N);
134 for (int i=0; i<N; i++)
135 {
136 is>>Ci0(i);
137 }
138 }
139 else retval = -1;
140
141 return retval;
142}
143
144double Source_Neutronique::rho(double t, double T)
145{
146 fct_tT.setVar("t",t);
147 fct_tT.setVar("T",T);
148 return fct_tT.eval();
149}
150
151
152/**
153 * Renvoie la chaine de caracere representant la fonction de repartition f(x,y,z) de la puissance
154 */
156{
157 return f_xyz;
158}
159
160/**
161 * Renvoie le nom de la sous domaine de degagement de puissance
162 */
164{
165 return n_ssz;
166}
167
168
170{
171
173
174
175 Un.resize(N+1);
176 Unp1.resize(N+1);
177 matA.resize(N+1,N+1);
178 matA = 0.;
179 for (int i=1; i<N+1; i++)
180 {
181 matA(0,i) = lambda(i-1);
182 matA(i,i) = -lambda(i-1);
183 matA(i,0) = beta(i-1)/Tvie;
184 }
185 Un(0) = P0;
186 if (Ci0_ok == 0)
187 for (int i=1; i<N+1; i++)
188 Un(i) = beta(i-1)*Un(0)/Tvie/lambda(i-1);
189 else
190 for (int i=1; i<N+1; i++)
191 Un(i) = Ci0(i-1);
192}
193
194
195/**
196 * Effectue resu = m*v
197 */void Source_Neutronique::mul(DoubleTab& m, DoubleVect& v, DoubleVect& resu)
198{
199 resu = 0.;
200 resu(0) = m(0,0)*v(0);
201 for (int i=1; i<N+1; i++)
202 {
203 resu(0)+= m(0,i)*v(i);
204 resu(i) = m(i,0)*v(0) + m(i,i)*v(i);
205 }
206}
207
208
209/**
210 * Schema de Runge Kutta classique
211 */
213{
214 static const double a1 = 1./6.;
215 static const double a2 = 1./3.;
216
217 DoubleVect fn1(Un);
218 DoubleVect fn2(Un);
219 DoubleVect fn3(Un);
220 DoubleVect fn4(Un);
221 const double dt2 = dt/2.;
222
223 // Un1 = Un+dt/2*f(tn,un)
224 mul(matA,Un, fn1);
225 Unp1 = Un;
226 Unp1.ajoute(dt2, fn1);
227
228 // Un2 = Un+dt/2*f(tn+dt/2,Un1)
229 mettre_a_jour_matA(temps_courant+dt2);
230
231 mul(matA,Unp1, fn2);
232 Unp1 = Un;
233 Unp1.ajoute(dt2, fn2);
234
235 // Un3 = Un+dt*f(tn+dt/2,Un2)
236 mul(matA,Unp1, fn3);
237 Unp1 = Un;
238 Unp1.ajoute(dt, fn3);
239
240 // Un+1 = Un+dt*(a1*f(tn,un) + a2*f(tn+dt/2,Un1) + a2*f(tn+dt/2,Un2) + a1*f(tn+dt/2,Un3))
241 mettre_a_jour_matA(temps_courant+dt);
242 mul(matA,Unp1, fn4);
243 Unp1 = Un;
244 Unp1.ajoute(a1*dt, fn4);
245 Unp1.ajoute(a2*dt, fn3);
246 Unp1.ajoute(a2*dt, fn2);
247 Unp1.ajoute(a1*dt, fn1);
248}
249
250
251/**
252 * Met a jour les coefficients de la matrice A
253 */
254void Source_Neutronique::mettre_a_jour_matA(double temps)
255{
256 matA(0,0) = beta_som/Tvie*(rho(temps,Tmoy)-1);
257}
258
259
260
261/**
262 * Schema Euler explicite
263 */
265{
266 mul(matA,Un, Unp1);
267 Unp1*=dt;
268 Unp1 += Un;
269 /* Cout << "matA " << matA << finl;
270 Cout << "Un " << Un << finl;
271 Cout << "Unp1 " << Unp1 << finl;
272 */
273}
274
275/**
276 * Aller_au_temps : permet d'avancer avec le pas de temps de stabilite propre de l'equation.
277 */
279{
280 while (temps_courant<temps)
281 {
282 const double dt_stab = 0.8*Tvie/beta_som*std::max(std::fabs(rho(temps_courant,Tmoy)-1),1.);
283 dt = std::min(dt_stab, temps-temps_courant);
284 (this->*faire_un_pas_de_temps)();
285 Un = Unp1;
286 temps_courant += dt;
287 mettre_a_jour_matA(temps_courant);
288 if (limpr(temps_courant,dt)) imprimer(temps_courant);
289 }
290
291}
292
293/**
294 * Imprime les resultats dans le fichier puissance.dat
295 */
296void Source_Neutronique::imprimer(double temps) const
297{
298
299 SFichier fic("puissances.dat",ios::app);
300 fic << temps ;
301 for (int i =0; i<N+1; i++)
302 {
303 fic << " " << Un(i);
304 }
305 fic << finl;
306
307 /*Cout << "Impression du pas de temps pour l'equation de la cinetique point " << finl;
308 Cout << ">>>> Pas de temps utilise dt = " << dt << finl;
309 Cout << ">>>> Pas de temps de stabilite dt_stab = " << dt_stab << finl;
310 */
311}
312
313int Source_Neutronique::limpr(double le_temps_courant,double ddt) const
314{
315 static const double epsilon = 1.e-9;
316 const Schema_Temps_base& sch = mon_equation->schema_temps();
317 // Si impression a chaque pas de temps, alors que pas demande, faire comme limpr() de Echange_contact_Correlation_VDF.cpp
318 if (sch.nb_pas_dt()==0)
319 return 0;
320 if (dt_impr<=ddt || ((sch.temps_final_atteint() || sch.nb_pas_dt_max_atteint() || sch.nb_pas_dt()<=1 || sch.stationnaire_atteint()) && dt_impr!=1e10))
321 return 1;
322 else
323 {
324 // Voir Schema_Temps_base::limpr pour information sur epsilon et modf
325 double i, j;
326 modf(le_temps_courant/dt_impr + epsilon, &i);
327 modf((le_temps_courant-ddt)/dt_impr + epsilon, &j);
328 return ( i>j );
329 }
330}
331
333{
334 if (init)
335 {
336 init = 0;
337 Tmoy = calculer_Tmoyenne();
338 temps_courant = temps;
339 mettre_a_jour_matA(temps);
340 la_puissance->valeurs()(0) = Un(0);
341 }
342 else
343 {
344 Tmoy = calculer_Tmoyenne();
345 aller_au_temps(temps);
346 temps_courant = temps;
347 la_puissance->valeurs()(0) = Un(0);
348 }
349}
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
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
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
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Definition Param.cpp:489
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
class Schema_Temps_base
int nb_pas_dt_max_atteint() const
Renvoie 1 si (le nombre de pas de temps >= nombre de pas de temps maximum).
int temps_final_atteint() const
Renvoie 1 si le temps final est atteint (ou depasse).
int nb_pas_dt() const
Renvoie le nombre de pas de temps effectues.
int stationnaire_atteint() const
Classe de base des flux de sortie.
Definition Sortie.h:52
class Source_Neutronique
void completer() override
Met a jour les references internes a l'objet Source_base.
const Nom & nom_ssz() const
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
virtual double calculer_Tmoyenne()=0
virtual int limpr(double, double) const
void mettre_a_jour(double temps) override
DOES NOTHING - to override in derived classes.
virtual void imprimer(double) const
const Nom & repartition() const
void set_param(Param &param) const override
double rho(double, double)
classe Source_base Un objet Source_base est un terme apparaissant au second membre d'une
Definition Source_base.h:42
virtual void completer()
Met a jour les references internes a l'objet Source_base.