mise en place de la gestion des interuptions (d'Herezh) pour l'assemblage des seconds membres
This commit is contained in:
parent
a05683f958
commit
ab330c7860
1 changed files with 196 additions and 74 deletions
|
@ -1799,13 +1799,12 @@ bool Algori::RaidSmEner(LesMaillages * lesMail,Assemblage& Ass,Vecteur & vglobin
|
|||
// on balaie les éléments nécessaires
|
||||
list <int >::const_iterator il,ilfin=list_elem_cpu.end();
|
||||
for (il = dernier_il;il != ilfin;il++)
|
||||
{ int ne = (*il);
|
||||
// on récupère un signal du process 0
|
||||
{ // on récupère un signal du process 0
|
||||
// on considère qu'il y a eu au moins un passage
|
||||
tempsRaidSmEner.Arret_du_comptage();
|
||||
temps_attente_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
if (reqs1.active()) reqs1.wait();
|
||||
temps_attente_matSm.Arret_du_comptage(); // fin comptage cpu
|
||||
tempsRaidSmEner.Arret_du_comptage();
|
||||
temps_transfert_court_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
DeuxEntiers num_el_et_mail(gestion_exception,-1);
|
||||
// on transmet les numéros d'élément et de maillage
|
||||
|
@ -1926,14 +1925,14 @@ bool Algori::RaidSmEner(LesMaillages * lesMail,Assemblage& Ass,Vecteur & vglobin
|
|||
#ifdef UTILISATION_MPI
|
||||
if (proc_en_cours == 0)
|
||||
#endif
|
||||
if (ParaGlob::NiveauImpression() >= 10)
|
||||
{ if (ParaGlob::NiveauImpression() >= 10)
|
||||
{ string entete = " affichage de la matrice de raideur (puissance interne) avant conditions limites";
|
||||
matglob.Affichage_ecran(entete);
|
||||
entete = " affichage du second membre (puissance interne) avant condition limites ";
|
||||
vglobin.Affichage_ecran(entete);
|
||||
};
|
||||
if (permet_affichage >3) cout << "\n -- fin calcul second membre et raideur " << flush;
|
||||
|
||||
};
|
||||
tempsRaidSmEner.Arret_du_comptage(); // fin comptage cpu
|
||||
}; // fin du cas sans exception
|
||||
// retour indiquant si oui ou non il y a eu des exceptions
|
||||
|
@ -1943,6 +1942,7 @@ bool Algori::RaidSmEner(LesMaillages * lesMail,Assemblage& Ass,Vecteur & vglobin
|
|||
// calcul du second membre pour tous les maillages ainsi que des énergies totales
|
||||
bool Algori::SecondMembreEnerg(LesMaillages * lesMail,Assemblage& Ass,Vecteur & vglobin)
|
||||
{tempsSecondMembreEnerg.Mise_en_route_du_comptage(); // comptage cpu
|
||||
bool retour = true; // init par défaut
|
||||
// on doit initialiser les temps globaux de loi de comp et de métrique car
|
||||
// on va ajouter ensuite des temps qui eux mêmes globalisent ce qui se passe à chaque pti
|
||||
// Temps_CPU_HZpp tps_zero; // un temps d'initialisation
|
||||
|
@ -1965,18 +1965,23 @@ bool Algori::SecondMembreEnerg(LesMaillages * lesMail,Assemblage& Ass,Vecteur &
|
|||
mpi::request reqs2;
|
||||
Vecteur deux_faux_entiers(2);
|
||||
bool premier_passage = true;
|
||||
int proc_en_cours = ParaGlob::Monde()->rank();
|
||||
int gestion_exception = 0; // pour la gestion
|
||||
#endif
|
||||
// on gère les exceptions éventuelles en mettant le bloc sous surveillance
|
||||
try
|
||||
int nbMailMax = lesMail->NbMaillage();
|
||||
int dernier_nbMail=1; // pour la gestion d'erreur
|
||||
list <int >::const_iterator dernier_il; // pour la gestion d'erreur
|
||||
try
|
||||
{// boucle sur les elements
|
||||
int nbMailMax = lesMail->NbMaillage();
|
||||
#ifndef UTILISATION_MPI
|
||||
// cas d'un calcul mono CPU
|
||||
for (int nbMail =1; nbMail<= nbMailMax; nbMail++)
|
||||
for (int nbMail =1; nbMail<= nbMailMax; nbMail++,dernier_nbMail++)
|
||||
{int nemax = lesMail->Nombre_element(nbMail);
|
||||
for (int ne=1; ne<= nemax;ne++)
|
||||
{
|
||||
#else
|
||||
#else
|
||||
// cas d'un calcul multi-CPU
|
||||
// on va parcourir les éléments associés au cpu
|
||||
// on récupère la distribution d'éléments concernant le cpu en cours
|
||||
|
@ -1989,7 +1994,7 @@ bool Algori::SecondMembreEnerg(LesMaillages * lesMail,Assemblage& Ass,Vecteur &
|
|||
{const list <int >& list_elem_cpu= tab_list_elem_cpu(nbMail); // pour simplifier
|
||||
// on balaie les éléments nécessaires
|
||||
list <int >::const_iterator il,ilfin=list_elem_cpu.end();
|
||||
for (il = list_elem_cpu.begin();il != ilfin;il++)
|
||||
for (il = dernier_il = list_elem_cpu.begin();il != ilfin;il++,dernier_il++)
|
||||
{ int ne = (*il);
|
||||
// on récupère un signal du process 0
|
||||
temps_attente_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
|
@ -2029,15 +2034,14 @@ bool Algori::SecondMembreEnerg(LesMaillages * lesMail,Assemblage& Ass,Vecteur &
|
|||
Ass.AssemSM (vglobin,*res,el.TableauDdl(),taN); // du second membre
|
||||
#else
|
||||
// cas d'un calcul parallèle, et CPU != 0
|
||||
int num_process = ParaGlob::Monde()->rank();
|
||||
if (num_process != 0)
|
||||
if (proc_en_cours != 0)
|
||||
{tempsSecondMembreEnerg.Arret_du_comptage();
|
||||
temps_transfert_court_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
// DeuxEntiers num_el_et_mail(el.Num_elt(),el.Num_maillage());
|
||||
deux_faux_entiers(1) = (double ) el.Num_elt();
|
||||
deux_faux_entiers(2) = (double ) el.Num_maillage();
|
||||
// on transmet les numéros d'élément et de maillage
|
||||
reqs1 = deux_faux_entiers.Ienvoi_MPI(0, 24);
|
||||
reqs1 = deux_faux_entiers.Ienvoi_MPI(0, 24111);
|
||||
// reqs1 = ParaGlob::Monde()->isend(0, 24, num_el_et_mail);
|
||||
temps_transfert_court_matSm.Arret_du_comptage(); // fin comptage cpu
|
||||
// puis on transmets le vecteur résidu
|
||||
|
@ -2046,7 +2050,7 @@ bool Algori::SecondMembreEnerg(LesMaillages * lesMail,Assemblage& Ass,Vecteur &
|
|||
reqs2.wait();
|
||||
temps_attente_matSm.Arret_du_comptage(); // fin comptage cpu
|
||||
temps_transfert_long_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
reqs2 = res->Ienvoi_MPI(0,25);
|
||||
reqs2 = res->Ienvoi_MPI(0,25111);
|
||||
temps_transfert_long_matSm.Arret_du_comptage(); // fin comptage cpu
|
||||
tempsSecondMembreEnerg.Mise_en_route_du_comptage();
|
||||
};
|
||||
|
@ -2083,65 +2087,124 @@ bool Algori::SecondMembreEnerg(LesMaillages * lesMail,Assemblage& Ass,Vecteur &
|
|||
}
|
||||
catch (ErrJacobienNegatif_ElemMeca excep)
|
||||
// cas d'un jacobien négatif "a prendre en compte"
|
||||
{ phase_de_convergence = -5; a_converge = false; return false; }
|
||||
catch (ErrVarJacobienMini_ElemMeca excep)
|
||||
{
|
||||
#ifndef UTILISATION_MPI
|
||||
phase_de_convergence = -5; a_converge = false; retour = false;
|
||||
#else
|
||||
gestion_exception = 1;
|
||||
#endif
|
||||
}
|
||||
catch (ErrVarJacobienMini_ElemMeca excep)
|
||||
// cas d'une variation de jacobien trop importante
|
||||
{ phase_de_convergence = -6; a_converge = false; return false; }
|
||||
{
|
||||
#ifndef UTILISATION_MPI
|
||||
phase_de_convergence = -6; a_converge = false; retour = false;
|
||||
#else
|
||||
gestion_exception = 2;
|
||||
#endif
|
||||
}
|
||||
catch (ErrNonConvergence_loiDeComportement excep)
|
||||
// cas d'une d'une erreur survenue à cause d'une non convergence pour la résolution
|
||||
// d'une loi de comportement incrémentale
|
||||
{ phase_de_convergence = -7; a_converge = false;
|
||||
{
|
||||
#ifndef UTILISATION_MPI
|
||||
cout << "\n non convergence sur une loi de comportement ";
|
||||
return false;
|
||||
switch (excep.cas)
|
||||
{case 1: phase_de_convergence = -8; break;
|
||||
case 0: default : phase_de_convergence = -7; break;
|
||||
};
|
||||
a_converge = false; retour = false;
|
||||
#else
|
||||
switch (excep.cas)
|
||||
{case 1: gestion_exception = 3; break;
|
||||
case 0: default : gestion_exception = 4; break;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
catch (ErrCalculFct_nD)
|
||||
// cas d'une d'une erreur survenue à cause d'une erreur sur le calcul d'une fct nD
|
||||
// au niveau du chargement
|
||||
{ phase_de_convergence = -10; a_converge = false;
|
||||
{
|
||||
#ifndef UTILISATION_MPI
|
||||
phase_de_convergence = -10; a_converge = false;
|
||||
cout << "\n *** erreur exception genere par une fonction nD utilisee en chargement ";
|
||||
return false;
|
||||
retour = false;
|
||||
#else
|
||||
gestion_exception = 5;
|
||||
#endif
|
||||
}
|
||||
catch (ErrSortie)
|
||||
// cas d'une direction voulue vers la sortie
|
||||
// on relance l'interuption pour le niveau supérieur
|
||||
{ ErrSortie toto;
|
||||
{
|
||||
#ifndef UTILISATION_MPI
|
||||
tempsSecondMembreEnerg.Arret_du_comptage();
|
||||
ErrSortie toto;
|
||||
throw (toto);
|
||||
#else
|
||||
gestion_exception = 6;
|
||||
#endif
|
||||
}
|
||||
catch (ErrSortieFinale)
|
||||
// cas d'une direction voulue vers la sortie
|
||||
// on relance l'interuption pour le niveau supérieur
|
||||
{ ErrSortieFinale toto;
|
||||
tempsSecondMembreEnerg.Arret_du_comptage(); // fin comptage cpu
|
||||
throw (toto);
|
||||
}
|
||||
{
|
||||
#ifndef UTILISATION_MPI
|
||||
tempsSecondMembreEnerg.Arret_du_comptage();
|
||||
ErrSortieFinale toto;
|
||||
throw (toto);
|
||||
#else
|
||||
gestion_exception = 7;
|
||||
#endif
|
||||
}
|
||||
catch ( ... )
|
||||
{ if (ParaGlob::NiveauImpression() >= 1)
|
||||
{cout << "\n warning: exception generee par un element mais dont la prise en compte "
|
||||
<< " n'est pas prevu !, on ne fait rien et on continue le calcul";
|
||||
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::SecondMembreEnerg(..";
|
||||
};
|
||||
}
|
||||
// affichage éventuelle du second membre
|
||||
if (ParaGlob::NiveauImpression() >= 10)
|
||||
{ string entete = " affichage du second membre (puissance interne) avant conditions limites ";
|
||||
vglobin.Affichage_ecran(entete);
|
||||
};
|
||||
if (permet_affichage >3) cout << "\n -- fin calcul second membre " << flush;
|
||||
//---- debug
|
||||
// if (pa.CalVolTotalEntreSurfaceEtPlansRef())
|
||||
// { //Tableau <Coordonnee> vol_total2D_avec_plan_ref; // volume total entre la surface et : yz, xz,xy
|
||||
// cout << "\n debug Algo::SecondMembreEnerg ";
|
||||
// cout << "\n vol_total2D_avec_plan_ref "
|
||||
// << vol_total2D_avec_plan_ref(1) << flush;
|
||||
// };
|
||||
//---- fin debug
|
||||
|
||||
// -- calcul des intégrales éventuelles avec transfert en global
|
||||
lesMail->Integration();
|
||||
{
|
||||
#ifndef UTILISATION_MPI
|
||||
if (ParaGlob::NiveauImpression() >= 1)
|
||||
{cout << "\n warning: exception generee par un element mais dont la prise en compte "
|
||||
<< " n'est pas prevu !, on ne fait rien et on continue le calcul";
|
||||
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::SecondMembreEnerg(..";
|
||||
};
|
||||
#else
|
||||
gestion_exception = 8;
|
||||
#endif
|
||||
}
|
||||
|
||||
tempsSecondMembreEnerg.Arret_du_comptage(); // fin comptage cpu
|
||||
#ifdef UTILISATION_MPI
|
||||
if (ParaGlob::Monde()->rank() == 0)
|
||||
|
||||
tempsSecondMembreEnerg.Arret_du_comptage(); // fin comptage cpu
|
||||
#ifdef UTILISATION_MPI
|
||||
// tout d'abord on gère le cas des exceptions
|
||||
if (proc_en_cours != 0)
|
||||
{if (gestion_exception != 0)
|
||||
{// on transmets l'info au proc 0 avec le même protocole que pour un résultat
|
||||
// on boucle sur tous les derniers éléments qui n'ont pas été calculé
|
||||
// ceci pour que proc 0 puisse correctement traiter tous les éléments
|
||||
const Tableau < list <int > >& tab_list_elem_cpu = distribution_CPU_algo.List_element_CPU_en_cours();
|
||||
int nb_mail_distrib = tab_list_elem_cpu.Taille();
|
||||
for (int nbMail =dernier_nbMail; nbMail<= nb_mail_distrib; nbMail++)
|
||||
{const list <int >& list_elem_cpu= tab_list_elem_cpu(nbMail); // pour simplifier
|
||||
// on balaie les éléments nécessaires
|
||||
list <int >::const_iterator il,ilfin=list_elem_cpu.end();
|
||||
for (il = dernier_il;il != ilfin;il++)
|
||||
{ // on récupère un signal du process 0
|
||||
// on considère qu'il y a eu au moins un passage
|
||||
tempsSecondMembreEnerg.Arret_du_comptage();
|
||||
temps_attente_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
if (reqs1.active()) reqs1.wait();
|
||||
temps_attente_matSm.Arret_du_comptage(); // fin comptage cpu
|
||||
temps_transfert_court_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
deux_faux_entiers(1) = gestion_exception;
|
||||
deux_faux_entiers(2) = -1;
|
||||
// on transmet au proc 0
|
||||
reqs1 = deux_faux_entiers.Ienvoi_MPI(0, 24111);
|
||||
temps_transfert_court_matSm.Arret_du_comptage(); // fin comptage cpu
|
||||
tempsSecondMembreEnerg.Mise_en_route_du_comptage();
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if (proc_en_cours == 0)
|
||||
{ tempsSecondMembreEnerg.Mise_en_route_du_comptage(); // comptage cpu
|
||||
// récup du nombre total d'éléments, cumul sur tous les maillages
|
||||
int total_elem = distribution_CPU_algo.NB_total_element();
|
||||
|
@ -2154,7 +2217,7 @@ bool Algori::SecondMembreEnerg(LesMaillages * lesMail,Assemblage& Ass,Vecteur &
|
|||
temps_transfert_court_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
// DeuxEntiers num_el_et_mail;
|
||||
// mpi::request reqs1 = ParaGlob::Monde()->irecv(mpi::any_source, 24, num_el_et_mail);
|
||||
reqs1 = deux_faux_entiers.Irecup_MPI(mpi::any_source, 24);
|
||||
reqs1 = deux_faux_entiers.Irecup_MPI(mpi::any_source, 24111);
|
||||
mpi::status stat = reqs1.wait(); // on attend que le conteneur soit rempli
|
||||
temps_transfert_court_matSm.Arret_du_comptage(); // fin comptage cpu
|
||||
tempsSecondMembreEnerg.Mise_en_route_du_comptage(); // comptage cpu
|
||||
|
@ -2164,30 +2227,77 @@ bool Algori::SecondMembreEnerg(LesMaillages * lesMail,Assemblage& Ass,Vecteur &
|
|||
// temps_attente.Arret_du_comptage(); // fin comptage cpu
|
||||
int ne = (int) deux_faux_entiers(1); //num_el_et_mail.un; // numero d'identification de l'element
|
||||
int nbMail = (int) deux_faux_entiers(2);//num_el_et_mail.deux; // numéro de maillage
|
||||
// d'où l'élément
|
||||
ElemMeca & el = *((ElemMeca*) &lesMail->Element_LesMaille(nbMail,ne));
|
||||
// récupération des conteneurs ad hoc vecteur et raideur
|
||||
int source = stat.source(); // récupération du numéro de la source
|
||||
Vecteur * residu = el.Conteneur_Residu();
|
||||
tempsSecondMembreEnerg.Arret_du_comptage();
|
||||
temps_transfert_long_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
mpi::request reqs2 = residu->Irecup_MPI(source, 25);
|
||||
reqs2.wait(); // on attend que le conteneur soit rempli
|
||||
temps_transfert_long_matSm.Arret_du_comptage(); // fin comptage cpu
|
||||
tempsSecondMembreEnerg.Mise_en_route_du_comptage();
|
||||
Tableau<Noeud *>& taN = el.Tab_noeud(); // tableau de noeuds de l'el
|
||||
// --- assemblage
|
||||
Ass.AssemSM (vglobin,*residu,el.TableauDdl(),taN); // du second membre
|
||||
if (nbMail > 0)
|
||||
// cas normal
|
||||
{
|
||||
// d'où l'élément
|
||||
ElemMeca & el = *((ElemMeca*) &lesMail->Element_LesMaille(nbMail,ne));
|
||||
// récupération des conteneurs ad hoc vecteur et raideur
|
||||
int source = stat.source(); // récupération du numéro de la source
|
||||
Vecteur * residu = el.Conteneur_Residu();
|
||||
tempsSecondMembreEnerg.Arret_du_comptage();
|
||||
temps_transfert_long_matSm.Mise_en_route_du_comptage(); // comptage cpu
|
||||
mpi::request reqs2 = residu->Irecup_MPI(source, 25111);
|
||||
reqs2.wait(); // on attend que le conteneur soit rempli
|
||||
temps_transfert_long_matSm.Arret_du_comptage(); // fin comptage cpu
|
||||
tempsSecondMembreEnerg.Mise_en_route_du_comptage();
|
||||
Tableau<Noeud *>& taN = el.Tab_noeud(); // tableau de noeuds de l'el
|
||||
// --- assemblage
|
||||
Ass.AssemSM (vglobin,*residu,el.TableauDdl(),taN); // du second membre
|
||||
}
|
||||
else // la suite concerne le cas d'une exception
|
||||
{// s'il y a une exception fatal, cela va arrêter proc 0 et donc tous les autres
|
||||
gestion_exception = ne;
|
||||
switch (gestion_exception)
|
||||
{case 1: phase_de_convergence = -5; a_converge = false; retour = false; break;
|
||||
case 2: phase_de_convergence = -6; a_converge = false; retour = false; break;
|
||||
case 3: phase_de_convergence = -8; retour = false; break;
|
||||
case 4: phase_de_convergence = -7; retour = false; break;
|
||||
case 5: phase_de_convergence = -10; a_converge = false;
|
||||
cout << "\n *** erreur exception genere par une fonction nD utilisee en chargement ";
|
||||
retour = false; break;
|
||||
case 6: {tempsRaidSmEner.Arret_du_comptage(); ErrSortie toto; throw (toto);}
|
||||
case 7: {tempsRaidSmEner.Arret_du_comptage(); ErrSortieFinale toto;; throw (toto);}
|
||||
case 8: { if (ParaGlob::NiveauImpression() >= 1)
|
||||
{cout << "\n warning: exception generee par un element mais dont la prise en compte "
|
||||
<< " n'est pas prevu !, on ne fait rien et on continue le calcul";
|
||||
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::SecondMembreEnerg(..";
|
||||
};break;
|
||||
}
|
||||
default:
|
||||
cout << "\n erreur en retour d'exception: on a lue gestion_exception = "<< gestion_exception
|
||||
<< " la gestion de ce cas n'existe pas !!! on stop l'execution ..."
|
||||
<< "\n Algori::SecondMembreEnerg(..";
|
||||
Sortie(1);
|
||||
}; // fin de la gestion des différents cas d'exception
|
||||
// arrivée ici on continue la boucle du while
|
||||
tempsRaidSmEner.Arret_du_comptage(); // fin comptage cpu
|
||||
};
|
||||
// on incrémente le nombre d'élément traité
|
||||
nb_elem_deja_calcule++;
|
||||
};
|
||||
tempsSecondMembreEnerg.Arret_du_comptage(); // fin comptage cpu
|
||||
};
|
||||
// récupération de toutes les énergies par le cpu 0
|
||||
tempsSecondMembreEnerg.Arret_du_comptage(); // fin comptage cpu
|
||||
Algori::Passage_energiesEtVolumes();
|
||||
tempsSecondMembreEnerg.Mise_en_route_du_comptage();
|
||||
#endif
|
||||
// à la sortie du calcul on transmets la gestion d'excep
|
||||
// on transmet à tous les proc l'indicateur calcul_a_effectuer
|
||||
broadcast(*ParaGlob::Monde(), gestion_exception, 0);
|
||||
// on vérifie que ce n'est pas une sortie due à une exception
|
||||
// si c'est ok on continue
|
||||
if (gestion_exception != 0)
|
||||
retour = false;
|
||||
#endif
|
||||
if(retour)
|
||||
{tempsSecondMembreEnerg.Mise_en_route_du_comptage(); // comptage cpu
|
||||
// -- calcul des intégrales éventuelles avec transfert en global
|
||||
lesMail->Integration();
|
||||
|
||||
#ifdef UTILISATION_MPI
|
||||
tempsSecondMembreEnerg.Arret_du_comptage(); // fin comptage cpu
|
||||
// récupération de toutes les énergies par le cpu 0
|
||||
Algori::Passage_energiesEtVolumes();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
tempsSecondMembreEnerg.Mise_en_route_du_comptage();
|
||||
// -- on transfert en global les énergies internes
|
||||
|
@ -2195,10 +2305,22 @@ bool Algori::SecondMembreEnerg(LesMaillages * lesMail,Assemblage& Ass,Vecteur &
|
|||
Transfert_ParaGlob_energies_hourglass_bulk_stab();
|
||||
// idem pour les volumes entre plans
|
||||
Transfert_ParaGlob_volume_entre_plans();
|
||||
tempsSecondMembreEnerg.Arret_du_comptage(); // fin comptage cpu
|
||||
|
||||
// retour indiquant que tout c'est bien passé
|
||||
return true ;
|
||||
// affichage éventuelle du second membre
|
||||
#ifdef UTILISATION_MPI
|
||||
if (proc_en_cours == 0)
|
||||
#endif
|
||||
{if (ParaGlob::NiveauImpression() >= 10)
|
||||
{ string entete = " affichage du second membre (puissance interne) avant conditions limites ";
|
||||
vglobin.Affichage_ecran(entete);
|
||||
};
|
||||
if (permet_affichage >3) cout << "\n -- fin calcul second membre " << flush;
|
||||
};
|
||||
tempsSecondMembreEnerg.Arret_du_comptage(); // fin comptage cpu
|
||||
}; // fin du cas sans exception
|
||||
|
||||
// retour indiquant si oui ou non il y a eu des exceptions
|
||||
return retour ;
|
||||
};
|
||||
|
||||
// Mise à jour de la raideur et du second membre pour le contact
|
||||
|
|
Loading…
Reference in a new issue