From a317216f06f12f2aba74548480d2fc82dc83d73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Rio?= Date: Tue, 30 Jan 2024 20:55:48 +0100 Subject: [PATCH] =?UTF-8?q?V=207.021=20-=207.023=20-=20modification=20des?= =?UTF-8?q?=20sorties=20post=20pour=20loi=20hypo=202D=5FC=20et=201D=5FC=20?= =?UTF-8?q?-=20corr=20bug=20lecture=20fct=5FnD=20avec=20toutes=20les=20loi?= =?UTF-8?q?s=20hypo=20isotropes=20-=20corr=20bug=20sur=20le=20calcul=20de?= =?UTF-8?q?=20la=20compressibilit=C3=A9=20pour=20les=20loi=20hypo=202D=5FC?= =?UTF-8?q?=20-=20premi=C3=A8re=20mise=20en=20place=20du=20calcul=20parall?= =?UTF-8?q?=C3=A8le=20sur=20le=20contact=20-=20ajout=20d'une=20fct=20nD=20?= =?UTF-8?q?pour=20g=C3=A9rer=20le=20niveau=20de=20commentaire=20sur=20LesC?= =?UTF-8?q?ontacts=20(ind=C3=A9pendante=20de=20celle=20qui=20g=C3=A8re=20l?= =?UTF-8?q?e=20niveau=20de=20commentaire=20concernant=20les=20=C3=A9l?= =?UTF-8?q?=C3=A9ments=20de=20contact)=20-=20am=C3=A9lioration=20de=20la?= =?UTF-8?q?=20m=C3=A9thode=20d'initialisation=20du=20contact,=20utilis?= =?UTF-8?q?=C3=A9e=20en=20d=C3=A9but=20d'incr=C3=A9ment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Algo/AlgoRef/Algori.cc | 35 +- .../AlgoDynaExplicite/AlgoriDynaExpli.cc | 16 +- .../AlgoStatiques/AlgoriNonDyna2.cc | 28 +- Chargement/Charge2.cc | 16 +- General/Distribution_CPU.cc | 2 +- Maillage/LesMaillages.cc | 6 + Maillage/LesMaillages.h | 8 +- Maillage/LesMaillages2.cc | 455 +++++++--- Maillage/Noeud.cc | 27 +- Parametres/EnteteParaGlob.h | 2 +- Parametres/ParaAlgoControle.cc | 43 +- Parametres/ParaAlgoControle.h | 7 +- TypeBase/TypeQuelconque.h | 1 + TypeBase/TypeQuelconqueParticulier.cc | 107 ++- TypeBase/TypeQuelconqueParticulier.h | 41 +- TypeBase/TypeQuelconqueParticulier_2.cc | 134 ++- TypeBase/TypeQuelconqueParticulier_3.cc | 16 +- comportement/Hypo_elastique/Hypo_hooke1D.cc | 25 +- comportement/Hypo_elastique/Hypo_hooke2D_C.cc | 26 +- comportement/Hypo_elastique/Hypo_hooke2D_C.h | 2 +- comportement/Hypo_elastique/Hypo_hooke3D.cc | 10 +- .../anisotropie/Hypo_ortho3D_entrainee.cc | 8 +- contact/ElContact.cc | 93 +- contact/ElContact.h | 4 +- contact/ElContact_2.cc | 8 +- contact/LesContacts.cc | 342 ++++--- contact/LesContacts.h | 50 +- contact/LesContacts_2.cc | 3 + contact/LesContacts_3.cc | 834 +++++++++++++++--- 29 files changed, 1850 insertions(+), 499 deletions(-) diff --git a/Algo/AlgoRef/Algori.cc b/Algo/AlgoRef/Algori.cc index 1c786c5..23de137 100644 --- a/Algo/AlgoRef/Algori.cc +++ b/Algo/AlgoRef/Algori.cc @@ -1749,6 +1749,7 @@ bool Algori::RaidSmEner(LesMaillages * lesMail,Assemblage& Ass,Vecteur & vglobin tempsRaidSmEner.Arret_du_comptage(); // fin comptage cpu #ifdef UTILISATION_MPI + // récupération des grandeurs locales par le proc 0 if (ParaGlob::Monde()->rank() == 0) { tempsRaidSmEner.Mise_en_route_du_comptage(); // comptage cpu // récup du nombre total d'éléments, cumul sur tous les maillages @@ -1794,7 +1795,26 @@ bool Algori::RaidSmEner(LesMaillages * lesMail,Assemblage& Ass,Vecteur & vglobin nb_elem_deja_calcule++; }; tempsRaidSmEner.Arret_du_comptage(); // fin comptage cpu + // }; + // maintenannt chaque proc i va transmettre au proc 0 les bilans + if (ParaGlob::Monde()->rank() != 0) + { + /* pour info, de plus il faut regarder plus haut le cas des intégralles... + + on part de l'idée que c'est mieux de transmettre petit à petit les grandeurs globales pour quelles suivent le même processus de mise en global + pour chaqu proc i comme pour le proc 0, car l'utilisation de ces grandeurs peut éventuellement être nécessaire tout de suite après ... + + energTotal.Inita(0.); // initialisation des énergies à 0 + energHourglass=0.;energStabiliMembBiel=0.; + volume_total_matiere = 0.; // init + E_bulk = 0.; // init + P_bulk=0.; // init + if (pa.CalVolTotalEntreSurfaceEtPlansRef()) + vol_total2D_avec_plan_ref.Inita(Coordonnee(ParaGlob::Dimension())); + + */ + } #endif #ifdef UTILISATION_MPI @@ -2161,6 +2181,14 @@ bool Algori::RaidSmEnerContact(LesContacts * lesCont,Assemblage& Ass,Vecteur & v } // -- on transfert en global les énergies Transfert_ParaGlob_energies_contact(); + // affichage éventuelle de la force maxi de contact + // pas nécessaire ici car c'est fait dans le calcul des réactions de contact +// lesCont->Forces_contact_maxi(true); + // idem pour les gap N et tangentiel +// lesCont->Gap_contact_maxi(true); + + if (permet_affichage >3) cout << "\n -- fin calcul second mmembre pour le contact " << flush; + if (permet_affichage >3) cout << "\n -- fin calcul second membre et raideur pour le contact " << flush; tempsRaidSmEnerContact.Arret_du_comptage(); // temps cpu @@ -2222,8 +2250,11 @@ bool Algori::SecondMembreEnergContact(LesContacts * lesCont,Assemblage& Ass,Vect if (ParaGlob::NiveauImpression() >= 10) { string entete = " affichage du second membre uniquement du au contact "; vglobin.Affichage_ecran(entete); - }; -//cout << vglobin << endl; + }; + + // -- on transfert en global les énergies + Transfert_ParaGlob_energies_contact(); + // affichage éventuelle de la force maxi de contact lesCont->Forces_contact_maxi(aff_iteration); // idem pour les gap N et tangentiel diff --git a/Algo/GalerkinContinu/AlgoDynaExplicite/AlgoriDynaExpli.cc b/Algo/GalerkinContinu/AlgoDynaExplicite/AlgoriDynaExpli.cc index e6de489..825ab5e 100644 --- a/Algo/GalerkinContinu/AlgoDynaExplicite/AlgoriDynaExpli.cc +++ b/Algo/GalerkinContinu/AlgoDynaExplicite/AlgoriDynaExpli.cc @@ -714,14 +714,16 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai if (pa.ContactType()) // réexamen du contact pour voir // il faut mettre le contact ici, car il utilise le déplacement de t à tdt {lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_tdt); //s'il n'y a pas - if (premier_calcul) {//double diam_mini = lesMail->Min_dist2Noeud_des_elements(TEMPS_t); + if (premier_calcul) + {//double diam_mini = lesMail->Min_dist2Noeud_des_elements(TEMPS_t); //lesContacts->DefElemCont(2. * diam_mini); //0.1); - lesContacts->DefElemCont(delta_X.Max_val_abs()); - premier_calcul=false;} // au début il n'y a pas de déplacement à priori, on prend 2. * le delta noeud mini - else - { lesContacts->SuppressionDefinitiveElemInactif(); // on supprime les éléments inactifs testés à l'incr prec dans Actualisation() - lesContacts->Nouveau(delta_X.Max_val_abs()); // idem mais je pense plus rapide - }; + lesContacts->DefElemCont(delta_X.Max_val_abs()); + premier_calcul=false; + } // au début il n'y a pas de déplacement à priori, on prend 2. * le delta noeud mini + else + { lesContacts->SuppressionDefinitiveElemInactif(); // on supprime les éléments inactifs testés à l'incr prec dans Actualisation() + lesContacts->Nouveau(delta_X.Max_val_abs()); // idem mais je pense plus rapide + }; }; // calcul des reactions de contact éventuelles (contact et frottement) et les puissances associées diff --git a/Algo/GalerkinContinu/AlgoStatiques/AlgoriNonDyna2.cc b/Algo/GalerkinContinu/AlgoStatiques/AlgoriNonDyna2.cc index b404e9c..9f72329 100644 --- a/Algo/GalerkinContinu/AlgoStatiques/AlgoriNonDyna2.cc +++ b/Algo/GalerkinContinu/AlgoStatiques/AlgoriNonDyna2.cc @@ -258,9 +258,6 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail, lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD); // verification qu'il n'y a pas de contact avant le premier increment de charge lesContacts->Verification(); -// // definition des elements de contact eventuels -// // et imposition éventuel de certaines des conditions de contact (dépend du modèle de contact) -// lesContacts->DefElemCont(0.); // au début le déplacement des noeuds est nul if (pa.ContactType() == 4) // cas particulier du type 4 de contact où on utilise les forces internes {// def d'un type générique, utilisé pour le transfert des forces internes, vers les conteneurs noeuds Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique @@ -817,6 +814,13 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail }; }; + #ifdef UTILISATION_MPI + if (pa.ContactType()) + { temps_transfert_long_algo.Mise_en_route_du_comptage(); // comptage cpu + vglobin.Broadcast(0); // transfert à tous les proc + temps_transfert_long_algo.Arret_du_comptage(); // fin comptage cpu + }; + #endif // calcul des maxi des puissances internes maxPuissInt = vglobin.Max_val_abs(); @@ -832,8 +836,8 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail F_int_tdt = vglobin; // sauvegarde des forces généralisées intérieures if (pa.ContactType() == 4) // si contact on passe les efforts aux noeuds - // on transfert les forces internes aux noeuds - lesMail->Quelconque_glob_vers_local(X1,F_int_tdt,typQ_gene_int); + // on transfert les forces internes aux noeuds + lesMail->Quelconque_glob_vers_local(X1,F_int_tdt,typQ_gene_int); // mise en place du chargement impose sur le second membre // et éventuellement sur la raideur en fonction de sur_raideur @@ -849,10 +853,22 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail // cas des efforts de contact, contribution second membre et matrice, // suivant le type de contact on utilise ou on recalcule les reactions de contact éventuelles (contact et frottement) if (pa.ContactType()) // et des énergies développées pendant le contact - // dans le cas où le calcul est inexploitable (pb dans le calcul) arrêt de la boucle + { + #ifdef UTILISATION_MPI + temps_transfert_long_algo.Mise_en_route_du_comptage(); // comptage cpu + vglobex.Broadcast(0); + temps_transfert_long_algo.Arret_du_comptage(); // fin comptage cpu + #endif +// dans le cas où le calcul est inexploitable (pb dans le calcul) arrêt de la boucle if (!RaidSmEnerContact(lescontacts,Ass,vcontact,(*matglob))) break; //cout << "\n debug AlgoNonDyna::CalEquilibre: vcontact => "; vcontact.Affiche(); // on globalise tout pour les forces externes généralisées + #ifdef UTILISATION_MPI + temps_transfert_long_algo.Mise_en_route_du_comptage(); // comptage cpu + vcontact.Broadcast(0); + temps_transfert_long_algo.Arret_du_comptage(); // fin comptage cpu + #endif + }; F_ext_tdt_prec = F_ext_tdt; // sauvegarde des valeurs de l'itération précédente if (pa.ContactType()) diff --git a/Chargement/Charge2.cc b/Chargement/Charge2.cc index 309e0b2..08cf539 100644 --- a/Chargement/Charge2.cc +++ b/Chargement/Charge2.cc @@ -491,7 +491,7 @@ bool Charge::ChargeSecondMembre_Ex_mecaSolid #else // cas non // { // appel du calcul du second membre correspondant à la charge surfacique - Vecteur& SM = elem.SM_charge_surfacique_E_tdt(vforce,pt_fonct,ref.NumeroFA(ns),pa); + Vecteur SM = elem.SM_charge_surfacique_E_tdt(vforce,pt_fonct,ref.NumeroFA(ns),pa); // assemblage du second membre // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée const ElFrontiere* elfront = NULL; // init @@ -619,7 +619,7 @@ bool Charge::ChargeSecondMembre_Ex_mecaSolid #else // cas non // { // appel du calcul du second membre correspondant à la charge de type pression // ici on récupère une adresse car il n'y a pas de crainte d'écraser un vecteur déjà en cours - Vecteur& SM = elem.SM_charge_pression_E_tdt(press_ac,pt_fonct,ref.NumeroFA(ns),pa); + Vecteur SM = elem.SM_charge_pression_E_tdt(press_ac,pt_fonct,ref.NumeroFA(ns),pa); // assemblage du second membre // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée const ElFrontiere* elfront = NULL; // init @@ -770,7 +770,7 @@ bool Charge::ChargeSecondMembre_Ex_mecaSolid #else // cas non // { // appel du calcul du second membre correspondant à la charge de type pression // ici on récupère une adresse car il n'y a pas de crainte d'écraser un vecteur déjà en cours - Vecteur& SM = elem.SM_charge_presUniDir_E_tdt(press_uni,pt_fonct,ref.NumeroFA(ns),pa); + Vecteur SM = elem.SM_charge_presUniDir_E_tdt(press_uni,pt_fonct,ref.NumeroFA(ns),pa); // assemblage du second membre // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée const ElFrontiere* elfront = NULL; // init @@ -911,7 +911,7 @@ bool Charge::ChargeSecondMembre_Ex_mecaSolid }; #else // cas non // { // appel du calcul du second membre correspondant à la charge lineique - Vecteur& SM = elem.SM_charge_lineique_E_tdt(f_lin,pt_fonct,ref.NumeroFA(ns),pa); + Vecteur SM = elem.SM_charge_lineique_E_tdt(f_lin,pt_fonct,ref.NumeroFA(ns),pa); // assemblage du second membre // il faut utiliser les noeuds et les ddlelement correspondant à la ligne chargée const ElFrontiere* elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // l'arete frontière @@ -1048,7 +1048,7 @@ bool Charge::ChargeSecondMembre_Ex_mecaSolid { // appel du calcul du second membre correspondant à la charge lineique // appel du calcul du second membre correspondant à la charge lineique // Vecteur f_lin = (tabFlineiqueSuiv_i.Coord()) * coeff ; - Vecteur SM& = elem.SM_charge_lineique_Suiv_E_tdt(f_lin,pt_fonct,ref.NumeroFA(ns),pa); + Vecteur SM = elem.SM_charge_lineique_Suiv_E_tdt(f_lin,pt_fonct,ref.NumeroFA(ns),pa); // assemblage du second membre // il faut utiliser les noeuds et les ddlelement correspondant à la ligne chargée const ElFrontiere* elfront = elem.Frontiere_lineique(ref.NumeroFA(ns)); // l'arete frontière @@ -1184,7 +1184,7 @@ bool Charge::ChargeSecondMembre_Ex_mecaSolid }; #else // cas non // {// appel du calcul du second membre correspondant à la charge volumique - Vecteur SM& = elem.SM_charge_volumique_E_tdt(f_vol,pt_fonct,pa,volume_finale); + Vecteur SM = elem.SM_charge_volumique_E_tdt(f_vol,pt_fonct,pa,volume_finale); // assemblage du second membre // il faut utiliser les noeuds et les ddlelement correspondant à l'élément assemb.AssemSM (vecglob,SM,elem.TableauDdl(),elem.Tab_noeud()); // assemblage @@ -1271,7 +1271,7 @@ bool Charge::ChargeSecondMembre_Ex_mecaSolid } }; #else // cas non // - {Vecteur SM& = elem.SM_charge_hydrostatique_E_tdt + {Vecteur SM = elem.SM_charge_hydrostatique_E_tdt (N,p_hydro,ref.NumeroFA(ns),A,pa,sans_limitation) ; // assemblage du second membre // il faut utiliser les noeuds et les ddlelement correspondant à la face chargée @@ -1360,7 +1360,7 @@ bool Charge::ChargeSecondMembre_Ex_mecaSolid }; #else // cas non // {// appel du calcul du second membre correspondant aux efforts hydrodynamique - Vecteur SM& = elem.SM_charge_hydrodynamique_E_tdt(coefHydroDyna_i.Frot_fluid(),poidvol + Vecteur SM = elem.SM_charge_hydrodynamique_E_tdt(coefHydroDyna_i.Frot_fluid(),poidvol ,coefHydroDyna_i.Coef_aero_n(),ref.NumeroFA(ns),coeff_charge ,coefHydroDyna_i.Coef_aero_t(),pa) ; // assemblage du second membre diff --git a/General/Distribution_CPU.cc b/General/Distribution_CPU.cc index 6443254..981b813 100755 --- a/General/Distribution_CPU.cc +++ b/General/Distribution_CPU.cc @@ -90,7 +90,7 @@ void Distribution_CPU::Calcul_Equilibrage_initiale(const LesMaillages * lesMai 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 + // pour que l'on puisse distribuer au moins un elem par proc de calcul if (total_elem < nb_proc_calcul) {cout << "\n *** erreur en calcul d'equilibrage initial: le nombre de cpu " << " disponible pour le calcul \n est inferieur au nb d'element total ! on ne peut pas continuer " diff --git a/Maillage/LesMaillages.cc b/Maillage/LesMaillages.cc index 404bda6..c27a3f1 100644 --- a/Maillage/LesMaillages.cc +++ b/Maillage/LesMaillages.cc @@ -56,6 +56,9 @@ LesMaillages::LesMaillages(): ,pour_statistique_de_ddl() ,statistique_t_typeQuel(),statistique_t_typeQuel_t(),ref_statistique_t() ,pour_statistique_t_de_ddl() +#ifdef UTILISATION_MPI + ,temps_transfert_long(),v_integ(),temps_serialisation() +#endif { cout << "\n erreur: ce constructeur ne doit pas etre utilise !!" << "\n LesMaillages::LesMaillages()"; @@ -76,6 +79,9 @@ LesMaillages::LesMaillages(UtilLecture * ent,ParaGlob * para,LesReferences* Ref) ,pour_statistique_de_ddl() ,statistique_t_typeQuel(),statistique_t_typeQuel_t(),ref_statistique_t() ,pour_statistique_t_de_ddl() +#ifdef UTILISATION_MPI + ,temps_transfert_long(),v_integ(),temps_serialisation() +#endif { lesRef = Ref; // mise à jour de la map qui fait la liaison nom de maillage <=> numéro de maillage lesRef->MiseAJourMap(mapNomMail); diff --git a/Maillage/LesMaillages.h b/Maillage/LesMaillages.h index 25673e1..2a8ec5b 100644 --- a/Maillage/LesMaillages.h +++ b/Maillage/LesMaillages.h @@ -922,7 +922,13 @@ class LesMaillages Tableau ref_statistique; // les références associées // si la référence est nulle, cela signifie que la statistique // est figée: sa valeur ne change pas - + #ifdef UTILISATION_MPI + // cas d'un calcul parallèle: // passage des infos entre process + Temps_CPU_HZpp temps_transfert_long ; + Temps_CPU_HZpp temps_serialisation ; + Vecteur v_integ; // conteneur intermédiaire de transfert + #endif + //pour_statistique_de_ddl a la même dimension que ref_statistique // 1) Dans le cas où ref_statistique(i) est une statistique de Ddl_enum_etendu // pour_statistique_de_ddl(i) == le Ddl_enum_etendu diff --git a/Maillage/LesMaillages2.cc b/Maillage/LesMaillages2.cc index b5a63be..95d158c 100644 --- a/Maillage/LesMaillages2.cc +++ b/Maillage/LesMaillages2.cc @@ -2126,147 +2126,356 @@ void LesMaillages::Integration() { // on passe en revue les références de volumes a intégrer // Tableau ref_integ_vol; // les références associées +#ifdef UTILISATION_MPI + int taill_v = 0; // pour le dimensionnement du transfert +#endif // les références sont ordonnées par apparition dans le fichier .info // des intégrales, ceci permet de repérer les bonnes grandeurs à cummuler int taill = ref_integ_vol.Taille(); for (int rang_integ =1;rang_integ<= taill;rang_integ++) if (ref_integ_vol(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas // l'intégrale stockée reste fixe pendant le calcul - { const ReferenceNE * ref = ((ReferenceNE *) ref_integ_vol(rang_integ)); + {const ReferenceNE * ref = ((ReferenceNE *) ref_integ_vol(rang_integ)); // initialisation du conteneur relatif à chaque ref TypeQuelconque& TQ = integ_vol_typeQuel(rang_integ); // pour simplifier // le conteneur qui contient le résultat globalisé TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); g_TG->InitParDefaut(); // on initialise le conteneur - - // cumule des valeurs: on récupère les infos à partir des éléments concernés - int ref_Taille=ref->Taille(); - for (int jj= 1; jj<= ref_Taille; jj++) - {int nbb = ref->Numero(jj) ; // le numero de l'element dans le maillage - int nnn = ref->Nbmaille(); // le numero du maillage - // recup de l'element - Element * poi = & Element_LesMaille(nnn,nbb); - // demande a l'element des infos - const Tableau * tab_Q = poi->Integ_vol_typeQuel(); - const Tableau & index_integ = *(poi->Index_Integ_vol_typeQuel()); - // la grandeur à cumuler c'est celle qui a le bon indexe - int indice = index_integ.Contient(rang_integ); - *(g_TG) += *((*tab_Q)(indice).Grandeur_pointee()); - -// -- les deux lignes d'avant sont a priori équivalentes aux lignes qui suivent -// int nb_integ = tab_Q->Taille(); // le nombre d'intégrale à considérer -// for (int iteg = 1;iteg <= nb_integ;iteg++) -// {if ((index_integ)(iteg)==rang_integ) // si l'index est négatif, on ne cumule pas -// // cela veut aussi dire que l'intégrale est figée -// // sinon si on a le bon index: on cumule l'intégrale -// {*(g_TG) += *((*tab_Q)(iteg).Grandeur_pointee()); -// break; -// }; -// }; + #ifdef UTILISATION_MPI + taill_v += g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + // en calcul parallèle, seule les proc i calculent les intégrales + if (ParaGlob::Monde()->rank() != 0) + { + #endif + // cumule des valeurs: on récupère les infos à partir des éléments concernés + int ref_Taille=ref->Taille(); + for (int jj= 1; jj<= ref_Taille; jj++) + {int num_elem = ref->Numero(jj) ; // le numero de l'element dans le maillage + int num_mail = ref->Nbmaille(); // le numero du maillage + + #ifdef UTILISATION_MPI + // on regarde si le proc i est concerné + if (ParaGlob::param->Element_concerner(num_mail,num_elem) ) + #endif + {// recup de l'element + Element * poi = & Element_LesMaille(num_mail,num_elem); + // demande a l'element des infos + const Tableau * tab_Q = poi->Integ_vol_typeQuel(); + const Tableau & index_integ = *(poi->Index_Integ_vol_typeQuel()); + // la grandeur à cumuler c'est celle qui a le bon indexe + int indice = index_integ.Contient(rang_integ); + *(g_TG) += *((*tab_Q)(indice).Grandeur_pointee()); + }; + + // -- les deux lignes d'avant sont a priori équivalentes aux lignes qui suivent + // int nb_integ = tab_Q->Taille(); // le nombre d'intégrale à considérer + // for (int iteg = 1;iteg <= nb_integ;iteg++) + // {if ((index_integ)(iteg)==rang_integ) // si l'index est négatif, on ne cumule pas + // // cela veut aussi dire que l'intégrale est figée + // // sinon si on a le bon index: on cumule l'intégrale + // {*(g_TG) += *((*tab_Q)(iteg).Grandeur_pointee()); + // break; + // }; + // }; + }; + // maintenant il s'agit d'alimenter les grandeurs globales + + // on récupère le pointeur correspondant à la grandeur correspondant au nom + // de référence + const string* nom_de_ref = g_TG->Nom_ref(); + #ifdef MISE_AU_POINT + if (nom_de_ref == NULL) + { cout << "\n *** pb dans l'integration !! " + << " nom_de_ref est nul, on ne peut pas continuer " + << "\n LesMaillages::Integration()"<GrandeurGlobal(*nom_de_ref)); + #ifdef MISE_AU_POINT + if (pointe == NULL) + { cout << "\n *** pb dans l'integration !! " + << " la variable globale "<< (*nom_de_ref) + << ", n'est pas disponible, on ne peut pas continuer " + << "\n LesMaillages::Integration()"<Nom_ref(); - #ifdef MISE_AU_POINT - if (nom_de_ref == NULL) - { cout << "\n *** pb dans l'integration !! " - << " nom_de_ref est nul, on ne peut pas continuer " - << "\n LesMaillages::Integration()"<Grandeur_pointee()) = *(g_TG); + #ifdef UTILISATION_MPI + }; + #endif + }; + // même chose pour les intégrales en volume et en temps + int taill1 = ref_integ_vol_t.Taille(); + for (int rang_integ =1;rang_integ<= taill1;rang_integ++) + if (ref_integ_vol_t(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas + // l'intégrale stockée reste fixe pendant le calcul + { const ReferenceNE * ref = ((ReferenceNE *) ref_integ_vol_t(rang_integ)); + // initialisation du conteneur relatif à chaque ref + TypeQuelconque& TQ = integ_vol_t_typeQuel(rang_integ); // pour simplifier + // le conteneur qui contient le résultat globalisé + TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); + g_TG->InitParDefaut(); // on initialise le conteneur + #ifdef UTILISATION_MPI + taill_v += g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + // en calcul parallèle, seule les proc i calculent les intégrales + if (ParaGlob::Monde()->rank() != 0) + { #endif - // récup du pointeur de conteneur - const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref)); - #ifdef MISE_AU_POINT - if (pointe == NULL) - { cout << "\n *** pb dans l'integration !! " - << " la variable globale "<< (*nom_de_ref) - << ", n'est pas disponible, on ne peut pas continuer " - << "\n LesMaillages::Integration()"<Nom_ref() -// << " :: " << *(g_TG) << flush; -// -//// -- fin debug - - - - TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); - *(gr_quelc->Grandeur_pointee()) = *(g_TG); - }; - // même chose pour les intégrales en volume et en temps - int taill1 = ref_integ_vol_t.Taille(); - for (int rang_integ =1;rang_integ<= taill1;rang_integ++) - if (ref_integ_vol_t(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas - // l'intégrale stockée reste fixe pendant le calcul - { const ReferenceNE * ref = ((ReferenceNE *) ref_integ_vol_t(rang_integ)); - // initialisation du conteneur relatif à chaque ref - TypeQuelconque& TQ = integ_vol_t_typeQuel(rang_integ); // pour simplifier - // le conteneur qui contient le résultat globalisé - TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); - g_TG->InitParDefaut(); // on initialise le conteneur - - // cumule des valeurs: on récupère les infos à partir des éléments concernés - int ref_Taille=ref->Taille(); - for (int jj= 1; jj<= ref_Taille; jj++) - {int nbb = ref->Numero(jj) ; // le numero de l'element dans le maillage - int nnn = ref->Nbmaille(); // le numero du maillage - // recup de l'element - Element * poi = & Element_LesMaille(nnn,nbb); - // demande a l'element des infos - const Tableau * tab_Q = poi->Integ_vol_t_typeQuel(); - const Tableau & index_integ = *(poi->Index_Integ_vol_t_typeQuel()); - // la grandeur à cumuler c'est celle qui a le bon indexe - int indice = index_integ.Contient(rang_integ); - *(g_TG) += *((*tab_Q)(indice).Grandeur_pointee()); + // cumule des valeurs: on récupère les infos à partir des éléments concernés + int ref_Taille=ref->Taille(); + for (int jj= 1; jj<= ref_Taille; jj++) + {int num_elem = ref->Numero(jj) ; // le numero de l'element dans le maillage + int num_mail = ref->Nbmaille(); // le numero du maillage + + #ifdef UTILISATION_MPI + // on regarde si le proc i est concerné + if (ParaGlob::param->Element_concerner(num_mail,num_elem) ) + #endif + {// recup de l'element + Element * poi = & Element_LesMaille(num_mail,num_elem); + // demande a l'element des infos + const Tableau * tab_Q = poi->Integ_vol_t_typeQuel(); + const Tableau & index_integ = *(poi->Index_Integ_vol_t_typeQuel()); + // la grandeur à cumuler c'est celle qui a le bon indexe + int indice = index_integ.Contient(rang_integ); + *(g_TG) += *((*tab_Q)(indice).Grandeur_pointee()); + }; - -// -- les deux lignes d'avant sont a priori équivalentes aux lignes qui suivent -// int nb_integ = tab_Q->Taille(); // le nombre d'intégrale à considérer -// for (int iteg = 1;iteg <= nb_integ;iteg++) -// {if ((index_integ)(iteg)==rang_integ) -// // sinon si on a le bon index: on cumule l'intégrale -// {*(g_TG) += *((*tab_Q)(iteg).Grandeur_pointee()); -// break; -// }; -// }; + + // -- les deux lignes d'avant sont a priori équivalentes aux lignes qui suivent + // int nb_integ = tab_Q->Taille(); // le nombre d'intégrale à considérer + // for (int iteg = 1;iteg <= nb_integ;iteg++) + // {if ((index_integ)(iteg)==rang_integ) + // // sinon si on a le bon index: on cumule l'intégrale + // {*(g_TG) += *((*tab_Q)(iteg).Grandeur_pointee()); + // break; + // }; + // }; + }; + // maintenant il s'agit d'alimenter les grandeurs globales + + // on récupère le pointeur correspondant à la grandeur correspondant au nom + // de référence + const string* nom_de_ref = g_TG->Nom_ref(); + #ifdef MISE_AU_POINT + if (nom_de_ref == NULL) + { cout << "\n *** pb dans l'integration !! " + << " nom_de_ref est nul, on ne peut pas continuer " + << "\n LesMaillages::Integration()"<GrandeurGlobal(*nom_de_ref)); + #ifdef MISE_AU_POINT + if (pointe == NULL) + { cout << "\n *** pb dans l'integration !! " + << " la variable globale "<< (*nom_de_ref) + << ", n'est pas disponible, on ne peut pas continuer " + << "\n LesMaillages::Integration()"<Grandeur_pointee()) = *(g_TG); + #ifdef UTILISATION_MPI + }; + #endif + }; +#ifdef UTILISATION_MPI + if (ParaGlob::Monde()->rank() != 0) + {temps_serialisation.Mise_en_route_du_comptage(); // comptage cpu + // on va transmettre au proc 0 les résultats pour que celui-ci globalise les informations + // on va utiliser un conteneur intermédiaire pour un unique transfert: + // 1) on commence par le re dimensionnner + v_integ.Change_taille(taill_v); + // on rempli le conteneur : c-a-d sérialisation uniquement des valeurs + int indice_v=1; // init + // 2) récup résultats intégrales de volumes + for (int rang_integ =1;rang_integ<= taill;rang_integ++) + if (ref_integ_vol(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas + // l'intégrale stockée reste fixe pendant le calcul + { // initialisation du conteneur relatif à chaque ref + TypeQuelconque& TQ = integ_vol_typeQuel(rang_integ); // pour simplifier + // le conteneur qui contient le résultat globalisé + TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); + int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + for (int i=1;i<= nb_ordre;i++,indice_v++) + v_integ(indice_v) = g_TG->GrandeurNumOrdre(i); }; - // maintenant il s'agit d'alimenter les grandeurs globales + // 3) récup résultats intégrales en volume et en temps + for (int rang_integ =1;rang_integ<= taill1;rang_integ++) + if (ref_integ_vol_t(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas + // l'intégrale stockée reste fixe pendant le calcul + { // initialisation du conteneur relatif à chaque ref + TypeQuelconque& TQ = integ_vol_t_typeQuel(rang_integ); // pour simplifier + // le conteneur qui contient le résultat globalisé + TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); + int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + for (int i=1;i<= nb_ordre;i++,indice_v++) + v_integ(indice_v) = g_TG->GrandeurNumOrdre(i); + }; + temps_serialisation.Arret_du_comptage(); // fin comptage cpu + temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu + // 4) transfert sans attente au proc 0 + mpi::request reqs1 = ParaGlob::Monde()->isend(0, 50, v_integ); + temps_transfert_long.Arret_du_comptage(); // comptage cpu + } + else // cas du proc 0 + {// on récupère les infos + // les conteneurs ont déjà été initialisé pendant le calcul de taill_v - // on récupère le pointeur correspondant à la grandeur correspondant au nom - // de référence - const string* nom_de_ref = g_TG->Nom_ref(); - #ifdef MISE_AU_POINT - if (nom_de_ref == NULL) - { cout << "\n *** pb dans l'integration !! " - << " nom_de_ref est nul, on ne peut pas continuer " - << "\n LesMaillages::Integration()"<GrandeurGlobal(*nom_de_ref)); - #ifdef MISE_AU_POINT - if (pointe == NULL) - { cout << "\n *** pb dans l'integration !! " - << " la variable globale "<< (*nom_de_ref) - << ", n'est pas disponible, on ne peut pas continuer " - << "\n LesMaillages::Integration()"<size()-1)) // gérer par les valeurs de tyfront + { // on récupère un résultat de cpu i + temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu + mpi::request reqs2 = v_integ.Irecup_MPI(mpi::any_source, 50); + reqs2.wait(); // on attend que le conteneur soit rempli + temps_transfert_long.Arret_du_comptage(); // fin comptage cpu + temps_serialisation.Mise_en_route_du_comptage(); // comptage cpu + // désérialisation et ajout pour globaliser + int indice_v=1; // init + // 1) cas des intégrales de volumes + for (int rang_integ =1;rang_integ<= taill;rang_integ++) + if (ref_integ_vol(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas + // l'intégrale stockée reste fixe pendant le calcul + { // désérialisation du conteneur relatif à chaque ref + TypeQuelconque& TQ = integ_vol_typeQuel(rang_integ); // pour simplifier + // le conteneur qui contient le résultat globalisé + TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); + int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + for (int i=1;i<= nb_ordre;i++,indice_v++) + {double val_modifier = g_TG->GrandeurNumOrdre(i)+v_integ(indice_v); + g_TG->Change_GrandeurNumOrdre(i,val_modifier); // modification + }; + }; + // 2) cas des intégrales en volume et temps + for (int rang_integ =1;rang_integ<= taill1;rang_integ++) + if (ref_integ_vol_t(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas + // l'intégrale stockée reste fixe pendant le calcul + { // désérialisation du conteneur relatif à chaque ref + TypeQuelconque& TQ = integ_vol_t_typeQuel(rang_integ); // pour simplifier + // le conteneur qui contient le résultat globalisé + TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); + int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + for (int i=1;i<= nb_ordre;i++,indice_v++) + {double val_modifier = g_TG->GrandeurNumOrdre(i)+v_integ(indice_v); + g_TG->Change_GrandeurNumOrdre(i,val_modifier); // modification + }; + }; + nb_proc_terminer++; + temps_serialisation.Arret_du_comptage(); // fin comptage cpu }; - #endif - // on l'affecte - TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); - *(gr_quelc->Grandeur_pointee()) = *(g_TG); - }; + + // maintenant on alimente les grandeurs globales, et on rempli le conteneur de transfert + // pour passer les infos aux proc i + // on rempli le conteneur : c-a-d sérialisation uniquement des valeurs + int indice_v=1; // init + // 1) cas des intégrales de volumes + for (int rang_integ =1;rang_integ<= taill;rang_integ++) + if (ref_integ_vol(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas + // l'intégrale stockée reste fixe pendant le calcul + { TypeQuelconque& TQ = integ_vol_typeQuel(rang_integ); // pour simplifier + // le conteneur qui contient le résultat globalisé + TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); + int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + for (int i=1;i<= nb_ordre;i++,indice_v++) + v_integ(indice_v) = g_TG->GrandeurNumOrdre(i); + // on récupère le pointeur correspondant à la grandeur correspondant au nom + // de référence + const string* nom_de_ref = g_TG->Nom_ref(); + // récup du pointeur de conteneur + const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref)); + TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); + *(gr_quelc->Grandeur_pointee()) = *(g_TG); + }; + + // 2) cas des intégrales en volume et temps + for (int rang_integ =1;rang_integ<= taill1;rang_integ++) + if (ref_integ_vol_t(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas + // l'intégrale stockée reste fixe pendant le calcul + { // désérialisation du conteneur relatif à chaque ref + TypeQuelconque& TQ = integ_vol_t_typeQuel(rang_integ); // pour simplifier + // le conteneur qui contient le résultat globalisé + TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); + int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + for (int i=1;i<= nb_ordre;i++,indice_v++) + v_integ(indice_v) = g_TG->GrandeurNumOrdre(i); + // on récupère le pointeur correspondant à la grandeur correspondant au nom + // de référence + const string* nom_de_ref = g_TG->Nom_ref(); + // récup du pointeur de conteneur + const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref)); + TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); + *(gr_quelc->Grandeur_pointee()) = *(g_TG); + }; + + }; + + // le proc 0 transmet aux proc i + temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu + v_integ.Broadcast(0); + temps_transfert_long.Arret_du_comptage(); // fin comptage cpu + + // pour les proc i, il faut mettre à jour les variables globales + if (ParaGlob::Monde()->rank() != 0) + {temps_serialisation.Mise_en_route_du_comptage(); // comptage cpu + // on désérialise uniquement les valeurs + // désérialisation + int indice_v=1; // init + // 1) cas des intégrales de volumes + for (int rang_integ =1;rang_integ<= taill;rang_integ++) + if (ref_integ_vol(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas + // l'intégrale stockée reste fixe pendant le calcul + { // désérialisation du conteneur relatif à chaque ref + TypeQuelconque& TQ = integ_vol_typeQuel(rang_integ); // pour simplifier + // le conteneur qui contient le résultat globalisé + TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); + int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + for (int i=1;i<= nb_ordre;i++,indice_v++) + g_TG->Change_GrandeurNumOrdre(i,v_integ(indice_v)); // modification + // on récupère le pointeur correspondant à la grandeur correspondant au nom + // de référence + const string* nom_de_ref = g_TG->Nom_ref(); + // récup du pointeur de conteneur + const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref)); + TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); + *(gr_quelc->Grandeur_pointee()) = *(g_TG); + }; + // 2) cas des intégrales en volume et temps + for (int rang_integ =1;rang_integ<= taill1;rang_integ++) + if (ref_integ_vol_t(rang_integ) != NULL) // si null cela veut que l'on n'intègre pas + // l'intégrale stockée reste fixe pendant le calcul + { // désérialisation du conteneur relatif à chaque ref + TypeQuelconque& TQ = integ_vol_t_typeQuel(rang_integ); // pour simplifier + // le conteneur qui contient le résultat globalisé + TypeQuelconque::Grandeur* g_TG = TQ.Grandeur_pointee(); + int nb_ordre = g_TG->NbMaxiNumeroOrdre(); // récup du nb maxi de numéros d'ordres + for (int i=1;i<= nb_ordre;i++,indice_v++) + g_TG->Change_GrandeurNumOrdre(i,v_integ(indice_v)); // modification + // on récupère le pointeur correspondant à la grandeur correspondant au nom + // de référence + const string* nom_de_ref = g_TG->Nom_ref(); + // récup du pointeur de conteneur + const void* pointe = (ParaGlob::param->GrandeurGlobal(*nom_de_ref)); + TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe); + *(gr_quelc->Grandeur_pointee()) = *(g_TG); + }; + temps_serialisation.Arret_du_comptage(); // fin comptage cpu + } + + +#endif + }; diff --git a/Maillage/Noeud.cc b/Maillage/Noeud.cc index 483e526..7f09313 100644 --- a/Maillage/Noeud.cc +++ b/Maillage/Noeud.cc @@ -1504,8 +1504,11 @@ void Noeud::Met_en_service_ddl() // changement du statut de variable à donnée pour un tableau d'enum de ddl void Noeud::ChangeVariable_a_Donnee(const Tableau& taben) { int tabenTaille = taben.Taille(); - for (int i = 1; i<=tabenTaille; i++) - tab_ddl(Existe(taben(i))).ChangeVariable_a_Donnee(); + for (int i = 1; i<=tabenTaille; i++) + {int exist = Existe(taben(i)); + if (exist) + tab_ddl(exist).ChangeVariable_a_Donnee(); + }; MiseAjourActif(); }; @@ -1513,7 +1516,10 @@ void Noeud::ChangeVariable_a_Donnee(const Tableau& taben) void Noeud::ChangeDonnee_a_Variable(const Tableau& taben) { int tabenTaille = taben.Taille(); for (int i = 1; i<=tabenTaille; i++) - tab_ddl(Existe(taben(i))).ChangeVariable_a_Donnee(); + {int exist = Existe(taben(i)); + if (exist) + tab_ddl(exist).ChangeVariable_a_Donnee(); + }; MiseAjourActif(); }; @@ -1523,7 +1529,10 @@ void Noeud::ChangeDonnee_a_Variable(const Tableau& taben) void Noeud::ChangeToutesLesConditions(const Tableau& ta) { int taTaille = ta.Taille(); for (int i = 1; i<=taTaille; i++) - { tab_ddl(Existe(ta(i).Id_nom())).CopieToutesLesConditions(ta(i).Retour_Fixe());}; + {int exist = Existe(ta(i).Id_nom()); + if (exist) + tab_ddl(exist).CopieToutesLesConditions(ta(i).Retour_Fixe()); + }; MiseAjourActif(); }; @@ -1537,7 +1546,10 @@ void Noeud::ChangeStatut(int cas,Enum_ddl enuta) int tenuTaille = tenu.Taille(); Enum_boolddl enubold=tab_ddl(Existe(enuta)).Retour_Fixe(); for (int i = 1; i<=tenuTaille; i++) - { tab_ddl(Existe(tenu(i))).CopieToutesLesConditions(enubold);}; + {int exist = Existe(tenu(i)); + if (exist) + tab_ddl(exist).CopieToutesLesConditions(enubold); + }; MiseAjourActif(); }; @@ -1549,7 +1561,10 @@ void Noeud::ChangeStatut(int cas,Enum_boolddl enubold) Tableau tenu= Combinaison(cas); int tenuTaille = tenu.Taille(); for (int i = 1; i<=tenuTaille; i++) - { tab_ddl(Existe(tenu(i))).CopieToutesLesConditions(enubold);}; + {int exist = Existe(tenu(i)); + if (exist) + tab_ddl(exist).CopieToutesLesConditions(enubold); + }; MiseAjourActif(); }; diff --git a/Parametres/EnteteParaGlob.h b/Parametres/EnteteParaGlob.h index 88388b7..a857a3d 100644 --- a/Parametres/EnteteParaGlob.h +++ b/Parametres/EnteteParaGlob.h @@ -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.020" ; // numéro de version du logiciel + string ParaGlob::nbVersion = "7.023" ; // 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 diff --git a/Parametres/ParaAlgoControle.cc b/Parametres/ParaAlgoControle.cc index 033373f..a44d0ea 100755 --- a/Parametres/ParaAlgoControle.cc +++ b/Parametres/ParaAlgoControle.cc @@ -203,6 +203,7 @@ ParaAlgoControle::ParaAlgoControle() : nb_glissant = 1; // par défaut il n'y a pas de moyenne glissante niveau_commentaire_lescontacts = 0; // par défaut c'est le général qui commande + fct_niveau_commentaire_lescontacts = "_";// pas de fonction par défaut niveau_commentaire_contact = 0; // par défaut c'est le général qui commande fct_niveau_commentaire_contact = "_";// pas de fonction par défaut @@ -317,6 +318,7 @@ ParaAlgoControle::ParaAlgoControle(const ParaAlgoControle& p) : nb_boucle_newton_position_frontiere(p.nb_boucle_newton_position_frontiere), nbDecolAutorise(p.nbDecolAutorise),typeDeDecolement(p.typeDeDecolement),nb_glissant(p.nb_glissant), niveau_commentaire_lescontacts(p.niveau_commentaire_lescontacts), + fct_niveau_commentaire_lescontacts(p.fct_niveau_commentaire_lescontacts), niveau_commentaire_contact(p.niveau_commentaire_contact), fct_niveau_commentaire_contact(p.fct_niveau_commentaire_contact), optimisation_numerotation(p.optimisation_numerotation), @@ -430,6 +432,7 @@ ParaAlgoControle& ParaAlgoControle::operator= (const ParaAlgoControle& p) nbDecolAutorise = p.nbDecolAutorise; typeDeDecolement = p.typeDeDecolement; nb_glissant = p.nb_glissant; niveau_commentaire_lescontacts = p.niveau_commentaire_lescontacts; + fct_niveau_commentaire_lescontacts = p.fct_niveau_commentaire_lescontacts; niveau_commentaire_contact = p.niveau_commentaire_contact; fct_niveau_commentaire_contact = p.fct_niveau_commentaire_contact; @@ -1108,8 +1111,15 @@ void ParaAlgoControle::Lecture_paraAlgoControle(UtilLecture & entreePrinc) else if (nom == "NB_MOY_GLISSANT") {nb_glissant= (int) entreePrinc.lect_avec_const_double_utilisateur("NB_MOY_GLISSANT ");} else if (nom == "NIVEAU_COMMENTAIRE_LESCONTACTS") - {niveau_commentaire_lescontacts= (int) entreePrinc.lect_avec_const_double_utilisateur("NIVEAU_COMMENTAIRE_LESCONTACTS "); - } + {if (strstr(entreePrinc.tablcar,"FCT_ND_NIVEAU_COMMENTAIRE_LESCONTACTS")!=NULL) + {*(entreePrinc.entree) >> nom_inter >> fct_niveau_commentaire_lescontacts; + niveau_commentaire_lescontacts = -1; // valeur négative arbitraire + } + else + {niveau_commentaire_lescontacts= (int) entreePrinc.lect_avec_const_double_utilisateur("NIVEAU_COMMENTAIRE_LESCONTACTS "); + fct_niveau_commentaire_lescontacts = "_"; + }; + } else if (nom == "NIVEAU_COMMENTAIRE_CONTACT") {if (strstr(entreePrinc.tablcar,"FCT_ND_NIVEAU_COMMENTAIRE_CONTACT")!=NULL) {*(entreePrinc.entree) >> nom_inter >> fct_niveau_commentaire_contact; @@ -1460,7 +1470,8 @@ void ParaAlgoControle::Ecriture_base_info_Para sort << "NB_DECOLLEMENT_MAXI " << nbDecolAutorise << "\n"; sort << "TYPE_DE_DECOLLEMENT " << typeDeDecolement << "\n"; sort << "NB_MOY_GLISSANT " << nb_glissant << "\n"; - sort << "NIVEAU_COMMENTAIRE_LESCONTACTS "<< niveau_commentaire_lescontacts << "\n"; + sort << "NIVEAU_COMMENTAIRE_LESCONTACTS "<< niveau_commentaire_lescontacts + << "FCT_ND_NIVEAU_COMMENTAIRE_LESCONTACT"<< fct_niveau_commentaire_lescontacts << "\n"; sort << "NIVEAU_COMMENTAIRE_CONTACT "<< niveau_commentaire_contact << "FCT_ND_NIVEAU_COMMENTAIRE_CONTACT"<< fct_niveau_commentaire_contact << "\n"; sort << "OPTIMISATION_NUMEROTATION "<< optimisation_numerotation << "\n"; @@ -1671,7 +1682,7 @@ void ParaAlgoControle::Lecture_base_info_Para(ifstream& ent,const int cas) ent >> toto >> nbDecolAutorise ; ent >> toto >> typeDeDecolement ; ent >> toto >> nb_glissant ; - ent >> toto >> niveau_commentaire_lescontacts; + ent >> toto >> niveau_commentaire_lescontacts >> toto >> fct_niveau_commentaire_lescontacts; ent >> toto >> niveau_commentaire_contact >> toto >> fct_niveau_commentaire_contact; ent >> toto >> optimisation_numerotation; // 7) paramètres liès aux énergies @@ -1879,7 +1890,8 @@ void ParaAlgoControle::Affiche() const cout << "NB_DECOLLEMENT_MAXI " << nbDecolAutorise << "\n"; cout << "TYPE_DE_DECOLLEMENT " << typeDeDecolement << "\n"; cout << "NB_MOY_GLISSANT " << nb_glissant << "\n"; - cout << "NIVEAU_COMMENTAIRE_LESCONTACTS " << niveau_commentaire_lescontacts << "\n"; + cout << "NIVEAU_COMMENTAIRE_LESCONTACTS " << niveau_commentaire_lescontacts + << "FCT_ND_NIVEAU_COMMENTAIRE_LESCONTACTS"<< fct_niveau_commentaire_lescontacts << "\n"; cout << "NIVEAU_COMMENTAIRE_CONTACT " << niveau_commentaire_contact << "FCT_ND_NIVEAU_COMMENTAIRE_CONTACT"<< fct_niveau_commentaire_contact << "\n"; cout << "OPTIMISATION_NUMEROTATION " << optimisation_numerotation << "\n"; @@ -2528,7 +2540,7 @@ void ParaAlgoControle::Info_commande_ParaAlgoControle(UtilLecture& entreePrinc) << "\n#--------------------------- " << "\n# PARAMETRE | VALEUR | " << "\n#--------------------------- "; - Tableau tab_modif(36,false); // indique qu'est-ce qui a été modifié + Tableau tab_modif(37,false); // indique qu'est-ce qui a été modifié //On va proposer un menu string repa=" "; cout << "\n --- controle generaux ------ "; @@ -2572,16 +2584,17 @@ void ParaAlgoControle::Info_commande_ParaAlgoControle(UtilLecture& entreePrinc) << "\n (33) FCT_ND_TANGENTIELLE_BORNE_REGULARISATION " << "\n (34) FCT_ND_FORCE_TANGENTIELLE_NOEUD_MAXI " << "\n (35) FCT_ND_NIVEAU_COMMENTAIRE_CONTACT " - << "\n (36 ou h ou ? ) informations " + << "\n (36) FCT_ND_NIVEAU_COMMENTAIRE_LESCONTACTS " + << "\n (37 ou h ou ? ) informations " << "\n "; repa = lect_return_defaut(false,"f"); if ((Minuscules(repa) == "f") || (Minuscules(repa) == "0"))// sortie directe break; int numa = ChangeEntier(repa); - if (repa == "?") numa = 36; + if (repa == "?") numa = 37; - if (!((numa >= 0)&&(numa<=36))) - { cout << "\n Erreur on attendait un entier entre 0 et 36 !!, " + if (!((numa >= 0)&&(numa<=37))) + { cout << "\n Erreur on attendait un entier entre 0 et 37 !!, " << "\n redonnez une bonne valeur" << "\n ou taper f ou 0 pour arreter le programme"; }; @@ -2614,13 +2627,13 @@ void ParaAlgoControle::Info_commande_ParaAlgoControle(UtilLecture& entreePrinc) { cout << " *** erreur: valeur non numerique !! ";}; break; } - case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35: + case 26:case 27:case 28:case 29:case 30:case 31:case 32:case 33:case 34:case 35:case 36: { cout << "\n donner le nom de la fonction nD (un string ) ? "; val_string= lect_chaine();cout << " nom lue ="<Dimension()) + {case -1: case 1: (*ptTens).Coor(1,1)=val;break; + case -2:{Tenseur_ns2HH& tens = *((Tenseur_ns2HH*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + case 2: {Tenseur2HH& tens = *((Tenseur2HH*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + case -3:{Tenseur_ns3HH& tens = *((Tenseur_ns3HH*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + case 3: {Tenseur3HH& tens = *((Tenseur3HH*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + default: + cout << "\n erreur dimension du tenseur non defini !" + << "\n Grandeur_TenseurHH::Change_GrandeurNumOrdre()"; + Sortie(1); + }; + }; // récup du nb maxi de numéros d'ordres int Grandeur_TenseurHH::NbMaxiNumeroOrdre() const { switch (ptTens->Dimension()) @@ -527,6 +550,24 @@ double Grandeur_TenseurBB::GrandeurNumOrdre(int n) const }; return 0.; // pour taire le warning }; +// modification +void Grandeur_TenseurBB::Change_GrandeurNumOrdre(int n, const double& val) +{ switch (ptTens->Dimension()) + {case -1: case 1: (*ptTens).Coor(1,1)=val;break; + case -2:{Tenseur_ns2BB& tens = *((Tenseur_ns2BB*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + case 2: {Tenseur2BB& tens = *((Tenseur2BB*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + case -3:{Tenseur_ns3BB& tens = *((Tenseur_ns3BB*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + case 3: {Tenseur3BB& tens = *((Tenseur3BB*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + default: + cout << "\n erreur dimension du tenseur non defini !" + << "\n Grandeur_TenseurBB::Change_GrandeurNumOrdre()"; + Sortie(1); + }; + }; // récup du nb maxi de numéros d'ordres int Grandeur_TenseurBB::NbMaxiNumeroOrdre() const { switch (ptTens->Dimension()) @@ -710,6 +751,20 @@ double Grandeur_TenseurBH::GrandeurNumOrdre(int n) const }; return 0.; // pour taire le warning }; +// modification +void Grandeur_TenseurBH::Change_GrandeurNumOrdre(int n, const double& val) +{ switch (ptTens->Dimension()) + {case 1: (*ptTens).Coor(1,1)=val;break; + case 2: {Tenseur2BH& tens = *((Tenseur2BH*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + case 3: {Tenseur3BH& tens = *((Tenseur3BH*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + default: + cout << "\n erreur dimension du tenseur non defini !" + << "\n Grandeur_TenseurBH::Change_GrandeurNumOrdre()"; + Sortie(1); + }; + }; // récup du nb maxi de numéros d'ordres int Grandeur_TenseurBH::NbMaxiNumeroOrdre() const { switch (ptTens->Dimension()) @@ -987,6 +1042,16 @@ double Tab_Grandeur_TenseurHH::GrandeurNumOrdre(int n) const int r_div = (n-1)%nbpartenseur+1; return tabTens(indice_tableau)->GrandeurNumOrdre(r_div); }; +// modification +void Tab_Grandeur_TenseurHH::Change_GrandeurNumOrdre(int n, const double& val) +{ int taille = tabTens.Taille(); + if (taille != 0) // si tableau vide on ne fait rien + {int nbpartenseur=tabTens(1)->NbMaxiNumeroOrdre(); + int indice_tableau = (n-1)/nbpartenseur + 1; + int r_div = (n-1)%nbpartenseur+1; + tabTens(indice_tableau)->Change_GrandeurNumOrdre(r_div,val); + }; + }; // récup du nb maxi de numéros d'ordres int Tab_Grandeur_TenseurHH::NbMaxiNumeroOrdre() const { if (tabTens.Taille() == 0) return 0; // cas d'un tableau vide @@ -1275,6 +1340,17 @@ double Tab2_Grandeur_TenseurHH::GrandeurNumOrdre(int n) const int r_div = (r_i-1)%nbpartenseur+1; return tabTens(in_i,in_j)->GrandeurNumOrdre(r_div); }; +// modification +void Tab2_Grandeur_TenseurHH::Change_GrandeurNumOrdre(int n, const double& val) +{ int taille1 = tabTens.Taille1();int taille2 = tabTens.Taille2(); + if ((taille1 == 0) || (taille2==0)) return ; // cas d'un tableau vide, on ne fait rien + int nbpartenseur=tabTens(1,1)->NbMaxiNumeroOrdre(); + int in_i = (n-1)/(nbpartenseur*taille2) + 1; + int r_i = (n-1)%(nbpartenseur*taille2)+1; // reste de la première division + int in_j = (r_i-1)/nbpartenseur + 1; + int r_div = (r_i-1)%nbpartenseur+1; + tabTens(in_i,in_j)->Change_GrandeurNumOrdre(r_div,val); + }; // récup du nb maxi de numéros d'ordres int Tab2_Grandeur_TenseurHH::NbMaxiNumeroOrdre() const { if ((tabTens.Taille1() == 0)||(tabTens.Taille2() == 0)) return 0; // cas d'un tableau vide @@ -1620,6 +1696,12 @@ double Tab_Grandeur_scalaire_double::GrandeurNumOrdre(int num) const if ((num <=0) || (num > taille)) {return 0.;} else return tab_val(num).val; }; +// modification +void Tab_Grandeur_scalaire_double::Change_GrandeurNumOrdre(int num, const double& val) + {int taille = tab_val.Taille(); + if ((num <=0) || (num > taille)) {return ;} // on ne fait rien + else tab_val(num).val=val; + }; void Tab_Grandeur_scalaire_double::Grandeur_brut(ostream & sort,int nbcar) const {int taille = tab_val.Taille(); @@ -1768,6 +1850,13 @@ void Grandeur_coordonnee::operator-= (const Grandeur& a) double Grandeur_coordonnee::GrandeurNumOrdre(int num) const {if((num>0)&&(num<=co.Dimension())) return co(num); else return 0.;}; +// modification +void Grandeur_coordonnee::Change_GrandeurNumOrdre(int num, const double& val) + {if((num>0)&&(num<=co.Dimension())) + co(num)=val; + // sinon on ne fait rien + }; + // change de repère de la grandeur void Grandeur_coordonnee::Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma ) {cout << "\n **** non implante !!! " @@ -2021,6 +2110,15 @@ double Tab_Grandeur_Coordonnee::GrandeurNumOrdre(int n) const int r_div = (n-1)%nbparcoor+1; return tabCoor(indice_tableau)->GrandeurNumOrdre(r_div); }; +// modification +void Tab_Grandeur_Coordonnee::Change_GrandeurNumOrdre(int n, const double& val) + { int taille = tabCoor.Taille(); + if (taille == 0) return ; // cas d'un tableau vide + int nbparcoor=tabCoor(1)->NbMaxiNumeroOrdre(); + int indice_tableau = (n-1)/nbparcoor + 1; + int r_div = (n-1)%nbparcoor+1; + tabCoor(indice_tableau)->Change_GrandeurNumOrdre(r_div,val); + }; // récup du nb maxi de numéros d'ordres int Tab_Grandeur_Coordonnee::NbMaxiNumeroOrdre() const { if (tabCoor.Taille() == 0) return 0; // cas d'un tableau vide @@ -2416,6 +2514,13 @@ double Tab_Grandeur_Ddl_etendu::GrandeurNumOrdre(int n) const if (n > taille) {return 0.;} // cas où c'est impossible else {return tabDdlEte(n)->GrandeurNumOrdre(1);}; }; +// modification +void Tab_Grandeur_Ddl_etendu::Change_GrandeurNumOrdre(int n, const double& val) + { int taille = tabDdlEte.Taille(); + if (taille == 0) return ; // cas d'un tableau vide + if (n > taille) {return ;} // cas où c'est impossible + else {tabDdlEte(n)->Change_GrandeurNumOrdre(1,val);}; + }; // récup du nb maxi de numéros d'ordres int Tab_Grandeur_Ddl_etendu::NbMaxiNumeroOrdre() const diff --git a/TypeBase/TypeQuelconqueParticulier.h b/TypeBase/TypeQuelconqueParticulier.h index 39aa431..0d6595c 100644 --- a/TypeBase/TypeQuelconqueParticulier.h +++ b/TypeBase/TypeQuelconqueParticulier.h @@ -119,6 +119,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const; // sortie de la grandeur brut sur sort // ramène le type de grandeur associée de la grandeur de base, car @@ -191,6 +192,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const ; // ramène le type de grandeur associée de la grandeur de base, car @@ -271,6 +273,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const ; // ramène le type de grandeur associée de la grandeur de base, car @@ -351,6 +354,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const ; // ramène le type de grandeur associée de la grandeur de base, car @@ -432,6 +436,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const ; // ramène le type de grandeur associée de la grandeur de base, car @@ -512,6 +517,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const; // ramène le type de grandeur associée de la grandeur de base, car @@ -598,6 +604,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const; // ramène le type de grandeur associée de la grandeur de base, car @@ -684,6 +691,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const; // ramène le type de grandeur associée de la grandeur de base, car @@ -770,6 +778,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const; // ramène le type de grandeur associée de la grandeur de base, car @@ -855,6 +864,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const; // ramène le type de grandeur associée de la grandeur de base, car @@ -939,6 +949,8 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const {if(num==1) return val; else return 0.;}; + void Change_GrandeurNumOrdre(int num, const double& val_) // modification + {if(num==1) val = val_; else val = 0.;}; int NbMaxiNumeroOrdre() const {return 1;}; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const {sort <<" "<< setw(nbcar)<< setprecision(nbcar) << val << " ";}; @@ -1013,6 +1025,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const {return tab_val.Taille();}; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const ; // ramène le type de grandeur associée de la grandeur de base, car @@ -1099,6 +1112,8 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const {if(num==1) return val; else return 0.;}; + void Change_GrandeurNumOrdre(int num, const double& val_) // modification + {if(num==1) val=val_; else val = 0.;}; int NbMaxiNumeroOrdre() const {return 1;}; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const {sort <<" "<< setw(nbcar)<< setprecision(nbcar) << val << " ";}; @@ -1175,6 +1190,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const {return tab_val.Taille();}; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const ; // ramène le type de grandeur associée de la grandeur de base, car @@ -1260,6 +1276,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const {return ve.Taille();}; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const {int tailp1 = ve.Taille()+1; for (int i=1;i0)) {return v(num);} else {return 0.;}}; + void Change_GrandeurNumOrdre(int num, const double& val) // modification + {if ((num <= v.Taille())&&(num>0)) {v(num)=val;} else {v(num)= 0.;}}; // récup du nom de référence virtual const string* Nom_ref() const {return &nom_ref;}; int NbMaxiNumeroOrdre() const {return v.Taille();}; // récup du nb maxi de numéros d'ordres @@ -1843,9 +1868,14 @@ void operator/= (double val) ; // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 - double GrandeurNumOrdre(int num) const {return 0;}; - // ici c'est le maxi des vecteurs nommés * le nombre - int NbMaxiNumeroOrdre() const {return 0;}; // récup du nb maxi de numéros d'ordres + // **** attention ici la procédure est très laborieuse : pas du tout optimale !!! + double GrandeurNumOrdre(int num) const ; + // idem procédure longue pour le changement + void Change_GrandeurNumOrdre(int num, const double& val); // modification + // récup du nb maxi de numéros d'ordres + // ici c'est la somme des maxi des vecteurs nommés + int NbMaxiNumeroOrdre() const ; + void Grandeur_brut(ostream & sort,int nbcar) const; // ramène le type de grandeur associée de la grandeur de base, car // la grandeur peut être une grandeur complexe comme un tableau ou un liste de grandeur de base @@ -1936,6 +1966,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const ; // ramène le type de grandeur associée de la grandeur de base, car @@ -2015,6 +2046,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const ; + void Change_GrandeurNumOrdre(int num, const double& val); // modification int NbMaxiNumeroOrdre() const; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const; // ramène le type de grandeur associée de la grandeur de base, car @@ -2107,6 +2139,8 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const {if(num==1) return val; else return 0.;}; + void Change_GrandeurNumOrdre(int num, const double& val_) // modification + {if(num==1) val=val_; else val = 0.;}; // récup du nom de référence virtual const string* Nom_ref() const {return &nom_ref;}; int NbMaxiNumeroOrdre() const {return 1;}; // récup du nb maxi de numéros d'ordres @@ -2198,6 +2232,7 @@ // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double GrandeurNumOrdre(int num) const {return 0;}; + void Change_GrandeurNumOrdre(int num, const double& val) {;};// modification, ici on ne fait rien int NbMaxiNumeroOrdre() const {return 0;}; // récup du nb maxi de numéros d'ordres void Grandeur_brut(ostream & sort,int nbcar) const; // ramène le type de grandeur associée de la grandeur de base, car diff --git a/TypeBase/TypeQuelconqueParticulier_2.cc b/TypeBase/TypeQuelconqueParticulier_2.cc index 68d6420..7d12eb2 100644 --- a/TypeBase/TypeQuelconqueParticulier_2.cc +++ b/TypeBase/TypeQuelconqueParticulier_2.cc @@ -178,11 +178,25 @@ double Grandeur_TenseurHB::GrandeurNumOrdre(int n) const return tens(tens.idx_i(n),tens.idx_j(n));break;} default: cout << "\n erreur dimension du tenseur non defini !" - << "\n Grandeur_TenseurHB::NbMaxiNumeroOrdre()"; + << "\n Grandeur_TenseurHB::GrandeurNumOrdre(.."; Sortie(1); }; return 0.; // pour taire le warning }; +// modification +void Grandeur_TenseurHB::Change_GrandeurNumOrdre(int n, const double& val) + { switch (ptTens->Dimension()) + {case 1: (*ptTens).Coor(1,1)=val; break; + case 2: {Tenseur2HB& tens = *((Tenseur2HB*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + case 3: {Tenseur3HB& tens = *((Tenseur3HB*) ptTens); + tens.Coor(tens.idx_i(n),tens.idx_j(n))=val;break;} + default: + cout << "\n erreur dimension du tenseur non defini !" + << "\n Grandeur_TenseurHB::Change_GrandeurNumOrdre(.."; + Sortie(1); + }; + }; // récup du nb maxi de numéros d'ordres int Grandeur_TenseurHB::NbMaxiNumeroOrdre() const { switch (ptTens->Dimension()) @@ -460,6 +474,15 @@ double Tab_Grandeur_TenseurBH::GrandeurNumOrdre(int n) const int r_div = (n-1)%nbpartenseur+1; return tabTens(indice_tableau)->GrandeurNumOrdre(r_div); }; +// modification +void Tab_Grandeur_TenseurBH::Change_GrandeurNumOrdre(int n, const double& val) + { int taille = tabTens.Taille(); + if (taille == 0) return ; // cas d'un tableau vide + int nbpartenseur=tabTens(1)->NbMaxiNumeroOrdre(); + int indice_tableau = (n-1)/nbpartenseur + 1; + int r_div = (n-1)%nbpartenseur+1; + tabTens(indice_tableau)->Change_GrandeurNumOrdre(r_div,val); + }; // récup du nb maxi de numéros d'ordres int Tab_Grandeur_TenseurBH::NbMaxiNumeroOrdre() const { if (tabTens.Taille() == 0) return 0; // cas d'un tableau vide @@ -745,6 +768,15 @@ double Tab_Grandeur_TenseurBB::GrandeurNumOrdre(int n) const int r_div = (n-1)%nbpartenseur+1; return tabTens(indice_tableau)->GrandeurNumOrdre(r_div); }; +// modification +void Tab_Grandeur_TenseurBB::Change_GrandeurNumOrdre(int n, const double& val) + { int taille = tabTens.Taille(); + if (taille == 0) return ; // cas d'un tableau vide + int nbpartenseur=tabTens(1)->NbMaxiNumeroOrdre(); + int indice_tableau = (n-1)/nbpartenseur + 1; + int r_div = (n-1)%nbpartenseur+1; + tabTens(indice_tableau)->Change_GrandeurNumOrdre(r_div,val); + }; // récup du nb maxi de numéros d'ordres int Tab_Grandeur_TenseurBB::NbMaxiNumeroOrdre() const { if (tabTens.Taille() == 0) return 0; // cas d'un tableau vide @@ -1030,6 +1062,15 @@ double Tab_Grandeur_TenseurHB::GrandeurNumOrdre(int n) const int r_div = (n-1)%nbpartenseur+1; return tabTens(indice_tableau)->GrandeurNumOrdre(r_div); }; +// modification +void Tab_Grandeur_TenseurHB::Change_GrandeurNumOrdre(int n, const double& val) + { int taille = tabTens.Taille(); + if (taille == 0) return ; // cas d'un tableau vide + int nbpartenseur=tabTens(1)->NbMaxiNumeroOrdre(); + int indice_tableau = (n-1)/nbpartenseur + 1; + int r_div = (n-1)%nbpartenseur+1; + tabTens(indice_tableau)->Change_GrandeurNumOrdre(r_div,val); + }; // récup du nb maxi de numéros d'ordres int Tab_Grandeur_TenseurHB::NbMaxiNumeroOrdre() const { if (tabTens.Taille() == 0) return 0; // cas d'un tableau vide @@ -1357,6 +1398,12 @@ double Tab_Grandeur_scalaire_entier::GrandeurNumOrdre(int num) const if ((num <=0) || (num > taille)) {return 0.;} else return tab_val(num).val; }; +// modification +void Tab_Grandeur_scalaire_entier::Change_GrandeurNumOrdre(int num, const double& val) + {int taille = tab_val.Taille(); + if ((num <=0) || (num > taille)) {return ;} + else tab_val(num).val = (int) val; + }; void Tab_Grandeur_scalaire_entier::Grandeur_brut(ostream & sort,int nbcar) const {int taille = tab_val.Taille(); @@ -1738,7 +1785,56 @@ void Tab_Grandeur_Vecteur_Nommer::operator/= (double val) *(tabVN(i)) /=val; }; -void Tab_Grandeur_Vecteur_Nommer::Grandeur_brut(ostream & sort,int nbcar) const +// récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre +// si pas possible, ramène 0 +// **** attention ici la procédure est très laborieuse : pas du tout optimale !!! +double Tab_Grandeur_Vecteur_Nommer::GrandeurNumOrdre(int num) const + {// la procédure est longue car on doit balayer tous les vecteurs internes + int nbMaxi= 0; // init + int nbMin = 0; + double retour=0.; + int taille = tabVN.Taille(); + for (int i=1;i<=taille;i++) //(*tabVN(i))/=val; + {nbMaxi += (tabVN(i))->NbMaxiNumeroOrdre(); + if (num <= nbMaxi) + {retour = (tabVN(i))->GrandeurNumOrdre(num-nbMin); + break; + } + else + {nbMin=nbMaxi;}; + }; + return retour; + }; + +// modification +// la procédure est longue car on doit balayer tous les vecteurs internes +void Tab_Grandeur_Vecteur_Nommer::Change_GrandeurNumOrdre(int num, const double& val) + {int nbMaxi= 0; // init + int nbMin = 0; + double retour=0.; + int taille = tabVN.Taille(); + for (int i=1;i<=taille;i++) //(*tabVN(i))/=val; + {nbMaxi += (tabVN(i))->NbMaxiNumeroOrdre(); + if (num <= nbMaxi) + {(tabVN(i))->Change_GrandeurNumOrdre(num-nbMin,val); + break; + } + else + {nbMin=nbMaxi;}; + }; + }; + +// récup du nb maxi de numéros d'ordres +// ici c'est la somme des maxi des vecteurs nommés +int Tab_Grandeur_Vecteur_Nommer::NbMaxiNumeroOrdre() const + { int nbMaxi= 0; // init + int taille = tabVN.Taille(); + for (int i=1;i<=taille;i++) //(*tabVN(i))/=val; + nbMaxi += (tabVN(i))->NbMaxiNumeroOrdre(); + return nbMaxi; + }; + +void Tab_Grandeur_Vecteur_Nommer::Grandeur_brut(ostream & sort,int nbcar) const { int taille = tabVN.Taille(); for (int k=1;k<=taille;k++) tabVN(k)->Grandeur_brut(sort,nbcar); @@ -1916,11 +2012,11 @@ int Grandeur_BaseH::NbMaxiNumeroOrdre() const // récup du nb maxi de numéros d // si pas possible, ramène 0 double Grandeur_BaseH::GrandeurNumOrdre(int num) const {// on va suivre les coordonnées de chaque vecteur - int nb_vec = baseH.NbVecteur(); int dim = baseH.Dimension(); int a = (num-1) / dim ; // le numéro du vecteur int i = num - a * dim; // l'indice de la coordonnée #ifdef MISE_AU_POINT + int nb_vec = baseH.NbVecteur(); int max = nb_vec * dim; if ((num > max) || (num < 1)) { cout << "\n erreur d'acces a la grandeur de numero d'ordre " << num @@ -1931,7 +2027,24 @@ double Grandeur_BaseH::GrandeurNumOrdre(int num) const #endif return baseH(a)(i); }; - +// modification +void Grandeur_BaseH::Change_GrandeurNumOrdre(int num, const double& val) + {// on va suivre les coordonnées de chaque vecteur + int dim = baseH.Dimension(); + int a = (num-1) / dim ; // le numéro du vecteur + int i = num - a * dim; // l'indice de la coordonnée + #ifdef MISE_AU_POINT + int nb_vec = baseH.NbVecteur(); + int max = nb_vec * dim; + if ((num > max) || (num < 1)) + { cout << "\n erreur d'acces a la grandeur de numero d'ordre " << num + << " seules sont accessibles les grandeurs de numeros entre 1 et "<< max + << "\n Grandeur_BaseH::Change_GrandeurNumOrdre(..."; + Sortie(1); + } + #endif + baseH.CoordoH(a)(i) = val; + }; void Grandeur_BaseH::Grandeur_brut(ostream & sort,int nbcar) const { int nb_vec = baseH.NbVecteur(); for (int i=1;i<=nb_vec;i++) @@ -2078,6 +2191,19 @@ double Tab_Grandeur_BaseH::GrandeurNumOrdre(int num) const }; return tabBaseH(i).GrandeurNumOrdre(num-num_dans_tableau); }; +// modification +void Tab_Grandeur_BaseH::Change_GrandeurNumOrdre(int num, const double& val) + { int num_dans_tableau = 0; + int taille_et_1 = tabBaseH.Taille() + 1; + int indic = 0;int i=0; + for (i=1;i num) + break; + }; + tabBaseH(i).Change_GrandeurNumOrdre(num-num_dans_tableau,val); + }; int Tab_Grandeur_BaseH::NbMaxiNumeroOrdre() const // récup du nb maxi de numéros d'ordres { int retour = 0; int taille_et_1 = tabBaseH.Taille() + 1; diff --git a/TypeBase/TypeQuelconqueParticulier_3.cc b/TypeBase/TypeQuelconqueParticulier_3.cc index 65107bc..429da45 100755 --- a/TypeBase/TypeQuelconqueParticulier_3.cc +++ b/TypeBase/TypeQuelconqueParticulier_3.cc @@ -151,6 +151,11 @@ void Grandeur_Vecteur::operator-= (const Grandeur& a) // si pas possible, ramène 0 double Grandeur_Vecteur::GrandeurNumOrdre(int num) const {if((num>0)&&(num<=ve.Taille())) return ve(num); else return 0.;}; +// modification +void Grandeur_Vecteur::Change_GrandeurNumOrdre(int num, const double& val) + {if((num>0)&&(num<=ve.Taille())) ve(num)=val; + // sinon rien + }; // change de repère de la grandeur void Grandeur_Vecteur::Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma ) @@ -403,7 +408,16 @@ double Tab_Grandeur_Vecteur::GrandeurNumOrdre(int n) const int indice_tableau = (n-1)/nbparcoor + 1; int r_div = (n-1)%nbparcoor+1; return tabVe(indice_tableau)->GrandeurNumOrdre(r_div); - }; + }; +// modification +void Tab_Grandeur_Vecteur::Change_GrandeurNumOrdre(int n, const double& val) + { int taille = tabVe.Taille(); + if (taille == 0) return ; // cas d'un tableau vide + int nbparcoor=tabVe(1)->NbMaxiNumeroOrdre(); + int indice_tableau = (n-1)/nbparcoor + 1; + int r_div = (n-1)%nbparcoor+1; + tabVe(indice_tableau)->Change_GrandeurNumOrdre(r_div,val); + }; // récup du nb maxi de numéros d'ordres int Tab_Grandeur_Vecteur::NbMaxiNumeroOrdre() const { if (tabVe.Taille() == 0) return 0; // cas d'un tableau vide diff --git a/comportement/Hypo_elastique/Hypo_hooke1D.cc b/comportement/Hypo_elastique/Hypo_hooke1D.cc index ea163ad..73c1cf6 100755 --- a/comportement/Hypo_elastique/Hypo_hooke1D.cc +++ b/comportement/Hypo_elastique/Hypo_hooke1D.cc @@ -266,14 +266,11 @@ void Hypo_hooke1D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCou // sinon on regarde si le module dépend d'une fonction nD else if(strstr(entreePrinc->tablcar,"Kc_fonction_nD:")!=0) { string nom; - string mot_cle1="Kc="; string mot_cle2="Kc_fonction_nD:"; - // on passe le mot clé générique - bool lec = entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle1); // on lit le nom de la fonction string nom_fonct; - lec = lec && entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); + bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer("**erreur02 en lecture** "+mot_cle2); throw (UtilLecture::ErrNouvelleDonnee(-1)); @@ -305,6 +302,8 @@ void Hypo_hooke1D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCou const Tableau & tab_enu = Kc_nD->Tab_enu_etendu(); if (tab_enu.Contient(TEMP)) thermo_dependant=true; + // prepa du flot de lecture + entreePrinc->NouvelleDonnee(); } // sinon c'est directement le module que l'on lit else @@ -390,14 +389,11 @@ void Hypo_hooke1D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCou // sinon on regarde si la fonction dépend d'une fonction nD else if(strstr(entreePrinc->tablcar,"f_fonction_nD:")!=0) { string nom; - string mot_cle1="f="; string mot_cle2="f_fonction_nD:"; - // on passe le mot clé générique - bool lec = entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle1); // on lit le nom de la fonction string nom_fonct; - lec = lec && entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); + bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer("**erreur02 en lecture** "+mot_cle2); throw (UtilLecture::ErrNouvelleDonnee(-1)); @@ -429,6 +425,8 @@ void Hypo_hooke1D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCou const Tableau & tab_enu = f_nD->Tab_enu_etendu(); if (tab_enu.Contient(TEMP)) thermo_dependant=true; + // prepa du flot de lecture + entreePrinc->NouvelleDonnee(); } else { // lecture de f @@ -898,7 +896,13 @@ void Hypo_hooke1D::Grandeur_particuliere } case DEF_ASSO_LOI: { Tab_Grandeur_TenseurBB& tyTQ= *((Tab_Grandeur_TenseurBB*) (*itq).Grandeur_pointee()); // pour simplifier - tyTQ(1+(*idecal))=save_resul.eps_cumulBB;(*idecal)++; + if (ParaGlob::Dimension() != 1) // il faut alors affecter en le 1D à la bonne dim + {tyTQ(1+(*idecal)).Affectation_trans_dimension(save_resul.eps_cumulBB,true); + } + else // cas même dimension + {tyTQ(1+(*idecal)) = save_resul.eps_cumulBB; + }; + (*idecal)++; break; } default: break; // sinon rien à faire @@ -984,7 +988,8 @@ void Hypo_hooke1D::ListeGrandeurs_particulieres(bool absolue,List_iotablcar,"Kc_fonction_nD:")!=0) { string nom; - string mot_cle1="Kc="; string mot_cle2="Kc_fonction_nD:"; - // on passe le mot clé générique - bool lec = entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle1); // on lit le nom de la fonction string nom_fonct; - lec = lec && entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); + bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer("**erreur02 en lecture** "+mot_cle2); throw (UtilLecture::ErrNouvelleDonnee(-1)); @@ -318,6 +315,8 @@ void Hypo_hooke2D_C::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesC const Tableau & tab_enu = Kc_nD->Tab_enu_etendu(); if (tab_enu.Contient(TEMP)) thermo_dependant=true; + // prepa du flot de lecture + entreePrinc->NouvelleDonnee(); } // sinon c'est directement le module que l'on lit else @@ -406,10 +405,10 @@ void Hypo_hooke2D_C::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesC string mot_cle2="mu_fonction_nD:"; // on passe le mot clé générique - bool lec = entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle1); +// bool lec = entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle1); // on lit le nom de la fonction string nom_fonct; - lec = lec && entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); + bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer("**erreur02 en lecture** "+mot_cle2); throw (UtilLecture::ErrNouvelleDonnee(-1)); @@ -441,6 +440,8 @@ void Hypo_hooke2D_C::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesC const Tableau & tab_enu = mu_nD->Tab_enu_etendu(); if (tab_enu.Contient(TEMP)) thermo_dependant=true; + // prepa du flot de lecture + entreePrinc->NouvelleDonnee(); } else { // sinon lecture de mu @@ -933,7 +934,13 @@ void Hypo_hooke2D_C::Grandeur_particuliere }; case DEF_ASSO_LOI: { Tab_Grandeur_TenseurBB& tyTQ= *((Tab_Grandeur_TenseurBB*) (*itq).Grandeur_pointee()); // pour simplifier - tyTQ(1+(*idecal))=save_resul.eps_cumulBB;(*idecal)++; + if (ParaGlob::Dimension() == 3) // il faut alors affecter en le 2D au 3D + {tyTQ(1+(*idecal)).Affectation_trans_dimension(save_resul.eps_cumulBB,true); + } + else // cas même dimension + {tyTQ(1+(*idecal)) = save_resul.eps_cumulBB; + }; + (*idecal)++; break; } @@ -945,7 +952,7 @@ void Hypo_hooke2D_C::Grandeur_particuliere // récupération et création de la liste de tous les grandeurs particulières // ces grandeurs sont ajoutées à la liste passées en paramètres -void Hypo_hooke2D_C::ListeGrandeurs_particulieres(List_io& liTQ) const +void Hypo_hooke2D_C::ListeGrandeurs_particulieres(bool absolue,List_io& liTQ) const { //on commence par définir une grandeur_scalaire_double Tableau tab_1(1); Tab_Grandeur_scalaire_double grand_courant(tab_1); @@ -1002,7 +1009,8 @@ void Hypo_hooke2D_C::ListeGrandeurs_particulieres(List_io& liTQ) tyTQ.Change_taille(taille); nexistePas = false; }; if (nexistePas) - {TenseurBB* tens = NevezTenseurBB(2); // un tenseur typique + {int dim_espace = ParaGlob::Dimension(); + TenseurBB* tens = NevezTenseurBB(dim_espace); // un tenseur typique Tab_Grandeur_TenseurBB epsassoBB(*tens,1); // def d'un type quelconque représentatif TypeQuelconque typQ(DEF_ASSO_LOI,EPS11,epsassoBB); diff --git a/comportement/Hypo_elastique/Hypo_hooke2D_C.h b/comportement/Hypo_elastique/Hypo_hooke2D_C.h index f4b79d0..d472ee1 100644 --- a/comportement/Hypo_elastique/Hypo_hooke2D_C.h +++ b/comportement/Hypo_elastique/Hypo_hooke2D_C.h @@ -189,7 +189,7 @@ class Hypo_hooke2D_C : public Loi_comp_abstraite (bool absolue,List_io& ,Loi_comp_abstraite::SaveResul * ,list& decal) const; // récupération de la liste de tous les grandeurs particulières // ces grandeurs sont ajoutées à la liste passées en paramètres - void ListeGrandeurs_particulieres(List_io& ) const; + void ListeGrandeurs_particulieres(bool absolue,List_io& ) const; // calcul d'un module d'young équivalent à la loi, ceci pour un // chargement nul diff --git a/comportement/Hypo_elastique/Hypo_hooke3D.cc b/comportement/Hypo_elastique/Hypo_hooke3D.cc index ecab855..6087ff2 100644 --- a/comportement/Hypo_elastique/Hypo_hooke3D.cc +++ b/comportement/Hypo_elastique/Hypo_hooke3D.cc @@ -248,14 +248,11 @@ void Hypo_hooke3D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCou // sinon on regarde si le module dépend d'une fonction nD else if(strstr(entreePrinc->tablcar,"Kc_fonction_nD:")!=0) { string nom; - string mot_cle1="Kc="; string mot_cle2="Kc_fonction_nD:"; - // on passe le mot clé générique - bool lec = entreePrinc->Lecture_et_verif_mot_cle(nom_class_methode,mot_cle1); // on lit le nom de la fonction string nom_fonct; - lec = lec && entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); + bool lec = entreePrinc->Lecture_mot_cle_et_string(nom_class_methode,mot_cle2,nom_fonct); if (!lec ) { entreePrinc->MessageBuffer("**erreur02 en lecture** "+mot_cle2); throw (UtilLecture::ErrNouvelleDonnee(-1)); @@ -287,6 +284,8 @@ void Hypo_hooke3D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCou const Tableau & tab_enu = Kc_nD->Tab_enu_etendu(); if (tab_enu.Contient(TEMP)) thermo_dependant=true; + // prepa du flot de lecture + entreePrinc->NouvelleDonnee(); } // sinon c'est directement le module que l'on lit else @@ -371,7 +370,6 @@ void Hypo_hooke3D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCou // sinon on regarde si mu dépend d'une fonction nD else if(strstr(entreePrinc->tablcar,"mu_fonction_nD:")!=0) { string nom; - string mot_cle1="mu="; string mot_cle2="mu_fonction_nD:"; // on lit le nom de la fonction @@ -408,6 +406,8 @@ void Hypo_hooke3D::LectureDonneesParticulieres (UtilLecture * entreePrinc,LesCou const Tableau & tab_enu = mu_nD->Tab_enu_etendu(); if (tab_enu.Contient(TEMP)) thermo_dependant=true; + // prepa du flot de lecture + if(strstr(entreePrinc->tablcar,"fin_loi_HYPO_ELAS3D")==0) entreePrinc->NouvelleDonnee(); } else { // sinon lecture de mu diff --git a/comportement/anisotropie/Hypo_ortho3D_entrainee.cc b/comportement/anisotropie/Hypo_ortho3D_entrainee.cc index 6553a65..1d4d380 100755 --- a/comportement/anisotropie/Hypo_ortho3D_entrainee.cc +++ b/comportement/anisotropie/Hypo_ortho3D_entrainee.cc @@ -1288,7 +1288,7 @@ double Hypo_ortho3D_entrainee::Module_compressibilite_equivalent(Enum_dure temps {double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1; double unsurKs2 = -nu12/E1+1./E2-nu23/E2; double unsurKs3 = -nu13/E1-nu23/E2+1./E3; - double module_compressibilite = 1./3.*(1./unsurKs1+1./unsurKs2+1./unsurKs3); + double module_compressibilite = 1./9.*(1./unsurKs1+1./unsurKs2+1./unsurKs3); return module_compressibilite; } else @@ -1635,7 +1635,7 @@ void Hypo_ortho3D_entrainee::Calcul_SigmaHH (TenseurHH& sigHH_t,TenseurBB& ,DdlE {double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1; double unsurKs2 = -nu12/E1+1./E2-nu23/E2; double unsurKs3 = -nu13/E1-nu23/E2+1./E3; - module_compressibilite = untiers*(1./unsurKs1+1./unsurKs2+1./unsurKs3); + module_compressibilite = untiers*untiers*(1./unsurKs1+1./unsurKs2+1./unsurKs3); }; } else @@ -2021,7 +2021,7 @@ void Hypo_ortho3D_entrainee::Calcul_DsigmaHH_tdt (TenseurHH& sigHH_t,TenseurBB& {double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1; double unsurKs2 = -nu12/E1+1./E2-nu23/E2; double unsurKs3 = -nu13/E1-nu23/E2+1./E3; - module_compressibilite = untiers*(1./unsurKs1+1./unsurKs2+1./unsurKs3); + module_compressibilite = untiers *untiers*(1./unsurKs1+1./unsurKs2+1./unsurKs3); }; } else @@ -2676,7 +2676,7 @@ void Hypo_ortho3D_entrainee::Calcul_dsigma_deps (bool en_base_orthonormee, Tense {double unsurKs1 = 1./E1 - nu12/E1 -nu13/E1; double unsurKs2 = -nu12/E1+1./E2-nu23/E2; double unsurKs3 = -nu13/E1-nu23/E2+1./E3; - module_compressibilite = untiers*(1./unsurKs1+1./unsurKs2+1./unsurKs3); + module_compressibilite = untiers * untiers*(1./unsurKs1+1./unsurKs2+1./unsurKs3); }; #ifdef MISE_AU_POINT if (Permet_affichage() > 4) diff --git a/contact/ElContact.cc b/contact/ElContact.cc index fd59ddc..a5af13e 100644 --- a/contact/ElContact.cc +++ b/contact/ElContact.cc @@ -1794,6 +1794,11 @@ int ElContact::Actualisation() }; #endif + if (Permet_affichage() > 4) + {cout << "\n -- ElContact::Actualisation "; + this->Affiche(1); + }; + int intersec = 0; // init: pour l'instant pas d'intersection int passage_par_angle_mort=0; // pour le passage d'angle mort à normal Coordonnee M1; @@ -1822,19 +1827,30 @@ int ElContact::Actualisation() // c'est plus long qu'un test de surface mais il n'y a pas vraiment d'autre solution int cas = elfront->PtEI()->Interne_tdt(noeud->Coord2()); if (Permet_affichage() > 5) - {cout << "\n -- ElContact::Actualisation: "; - cout << " Interne_tdt ? cas= " << cas <<", "; - this->Affiche(1); + {cout << " Frontiere: FrontPointF -> test Interne_tdt ? cas= " << cas; + // retour : =0 le point est externe, =1 le point est interne , + // = 2 le point est sur la frontière à la précision près + switch (cas) + {case 0 : cout << " (le point est externe a l'element) "; break; + case 1 : cout << " (le point est interne a l'element) "; break; + case 2 : cout << " (le point est sur la frontiere a la prec pres) "; break; + default: + cout << "\n **** erreur le retour cas = "<< cas + << " de la methode elfront->PtEI()->Interne_tdt(... " + << " n'est pas normal on ne peut pas continuer ! "; + Sortie(1); + break; + }; }; - // pour éviter les flip flop, si on a eu trop de changement de frontière // on valide de manière arbitraire le choix actuel if (nb_change_frontiere > nb_change_frontiere_max) {cas = 1; if (Permet_affichage() > 5) - {cout << "\n -- nb_change_frontiere: " << nb_change_frontiere - << " on impose cas = 1 " ; + {cout << "\n >> nb_change_frontiere: " << nb_change_frontiere + << " > nb_change_frontiere_max ("<Taille(); for (int i=1; i < ta_taille_et1; i++) - { cas = (*ta)(i)->PtEI()->Interne_tdt(noeud->Coord2()); + { + if (Permet_affichage() > 5) + cout << "\n >> test de l'element voisin "<PtEI()->Interne_tdt(noeud->Coord2()); if (Permet_affichage() > 5) - {cout << "\n -- ElContact::Actualisation: "; - cout << " Interne_tdt sur mitoyen d'angel mort ? cas= " << cas <<", "; - this->Affiche(1); + {cout << " Interne_tdt sur mitoyen d'angle mort ? cas= " << cas ; + switch (cas) + {case 0 : cout << " (le point est externe a l'element) "; break; + case 1 : cout << " (le point est interne a l'element) "; break; + case 2 : cout << " (le point est sur la frontiere a la prec pres) "; break; + default: + cout << "\n **** erreur le retour cas = "<< cas + << " de la methode elfront->PtEI()->Interne_tdt(... " + << " n'est pas normal on ne peut pas continuer ! "; + Sortie(1); + break; + }; }; if (cas) // on a trouvé un élément mitoyen qui contient le point {// --- changement d'element frontiere if (Permet_affichage() > 2) - {cout << "\n change front. du noeud "<< noeud->Num_noeud() <<" mail= " << noeud->Num_Mail() + {cout << "\n >> change front. du noeud "<< noeud->Num_noeud() <<" mail= " << noeud->Num_Mail() << " ==> "; elfront->Affiche(1); if (Permet_affichage() > 4) @@ -1876,8 +1904,8 @@ int ElContact::Actualisation() intersec = 2; passage_par_angle_mort=2; }; - if (intersec) - break; + if (intersec == 2) + break; }; }; } @@ -1933,6 +1961,8 @@ int ElContact::Actualisation() if (ta != NULL) // cas où il y a des éléments voisins ! {for (int i=1; i<= ta->Taille(); i++) { bool mitoyen_valider = false; + if (Permet_affichage() > 5) + cout << "\n >> test de l'element voisin "<Angle_mort()) { ElFrontiere & elfroto = *((*ta)(i)->Eleme()); // pour commodite @@ -1947,9 +1977,18 @@ int ElContact::Actualisation() // c'est plus long qu'un test de surface mais il n'y a pas vraiment d'autre solution int cas = (*ta)(i)->PtEI()->Interne_tdt(noeud->Coord2()); if (Permet_affichage() > 5) - {cout << "\n -- ElContact::Actualisation: "; - cout << " Interne_tdt sur mitoyen ? cas= " << cas <<", "; - this->Affiche(1); + {cout << " Interne_tdt sur mitoyen d'angle mort ? cas= " << cas ; + switch (cas) + {case 0 : cout << " (le point est externe a l'element) "; break; + case 1 : cout << " (le point est interne a l'element) "; break; + case 2 : cout << " (le point est sur la frontiere a la prec pres) "; break; + default: + cout << "\n **** erreur le retour cas = "<< cas + << " de la methode elfront->PtEI()->Interne_tdt(... " + << " n'est pas normal on ne peut pas continuer ! "; + Sortie(1); + break; + }; }; if (cas) // si true, le point est interne @@ -1978,7 +2017,10 @@ int ElContact::Actualisation() || (nb_change_frontiere > nb_change_frontiere_max) // pour éviter les flip-flop ) // on a trouve une bonne intersection - { mitoyen_valider = true;M1 = M1_new;}; + { mitoyen_valider = true;M1 = M1_new; + if (Permet_affichage() > 5) + cout << " intersection ok "; + }; }; }; @@ -1986,7 +2028,7 @@ int ElContact::Actualisation() if (mitoyen_valider) { // --- changement d'element frontiere if (Permet_affichage() > 2) - {cout << "\n change front. du noeud "<< noeud->Num_noeud() <<" mail= " << noeud->Num_Mail() + {cout << "\n change front. du noeud "<< noeud->Num_noeud() <<" mail= " << noeud->Num_Mail() << " == "; elfront->Affiche(1); if (Permet_affichage() > 4) @@ -2012,7 +2054,7 @@ int ElContact::Actualisation() }; }; }; - }; + }; }; }; // fin du test sur les front d'angle mort @@ -2032,7 +2074,7 @@ int ElContact::Actualisation() break; }; if (Permet_affichage() > 6) - {cout << "\n actualisation du noeud esclave " + {cout << "\n actualisation du noeud esclave " << noeud->Num_noeud() <<" mail= " << noeud->Num_Mail() << " ancienne position " << M_noeud_tdt_avant_projection << " nouvelle position " << noeud->Coord2(); @@ -2046,8 +2088,13 @@ int ElContact::Actualisation() } #ifdef MISE_AU_POINT - if (Permet_affichage() > 2) - {cout << "\n ElContact::Actualisation(., intersec= "<< intersec; + if (Permet_affichage() > 4) + {cout << ": noeud "<< noeud->Num_noeud() <<" mail= " << noeud->Num_Mail() + << ", intersec= "<< intersec; + if (intersec == 0) {cout << " (pas d'intersection trouvé)";} + else if (intersec == 1) {cout << " (contact ok sur l'élément)";} + else if (intersec == -1){cout << " (contact ok mais hors de l'élément)";} + else if (intersec == 2){cout << " (changement de frontière, et contact ok sur la nouvelle frontière)";}; }; #endif @@ -2173,7 +2220,7 @@ void ElContact::Change_force(const Coordonnee& force) // calcul de la normale en fonction de differente conditions Coordonnee N( Calcul_Normale(dim,pl,dr,indic)); - F_N_max = Dabs(force_contact*N); // sauvegarde + F_N_max = (force_contact*N); // sauvegarde F_T_max = sqrt(force_contact.Norme()-F_N_max*F_N_max); diff --git a/contact/ElContact.h b/contact/ElContact.h index a6879a2..3fa102f 100644 --- a/contact/ElContact.h +++ b/contact/ElContact.h @@ -326,13 +326,13 @@ class ElContact void Met_Inactif() { actif = 0;nb_decol_tdt=0; #ifdef MISE_AU_POINT if (Permet_affichage() > 2) - {cout << "\n inactivation du contact: ";this->Affiche(1);}; + {cout << "\n -- ElContact::Met_Inactif() -> inactivation du contact: ";this->Affiche(1);}; #endif }; // met en inactif void Met_actif() { actif++;nb_decol_tdt=0; #ifdef MISE_AU_POINT if (Permet_affichage() > 2) - {cout << "\n activation du contact: ";this->Affiche(1);}; + {cout << "\n -- ElContact::Met_actif() -> activation du contact: ";this->Affiche(1);}; #endif }; // met en actif une fois de plus diff --git a/contact/ElContact_2.cc b/contact/ElContact_2.cc index 16d7549..5e64b3a 100755 --- a/contact/ElContact_2.cc +++ b/contact/ElContact_2.cc @@ -245,7 +245,7 @@ Vecteur* ElContact::SM_charge_contact() } default: break; // déjà vu au dessus }; - F_N_max = Dabs(intens_force); // sauvegarde + F_N_max = (intens_force); // sauvegarde if (Permet_affichage() > 5) {cout << " noeud: " << noeud->Num_noeud(); cout << "\n deltaX " << deltaX @@ -787,7 +787,7 @@ Element::ResRaid ElContact::SM_K_charge_contact() } default: break; // déjà vu au dessus }; - F_N_max = Dabs(intens_force); // sauvegarde + F_N_max = (intens_force); // sauvegarde if (Permet_affichage() > 5) {cout << " noeud: " << noeud->Num_noeud(); @@ -831,7 +831,7 @@ Element::ResRaid ElContact::SM_K_charge_contact() int nb_n_facette = tabForce_cont.Taille(); for (int i=1; i<= nb_n_facette; i++) tabForce_cont(i).Zero(); if (Permet_affichage() > 6) - { cout << " noeud: " << noeud->Num_noeud() + { cout << "\n noeud: " << noeud->Num_noeud() << ": force collage non prise en compte " << force_contact << " gap(positif)= " << gap << ", Normale= " << N; cout << "\n deltaX " << deltaX @@ -851,7 +851,7 @@ Element::ResRaid ElContact::SM_K_charge_contact() int nb_n_facette = tabForce_cont.Taille(); for (int i=1; i<= nb_n_facette; i++) tabForce_cont(i).Zero(); if (Permet_affichage() >= 6) - { cout << " noeud: " << noeud->Num_noeud() + { cout << "\n noeud: " << noeud->Num_noeud() << ": force collage non prise en compte " << force_contact << " gap(positif et > borne regularisation)= " << gap << ", Normale= " << N; cout << "\n deltaX " << deltaX diff --git a/contact/LesContacts.cc b/contact/LesContacts.cc index 74a4df4..e82eb47 100644 --- a/contact/LesContacts.cc +++ b/contact/LesContacts.cc @@ -40,6 +40,10 @@ // --------------- variables statiques --------- MotCle LesContacts::motCle; // liste des mots clés + Tableau LesContacts::tqi_const_fct_nD_niveau_commentaire; + Tableau < TypeQuelconque * > LesContacts::tqi_fct_nD_niveau_commentaire; + Tableau LesContacts::t_num_ordre_fct_nD_niveau_commentaire; + //------------------------- la classe ReactCont ------------- // surcharge de l'operator de lecture @@ -168,6 +172,10 @@ void LesContacts::Init_contact(LesMaillages& lesMail ,LesFonctions_nD* lesFonctionsnD) { tempsContact.Mise_en_route_du_comptage(); // temps cpu + // sauvegarde de la liste des fonctions nD + sauve_lesFonctionsnD = lesFonctionsnD; + // init éventuel du pilotage par fct nD du niveau de commentaire + LesContacts::Init_fct_niveau_commentaire(); int niveau_commentaire_lescontacts = Permet_affichage(); // on met à jour le niveau de commentaire dans les éléments de contact ElContact::Mise_a_jour_niveau_commentaire(); @@ -180,8 +188,6 @@ void LesContacts::Init_contact(LesMaillages& lesMail #endif cout << "\n -- LesContacts::Init_contact: "; - // sauvegarde de la liste des fonctions nD - sauve_lesFonctionsnD = lesFonctionsnD; Creation_Fct_nD_contact(); // récupération des fonctions de pilotage éventuelles // --- récup info maillage @@ -683,9 +689,9 @@ bool LesContacts::DefElemCont(double dep_max) { #ifdef UTILISATION_MPI cout << "\n proc " << proc_en_cours - << " ==> LesContacts::Def Elem Cont, initialement "< LesContacts::Def Elem Cont, initialement "< li_pour_noeuds; // pour une sortie spécifique noeud + Grandeur_scalaire_entier grand_courant_entier(0); // par défaut pour la création des conteneurs quelconques + li_pour_noeuds.push_front(TypeQuelconque(NUM_NOEUD,X1,grand_courant_entier)); + Grandeur_scalaire_entier& gr_pour_noeud + = *((Grandeur_scalaire_entier*) (*li_pour_noeuds.begin()).Grandeur_pointee()); + list li_pour_elcont; // pour une sortie spécifique élément finis + li_pour_elcont.push_front(TypeQuelconque(NUM_ELEMENT,EPS11,grand_courant_entier)); + #ifdef UTILISATION_MPI int proc_en_cours = ParaGlob::Monde()->rank(); #endif @@ -1002,28 +1016,31 @@ bool LesContacts::Nouveau(double dep_max) #else cout << "\n" #endif - << " ==> LesContacts::Nouveau: temps= " << ParaGlob::Variables_de_temps().TempsCourant(); + << " -- LesContacts::Nouveau: temps= " << ParaGlob::Variables_de_temps().TempsCourant(); // on montre les noeuds actuellement en contact - if (niveau_commentaire_lescontacts > 5) + if (Permet_affichage() > 4) { #ifdef UTILISATION_MPI cout << "\n proc " << proc_en_cours #else cout << "\n" #endif - << " >> bilan des noeud(s) actuellement en contact: "; + << " >> bilan des noeud(s) actuellement en contact: "; + int nb_noe_en_contact = 0; for (int intot = 1;intot<= nb_mail_Esclave;intot++) // boucle sur les maillages esclaves for (int j=1;j<= nb_zone;j++) {const Tableau & tesc= tesctotal(intot)(j); // pout simplifier la notation const Tableau tesN_col = tesN_collant(intot)(j); // pour simplifier int tesc_taille=tesc.Taille(); for (int inesc = 1;inesc<= tesc_taille;inesc++) // boucle sur les noeuds esclaves - {if (niveau_commentaire_lescontacts > 4) - { Noeud* no = tesc(inesc); -// int n_noee = no->Num_noeud(); + {Noeud* no = tesc(inesc); + int n_noee = no->Num_noeud(); + (*gr_pour_noeud.ConteneurEntier()) = n_noee; // pour l'affichage + if (Permet_affichage(&li_pour_noeuds) > 5) + { int num_mail_noe_esclave = no->Num_Mail(); // if (no->Num_noeud()==495) - cout << "\n noeud " << no->Num_noeud() << " du maillage " << no->Num_Mail(); + cout << "\n noeud " << no->Num_noeud() << " du maillage " << no->Num_Mail(); cout << " coord2= "; no->Coord2().Affiche_1(cout); // #ifdef MISE_AU_POINT // if (tesN_encontact(num_mail_noe_esclave).find(no) @@ -1043,14 +1060,22 @@ bool LesContacts::Nouveau(double dep_max) if (tesN_encontact_ii.find(no) != tesN_encontact_ii.end()) {//LaLIST < LaLIST::iterator > & list_tesN = tesN_encontact_ii[no]; // LaLIST < LaLIST::iterator >::iterator pl,plfin=list_tesN.end(); - cout << "\n --> noeud actuellement en contact "; + cout << "\n --> noeud actuellement en contact "; + nb_noe_en_contact++; if (tesN_collant(num_mail_noe_esclave)(j)(inesc)) cout << " collant "; } - else {cout << "\n --> noeud actuellement pas en contact ";}; + else {cout << "\n --> noeud actuellement pas en contact ";}; cout << flush; }; }; }; + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " ->> bilan : " << nb_noe_en_contact << " noeud(s) actuellement en contact: "; + }; if (niveau_commentaire_lescontacts > 4) // on va lister les éléments de contact @@ -1060,10 +1085,17 @@ bool LesContacts::Nouveau(double dep_max) #else cout << "\n" #endif - << " liste des Elcontact au debut de LesContacts::Nouveau: (fct du niveau de commentaire des elcontact): "; + << " >> liste des Elcontact au debut de LesContacts::Nouveau: (fct du niveau de commentaire des elcontact): "; LaLIST::iterator ipp,ippfin=listContact.end(); for (ipp=listContact.begin();ipp != ippfin; ipp++) {(*ipp).Affiche(2);}; + cout << " fin liste "; + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " ->> bilan : " << listContact.size() << " element(s) de contact: "; }; // on met à jour les boites des éléments qui contiennent les frontières @@ -1092,8 +1124,9 @@ bool LesContacts::Nouveau(double dep_max) if ((*iE).Contact()) { // on valide si le contact est ok (*iE).Met_actif(); - if (niveau_commentaire_lescontacts > 3) - { cout << "\nreactivation (dans newcontact) contact: "; + (*gr_pour_noeud.ConteneurEntier()) = (*iE).Esclave()->Num_noeud(); + if (Permet_affichage(&li_pour_noeuds) > 3) + { cout << "\n reactivation (dans LesContacts::Nouveau) contact: "; (*iiE).Affiche(1); cout << endl; }; } @@ -1103,8 +1136,9 @@ bool LesContacts::Nouveau(double dep_max) Noeud* noe_esclave = (*iiE).Esclave(); int num_mail_esclave = noe_esclave->Num_Mail(); int num_noeud = noe_esclave->Num_noeud(); - if (niveau_commentaire_lescontacts > 3) - { cout << "\neffacement contact (dans newcontact): "; + (*gr_pour_noeud.ConteneurEntier()) = num_noeud; + if (Permet_affichage(&li_pour_noeuds) > 3) + { cout << "\n effacement contact (dans LesContacts::Nouveau): "; (*iiE).Affiche(1);cout << endl; }; listContact_efface_tatdt.push_front(*iiE); // mémorise @@ -1134,13 +1168,14 @@ bool LesContacts::Nouveau(double dep_max) LaLIST_io ::iterator iM,iMfin; LaLIST ::iterator icont_inter; // sert pour la recherche de doublon list ::iterator inumtesN; // " " " + // tout d'abord on met à jour les boites d'encombrement des éléments frontière for (int jjf=1;jjf<=nbmailMaitre;jjf++) for (int j=1;j<= nb_zone;j++) { iMfin=(t_listFront(jjf)(j)).end(); - // tout d'abord on met à jour les boites d'encombrement des éléments frontière for (iM = (t_listFront(jjf)(j)).begin() ; iM != iMfin; iM++) (*iM).Boite_encombrement_frontiere(TEMPS_tdt,dep_max); - }; + }; + // parcours des noeuds esclaves for (int intot = 1;intot<= nb_mail_Esclave;intot++) // boucle sur les maillages esclaves {for (int j_zone=1;j_zone<= nb_zone;j_zone++) {const Tableau & tesc= tesctotal(intot)(j_zone); // pout simplifier la notation @@ -1174,18 +1209,20 @@ bool LesContacts::Nouveau(double dep_max) {LaLIST < LaLIST::iterator > & list_tesN = tesN_encontact_ii[no]; nb_contact = list_tesN.size(); }; - if (niveau_commentaire_lescontacts > 5) + + (*gr_pour_noeud.ConteneurEntier()) = n_noee; + if (Permet_affichage(&li_pour_noeuds) > 6) { #ifdef UTILISATION_MPI - cout << "\n proc " << proc_en_cours + cout << "\n proc " << proc_en_cours #else - cout << "\n" + cout << "\n " #endif << " (re) examen eventuel : contact du noeud " << n_noee << " du maillage " << num_mail_noe_esclave; cout << " coord2= "; no->Coord2().Affiche_1(cout); - if (niveau_commentaire_lescontacts > 5) + if (Permet_affichage(&li_pour_noeuds) > 7) {cout << " num_mail_dans_contact = " << num_mail_noe_esclave <<" inesc(num N local)= " << inesc - << "\n tesN_encontact= " << nb_contact + << "\n tesN_encontact= " << nb_contact << " contacts enregistres"; }; // on dit si un des contacts est actif @@ -1197,15 +1234,15 @@ bool LesContacts::Nouveau(double dep_max) if ( (*(*il)).Actif() ) actif++; if (actif) - {cout << "\n noeud actuellement en contact dans " << actif << " element(s) "; + {cout << "\n noeud actuellement en contact dans " << actif << " element(s) "; if (tesN_collant(num_mail_noe_esclave)(j_zone)(inesc)) cout << " collant "; } - else cout << "\n noeud actuellement pas en contact "; + else cout << "\n noeud actuellement pas en contact "; int icont = 1; for (il = list_tesN.begin();il != ilfin; il++,icont++) {Front* elfront = (*(*il)).Elfront(); Element * elem = elfront->PtEI(); // l'element qui contiend la frontiere - cout << "\n elem_contact: "<Num_frontiere() + cout << "\n elem_contact: "<Num_frontiere() << " de l'element " << elem->Geometrie() << " : " << elfront->PtEI()->Num_elt() << ", type: " << Nom_type_geom(elfront->Eleme_const()->Type_geom_front()) << " du maillage :" << elfront->PtEI()->Num_maillage(); @@ -1238,8 +1275,8 @@ bool LesContacts::Nouveau(double dep_max) Front* eltest = elc.Elfront(); if (eltest->MemeOrigine(elfront) ) {a_considerer=false; - if (elc.Permet_affichage() > 5) - {cout << "\n noeud esclave deja en contact "; elc.Affiche(1); + if (elc.Permet_affichage() > 6) + {cout << "\n noeud esclave deja en contact "; elc.Affiche(1); }; break;} }; @@ -1259,7 +1296,9 @@ bool LesContacts::Nouveau(double dep_max) // qui contient l'élément frontière (car l'élément frontière à une épaisseur nulle!) Element & elem = *((*iM).PtEI()); // l'element qui contiend la frontiere Front& elfront = (*iM); - if (niveau_commentaire_lescontacts > 5) + + (*gr_pour_noeud.ConteneurEntier()) = no->Num_noeud(); + if (Permet_affichage(&li_pour_noeuds) > 7) {// --- sortie d'info pour vérifier l'appartenance à la boite ou non #ifdef UTILISATION_MPI cout << "\n proc " << proc_en_cours @@ -1283,14 +1322,14 @@ bool LesContacts::Nouveau(double dep_max) break; // on arrête la boucle si on trouve l'élément parmi ceux contenant le noeud }; - if (niveau_commentaire_lescontacts > 5) + if (Permet_affichage(&li_pour_noeuds) > 6) { #ifdef UTILISATION_MPI - cout << "\n proc " << proc_en_cours + cout << "\n proc " << proc_en_cours #else - cout << "\n" + cout << "\n " #endif - << "\n frontiere: " << elfront.Num_frontiere() << " (nb loc: "<Type_geom_front()) << " de l'element " << elem.Geometrie() << " : " << elfront.PtEI()->Num_elt() @@ -1318,21 +1357,23 @@ bool LesContacts::Nouveau(double dep_max) // break;}; // }; */ - if (niveau_commentaire_lescontacts > 5) - {//cout << "\n 2debug LesContacts::Nouveau( " ; + (*gr_pour_noeud.ConteneurEntier()) = n_noee; + if (Permet_affichage(&li_pour_noeuds) > 7) + {cout << "\n liste des contacts sur le noeud " << n_noee + << " qui est prevu en effacement sur l'increment " ; LaLIST ::iterator ila,ilafin=listContact_efface_tatdt.end(); for (ila = listContact_efface_tatdt.begin();ila != ilafin;ila++) - { cout << "\n " << n_noee << " " << (*ila).Esclave()->Num_noeud() + { cout << "\n " << n_noee << " " << (*ila).Esclave()->Num_noeud() << " " ; (*ila).Elfront()->Affiche(); (*iM).Affiche(); - cout << "\n ((*ila).Esclave()->Num_noeud() == noee->Num_noeud()) " + cout << "\n ((*ila).Esclave()->Num_noeud() == noee->Num_noeud()) " << ((*ila).Esclave()->Num_noeud() == n_noee); - cout << "\n ((*((*ila).Elfront()->Eleme())) == (*((*iM)->Eleme()))) " + cout << "\n ((*((*ila).Elfront()->Eleme())) == (*((*iM)->Eleme()))) " << ((*((*ila).Elfront()->Eleme())) == (*((*iM).Eleme()))); - cout << "\n ((*ila).Esclave()->Num_Mail() == noee->Num_Mail()) " + cout << "\n ((*ila).Esclave()->Num_Mail() == noee->Num_Mail()) " << ((*ila).Esclave()->Num_Mail() == n_noee); - cout << "\n vraiment_nouveau_element= " << vraiment_nouveau_element << endl; + cout << "\n vraiment_nouveau_element= " << vraiment_nouveau_element << endl; }; }; // on ne continue que si c'est un vrai nouvel élément @@ -1351,9 +1392,9 @@ bool LesContacts::Nouveau(double dep_max) if (con.Permet_affichage() > 5) { #ifdef UTILISATION_MPI - cout << "\n proc " << proc_en_cours + cout << "\n proc " << proc_en_cours #else - cout << "\n" + cout << "\n " #endif << " frontiere en contact deja existante , on arrete la creation "; elfront.Affiche(1); @@ -1372,15 +1413,15 @@ bool LesContacts::Nouveau(double dep_max) || (elcont.Permet_affichage() > 5)) { Front* elfront = elcont.Elfront(); #ifdef UTILISATION_MPI - cout << "\n proc " << proc_en_cours + cout << "\n proc " << proc_en_cours #else - cout << "\n" + cout << "\n " #endif - << " examen plus precis: frontiere: " << elfront->Num_frontiere() + << " test nouveau contact: examen plus precis: frontiere: " << elfront->Num_frontiere() << ", type: " << Nom_type_geom(elfront->Eleme_const()->Type_geom_front()) << " de l'element " << elfront->PtEI()->Num_elt() << " du maillage " << elfront->PtEI()->Num_maillage() ; - if (niveau_commentaire_lescontacts > 7) + if (Permet_affichage(&li_pour_noeuds) > 7) elcont.Affiche(); }; @@ -1388,8 +1429,7 @@ bool LesContacts::Nouveau(double dep_max) // si le contact existe, ceci en fonction de la méthode de contact bool ret = elcont.Contact(); if (elcont.Permet_affichage() > 5) - {cout << "\n retour de Contact: ret= " << ret; - + {cout << "\n retour de Contact: ret= " << ret; } if (ret) {//sauvegarde éventuelle de l'element contact @@ -1405,14 +1445,14 @@ bool LesContacts::Nouveau(double dep_max) || (elcont.Permet_affichage() > 3)) { #ifdef UTILISATION_MPI - cout << "\n proc " << proc_en_cours + cout << "\n proc " << proc_en_cours #else - cout << "\n" + cout << "\n " #endif - << "\n newcontact: " ; + << " newcontact: " ; if (tesN_col(inesc)) cout << " collant "; elcont.Affiche(1); - }; + }; } else if (!test_existance->Actif()) // s'il existe et est inactif on le rend actif (pour remplacer celui qui devrait être créé) @@ -1426,13 +1466,13 @@ bool LesContacts::Nouveau(double dep_max) else { if ((niveau_commentaire_lescontacts > 5) || (elcont.Permet_affichage() > 5)) - cout << " --> contact deja enregistre " ; + cout << " --> contact deja enregistre " ; } ; } else { if ((niveau_commentaire_lescontacts > 5) || (elcont.Permet_affichage() > 5)) - cout << " --> pas de contact " ; + cout << " --> pas de contact " ; } ; // listContact.push_back(elcont);numtesN.push_back(DeuxEntiers(intot,inesc)); @@ -1463,37 +1503,41 @@ bool LesContacts::Nouveau(double dep_max) if (niveau_commentaire_lescontacts > 3) { #ifdef UTILISATION_MPI - cout << "\n proc " << proc_en_cours + cout << "\n proc " << proc_en_cours #else - cout << "\n" + cout << "\n " #endif - << " bilan: "<< listContact.size() << " elem contact "; + << " en fin de au debut de LesContacts::Nouveau: bilan: "<< listContact.size() << " elem(s) contact "; if ( listContact_nouveau_tatdt.size()) cout <<", "<< (listContact_nouveau_tatdt.size()-taille_list_contact_nouveau_au_debut) << " nouveau(x) "; if (listContact_efface_tatdt.size()) cout <<", "< 4) + // on va lister les éléments de contact + { #ifdef UTILISATION_MPI cout << "\n proc " << proc_en_cours #else cout << "\n" + #endif + << " liste des Elcontact a la fin de LesContacts::Nouveau: (fct du niveau de commentaire des elcontact): "; + LaLIST::iterator ipp,ippfin=listContact.end(); + for (ipp=listContact.begin();ipp != ippfin; ipp++) + {(*ipp).Affiche(2);}; + cout << " fin liste "; + }; + if (niveau_commentaire_lescontacts > 3) + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n " #endif << " <== fin LesContacts::Nouveau " ; }; - if (niveau_commentaire_lescontacts > 4) - // on va lister les éléments de contact - { - #ifdef UTILISATION_MPI - cout << "\n proc " << proc_en_cours - #else - cout << "\n" - #endif - << " liste des Elcontact a la fin de LesContacts::Nouveau: (fct du niveau de commentaire des elcontact): "; - LaLIST::iterator ipp,ippfin=listContact.end(); - for (ipp=listContact.begin();ipp != ippfin; ipp++) - {(*ipp).Affiche(2);}; - }; - + tempsContact.Arret_du_comptage(); // fin cpu //cout << "\n tempsContact.Temps_CPU_User = " << tempsContact.Temps_CPU_User() << flush; return retour; @@ -1582,7 +1626,7 @@ bool LesContacts::SuppressionDefinitiveElemInactif() } //**** j'ai l'impression que la ligne qui suit ne sert à rien, car le if précédent était uniquement pour les inactifs, donc si on va à la ligne qui suit // c'est que l'élément est actif, donc cela ne sert à rien de le réactiver ???? ceci dit cela ne génère pas une erreur a priori - else {(*iE).Met_actif();}; // on valide l'activation + else {/*(*iE).Met_actif();*/}; // on valide l'activation }; // info if (niveau_commentaire_lescontacts > 2) @@ -1954,6 +1998,7 @@ bool LesContacts::Actualisation(int choix) LaLIST::iterator ipp,ippfin=listContact.end(); for (ipp=listContact.begin();ipp != ippfin; ipp++) {(*ipp).Affiche(2);}; + cout << " fin liste "; }; for (i=1, iE = listContact.begin(); iE !=iEfin; iE++,i++)//,iden++) @@ -2018,7 +2063,7 @@ bool LesContacts::Actualisation(int choix) retour = true; // on signale le changement } else if (test_existance != NULL) - // cas où test est forcément == 2 (car on a calculé test_existance) il on est arrivé sur un élément existant qui est actif + // cas où test est forcément == 2 (car on a calculé test_existance) et on est arrivé sur un élément existant qui est actif // on inactive l'element de contact {if (test_existance->Actif()) { LaLIST ::iterator iiE = iE; @@ -2041,12 +2086,14 @@ bool LesContacts::Actualisation(int choix) // ou alors que test < 0 mais on a choix == 1, c-a-d que l'on veut maintenir le contact même en dehors de l'élément actuel // (c'est par exemple une situation transitoire pendant les itérations en implicite) { if (niveau_commentaire_lescontacts >= 7) + { #ifdef UTILISATION_MPI cout << "\n proc " << proc_en_cours<<": " #else cout << "\n" #endif << " contact maintenu: ";(*iE).Affiche(1); + }; }; // si on a inactivé l'élément, on regarde s'il n'y a pas un autre contact, utilisant le même noeud // que l'on pourrait activer @@ -2066,34 +2113,42 @@ bool LesContacts::Actualisation(int choix) {LaLIST < LaLIST::iterator > & list_tesN = tesN_encontact_ii[noe]; LaLIST < LaLIST::iterator >::iterator pl,plfin=list_tesN.end(); for (pl = list_tesN.begin();pl != plfin;pl++) + if ((*pl) != iE) // on évite celui qu'on vient d'inactiver !! {ElContact& elc = (*(*pl)); - // là on va faire une actualisation simplifiée: le cas collant n'est pas à prendre en compte - // car on n'arrive jamais ici en collant - bool actif_transitoire = true; - elc.Met_actif(); // on doit activer l'élément pour utiliser Actualisation - // cela veut dire que systématiquement on calcule comme si le noeud esclave se déplace en contact - // (ce n'est pas une initialisation ) - test = elc.Actualisation(); - test_existance = NULL ; // init - if (test == 2) - {// on a changé de frontière, on regarde si l'élément de contact avec la nouvelle frontière n'est pas - //identique à un élément existant - test_existance= Element_contact_deja_present(iE); + // on ne continue que si l'élément est inactif, sinon il est étudié dans la boucle globale + if (!(elc.Actif())) + {// là on va faire une actualisation simplifiée: le cas collant n'est pas à prendre en compte + // car on n'arrive jamais ici en collant + elc.Met_actif(); // on doit activer l'élément pour utiliser Actualisation + // cela veut dire que systématiquement on calcule comme si le noeud esclave se déplace en contact + // (ce n'est pas une initialisation ) + test = elc.Actualisation(); + test_existance = NULL ; // init + if (test == 2) + {// on a changé de frontière, on regarde si l'élément de contact avec la nouvelle frontière n'est pas + //identique à un élément existant + test_existance= Element_contact_deja_present(iE); + }; + if ((test_existance == NULL) && (test > 0)) + // arrivée ici cela veut dire que le contact est valide + // on conserve l'élément actif + { if (niveau_commentaire_lescontacts > 2) + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours<<": " + #else + cout << "\n" + #endif + << "reactivation contact :";elc.Affiche(1); + }; + } + else // sinon on inactive l'élément pour le ramener à l'état initial + {elc.Met_Inactif(); + if (elc.Permet_affichage() > 2) + cout << " ===>> inactivation car element doublon "; + + }; }; - if ((test_existance == NULL) && (test > 0)) - // arrivée ici cela veut dire que le contact est valide - // on conserve l'élément actif - { actif_transitoire=false; // active l'élément - if (niveau_commentaire_lescontacts > 2) - #ifdef UTILISATION_MPI - cout << "\n proc " << proc_en_cours<<": " - #else - cout << "\n" - #endif - << "reactivation contact :";elc.Affiche(1); - } - else // sinon on inactive l'élément ; - elc.Met_Inactif(); }; }; @@ -2114,6 +2169,7 @@ bool LesContacts::Actualisation(int choix) LaLIST::iterator ipp,ippfin=listContact.end(); for (ipp=listContact.begin();ipp != ippfin; ipp++) {(*ipp).Affiche(2);}; + cout << " fin liste "; // on calcule et affiche le nombre de contact actif Calcul_Nb_contact_actif(); #ifdef UTILISATION_MPI @@ -2190,6 +2246,7 @@ void LesContacts::Liste_noeuds_position_changer(list & li_noe) li_noe.push_back(noe); }; }; + tempsContact.Arret_du_comptage(); // fin cpu } #ifdef UTILISATION_MPI temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu @@ -2220,7 +2277,6 @@ void LesContacts::Liste_noeuds_position_changer(list & li_noe) } else // cas du cpu 0 {// l'objectif ici est de récupérer les infos - tempsContact.Arret_du_comptage(); // fin cpu union double_int { double x; int n[2]; @@ -2249,11 +2305,8 @@ void LesContacts::Liste_noeuds_position_changer(list & li_noe) nb_proc_terminer++; // on prend en compte que l'on a récupéré un conteneur tempsContact.Arret_du_comptage(); }; - #ifdef UTILISATION_MPI if (niveau_commentaire_lescontacts >= 7) cout << "\n proc 0: -- LesContacts::Liste_noeuds_position_changer: "; - #endif - }; #endif @@ -2263,13 +2316,28 @@ void LesContacts::Liste_noeuds_position_changer(list & li_noe) // calcul des reactions de contact et stockage des valeurs // solution : le vecteur residu // test d'un decollement eventuelle, pour un noeud en contact +// Dans le cas d'un calcul parallèle, tous les cpu calculent, mais seule le cpu 0 +// affiche les messages normaux, mais tous les cpu affichent les messages d'erreur éventuels +// et les messages pour les niveaux de commentaires > 4 + void LesContacts::CalculReaction(Vecteur& residu,bool& decol,const Nb_assemb& casAssemb ,bool affiche) { tempsContact.Mise_en_route_du_comptage(); // def deb compt + #ifdef UTILISATION_MPI + int proc_en_cours = ParaGlob::Monde()->rank(); + #endif int niveau_commentaire_lescontacts = Permet_affichage(); - if (niveau_commentaire_lescontacts > 4) - cout << "\n -- LesContacts::CalculReaction: "; + #ifdef UTILISATION_MPI + if (proc_en_cours == 0) + #endif + if (niveau_commentaire_lescontacts > 4) + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " -- LesContacts::CalculReaction: \n"; int nb_Assemb = casAssemb.n; // récup du numéro d'assemblage // récup du type de contact int contact_type = ElContact::Recup_et_mise_a_jour_type_contact(); @@ -2295,7 +2363,13 @@ void LesContacts::CalculReaction(Vecteur& residu,bool& decol,const Nb_assemb& ca int posi = noe->Pointeur_assemblage(X1,nb_Assemb); // position du ddl X1 #ifdef MISE_AU_POINT if ( posi == -1 ) - { cout << "\nErreur : ddl X1 " + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << "Erreur : ddl X1 " << " inexistant pour le cas de charge " << nb_Assemb << '\n' << " LesContacts::CalculReaction( (1)\n"; tempsContact.Arret_du_comptage(); // fin cpu @@ -2356,7 +2430,13 @@ void LesContacts::CalculReaction(Vecteur& residu,bool& decol,const Nb_assemb& ca { posi = tabNoeud(it)->Pointeur_assemblage(X1,nb_Assemb) ; // position du ddl X1 #ifdef MISE_AU_POINT if ( posi == -1 ) - { cout << "\nErreur : ddl X1 " + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << "Erreur : ddl X1 " << " inexistant pour le cas de charge " << nb_Assemb << '\n' << " LesContacts::CalculReaction( (2)\n"; tempsContact.Arret_du_comptage(); // fin cpu @@ -2375,16 +2455,26 @@ void LesContacts::CalculReaction(Vecteur& residu,bool& decol,const Nb_assemb& ca }; }; // affichage éventuelle de la force maxi de contact - Forces_contact_maxi(affiche); - // idem pour les gap N et T - Gap_contact_maxi(affiche); + #ifdef UTILISATION_MPI + if (proc_en_cours == 0) + #endif + {Forces_contact_maxi(affiche); + // idem pour les gap N et T + Gap_contact_maxi(affiche); + }; tempsContact.Arret_du_comptage(); // fin cpu }; // affichage des reactions de contact sur la sortie +// il s'agit ici d'une sortie sur fichier : seule le cpu 0 l'effectue void LesContacts::Affiche(ofstream& sort) const - { // on balaie le tableau de reaction + { + #ifdef UTILISATION_MPI + int proc_en_cours = ParaGlob::Monde()->rank(); + if (proc_en_cours == 0) + #endif +// on balaie le tableau de reaction for (int i= 1; i<= tabReacCont.Taille();i++) { ReactCont & R = tabReacCont(i); sort << "\n================= noeud esclave =================="; @@ -2404,16 +2494,16 @@ void LesContacts::Affiche(ofstream& sort) const }; // affichage à l'écran des informations liées au contact +// cas d'un calcul parallèle, on considère qu'il s'agit d'un affichage volontaire +// donc tous les cpu peuvent l'utiliser: on affiche en + le num du cpu void LesContacts::Affiche() const { #ifdef UTILISATION_MPI int proc_en_cours = ParaGlob::Monde()->rank(); + cout << "\n proc " << proc_en_cours + #else + cout << "\n" #endif - #ifdef UTILISATION_MPI - cout << "\n proc " << proc_en_cours - #else - cout << "\n" - #endif << "\n ---- affichage des informations liees au contact --------"; cout << "\n 1) liste des elements en contact"; LaLIST ::const_iterator il,ilfin=listContact.end(); @@ -2690,7 +2780,7 @@ void LesContacts::Lecture_zone_contact(UtilLecture & entreePrinc,const LesRefere #ifdef UTILISATION_MPI if (proc_en_cours == 0) #endif - cout << " fin de la lecture du nombre de domaines esclaves en auto-contact " << endl; + cout << " fin de la lecture du nombre de domaines esclaves en auto-contact " << endl; entreePrinc.NouvelleDonnee(); // positionnement sur une nouvelle info }; // --- cas des zones particulières de contact @@ -2738,12 +2828,12 @@ void LesContacts::Lecture_zone_contact(UtilLecture & entreePrinc,const LesRefere };*/ // lecture normale, vérification que la référence existe bien { - #ifdef UTILISATION_MPI - if (proc_en_cours == 0) - - #endif if (!(lesRef.Existe(nom_ref,nom_mail))) - { cout << "\n erreur le nom de reference de zone de contact : " << nom_ref + { + #ifdef UTILISATION_MPI + if (proc_en_cours == 0) + #endif + cout << "\n erreur le nom de reference de zone de contact : " << nom_ref << " , n'existe pas !!" << "\n LesContacts::Lecture_zone_contact(.."; throw (UtilLecture::ErrNouvelleDonnee(-1)); @@ -2788,7 +2878,7 @@ void LesContacts::Lecture_zone_contact(UtilLecture & entreePrinc,const LesRefere #ifdef UTILISATION_MPI if (proc_en_cours == 0) #endif - cout << " fin de la lecture des zones de contact " << endl; + cout << " fin de la lecture des zones de contact " << endl; }; // --- cas des contacts solide-deformable if (strstr(entreePrinc.tablcar,"contact_solide_deformable")!=NULL) @@ -2796,7 +2886,7 @@ void LesContacts::Lecture_zone_contact(UtilLecture & entreePrinc,const LesRefere #ifdef UTILISATION_MPI if (proc_en_cours == 0) #endif - cout << " debut de la lecture des contacts solide-deformable " << endl; + cout << " debut de la lecture des contacts solide-deformable " << endl; string toto; // variables de travail while (strstr(entreePrinc.tablcar,"fin_liste_des_couples_de_noms_solide_deformable")==NULL) // && (!motCle.SimotCle(entreePrinc.tablcar))) diff --git a/contact/LesContacts.h b/contact/LesContacts.h index 30509b4..9fd987e 100644 --- a/contact/LesContacts.h +++ b/contact/LesContacts.h @@ -226,18 +226,18 @@ class LesContacts // récupération via les éléments de contact des forces maxis // un : le maxi en effort normal, deux: le maxi en effort tangentiel - DeuxDoubles Forces_contact_maxi(bool affiche) const; + DeuxDoubles Forces_contact_maxi(bool affiche) ; - // récupération via les éléments de contact des gaps maxis + // récupération via les éléments de contact des gaps maxi en négatif, donc les mini // un : le maxi en gap normal, deux: le maxi en gap tangentiel - DeuxDoubles Gap_contact_maxi(bool affiche) const; + DeuxDoubles Gap_contact_maxi(bool affiche) ; // cas d'une méthode avec pénalisation: calcul éventuel d'un pas de temps idéal, // si oui retour de la valeur delta_t proposé // sinon dans tous les autres cas retour de 0. // le calcul se fait en fonction du pas de temps courant, des forces de réaction et de la pénétration // donc nécessite que le contact ait déjà été étudié et que les efforts de contact ait été calculé - double Pas_de_temps_ideal()const; + double Pas_de_temps_ideal(); // calcul d'une estimation du pas de temps critique du aux éléments de contact @@ -323,14 +323,18 @@ class LesContacts //retourne le niveau d'affichage - int Permet_affichage() const - {int niveau_commentaire_lescontacts = ParaGlob::param->ParaAlgoControleActifs().Niveau_commentaire_LesContact(); - if (niveau_commentaire_lescontacts == 0) {niveau_commentaire_lescontacts = ParaGlob::NiveauImpression();}; - return niveau_commentaire_lescontacts; + // li si non nulle permet d'indiquer spécifiquement quelle grandeur on veut + // sortir + int Permet_affichage(list * li = NULL ) const + { int niveau_commentaire_lescontacts; + return( (fct_niveau_commentaire == NULL) ? + (niveau_commentaire_lescontacts == 0) ? ParaGlob::NiveauImpression() : niveau_commentaire_lescontacts + : Valeur_fct_nD_LesContacts(fct_niveau_commentaire, li + ,LesContacts::tqi_fct_nD_niveau_commentaire + ,LesContacts::tqi_const_fct_nD_niveau_commentaire + ,LesContacts::t_num_ordre_fct_nD_niveau_commentaire) + ); }; - - - // initialisation de la liste de grandeurs qui sont effectivement gérées par le contact // ok, mais à revoir sans doute cf. pense bete 14 oct @@ -366,7 +370,14 @@ class LesContacts // VARIABLES PROTEGEES de la classe LesContacts: LesFonctions_nD* sauve_lesFonctionsnD ; // sauvegarde à l'initialisation (méthode Init_contact) ElContact::Fct_nD_contact fct_nD_contact; // fonctions nD de pilotage: peuvent ne pas exister - + // -- partie affichage éventuellement piloté + Fonction_nD * fct_niveau_commentaire; // fct nD dans le cas d'une valeur pilotée + static Tableau tqi_const_fct_nD_niveau_commentaire; + static Tableau < TypeQuelconque * > tqi_fct_nD_niveau_commentaire; + static Tableau t_num_ordre_fct_nD_niveau_commentaire; + // -- fin partie affichage éventuellement piloté + + LaLIST listContact; // la liste des elements en contact LaLIST ::iterator> listContact_nouveau_tatdt; // la liste des nouveaux contacts qui sont apparus sur l'incrément LaLIST listContact_efface_tatdt; // la liste des contacts effacés sur l'incrément @@ -440,7 +451,7 @@ class LesContacts // sans changer la map Tableau < std::map::iterator > > > tesN_encontact; - // tesN_encontact(numMail_esclave)[*pt_noeud] -> la liste des iterators d'élément en contact + // tesN_encontact(numMail_esclave)[*pt_noeud] -> la liste des iterators d'élément de contact // avec le noeud //--------- fin tableaux de gestions pour la recherche de contact ---------------- @@ -524,6 +535,19 @@ class LesContacts return (&(*ili)); return NULL; } ; + + // init éventuel du pilotage par fct nD du niveau de commentaire + void Init_fct_niveau_commentaire(); + // définition des conteneurs des TypeQuelconque pour fct nD de LesContacts + void Definition_conteneurs_fctnD_TypeQuelconque + (Fonction_nD * pt_fonct,Tableau < TypeQuelconque * >& tqi,Tableau < const TypeQuelconque * >& tqii + ,Tableau & t_num_ordre ); + + // calcul d'une fonction nD relative à aux données de LesContacts + double Valeur_fct_nD_LesContacts(Fonction_nD * fct_nD,list * li + ,Tableau < TypeQuelconque * >& tqi + ,Tableau < const TypeQuelconque * >& tqii + ,Tableau & t_num_ordre) const; }; /// @} // end of group diff --git a/contact/LesContacts_2.cc b/contact/LesContacts_2.cc index e7e7f10..4684613 100755 --- a/contact/LesContacts_2.cc +++ b/contact/LesContacts_2.cc @@ -49,6 +49,9 @@ void LesContacts::Lec_base_info_LesContacts(ifstream& ent ,Element& (T::*RecupElement_LesMaille)(int i, int j) const) { int niveau_commentaire_lescontacts = Permet_affichage(); + if (Permet_affichage()>4) + cout << "\n -- LesContacts::Lec_base_info_LesContacts "; + // tout d'abord on lit le type string type_contact,no_taille; int taille=0; // taille par défaut ent >> type_contact >> no_taille >> taille; diff --git a/contact/LesContacts_3.cc b/contact/LesContacts_3.cc index 32b9ddb..aa85360 100755 --- a/contact/LesContacts_3.cc +++ b/contact/LesContacts_3.cc @@ -51,9 +51,15 @@ void LesContacts::TdtversT() listContact_efface_tatdt.clear(); }; -// actualisation des ddl et des grandeurs actives de t vers tdt +// actualisation des ddl et des grandeurs actives de t vers tdt +// dans le cas //, on ajoute dans les messages, le num du prog void LesContacts::TversTdt() - { // on essaie de mettre la situation de contact comme elle était à t + { + #ifdef UTILISATION_MPI + int proc_en_cours = ParaGlob::Monde()->rank(); + #endif + + // on essaie de mettre la situation de contact comme elle était à t // a) on supprime les nouveaux contacts {LaLIST ::iterator>::iterator al,alfin=listContact_nouveau_tatdt.end(); for (al=listContact_nouveau_tatdt.begin();al != alfin; al++) @@ -64,7 +70,13 @@ void LesContacts::TversTdt() #ifdef MISE_AU_POINT if (tesN_encontact(num_mail_noe_esclave).find(no) == tesN_encontact(num_mail_noe_esclave).end() ) - { cout << "\n*** Erreur : on ne trouve pas la liste d'element en contact avec le noeud esclave " + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << "*** Erreur : on ne trouve pas la liste d'element en contact avec le noeud esclave " << n_noee << " du maillage " << num_mail_noe_esclave << " la suite n'est pas possible " << " LesContacts::TversTdt(.. \n"; @@ -88,7 +100,13 @@ void LesContacts::TversTdt() int num_mail_noe_esclave = no->Num_Mail(); #ifdef MISE_AU_POINT if (Element_contact_deja_present(*al)) - { cout << "\n*** Erreur : l'element de contact existe déjà, ce n'est pas normal " + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << "\n*** Erreur : l'element de contact existe déjà, ce n'est pas normal " << (*al).Esclave()->Num_noeud() << " du maillage " << (*al).Esclave()->Num_Mail() << " la suite n'est pas possible " @@ -102,7 +120,13 @@ void LesContacts::TversTdt() #ifdef MISE_AU_POINT if (tesN_encontact(num_mail_noe_esclave).find(no) == tesN_encontact(num_mail_noe_esclave).end() ) - { cout << "\n*** Erreur : on ne trouve pas la liste d'element en contact avec le noeud esclave " + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << "\n*** Erreur : on ne trouve pas la liste d'element en contact avec le noeud esclave " << n_noee << " du maillage " << num_mail_noe_esclave << " la suite n'est pas possible " << " LesContacts::TversTdt(.. \n"; @@ -122,7 +146,12 @@ void LesContacts::TversTdt() }; Calcul_Nb_contact_actif(); if ((ParaGlob::NiveauImpression() > 4) || (Permet_affichage() > 4 )) - cout << "\n >> LesContacts::TversTdt : nb contact actif = "<< nb_contact_actif << endl ; + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << "\n >> LesContacts::TversTdt : nb contact actif = "<< nb_contact_actif << endl ; }; @@ -130,22 +159,57 @@ void LesContacts::TversTdt() // si oui retour de la valeur delta_t proposé // sinon dans tous les autres cas retour de 0. // le calcul se fait en fonction du pas de temps courant et de la pénétration -// donc nécessite que le contact ait déjà été étudié -double LesContacts::Pas_de_temps_ideal()const -{ double delta_optimal=ConstMath::tresgrand; - // on passe en revue tous les contacts - LaLIST ::const_iterator il,ilfin=listContact.end(); - for (il=listContact.begin();il != ilfin; il++) - { double dtelem_optimal = (*il).Pas_de_temps_ideal(); - if (dtelem_optimal != 0.) - delta_optimal = MiN(delta_optimal, dtelem_optimal); - }; - // retour du temps proposé - if (delta_optimal==ConstMath::tresgrand) - // cela veut dire qu'il n'a pas été modifié, on le met à 0 pour indiquer que l'on a rien - // n'a proposer - delta_optimal = 0.; +// donc nécessite que le contact ait déjà été étudié +// Dans le cas d'un calcul parallèle, il y a transfert du résultat au cpu 0 +// seules les cpu i calculent le pas de temps idéal pour leur portion et le proc 0 choisit le min +double LesContacts::Pas_de_temps_ideal() +{ tempsContact.Mise_en_route_du_comptage(); // def deb compt + double delta_optimal=ConstMath::tresgrand; +#ifdef UTILISATION_MPI + int proc_en_cours = ParaGlob::Monde()->rank(); + if (proc_en_cours != 0) + { +#endif + { + // on passe en revue tous les contacts + LaLIST ::const_iterator il,ilfin=listContact.end(); + for (il=listContact.begin();il != ilfin; il++) + { double dtelem_optimal = (*il).Pas_de_temps_ideal(); + if (dtelem_optimal != 0.) + delta_optimal = MiN(delta_optimal, dtelem_optimal); + }; + // retour du temps proposé + if (delta_optimal==ConstMath::tresgrand) + // cela veut dire qu'il n'a pas été modifié, on le met à 0 pour indiquer que l'on a rien + // n'a proposer + delta_optimal = 0.; + tempsContact.Arret_du_comptage(); // fin cpu + } +#ifdef UTILISATION_MPI + temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu + // maintenant on va transmettre au cpu 0 + mpi::request reqs1 = ParaGlob::Monde()->isend(0, 56, delta_optimal); + // on attend pas + temps_transfert_court.Arret_du_comptage(); // fin comptage cpu + } + else // cas du cpu 0 + {// l'objectif ici est de récupérer les infos + tempsContact.Arret_du_comptage(); // fin cpu + int nb_proc_terminer = 0; // permettra de terminer + 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 + temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu + double dtelem_optimal ; + mpi::request reqs1 = ParaGlob::Monde()->irecv(mpi::any_source, 56, dtelem_optimal ); + reqs1.wait(); // on attend que le conteneur soit rempli + delta_optimal = MiN(delta_optimal, dtelem_optimal); + nb_proc_terminer++; // on prend en compte que l'on a récupéré un conteneur + }; + }; +#endif + return delta_optimal; + }; // écriture base info @@ -174,7 +238,7 @@ void LesContacts::Ecri_base_info_LesContacts(ofstream& sort) // Il s'agit ici de mettre à jour les conteneurs stockés aux noeuds et/ou aux éléments // qui servent à récupérer les infos liés aux contact correspondant à liTQ - // actuellement les conteneurs passés en paramètre ne servent que pour + // actuellement les conteneurs passés en paramètre servent que pour // les énumérés, et les informations résultantes sont stockées au niveau des noeuds // constituant les éléments de contact // absolue: indique si oui ou non on sort les tenseurs dans la base absolue ou une base particulière @@ -683,6 +747,9 @@ void LesContacts::Mise_a_jour_boite_encombrement_element_contenant_front() void LesContacts::Suppression_gap_pour_noeud_collant() { int niveau_commentaire_lescontacts = Permet_affichage(); + #ifdef UTILISATION_MPI + int proc_en_cours = ParaGlob::Monde()->rank(); + #endif // on passe en revue les zones de contact et si nécessaire on supprime les gaps // sinon retour bool continuer = false; // init par défaut @@ -696,7 +763,7 @@ void LesContacts::Suppression_gap_pour_noeud_collant() // sinon il faut effectivement faire une suppression de gap #ifdef UTILISATION_MPI - if (ParaGlob::Monde()->rank() == 0) + if (proc_en_cours == 0) #endif if (niveau_commentaire_lescontacts > 2) cout << "\n >>>> Suppression_gap_pour_noeud_collant : "; @@ -711,7 +778,7 @@ void LesContacts::Suppression_gap_pour_noeud_collant() do { #ifdef UTILISATION_MPI - if (ParaGlob::Monde()->rank() == 0) + if (proc_en_cours == 0) #endif if (niveau_commentaire_lescontacts >2 ) cout << "\n boucle : "<::iterator il,ilfin=list_P.end(); #ifdef UTILISATION_MPI - if (ParaGlob::Monde()->rank() == 0) + if (proc_en_cours == 0) #endif if (niveau_commentaire_lescontacts >5 ) {cout << "\n " << list_P.size() << " proj trouvees " @@ -795,7 +862,7 @@ void LesContacts::Suppression_gap_pour_noeud_collant() for (il=list_P.begin(); il!= ilfin;il++,iface++) { double Ndis = (M-(*il)).Norme(); #ifdef UTILISATION_MPI - if (ParaGlob::Monde()->rank() == 0) + if (proc_en_cours == 0) #endif if (niveau_commentaire_lescontacts >5 ) cout << " dist: " << Ndis ; @@ -817,13 +884,13 @@ void LesContacts::Suppression_gap_pour_noeud_collant() if (distance > le_maxi_des_distances_trouve) le_maxi_des_distances_trouve = distance; #ifdef UTILISATION_MPI - if (ParaGlob::Monde()->rank() == 0) + if (proc_en_cours == 0) #endif if (niveau_commentaire_lescontacts >3 ) cout << "\n suppression gap=("<Num_noeud() << " du maillage " << noee->Num_Mail() << " (zone "<rank() == 0) + if (proc_en_cours == 0) #endif if (niveau_commentaire_lescontacts >4 ) {cout << "\n ancienne coordonnee "<< pt_esc @@ -851,7 +918,7 @@ void LesContacts::Suppression_gap_pour_noeud_collant() if ((!projection_ok) && (boucle==1)) // au premier passage { #ifdef UTILISATION_MPI - if (ParaGlob::Monde()->rank() == 0) + if (proc_en_cours == 0) #endif if (niveau_commentaire_lescontacts >3 ) cout << "\n pas de projection trouvee donc de suppression gap du noeud "<Num_noeud() @@ -859,7 +926,7 @@ void LesContacts::Suppression_gap_pour_noeud_collant() } ; }; //-- fin de la boucle sur inesc #ifdef UTILISATION_MPI - if (ParaGlob::Monde()->rank() == 0) + if (proc_en_cours == 0) #endif if (niveau_commentaire_lescontacts >2 ) {if (compteur_noeuds_projecte) @@ -884,9 +951,6 @@ void LesContacts::Suppression_gap_pour_noeud_collant() int LesContacts::Recup_ref( ElContact& al) { int nb_zone = MaX(1,nom_ref_zone_contact.size()); const Tableau & tn = al.TabNoeud(); - int num_mail_esclave = tn(1)->Num_Mail(); - int num_mail_maitre = tn(2)->Num_Mail(); - int num_noe = tn(1)->Num_noeud(); // on parcours la liste des frontières succeptibles d'entrer en contact // pour repérer la zone @@ -1028,6 +1092,9 @@ int LesContacts::Calcul_Nb_contact_actif() // création du conteneur Fct_nD_contact void LesContacts::Creation_Fct_nD_contact() { +#ifdef UTILISATION_MPI + int proc_en_cours = ParaGlob::Monde()->rank(); +#endif {// cas de la penalisation normale string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_nD_penalisationPenetration(); @@ -1039,7 +1106,13 @@ void LesContacts::Creation_Fct_nD_contact() fct_nD_contact.fct_nD_penalisationPenetration = pt_fonct; } else - { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la penalisation normale " + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage de la penalisation normale " << " le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); @@ -1059,10 +1132,16 @@ void LesContacts::Creation_Fct_nD_contact() fct_nD_contact.fct_nD_penetration_contact_maxi = pt_fonct; } else - { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " - << " penetration maxi, le nom : " << nom_fct - << " ne correspond pas a une fonction nD existante !! "; - Sortie(1); + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage de la " + << " penetration maxi, le nom : " << nom_fct + << " ne correspond pas a une fonction nD existante !! "; + Sortie(1); }; } else @@ -1079,10 +1158,16 @@ void LesContacts::Creation_Fct_nD_contact() fct_nD_contact.fct_nD_penetration_borne_regularisation = pt_fonct; } else - { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " - << " borne de regularisation, le nom : " << nom_fct - << " ne correspond pas a une fonction nD existante !! "; - Sortie(1); + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage de la " + << " borne de regularisation, le nom : " << nom_fct + << " ne correspond pas a une fonction nD existante !! "; + Sortie(1); }; } else @@ -1099,10 +1184,16 @@ void LesContacts::Creation_Fct_nD_contact() fct_nD_contact.fct_nD_force_contact_noeud_maxi = pt_fonct; } else - { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " - << " force de contact normale, le nom : " << nom_fct - << " ne correspond pas a une fonction nD existante !! "; - Sortie(1); + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage de la " + << " force de contact normale, le nom : " << nom_fct + << " ne correspond pas a une fonction nD existante !! "; + Sortie(1); }; } else @@ -1119,7 +1210,13 @@ void LesContacts::Creation_Fct_nD_contact() fct_nD_contact.fct_nD_penalisationTangentielle = pt_fonct; } else - { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la penalisation tangentielle " + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage de la penalisation tangentielle " << " le nom : " << nom_fct << " ne correspond pas a une fonction nD existante !! "; Sortie(1); @@ -1139,10 +1236,16 @@ void LesContacts::Creation_Fct_nD_contact() fct_nD_contact.fct_nD_tangentielle_contact_maxi = pt_fonct; } else - { cout << "\n *** erreur dans la definition de la fonction nD de pilotage du " - << " deplacement tangentiel maxi, le nom : " << nom_fct - << " ne correspond pas a une fonction nD existante !! "; - Sortie(1); + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage du " + << " deplacement tangentiel maxi, le nom : " << nom_fct + << " ne correspond pas a une fonction nD existante !! "; + Sortie(1); }; } else @@ -1159,10 +1262,16 @@ void LesContacts::Creation_Fct_nD_contact() fct_nD_contact.fct_nD_tangentielle_borne_regularisation = pt_fonct; } else - { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " - << " borne de regularisation tangentielle, le nom : " << nom_fct - << " ne correspond pas a une fonction nD existante !! "; - Sortie(1); + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage de la " + << " borne de regularisation tangentielle, le nom : " << nom_fct + << " ne correspond pas a une fonction nD existante !! "; + Sortie(1); }; } else @@ -1179,10 +1288,16 @@ void LesContacts::Creation_Fct_nD_contact() fct_nD_contact.fct_nD_force_tangentielle_noeud_maxi = pt_fonct; } else - { cout << "\n *** erreur dans la definition de la fonction nD de pilotage de la " - << " force tangentielle maxi, le nom : " << nom_fct - << " ne correspond pas a une fonction nD existante !! "; - Sortie(1); + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage de la " + << " force tangentielle maxi, le nom : " << nom_fct + << " ne correspond pas a une fonction nD existante !! "; + Sortie(1); }; } else @@ -1199,10 +1314,16 @@ void LesContacts::Creation_Fct_nD_contact() fct_nD_contact.fct_niveau_commentaire = pt_fonct; } else - { cout << "\n *** erreur dans la definition de la fonction nD de pilotage du " - << " niveau de commentaire en contact, le nom : " << nom_fct - << " ne correspond pas a une fonction nD existante !! "; - Sortie(1); + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage du " + << " niveau de commentaire en contact, le nom : " << nom_fct + << " ne correspond pas a une fonction nD existante !! "; + Sortie(1); }; } else @@ -1327,71 +1448,204 @@ Sortie(1); // récupération via les éléments de contact des forces maxis // et affichage éventuel // un : le maxi en effort normal, deux: le maxi en effort tangentiel -DeuxDoubles LesContacts::Forces_contact_maxi(bool affiche) const - {DeuxDoubles retour; - int niveau_commentaire_lescontacts = Permet_affichage(); +// Dans le cas d'un calcul parallèle, il y a transfert du résultat au cpu 0 +// seules les cpu i calculent +DeuxDoubles LesContacts::Forces_contact_maxi(bool affiche) + {tempsContact.Mise_en_route_du_comptage(); // def deb compt + DeuxDoubles retour_min,retour_max; // def et init à 0 + int niveau_commentaire_lescontacts = Permet_affichage(); +#ifdef UTILISATION_MPI + int proc_en_cours = ParaGlob::Monde()->rank(); + if (proc_en_cours != 0) + { +#endif + { + LaLIST ::const_iterator iNmin,iNmax,iTmax,il,ilfin = listContact.end(); + LaLIST ::const_iterator ilbegin = listContact.begin(); + for (il = iNmax = iTmax = iNmin = ilbegin;il != ilfin; il++) + if ((*il).Actif()) + { const ElContact& icont = (*il); // pour simplifier + double fNmax = icont.F_N_MAX(); + double fTmax = icont.F_T_MAX(); + if (fNmax < retour_min.un ) + {retour_min.un = fNmax;iNmin = il; + }; + if (fNmax > retour_max.un ) + {retour_max.un = fNmax;iNmax = il; + }; + // fTmax est toujours positif, donc on ne teste que le maxi + if (fTmax > retour_max.deux) + {retour_max.deux = fTmax;iTmax = il; + }; + }; + // affichage si on n'est pas en // + #ifndef UTILISATION_MPI + if ((affiche && (ParaGlob::NiveauImpression() > 2)) + || (niveau_commentaire_lescontacts > 3) // spécifiquement pour le contact + ) + { cout << "\n F_N => [" << retour_min.un << " : " << retour_max.un << "]" + << ", F_T max = " << retour_max.deux; + }; + if (niveau_commentaire_lescontacts > 6) + {if (iNmin != ilbegin ){cout << "\n mini F_N : "; (*iNmin).Affiche(0);}; + if (iNmax != ilbegin ){cout << "\n maxi F_N : "; (*iNmax).Affiche(0);}; + if (iTmax != ilbegin ){cout << "\n maxi F_T : "; (*iTmax).Affiche(0);}; + cout << "\n "; + } + else if (niveau_commentaire_lescontacts > 3) + {if (iNmin != ilbegin ) {cout << "\n mini F_N : "; (*iNmin).Affiche(1);}; + if (iNmax != ilbegin ){cout << "\n maxi F_N : "; (*iNmax).Affiche(1);}; + if (iTmax != ilbegin ){cout << "\n maxi F_T : "; (*iTmax).Affiche(1);}; + cout << "\n "; + } - LaLIST ::const_iterator iNmax,iTmax,il,ilfin = listContact.end(); - for (il = iNmax = iTmax = listContact.begin();il != ilfin; il++) - if ((*il).Actif()) - { const ElContact& icont = (*il); // pour simplifier - double fNmax = icont.F_N_MAX(); - double fTmax = icont.F_T_MAX(); - if (Dabs(fNmax) > Dabs(retour.un) ) - {retour.un = fNmax;iNmax = il; - }; - if (Dabs(fTmax) > Dabs(retour.deux) ) - {retour.deux = fTmax;iTmax = il; - }; - }; - if ((affiche && (ParaGlob::NiveauImpression() > 2)) - || (niveau_commentaire_lescontacts > 3) // spécifiquement pour le contact - ) - cout << "\n contact: reaction ==> F_N max " << retour.un << " F_T max " << retour.deux; - if (niveau_commentaire_lescontacts > 6) - {cout << "\n F_N max: "; (*iNmax).Affiche(0); - cout << "\n F_T max: "; (*iTmax).Affiche(0); - cout << "\n"; +// cout << "\n contact: reaction ==> F_N max " << retour.un << " F_T max " << retour.deux; +// if (niveau_commentaire_lescontacts > 6) +// {if (iNmax != itbegin) {cout << "\n F_N max: "; (*iNmax).Affiche(0);}; +// if (iTmax != itbegin) {cout << "\n F_T max: "; (*iTmax).Affiche(0);}; +// cout << "\n"; +// } +// else if (niveau_commentaire_lescontacts > 3) +// {if (iNmax != itbegin) {cout << "\n F_N max: "; (*iNmax).Affiche(1);}; +// if (iTmax != itbegin) {cout << "\n F_T max: "; (*iTmax).Affiche(1);}; +// cout << "\n"; +// }; + #endif + tempsContact.Arret_du_comptage(); // fin cpu + } + #ifdef UTILISATION_MPI + temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu + // maintenant on va transmettre au cpu 0 + Vecteur v_inter(2);v_inter(1) = retour.un; v_inter(2) = retour.deux; + // envoi + v_inter.Ienvoi_MPI(0,66); + // on attend pas + temps_transfert_long.Arret_du_comptage(); // fin comptage cpu } - else if (niveau_commentaire_lescontacts > 3) - {cout << "\n F_N max: "; (*iNmax).Affiche(1); - cout << "\n F_T max: "; (*iTmax).Affiche(1); - cout << "\n"; - }; - return retour; + else // cas du cpu 0 + {// l'objectif ici est de récupérer les infos + tempsContact.Arret_du_comptage(); // fin cpu + int nb_proc_terminer = 0; // permettra de terminer + 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 + temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu + Vecteur v_inter(2); + mpi::request reqs1 = v_inter.Irecup_MPI(mpi::any_source, 66); + reqs1.wait(); // on attend que le conteneur soit rempli + + if (Dabs(v_inter(1)) > Dabs(retour.un) ) + {retour.un = v_inter(1);}; + if (Dabs(v_inter(2)) > Dabs(retour.deux) ) + {retour.deux = v_inter(2); + }; + temps_transfert_court.Arret_du_comptage(); // fin comptage cpu + nb_proc_terminer++; // on prend en compte que l'on a récupéré un conteneur + }; + if ((affiche && (ParaGlob::NiveauImpression() > 2)) + || (niveau_commentaire_lescontacts > 3) // spécifiquement pour le contact + ) + cout << "\n contact: reaction ==> |F_N max| " << Dabs(retour_min.un) << " |F_T max| " << DabsMaX(retour_min.deux,retour_max.deux); + }; + #endif + + tempsContact.Arret_du_comptage(); // fin cpu + return retour_max; }; -// récupération via les éléments de contact des gaps maxis +// récupération via les éléments de contact des gaps maxi en négatif, donc les mini // un : le maxi en gap normal, deux: le maxi en gap tangentiel -DeuxDoubles LesContacts::Gap_contact_maxi(bool affiche) const - {DeuxDoubles retour; - LaLIST ::const_iterator iNmax,iTmax,il,ilfin = listContact.end(); - for (il = iNmax = iTmax = listContact.begin();il != ilfin; il++) - if ((*il).Actif()) - { const ElContact& icont = (*il); // pour simplifier - double fNmax = icont.Gaptdt(); - double fTmax = icont.Dep_T_tdt(); - if (Dabs(fNmax) > Dabs(retour.un) ) - {retour.un = fNmax;iNmax = il; - }; - if (Dabs(fTmax) > Dabs(retour.deux) ) - {retour.deux = fTmax;iTmax = il; - }; - }; +// Dans le cas d'un calcul parallèle, il y a transfert du résultat au cpu 0 +// seules les cpu i calculent +DeuxDoubles LesContacts::Gap_contact_maxi(bool affiche) + {tempsContact.Mise_en_route_du_comptage(); // def deb compt + DeuxDoubles retour_max,retour_min; int niveau_commentaire_lescontacts = Permet_affichage(); - if ((affiche && (ParaGlob::NiveauImpression() > 2)) - || (niveau_commentaire_lescontacts > 3) // spécifiquement pour le contact - ) - cout << ", maxi gap_N : " << retour.un << " gap_T : " << retour.deux; - if (niveau_commentaire_lescontacts > 6) - {cout << "\n maxi gap_N : "; (*iNmax).Affiche(0); - cout << "\n maxi gap_T : "; (*iTmax).Affiche(0); +#ifdef UTILISATION_MPI + int proc_en_cours = ParaGlob::Monde()->rank(); + if (proc_en_cours != 0) + { +#endif + { + LaLIST ::const_iterator iNmax,iTmax,iNmin,iTmin,il,ilfin = listContact.end(); + LaLIST ::const_iterator ilbegin=listContact.begin(); + for (il = iNmax = iTmax = iNmin = iTmin = ilbegin;il != ilfin; il++) + if ((*il).Actif()) + { const ElContact& icont = (*il); // pour simplifier + double fNmax = icont.Gaptdt(); + double fTmax = icont.Dep_T_tdt(); + if (fNmax > retour_max.un ) + {retour_max.un = fNmax;iNmax = il; + }; + if (fNmax < retour_min.un ) + {retour_min.un = fNmax;iNmin = il; + }; + if (fTmax > retour_max.deux ) + {retour_max.deux = fTmax;iTmax = il; + }; + if (fTmax < retour_min.deux ) + {retour_min.deux = fTmax;iTmin = il; + }; + }; + // affichage si on n'est pas en // + #ifndef UTILISATION_MPI + if ((affiche && (ParaGlob::NiveauImpression() > 2)) + || (niveau_commentaire_lescontacts > 3) // spécifiquement pour le contact + ) + cout << ", [" << retour_min.un << " <= gap_N <= " << retour_max.un << "], [" << retour_min.deux <<" <= gap_T <= " << retour_max.deux<<"] "; + if (niveau_commentaire_lescontacts > 6) + {if (iNmin != ilbegin ){cout << "\n mini gap_N : "; (*iNmin).Affiche(0);}; + if (iNmax != ilbegin ){cout << "\n maxi gap_N : "; (*iNmax).Affiche(0);}; + if (iTmin != ilbegin ){cout << "\n mini gap_T : "; (*iTmin).Affiche(0);}; + if (iTmax != ilbegin ){cout << "\n maxi gap_T : "; (*iTmax).Affiche(0);}; + cout << "\n "; + } + else if (niveau_commentaire_lescontacts > 3) + {if (iNmin != ilbegin ) {cout << "\n mini gap_N : "; (*iNmin).Affiche(1);}; + if (iNmax != ilbegin ){cout << "\n maxi gap_N : "; (*iNmax).Affiche(1);}; + if (iTmin != ilbegin ){cout << "\n mini gap_T : "; (*iTmin).Affiche(1);}; + if (iTmax != ilbegin ){cout << "\n maxi gap_T : "; (*iTmax).Affiche(1);}; + cout << "\n "; + } + #endif + tempsContact.Arret_du_comptage(); // fin cpu + } + #ifdef UTILISATION_MPI + temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu + // maintenant on va transmettre au cpu 0 + Vecteur v_inter(2);v_inter(1) = retour.un; v_inter(2) = retour.deux; + // envoi + v_inter.Ienvoi_MPI(0,67); + // on attend pas + temps_transfert_long.Arret_du_comptage(); // fin comptage cpu } - else if (niveau_commentaire_lescontacts > 3) - {cout << "\n maxi gap_N : "; (*iNmax).Affiche(1); - cout << "\n maxi gap_T : "; (*iTmax).Affiche(1); - }; - return retour; + else // cas du cpu 0 + {// l'objectif ici est de récupérer les infos + tempsContact.Arret_du_comptage(); // fin cpu + int nb_proc_terminer = 0; // permettra de terminer + 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 + temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu + Vecteur v_inter(2); + mpi::request reqs1 = v_inter.Irecup_MPI(mpi::any_source, 67); + reqs1.wait(); // on attend que le conteneur soit rempli + + if (Dabs(v_inter(1)) > Dabs(retour.un) ) + {retour.un = v_inter(1);}; + if (Dabs(v_inter(2)) > Dabs(retour.deux) ) + {retour.deux = v_inter(2); + }; + temps_transfert_court.Arret_du_comptage(); // fin comptage cpu + nb_proc_terminer++; // on prend en compte que l'on a récupéré un conteneur + }; + if ((affiche && (ParaGlob::NiveauImpression() > 2)) + || (niveau_commentaire_lescontacts > 3) // spécifiquement pour le contact + ) + cout << ", [" << retour_min.un << " <= gap_N <= " << retour_max.un << "], [" << retour_min.deux <<" <= gap_T <= " << retour_max.deux<<"] "; + }; + #endif + + tempsContact.Arret_du_comptage(); // fin cpu + return retour_min; }; @@ -1706,7 +1960,6 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail) Enum_type_geom type_front; int num_front = el->Num_frontiere(*elfpoint,type_front); // 4. on crée l'élément front ad hoc et on l'ajoute à la liste - const DdlElement & ddlElem = el->TableauDdl(); // récup des ddl int angle_mort = 1; la_list_des_front.push_front(Front(*elfpoint,&elem_non_const,num_front,angle_mort)); LaLIST_io ::iterator iik = la_list_des_front.begin(); // récup de l'iterator @@ -1881,7 +2134,6 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail) Enum_type_geom type_front; int num_front = el->Num_frontiere(*elfpoint,type_front); // 4. on crée l'élément front ad hoc et on l'ajoute à la liste - const DdlElement & ddlElem = el->TableauDdl(); // récup des ddl int angle_mort = 1; la_list_des_front.push_front(Front(*elfpoint,&elem_non_const,num_front,angle_mort)); LaLIST_io ::iterator iik = la_list_des_front.begin(); // récup de l'iterator @@ -1971,7 +2223,341 @@ void LesContacts::ElementAngleMort(LesMaillages& lesMail) }; - +// init éventuel du pilotage par fct nD du niveau de commentaire +void LesContacts::Init_fct_niveau_commentaire() + { + #ifdef UTILISATION_MPI + int proc_en_cours = ParaGlob::Monde()->rank(); + #endif + string nom_fct = ParaGlob::param->ParaAlgoControleActifs().Fct_niveau_commentaire_LesContact(); + if (nom_fct != "_") + {// on va récupérer la fonction + if (sauve_lesFonctionsnD->Existe(nom_fct)) + { Fonction_nD * pt_fonct = sauve_lesFonctionsnD->Trouve(nom_fct); + // sauvegarde + fct_niveau_commentaire = pt_fonct; + } + else + { + #ifdef UTILISATION_MPI + cout << "\n proc " << proc_en_cours + #else + cout << "\n" + #endif + << " *** erreur dans la definition de la fonction nD de pilotage du " + << " niveau de commentaire en contact, le nom : " << nom_fct + << " ne correspond pas a une fonction nD existante !! "; + Sortie(1); + }; + } + else + {fct_niveau_commentaire=NULL;}; + // initialisation des conteneurs de la fonction nD + if (fct_niveau_commentaire != NULL) + Definition_conteneurs_fctnD_TypeQuelconque + (fct_niveau_commentaire + ,tqi_fct_nD_niveau_commentaire,tqi_const_fct_nD_niveau_commentaire + ,t_num_ordre_fct_nD_niveau_commentaire); + }; + + + // définition des conteneurs static des TypeQuelconque + void LesContacts::Definition_conteneurs_fctnD_TypeQuelconque + (Fonction_nD * pt_fonct,Tableau < TypeQuelconque * >& tqi,Tableau < const TypeQuelconque * >& tqii + ,Tableau & t_num_ordre ) + {// on commence par récupérer le conteneurs des grandeurs à fournir + const Tableau & tab_queconque = pt_fonct->Tab_enu_quelconque(); + // on dimensionne + int tail_tab_queconque = tab_queconque.Taille(); + tqi.Change_taille(tail_tab_queconque); + t_num_ordre.Change_taille(tail_tab_queconque); + Grandeur_scalaire_entier grand_courant_entier(0); // par défaut pour la création des conteneurs quelconques + Grandeur_scalaire_double grand_courant_double(0.); // par défaut pour la création des conteneurs quelconques + // grandeurs de travail + int dim = ParaGlob::Dimension(); + Coordonnee inter(dim); + Grandeur_coordonnee grand_coor_courant(inter); + + // on va balayer les grandeurs quelconques + for (int i=1;i<= tail_tab_queconque;i++) + { bool trouver = false; + EnumTypeQuelconque enu = tab_queconque(i); + + tqi(i) = NULL; // init + t_num_ordre(i) = 1; //***** pour l'instant uniquement la première coordonnée s'il s'agit d'un Coordonnee + // *** à abonder par la suite !!!!!!!!!! + + // on regarde tout d'abord les grandeurs spécifiques + switch (enu) + { // il y a des grandeurs vectorielles qui pour l'instant ne sont pas prises en compte + // cf. fct nD + // NORMALE_CONTACT, GLISSEMENT_CONTACT ,PENETRATION_CONTACT,FORCE_CONTACT, + case CONTACT_NB_DECOL: + { tqi(i) = new TypeQuelconque(CONTACT_NB_DECOL,X1,grand_courant_entier); + trouver = true; + break; + } + case CONTACT_PENALISATION_N: + { tqi(i) = new TypeQuelconque(CONTACT_PENALISATION_N,X1,grand_courant_double); + trouver = true; + break; + } + case CONTACT_PENALISATION_T: + { tqi(i) = new TypeQuelconque(CONTACT_PENALISATION_T,X1,grand_courant_double); + trouver = true; + break; + } + case CONTACT_NB_PENET: + { tqi(i) = new TypeQuelconque(CONTACT_NB_PENET,X1,grand_courant_entier); + trouver = true; + break; + } + case CONTACT_CAS_SOLIDE: + { tqi(i) = new TypeQuelconque(CONTACT_CAS_SOLIDE,X1,grand_courant_entier); + trouver = true; + break; + } + case CONTACT_ENERG_GLISSE_ELAS: + { tqi(i) = new TypeQuelconque(CONTACT_ENERG_GLISSE_ELAS,X1,grand_courant_double); + trouver = true; + break; + } + case CONTACT_ENERG_GLISSE_PLAS: + { tqi(i) = new TypeQuelconque(CONTACT_ENERG_GLISSE_PLAS,X1,grand_courant_double); + trouver = true; + break; + } + case CONTACT_ENERG_GLISSE_VISQ: + { tqi(i) = new TypeQuelconque(CONTACT_ENERG_GLISSE_VISQ,X1,grand_courant_double); + trouver = true; + break; + } + case CONTACT_ENERG_PENAL: + { tqi(i) = new TypeQuelconque(CONTACT_ENERG_PENAL,X1,grand_courant_double); + trouver = true; + break; + } + case NOEUD_PROJECTILE_EN_CONTACT: + { tqi(i) = new TypeQuelconque(NOEUD_PROJECTILE_EN_CONTACT,X1,grand_courant_double); + trouver = true; + break; + } + 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())); + trouver = true; + break; + } + case NUM_NOEUD: + { tqi(i) = new TypeQuelconque(NUM_NOEUD,X1,grand_courant_entier); + trouver = true; + break; + } + case NUM_MAIL_NOEUD: + { tqi(i) = new TypeQuelconque(NUM_MAIL_NOEUD,X1,grand_courant_entier); + trouver = true; + break; + } + case POSITION_GEOMETRIQUE: + {tqi(i) = new TypeQuelconque(POSITION_GEOMETRIQUE,X1,grand_coor_courant); + trouver = true; + break; + } + case POSITION_GEOMETRIQUE_t: + {tqi(i) = new TypeQuelconque(POSITION_GEOMETRIQUE_t,X1,grand_coor_courant); + trouver = true; + break; + } + case POSITION_GEOMETRIQUE_t0: + {tqi(i) = new TypeQuelconque(POSITION_GEOMETRIQUE_t0,X1,grand_coor_courant); + trouver = true; + break; + } + // *** pour l'instant la suite n'est pas opérationelle car il s'agit de vecteur + // dont les composantes n'ont pas d'équivalent en ddl_enum_etendu + // il faudrait les définir si on veut pouvoir s'en servir + case PENETRATION_CONTACT: + {tqi(i) = new TypeQuelconque(PENETRATION_CONTACT,X1,grand_coor_courant); + trouver = true; + break; + } + case PENETRATION_CONTACT_T: + {tqi(i) = new TypeQuelconque(PENETRATION_CONTACT_T,X1,grand_coor_courant); + trouver = true; + break; + } + case GLISSEMENT_CONTACT: + {tqi(i) = new TypeQuelconque(GLISSEMENT_CONTACT,X1,grand_coor_courant); + trouver = true; + break; + } + case GLISSEMENT_CONTACT_T: + {tqi(i) = new TypeQuelconque(GLISSEMENT_CONTACT_T,X1,grand_coor_courant); + trouver = true; + break; + } + case NORMALE_CONTACT: + {tqi(i) = new TypeQuelconque(NORMALE_CONTACT,X1,grand_coor_courant); + trouver = true; + break; + } + case FORCE_CONTACT: + {tqi(i) = new TypeQuelconque(FORCE_CONTACT,X1,grand_coor_courant); + trouver = true; + break; + } + case FORCE_CONTACT_T: + {tqi(i) = new TypeQuelconque(POSITION_GEOMETRIQUE,X1,grand_coor_courant); + trouver = true; + break; + } + case CONTACT_COLLANT: + { tqi(i) = new TypeQuelconque(CONTACT_COLLANT,X1,grand_courant_entier); + trouver = true; + break; + } + case NUM_ZONE_CONTACT: + { tqi(i) = new TypeQuelconque(NUM_ZONE_CONTACT,X1,grand_courant_entier); + trouver = true; + break; + } + case NUM_ELEMENT: + { tqi(i) = new TypeQuelconque(NUM_ELEMENT,X1,grand_courant_entier); + trouver = true; + break; + } + case NUM_MAIL_ELEM: + { tqi(i) = new TypeQuelconque(NUM_MAIL_ELEM,X1,grand_courant_entier); + trouver = true; + break; + } + //*** fin + + default: + trouver = false; + break; + }; + + // si on n'a rien trouvé + if (!trouver) + {cout << "\n erreur***: la grandeur " << NomTypeQuelconque(enu) + << " n'existe pas les elements de contact " + << " la fonction nD " << pt_fonct->NomFonction() + << " ne peut pas etre renseignee " + << "\n ElContact::Fct_nD_contact::Definition_conteneurs_static_TypeQuelconque(.." << flush; + pt_fonct->Affiche(); + Sortie(1); + }; + + }; + // tableau de const intermédiaire pour l'appel de la fonction + tqii.Change_taille(tail_tab_queconque); + for (int i=1;i<= tail_tab_queconque;i++) + tqii(i) = tqi(i); + }; + + +// calcul d'une fonction nD relative à des données de LesContacts +double LesContacts::Valeur_fct_nD_LesContacts + (Fonction_nD * pt_fonct,list* li + ,Tableau < TypeQuelconque * >& tqi + ,Tableau < const TypeQuelconque * >& tqii + ,Tableau & t_num_ordre) const + { // on commence par récupérer les conteneurs des grandeurs à fournir + List_io & li_enu_scal = pt_fonct->Li_enu_etendu_scalaire(); + List_io & li_quelc = pt_fonct->Li_equi_Quel_evolue(); + const Tableau & tab_queconque = pt_fonct->Tab_enu_quelconque(); + + + // on passe en revue les grandeurs pour les renseigner + + // --- on balaie maintenant la liste des grandeurs à sortir + // 1) tout d'abord les ddl étendues + // pour l'instant cette liste doit-être vide + if (li_enu_scal.size() != 0) + { cout << "\n *** erreur : LesContacts::Valeur_fct_nD_LesContacts " + << " la fonction nD associe a l'affichage pour LesContacts ne doit pas " + << " inclure des Ddl_enum_etendu !! changer la fonction "; + Sortie(1); + } + Tableau val_ddl_enum (li_enu_scal.size()); // init par défaut + + + // 2) puis les grandeurs quelconques évoluées + {List_io::iterator ipq,ipqfin=li_quelc.end(); + for (ipq=li_quelc.begin();ipq!=ipqfin;ipq++) + { bool trouver = false; + TypeQuelconque& enuTQ = (*ipq); // pour simplifier + const TypeQuelconque_enum_etendu& en_ET_TQ = enuTQ.EnuTypeQuelconque().EnumTQ(); + + // si li est non nulle, li indique spécifiquement quelle grandeur on veut sortir + if (li != NULL) + { // on va balayer la liste et voir si une grandeur correspond + list::iterator ili,ilifin = li->end(); + for (ili = li->begin();ili != ilifin; ili++) + { TypeQuelconque& enuTQ_li = (*ili); // pour simplifier + const TypeQuelconque_enum_etendu& en_ET_TQ_li = enuTQ_li.EnuTypeQuelconque().EnumTQ(); + if (en_ET_TQ_li == en_ET_TQ ) // cas ou on a trouvé la grandeur demandée + { // pour l'instant seules les grandeurs scalaires entières sont admises + Grandeur_scalaire_entier& gr= *((Grandeur_scalaire_entier*) ((*ipq).Grandeur_pointee())); + Grandeur_scalaire_entier& gr_li= *((Grandeur_scalaire_entier*) ((*ili).Grandeur_pointee())); + (*gr.ConteneurEntier()) = (*gr_li.ConteneurEntier()); + trouver = true; + }; + }; + }; + if (!trouver) // si non existant, init par défaut + (*ipq).Grandeur_pointee()->InitParDefaut(); + }; + }; + + // 3) et enfin les grandeurs quelconques: + // >>> en fait même topo que pour la liste + // les conteneurs sont normalement déjà bien dimensionné + int tail_tab_queconque = tab_queconque.Taille(); + + // on va balayer les grandeurs quelconques + for (int i=1;i<= tail_tab_queconque;i++) + { bool trouver = false; + EnumTypeQuelconque enu = tab_queconque(i); + + // si li est non nulle, li indique spécifiquement quelle grandeur on veut sortir + if (li != NULL) + { // on va balayer la liste et voir si une grandeur correspond + list::iterator ili,ilifin = li->end(); + for (ili = li->begin();ili != ilifin; ili++) + { TypeQuelconque& enuTQ_li = (*ili); // pour simplifier + EnumTypeQuelconque en_ET_TQ_li = enuTQ_li.EnuTypeQuelconque().EnumTQ(); + if (en_ET_TQ_li == enu ) // cas ou on a trouvé la grandeur demandée + { // pour l'instant seules les grandeurs scalaires entières sont admises + Grandeur_scalaire_entier& gr= *((Grandeur_scalaire_entier*) ((*tqi(i)).Grandeur_pointee())); + Grandeur_scalaire_entier& gr_li= *((Grandeur_scalaire_entier*) ((*ili).Grandeur_pointee())); + (*gr.ConteneurEntier()) = (*gr_li.ConteneurEntier()); + trouver = true; + }; + }; + }; + if (!trouver) // si non existant, init par défaut + (*tqi_fct_nD_niveau_commentaire(i)).Grandeur_pointee()->InitParDefaut(); + + }; + // tqii pointe aux mêmes endroit que tqi mais est déclaré en const ... + // calcul de la valeur et retour dans tab_ret + Tableau & tab_val = pt_fonct->Valeur_FnD_Evoluee(&val_ddl_enum,&li_enu_scal,&li_quelc,&(tqii),&t_num_ordre); + + #ifdef MISE_AU_POINT + if (tab_val.Taille() != 1) + { cout << "\nErreur : la fonction nD " << pt_fonct->NomFonction() + << " doit calculer un scalaire or le tableau de retour est de taille " + << tab_val.Taille() << " ce n'est pas normal !\n" << flush; + if (Permet_affichage() > 2 ) + cout << "\n LesContacts::Valeur_fct_nD_LesContacts(... \n"; + Sortie(1); + }; + #endif + // on récupère le premier élément du tableau uniquement + return tab_val(1); + };