TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Solveur_U_P.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 <Neumann_sortie_libre.h>
17#include <MD_Vector_composite.h>
18#include <Discretisation_base.h>
19#include <Matrice_Diagonale.h>
20#include <Navier_Stokes_std.h>
21#include <Schema_Temps_base.h>
22#include <Assembleur_base.h>
23#include <MD_Vector_tools.h>
24#include <TRUSTTab_parts.h>
25#include <Probleme_base.h>
26#include <MD_Vector_std.h>
27#include <Matrice_Bloc.h>
28#include <Solveur_U_P.h>
29#include <Dirichlet.h>
30#include <TRUSTTrav.h>
31#include <Front_VF.h>
32#include <EChaine.h>
33#include <Debog.h>
34
35Implemente_instanciable(Solveur_U_P,"Solveur_U_P",Simple);
36// XD solveur_u_p simple solveur_u_p BRACE similar to simple.
37
38
39Sortie& Solveur_U_P::printOn(Sortie& os ) const { return Simple::printOn(os); }
40
42
43//Input: Uk-1 ; Pk-1
44//Output: Uk ; Pk
45//k denotes an iteration
46void Solveur_U_P::iterer_NS(Equation_base& eqn,DoubleTab& current,DoubleTab& pression,double dt,Matrice_Morse& matrice_inut,double seuil_resol,DoubleTrav& secmem,int nb_ite,int& converge, int& ok)
47{
48 if (eqn.probleme().is_dilatable())
49 {
50 Cerr<<" Solveur_U_P cannot be used with a quasi-compressible fluid."<<finl;
51 Cerr<<__FILE__<<(int)__LINE__<<" non code" <<finl;
53 }
54
55 const bool is_PolyMAC_CDO = eqn.discretisation().is_PolyMAC_CDO();
57 SolveurSys& le_solveur_ = param.solveur();
58
59 Navier_Stokes_std& eqnNS = ref_cast(Navier_Stokes_std,eqn);
61
62 /* MD_Vector (vitesse, pression) */
63 MD_Vector md_UP;
65 DoubleTab_parts ppart(pression); //in PolyMAC_CDO, pression contains (p, v) -> the second part must be ignored...
66
67 mds.add_part(current.get_md_vector(), current.line_size());
68 if (is_PolyMAC_CDO)
69 mds.add_part(ppart[0].get_md_vector(), ppart[0].line_size());
70 else
71 mds.add_part(pression.get_md_vector(), pression.line_size());
72
73 md_UP.copy(mds);
74
75 DoubleTab Inconnues,residu;
78
79 DoubleTab_parts residu_parts(residu);
80 DoubleTab_parts Inconnues_parts(Inconnues);
81
82 Inconnues_parts[0] = current;
83 Inconnues_parts[1] = is_PolyMAC_CDO ? ppart[0] : pression;
84
85 Matrice_Bloc Matrice_global(2,2) ; //matrix M.(du, dp) = (Navier-Stokes, divergence)
86
87 /* Navier-Stokes row: N-S block, gradient block */
88 Matrice_global.get_bloc(0,0).typer("Matrice_Morse");
89 Matrice_Morse& matrice=ref_cast(Matrice_Morse, Matrice_global.get_bloc(0,0).valeur());
90 Matrice_global.get_bloc(0,1).typer("Matrice_Morse");
91 Matrice_Morse& mat_grad=ref_cast(Matrice_Morse, Matrice_global.get_bloc(0,1).valeur());
92
93 if (eqnNS.has_interface_blocs()) /* if interface_blocs: both can be filled at once */
94 {
95 eqnNS.dimensionner_blocs({{ "vitesse", &matrice }, { "pression", &mat_grad }});
96 eqnNS.assembler_blocs_avec_inertie({{ "vitesse", &matrice }, { "pression", &mat_grad }}, residu_parts[0]);
97 }
98 else /* otherwise: less elegant */
99 {
100 Operateur_Grad& gradient = eqnNS.operateur_gradient();
101
102 eqnNS.dimensionner_matrice(matrice);
103 eqnNS.assembler_avec_inertie(matrice,current,residu_parts[0]);
104 gradient->dimensionner( mat_grad);
105 gradient->contribuer_a_avec(pression, mat_grad);
106 mat_grad.get_set_coeff()*=-1;
107 /* to convert back to increments */
108 residu_parts[0]*=-1;
109 matrice.ajouter_multvect(current, residu_parts[0]);
110 gradient->ajouter(pression,residu_parts[0]);
111 residu_parts[0]*=-1;
112 }
113
114 if (is_PolyMAC_CDO)
115 {
116 /* ligne de masse : (div, 0) */
117 Operateur_Div& divergence = eqnNS.operateur_divergence();
118 Matrice_global.get_bloc(1,0).typer("Matrice_Morse");
119 Matrice_Morse& mat_div=ref_cast(Matrice_Morse, Matrice_global.get_bloc(1,0).valeur());
120 divergence->dimensionner(mat_div);
121 divergence->contribuer_a_avec( current,mat_div);
122 divergence.calculer(current, residu_parts[1]);
123
124 Matrice_global.get_bloc(1,1).typer("Matrice_Diagonale");
125 Matrice_Diagonale& mat_diag = ref_cast(Matrice_Diagonale,Matrice_global.get_bloc(1,1).valeur());
126 mat_diag.dimensionner(mat_div.nb_lignes());
127
128 /* doit-on fixer P(elem 0) = 0 ? */
129 int has_P_ref=0;
130 const Conds_lim& cls = eqnNS.domaine_Cl_dis().les_conditions_limites();
131 for (int n_bord=0; n_bord < cls.size(); n_bord++)
132 if (sub_type(Neumann_sortie_libre,cls[n_bord].valeur())) has_P_ref=1;
133
134 if (!has_P_ref && !Process::me()) mat_diag.coeff(0, 0) = 1; //revient a imposer P(0) = 0
135
136 //in PolyMAC_CDO, empty rows must be added to grad and empty columns to div
137 int n = matrice.get_tab1().size_array();
138 mat_grad.get_set_tab1().resize(n);
139 for (int i = mat_grad.get_tab1().size_array(); i < n; i++)
140 mat_grad.get_set_tab1()(i) = mat_grad.get_tab1()(i - 1);
141 mat_div.set_nb_columns(n - 1);
142
143 le_solveur_->reinit();
144 le_solveur_->resoudre_systeme(Matrice_global,residu,Inconnues);
145
146 //Compute Uk = U*_k + U'k
147 current += Inconnues_parts[0];
148 ppart[0] += Inconnues_parts[1];
149 //current.echange_espace_virtuel();
150 Debog::verifier("Solveur_U_P::iterer_NS current",current);
151 eqn.solv_masse().corriger_solution(current, current); //CoviMAC: enforce consistency between ve and vf
152 eqnNS.assembleur_pression()->modifier_solution(pression);
153
154 if (1)
155 {
156 divergence.calculer(current, secmem);
157 Cerr<<" afterdiv "<<mp_max_abs_vect(secmem)<<finl;;
158 }
159 }
160 else
161 {
162
163 /* should we fix P(elem 0) = 0? */
164 int has_P_ref=0;
165 const Conds_lim& cls = eqnNS.domaine_Cl_dis().les_conditions_limites();
166 for (int n_bord=0; n_bord < cls.size(); n_bord++)
167 if (sub_type(Neumann_sortie_libre,cls[n_bord].valeur())) has_P_ref=1;
168
169
170 /* ligne de masse : (div, 0) */
171 Operateur_Div_base& divergence = eqnNS.operateur_divergence().valeur();
172 Matrice_global.get_bloc(1,0).typer("Matrice_Morse");
173 Matrice_Morse& mat_div_v = ref_cast(Matrice_Morse, Matrice_global.get_bloc(1,0).valeur());
174 if (divergence.has_interface_blocs()) /* if interface_blocs: direct */
175 {
176 Matrice_global.get_bloc(1,1).typer("Matrice_Morse");
177 Matrice_Morse& mat_div_p = ref_cast(Matrice_Morse, Matrice_global.get_bloc(1,1).valeur());
178 divergence.dimensionner_blocs({ { "vitesse", &mat_div_v } , { "pression", &mat_div_p}});
179 divergence.ajouter_blocs({ { "vitesse", &mat_div_v } , { "pression", &mat_div_p}}, residu_parts[1]);
180 if (!has_P_ref && !Process::me()) mat_div_p(0, 0) += 1; //equivalent to imposing P(0) = 0
181 }
182 else /* otherwise: the operator fills mat_div_v, and mat_div_p = 0 is built manually */
183 {
184 divergence.dimensionner(mat_div_v);
185 divergence.contribuer_a_avec(current, mat_div_v);
186 divergence.calculer(current, residu_parts[1]);
187 Matrice_global.get_bloc(1,1).typer("Matrice_Diagonale");
188 Matrice_Diagonale& mat_div_p = ref_cast(Matrice_Diagonale,Matrice_global.get_bloc(1,1).valeur());
189 mat_div_p.dimensionner(mat_div_v.nb_lignes());
190 if (!has_P_ref && !Process::me()) mat_div_p.coeff(0, 0) += 1; //equivalent to imposing P(0) = 0
191 }
192 le_solveur_->reinit();
193 le_solveur_->resoudre_systeme(Matrice_global,residu,Inconnues);
194
195 //Compute Uk = U*_k + U'k
196 current += Inconnues_parts[0];
197 pression += Inconnues_parts[1];
198 //current.echange_espace_virtuel();
199 Debog::verifier("Solveur_U_P::iterer_NS current",current);
200 eqn.solv_masse().corriger_solution(current, current); //CoviMAC: enforce consistency between ve and vf
201 eqnNS.assembleur_pression()->modifier_solution(pression);
202
203 if (1)
204 {
205 // DoubleTrav secmem(current);
206 divergence.calculer(current, secmem);
207 Cerr<<" apresdiv "<<mp_max_abs_vect(secmem)<<finl;;
208 }
209 }
210}
class Conds_lim This class represents a vector of boundary conditions.
Definition Conds_lim.h:32
static void verifier(const char *const msg, double)
Definition Debog.cpp:21
virtual bool is_PolyMAC_CDO() const
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Equation_base The role of an equation is the calculation of one or more fields....
virtual void assembler_blocs_avec_inertie(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={})
const Discretisation_base & discretisation() const
Returns the discretization associated with the equation.
Solveur_Masse_base & solv_masse()
Returns the mass solver associated with the equation.
virtual void assembler_avec_inertie(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem)
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the discretized boundary condition domain associated with the equation.
Probleme_base & probleme()
Returns the problem associated with the equation.
virtual void dimensionner_matrice(Matrice_Morse &mat_morse)
Metadata for a distributed composite vector.
void add_part(const MD_Vector &part, int shape=0, Nom name="")
Append the "part" descriptor to the composite vector.
static void creer_tableau_distribue(const MD_Vector &, Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Transforms v into a parallel array having the structure md.
: This class is an OWN_PTR but the pointed object is shared among multiple
Definition MD_Vector.h:48
void copy(const MD_Vector_base &)
Constructs an MD_Vector object by copying an existing object.
Definition MD_Vector.cpp:26
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Matrix-vector multiply-accumulate operation (saxpy).
virtual const Matrice & get_bloc(int i, int j) const
Matrice_Diagonale class - Represents a diagonal matrix.
void dimensionner(int size)
double coeff(int i, int j) const
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
const auto & get_tab1() const
void set_nb_columns(const int)
auto & get_set_coeff()
auto & get_set_tab1()
int nb_lignes() const override
Return local number of lines (=size on the current proc).
Navier_Stokes_std This class carries the terms of the momentum equation.
Operateur_Div & operateur_divergence()
Returns the divergence operator associated with the equation.
Operateur_Grad & operateur_gradient()
Returns the gradient operator associated with the equation.
int has_interface_blocs() const override
void dimensionner_blocs(matrices_t matrices, const tabs_t &semi_impl={}) const override
void reassembler_pression_si_necessaire()
Neumann_sortie_libre This class represents an open boundary without imposed velocity.
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
Classe Operateur_Div_base This class is the base of the hierarchy of operators representing.
Operateur_Div Generic class of the hierarchy of operators computing the divergence.
Classe Operateur_Grad Generic class of the hierarchy of operators computing the gradient.
class Parametre_implicite A Parametre_implicite object groups together the various
bool is_dilatable() const
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
Definition Process.cpp:122
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
class SolveurSys A SolveurSys represents any class
Definition SolveurSys.h:32
int resoudre_systeme(const Matrice_Base &matrice, const DoubleVect &secmem, DoubleVect &solution)
Parametre_implicite & get_and_set_parametre_implicite(Equation_base &eqn)
virtual DoubleTab & corriger_solution(DoubleTab &x, const DoubleTab &y, int incr=0) const
void iterer_NS(Equation_base &, DoubleTab &current, DoubleTab &pression, double, Matrice_Morse &, double, DoubleTrav &, int nb_iter, int &converge, int &ok) override
Base class for output streams.
Definition Sortie.h:52
int line_size() const
Definition TRUSTVect.tpp:67
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123