17#include <Navier_Stokes_std.h>
19#include <Matrice_Bloc.h>
20#include <Matrice_Morse_Sym.h>
21#include <Assembleur_base.h>
22#include <Schema_Temps_base.h>
23#include <Schema_Euler_Implicite.h>
24#include <Fluide_Dilatable_base.h>
25#include <Probleme_base.h>
26#include <MD_Vector_composite.h>
27#include <MD_Vector_tools.h>
28#include <TRUSTTab_parts.h>
31#include <Discretisation_base.h>
60 les_mots[0] =
"relax_pression";
63 int rang=les_mots.
search(motlu);
81void diviser_par_rho_np1_face(
Equation_base& eqn,DoubleTab& tab_array)
84 int nbdim = tab_array.
nb_dim();
87 CDoubleArrView rho =
static_cast<const ArrOfDouble&
>(fluide_dil.
rho_face_np1()).view_ro();
90 DoubleArrView array =
static_cast<ArrOfDouble&
>(tab_array).view_rw();
91 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, taille_0_tot), KOKKOS_LAMBDA(
const int i)
93 for (
int j = 0; j < dim; j++)
99 DoubleTabView array = tab_array.
view_rw();
100 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, taille_0_tot), KOKKOS_LAMBDA(
const int i)
102 for (
int j=0; j<dim; j++)
103 array(i,j) /= rho(i);
106 end_gpu_timer(__KERNEL_NAME__);
109void iterer_eqn_expl(
Equation_base& eqn,
int nb_iter,
double dt,DoubleTab& current,DoubleTab& dudt,
110 int& converge,
const int no_qdm_)
119 Cout<<eqn.
que_suis_je()<<
" equation is not solved."<<finl;
129 modf((dt/dt_stab), &n_sous_ite);
130 if (dt>dt_stab*n_sous_ite) n_sous_ite=n_sous_ite+1.;
131 double dt_calc = dt/n_sous_ite;
132 assert(dt_calc<=dt_stab);
133 for (
double i=0; i<n_sous_ite; i=i+1.)
140 Cout <<
"It is solved with " << n_sous_ite <<
" explicit sub-iterations."<<finl;
144void iterer_eqn_expl_diffusion_implicite(
Equation_base& eqn,
int nb_iter,
double dt,DoubleTab& current,DoubleTab& dudt,
145 int& converge,
const int no_qdm_,
const double seuil)
154 Cout<<eqn.
que_suis_je()<<
" equation is not solved."<<finl;
178 double dt,
int nb_iter,
int& ok)
180 DoubleTab dudt(current);
190 if (freq!=0 && (nb_pas_dt%freq)!=0)
192 Cout<<
"Time step : "<<nb_pas_dt<<
" - "<<eqn.
que_suis_je()<<
" equation is not solved."<<finl;
198 Cout<<eqn.
que_suis_je()<<
" equation is not solved."<<finl;
212 iterer_eqn_expl(eqn,nb_iter,dt,current,dudt,converge,
no_qdm_);
216 return (converge==1);
222 assert(seuil_verification_solveur>0);
224 double seuil_convg = seuil_convergence_implicite;
229 if ((residu*dt*10<seuil_convg)&&(nb_iter==1))
231 seuil_convergence_implicite /= 1.1;
232 seuil_convg = seuil_convergence_implicite;
234 Cout<<
"seuil_convg "<<seuil_convg<<finl;
241 if (!matrice_en_pression_2) matrice_en_pression_2.detach();
260 DoubleTrav resu(current);
266 DoubleTrav secmem(pression);
267 pression.echange_espace_virtuel();
268 iterer_NS(eqnNS,current,pression,dt,matrice,seuil_verification_solveur,secmem,nb_iter,converge, ok);
273 DoubleTrav resu_temp(current);
299 if (seuil_test_preliminaire_solveur>0)
301 double norme_b=mp_norme_vect(resu_temp);
302 if (norme_b<seuil_test_preliminaire_solveur)
308 Cout<<
"Resolution of system is not necessary: "<< norme_b <<
" < "<< seuil_test_preliminaire_solveur <<finl;
321 for (
int j = 0; j < current.
line_size(); j++)
322 current(i, j) = std::max(current(i, j), 0.);
330 double norme_resu = mp_norme_vect(resu_temp) ;
332 if (norme_resu>seuil_verification_solveur) con = 0;
335 Cout<<
"Residu of iterative solving : "<<norme_resu<<
" instead of "<<seuil_verification_solveur<<finl;
336 Cout<<
"Iterating on the linear system again:"<< finl;
337 seuil_verification_solveur *= 2;
358 double dudt_norme = mp_norme_vect(dudt);
359 converge = (dudt_norme < seuil_convg);
362 Cout<<eqn.
que_suis_je()<<
" is not converged at the implicit iteration "<<nb_iter<<
" ( ||uk-uk-1|| = "<<dudt_norme<<
" > implicit threshold "<<seuil_convg<<
" )"<<finl;
363 if (nb_iter>=10) Cout <<
"Consider lowering facsec_max value. Look at the reference manual for advice to set facsec_max value according to the problem type." << finl;
366 Cout<<eqn.
que_suis_je()<<
" is converged at the implicit iteration "<<nb_iter<<
" ( ||uk-uk-1|| = "<<dudt_norme<<
" < implicit threshold "<<seuil_convg<<
" )"<<finl;
371 return (ok && converge==1);
384 for (i = 0; i < eqs.size(); i++) key[i] = (intptr_t) &eqs[i].valeur();
386 int init = !
mbloc.count(key);
390 for (Mglob.
dimensionner(eqs.size(), eqs.size()), i = 0; i < eqs.size(); i++)
391 for (j = 0; j < eqs.size(); j++) Mglob.
get_bloc(i, j).typer(
"Matrice_Morse");
394 int interface_blocs_ok = 1;
395 for (i = 0; i < eqs.size(); i++) interface_blocs_ok &= eqs[i]->has_interface_blocs();
396 std::vector<matrices_t> mats(eqs.size());
397 for (i = 0; i < eqs.size(); i++)
398 for (j = 0; j < eqs.size(); j++)
407 for (bs = eqs[0]->inconnue().valeurs().line_size(), i = 1; i < eqs.size(); i++)
408 if (eqs[i]->inconnue().valeurs().line_size() != bs) bs = 0;
412 for (i = 0; i < eqs.size(); i++)
420 if (interface_blocs_ok)
421 for (i = 0; i < eqs.size(); i++)
422 for (eqs[i]->dimensionner_blocs(mats[i], {}), j = 0; j < eqs.size(); j++)
426 mat.
dimensionner(eqs[i]->inconnue().valeurs().size_totale(), eqs[j]->inconnue().valeurs().size_totale(), 0);
428 else for (i = 0; i < eqs.size(); i++)
429 for (j = 0; j < eqs.size(); j++)
435 if (i == j) mat += mat2;
438 else for (i = 0; i < eqs.size(); i++)
439 for (j = 0; j < eqs.size(); j++)
446 DoubleTrav inconnues, residus, dudt;
451 DoubleTab_parts residu_parts(residus), inconnues_parts(inconnues), dudt_parts(dudt);
454 for(i = 0; i < eqs.size(); i++) inconnues_parts[i] = eqs[i]->inconnue().valeurs();
458 if (interface_blocs_ok)
460 for (i = 0; i < eqs.size(); i++)
463 if (!eqs[i]->discretisation().is_poly_family())
465 for (j = 0; j < eqs.size(); j++)
468 if (eqs[i]->probleme().
le_nom().getString() != eqs[j]->probleme().
le_nom().getString())
471 mats[i][nom_j.
getString()]->ajouter_multvect(inconnues_parts[j], residu_parts[i]);
476 if (eqs[0]->discretisation().is_poly_family()) Mglob.
ajouter_multvect(inconnues, residus);
478 else for(i = 0; i < eqs.size(); i++)
479 for (j = 0; j < eqs.size(); j++)
482 eqs[i]->
ajouter_termes_croises(inconnues_parts[i], eqs[j]->probleme(), inconnues_parts[j], residu_parts[i]);
497 ArrOfDouble dudt_carres((
int)eqs.size());
498 for(i = 0; i < eqs.size(); i++)
500 dudt_parts[i] -= inconnues_parts[i];
501 dudt_carres[(int)i] = local_carre_norme_vect(dudt_parts[i]);
506 bool converge =
true;
507 for(i = 0; i < eqs.size(); i++)
509 double dudt_norme = sqrt(dudt_carres[(
int)i]);
512 converge &= (dudt_norme < seuil_convg);
515 Cout<<eqs[i]->
que_suis_je()<<
" is not converged at the implicit iteration "<<nb_iter<<
" ( ||uk-uk-1|| = "<<dudt_norme<<
" > implicit threshold "<<seuil_convg<<
" )"<<finl;
516 if (nb_iter>=10) Cout <<
"Consider lowering facsec_max value. Look at the reference manual for advice to set facsec_max value according to the problem type." << finl;
519 Cout<<eqs[i]->
que_suis_je()<<
" is converged at the implicit iteration "<<nb_iter<<
" ( ||uk-uk-1|| = "<<dudt_norme<<
" < implicit threshold "<<seuil_convg<<
" )"<<finl;
524 eqs[i]->
inconnue().Champ_base::changer_temps(t);
526 for(i = 0; i < eqs.size(); i++) eqs[i]->probleme().
mettre_a_jour(eqs[i]->schema_temps().temps_courant());
529 for (i = 0; i < eqs.size(); i++)
530 for (j = 0; j < eqs.size(); j++) ref_cast(
Matrice_Morse, Mglob.
get_bloc(i, j).valeur()).get_set_coeff().reset();
537 int deux_entrees = 0;
538 if (correction_en_vitesse.
nb_dim()==2) deux_entrees = 1;
539 gradient->multvect(correction_en_pression,gradP);
542 nb_comp = correction_en_vitesse.
dimension(1);
544 ConstDoubleTab_parts part(correction_en_vitesse);
545 int nb_ligne_reel = part[0].dimension(0);
550 for(i=0; i<nb_ligne_reel; i++)
552 for (j=0; j<nb_comp; j++)
555 correction_en_vitesse(i) = -gradP(i)/matrice(i*nb_comp+j,i*nb_comp+j);
561 for(i=0; i<nb_ligne_reel; i++)
562 for (j=0; j<nb_comp; j++)
565 correction_en_vitesse(i,j) = -gradP(i,j)/matrice(i*nb_comp+j,i*nb_comp+j);
577 double dt,
Matrice_Morse& matrice,
double seuil_resol,DoubleTrav& secmem,
int nb_ite,
int& converge,
int& ok)
584 DoubleTrav gradP(current);
585 DoubleTrav correction_en_pression(pression);
586 DoubleTrav correction_en_vitesse(current);
587 DoubleTrav resu(current);
601 gradient.calculer(pression,gradP);
632 solveur_pression_->reinit();
644 divergence.ajouter(current,secmem);
647 divergence.calculer(current,secmem);
656 secmem,correction_en_pression);
665 pression.ajoute(
beta_,correction_en_pression);
666 eqnNS.assembleur_pression()->modifier_solution(pression);
668 current += correction_en_vitesse;
671 diviser_par_rho_np1_face(eqn,current);
DoubleTab & futur(int i=1) override
Renvoie les valeurs du champs a l'instant t+i.
DoubleTab & passe(int i=1) override
Renvoie les valeurs du champs a l'instant t-i.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual bool is_poly_family() const
virtual void imposer_cond_lim(Champ_Inc_base &, double)=0
Class defining operators and methods for all reading operation in an input flow (file,...
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
virtual int equation_non_resolue() const
virtual void dimensionner_termes_croises(Matrice_Morse &matrice, const Probleme_base &autre_pb, int nl, int nc)
virtual void ajouter_termes_croises(const DoubleTab &inco, const Probleme_base &autre_pb, const DoubleTab &autre_inco, DoubleTab &resu) const
virtual const Milieu_base & milieu() const =0
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.
virtual void valider_iteration()
methode virtuelle permettant de corriger l'onconnue lors d'iterations implicites par exemple K-eps do...
virtual const Champ_Inc_base & inconnue() const =0
virtual void contribuer_termes_croises(const DoubleTab &inco, const Probleme_base &autre_pb, const DoubleTab &autre_inco, Matrice_Morse &matrice) const
virtual void mettre_a_jour(double temps)
La valeur de l'inconnue sur le pas de temps a ete calculee.
virtual void assembler_avec_inertie(Matrice_Morse &mat_morse, const DoubleTab &present, DoubleTab &secmem)
virtual bool positive_unkown()
virtual DoubleTab & derivee_en_temps_inco(DoubleTab &)
Returns the time derivative of the unknown I of the equation: dI/dt = M-1*(sum(operators(I) + sources...
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.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
virtual void dimensionner_matrice(Matrice_Morse &mat_morse)
virtual int has_interface_blocs() const
virtual double calculer_pas_de_temps() const
Calcul du prochain pas de temps.
const Nom & le_nom() const override
Renvoie le nom du champ.
classe Fluide_Dilatable_base Cette classe represente un d'un fluide dilatable,
virtual void secmembre_divU_Z(DoubleTab &) const =0
const DoubleTab & rho_face_np1() const
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.
: Cette classe est un OWN_PTR mais l'objet pointe est partage entre plusieurs
void copy(const MD_Vector_base &)
construction d'un objet MD_Vector par copie d'un objet existant.
virtual DoubleVect & ajouter_multvect(const DoubleVect &x, DoubleVect &r) const
Operation de multiplication-accumulation (saxpy) matrice vecteur.
virtual void dimensionner(int N, int M)
virtual const Matrice & get_bloc(int i, int j) const
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
void dimensionner(int n, _SIZE_ nnz)
Size the matrix with n lines and n columns and nnz zero-values coefficients.
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
Classe Matrice Classe generique de la hierarchie des matrices.
virtual int check_unknown_range() const
Une chaine de caractere (Nom) en majuscules.
Un tableau d'objets de la classe Motcle.
int search(const Motcle &t) const
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 reassembler_pression_si_necessaire()
Matrice & matrice_pression()
SolveurSys & solveur_pression()
Renvoie le solveur en pression (version const).
Champ_Inc_base & pression()
class Nom Une chaine de caractere pour nommer les objets de TRUST
virtual int debute_par(const char *const n) const
const std::string & getString() const
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
virtual const Nom & le_nom() const
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
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
double & seuil_verification_solveur()
double & seuil_diffusion_implicite()
int equation_frequence_resolue(double t)
bool & calcul_explicite()
double & seuil_convergence_implicite()
double & seuil_test_preliminaire_solveur()
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
bool is_dilatable() const
virtual void mettre_a_jour(double temps)
Effectue une mise a jour en temps du probleme.
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
static void mp_sum_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
classe SETS (semi-implicite + etapes de stabilisation, a la TRACE)
int diffusion_implicite() const
Renvoie 1 si le schema en temps a ete lu diffusion_implicite.
double temps_courant() const
Renvoie le temps courant.
int & set_diffusion_implicite()
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
double seuil_diffusion_implicite() const
int nb_pas_dt() const
Renvoie le nombre de pas de temps effectues.
double & set_seuil_diffusion_implicite()
std::map< list_of_eq_ptr_t, Matrice_Bloc > mbloc
void iterer_NS(Equation_base &, DoubleTab ¤t, DoubleTab &pression, double, Matrice_Morse &, double, DoubleTrav &, int nb_iter, int &converge, int &ok) override
Entree & lire(const Motcle &, Entree &) override
bool iterer_eqs(LIST(OBS_PTR(Equation_base)) eqs, int compteur, int &ok) override
void calculer_correction_en_vitesse(const DoubleTrav &correction_en_pression, DoubleTrav &gradP, DoubleTrav &correction_en_vitesse, const Matrice_Morse &matrice, const Operateur_Grad &gradient)
std::vector< intptr_t > list_of_eq_ptr_t
bool iterer_eqn(Equation_base &equation, const DoubleTab &inconnue, DoubleTab &result, double dt, int numero_iteration, int &ok) override
Entree & lire(const Motcle &, Entree &) override
void assembler_matrice_pression_implicite(Equation_base &eqn_NS, const Matrice_Morse &matrice, Matrice &matrice_en_pression_2)
class SolveurSys Un SolveurSys represente n'importe qu'elle classe
int resoudre_systeme(const Matrice_Base &matrice, const DoubleVect &secmem, DoubleVect &solution)
int is_seuil_convg_variable
Parametre_implicite & get_and_set_parametre_implicite(Equation_base &eqn)
Classe de base des flux de sortie.
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension_tot(int) const override
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_rw()
_SIZE_ dimension(int d) const
_SIZE_ size_totale() const
void ajoute(_SCALAR_TYPE_ alpha, const TRUSTVect &y, Mp_vect_options opt=VECT_ALL_ITEMS)
virtual const MD_Vector & get_md_vector() const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")