TrioCFD 1.9.8
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//Entree : Uk-1 ; Pk-1
44//Sortie Uk ; Pk
45//k designe une 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); //dans PolyMAC_CDO, pression contient (p, v) -> on doit ignorer la 2e partie...
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) ; //matrice M.(du, dp) = (Navier-Stokes, divergence)
86
87 /* ligne Navier-Stokes : blocs N-S, bloc gradient */
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()) /* si interface_blocs : on peut remplir les deux d'un coup */
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 /* sinon : moins 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 /* pour repasser en 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 //en PolyMAC_CDO, on doit ajouter des lignes vides a grad et des colonnes vides a 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 //Calcul de 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 : mise en coherence de ve avec vf
152 eqnNS.assembleur_pression()->modifier_solution(pression);
153
154 if (1)
155 {
156 divergence.calculer(current, secmem);
157 Cerr<<" apresdiv "<<mp_max_abs_vect(secmem)<<finl;;
158 }
159 }
160 else
161 {
162
163 /* doit-on fixer 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()) /* si 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; //revient a imposer P(0) = 0
181 }
182 else /* sinon : l'operateur remplit mat_div_v, on construit a la main mat_div_p = 0 */
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; //revient a imposer P(0) = 0
191 }
192 le_solveur_->reinit();
193 le_solveur_->resoudre_systeme(Matrice_global,residu,Inconnues);
194
195 //Calcul de 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 : mise en coherence de ve avec 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}
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
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
Renvoie la i-ieme condition aux limites.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual void assembler_blocs_avec_inertie(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={})
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
Solveur_Masse_base & solv_masse()
Renvoie le solveur de masse associe a l'equation.
virtual void assembler_avec_inertie(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem)
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Probleme_base & probleme()
Renvoie le probleme associe a l'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)
transforme v en un tableau parallele ayant la structure md.
: Cette classe est un OWN_PTR mais l'objet pointe est partage entre plusieurs
Definition MD_Vector.h:48
void copy(const MD_Vector_base &)
construction d'un objet MD_Vector par copie d'un objet existant.
Definition MD_Vector.cpp:26
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Operation de multiplication-accumulation (saxpy) matrice vecteur.
virtual const Matrice & get_bloc(int i, int j) const
Classe Matrice_Diagonale Represente une matrice diagonale.
void dimensionner(int size)
double coeff(int i, int j) const
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
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).
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
Operateur_Div & operateur_divergence()
Renvoie l'operateur de calcul de la divergence associe a l'equation.
Operateur_Grad & operateur_gradient()
Renvoie l'operateur de calcul du gradient associe a l'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()
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
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
Classe Operateur_Div_base Cette classe est la base de la hierarchie des operateurs representant.
classe Operateur_Div Classe generique de la hierarchie des operateurs calculant la divergence
Classe Operateur_Grad Classe generique de la hierarchie des operateurs calculant le gradient.
classe Parametre_implicite Un objet Parametre_implicite est un objet regroupant les differentes
bool is_dilatable() const
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
class SolveurSys Un SolveurSys represente n'importe qu'elle classe
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
Classe de base des flux de sortie.
Definition Sortie.h:52
int line_size() const
Definition TRUSTVect.tpp:67
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123