TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Op_Diff_RotRot.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 <Champ_P1_isoP1Bulle.h>
17#include <LecFicDistribueBin.h>
18#include <Matrice_Morse_Sym.h>
19#include <Champ_Uniforme.h>
20#include <Op_Diff_RotRot.h>
21
22#include <Domaine_Cl_VEF.h>
23
24#include <SFichier.h>
25#include <Solv_GCP.h>
26#include <SSOR.h>
27
28Implemente_instanciable(Op_Diff_RotRot, "Op_Diff_VEF_ROTROT_P1NC", Operateur_Diff_base);
29
30Sortie& Op_Diff_RotRot::printOn(Sortie& s) const { return s << que_suis_je(); }
31
32Entree& Op_Diff_RotRot::readOn(Entree& s) { return s; }
33
34const Domaine_VEF& Op_Diff_RotRot::domaine_vef() const { return ref_cast(Domaine_VEF, le_dom_vef.valeur()); }
35
36void Op_Diff_RotRot::associer(const Domaine_dis_base& domaine_dis, const Domaine_Cl_dis_base& domaine_Cl_dis, const Champ_Inc_base& inco)
37{
38 const Domaine_VEF& zvef = ref_cast(Domaine_VEF, domaine_dis);
39 const Domaine_Cl_VEF& zclvef = ref_cast(Domaine_Cl_VEF, domaine_Cl_dis);
40 le_dom_vef = zvef;
41 la_zcl_vef = zclvef;
42
43 curl_.associer(domaine_dis, domaine_Cl_dis, inco);
44 rot_.associer(domaine_dis, domaine_Cl_dis, inco);
45
46 //////////////////////////////////////////////
47 //On definit le champ vorticite
48 vorticite_.typer("Champ_P1_isoP1Bulle");
49 Champ_P1_isoP1Bulle& vorticite = ref_cast(Champ_P1_isoP1Bulle, vorticite_.valeur());
50
51 vorticite.associer_domaine_dis_base(zvef);
52 vorticite.nommer("vorticite");
53
54 if (dimension == 2)
55 vorticite.fixer_nb_comp(1);
56 else
57 vorticite.fixer_nb_comp(dimension);
58
59 int nb_tot = zvef.nb_elem() + zvef.nb_som() - 1;
60 vorticite.fixer_nb_valeurs_nodales(nb_tot);
61
62 vorticite.fixer_unite("s-1");
63
64 //////////////////////////////////////////////////
65
66 solveur_.typer("Solv_GCP");
68 p.typer("SSOR");
69 ref_cast(Solv_GCP,solveur.valeur()).set_precond(p);
71 tester();
72
73}
74
75DoubleTab& Op_Diff_RotRot::calculer(const DoubleTab& vitesse, DoubleTab& diffusion) const
76{
77 diffusion = 0;
78 return ajouter(vitesse, diffusion);
79}
80
81//Methode de l'operateur de diffusion sous forme
82//rotationnel de la vorticite sans const la seule qui
83//doit etre appelee.
84DoubleTab& Op_Diff_RotRot::ajouter(const DoubleTab& vitesse, DoubleTab& diffusion) const
85{
86 Cerr << "je suis dans OpDiffRotRot" << finl;
87 DoubleTab curl(matrice_vorticite_->ordre());
88
89 curl_.calculer(vitesse, curl);
90 //curl=-1*curl;
91 calculer_vorticite(vorticite_->valeurs(), curl);
92 rot_.calculer(vorticite_->valeurs(), diffusion);
93
94 Cerr << "je sors de OpDiffRotRot" << finl;
95
96 return diffusion;
97
98}
99
100int Op_Diff_RotRot::calculer_vorticite(DoubleTab& solution, const DoubleTab& curl) const
101{
102 const Domaine& domaine = domaine_vef().domaine();
103 //static int nb_appel2=0;
104
105 // Resolution en vorticite: on ne considere que le cas
106 // sequentiel pour le moment.
107 // Pour le cas parallele, il faut s'inspirer de la classe N_S.cpp.
108
110 {
111 //On considere que la matrice de vorticite est une matrice
112 //morse par defaut, et on applique la methode inverse()
113 //pour resoudre le systeme lineaire.
114 const Matrice_Morse_Sym& la_matrice = ref_cast(Matrice_Morse_Sym, matrice_vorticite_.valeur());
115 // Matrice_Morse& la_matrice = (Matrice_Morse&) matrice_vorticite_.valeur();
116 DoubleTab solution_temporaire(la_matrice.ordre());
117
118 assert(solution_temporaire.size() == solution.size() - 1);
119 assert(curl.size() == solution_temporaire.size());
120
121 //On resoud un systeme lineaire pour calculer la vorticite
122 //La vorticite est alors stockee dans la variable solution
123 // la_matrice.inverse(curl,solution_temporaire,1e-15);
124 Solv_GCP& solv = ref_cast_non_const(Solv_GCP, solveur_.valeur());
125 solv.set_seuil(1e-17);
126 solv.resoudre_systeme(la_matrice, curl, solution_temporaire);
127
128 //On recopie les valeurs de solution temoraire dans solution
129 //Une case n'est pas remplie: on le fait plus tard.
130 for (int i = 0; i < solution_temporaire.size(); i++)
131 solution[i] = solution_temporaire[i];
132
133 //On remplit le dernier element de "solution"
134 int sommet = domaine.nb_som() - 1;
135
136 for (int i = 0; i < curl_.elem_som_size(sommet); i++)
137 solution[sommet] += solution_temporaire[curl_.elements_pour_sommet(sommet, i)];
138
139 //nb_appel2++;
140
141 }
142
143 return 1;
144}
145
146//////////////////////////////////////////////////////
147/* Fonctions permettant l'assemblage de la matrice */
148/* de vorticite */
149/////////////////////////////////////////////////////
150/* On calcule la matrice de vorticite pour le probleme triple:
151 / on considere le cas sans condition au limite pour la vorticite
152 / pour le moment, et on ne code pas la partie parallele de
153 / l'algo.
154 / REM: pour l'instant, ne fonctionne qu'en 2D
155 */
157{
158 const Domaine& domaine = domaine_vef().domaine();
159
160 int colonne_a_remplir_tab2, colonne_a_remplir_coeff;
161
162 Cerr << "Assemblage de la matrice de vorticite en cours..." << finl;
163 matrice.typer("Matrice_Morse_Sym");
164 //Matrice_Morse& la_matrice=(Matrice_Morse&) matrice.valeur();
165
166 // On dimensionne la matrice de maniere convenable.
167 // La matrice est carree et de taille (nombre_elem+nombre_som)
168 // Le nombre de coeff non nuls n'excedent pas
169 // (2* (dimension+1) + 1)* nb_elem + (nb_som-1) * (nb_som-1)
170 // ATTENTION: une BASE de mon espace est les fonctions indicatrices
171 // des elements + les fonctions chapeaux - 1 de ces fonctions
172 // Sinon la somme des toutes les fontions chapeaux - la somme
173 // de toutes les fonctions indicatrices = 0
174 // Par defaut, on enleve la derniere fonction chapeau pour
175 // former notre base.
176 // Cf. Papier dans Latex/Vorticity
177 int nombre_coeff_non_nuls = (2 * dimension + 3) * domaine.nb_elem() + (domaine.nb_som() - 1) * (domaine.nb_som() - 1);
178 //la_matrice.dimensionner(domaine.nb_elem()+domaine.nb_som()-1,nombre_coeff_non_nuls);
179 Matrice_Morse la_matrice(domaine.nb_elem() + domaine.nb_som() - 1, nombre_coeff_non_nuls);
180
181 //Au cas ou la matrice existe deja dans un fichier
182 Nom nomfic("Vorticite.sv");
183 LecFicDistribueBin vorticite;
184 int fic_vorticite_existe;
185
186 if (vorticite.ouvrir(nomfic))
187 fic_vorticite_existe = 1;
188 else
189 fic_vorticite_existe = 0;
190
191 if (fic_vorticite_existe)
192 {
193 Cerr << "Relecture de la matrice de vorticite sur le fichier: " << nomfic << finl;
194 vorticite >> la_matrice;
195 vorticite.close();
196 Cerr << "Fin de la relecture de la matrice de vorticite." << finl;
197 return 1;
198 }
199
200 Cerr << "Assemblage de la matrice de vorticite " << nomfic << finl;
201
202 // Maintenant on remplit la matrice ligne par ligne
203 // On rappelle que les elements et les sommets sont numerotes
204 // a partir de 0.
205 // Mais les indices de colonnes et de lignes des tableaux
206 // d'une matrice morse FORTRAN commencent a 1.
207 // Ex de construction: matrice[numerotation_C++] = numerotation_FORTRAN
208
209 // Parametres importants pour remplir les tableaux
210 nombre_coeff_non_nuls = 1;
211 colonne_a_remplir_tab2 = 0; //pour le C++
212 colonne_a_remplir_coeff = 0; //pour le C++
213
214 // On commence par remplir les lignes de la sous-matrice
215 // de taille nb_elem * (nb_elem + nb_som) : cf. structure de la matrice
216 for (int numero_elem = 0; numero_elem < domaine.nb_elem(); numero_elem++)
217 {
218 // Pour un element donne "numero_elem", on calcule la liste
219 // des sommets qui appartiennent a cet element.
220 IntList sommets_pour_elem = sommets_pour_element(numero_elem);
221 Tri(sommets_pour_elem); //tableau trie
222
223 // On remplit tab1
224 la_matrice.get_set_tab1()(numero_elem) = nombre_coeff_non_nuls;
225
226 // On remplit tab2 et coeff
227
228 //Les nb_elem premiers elements de la ligne "numero_elem"
229 //a cause du FORTRAN
230 la_matrice.get_set_tab2()(colonne_a_remplir_tab2) = numero_elem + 1;
231 la_matrice.get_set_coeff()(colonne_a_remplir_coeff) = remplir_elem_elem_EF(numero_elem);
232
233 //On incremente nb_coeff_non_nuls car on vient de remplir
234 //une ligne par l'un de ces elements non nul
235 nombre_coeff_non_nuls++;
236
237 //On incremente les compteurs puisque l'on vient de remplir
238 //des cases du tableau
239 colonne_a_remplir_tab2++;
240 colonne_a_remplir_coeff++;
241
242 //Les nb_som elements de la ligne "numero_elem"
243 for (int i = 0; i < domaine.nb_som_elem(); i++)
244 {
245 //Si ce "sommet_pour_elem[i]" est different du numero
246 //du dernier sommet alors on stocke le bon coefficient
247 if (sommets_pour_elem[i] != domaine.nb_som() - 1)
248 {
249 la_matrice.get_set_tab2()(colonne_a_remplir_tab2) = domaine.nb_elem() + sommets_pour_elem[i] + 1; //pour FORTRAN
250 la_matrice.get_set_coeff()(colonne_a_remplir_coeff) = remplir_elem_som_EF(numero_elem, sommets_pour_elem[i]);
251
252 //On incremente nb_coeff_non_nuls car on vient de remplir
253 //une ligne avec l'un de ces elements non nul
254 nombre_coeff_non_nuls++;
255
256 //Enfin on incremente les colonne_* pour eviter de reecrire
257 //sur des coefficients deja stockes
258 colonne_a_remplir_tab2++;
259 colonne_a_remplir_coeff++;
260 }
261
262 }
263
264 //Pas besoin de modifier les entiers nombre_coeff_non_nuls et
265 //colonne_* : ils sont a la bonne valeur.
266
267 }
268
269 // On remplit les lignes de la sous-matrice de taille
270 // nb_som *( nb_elem+nb_som) :cf. structure de la matrice
271 for (int numero_som = 0; numero_som < domaine.nb_som() - 1; numero_som++)
272 {
273 // On stocke les tableaux qui nous sont utiles
274 // Ainsi que leur taille respective
275 IntList Elem_pour_sommet = elements_pour_sommet(numero_som);
276 IntList Sommets_voisins = sommets_voisins(numero_som, Elem_pour_sommet);
277 Tri(Elem_pour_sommet); //liste triee
278 Tri(Sommets_voisins); //liste triee
279
280 //On remplit tab1
281 //pour FORTRAN
282 la_matrice.get_set_tab1()(domaine.nb_elem() + numero_som) = nombre_coeff_non_nuls;
283
284 //On remplit tab2 et coeff
285
286 //Les nb_elem premiers elements de la ligne "numero_som"
287 for (int i = 0; i < Elem_pour_sommet.size(); i++)
288 {
289 //A cause du FORTRAN
290 la_matrice.get_set_tab2()(colonne_a_remplir_tab2) = Elem_pour_sommet[i] + 1;
291 la_matrice.get_set_coeff()(colonne_a_remplir_coeff) = remplir_som_elem_EF(Elem_pour_sommet[i], numero_som);
292
293 //On incremente nb_coeff_non_nuls car on vient de remplir
294 //une ligne avec l'un de ces elements non nul
295 nombre_coeff_non_nuls++;
296
297 //On incremente convenablement les indices de colonnes
298 colonne_a_remplir_tab2++;
299 colonne_a_remplir_coeff++;
300 }
301
302 //Pas besoin de modifier les entiers nb_coeff_non_nuls et
303 //colonne_* : ils sont a la bonne valeur.
304
305 //Les nb_som elements de la ligne "numero_som"
306 for (int i = 0; i < Sommets_voisins.size(); i++)
307 {
308 //On recupere le numero global du sommet_voisin
309 int numero_som_global = Sommets_voisins[i];
310
311 //Et si "numero_som_global" est different du numero
312 //du dernier sommet, alors on stocke le bon coefficient
313
314 if (numero_som_global != domaine.nb_som() - 1)
315 {
316 //A cause du FORTRAN
317 la_matrice.get_set_tab2()(colonne_a_remplir_tab2) = domaine.nb_elem() + Sommets_voisins[i] + 1;
318 la_matrice.get_set_coeff()(colonne_a_remplir_coeff) = remplir_som_som_EF(numero_som, Sommets_voisins[i], Elem_pour_sommet);
319
320 //On incremente nb_coeff_non_nuls car on vient de remplir
321 //une ligne avec l'un de ces elements non nul
322 nombre_coeff_non_nuls++;
323
324 //On incremente les indices
325 colonne_a_remplir_tab2++;
326 colonne_a_remplir_coeff++;
327 }
328
329 }
330
331 //Pas besoin d'incrementer nombre_coeff_non_nuls et colonne_*
332 //: ils sont deja a la bonne valeur
333 }
334
335 //Par convention pour les matrices morses, le dernier element
336 //de tab1 est tab1[domaine.nb_elem()+domaine.nb_som()+1] et vaut
337 //le nombre total de coefficients non nuls +1
338 //soit avec notre algorithme: nombre_coeff_non_nuls
339 la_matrice.get_set_tab1()(domaine.nb_elem() + domaine.nb_som() - 1) = nombre_coeff_non_nuls;
340
341 // if(Debog::mode_db==2) Debog::save_matrix_seq(la_matrice);
342 // else if(Debog::mode_db==3)
343 // Debog::save_and_distribute_matrix_seq(la_matrice);
344
345 Matrice_Morse_Sym& la_matrice_sym = ref_cast(Matrice_Morse_Sym, matrice.valeur());
346 la_matrice_sym = la_matrice;
347
348 Cerr << "Fin de l'assemblage de la matrice de vorticite. " << finl;
349
350 return 1;
351}
352
353/* Pour un element donne "numero_elem" retourne */
354/* la liste des sommets appartenant a cet element */
355IntList Op_Diff_RotRot::sommets_pour_element(int numero_elem) const
356{
357 IntList resultat;
358 int numero_global_sommet = 0;
359 const Domaine& domaine = domaine_vef().domaine();
360
361 // Par precaution mais normalement inutile
362 if (!resultat.est_vide())
363 resultat.vide();
364
365 for (int i = 0; i < domaine.nb_som_elem(); i++)
366 {
367 numero_global_sommet = domaine.sommet_elem(numero_elem, i);
368 resultat.add_if_not(numero_global_sommet);
369 }
370
371 return resultat;
372}
373
374/* Pour un sommet donne "numero_sommet" retourne */
375/* la liste des elements contenant ce sommet */
376IntList Op_Diff_RotRot::elements_pour_sommet(int numero_sommet) const
377{
378 IntList resultat;
379 int numero_global_som;
380 const Domaine& domaine = domaine_vef().domaine();
381
382 // Par precaution mais normalement inutile
383 if (!resultat.est_vide())
384 resultat.vide();
385
386 // Pas tres efficace mais marche quelle que soit la dimension:
387 // on boucle sur les elements, on regarde pour chaque element
388 // ses sommets, puis on compare ces sommets au parametre d'entree
389 // et si l'un d'eux coincide avec le parametre d'entree, on stocke
390 // l'element.
391 for (int numero_elem = 0; numero_elem < domaine.nb_elem(); numero_elem++)
392 for (int numero_som = 0; numero_som < domaine.nb_som_elem(); numero_som++)
393 {
394 numero_global_som = domaine.sommet_elem(numero_elem, numero_som);
395 if (numero_sommet == numero_global_som)
396 resultat.add_if_not(numero_elem);
397 }
398
399 return resultat;
400
401}
402
403/* Pour un sommet donne "numero_sommet" retourne */
404/* la liste des sommets voisins de "numero_sommet" */
405/* Parametre: la liste des elements contenant "numero_sommet" */
406/* Il suffit de chercher dans ces elements pour avoir le resultat */
407/* REM: la liste resultat contient le sommet "numero_sommet" */
408IntList Op_Diff_RotRot::sommets_voisins(int numero_sommet, const IntList& liste) const
409{
410 IntList resultat;
411 int numero_global_som;
412 const Domaine& domaine = domaine_vef().domaine();
413
414 //Il suffit de recuperer les sommets des elements de "liste"
415 //puis de les comparer a "numero_som" et de les conserver
416 //sans doublon.
417 for (int numero_elem_loc = 0; numero_elem_loc < liste.size(); numero_elem_loc++)
418 for (int numero_som = 0; numero_som < domaine.nb_som_elem(); numero_som++)
419 {
420 numero_global_som = domaine.sommet_elem(liste[numero_elem_loc], numero_som);
421 resultat.add_if_not(numero_global_som); //contient "numero_sommet"
422 }
423
424 // Cerr << "Affichage de sommets_voisins pour numero_som " << numero_sommet
425 // << finl;
426 // for (int i=0;i<resultat.size();i++)
427 // Cerr << resultat[i] << finl;
428
429 return resultat;
430}
431
432/* Fonction de tri d'une IntList */
433/* Le tri s'effectue par ordre croissant */
434/* REM: on n'a aucun doublon dans la liste triee */
435void Op_Diff_RotRot::Tri(IntList& liste_a_trier) const
436{
437 if (liste_a_trier.est_vide())
438 {
439 Cerr << "Erreur dans Op_Diff_RotRot::Tri()." << finl;
440 Cerr << "La liste a trier est vide: sortie du programme." << finl;
442 }
443
444 IntList temporaire;
445 int minimum;
446
447 while (!liste_a_trier.est_vide())
448 {
449 minimum = liste_a_trier[0];
450
451 for (int i = 0; i < liste_a_trier.size(); i++)
452 minimum = (minimum <= liste_a_trier[i] ? minimum : liste_a_trier[i]);
453
454 temporaire.add_if_not(minimum);
455 liste_a_trier.suppr(minimum);
456 }
457
458 for (int i = 0; i < temporaire.size(); i++)
459 liste_a_trier.add_if_not(temporaire[i]);
460
461}
462
463/* Pour l'element "numero_elem" retourne le coefficient */
464/* a placer dans la sous matrice de taille nb_elem * nb_elem */
465/* a la ligne "numero_elem" , colonne "numero_elem"*/
466/* Matrice EF */
467double Op_Diff_RotRot::remplir_elem_elem_EF(const int numero_elem) const
468{
469 return 1. * domaine_vef().volumes(numero_elem);
470}
471
472/* Pour l'element "numero_elem" retourne le coefficient */
473/* a placer dans la sous matrice de taille nb_elem * nb_som */
474/* a la ligne "numero_elem" , colonne "numero_som"*/
475/* Matrice EF */
476double Op_Diff_RotRot::remplir_elem_som_EF(const int numero_elem, const int numero_som) const
477{
478 return (1. * domaine_vef().volumes(numero_elem) / (dimension + 1));
479}
480
481/* Pour le sommet "numero_som" retourne le coefficient */
482/* a placer dans la sous matrice de taille nb_som * nb_elem */
483/* a la ligne "numero_som" , colonne "numero_elem"*/
484/* Matrice EF */
485double Op_Diff_RotRot::remplir_som_elem_EF(const int numero_elem, const int numero_som) const
486{
487 return (1. * domaine_vef().volumes(numero_elem) / (dimension + 1));
488}
489
490/* Pour l'element "numero_som" retourne le coefficient */
491/* a placer dans la sous matrice de taille nb_som * nb_som */
492/* a la ligne "numero_som" , colonne "sommet_voisin"*/
493/* "elem_voisins" est le tableau des elements contenant "numero_som" */
494/* Matrice EF */
495double Op_Diff_RotRot::remplir_som_som_EF(const int numero_som, const int sommet_voisin, const IntList& elem_voisins) const
496{
497 double resultat = 0.;
498 int test = 0;
499
500 //Premier test: si numero_som = sommet_voisin
501 //Alors on peut tout de suite retourner le resultat
502 if (numero_som == sommet_voisin)
503 {
504 for (int i = 0; i < elem_voisins.size(); i++)
505 {
506 resultat += domaine_vef().volumes(elem_voisins[i]);
507 }
508
509 //On tient compte de la dimension dans nos calculs
510 resultat *= 2. / ((dimension + 1) * (dimension + 2));
511
512 return resultat;
513 }
514
515 //Sinon:
516 //On calcule la contribution au resultat
517
518 for (int i = 0; i < elem_voisins.size(); i++)
519 {
520 if (sommets_pour_element(elem_voisins[i]).contient(sommet_voisin))
521 {
522 resultat += domaine_vef().volumes(elem_voisins[i]);
523 test++;
524 }
525 }
526
527 //On tient compte de la dimension dans laquelle on evolue
528 resultat *= 1. / ((dimension + 1) * (dimension + 2));
529
530 //On verifier que sommet_voisin etait bien dans le voisinage de numero_voisin
531 if (test == 0)
532 {
533 Cerr << "Erreur Op_Diff_RotRot::remplir_som_som_EF." << finl;
534 Cerr << "sommet_voisin n'est pas dans le voisinage de numero_voisin." << finl;
535 Cerr << "Sortie du programme." << finl;
537 }
538
539 return resultat;
540
541}
542
543DoubleTab Op_Diff_RotRot::vecteur_normal(const int face, const int elem) const
544{
545 assert(dimension == 2);
546
547 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
548 DoubleTab le_vecteur_normal(dimension);
549
550 for (int composante = 0; composante < dimension; composante++)
551
552 le_vecteur_normal(composante) = domaine_VEF.face_normales(face, composante) * domaine_VEF.oriente_normale(face, elem);
553
554 return le_vecteur_normal;
555}
556
558{
559 // const Domaine& domaine = domaine_Vef().domaine();
560
561 // if (vorticite_->nb_valeurs_nodales() !=
562 // domaine.nb_elem()+domaine.nb_som()-1 )
563 // {
564 // Cerr << "Probleme dans la definition de la vorticite." << finl;
565 // Cerr << "Le nombre de composante enregistree n'est pas le bon." << finl;
566 // Process::exit();
567 // }
568
569 //Test de la matrice de vorticite
570 const Matrice_Morse_Sym& la_matrice = ref_cast(Matrice_Morse_Sym, matrice_vorticite_.valeur());
571 Solv_GCP& solv = ref_cast_non_const(Solv_GCP, solveur_.valeur());
572
573 DoubleTab resultat(la_matrice.ordre());
574 //DoubleTab resultat1(la_matrice.ordre());
575 DoubleTab secmem(la_matrice.ordre());
576 DoubleTab secmem1(la_matrice.ordre());
577 secmem = 0.;
578 secmem[0] = -0.25;
579 secmem[4] = -0.0833333;
580 secmem[5] = -0.0833333;
581 secmem1 = 1e-10 + 1e-15;
582
583 SFichier fic("Matrice.test");
584 la_matrice.imprimer_formatte(fic);
585
586 resultat = 0.;
587 solv.set_seuil(1e-17);
588 solv.resoudre_systeme(la_matrice, secmem, resultat);
589 Cerr << "Resultat de l'inversion" << finl;
590 for (int i = 0; i < 8; i++)
591 Cerr << resultat[i] << " ; ";
592 Cerr << finl;
593
594 solv.resoudre_systeme(la_matrice, secmem1, resultat);
595 Cerr << "Resultat de l'inversion" << finl;
596 for (int i = 0; i < 8; i++)
597 Cerr << resultat[i] << " ; ";
598 Cerr << finl;
599
600 return 1;
601}
602
604{
605 diffusivite_ = ref_cast(Champ_Uniforme, diffu);
606}
607
609{
610 return diffusivite_;
611}
Classe Champ_Inc_base.
void associer_domaine_dis_base(const Domaine_dis_base &) override
int fixer_nb_valeurs_nodales(int) override
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
class Domaine_VEF
Definition Domaine_VEF.h:54
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
double volumes(int i) const
Definition Domaine_VF.h:113
int oriente_normale(int f, int e) const
Definition Domaine_VF.h:194
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual void fixer_nb_comp(int i)
Fixe le nombre de composantes du champ.
void nommer(const Nom &) override
Donne un nom au champ.
virtual const Nom & fixer_unite(const Nom &)
Specifie l'unite d'un champ scalaire ou dont toutes les composantes ont la meme unite.
Lecture dans un fichier au format binaire.
int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::in) override
Ouvre le fichier avec les parametres mode et prot donnes Ces parametres sont les parametres de la met...
Classe Matrice_Morse_Sym Represente une matrice M (creuse) symetrique stockee au format Morse.
Sortie & imprimer_formatte(Sortie &s) const override
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
auto & get_set_tab2()
int ordre() const override
Renvoie l'ordre de la matrice: - le nombre de lignes si la matrice est carree.
auto & get_set_coeff()
auto & get_set_tab1()
Classe Matrice Classe generique de la hierarchie des matrices.
Definition Matrice.h:34
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
static int dimension
Definition Objet_U.h:99
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
double remplir_elem_som_EF(const int numero_elem, const int numero_som) const
IntList sommets_voisins(int numero_som, const IntList &liste) const
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
void Tri(IntList &liste_a_trier) const
IntList elements_pour_sommet(int numero_som) const
Op_Rot_VEFP1B rot_
void associer(const Domaine_dis_base &, const Domaine_Cl_dis_base &, const Champ_Inc_base &) override
const Domaine_VEF & domaine_vef() const
DoubleTab vecteur_normal(const int face, const int elem) const
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void associer_diffusivite(const Champ_base &) override
int assembler_matrice(Matrice &)
double remplir_elem_elem_EF(const int numero_elem) const
const Champ_base & diffusivite() const override
Matrice matrice_vorticite_
double remplir_som_som_EF(const int numero_som, const int sommet_voisin, const IntList &) const
OWN_PTR(Champ_Inc_base) vorticite_
SolveurSys solveur_
double remplir_som_elem_EF(const int numero_elem, const int numero_som) const
IntList sommets_pour_element(int numero_elem) const
int calculer_vorticite(DoubleTab &, const DoubleTab &) const
Op_Curl_VEFP1B curl_
classe Operateur_Diff_base Cette classe est la base de la hierarchie des operateurs representant
SolveurSys solveur
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static bool is_sequential()
Definition Process.cpp:115
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
int resoudre_systeme(const Matrice_Base &, const DoubleVect &, DoubleVect &) override
Definition Solv_GCP.cpp:111
Classe de base des flux de sortie.
Definition Sortie.h:52
int est_vide() const
TRUSTList & add_if_not(_TYPE_)
Ajout d'un element a la liste ssi il n'existe pas deja.
void suppr(_TYPE_)
Supprime un element contenu dans la liste.
void vide()
Vide la liste.
int size() const
Definition TRUSTList.h:68
_SIZE_ size() const
Definition TRUSTVect.tpp:45
void set_seuil(double s)