TrioCFD 1.9.9_beta
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 << "The number of groups N must be specified before lambda in " << 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 << "The number of groups N must be specified before beta in " << 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 << "The keyword " << mot << " is not understood in " << que_suis_je() << finl;
106 exit();
107 }
108 }
109 else if (mot=="rho")
110 {
111 Nom tmp;
112 is >> tmp;
113 Cerr << "Reading reactivity " << 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 << "The number of groups N must be specified before the initial Ci values in " << 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 * Returns the string representing the spatial distribution function f(x,y,z) of the power.
154 */
156{
157 return f_xyz;
158}
159
160/**
161 * Returns the name of the sub-domain where power is released.
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 * Computes resu = m*v.
197 */
198void Source_Neutronique::mul(DoubleTab& m, DoubleVect& v, DoubleVect& resu)
199{
200 resu = 0.;
201 resu(0) = m(0,0)*v(0);
202 for (int i=1; i<N+1; i++)
203 {
204 resu(0)+= m(0,i)*v(i);
205 resu(i) = m(i,0)*v(0) + m(i,i)*v(i);
206 }
207}
208
209
210/**
211 * Classical Runge-Kutta scheme.
212 */
214{
215 static const double a1 = 1./6.;
216 static const double a2 = 1./3.;
217
218 DoubleVect fn1(Un);
219 DoubleVect fn2(Un);
220 DoubleVect fn3(Un);
221 DoubleVect fn4(Un);
222 const double dt2 = dt/2.;
223
224 // Un1 = Un+dt/2*f(tn,un)
225 mul(matA,Un, fn1);
226 Unp1 = Un;
227 Unp1.ajoute(dt2, fn1);
228
229 // Un2 = Un+dt/2*f(tn+dt/2,Un1)
230 mettre_a_jour_matA(temps_courant+dt2);
231
232 mul(matA,Unp1, fn2);
233 Unp1 = Un;
234 Unp1.ajoute(dt2, fn2);
235
236 // Un3 = Un+dt*f(tn+dt/2,Un2)
237 mul(matA,Unp1, fn3);
238 Unp1 = Un;
239 Unp1.ajoute(dt, fn3);
240
241 // 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))
242 mettre_a_jour_matA(temps_courant+dt);
243 mul(matA,Unp1, fn4);
244 Unp1 = Un;
245 Unp1.ajoute(a1*dt, fn4);
246 Unp1.ajoute(a2*dt, fn3);
247 Unp1.ajoute(a2*dt, fn2);
248 Unp1.ajoute(a1*dt, fn1);
249}
250
251
252/**
253 * Updates the coefficients of matrix A.
254 */
255void Source_Neutronique::mettre_a_jour_matA(double temps)
256{
257 matA(0,0) = beta_som/Tvie*(rho(temps,Tmoy)-1);
258}
259
260
261
262/**
263 * Explicit Euler scheme.
264 */
266{
267 mul(matA,Un, Unp1);
268 Unp1*=dt;
269 Unp1 += Un;
270 /* Cout << "matA " << matA << finl;
271 Cout << "Un " << Un << finl;
272 Cout << "Unp1 " << Unp1 << finl;
273 */
274}
275
276/**
277 * Advances in time using the stability time step specific to the equation.
278 */
280{
281 while (temps_courant<temps)
282 {
283 const double dt_stab = 0.8*Tvie/beta_som*std::max(std::fabs(rho(temps_courant,Tmoy)-1),1.);
284 dt = std::min(dt_stab, temps-temps_courant);
285 (this->*faire_un_pas_de_temps)();
286 Un = Unp1;
287 temps_courant += dt;
288 mettre_a_jour_matA(temps_courant);
289 if (limpr(temps_courant,dt)) imprimer(temps_courant);
290 }
291
292}
293
294/**
295 * Prints results to the file puissances.dat.
296 */
297void Source_Neutronique::imprimer(double temps) const
298{
299
300 SFichier fic("puissances.dat",ios::app);
301 fic << temps ;
302 for (int i =0; i<N+1; i++)
303 {
304 fic << " " << Un(i);
305 }
306 fic << finl;
307
308 /*Cout << "Printing time step for the point kinetics equation" << finl;
309 Cout << ">>>> Time step used dt = " << dt << finl;
310 Cout << ">>>> Stability time step dt_stab = " << dt_stab << finl;
311 */
312}
313
314int Source_Neutronique::limpr(double le_temps_courant,double ddt) const
315{
316 static const double epsilon = 1.e-9;
317 const Schema_Temps_base& sch = mon_equation->schema_temps();
318 // If printing at every time step when not requested, behave like limpr() in Echange_contact_Correlation_VDF.cpp
319 if (sch.nb_pas_dt()==0)
320 return 0;
321 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))
322 return 1;
323 else
324 {
325 // See Schema_Temps_base::limpr for information on epsilon and modf
326 double i, j;
327 modf(le_temps_courant/dt_impr + epsilon, &i);
328 modf((le_temps_courant-ddt)/dt_impr + epsilon, &j);
329 return ( i>j );
330 }
331}
332
334{
335 if (init)
336 {
337 init = 0;
338 Tmoy = calculer_Tmoyenne();
339 temps_courant = temps;
340 mettre_a_jour_matA(temps);
341 la_puissance->valeurs()(0) = Un(0);
342 }
343 else
344 {
345 Tmoy = calculer_Tmoyenne();
346 aller_au_temps(temps);
347 temps_courant = temps;
348 la_puissance->valeurs()(0) = Un(0);
349 }
350}
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
A character string (Nom) in uppercase.
Definition Motcle.h:26
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
friend class Entree
Definition Objet_U.h:71
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
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)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
Definition SFichier.h:29
class Schema_Temps_base
int nb_pas_dt_max_atteint() const
Returns 1 if (the number of time steps >= maximum number of time steps).
int temps_final_atteint() const
Returns 1 if the final time has been reached (or exceeded).
int nb_pas_dt() const
Returns the number of time steps performed.
int stationnaire_atteint() const
Base class for output streams.
Definition Sortie.h:52
class Source_Neutronique
void completer() override
Updates internal references of the Source_base object.
const Nom & nom_ssz() const
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
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)
Source_base A Source_base object is a term appearing on the right-hand side of an.
Definition Source_base.h:42
virtual void completer()
Updates internal references of the Source_base object.