TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
PrecondA.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 <Matrice_Morse_Sym.h>
17#include <Matrice_Bloc_Sym.h>
18#include <TRUSTTab_parts.h>
19#include <PrecondA.h>
20#include <Motcle.h>
21#include <Param.h>
22
23Implemente_instanciable(PrecondA,"ssor_bloc",Precond_base);
24// XD ssor_bloc precond_base ssor_bloc INHERITS_BRACE not_set
25
27{
28 return s;
29}
30
32{
33 Param param(que_suis_je());
34 set_param(param);
35 param.lire_avec_accolades_depuis(is);
36 return is;
37}
38
39void PrecondA::set_param(Param& param) const
40{
41 param.ajouter("precond0",&le_precond_0); // XD attr precond0 precond_base precond0 OPT not_set
42 param.ajouter("precond1",&le_precond_1); // XD attr precond1 precond_base precond1 OPT not_set
43 param.ajouter("preconda",&le_precond_a); // XD attr preconda precond_base preconda OPT not_set
44 param.ajouter("alpha_0",&alpha_0); // XD attr alpha_0 floattant alpha_0 OPT not_set
45 param.ajouter("alpha_1",&alpha_1); // XD attr alpha_1 floattant alpha_1 OPT not_set
46 param.ajouter("alpha_a",&alpha_a); // XD attr alpha_a floattant alpha_a OPT not_set
47}
48
49static void prepare_precond(OWN_PTR(Precond_base)& p, const Matrice_Base& m, const DoubleVect& v,
51{
52 if (p)
53 {
54 Precond_base& pp = p.valeur();
55 pp.reinit(status);
56 pp.prepare(m, v);
57 }
58}
59
60void PrecondA::prepare_(const Matrice_Base& m, const DoubleVect& v)
61{
62 Init_Status status = get_status();
63 const Matrice_Bloc_Sym& matbloc = ref_cast(Matrice_Bloc_Sym, m);
64 ConstDoubleTab_parts parts(v);
65 prepare_precond(le_precond_0, matbloc.get_bloc(0,0), parts[0], status);
66 prepare_precond(le_precond_1, matbloc.get_bloc(1,1), parts[1], status);
67 if (parts.size() > 2)
68 prepare_precond(le_precond_a, matbloc.get_bloc(2,2), parts[2], status);
70}
71
72/*! @brief Calcule la solution du systeme lineaire: A * solution = b avec la methode de relaxation PrecondA.
73 *
74 */
76 const DoubleVect& b,
77 DoubleVect& solution)
78{
79
80 double pscb = mp_prodscal(b, b);
81
82 if(pscb<1.e-24)
83 {
84 solution=b;
85 return 1;
86 }
87 // On calcule solution = inverse(C)*b avec:
88 // inverse(C) = inverse((1/w D - E)) *(2-w/w D) * inverse((1/wD -E)t)
89 // D :partie diagonale des blocs de la matrice
90 // E :partie triangulaire inferieure des blocs de la matrice
91 const Matrice_Bloc_Sym& matbloc=ref_cast(Matrice_Bloc_Sym, matrice);
92 if (matbloc.nb_bloc_lignes()<2
93 || matbloc.nb_bloc_colonnes()<2
94 || matbloc.nb_bloc_lignes()!=matbloc.nb_bloc_colonnes())
95 {
96 Cerr << "The preconditioning SSOR_BLOC can be used only for symetric block matrixes" << finl;
97 Cerr << "containing at least 2*2 blocs. For example, when considering the following VEF discretizations :"<< finl;
98 Cerr << "P0+P1 or P0+Pa or P0+P1+Pa." << finl;
99 exit();
100 }
101 int nblocs=matbloc.nb_bloc_lignes();
102 const Matrice_Base& A00=matbloc.get_bloc(0,0);
103 const Matrice_Base& A01=matbloc.get_bloc(0,1);
104 const Matrice_Base& A11=matbloc.get_bloc(1,1);
105 const Matrice_Base& A0a=matbloc.get_bloc(0,nblocs-1);
106 const Matrice_Base& A1a=matbloc.get_bloc(1,nblocs-1);
107 const Matrice_Base& Aaa=matbloc.get_bloc(nblocs-1,nblocs-1);
108 DoubleTab_parts parties(solution);
109 DoubleVect& X0 = parties[0];
110 DoubleVect& X1 = parties[1];
111 DoubleVect& Xa = parties[parties.size() - 1];
112
113 DoubleVect F(b);
114 DoubleTab_parts parties_f(F);
115 DoubleVect& Y0 = parties_f[0];
116 DoubleVect& Y1 = parties_f[1];
117 DoubleVect& Ya = parties_f[parties_f.size() - 1];
118
119#ifdef TRACE
120 Cerr << finl << "Y0 " << mp_norme_vect(Y0) << finl;
121 Cerr << finl << "Y1 " << mp_norme_vect(Y1) << finl;
122 if(nblocs == 3)
123 Cerr << finl << "Ya " << mp_norme_vect(Ya) << finl;
124 matrice.multvect(b, F);
125 double psc=mp_prodscal(F,b);
126 assert(psc>0);
127 double pscF=mp_prodscal(F,F);
128 Cout << finl <<"cos(angle) no prec " << psc*psc/(pscF*pscb) << finl;
129 Cout << finl <<"(F,b) " << psc << finl;
130 Cout << finl <<"(b,b) " << pscb << finl;
131 Cout << finl <<"(F,F) " << pscF << finl;
132 F.ajoute(-psc/pscb,b,VECT_ALL_ITEMS);
133
134 Cout << finl <<"(F0,F0) " << mp_prodscal(Y0,Y0) << finl;
135 Cout << finl <<"(F1,F1) " << mp_prodscal(Y1,Y1) << finl;
136 if(nblocs == 3)
137 Cout << finl <<"(Fa,Fa) " << mp_prodscal(Ya,Ya) << finl;
138 F=b;
139#endif
140
141 // Descente :
142
143 le_precond_1->preconditionner(A11,Y1,X1);
144 operator_multiply(X1, -alpha_1, VECT_ALL_ITEMS);
145 A11.ajouter_multvect(X1, Y1);
146 A01.ajouter_multvect(X1, Y0);
147 if(nblocs == 3)
148 A1a.ajouter_multvectT(X1, Ya);
149 operator_multiply(X1, -1, VECT_ALL_ITEMS);
150 le_precond_0->preconditionner(A00,Y0,X0);
151 operator_multiply(X0, -alpha_0, VECT_ALL_ITEMS);
152 A00.ajouter_multvect(X0, Y0);
153 A01.ajouter_multvectT(X0, Y1);
154 if(nblocs == 3)
155 A0a.ajouter_multvectT(X0, Ya);
156 operator_multiply(X0, -1, VECT_ALL_ITEMS);
157 if(nblocs == 3)
158 {
159 le_precond_a->preconditionner(Aaa,Ya,Xa);
160 operator_multiply(Xa, -alpha_a, VECT_ALL_ITEMS);
161 Aaa.ajouter_multvect(Xa, Ya);
162 A1a.ajouter_multvect(Xa, Y1);
163 A0a.ajouter_multvect(Xa, Y0);
164 operator_multiply(Xa, -1, VECT_ALL_ITEMS);
165 }
166 // X contient S,
167 F=solution;
168 // Diagonale :
169
170 A11.multvect(Y1,X1);
171 operator_multiply(X1, 1./alpha_1, VECT_ALL_ITEMS);
172 A00.multvect(Y0,X0);
173 operator_multiply(X0, 1./alpha_0, VECT_ALL_ITEMS);
174 if(nblocs == 3)
175 {
176 Aaa.multvect(Ya,Xa);
177 operator_multiply(Xa, 1./alpha_a, VECT_ALL_ITEMS);
178 }
179 // X contient T,
180 F=solution;
181
182 // Remontee :
183
184 if(nblocs == 3)
185 {
186 le_precond_a->preconditionner(Aaa,Ya,Xa);
187 operator_multiply(Xa, -alpha_a, VECT_ALL_ITEMS);
188 Aaa.ajouter_multvect(Xa, Ya);
189 A1a.ajouter_multvect(Xa, Y1);
190 A0a.ajouter_multvect(Xa, Y0);
191 operator_multiply(Xa, -1., VECT_ALL_ITEMS);
192 }
193 le_precond_0->preconditionner(A00,Y0,X0);
194 operator_multiply(X0, -alpha_0, VECT_ALL_ITEMS);
195 A00.ajouter_multvect(X0, Y0);
196 A01.ajouter_multvectT(X0, Y1);
197 if(nblocs == 3)
198 A0a.ajouter_multvectT(X0, Ya);
199 operator_multiply(X0, -1., VECT_ALL_ITEMS);
200 le_precond_1->preconditionner(A11,Y1,X1);
201 operator_multiply(X1, -alpha_1, VECT_ALL_ITEMS);
202 A11.ajouter_multvect(X1, Y1);
203 A01.ajouter_multvect(X1, Y0);
204 if(nblocs == 3)
205 A1a.ajouter_multvectT(X1, Ya);
206 operator_multiply(X1, -1., VECT_ALL_ITEMS);
207#ifdef TRACE
208 matrice.multvect(solution, F);
209 psc=mp_prodscal(F,b);
210 assert(psc>0);
211 pscF=mp_prodscal(F,F);
212 Cout << finl <<"cos(angle) " << psc*psc/(pscF*pscb) << finl;
213 Cout << finl <<"(F,b) " << psc << finl;
214 Cout << finl <<"(b,b) " << pscb << finl;
215 Cout << finl <<"(F,F) " << pscF << finl;
216 F.ajoute(-psc/pscb,b);
217
218 Cout << finl <<"(F0,F0) " << mp_prodscal(Y0,Y0) << finl;
219 Cout << finl <<"(F1,F1) " << mp_prodscal(Y1,Y1) << finl;
220 if(nblocs == 3)
221 Cout << finl <<"(Fa,Fa) " << mp_prodscal(Ya,Ya) << finl;
222#endif
223
224 return 1;
225}
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Classe Matrice_Base Classe de base de la hierarchie des matrices.
virtual DoubleVect & ajouter_multvectT(const DoubleVect &x, DoubleVect &r) const
Operation de multiplication-accumulation (saxpy) matrice vecteur.
virtual DoubleVect & multvect(const DoubleVect &, DoubleVect &) const
Multiplication d'un vecteur par la matrice.
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Operation de multiplication-accumulation (saxpy) matrice vecteur.
const Matrice & get_bloc(int i, int j) const override
int nb_bloc_lignes() const
int nb_bloc_colonnes(void) const
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
int preconditionner_(const Matrice_Base &, const DoubleVect &src, DoubleVect &solution) override
Calcule la solution du systeme lineaire: A * solution = b avec la methode de relaxation PrecondA.
Definition PrecondA.cpp:75
void set_param(Param &param) const override
Definition PrecondA.cpp:39
double alpha_1
Definition PrecondA.h:40
double alpha_a
Definition PrecondA.h:40
void prepare_(const Matrice_Base &, const DoubleVect &src) override
this method must be overloaded if some preparation is necessary.
Definition PrecondA.cpp:60
double alpha_0
Definition PrecondA.h:40
void prepare(const Matrice_Base &, const DoubleVect &src)
prepares the preconditionner if needed after a matrix change (reinit() call).
virtual void prepare_(const Matrice_Base &, const DoubleVect &)
this method must be overloaded if some preparation is necessary.
Init_Status get_status()
void reinit(Init_Status x=REINIT_ALL)
this method must be called before preconditionner() whenever the matrix changes (coefficients only or...
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
int size() const
void ajoute(_SCALAR_TYPE_ alpha, const TRUSTVect &y, Mp_vect_options opt=VECT_ALL_ITEMS)
Definition TRUSTVect.tpp:52