V 7.020 : intégration en cours de la parallèlisation MPI dans le contact, version intermédiaire

This commit is contained in:
Gérard Rio 2023-12-15 19:17:23 +01:00
parent d599e5fcb0
commit b670e8f9b8
28 changed files with 1548 additions and 472 deletions

View file

@ -992,12 +992,19 @@ bool Algori::Gestion_stockage_et_renumerotation_avec_contact(bool premier_calcul
{// si demandé, renumérotation en fonction des éléments en contact
if (ParaGlob::param->ParaAlgoControleActifs().Optimisation_numerotation())
{ // récup des connexions entre noeud dues aux contacts
const Tableau <Condilineaire>& tabCondLine= lescontacts->ConnectionCLL();
if (tabCondLine.Taille() > 0) //cas où il faut en tenir compte
list <Condilineaire>& listCondLine= lescontacts->ConnectionCLL();
if (listCondLine.size() > 0) //cas où il faut en tenir compte
{// récup des connexions entre noeuds dues aux CLL externes
Tableau <Tableau <Condilineaire> > tabCLL(lesCondLim->ConnectionCLL(lesMail,lesRef));
int tailtabCLL = tabCLL.Taille();tabCLL.Change_taille(tailtabCLL+1);
tabCLL(tailtabCLL+1) = tabCondLine; // ajout de la partie contact
// tabCLL(tailtabCLL+1) = listCondLine;
// ajout de la partie contact
Tableau <Condilineaire>& tabCLL_contact = tabCLL(tailtabCLL+1); // pour simplifier
tabCLL_contact.Change_taille(listCondLine.size());
list <Condilineaire>::iterator il,ilfin = listCondLine.end();
int i=1;
for (il = listCondLine.begin();il != ilfin;il++,i++)
tabCLL_contact(i) = (*il);
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 2))
cout << "\n -- renumerotation en tenant compte des elements de contact ";
// appel de l'utilitaire dans lesMaillages: avec mise à jour dans la foulée de l'assemblage
@ -1029,13 +1036,19 @@ bool Algori::Gestion_stockage_et_renumerotation_avec_contact(bool premier_calcul
{if (nouvelle_situation_contact)
{if (ParaGlob::param->ParaAlgoControleActifs().Optimisation_numerotation())
{ // récup des connexions entre noeud dues aux contacts
const Tableau <Condilineaire>& tabCondLine= lescontacts->ConnectionCLL();
if (tabCondLine.Taille() > 0) //cas où il faut en tenir compte
list <Condilineaire>& listCondLine= lescontacts->ConnectionCLL();
if (listCondLine.size() > 0) //cas où il faut en tenir compte
{// récup des connexions entre noeuds dues aux CLL externes: comme les cll ont été mises à jour
// on récupère directement le tableau
Tableau <Tableau <Condilineaire> > tabCLL(lesCondLim->Tab_CLinApplique());
int tailtabCLL = tabCLL.Taille();tabCLL.Change_taille(tailtabCLL+1);
tabCLL(tailtabCLL+1) = tabCondLine; // ajout de la partie contact
// ajout de la partie contact
Tableau <Condilineaire>& tabCLL_contact = tabCLL(tailtabCLL+1); // pour simplifier
tabCLL_contact.Change_taille(listCondLine.size());
list <Condilineaire>::iterator il,ilfin = listCondLine.end();
int i=1;
for (il = listCondLine.begin();il != ilfin;il++,i++)
tabCLL_contact(i) = (*il);
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 2))
cout << "\n -- renumerotation en tenant compte d'un changement de contact ";
// appel de l'utilitaire dans lesMaillages: avec mise à jour dans la foulée de l'assemblage
@ -1107,7 +1120,7 @@ bool Algori::Gestion_stockage_et_renumerotation_sans_contact(LesContacts* lesco
{ // récup des connexions entre noeuds dues aux CLL externes
Tableau <Tableau <Condilineaire> > tabCLL(lesCondLim->ConnectionCLL(lesMail,lesRef));
// int tailtabCLL = tabCLL.Taille();tabCLL.Change_taille(tailtabCLL+1);
// tabCLL(tailtabCLL+1) = tabCondLine; // ajout de la partie contact
// tabCLL(tailtabCLL+1) = listCondLine; // ajout de la partie contact
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 2))
cout << "\n -- renumerotation des pointeurs d'assemblage en tenant compte des CLL ";
// appel de l'utilitaire dans lesMaillages: avec mise à jour dans la foulée de l'assemblage

View file

@ -53,8 +53,10 @@ void AlgoriCombine::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
@ -129,8 +131,10 @@ void AlgoriCombine::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
{ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
tab_algo(i)->InitAlgorithme(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor
@ -187,8 +191,10 @@ void AlgoriCombine::MiseAJourAlgo(ParaGlob * paraGlob,LesMaillages * lesMail,
{ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
tab_algo(i)->MiseAJourAlgo(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor
@ -263,8 +269,10 @@ void AlgoriCombine::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
@ -334,8 +342,10 @@ void AlgoriCombine::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
@ -412,8 +422,10 @@ void AlgoriCombine::FinCalcul(ParaGlob * paraGlob,LesMaillages * lesMail,LesRefe
{ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());

View file

@ -963,8 +963,10 @@ void AlgoriRungeKutta::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif

View file

@ -755,9 +755,9 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -779,7 +779,7 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir

View file

@ -536,9 +536,9 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -560,7 +560,7 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
@ -805,8 +805,10 @@ void AlgoriDynaExpli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
@ -1419,9 +1421,9 @@ void AlgoriDynaExpli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if ((pa.ContactType())&&(compteur_demarrage > 0))
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -1444,7 +1446,7 @@ void AlgoriDynaExpli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if ((pa.ContactType()==1)&&(compteur_demarrage > 0)) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
// ***donc pour l'instant du a un bug je commente

View file

@ -296,8 +296,10 @@ void AlgoriDynaExpli_zhai::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * les
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
@ -881,9 +883,9 @@ void AlgoriDynaExpli_zhai::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMa
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -906,7 +908,7 @@ void AlgoriDynaExpli_zhai::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMa
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,(vglobaal),Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,(vglobaal),*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,(vglobaal),*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
// ***donc pour l'instant du a un bug je commente

View file

@ -285,8 +285,10 @@ void Algori_chung_lee::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
@ -806,9 +808,9 @@ void Algori_chung_lee::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail,
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -831,7 +833,7 @@ void Algori_chung_lee::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail,
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
// ***donc pour l'instant du a un bug je commente
@ -1486,9 +1488,9 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -1509,7 +1511,7 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir

View file

@ -1321,8 +1321,10 @@ void AlgoriRelaxDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
temps_transfert_court_algo.Arret_du_comptage(); // comptage cpu
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
@ -2328,9 +2330,9 @@ Vecteur V_ext(F_int_tdt);
lescontacts->CalculReaction(vglobin,decol,Ass1.Nb_cas_assemb(),aff_iteration);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire> *listCondLine = NULL; // init donc sans élément
if (((pa.ContactType()==1) || (pa.ContactType()==3))&&(compteur_demarrage > 0))
tabCondLine = &(lescontacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lescontacts->ConditionLin(Ass1.Nb_cas_assemb()));
// -- dans le cas d'un amortissement visqueux critique ou
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
@ -2376,7 +2378,7 @@ Vecteur V_ext(F_int_tdt);
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if ((pa.ContactType()==1)&&(compteur_demarrage > 0)) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir

View file

@ -874,8 +874,10 @@ void AlgoriTchamwa::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
@ -1497,9 +1499,9 @@ void AlgoriTchamwa::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -1522,7 +1524,7 @@ void AlgoriTchamwa::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,(vglobaal),Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,(vglobaal),*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,(vglobaal),*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir

View file

@ -52,8 +52,10 @@ void AlgoriNewmark::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
@ -873,9 +875,9 @@ void AlgoriNewmark::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
lescontacts->CalculReaction(vglobin,decol,Ass1.Nb_cas_assemb(),aff_iteration);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lescontacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lescontacts->ConditionLin(Ass1.Nb_cas_assemb()));
//------ fin de la partie pour laquelle je m'interroge --------------------
// dans le cas où l'on utilise de l'amortissement numérique, calcul de la part visqueuse dans SM et K
@ -928,7 +930,7 @@ void AlgoriNewmark::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// -->> expression de la raideur et du second membre dans un nouveau repere
lesCondLim->CoLinCHrepere_int((*matglob),vglobaal,Ass1.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1)
lesCondLim->CoLinCHrepere_ext((*matglob),vglobaal,*tabCondLine,Ass1.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext((*matglob),vglobaal,*listCondLine,Ass1.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// en fait ne sert à rien, car les réactions maxi sont calculées dans condlin, mais comme c'est peut-être un peu spécial ici on laisse
// mais dans les autres algos c'est supprimé !!!!!

View file

@ -57,8 +57,10 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
temps_transfert_court_algo.Arret_du_comptage(); // comptage cpu
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
@ -870,9 +872,9 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if ((pa.ContactType()==1) || (pa.ContactType()==3))
tabCondLine = &(lescontacts->ConditionLin(Ass.Nb_cas_assemb()));
listCondLine = &(lescontacts->ConditionLin(Ass.Nb_cas_assemb()));
// - initialisation des sauvegardes sur matrice et second membre
lesCondLim->InitSauve(Ass.Nb_cas_assemb());
@ -892,9 +894,9 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// mais ici on n'impose pas les conditons, on fait simplement le changement de repère
lesCondLim->CoLinCHrepere_int((*matglob),vglobaal,Ass.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1)
lesCondLim->CoLinCHrepere_ext((*matglob),vglobaal,*tabCondLine,Ass.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext((*matglob),vglobaal,*listCondLine,Ass.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==3) // *** exploratoire
lesCondLim->CoLinUneOpe_ext((*matglob),vglobaal,*tabCondLine,Ass.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinUneOpe_ext((*matglob),vglobaal,*listCondLine,Ass.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// en fait ne sert à rien, car les réactions maxi sont calculées dans condlin, mais comme c'est peut-être un peu spécial ici on laisse
// mais dans les autres algos c'est supprimé !!!!!

View file

@ -498,7 +498,7 @@ void ImpliNonDynaCont::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
maxPuissExt = vglobex.Max_val_abs();
F_ext_tdt = vglobex; // sauvegarde des forces généralisées extérieures
// - definition des conditions limites de contact
const Tableau <Condilineaire>& tabCondLine = lescontacts->ConditionLin(Ass.Nb_cas_assemb());
list <Condilineaire>& listCondLine = lescontacts->ConditionLin(Ass.Nb_cas_assemb());
// -- appel du calcul de la raideur et du second membre, énergies
// dans le cas d'un calcul inexploitable arrêt de la boucle
if (!RaidSmEner(lesMail,Ass,vglobin,matglob)) break;
@ -525,7 +525,7 @@ void ImpliNonDynaCont::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
vglobal.Affiche();*/
// cout <<" \n une valeur continuer ? "; cin >> toti;
// expression de la raideur et du second membre dans un nouveau repere
lesCondLim->CoLinCHrepere_ext(matglob,vglobaal,tabCondLine,Ass.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(matglob,vglobaal,listCondLine,Ass.Nb_cas_assemb(),vglob_stat);
/* cout << "\n matrice et second membre dans le nouveau repere";
matglob.Affiche1(1,4,1,1,4,1);
vglobal.Affiche(); */

View file

@ -652,8 +652,10 @@ void AlgoBonelli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau (distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours());
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif

View file

@ -1620,7 +1620,7 @@ bool Charge::ChargeSMembreRaideur_Im_mecaSolid
// $$$--- cas des forces ponctuelles ---$$$
#ifdef UTILISATION_MPI
// cas d'un calcul //, les chargements aux noeuds sont calculés par le cpu 0uniquement
// cas d'un calcul //, les chargements aux noeuds sont calculés par le cpu 0 uniquement
if (ParaGlob::Monde()->rank() == 0)
#endif
// on parcours le tableau tabPonctuel

View file

@ -38,6 +38,9 @@ Distribution_CPU::Distribution_CPU():
tab_list_maillage_element(),tab_indic()
,total_elem(0)
,tab_vide_list_maillage_element()
,tab_list_maillage_noeud(),tab_indic_noeud()
,total_noeud(0)
,tab_vide_list_maillage_noeud()
{};
// constructeur de copie
@ -45,6 +48,9 @@ Distribution_CPU::Distribution_CPU (const Distribution_CPU& a):
tab_list_maillage_element(a.tab_list_maillage_element)
,tab_indic(a.tab_indic),total_elem(a.total_elem)
,tab_vide_list_maillage_element()
,tab_list_maillage_noeud(a.tab_list_maillage_noeud)
,tab_indic_noeud(a.tab_indic_noeud),total_noeud(a.total_noeud)
,tab_vide_list_maillage_noeud()
{};
// calcul de l'équilibrage initiale
@ -63,8 +69,6 @@ void Distribution_CPU::Calcul_Equilibrage_initiale(const LesMaillages * lesMai
Sortie(1);
};
tab_indic.Change_taille(nb_proc_calcul);
// dans une première étape on ne s'intéresse qu'aux éléments
// on suppose que les éléments sont identiques en temps de calcul
// on repère les éléments par le numéro de maillage + le numéro d'élément, en cours
@ -73,13 +77,18 @@ void Distribution_CPU::Calcul_Equilibrage_initiale(const LesMaillages * lesMai
total_elem = 0; // init
Tableau <Tableau <bool > > inter(nb_mail); // inter utilisé ensuite pour dimensionner tab_indic
Tableau <Tableau <bool > > inter_noeud(nb_mail); // inter utilisé ensuite pour dimensionner tab_indic_noeud
for (int i=1;i<=nb_mail;i++)
{int nb_elem_mail = lesMaillages->Nombre_element(i);
total_elem += nb_elem_mail;
inter(i).Change_taille(nb_elem_mail,false);
int nb_noeud_mail = lesMaillages->Nombre_noeud(i);
total_noeud += nb_noeud_mail;
inter_noeud(i).Change_taille(nb_noeud_mail,false);
};
// on dimensionne tab_indic, tout est à false
tab_indic.Change_taille(nb_proc_calcul,inter);
tab_indic_noeud.Change_taille(nb_proc_calcul,inter_noeud);
// il faut que le nombre d'élément soit au moins >= au nb de proc de calcul
// pour que l'on puisse distribuer au moin un elem par proc de calcul
if (total_elem < nb_proc_calcul)
@ -97,8 +106,11 @@ void Distribution_CPU::Calcul_Equilibrage_initiale(const LesMaillages * lesMai
tab_list_maillage_element.Change_taille(nb_proc_calcul);
for (int iproc =1;iproc <= nb_proc_calcul; iproc++)
{tab_list_maillage_element(iproc).Change_taille(nb_mail);
tab_list_maillage_noeud(iproc).Change_taille(nb_mail);
for (int imail=1; imail<= nb_mail; imail++)
tab_list_maillage_element(iproc)(imail).clear();
{tab_list_maillage_element(iproc)(imail).clear();
tab_list_maillage_noeud(iproc)(imail).clear();
};
};
// on parcours tous les éléments et on remplit les tableaux
int iproc = 1; // le num du proc en cours
@ -107,10 +119,20 @@ void Distribution_CPU::Calcul_Equilibrage_initiale(const LesMaillages * lesMai
{
int nb_ele = lesMaillages->Nombre_element(imail);
{list <int > * li_maillage_element = & tab_list_maillage_element(iproc)(imail); // init
list <int > * li_maillage_noeud = & tab_list_maillage_noeud(iproc)(imail); // init
// de la liste courante
for (int ile = 1; ile<=nb_ele;ile++,nb_ele_enreg_iproc++)
{ li_maillage_element->push_back(ile);
tab_indic(iproc)(imail)(ile)=true; // on signale
// idem pour les noeuds
Element& ele = lesMaillages->Element_LesMaille(imail,ile);
Tableau<Noeud *>& tab_N = ele.Tab_noeud();
int nb_N = tab_N.Taille();
for (int ne =1;ne<=nb_N;ne++)
{int num_noeud = tab_N(ne)->Num_noeud();
tab_indic_noeud(iproc)(imail)(num_noeud)=true;
li_maillage_noeud->push_back(num_noeud);
};
// on regarde s'il faut changer de cpu
// si c'est le dernier cpu, on ne change pas -> pour éviter
// les pb d'arrondi
@ -119,6 +141,7 @@ void Distribution_CPU::Calcul_Equilibrage_initiale(const LesMaillages * lesMai
{iproc++;
nb_ele_enreg_iproc=1; // reinit du compteur
li_maillage_element = & tab_list_maillage_element(iproc)(imail); // pointage liste associée
li_maillage_noeud = & tab_list_maillage_noeud(iproc)(imail);
};
};
};
@ -141,7 +164,8 @@ void Distribution_CPU::Passage_Equilibrage_aux_CPU()
// mise à jour de ParaGlob, qui peut transmettre à tous
// la liste des numéros d'éléments concernés
ParaGlob::param->Init_tableau(&tab_list_maillage_element,&tab_indic);
ParaGlob::param->Init_tableau(&tab_list_maillage_element,&tab_indic
,&tab_list_maillage_noeud,&tab_indic_noeud);
};
@ -162,15 +186,30 @@ void Distribution_CPU::save(Archive & ar, const unsigned int version) const
// pour cela on se sert de tab_indic pour le premier cpu
for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
ar << (int) tab_indic(1)(num_mail).Taille();
// maintenant tab_list_maillage_element
for (int imail=1;imail<=nb_mail;imail++)
{ const list <int >& list_maillage_element = tab_list_maillage_element(i_proc)(imail);
ar << std::string(" list:i_taille= ")<< (int) list_maillage_element.size() ;
ar << std::string(" list_maillage_element:i_taille= ")<< (int) list_maillage_element.size() ;
list <int >::const_iterator il, ilfin= list_maillage_element.end();
for (il = list_maillage_element.begin(); il != ilfin; il++)
{ int truc = (*il);
ar << truc ;
};
};
// on sauvegarde également le nombre total de noeud par maillage
// pour cela on se sert de tab_indic_noeud pour le premier cpu
for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
ar << (int) tab_indic_noeud(1)(num_mail).Taille();
// puis tab_list_maillage_noeud
for (int imail=1;imail<=nb_mail;imail++)
{ const list <int >& list_maillage_noeud = tab_list_maillage_noeud(i_proc)(imail);
ar << std::string(" list_maillage_noeud:i_taille= ")<< (int) list_maillage_noeud.size() ;
list <int >::const_iterator il, ilfin= list_maillage_noeud.end();
for (il = list_maillage_noeud.begin(); il != ilfin; il++)
{ int truc = (*il);
ar << truc ;
};
};
};
}
@ -192,25 +231,30 @@ void Distribution_CPU::load(Archive & ar, const unsigned int version)
// redimentionnement éventuel, si même taille, aucune action
tab_list_maillage_element.Change_taille(nb_proc_calcul);
tab_list_maillage_noeud.Change_taille(nb_proc_calcul);
// idem tab_indic
tab_indic.Change_taille(nb_proc_calcul);
tab_indic_noeud.Change_taille(nb_proc_calcul);
total_elem = 0; // init
total_noeud = 0; // init
for (int i_proc=1;i_proc<= nb_proc_calcul; i_proc++)
{ int nb_mail;
ar >> toto >> nb_mail;
tab_list_maillage_element(i_proc).Change_taille(nb_mail);
tab_indic(i_proc).Change_taille(nb_mail);
tab_list_maillage_noeud(i_proc).Change_taille(nb_mail);
tab_indic_noeud(i_proc).Change_taille(nb_mail);
// on va lire le nombre total d'éléments pour chaque maillage
for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
{ int nb_elem_mail;
ar >> nb_elem_mail;
tab_indic(i_proc)(num_mail).Change_taille(nb_elem_mail,false);
};
// puis les tableaux
for (int imail=1;imail<=nb_mail;imail++)
{ Tableau <bool > & tab_indic_cpu_mail = tab_indic(i_proc)(imail); // pour simplifier
// tab_indic_cpu_mail.Inita(false); // par défaut init à false pour tous les éléments
list <int >& list_maillage_element = tab_list_maillage_element(i_proc)(imail);
int size_list;
ar >> toto >> size_list;
@ -223,7 +267,7 @@ void Distribution_CPU::load(Archive & ar, const unsigned int version)
tab_indic_cpu_mail(inter)=true; // on rempli tab_indic
}
}
else // cas où la taille n'est pas bonne
else // cas où la taille n'est pas bonne
{list_maillage_element.clear();
int inter; // élément de travail
for (int j=1;j<= size_list;j++)
@ -232,10 +276,43 @@ void Distribution_CPU::load(Archive & ar, const unsigned int version)
tab_indic_cpu_mail(inter)=true; // on rempli tab_indic
};
};
// mise à jour du nombre total d'élément
total_elem += list_maillage_element.size();
// mise à jour du nombre total d'élément
total_elem += list_maillage_element.size();
};
// on va lire le nombre total de noeud pour chaque maillage
for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
{ int nb_noeud_mail;
ar >> nb_noeud_mail;
tab_indic_noeud(i_proc)(num_mail).Change_taille(nb_noeud_mail,false);
};
}
// puis les tableaux
for (int imail=1;imail<=nb_mail;imail++)
{ Tableau <bool > & tab_indic_noeud_cpu_mail = tab_indic_noeud(i_proc)(imail); // pour simplifier
list <int >& list_maillage_noeud = tab_list_maillage_noeud(i_proc)(imail);
int size_list;
ar >> toto >> size_list;
if (size_list == list_maillage_noeud.size())
{// si la liste existante a la bonne taille, on ne fait que lire
int inter;
list <int >::iterator il, ilfin= list_maillage_noeud.end();
for (il = list_maillage_noeud.begin(); il != ilfin; il++)
{ar >> inter; (*il)=inter;
tab_indic_noeud_cpu_mail(inter)=true; // on rempli tab_indic
}
}
else // cas où la taille n'est pas bonne
{list_maillage_noeud.clear();
int inter; // élément de travail
for (int j=1;j<= size_list;j++)
{ar >> inter;
list_maillage_noeud.push_back(inter);
tab_indic_noeud_cpu_mail(inter)=true; // on rempli tab_indic
};
};
// mise à jour du nombre total d'élément
total_noeud += list_maillage_noeud.size();
};
};
};
// affichage des infos relatives à la distribution
@ -248,7 +325,7 @@ void Distribution_CPU::Affiche() const
{cout << "\n ... cas du proc de calcul : "<< i_proc;
int nb_mail = tab_list_maillage_element(i_proc).Taille();
cout << std::string(" nb_mail considere = ")<< nb_mail ;
// on sauvegarde également le nombre total d'élément par maillage
// on affiche également le nombre total d'élément par maillage
// pour cela on se sert de tab_indic pour le premier cpu
for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
cout << ", nb elem total du maillage " << num_mail << " => " << (int) tab_indic(1)(num_mail).Taille();
@ -263,6 +340,21 @@ void Distribution_CPU::Affiche() const
cout << truc << " , ";
};
};
// idem pour les noeuds on affiche le nombre total de noeud par maillage
// pour cela on se sert de tab_indic_noeud pour le premier cpu
for (int num_mail = 1; num_mail <= nb_mail;num_mail++)
cout << ", nb noeud total du maillage " << num_mail << " => " << (int) tab_indic_noeud(1)(num_mail).Taille();
for (int imail=1;imail<=nb_mail;imail++)
{ const list <int >& list_maillage_noeud = tab_list_maillage_noeud(i_proc)(imail);
cout << " \n cas du maillage "<< imail
<< std::string(": nb noeud pour le proc => ")<< (int) list_maillage_noeud.size()
<< " c-a-d les elem : \n ";
list <int >::const_iterator il, ilfin= list_maillage_noeud.end();
for (il = list_maillage_noeud.begin(); il != ilfin; il++)
{ int truc = (*il);
cout << truc << " , ";
};
};
};
}

View file

@ -56,6 +56,10 @@
* BUT: une classe qui a pour objectif de gérer, calculer,
* certaines particularités liées à la parallélisation:
* - l'équilibrage de charge de calcul sur les processeurs
* La classe sert de conteneur basique: des tableaux de numéros
* L'idée est d'avoir un accès rapide aux données.
* NB: Par contre si les maillages évolues (nb noeuds, nb éléments, numérotations)
* il faut réinitialiser les tableaux
*
*
* \author Gérard Rio
@ -97,6 +101,20 @@ class Distribution_CPU
return tab_list_maillage_element(ParaGlob::Monde()->rank());
else return tab_vide_list_maillage_element;
};
// retour de tab_list_maillage_noeud(i)(j) contient la liste
// pour le maillage j des num <noeud> associés au cpu i
// NB: si la taille du tableau == 0, cela signifie qu'il n'a pas encore été construit
// on peut dans ce cas déclancher un calcul d'équilibrage initial
const Tableau <Tableau < list <int > > > * Tableau_noeud_CPU_en_cours() const
{return &tab_list_maillage_noeud;};
// retour de la liste des noeud relatif au cpu en cours
// si c'est le cpu 0, retourne un tableau vide
const Tableau < list <int > > & List_noeud_CPU_en_cours() const
{if (ParaGlob::Monde()->rank() != 0)
return tab_list_maillage_noeud(ParaGlob::Monde()->rank());
else return tab_vide_list_maillage_noeud;
};
// retourne le tableau indicateur permettant de dire si un élément est concerné par un CPU
// tab_indic(CPU)(mail)(ele) : = 1 si l'élément ele du maillage mail est concerné
@ -111,6 +129,20 @@ class Distribution_CPU
// récup du nombre total d'éléments, cumul sur tous les maillages
int NB_total_element() const {return total_elem ;};
// retourne le tableau indicateur permettant de dire si un noeud est concerné par un CPU
// tab_indic_noeud(CPU)(mail)(ne) : = 1 si le noeud ne du maillage mail est concerné
// par le CPU
const Tableau <Tableau < Tableau <bool > > > * Tab_indique_noeud_CPU_en_cours() const {return &tab_indic_noeud;};
// indicateur permettant de dire si un noeud est concerné par un CPU donné
// tab_indic_noeud(CPU)(mail)(ne) : = 1 si le noeud ne du maillage mail est concerné
// par le CPU
bool Noeud_concerner(int CPU,int mail,int ne) const
{return tab_indic_noeud(CPU)(mail)(ne);};
// récup du nombre total de noeud, cumul sur tous les maillages
int NB_total_noeud() const {return total_noeud ;};
// affichage des infos relatives à la distribution
void Affiche() const ;
@ -129,6 +161,10 @@ class Distribution_CPU
private :
// VARIABLES PROTEGEES :
// les conteneurs sont basiques, en particulier on ne stocke pas
// un pointeur sur les maillages, du coup il faut tout sauvegarder et
// tout relire, mais normalement c'est une opération qui s'effectue peu souvent (à voir !!)
// tab_list_maillage_element(i)(j) contient la liste
// pour le maillage j des num <élément> associés au cpu i
Tableau <Tableau < list <int > > > tab_list_maillage_element;
@ -141,6 +177,22 @@ class Distribution_CPU
Tableau <Tableau < Tableau <bool > > > tab_indic;
int total_elem ; // nombre total d'éléments cumulé sur tous les maillages
// tab_list_maillage_noeud(i)(j) contient la liste
// pour le maillage j des num <noeud> associés au cpu i
// c-a-d appartenent à un élément de maillage associés au cpu
// important: un noeud peut être associés à plusieurs cpu
Tableau <Tableau < list <int > > > tab_list_maillage_noeud;
// un tableau vide, qui correspond au cas du CPU 0
Tableau < list <int > > tab_vide_list_maillage_noeud;
// indicateur permettant de dire si un noeud est concerné par un CPU donné
// tab_indic_noeud(CPU)(mail)(ne) : = 1 si le noeud ne du maillage mail est concerné
// par le CPU
Tableau <Tableau < Tableau <bool > > > tab_indic_noeud;
int total_noeud; // nombre total de noeud cumulé sur tous les maillages
// METHODES PROTEGEES :
// -- serialisation ---

View file

@ -2855,7 +2855,7 @@ void LesCondLim::Affiche_reaction(ofstream& sort,const LesMaillages * lesMail) c
// vec2 : est un second vecteur éventuel (si != NULL) sur lequel on impose les mêmes CL que vecglob
// mais sans sauvegarde (correspond par exemple à une partie de vecglob)
bool LesCondLim::CoLinCHrepere_ext(Mat_abstraite & matglob,Vecteur& vecglob
,const Tableau <Condilineaire>& tab,const Nb_assemb& nb_casAssemb,Vecteur* vec2)
,list <Condilineaire>& listCondLine,const Nb_assemb& nb_casAssemb,Vecteur* vec2)
{
#ifdef UTILISATION_MPI
// cas d'un calcul //, seule la (ou les) matrices du CPU 0 sont concernées
@ -2866,19 +2866,21 @@ bool LesCondLim::CoLinCHrepere_ext(Mat_abstraite & matglob,Vecteur& vecglob
tempsCLL.Mise_en_route_du_comptage(); // temps cpu
// on boucle sur le tableau et pour chaque element on impose une condition lineaire
int tabTaille = tab.Taille();
/// int tabTaille = tab.Taille();
bool modification = false; // init du retour
for (int i=1;i<= tabTaille; i++)
{Condilineaire& condi = tab(i);
list <Condilineaire>::iterator il,ilfin = listCondLine.end();
for (il = listCondLine.begin();il != ilfin;il++)
// for (int i=1;i<= tabTaille; i++)
{Condilineaire& condi = (*il);
// calcul des pointeurs d'assemblage
condi.ConditionPourPointeursAssemblage(nb_casAssemb);
// application de la condition
condlim(nb_casAssemb.n).CondlineaireCHRepere
( matglob,vecglob,tab(i).Pt_t(),tab(i).Val(),tab(i).Beta(),vec2);
( matglob,vecglob,condi.Pt_t(),condi.Val(),condi.Beta(),vec2);
modification=true;
};
// affichage éventuelle de la matrice de raideur et du second membre
if ((ParaGlob::NiveauImpression() >= 10) && (tabTaille != 0))
if ((ParaGlob::NiveauImpression() >= 10) && (listCondLine.size() != 0))
{ string entete = " affichage de la matrice apres changement de repere du aux conditions limites externes (ex contact)";
matglob.Affichage_ecran(entete);
entete = " affichage du second membre apres changement de repere du aux conditions limites externes (ex contact) ";
@ -2895,7 +2897,7 @@ bool LesCondLim::CoLinCHrepere_ext(Mat_abstraite & matglob,Vecteur& vecglob
// vec2 : est un second vecteur éventuel (si != NULL) sur lequel on impose les mêmes CL que vecglob
// mais sans sauvegarde (correspond par exemple à une partie de vecglob)
bool LesCondLim::CoLinUneOpe_ext(Mat_abstraite & matglob,Vecteur& vecglob
,const Tableau <Condilineaire>& tab
,list <Condilineaire>& listCondLine
,const Nb_assemb& nb_casAssemb,Vecteur* vec2)
{
#ifdef UTILISATION_MPI
@ -2906,21 +2908,21 @@ bool LesCondLim::CoLinUneOpe_ext(Mat_abstraite & matglob,Vecteur& vecglob
tempsCLL.Mise_en_route_du_comptage(); // temps cpu
// on boucle sur le tableau et pour chaque element on impose une condition lineaire
int tabTaille = tab.Taille();
// on boucle dans la liste et pour chaque element on impose une condition lineaire
bool modification = false; // init du retour
for (int i=1;i<= tabTaille; i++)
{Condilineaire& condi = tab(i);
list <Condilineaire>::iterator il,ilfin = listCondLine.end();
for (il = listCondLine.begin();il != ilfin;il++)
{Condilineaire& condi = (*il);
// calcul des pointeurs d'assemblage
condi.ConditionPourPointeursAssemblage(nb_casAssemb);
// application d'une condition linéaire seule, avec en retour, la situation de la condition linéaire
// imposée, ramené dans le repère initial
condlim(nb_casAssemb.n).CondiLineaireImposeComplet
( matglob,vecglob,tab(i).Pt_t(),tab(i).Val(),tab(i).Beta(),vec2);
( matglob,vecglob,condi.Pt_t(),condi.Val(),condi.Beta(),vec2);
modification=true;
};
// affichage éventuelle de la matrice de raideur et du second membre
if ((ParaGlob::NiveauImpression() >= 10) && (tabTaille != 0))
if ((ParaGlob::NiveauImpression() >= 10) && (listCondLine.size() != 0))
{ string entete = " affichage de la matrice apres application CLL externes (ex contact) ";
matglob.Affichage_ecran(entete);
entete = " affichage du second membre apres apres application CLL externes (ex contact) ";

View file

@ -295,7 +295,7 @@ class LesCondLim
// vec2 : est un second vecteur éventuel (si != NULL) sur lequel on impose les mêmes CL que vecglob
// mais sans sauvegarde (correspond par exemple à une partie de vecglob)
bool CoLinCHrepere_ext(Mat_abstraite & matglob,Vecteur& vecglob
,const Tableau <Condilineaire>& tabCondLine
, list <Condilineaire>& listCondLine
,const Nb_assemb& nb_casAssemb,Vecteur* vec2);
// blocage des seconds membres pour les conditions lineaires
@ -316,7 +316,7 @@ class LesCondLim
// vec2 : est un second vecteur éventuel (si != NULL) sur lequel on impose les mêmes CL que vecglob
// mais sans sauvegarde (correspond par exemple à une partie de vecglob)
bool CoLinUneOpe_ext(Mat_abstraite & matglob,Vecteur& vecglob
,const Tableau <Condilineaire>& tabCondLine
,list <Condilineaire>& listCondLine
,const Nb_assemb& nb_casAssemb,Vecteur* vec2);

View file

@ -41,7 +41,7 @@
EnumLangue ParaGlob::langueHZ = FRANCAIS; // langue utilisée pour les entrées sorties
int ParaGlob::nbComposantesTenseur = 1; // nombre de composantes par defaut a 1
int ParaGlob::nivImpression = 2; // niveau d'impression
string ParaGlob::nbVersion = "7.019" ; // numéro de version du logiciel
string ParaGlob::nbVersion = "7.020" ; // numéro de version du logiciel
string ParaGlob::NbVersionsurfichier = ""; // numéro de version lue en entrée fichier
int ParaGlob::nb_diggit_double_calcul= 17; // nombre de chiffre significatifs utilisé pour
// l'affichage des double précision pour l'archivage

View file

@ -147,11 +147,15 @@ class ParaGlob
static boost::mpi::communicator * Monde() {return world;};
static void Init_boost_communicator (boost::mpi::communicator * pt_world)
{world = pt_world;};
// -- equilibrage d'éléments
// -- equilibrage d'éléments et noeuds associés
void Init_tableau (const Tableau <Tableau < list <int > > >* tab_list_maillage_element
,const Tableau <Tableau < Tableau <bool > > >* tab_indic)
,const Tableau <Tableau < Tableau <bool > > >* tab_indic
,const Tableau <Tableau < list <int > > >* tab_list_maillage_noeud
,const Tableau <Tableau < Tableau <bool > > >* tab_indic_noeud)
{tab_list_mail_element = tab_list_maillage_element;
tabb_indic = tab_indic;
tab_list_mail_noeud = tab_list_maillage_noeud;
tabb_indic_noeud = tab_indic_noeud;
};
// retour des listes des éléments relatif au cpu en cours, c-a-d pour tous les maillages
// tab (j) donne la liste des éléments pour le maillage j
@ -165,6 +169,20 @@ class ParaGlob
// par le CPU
bool Element_concerner(int mail,int ele) const
{return (*tabb_indic)(world->rank())(mail)(ele);};
// retour des listes des noeuds relatif au cpu en cours, c-a-d pour tous les maillages
// tab (j) donne la liste des noeuds pour le maillage j
const Tableau < list <int > > & const_List_noeud_CPU_en_cours() const
{return (*tab_list_mail_noeud)(world->rank());};
// spécifiquement, la liste des noeud pour le maillage j
const list <int > & const_List_noeud_CPU_en_cours(int j) const
{return (*tab_list_mail_noeud)(world->rank())(j);};
// indicateur permettant de dire si un noeud est concerné par le cpu en cours
// tab_indic_noeud(mail)(ne) : = 1 si noeud ne du maillage mail est concerné
// par le CPU
bool Noeud_concerner(int mail,int ne) const
{return (*tabb_indic_noeud)(world->rank())(mail)(ne);};
#endif
// lecture du type de calcul et d'une liste de sous_type éventuel
@ -417,6 +435,15 @@ class ParaGlob
// tab_indic(CPU)(mail)(ele) : = 1 si l'élément ele du maillage mail est concerné
// par le CPU, il s'agit d'une copie qui doit être mise à jour par Distribution_CPU
const Tableau <Tableau < Tableau <bool > > >* tabb_indic;
// -- noeuds associés aux éléments
// tab_list_maillage_noeud(i)(j) contient la liste
// pour le maillage j des num <noeud> associés au cpu i
// ici il s'agit d'une copie de tab_list_maillage_noeud qui doit être mise à jour par Distribution_CPU
const Tableau <Tableau < list <int > > >* tab_list_mail_noeud;
// indicateur permettant de dire si un noeud est concerné par un CPU donné
// tab_indic_noeud(CPU)(mail)(ne) : = 1 si le noeud ne du maillage mail est concerné
// par le CPU, il s'agit d'une copie qui doit être mise à jour par Distribution_CPU
const Tableau <Tableau < Tableau <bool > > >* tabb_indic_noeud;
#endif
//------------ info sur le temps ---------------

View file

@ -186,3 +186,89 @@ void Condilineaire::Ecriture_base_info(ofstream& sort)
// le numéro d'ordre du ddl modifié dans noeud
sort << iddl << " \n";
};
#ifdef UTILISATION_MPI // spécifique au calcul parallèle
// stockage dans un unique vecteur, des infos à partir de l'indice rang inclus
// correspond à une sérialisation des infos
// ramène le positionnement dans v pour un prochain enreg, sauf si > à la taille de v
// dans ce cas ramène 0
int Condilineaire::Pack_vecteur(Vecteur& v,int rang) const
{ // le tableau de pointeurs
int taille_pt = pt.Taille();
v(rang) = taille_pt;rang++;
for (int i=1;i<=taille_pt;i++)
{v(rang)= pt(i);rang++;};
// le vecteur val
int taille_val = val.Taille();
v(rang) = taille_val;
for (int i=1;i<=taille_val;i++)
{v(rang)= val(i);rang++;};
// beta
v(rang)=beta; rang++;
// Uk_impose
v(rang)=Uk_impose; rang++;
// le cas d'assemblage associé
rang = casAssemb.Pack_vecteur(v,rang);
// le tableau t_enu
int taille_t_enu = t_enu.Taille();
v(rang) = taille_t_enu;rang++;
for (int i=1;i<=taille_t_enu;i++)
{v(rang)= t_enu(i);rang++;};
// iddl
v(rang)=iddl; rang++;
// le taleau t_noeud
// on considère que la numérotation est la même pour tous les cpu
// du coup on sauvegarde le numéro de maillage et le numéro de noeud
int taille_t_noeud = t_noeud.Taille();rang++;
v(rang)= taille_t_noeud;
for (int i=1;i<=taille_t_noeud;i++)
{v(rang)= t_noeud(i)->Num_Mail();rang++;
v(rang)= t_noeud(i)->Num_noeud();rang++;
};
if (rang > v.Taille()) rang = 0;
return rang;
};
// taille du conteneur actuel de la condition linéaire
int Condilineaire::Taille_Pack() const
{int taille_pack = 0; // init
taille_pack += pt.Taille() + 1;
taille_pack += val.Taille() + 1;
taille_pack += 2;
taille_pack += casAssemb.Taille_Pack();
taille_pack += t_enu.Taille()+1;
taille_pack += 1;
taille_pack += 2*t_noeud.Taille()+1;
return taille_pack;
};
#endif
/*
// VARIABLES PROTEGEES :
Tableau<int> pt; //tableau des pointeurs de ddl concerne, pt(i) = la position du ddl i
// dans la matrice globale
Vecteur val; // tableau des coefficients de la condition lineaire
double beta; // valeur beta a laquelle est egale la condition lineaire
// dans le cas de la mise en place de la CL à partir d'un changement de repère, on peut stocker la valeur imposée avant chg de repère
double Uk_impose; // valeur a imposer sur le ddl avant changement de repère, qui correspondra à beta après chg de repère
// Uk_impose sert uniquement de stockage, mais n'est pas forcément cohérent avec la CL, sa manipulation est faite en dehors de la classe
// via : ChangeUk_impose et Val_Uk_impose
Nb_assemb casAssemb; // le cas d'assemblage associé
// le blocage de condition est appliquee sur le ddl numero "iddl" du noeud "noe"
Tableau <Enum_ddl > t_enu; // tableau des identificateur de ddl de la CLL
// t_enu(1) est l'identificateur du ddl qui est bloqué pour la CLL
// lorsque seul t_enu(1) existe, cela signifie qu'il faut construire
// les indices,
// iddl -> le numéro d'ordre dans sa famille, du ddl bloqué
// NB: ce n'est pas la position du ddl dans le noeud !!, cette dernière est: Tab_Enum()(1)
int iddl;
// le tableau des noeuds de la CLL, le premier contient la condition
Tableau < Noeud *> t_noeud;
*/

View file

@ -56,6 +56,17 @@
#include "Noeud.h"
#include "Nb_assemb.h"
#include <stdlib.h>
#ifdef UTILISATION_MPI
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/string.hpp>
#include "mpi.h"
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/serialization/string.hpp>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
#endif
/// @addtogroup Les_classes_Matrices
@ -166,7 +177,24 @@ class Condilineaire
// attibuer le noeud
void Lecture_base_info(Tableau <int>& numMaillage, ifstream& ent,Tableau <int>& numNoeud) ;
void Ecriture_base_info(ofstream& sort) ;
#ifdef UTILISATION_MPI // spécifique au calcul parallèle
// stockage dans un unique vecteur, des infos à partir de l'indice rang inclus
// correspond à une sérialisation des infos
// ramène le positionnement dans v pour un prochain enreg, sauf si > à la taille de v
// dans ce cas ramène 0
int Pack_vecteur(Vecteur& v,int rang) const;
// taille du conteneur actuel de la condition linéaire
int Taille_Pack() const;
// modification des infos à partir de l'indice rang inclus en fonction du vecteur passé en paramètre
// correspond à une désérialisation
// ramène le positionnement dans v pour un prochain enreg, sauf si > à la taille de v
// dans ce cas ramène 0
// on passe un pointeur de fonctions qui ramène un noeud en fonction d'un numéro de maillage et d'un
// numéro de noeud, ceci pour éviter de passer toute l'instance de la classe Les_maillages
template <class T> int UnPack_vecteur(T& instance,const Vecteur& v,int rang,
Noeud & (T::*Ptfonc) (int num_mail,int num_noeud) const );
#endif
protected :
// VARIABLES PROTEGEES :
Tableau<int> pt; //tableau des pointeurs de ddl concerne, pt(i) = la position du ddl i
@ -195,6 +223,10 @@ class Condilineaire
// METHODES PROTEGEES :
};
// pour faire de l'inline: nécessaire avec les templates
// on n'inclut que les méthodes templates
#include "Condilineaire_2.cc"
#define Condilineaire_deja_inclus
/// @} // end of group
#endif

View file

@ -0,0 +1,91 @@
// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
#ifndef Condilineaire_deja_inclus
#include "Condilineaire.h"
#endif
// contient que les méthodes nécessitant les templates, qui doivent donc être
//incluses dans le .h
#ifndef Condilineaire_deja_inclus
#include "Condilineaire.h"
#ifdef UTILISATION_MPI // spécifique au calcul parallèle
// modification des infos à partir de l'indice rang inclus en fonction du vecteur passé en paramètre
// correspond à une désérialisation
// ramène le positionnement dans v pour un prochain enreg, sauf si > à la taille de v
// dans ce cas ramène 0
// on passe un pointeur de fonctions qui ramène un noeud en fonction d'un numéro de maillage et d'un
// numéro de noeud, ceci pour éviter de passer toute l'instance de la classe Les_maillages
template <class T> int Condilineaire::UnPack_vecteur(T& instance,const Vecteur& v,int rang,
Noeud & (T::*Ptfonc) (int num_mail,int num_noeud) const )
{ // le tableau de pointeurs
int taille_pt = (int) v(rang);rang++;
pt.Change_taille(taille_pt);
for (int i=1;i<=taille_pt;i++)
{pt(i) = (int) v(rang);rang++;};
// le vecteur val
int taille_val = (int) v(rang);rang++;
val.Change_taille(taille_val);
for (int i=1;i<=taille_val;i++)
{val(i) = v(rang);rang++;};
// beta
beta = v(rang); rang++;
// Uk_impose
Uk_impose = v(rang); rang++;
// le cas d'assemblage associé
rang = casAssemb.UnPack_vecteur(v,rang);
// le tableau t_enu
int taille_t_enu = (int) v(rang);rang++;
t_enu.Change_taille(taille_t_enu);
for (int i=1;i<=taille_t_enu;i++)
{t_enu(i) = (Enum_ddl) v(rang);rang++;};
// iddl
iddl = (int) v(rang); rang++;
// le taleau t_noeud
// on considère que la numérotation est la même pour tous les cpu
// du coup on sauvegarde le numéro de maillage et le numéro de noeud
int taille_t_noeud = (int) v(rang);rang++;
t_noeud.Change_taille(taille_t_noeud);
for (int i=1;i<=taille_t_noeud;i++)
{int num_mail = (int) v(rang);rang++;
int num_noeud = (int) v(rang);rang++;
t_noeud(i) = &((instance.*Ptfonc) (num_mail,num_noeud));
};
if (rang > v.Taille()) rang = 0;
return rang;
};
#endif
#endif

View file

@ -88,13 +88,34 @@ class Nb_assemb
{ n = c.n; return (*this);}
//Surcharge d'operateur logique
bool operator == (const Nb_assemb& a) const
{ return (a.n == n); };
bool operator != (const Nb_assemb& a) const
{ return (a.n != n); };
bool operator == (const Nb_assemb& a) const
{ return (a.n == n); };
bool operator != (const Nb_assemb& a) const
{ return (a.n != n); };
// donnée
#ifdef UTILISATION_MPI // spécifique au calcul parallèle
// stockage dans un unique vecteur, des infos à partir de l'indice rang inclus
// correspond à une sérialisation des infos
// ramène le positionnement dans v pour un prochain enreg, sauf si > à la taille de v
// dans ce cas ramène 0
int Pack_vecteur(Vecteur& v,int rang) const
{v(rang)=n; int next = rang+1; if (next > v.Taille()) next = 0;
return next; };
// taille du conteneur actuel de la condition linéaire
// stocké en réel
int Taille_Pack() const {return 1;};
// opération inverse
// modification des infos à partir de l'indice rang inclus en fonction du vecteur passé en paramètre
// correspond à une désérialisation
// ramène le positionnement dans v pour un prochain enreg, sauf si > à la taille de v
// dans ce cas ramène 0
int UnPack_vecteur(const Vecteur& v,int rang)
{ n = (int) v(rang);
int next = rang+1; if (next > v.Taille()) next = 0;
return next;} ;
#endif
// donnée
int n;
};

View file

@ -267,7 +267,7 @@ ElContact::Fct_nD_contact& ElContact::Fct_nD_contact::operator= (const ElContact
}
case NOEUD_FACETTE_EN_CONTACT:
{ tqi(i) = new TypeQuelconque(NOEUD_FACETTE_EN_CONTACT,X1,grand_courant_double);
Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*tqi(i)).Grandeur_pointee()));
// Grandeur_scalaire_double& gr= *((Grandeur_scalaire_double*) ((*tqi(i)).Grandeur_pointee()));
trouver = true;
break;
}
@ -713,7 +713,7 @@ bool ElContact::Contact( bool init)
// 1) === le cas des angles morts est particulier, on commence par le traiter
if (elfront->Angle_mort())
{ ElFrontiere & elfro = *(elfront->Eleme()); // pour commodite
{ //ElFrontiere & elfro = *(elfront->Eleme()); // pour commodite
int dim = noeud->Dimension();
Plan pl(dim); Droite dr(dim); int indic; // def des variables de tangence
N = Calcul_Normale(dim,pl,dr,indic);
@ -1628,6 +1628,9 @@ Coordonnee ElContact::Intersection( const Coordonnee& V,bool init)
// retour du point d'intersection
return M1;
};
// si on arrive ici on considère qu'il n'y a pas d'intersection
Coordonnee a(0);
return a;
};
// construction de la condition lineaire de contact
@ -1912,7 +1915,8 @@ int ElContact::Actualisation()
ElFrontiere & elfro = *(elfront->Eleme()); // pour commodite
// ici on recherche avec une précision donnée
double extra_in_surface = ParaGlob::param->ParaAlgoControleActifs().PointInternePrecThetaiInterne();
int contactType = ElContact::Recup_et_mise_a_jour_type_contact();
// int contactType =
ElContact::Recup_et_mise_a_jour_type_contact();
if ((elfro.InSurf(extra_in_surface))
|| (nb_change_frontiere > nb_change_frontiere_max) // pour limiter les flip-flop
)

File diff suppressed because it is too large Load diff

View file

@ -64,6 +64,17 @@
#include "Basiques.h"
#include "TypeQuelconque.h"
#include "Temps_CPU_HZpp.h"
#include <stdlib.h>
#ifdef UTILISATION_MPI
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/string.hpp>
#include "mpi.h"
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/serialization/string.hpp>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
#endif
/// @addtogroup Groupe_sur_les_contacts
@ -144,14 +155,21 @@ class LesContacts
// definition de conditions lineaires de contact
// marquage des ddl correspondant aux directions bloquees s'il s'agit d'un contact de type 1
// casAssemb : donne le cas d'assemblage en cours
//
const Tableau <Condilineaire>& ConditionLin(const Nb_assemb& casAssemb);
// Dans le cas d'un calcul parallèle, il y a transfert des conditions au cpu 0
// seules les cpu i calculent les conditions linéaires
// NB: on ne met pas la liste en const car on a besoin de pouvoir modifier les infos à l'intérieur
// des CL pour les utiliser, mais l'idée est la liste elle, reste constante
list <Condilineaire>& ConditionLin(const Nb_assemb& casAssemb);
// création d'un tableau de condition linéaire, correspondant à tous les éléments de contact en cours
// création d'une liste de condition linéaire, correspondant à tous les éléments de contact en cours
// qu'ils soient actifs ou pas (a prior cette méthode est conçu pour donner des infos relativement à la largeur
// de bandes en noeuds due aux CLL)
// chacune des condition ne contient "d'exploitable" que le tableau de noeuds associés à la CLL,
const Tableau <Condilineaire>& ConnectionCLL();
// Dans le cas d'un calcul parallèle, il y a transfert des conditions au cpu 0
// seules les cpu i calculent les conditions linéaires
// NB: on ne met pas la liste en const car on a besoin de pouvoir modifier les infos à l'intérieur
// des CL pour les utiliser, mais l'idée est la liste elle, reste constante
list <Condilineaire>& ConnectionCLL();
// effacement du marquage de ddl bloque du au conditions lineaire de contact
void EffMarque();
@ -172,6 +190,8 @@ class LesContacts
// = true : si la largeur de bande en noeud est supérieure à 1 (cas d'un contact avec une surface déformable)
// = false : si non, ce qui signifie dans ce cas qu'il n'y a pas d'augmentation de la largeur
// en noeud (cas d'un contact avec une surface rigide)
// dans le cas d'un calcul // seule le cpu 0 effectue la résolution, par contre tous les cpu i contribuent
// ils vont donc transmettre les informations au cpu 0
bool Largeur_Bande(int& demi,int& total,const Nb_assemb& casAssemb,int& cumule);
// actualisation du contact, on examine que les elements de contact, dont on
@ -185,6 +205,9 @@ class LesContacts
// si l'intersection n'est pas calculable
// NB: pour les deux choix, s'il y a doublon d'élément de contact, due à un changement de frontière
// en cours d'actualisation, on inactive le(s) doublon(s)
// dans le cas d'un calcul // chaque proc i effectue son actualisation, s'il y a changement de surface avec sortie
// de la surface gérée par le proc i, cela sera vérifié au niveau de l'élément de contact
// Le proc 0 se contente de récupérer et globaliser les retours des proc i
bool Actualisation(int choix);
// ramène une liste de noeuds dont la position a été perturbé par le contact
@ -231,6 +254,7 @@ class LesContacts
// lecture éventuelle des zones où le contact doit être recherché, à l'exclusion de tout
// autre zone, ainsi que la définition de l'auto-contact éventuel
// ainsi que des contacts solide-deformables éventuel
// cas d'un calcul parallèle, tous les proc utilisent la méthode, seule le proc 0 affiche
void Lecture_zone_contact(UtilLecture & entreePrinc,const LesReferences& lesRef);
// récupération des ddl ou des grandeurs actives de tdt vers t
@ -350,7 +374,7 @@ class LesContacts
// list <TroisEntiers> numtesN; // .un : maillage, .deux: num zone de contact, .trois: num propre du noeud
// // la liste des numéros dans tesN des noeuds en contact
Tableau <ReactCont> tabReacCont; // les reactions
Tableau <Condilineaire> tabCoLin; // tableau des conditions lineaires
list <Condilineaire> listCoLin; // tableau des conditions lineaires
static MotCle motCle; // liste des mots clés
// la liste des éléments qui contiennent des frontières, est reconstitué au démarrage avec Init_contact(..
@ -437,7 +461,7 @@ class LesContacts
List_io<TypeQuelconque> liQ_en_sortie; // liste de grandeurs quelconque qu'il faut sortir
// -------- une variable de travail pour la méthode LesContacts::ConnectionCLL()---
Tableau <Condilineaire> t_connectionCLL;
list <Condilineaire> t_connectionCLL;
//------- temps cpu -----
// retourne temps cumulé pour imposer les CL imposées
@ -447,6 +471,10 @@ class LesContacts
Temps_CPU_HZpp temps_transfert_court ;
Temps_CPU_HZpp temps_transfert_long ;
Temps_CPU_HZpp temps_attente ;
Vecteur inter_transfer; // un conteneur de transfert pour ConditionLin
Vecteur inter_transfer2; // un conteneur de transfert pour ConnectionCLL
// on sauvegarde un pointeur sur les maillages
LesMaillages* lesMaille;
#endif
// METHODES PROTEGEES :

View file

@ -695,6 +695,9 @@ void LesContacts::Suppression_gap_pour_noeud_collant()
return;
// sinon il faut effectivement faire une suppression de gap
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts > 2)
cout << "\n >>>> Suppression_gap_pour_noeud_collant : ";
// on va iterer sur les noeuds esclaves collants dont on veut supprimer le gap
@ -706,7 +709,11 @@ void LesContacts::Suppression_gap_pour_noeud_collant()
int boucle_maxi = 10; // 10 boucle maxi
int boucle = 1;
do
{ if (niveau_commentaire_lescontacts >2 )
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >2 )
cout << "\n boucle : "<<boucle << flush;
for (int intot = 1;intot<= nb_mail_Esclave;intot++) // boucle sur les maillages esclaves
for (int j=1;j<=nb_zone;j++) // boucle sur les zones de contact
@ -772,6 +779,9 @@ void LesContacts::Suppression_gap_pour_noeud_collant()
bool projection_ok = false; // init
if (list_P.size() != 0)
{list <Coordonnee >::iterator il,ilfin=list_P.end();
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >5 )
{cout << "\n " << list_P.size() << " proj trouvees "
<< " Noe: "<<noee->Num_noeud()
@ -784,6 +794,9 @@ void LesContacts::Suppression_gap_pour_noeud_collant()
LaLIST_io <LaLIST_io <Front>::iterator>::iterator iface_maxi ;
for (il=list_P.begin(); il!= ilfin;il++,iface++)
{ double Ndis = (M-(*il)).Norme();
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >5 )
cout << " dist: " << Ndis ;
if (Ndis < distance)
@ -803,9 +816,15 @@ void LesContacts::Suppression_gap_pour_noeud_collant()
tout_projeter=false;
if (distance > le_maxi_des_distances_trouve)
le_maxi_des_distances_trouve = distance;
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >3 )
cout << "\n suppression gap=("<<distance<<") du noeud "<<noee->Num_noeud()
<< " du maillage " << noee->Num_Mail() << " (zone "<<j<<")";
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >4 )
{cout << "\n ancienne coordonnee "<< pt_esc
<< " nouvelle " << P;
@ -830,11 +849,18 @@ void LesContacts::Suppression_gap_pour_noeud_collant()
{compteur_noeuds_projecte++;};
};
if ((!projection_ok) && (boucle==1)) // au premier passage
{ if (niveau_commentaire_lescontacts >3 )
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >3 )
cout << "\n pas de projection trouvee donc de suppression gap du noeud "<<noee->Num_noeud()
<< " du maillage" << noee->Num_Mail() << " (zone "<<j<<")";
} ;
}; //-- fin de la boucle sur inesc
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >2 )
{if (compteur_noeuds_projecte)
cout << "\n zone: " << j <<", " << compteur_noeuds_projecte << " suppression(s) de gap, maxi_distance= "
@ -905,20 +931,82 @@ int LesContacts::Recup_ref( ElContact& al)
// qu'ils soient actifs ou pas (a prior cette méthode est conçu pour donner des infos relativement à la largeur
// de bandes en noeuds due aux CLL)
// chacune des condition ne contient "d'exploitable" que le tableau de noeuds associés à la CLL,
const Tableau <Condilineaire>& LesContacts::ConnectionCLL()
list <Condilineaire>& LesContacts::ConnectionCLL()
{
// on boucle sur le tableau et pour chaque element on crée une condition lineaire
int tabTaille = listContact.size();
t_connectionCLL.Change_taille(tabTaille);
// un tableau servant à la def de la CLL
Tableau <Enum_ddl > t_enu(1); t_enu(1)=X1 ;
LaLIST <ElContact>::const_iterator il,ilfin=listContact.end();
int posi=1; // init pour le tableau
for (il=listContact.begin();il != ilfin;il++,posi++)
{ const Tableau < Noeud *>& t_n = (*il).Const_TabNoeud();
// on est dans le cas ou l'on connait les infos relatives uniquements aux noeuds, aux enum ddl
t_connectionCLL(posi) = Condilineaire(t_enu, t_n);
};
tempsContact.Mise_en_route_du_comptage(); // def deb compt
#ifdef UTILISATION_MPI
int proc_en_cours = ParaGlob::Monde()->rank();
if (proc_en_cours != 0)
{
#endif
{
// // on boucle sur le tableau et pour chaque element on crée une condition lineaire
// int tabTaille = listContact.size();
// t_connectionCLL.Change_taille(tabTaille);
t_connectionCLL.clear();
// un tableau servant à la def de la CLL
Tableau <Enum_ddl > t_enu(1); t_enu(1)=X1 ;
LaLIST <ElContact>::const_iterator il,ilfin=listContact.end();
int posi=1; // init pour le tableau
for (il=listContact.begin();il != ilfin;il++,posi++)
{ const Tableau < Noeud *>& t_n = (*il).Const_TabNoeud();
// on est dans le cas ou l'on connait les infos relatives uniquements aux noeuds, aux enum ddl
t_connectionCLL.push_back(Condilineaire(t_enu, t_n));
};
tempsContact.Arret_du_comptage(); // fin cpu
}
#ifdef UTILISATION_MPI
temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu
// maintenant on va les transmettres au cpu 0
// pour cela on va utiliser un conteneur intermédiaire
// on calcul la taille nécessaire pour le conteneur (a découper éventuellement ??)
int taille_conteneur=0;
list <Condilineaire>::iterator il,ilfin = t_connectionCLL.end();
for (il = t_connectionCLL.begin();il != ilfin;il++)
taille_conteneur += (*il).Taille_Pack();
inter_transfer2.Change_taille(taille_conteneur); // le conteneur
// on rempli le conteneur
int rang = 1; // init
for (il = t_connectionCLL.begin();il != ilfin;il++)
rang = (*il).Pack_vecteur(inter_transfer2,rang);
temps_attente.Arret_du_comptage();
// on transfert
mpi::request reqs1 = ParaGlob::Monde()->isend(0, 42, taille_conteneur);
mpi::request reqs2 = inter_transfer2.Ienvoi_MPI(0,43);
// on attend pas
temps_transfert_long.Arret_du_comptage(); // fin comptage cpu
}
else // cas du cpu 0
{// l'objectif ici est de récupérer les conditions linéaires
tempsContact.Arret_du_comptage(); // fin cpu
temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu
int nb_proc_terminer = 0; // permettra de terminer
t_connectionCLL.clear();// Change_taille(nb_contact_actif);
while (nb_proc_terminer < (ParaGlob::Monde()->size()-1)) // gérer par les valeurs de tyfront
{ // on récupère un résultat de cpu i
int taille_transfert;
mpi::request reqs1 = ParaGlob::Monde()->irecv(mpi::any_source, 42, taille_transfert);
mpi::status stat = reqs1.wait(); // on attend que le conteneur soit rempli
inter_transfer2.Change_taille(taille_transfert); // le conteneur
int source = stat.source(); // récupération du numéro de la source
// on récupère
mpi::request reqs2 = inter_transfer2.Irecup_MPI(source, 43);
reqs2.wait(); // on attend que le conteneur soit rempli
nb_proc_terminer++; // on prend en compte que l'on a récupéré un conteneur
// on va remplir la liste des conditions limites
int rang = 1; // init
while (rang != 0)
{ Condilineaire condi; // une condition intermédiaire
rang = condi.UnPack_vecteur(*lesMaille,inter_transfer2,rang,
&LesMaillages::Noeud_LesMaille);
t_connectionCLL.push_back(condi);
};
};
temps_transfert_long.Arret_du_comptage();
};
#endif
// retour
return t_connectionCLL;
@ -1330,6 +1418,9 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail)
// ** mais on a: les éléments de frontière de t_listFront(i) font partie du maillage
// i + (nb_mail_Esclave-nbmailautocontact)
int niveau_commentaire_lescontacts = Permet_affichage();
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts > 4)
cout << "\n ==> LesContacts::ElementAngleMort: ";
@ -1439,6 +1530,9 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail)
}
};
int nb_front_fin = la_list_des_front.size(); // la taille finale
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >2 )
cout << "\n mail. maitre "<<im<<" : "<<(nb_front_fin-nb_front_init)
<< " frontieres segment pour angle mort pour contact ";
@ -1495,6 +1589,9 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail)
};
};
int nb_front_fin = la_list_des_front.size(); // la taille finale
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >2 )
cout << "\n mail. maitre "<<im << " : zone de contact: " << i_zone
<<" : " <<(nb_front_fin-nb_front_init)
@ -1624,7 +1721,9 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail)
};
// on sauvegarde le nouvelle front dans une liste spécifique
front_angle_mort.push_front(&(*iik));
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >4 )
{ cout << "\n ajout front point: noeud "<<el->Num_noeud(num_noe_local)
<< " mail: " << jf //<< " zone "
@ -1635,12 +1734,18 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail)
};
};
int nb_front_fin = la_list_des_front.size(); // la taille finale
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >2 )
cout << "\n ajout angle mort pour contact: mail. maitre "<< jf <<" : "<<(nb_front_fin-nb_front_init)
<< " frontieres point ";
#ifdef MISE_AU_POINT
// petite vérif en passant
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if ((nb_front_fin-nb_front_init) != front_angle_mort.size())
{cout << "\n *** erreur dans la definition des elements point d'angle mort "
<< " on a deux listes qui les representent mais qui n'ont pas la meme taille "
@ -1794,6 +1899,9 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail)
// on sauvegarde le nouvelle front dans une liste spécifique
front_angle_mort.push_front(&(*iik));
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >4 )
{ cout << "\n ajout front point: noeud "<<el->Num_noeud(num_noe_local)
<< " mail: " << jf << " zone "<< i_zone
@ -1804,6 +1912,9 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail)
};
};
int nb_front_fin = la_list_des_front.size(); // la taille finale
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >2 )
cout << "\n ajout angle mort pour contact: mail. maitre "<<jf << " : zone de contact: " << i_zone
<<" : " <<(nb_front_fin-nb_front_init)
@ -1811,6 +1922,9 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail)
#ifdef MISE_AU_POINT
// petite vérif en passant
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if ((nb_front_fin-nb_front_init) != front_angle_mort.size())
{cout << "\n *** erreur dans la definition des elements point d'angle mort "
<< " on a deux listes qui les representent mais qui n'ont pas la meme taille "
@ -1838,6 +1952,9 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail)
};
};
};
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (niveau_commentaire_lescontacts >7 )
{ cout << "\n liste finale des elements angle mort "
<< " mail: " << jf << " zone "<< i_zone;