Compare commits

...

No commits in common. "master" and "V_7.020" have entirely different histories.

1074 changed files with 38028 additions and 11490 deletions

BIN
.DS_Store vendored

Binary file not shown.

111
.gitignore vendored Executable file
View file

@ -0,0 +1,111 @@
CVS/
*copi*
essai*
*old*
*.cp
*essai
*save*
.DS_Store
*.zip
*.cpp
*.f
*copy*
*maxima
Readme
*yaca
*yaca*
*.txt
NRC/
untitled
*.texte
*.sav
FAQ
ConsoleSIOUX.*
ConsoleSIOUX.plc
Carbon*
*.xws
tata
*.sh
*yacas
*maxima*
*yacas*
*sauve*
*.tex
*.cpp*
Algo/GalerkinContinu/AlgoMixte/AlgoriStatExpli.cc
Algo/GalerkinContinu/AlgoMixte/AlgoriStatExpli.h
Documentation/
Elements/MecaFlu/
Elements/Mecanique/SFE/Met_Sfe1s3_28sep.cc
Elements/Mecanique/SFE/compaAnaHZ
Elements/Mecanique/SFE/derive_courbure
Elements/Remonte/
Elements/Thermique/ElemPoint/
Elements/Thermique/ElemThermiGene.h
Elements/Thermique/Hexaedre/
Elements/Thermique/Pentaedre/
Elements/Thermique/Quad_asisymetrie/
Elements/Thermique/SFE/
Elements/Thermique/Tetraedre/
Elements/Thermique/Tria_axisymetrie/
Elements/Thermique/Triangle/
Elements/Thermique/quadrangle/
Flambage/Valpro.h
G_Var_precompile/
General/creatio_tube.c
General/herezh.Projet
General/suppres_tube.c
Lecture/UtilXML.h
Maillage/Renumerotation.cc
Maillage/renume.cc
Parametres/TypeCalcul.h
Parametres/Type_Calcul.h
Resolin/Resolution_Condi/Assemblage.cp_11-9-2001
Resultats/Gid_25mars/
Resultats/Gmsh_25mars/
STL_bouquin/
Tableaux/Tableau_T.cc
TypeBase/Reels.h
TypeBase/Reels3.cc
TypeBase/Reels3.h
TypeBase/TypePremierXML.h
TypeBase/XPath.h
TypeBase/XPath_hz.h
TypeBase/XPointer.h
TypeBase/XPointer_hz.h
Chargement/ComLoi_comp_abstraite.h
comportement/ExceptionsLoiComp.h
comportement/Hyper_elastique/Hyper1.cc
comportement/Hyper_elastique/Hyper1.h
comportement/Hyper_elastique/result
comportement/Hyper_elastique/verif_Epartielles
comportement/Hyper_elastique/verif_Etotal
comportement/Hyper_elastique/verif_Si
comportement/loi_visco_plastiques/
comportement/lois_speciales/Loi_rien2D.cc
comportement/lois_speciales/Loi_rien2D.h
comportement/plasticite/Prandtl_Reuss.h_version1
comportement/plasticite/Prandtl_Reuss1D.h.sept2001
comportement/plasticite/Prandtl_Reuss_23_11_02.h
macro/
tenseurs_mai99/Coordonnees/Coordonnee3_T.cc
tenseurs_mai99/Coordonnees/Coordonnee3_T.h
tenseurs_mai99/Reperes_bases/Base_T.cc
tenseurs_mai99/Reperes_bases/Bases.h
tenseurs_mai99/Reperes_bases/Repere.cc
tenseurs_mai99/Reperes_bases/Repere.h
tenseurs_mai99/Tenseur/TenseurO4.h
tenseurs_mai99/Tenseur/TenseurO4_1.cc
tenseurs_mai99/Tenseur/TenseurO4_2.cc
tenseurs_mai99/Tenseur/TenseurQgene-1.cc
tenseurs_mai99/Tenseur/TenseurQgene-2.cc
tenseurs_mai99/Vecteurs/Vecteur.c++
tenseurs_mai99/Vecteurs/Vecteur.hc
tenseurs_mai99/Vecteurs/Vecteur_de_pointeurs.cc
tenseurs_mai99/Vecteurs/Vecteur_de_pointeurs.h
tenseurs_mai99/Vecteurs/Vecteuri.cc
tenseurs_mai99/Vecteurs/Vecteuri.h
unix/makefile
caneva.h

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -80,6 +80,10 @@
#include "Temps_CPU_HZpp.h"
#include "TypeQuelconqueParticulier.h"
#include "VariablesExporter.h"
#ifdef UTILISATION_MPI
#include "Distribution_CPU.h"
#include "ResRaid_MPI.h"
#endif
// peut-être à modifier sur linux
#ifdef BIBLIOTHEQUE_STL_CODE_WARRIOR
@ -152,7 +156,8 @@ class Algori
Algori (EnumTypeCalcul type,const bool avec_typeDeCalcul
,const list <EnumSousTypeCalcul>& soustype
,const list <bool>& avec_soustypeDeCalcul
,UtilLecture& entreePrinc);
,UtilLecture& entreePrinc
);
// constructeur de copie
Algori (const Algori& algo);
@ -171,14 +176,16 @@ class Algori
static Algori* New_Agori(EnumTypeCalcul type,const bool avec_typeDeCalcul
,const list <EnumSousTypeCalcul>& soustype
,const list <bool>& avec_soustypeDeCalcul
,UtilLecture& entreePrinc);
,UtilLecture& entreePrinc
);
// ramène un tableau de pointeurs sur tous les algorithmes spécifique existants
// IMPORTANT : il y a création des algorithmes (utilisation d'un new)
static Tableau <Algori *> New_tous_les_Algo
(const bool avec_typeDeCalcul
,const list <EnumSousTypeCalcul>& soustype
,const list <bool>& avec_soustypeDeCalcul
,UtilLecture& entreePrinc);
,UtilLecture& entreePrinc
);
//lecture des parametres de controle
// peut être modifié dans le cas d'un algo particulier
@ -303,12 +310,12 @@ class Algori
// type_incre :signal permet de localiser le dernier incrément
virtual void Ecriture_base_info
(int cas,LesMaillages *lesMaillages,
LesReferences* lesReferences,LesCourbes1D* lesCourbes1D,
LesFonctions_nD* lesFonctionsnD,
LesLoisDeComp* lesLoisDeComp,
DiversStockage* diversStockage,Charge* charge,
LesCondLim* lesCondlim,LesContacts* lesContacts,Resultats* resultats,
OrdreVisu::EnumTypeIncre type_incre,int incre = 0);
LesReferences* lesReferences,LesCourbes1D* lesCourbes1D,
LesFonctions_nD* lesFonctionsnD,
LesLoisDeComp* lesLoisDeComp,
DiversStockage* diversStockage,Charge* charge,
LesCondLim* lesCondlim,LesContacts* lesContacts,Resultats* resultats,
OrdreVisu::EnumTypeIncre type_incre,int incre = 0);
// cas d'un démarrage à partir de base_info
// éventuellement est définit de manière spécifique pour chaque algorithme
// dans les classes filles
@ -316,13 +323,14 @@ class Algori
// incrément voulu et qu'il faut simplement faire la lecture des infos
// cas = 3 : on met à jour uniquement les données variables, il y a modification des grandeurs,
// mais pas redimentionnement lorsque cela est viable (sinon on redimentionne)
virtual void Lecture_base_info(int cas,LesMaillages *lesMaillages,
LesReferences* lesReferences,LesCourbes1D* lesCourbes1D,
LesFonctions_nD* lesFonctionsnD,
LesLoisDeComp* lesLoisDeComp,
DiversStockage* diversStockage,Charge* charge,
LesCondLim* lesCondlim,LesContacts* lesContacts,Resultats* resultats,
int inc_voulu=0);
virtual void Lecture_base_info
(int cas,LesMaillages *lesMaillages,
LesReferences* lesReferences,LesCourbes1D* lesCourbes1D,
LesFonctions_nD* lesFonctionsnD,
LesLoisDeComp* lesLoisDeComp,
DiversStockage* diversStockage,Charge* charge,
LesCondLim* lesCondlim,LesContacts* lesContacts,Resultats* resultats,
int inc_voulu=0);
// visualisation intéractive via le standard vrml
// la fonction est virtuelle ce qui lui permet d'être éventuellement facilement surchargée
@ -444,6 +452,11 @@ class Algori
streampos Debut_increment() const {return debut_increment;};
// ==============VARIABLES PROTEGEES :
#ifdef UTILISATION_MPI
// cas d'un calcul parallèle
Distribution_CPU distribution_CPU_algo; // gestion de la distribution de charge sur CPU
#endif
// 1)----------- protégées: spécifiques à un algo ----------
int mode_debug; // permet de spécifier des options particulières pour débugger
// controle de la sortie des informations: utilisé par les classes dérivées
@ -530,6 +543,16 @@ class Algori
// variables privées internes servant au pilotage de la convergence
int PhaseDeConvergence() const {return phase_de_convergence;}; // pour l'acces en lecture uniquement
void Change_PhaseDeConvergence(int phase) {phase_de_convergence=phase;};
#ifdef UTILISATION_MPI
// cas d'un calcul parallèle
void Passage_indicConvergenceAuxProcCalcul() ; // passage des indicateurs aux process de calcul
// globalisation des grandeurs globales: proc de calcul -> maitre puis transmission à ParaGlob
// et transmission aux proc de calcul:
// on ne demande pas à ParaGlob de faire la transmission, car il ne sait pas ce qu'il transmet
// et les infos ne sont pas contigües, le transfert ne sera pas performant
void Globalisation_et_transfert_auxProcCalcul_grandeurs_globales();
#endif
private :
int phase_de_convergence; // =0 indique si l'on est en phase de convergence
// =1 on a convergé soit très bien soit correctement
@ -550,7 +573,7 @@ class Algori
// que si on veut une vérification double (deux fois) de la convergence
Tableau <double> max_var_residu; // tableau qui garde en souvenir la suite des maxi pour le pilotage
int nb_cycle_test_max_var_residu; // utilisé dans Convergence()
//--- gestion des stockages
// -- une classe de stockage de paramètres pour le changement de largeur de bande
class ParaStockage {public: Nb_assemb nbass; int demi,total;
@ -716,7 +739,22 @@ class Algori
Temps_CPU_HZpp temps_metrique_K_SM; // lesTempsCpu(14)
Temps_CPU_HZpp temps_chargement; // lesTempsCpu(15)
Temps_CPU_HZpp temps_rech_contact; // lesTempsCpu(16)
#ifdef UTILISATION_MPI
// cas d'un calcul parallèle: // passage des infos entre process
Temps_CPU_HZpp temps_transfert_court_algo ; // lesTempsCpu(17)
Temps_CPU_HZpp temps_transfert_long_algo ; // lesTempsCpu(18)
Temps_CPU_HZpp temps_attente_algo ; // lesTempsCpu(19)
Temps_CPU_HZpp temps_transfert_court_matSm ; // lesTempsCpu(20)
Temps_CPU_HZpp temps_transfert_long_matSm ; // lesTempsCpu(21)
Temps_CPU_HZpp temps_attente_matSm ; // lesTempsCpu(22)
Temps_CPU_HZpp temps_transfert_court_charge ; // lesTempsCpu(23)
Temps_CPU_HZpp temps_transfert_long_charge ; // lesTempsCpu(24)
Temps_CPU_HZpp temps_attente_charge ; // lesTempsCpu(25)
Temps_CPU_HZpp temps_transfert_court_contact ; // lesTempsCpu(26)
Temps_CPU_HZpp temps_transfert_long_contact ; // lesTempsCpu(27)
Temps_CPU_HZpp temps_attente_contact ; // lesTempsCpu(28)
#endif
Tableau <Coordonnee3> lesTempsCpu; // un tableau intermédiaire qui récupère et globalise les temps pour les sorties
// via listeVarGlob, mais c'est les variables Temps_CPU_HZpp qui stockent
// réellement les temps
@ -865,7 +903,7 @@ class Algori
// nouvelle_largeur_imposee.deux = la demie largeur
// nouvelles_largeur_en_ddl.trois = la demie largeur maximale pour la partie éléments finis
// uniquement (sans les CLL)
Tableau <Mat_abstraite* > Mise_a_jour_Choix_matriciel_contact
void Mise_a_jour_Choix_matriciel_contact
(Tableau <Mat_abstraite* >& tab_matglob,const Nb_assemb& nb_casAssemb
, LesContacts*lescontacts
,int niveau_substitution ,TroisEntiers* nouvelle_largeur_imposee = NULL);
@ -1032,7 +1070,9 @@ class Algori
// mise à jour de la viscosité critique en continu: spécifique au algo de relaxation dynamique, appelé par Cal_mat_visqueux_num_expli
void CalculEnContinuMatriceViscositeCritique(const Mat_abstraite& mat_mass,Mat_abstraite& mat_C_pt
,const Vecteur & delta_X, const Vecteur & vitesse);
protected:
protected:
// passage des grandeurs gérées par l'algorithme de tdt à t
// en particulier les énergies et les puissances
void TdtversT();
@ -1082,7 +1122,8 @@ class Algori
// passage des grandeurs globales aux noeuds où il y a des variables globales attachées
// nb_casAssemb correspond au cas d'assemblage de X1
void Passage_de_grandeurs_globales_vers_noeuds_pour_variables_globales(LesMaillages * lesMail,VariablesExporter* varExpor,const Nb_assemb& nb_casAssemb,const LesReferences& lesRef);
void Passage_de_grandeurs_globales_vers_noeuds_pour_variables_globales
(LesMaillages * lesMail,VariablesExporter* varExpor,const Nb_assemb& nb_casAssemb,const LesReferences& lesRef);
// des fonctions inlines pour mettre à jour des grandeurs globales
// -- initialisation du compteur d'itérations
@ -1257,6 +1298,13 @@ class Algori
};
};
#ifdef UTILISATION_MPI
// cas d'un calcul parallèle, passage des énergies, volumes
// a priori utilisée dans le calcul de raideur et second membres
void Passage_energiesEtVolumes();
#endif
};
/// @} // end of group

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -64,8 +64,9 @@ void Algori::Lecture_base_info(int cas,LesMaillages *lesMaillages,
{bool inc_trouve = entreePrinc->Positionnement_base_info(inc_voulu);
if (!inc_trouve)
{ cout << "\nErreur : On ne trouve pas l'increment de restart demande !\n";
cout << "Algori::Lecture_base_info(....)"
<< " increment = " << inc_voulu << endl;
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
cout << "Algori::Lecture_base_info(....)"
<< " increment = " << inc_voulu << endl;
// dans le cas où un comptage du calcul est en cours on l'arrête
if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
@ -108,8 +109,9 @@ void Algori::Lecture_base_info(int cas,LesMaillages *lesMaillages,
// dans le cas où on n'a pas trouvé le bon incrément message d'erreur
if (!inc_trouve)
{ cout << "\nErreur : On ne trouve pas l'increment demande !\n";
cout << "Algori::Lecture_base_info(....)"
<< " incrément = " << inc_voulu << endl;
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
cout << "Algori::Lecture_base_info(....)"
<< " incrément = " << inc_voulu << endl;
// dans le cas où un comptage du calcul est en cours on l'arrête
if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
@ -119,8 +121,9 @@ void Algori::Lecture_base_info(int cas,LesMaillages *lesMaillages,
}
default :
{ cout << "\nErreur : valeur incorrecte du type de restart !\n";
cout << "Algori::Lecture_base_info(....)"
<< " cas= " << cas << endl;
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
cout << "Algori::Lecture_base_info(....)"
<< " cas= " << cas << endl;
// dans le cas où un comptage du calcul est en cours on l'arrête
if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
@ -131,7 +134,10 @@ void Algori::Lecture_base_info(int cas,LesMaillages *lesMaillages,
// lecture particulière à l'algorithme
Lecture_base_info(*entrons,cas);
// ******* reste lescontacts
#ifdef UTILISATION_MPI
// si calcul on sauvegarde la distribution
distribution_CPU_algo.Lecture_base_info(*entrons,cas);
#endif
lesMaillages->Lecture_base_info(*entrons,cas); // lecture des maillages et des references
lesReferences->Lecture_base_info(*entrons,cas); // lecture des références
lesCourbes1D->Lecture_base_info(*entrons,cas); // lecture des courbes1D
@ -242,8 +248,9 @@ void Algori::Ecriture_base_info
}
default :
{ cout << "\nErreur : valeur incorrecte du type de sauvegarde !\n";
cout << "Algori::Ecriture_base_info(....)"
<< " cas= " << cas << endl;
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
cout << "Algori::Ecriture_base_info(....)"
<< " cas= " << cas << endl;
// dans le cas où un comptage du calcul est en cours on l'arrête
if (tempsSauvegarde.Comptage_en_cours()) tempsSauvegarde.Arret_du_comptage();
if (tempsSortieFilCalcul.Comptage_en_cours()) tempsSortieFilCalcul.Arret_du_comptage();
@ -256,6 +263,10 @@ void Algori::Ecriture_base_info
{
// ******* reste lescontacts
Ecriture_base_info(*sortons,cas);
#ifdef UTILISATION_MPI
// si calcul on sauvegarde la distribution
distribution_CPU_algo.Ecriture_base_info(*sortons,cas);
#endif
lesMaillages->Ecriture_base_info(*sortons,cas); // Ecriture des maillages et des references
lesReferences->Ecriture_base_info(*sortons,cas); // Ecriture des references
lesCourbes1D->Ecriture_base_info(*sortons,cas); // Ecriture des courbes1D
@ -283,12 +294,13 @@ void Algori::Visu_vrml(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRefere
{ // on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{// écriture de l'en-tête
cout << "\n ======== module de visualisation format vrml ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== module de visualisation format vrml ========\n";
// -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
// tout d'abord ouverture du fichier de restart si nécessaire
entreePrinc->Ouverture_base_info("lecture");
// récup du flot d'entrée
ifstream * entrons = entreePrinc->Ent_BI();
// ifstream * entrons = entreePrinc->Ent_BI();
// def du conteneur des numéros d'incréments
list <int> list_incre = entreePrinc->Liste_increment();
// on informe l'instance de visualisation de la liste des incréments possibles
@ -377,7 +389,8 @@ void Algori::Visu_vrml(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRefere
// entreePrinc->Fermeture_fichier_legende_vrml();
}
// fin de la visualisation
cout << "\n ======== fin du module de visualisation format vrml ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format vrml ========\n";
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
@ -388,7 +401,8 @@ void Algori::Visu_vrml(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRefere
catch ( ... )
{ if (ParaGlob::NiveauImpression() >= 1)
{cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format vrml";
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::Visu_vrml(..";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::Visu_vrml(..";
cout << endl;
};
};
@ -406,12 +420,13 @@ void Algori::Visu_maple(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRefer
{ // on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{// écriture de l'en-tête
cout << "\n ======== module de visualisation par fichiers de points au format maple ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== module de visualisation par fichiers de points au format maple ========\n";
// -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
// tout d'abord ouverture du fichier de restart si nécessaire
entreePrinc->Ouverture_base_info("lecture");
// récup du flot d'entrée
ifstream * entrons = entreePrinc->Ent_BI();
// ifstream * entrons = entreePrinc->Ent_BI();
// def du conteneur des numéros d'incréments
list <int> list_incre = entreePrinc->Liste_increment();
// on informe l'instance de visualisation de la liste des incréments possibles
@ -509,7 +524,8 @@ void Algori::Visu_maple(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRefer
// entreePrinc->Fermeture_fichier_principal_maple();
}
// fin de la visualisation
cout << "\n ======== fin module de visualisation par fichiers de points au format maple ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin module de visualisation par fichiers de points au format maple ========\n";
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
@ -520,7 +536,8 @@ void Algori::Visu_maple(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRefer
catch ( ... )
{ if (ParaGlob::NiveauImpression() >= 1)
{cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format maple";
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::Visu_maple(..";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::Visu_maple(..";
cout << endl;
};
};
@ -538,12 +555,13 @@ void Algori::Visu_geomview(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRe
{ // on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{// écriture de l'en-tête
cout << "\n ======== module de visualisation format geomview ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== module de visualisation format geomview ========\n";
// -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
// tout d'abord ouverture du fichier de restart si nécessaire
entreePrinc->Ouverture_base_info("lecture");
// récup du flot d'entrée
ifstream * entrons = entreePrinc->Ent_BI();
// ifstream * entrons = entreePrinc->Ent_BI();
// def du conteneur des numéros d'incréments
list <int> list_incre = entreePrinc->Liste_increment();
// on informe l'instance de visualisation de la liste des incréments possibles
@ -656,7 +674,8 @@ void Algori::Visu_geomview(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRe
// entreePrinc->Fermeture_fichier_legende_geomview();
}
// fin de la visualisation
cout << "\n ======== fin du module de visualisation format geomview ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format geomview ========\n";
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
@ -667,7 +686,8 @@ void Algori::Visu_geomview(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRe
catch ( ... )
{ if (ParaGlob::NiveauImpression() >= 1)
{cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format geomview";
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::Visu_geomview(..";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::Visu_geomview(..";
cout << endl;
};
};
@ -685,12 +705,13 @@ void Algori::Visu_Gid(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferen
{ // on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{// écriture de l'en-tête
cout << "\n ======== module de visualisation format Gid ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== module de visualisation format Gid ========\n";
// -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
// tout d'abord ouverture du fichier de restart si nécessaire
entreePrinc->Ouverture_base_info("lecture");
// récup du flot d'entrée
ifstream * entrons = entreePrinc->Ent_BI();
// ifstream * entrons = entreePrinc->Ent_BI();
// def du conteneur des numéros d'incréments
list <int> list_incre = entreePrinc->Liste_increment();
// on informe l'instance de visualisation de la liste des incréments possibles
@ -809,7 +830,8 @@ void Algori::Visu_Gid(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferen
// entreePrinc->Fermeture_fichier_resultat_Gid();
}
// fin de la visualisation
cout << "\n ======== fin du module de visualisation format GID ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format GID ========\n";
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
@ -820,7 +842,8 @@ void Algori::Visu_Gid(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesReferen
catch ( ... )
{ if (ParaGlob::NiveauImpression() >= 1)
{cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format GID";
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::Visu_Gid(..";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::Visu_Gid(..";
cout << endl;
};
};
@ -838,12 +861,13 @@ void Algori::Visu_Gmsh(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRefere
{ // on gère les exceptions éventuelles en mettant le bloc sous surveillance
try
{// écriture de l'en-tête
cout << "\n ======== module de visualisation format Gmsh ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== module de visualisation format Gmsh ========\n";
// -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
// tout d'abord ouverture du fichier de restart si nécessaire
entreePrinc->Ouverture_base_info("lecture");
// récup du flot d'entrée
ifstream * entrons = entreePrinc->Ent_BI();
// ifstream * entrons = entreePrinc->Ent_BI();
// def du conteneur des numéros d'incréments
list <int> list_incre = entreePrinc->Liste_increment();
// on informe l'instance de visualisation de la liste des incréments possibles
@ -963,7 +987,8 @@ void Algori::Visu_Gmsh(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRefere
// entreePrinc->Fermeture_TousLesFichiersResultats_Gmsh();
}
// fin de la visualisation
cout << "\n ======== fin du module de visualisation format Gmsh ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format Gmsh ========\n";
}
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
@ -974,7 +999,8 @@ void Algori::Visu_Gmsh(ParaGlob * paraGlob,LesMaillages * lesMaillages,LesRefere
catch ( ... )
{ if (ParaGlob::NiveauImpression() >= 1)
{cout << "\n **** warning: erreur en ecriture pour la visualisation interactive via le format Gmsh";
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::Visu_Gmsh(..";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n Algori::Visu_Gmsh(..";
cout << endl;
};
};
@ -999,12 +1025,13 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
return;
}
// écriture de l'en-tête
cout << "\n ======== lecture du fichier de commande de visualisation ========\n";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== lecture du fichier de commande de visualisation ========\n";
// -- on définit l'ensemble des incréments possibles, ceci sont stocké dans .BI
// tout d'abord ouverture du fichier de restart si nécessaire
entreePrinc->Ouverture_base_info("lecture");
// récup du flot d'entrée
ifstream * entrons = entreePrinc->Ent_BI();
// ifstream * entrons = entreePrinc->Ent_BI();
// def du conteneur des numéros d'incréments
list <int> list_incre = entreePrinc->Liste_increment();
// on informe les instances de visualisation de la liste des incréments possibles
@ -1032,7 +1059,7 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
{ // cas où pas de liste -> on initialise à 0 et au dernier incrément si différent
list_incre_init_inter = &(visualise.List_balaie_init(-1));
}
const list<int> & list_incre_init = * list_incre_init_inter;
// const list<int> & list_incre_init = * list_incre_init_inter;
// on impose la liste pour les autres types de visualisation
visualise_maple.List_balaie_init(*list_incre_init_inter);//list_incre_init);
visualise_geomview.List_balaie_init(*list_incre_init_inter);//list_incre_init);
@ -1123,14 +1150,14 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
<< " fin_fichier_commande_visu ! "
<< "\n normalement ce mot cle doit finir le fichier, on continue quand meme, mais"
<< "\n il y a peut-etre un probleme";
if (ParaGlob::NiveauImpression() >= 4)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::LectureCommandeVisu(..";
}
else
{ // erreur en lecture
cout << "\n **** ERREUR en lecture du fichier de commande de visualisation "
<< "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite";
if (ParaGlob::NiveauImpression() >= 4)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::LectureCommandeVisu(..";
}
}
@ -1143,12 +1170,13 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
catch (...)// erreur inconnue
{ cout << "\n **** ERREUR inconnuee en lecture du fichier de commande de visualisation "
<< "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite";
if (ParaGlob::NiveauImpression() >= 4)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::LectureCommandeVisu(..";
};
// avertissement de la fin de lecture du fichier de commande
if (ParaGlob::NiveauImpression() >= 0)
// if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin de la lecture du fichier de commande de visualisation ========\n";
// visualisation en fonction de l'activité des différents types de sortie
// récup de la list des incréments à balayer
@ -1268,7 +1296,7 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
// entreePrinc->Fermeture_fichier_principal_vrml();
// entreePrinc->Fermeture_fichier_legende_vrml();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format vrml ========\n";
}
if (visualise_maple.Visu_maple_valide())
@ -1278,7 +1306,7 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
// // on ferme la sortie maple (fichier) et appel éventuel du visualisateur
// entreePrinc->Fermeture_fichier_principal_maple();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin module de visualisation par fichiers de points au format maple ========\n";
}
if (visualise_geomview.Visu_geomview_valide())
@ -1288,7 +1316,7 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
// entreePrinc->Fermeture_fichier_principal_geomview();
// entreePrinc->Fermeture_fichier_legende_geomview();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format geomview ========\n";
}
if (visualise_Gid.Visu_Gid_valide())
@ -1298,7 +1326,7 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
// entreePrinc->Fermeture_fichier_initial_Gid();
// entreePrinc->Fermeture_fichier_resultat_Gid();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format Gid ========\n";
}
if (visualise_Gmsh.Visu_Gmsh_valide())
@ -1308,7 +1336,7 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
// entreePrinc->Fermeture_fichier_initial_Gmsh();
// entreePrinc->Fermeture_TousLesFichiersResultats_Gmsh();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format Gmsh ========\n";
}
}
@ -1321,7 +1349,8 @@ void Algori::LectureCommandeVisu(ParaGlob * paraGlob,LesMaillages * lesMaillages
catch ( ... )
{ if (ParaGlob::NiveauImpression() >= 1)
{cout << "\n **** warning: erreur inconnue en lecture du fichier commande Visu";
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::LectureCommandeVisu(..";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::LectureCommandeVisu(..";
cout << "endl";
};
};
@ -1350,7 +1379,7 @@ void Algori::EcritureCommandeVisu()
catch (...)// erreur en écriture
{ cout << "\n **** ERREUR en ecriture du fichier de commande de visualisation "
<< "\n on continue quand meme";
if (ParaGlob::NiveauImpression() >= 4)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::EcritureCommandeVisu(..";
};
};
@ -1401,7 +1430,8 @@ void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,L
return;
}
// écriture de l'en-tête
if (ParaGlob::NiveauImpression() >= 2) {cout << "\n ======== lecture du fichier de commande "
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 1)) || (permet_affichage > 2))
{cout << "\n ======== lecture du fichier de commande "
<< "de visualisation ========\n";
};
//-- initialisation des grandeurs globales par maillage
@ -1515,19 +1545,19 @@ void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,L
<< " fin_fichier_commande_visu ! "
<< "\n normalement ce mot cle doit finir le fichier, on continue quand meme, mais"
<< "\n il y a peut-etre un probleme";
if (ParaGlob::NiveauImpression() >= 4)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::VisuAuFilDuCalcul(..";
}
else if ( erreur.lecture == 0) // on ne peut pas ouvrir le fichier
{ cout << "\n **** erreur en ouverture du fichier ";
if (ParaGlob::NiveauImpression() >= 4)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::VisuAuFilDuCalcul(..";
}
else
{ // erreur en lecture
cout << "\n **** ERREUR en lecture du fichier de commande de visualisation "
<< "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite";
if (ParaGlob::NiveauImpression() >= 4)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::VisuAuFilDuCalcul(..";
}
}
@ -1540,12 +1570,13 @@ void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,L
catch (...)// erreur inconnue
{ cout << "\n **** ERREUR inconnuee en lecture du fichier de commande de visualisation "
<< "\n on continue quand meme, mais il y aura peut-etre un probleme de coherence pour la suite";
if (ParaGlob::NiveauImpression() >= 4)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::VisuAuFilDuCalcul(..";
}
// avertissement de la fin de lecture du fichier de commande
if (ParaGlob::NiveauImpression() >= 2)
cout << "\n ======== fin de la lecture du fichier de commande de visualisation ========\n";
// if (ParaGlob::NiveauImpression() >= 2)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 2))
cout << "\n ======== fin de la lecture du fichier de commande de visualisation ========\n";
// initialisation de la sortie vrml (fichier) si la sortie vrml est valide
if (visualise.Visu_vrml_valide())
{ entreePrinc->Ouverture_fichier_principal_vrml();
@ -1675,7 +1706,7 @@ void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,L
// entreePrinc->Fermeture_fichier_principal_vrml();
// entreePrinc->Fermeture_fichier_legende_vrml();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format vrml ========\n";
};
if (visualise_maple.Visu_maple_valide())
@ -1685,7 +1716,7 @@ void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,L
// // on ferme la sortie maple (fichier) et appel éventuel du visualisateur
// entreePrinc->Fermeture_fichier_principal_maple();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin module de visualisation par fichiers de points au format maple ========\n";
};
if (visualise_geomview.Visu_geomview_valide())
@ -1695,7 +1726,7 @@ void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,L
// entreePrinc->Fermeture_fichier_principal_geomview();
// entreePrinc->Fermeture_fichier_legende_geomview();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format geomview ========\n";
};
if (visualise_Gid.Visu_Gid_valide())
@ -1705,7 +1736,7 @@ void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,L
// entreePrinc->Fermeture_fichier_initial_Gid();
// entreePrinc->Fermeture_fichier_resultat_Gid();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format Gid ========\n";
};
if (visualise_Gmsh.Visu_Gmsh_valide())
@ -1715,7 +1746,7 @@ void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,L
// entreePrinc->Fermeture_fichier_initial_Gmsh();
// entreePrinc->Fermeture_TousLesFichiersResultats_Gmsh();
// fin de la visualisation
if (ParaGlob::NiveauImpression() >= 0)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
cout << "\n ======== fin du module de visualisation format Gmsh ========\n";
};
}; //-- fin du if (type_incre == OrdreVisu::DERNIER_INCRE)
@ -1728,9 +1759,10 @@ void Algori::VisuAuFilDuCalcul(ParaGlob * paraGlob,LesMaillages * lesMaillages,L
throw (toto);
}
catch ( ... )
{ if (ParaGlob::NiveauImpression() >= 1)
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
{cout << "\n **** warning: erreur en ecriture pour la visualisation au fil du calcul";
if (ParaGlob::NiveauImpression() >= 4) cout << "\n Algori::VisuAuFilDuCalcul(..";
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
cout << "\n Algori::VisuAuFilDuCalcul(..";
cout << endl;
};
};
@ -1860,6 +1892,20 @@ void Algori::Ecriture_base_info
sort << "\n tps_metrique_KSM "<< temps_metrique_K_SM;
sort << "\n tps_chargement "<< temps_chargement;
sort << "\n tps_rech_contact "<< temps_rech_contact;
#ifdef UTILISATION_MPI
sort << "\n tps_transfert_court_Algo "<< temps_transfert_court_algo;
sort << "\n tps_transfert_long_Algo "<< temps_transfert_long_algo;
sort << "\n tps_attente_Algo "<< temps_attente_algo;
sort << "\n tps_transfert_court_matSm "<< temps_transfert_court_matSm;
sort << "\n tps_transfert_long_matSm "<< temps_transfert_long_matSm;
sort << "\n tps_attente_matSm "<< temps_attente_matSm;
sort << "\n tps_transfert_court_charge "<< temps_transfert_court_charge;
sort << "\n tps_transfert_long_charge "<< temps_transfert_long_charge;
sort << "\n tps_attente_charge "<< temps_attente_charge;
sort << "\n tps_transfert_court_contact "<< temps_transfert_court_contact;
sort << "\n tps_transfert_long_contact "<< temps_transfert_long_contact;
sort << "\n tps_attente_contact "<< temps_attente_contact;
#endif
// ----- écriture éventuelle des paramètres de l'algorithme et informations particulières
sort << "\n -----parametre_et_variables_particulieres_algo: " << Nom_TypeCalcul(typeCalcul);
@ -2046,7 +2092,20 @@ void Algori::Lecture_base_info(ifstream& ent,const int cas)
ent >> nom1 >> temps_metrique_K_SM;
ent >> nom1 >> temps_chargement;
ent >> nom1 >> temps_rech_contact;
#ifdef UTILISATION_MPI
ent >> nom1 >> temps_transfert_court_algo;
ent >> nom1 >> temps_transfert_long_algo;
ent >> nom1 >> temps_attente_algo;
ent >> nom1 >> temps_transfert_court_matSm;
ent >> nom1 >> temps_transfert_long_matSm;
ent >> nom1 >> temps_attente_matSm;
ent >> nom1 >> temps_transfert_court_charge;
ent >> nom1 >> temps_transfert_long_charge;
ent >> nom1 >> temps_attente_charge;
ent >> nom1 >> temps_transfert_court_contact;
ent >> nom1 >> temps_transfert_long_contact;
ent >> nom1 >> temps_attente_contact;
#endif
// --- lecture éventuelle des paramètres de l'algorithme
// on regarde tout d'abord si l'algo en lecture correspond

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -1189,11 +1189,18 @@ int Algori::AmortissementCinetique(const Vecteur & delta_ddl,const double& coef_
if (fct_nD_inter_nb_entre_relax != NULL)
{int old_valeur = inter_nb_entre_relax;
inter_nb_entre_relax = (fct_nD_inter_nb_entre_relax->Valeur_pour_variables_globales())(1);
if ((ParaGlob::NiveauImpression() > 2) && (old_valeur != inter_nb_entre_relax))
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 1))
if (old_valeur != inter_nb_entre_relax)
cout << "\n >>> changement de inter_nb_entre_relax de " << old_valeur
<< " en ==> "<< inter_nb_entre_relax;
};
// #ifdef UTILISATION_MPI
// // debug
// cout << "\n debug Algori::AmortissementCinetique N: " << icharge
// << " debut, proc= "<< ParaGlob::Monde()->rank() << flush;
// // fin debug
// #endif
// // dans le cas où l'on veut un amortissement individuel aux noeuds, on appelle la méthode spécifique
// int relax_vit_individuel = 0;
// if (amortissement_cinetique_au_noeud && !relax_vit)
@ -1201,6 +1208,7 @@ int Algori::AmortissementCinetique(const Vecteur & delta_ddl,const double& coef_
//*** je ne comprends pas le test que j'ai mis ici: abscon !! 16 oct 2018
// on ne continue que s'il n'y a pas d'amortissement cinétique en route
bool relaxation_effectuee = false; // initialisation
if (!((icharge > nb_deb_test_amort_cinetique_noe) && amortissement_cinetique_au_noeud))
// ---- non la suite n'est pas bonne et converge beaucoup moins bien !!
// je le remplace : on test si on est en amortissement cinétique, et que le nombre d'itérations
@ -1223,7 +1231,6 @@ int Algori::AmortissementCinetique(const Vecteur & delta_ddl,const double& coef_
// si > 0 : indique que la procédure est active, et que, de manière consécutive, indique
// le nombre de fois où il y a eu baisse
bool relaxation_effectuee = false; // initialisation
bool relaxation_reactive = false; // "
if ((amortissement_cinetique)&&(icharge != 0) && (icharge > nb_deb_test_amort_cinetique))
{ // on regarde si l'énergie cinétique a déjà été calculée, sinon on la calcule
@ -1252,7 +1259,7 @@ int Algori::AmortissementCinetique(const Vecteur & delta_ddl,const double& coef_
else {moy_gliss_t= 0.; moyenne_glissante = 0.;}; // au cas où on met une valeur très grande
};
// écriture d'info pour le débug au cas où
if ((ParaGlob::NiveauImpression() > 6) || (permet_affichage >3 ))
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 6)) || (permet_affichage > 3))
{if (taille_moyenne_glissante == 1)
{cout << "\n E_cin_tdt= " << E_cin_tdt << " compteur_decroit_pourRelaxDyn= " << compteur_decroit_pourRelaxDyn
<< " pic_E_cint_t= " << pic_E_cint_t << endl;
@ -1325,6 +1332,7 @@ int Algori::AmortissementCinetique(const Vecteur & delta_ddl,const double& coef_
&& (nb_depuis_derniere_relax >= inter_nb_entre_relax))
{ // cas ou on met en place l'amortissement
V.Zero();relaxation_effectuee=true;
nb_depuis_derniere_relax = 0;
dernier_pic = pic_E_cint_t; // on sauvegarde
if (taille_moyenne_glissante != 1) // on remet tout à 0
@ -1371,7 +1379,7 @@ int Algori::AmortissementCinetique(const Vecteur & delta_ddl,const double& coef_
{ if (delta_ddl.Max_val_abs() <= max_deltaX_pourRelaxDyn) nb_dX_OK_pourRelaxDyn++;
if (nb_dX_OK_pourRelaxDyn > nb_max_dX_OK_pourRelaxDyn)
{ relax_vit = -1;
if (ParaGlob::NiveauImpression() > 6)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 6)) || (permet_affichage > 3))
cout << "\n critere en deplacement ok: max_deltaX= " << delta_ddl.Max_val_abs();
nb_dX_OK_pourRelaxDyn=0; // on initialise pour une prochaine fois
// dans le cas ou l'arrêt réel n'est pas drivé par le déplacement
@ -1385,7 +1393,8 @@ int Algori::AmortissementCinetique(const Vecteur & delta_ddl,const double& coef_
// on tente d'afficher que si l'amortissement a effectivement eu lieu
// if (relax_vit && pa.AfficheIncrEnergie())
if (relaxation_effectuee && ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0)))
if (relaxation_effectuee)
{if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 2))
{cout << "\n N:" << icharge << " relaxation cinetique effectuee "
<< " pic_E_cint_t("<<compteur_pic_energie<<") " << dernier_pic
<< " max_pic_E_cin= " << max_pic_E_cin;
@ -1405,17 +1414,59 @@ int Algori::AmortissementCinetique(const Vecteur & delta_ddl,const double& coef_
cout << " relaxation_re_active ";
cout << endl;
};
};
};
#ifdef UTILISATION_MPI
temps_transfert_court_algo.Mise_en_route_du_comptage(); // comptage cpu
broadcast(*ParaGlob::Monde(), relaxation_effectuee, 0);
// debug
//cout << "\n debug Algori::AmortissementCinetique "
// << " barriere transfert relaxation_effectuee , proc= "<< ParaGlob::Monde()->rank() << flush;
// fin debug
// ParaGlob::Monde()->barrier(); // synchronisation ici de tous les process
temps_transfert_court_algo.Arret_du_comptage(); // fin comptage cpu
#endif
#ifdef UTILISATION_MPI
// // debug
// cout << "\n debug Algori::AmortissementCinetique "
// << " relaxation_effectué = "<< relaxation_effectuee << " proc= "<< ParaGlob::Monde()->rank() << flush;
// // fin debug
if (relaxation_effectuee && (ParaGlob::Monde()->rank() != 0))
// if (relaxation_effectuee )
{ V.Zero();
// // debug
// cout << "\n debug Algori::AmortissementCinetique "
// << " mise à 0 du vecteur vitesse, proc= "<< ParaGlob::Monde()->rank() << flush;
// // fin debug
};
#endif
// dans le cas où l'on veut également un amortissement individuel aux noeuds, on appelle la méthode spécifique
// que si il n'y a pas eu d'amortissement cinétique global
int relax_vit_individuel = 0;
int relax_vit_individuel = 0;int retour = 0;
if (amortissement_cinetique_au_noeud && !relax_vit)
{ relax_vit_individuel=AmortissementCinetique_individuel_aux_noeuds(delta_ddl,coef_mass,X,mat_mass,icharge,V);
// ici on a relax_vit = 0 donc le retour est uniquement particularisé par relax_vit_individuel
return relax_vit_individuel;
retour = relax_vit_individuel;
}
else // sinon on est dans le cas où on a seulement un amortissement global et seul relax_vit donne une info à ce sujet
{ return relax_vit;};
{ retour = relax_vit;};
#ifdef UTILISATION_MPI
temps_transfert_court_algo.Mise_en_route_du_comptage(); // comptage cpu
broadcast(*ParaGlob::Monde(), retour, 0);
temps_transfert_court_algo.Arret_du_comptage(); // fin comptage cpu
//// debug
//cout << "\n debug Algori::AmortissementCinetique N: " << icharge
// << " fin, proc= "<< ParaGlob::Monde()->rank() << flush;
//// fin debug
#endif
return retour;
// la ligne qui suit est fausse car avec un "ou" le résultat est uniquement 1 ou 0, et en particulier
// les - sont supprimé !! ce qui pose un pb lorsque relax_vit = -1 !!
@ -1562,8 +1613,9 @@ int Algori::AmortissementCinetique_individuel_aux_noeuds(const Vecteur & delta_d
// }
//// fin debug
// on tente d'afficher que si l'amortissement a effectivement eu lieu
if (relaxation_effectuee && (ParaGlob::NiveauImpression() > 7))
{cout << "\n relax effectue au noeud " << noe
if (relaxation_effectuee)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 7)) || (permet_affichage > 5))
{cout << "\n relax effectue au noeud " << noe
<< " pic_eN_cint_t("<<compteur_pic_energie_noe<<") " << dernier_pic_eN
<< " max_pic_eN_cin= " << max_pic_eN_cin;
if (compt_decroit_pourRelaxDyn_noe == -2)
@ -1573,8 +1625,9 @@ int Algori::AmortissementCinetique_individuel_aux_noeuds(const Vecteur & delta_d
cout << endl;
};
}; // fin de la boucle sur les noeuds
if ((ParaGlob::NiveauImpression() > 4)&&(compteur_relaxation_ok>0)) // affichage global éventuel
cout << "\n nb de relaxation individuelle effectuee: " << compteur_relaxation_ok;
if (compteur_relaxation_ok>0) // affichage global éventuel
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 4)) || (permet_affichage > 2))
cout << "\n nb de relaxation individuelle effectuee: " << compteur_relaxation_ok;
};// -- fin du cas où l'on applique l'amortissement
@ -1735,7 +1788,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
else if (compteur > pa.Iterations())
{ nombre_de_mauvaises_convergences++;
nombre_de_bonnes_convergences = 0;
if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{ cout << "\n============================================================================"
<< "\n ******* NON convergence des iterations d'equilibre ********* "
<< "\n============================================================================";
@ -1750,7 +1803,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
}
else if (phase_de_convergence == -2) // cas où c'est Convergence() qui est la cause de l'arret
// pour cause d'évolution divergente des résidus
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{ cout << "\n============================================================================"
<< "\n *** NON convergence equilibre: evolution divergente des residus ********* "
<< "\n============================================================================";
@ -1766,7 +1819,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
}
else if (phase_de_convergence == -3) // cas où c'est Convergence() qui est la cause de l'arret
// pour cause de variation de ddl minimal atteinte
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{ cout << "\n============================================================================"
<< "\n *** NON convergence equilibre: variation de ddl minimal atteinte ********* "
<< "\n============================================================================";
@ -1782,7 +1835,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
}
else if (phase_de_convergence == -4) // cas où c'est Convergence() qui est la cause de l'arret
// pour cause de variation de ddl maximal atteinte
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{ cout << "\n============================================================================"
<< "\n *** NON convergence equilibre: variation de ddl maximum atteinte ********* "
<< "\n============================================================================";
@ -1797,7 +1850,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
fin_iter = false; // on signale qu'il n'y a pas convergence
}
else if (phase_de_convergence == -5) // cas d'un arrêt à cause d'un jacobien négatif, qui est géré
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{ cout << "\n============================================================================"
<< "\n *** NON convergence due a la gestion de jacobien negatif ********* "
<< "\n============================================================================";
@ -1812,7 +1865,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
nombre_de_mauvaises_convergences++;
}
else if (phase_de_convergence == -6) // cas d'un arrêt à cause d'une variation de jacobine trop grande
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{ cout << "\n============================================================================"
<< "\n *** NON convergence due a une variation de jacobien trop grande ********* "
<< "\n============================================================================";
@ -1827,7 +1880,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
nombre_de_mauvaises_convergences++;
}
else if (phase_de_convergence == -7) // cas d'un arrêt à cause d'une non convergence de la loi de comp
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{ cout << "\n============================================================================"
<< "\n *** NON convergence due a la loi de comportement ********* "
@ -1845,7 +1898,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
}
else if (phase_de_convergence == -8) // cas d'un arrêt à cause d'une non convergence de la loi de comp
// mais pour un pb qui couve depuis plusieurs incréments
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{ cout << "\n============================================================================"
<< "\n *** NON convergence du a la loi de comportement ********* "
@ -1864,7 +1917,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
nombre_de_mauvaises_convergences++;
}
else if (phase_de_convergence == -9) // cas d'un arrêt à cause d'un pb de la résolution du syteme linéaire
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{ cout << "\n=============================================================================="
<< "\n *** NON convergence due a un pb de resolution du systeme lineaire ********* "
@ -1881,7 +1934,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
nombre_de_mauvaises_convergences++;
}
else if (phase_de_convergence == -10) // cas d'un arrêt à cause d'un pb de calcul des efforts extérieurs
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{ cout << "\n=============================================================================="
<< "\n *** NON convergence due a un pb de calcul des efforts exterieurs ********* "
@ -1898,7 +1951,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
nombre_de_mauvaises_convergences++;
}
else if (phase_de_convergence == -11) // cas d'un arrêt à cause d'un nan ou infini sur forces ext, int
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{ cout << "\n=============================================================================="
<< "\n *** NON convergence due a un nan ou infini sur forces int, ext, totales ********* "
@ -1915,7 +1968,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
nombre_de_mauvaises_convergences++;
}
else // cas d'une erreur de pilotage: on ne sait pas pourquoi il s'est arrêté sans convergence
{ if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{ if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{cout << "\n cas de pilotage de fin d'iteration inconnues ? ou alors qui suit une erreur signalee precedemment ";
if (ParaGlob::NiveauImpression() > 5)
@ -1940,7 +1993,7 @@ bool Algori::Pilotage_fin_iteration_implicite(int compteur)
}
return fin_iter;
//debug
if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{ cout << "\n Algori::Pilotage_fin_iteration_implicite: phase_de_convergence=" << phase_de_convergence
<< " nombre_de_bonnes_convergences= " << nombre_de_bonnes_convergences
<< " nombre_de_mauvaises_convergences " << nombre_de_mauvaises_convergences << endl ;
@ -2029,7 +2082,8 @@ void Algori::Pilotage_chaque_iteration(Vecteur* sol,double& maxDeltaDdl,const in
{ // -- sur ou sous relaxation
double sursousrelax = pa.SurSousRelaxation();
(*sol) *= sursousrelax;
if ((ParaGlob::NiveauImpression() >= 4) && (sursousrelax != 1.))
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 3)) || (permet_affichage > 2))
if (sursousrelax != 1.)
{if(ParaGlob::Francais())
{cout << "\n intervention d'une sur-sous relaxation: ";}
else {cout << "\n intervention of an over or under relaxation: ";};
@ -2041,7 +2095,7 @@ void Algori::Pilotage_chaque_iteration(Vecteur* sol,double& maxDeltaDdl,const in
{// cas d'une limitation globale (tout le vecteur sol change
if (maxDeltaDdl > pa.NormeMax_increment())
{ double facteur=(pa.NormeMax_increment()/maxDeltaDdl);
if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{cout << "\n ===>>>>> intervention de la reduction du vecteur increment de ddl ";}
else {cout << "\n ===>>>>> intervention of the reduction for the vector increment of dof ";};
@ -2064,7 +2118,7 @@ void Algori::Pilotage_chaque_iteration(Vecteur* sol,double& maxDeltaDdl,const in
{ vect(i) = Signe(vect(i),maxa); modif = true;};
};
if (modif)
{if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
{if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{cout << "\n ===>>>>> intervention de la reduction du vecteur increment de ddl, limitation des maxis ";}
else {cout << "\n ===>>>>> intervention of the reduction for the vector increment of dof, limitation of the maxis ";};
@ -2114,7 +2168,7 @@ void Algori::Pilotage_maxi_X_V(const Vecteur& X_t,Vecteur& X_tdt,const Vecteur&
double maxDeltaDdl=vec_trav.Max_val_abs();
if (maxDeltaDdl > normeMax_X_increment)
{ double facteur=(normeMax_X_increment/maxDeltaDdl);
if (ParaGlob::NiveauImpression() > 2)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{cout << "\n ===>>>>> intervention de la reduction du vecteur delta X ";}
else {cout << "\n ===>>>>> intervention of the reduction for the vector delta X ";};
@ -2139,7 +2193,7 @@ void Algori::Pilotage_maxi_X_V(const Vecteur& X_t,Vecteur& X_tdt,const Vecteur&
{ vec_trav(i) = Signe(vec_trav(i),maxa); modif = true;};
};
if (modif)
{if (ParaGlob::NiveauImpression() > 2)
{if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{cout << "\n ===>>>>> intervention de la reduction du vecteur delta X, limitation des maxis ";}
else {cout << "\n ===>>>>> intervention of the reduction for the vector delta X, limitation of the maxis ";};
@ -2159,7 +2213,7 @@ void Algori::Pilotage_maxi_X_V(const Vecteur& X_t,Vecteur& X_tdt,const Vecteur&
double maxDeltaDdl=vec_trav.Max_val_abs();
if (maxDeltaDdl > normeMax_V_increment)
{ double facteur=(normeMax_V_increment/maxDeltaDdl);
if (ParaGlob::NiveauImpression() > 2)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{cout << "\n ===>>>>> intervention de la reduction du vecteur delta V ";}
else {cout << "\n ===>>>>> intervention of the reduction for the vector delta V ";};
@ -2184,7 +2238,7 @@ void Algori::Pilotage_maxi_X_V(const Vecteur& X_t,Vecteur& X_tdt,const Vecteur&
{ vec_trav(i) = Signe(vec_trav(i),maxa); modif = true;};
};
if (modif)
{if (ParaGlob::NiveauImpression() > 4)
{if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 4)) || (permet_affichage > 0))
{if(ParaGlob::Francais())
{cout << "\n ===>>>>> intervention de la reduction du vecteur delta V, limitation des maxis ";}
else {cout << "\n ===>>>>> intervention of the reduction for the vector delta V, limitation of the maxis ";};
@ -2222,9 +2276,15 @@ void Algori::TdtversT()
// pour un problème de mécanique, en comparant le nombre de point d'intégration total
// et le nombre totale de degré de liberté
void Algori::VerifSingulariteRaideurMeca(int nbddl,const LesMaillages& lesMail) const
{ if (ParaGlob::NiveauImpression() != 0)
{
#ifdef UTILISATION_MPI
// cas d'un calcul //, seule la matrice du CPU 0 est concernée
if (ParaGlob::Monde()->rank() != 0)
return ;
#endif
if (ParaGlob::NiveauImpression() != 0)
{ // récup du nombre de grandeurs génératrices
Enum_ddl enu(SIG11); // init par défaut
// Enum_ddl enu(SIG11); // init par défaut
// on récupère la liste des problèmes physiques gérés par les éléments de tous les maillages
const list <Enum_ddl >& li = lesMail.Ddl_representatifs_des_physiques();
@ -2236,12 +2296,12 @@ void Algori::VerifSingulariteRaideurMeca(int nbddl,const LesMaillages& lesMail)
// affichage
const double ratio = 1.2; // le pourcentage
if (nbpt < ratio * nbddl)
if ((ParaGlob::NiveauImpression() > 0) || (permet_affichage> 0))
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 0)) || (permet_affichage > 0))
{ cout << "\n *** Attention, le nombre total de grandeurs generatrices aux point d'integrations dans "
<< " le probleme: " << nbpt << " est inferieur "
<< " a " << ratio << " * le nombre total de ddl du probleme !! c-a-d: "<< int(ratio * nbddl)
<< "\n en consequence il est possible que la matrice de raideur soit naturellement singuliere \n\n ";
if (ParaGlob::NiveauImpression() > 7)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 7)) || (permet_affichage > 0))
cout << "\n void Algori::VerifSingulariteRaideurMeca(... ";
};
};
@ -2282,7 +2342,7 @@ void Algori::Coherence_Algo_typeConvergence()
&& (Evolution_temporelle_du_calcul(typeCalcul) != AUCUNE_EVOLUTION))
{ cout << "\n *** erreur: utilisation de la norme E_cinetique/E_statique avec un calcul non dynamique"
<< " arret ! ";
if (ParaGlob::NiveauImpression() > 5)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 5)) || (permet_affichage > 0))
cout << "\n Algori::Coherence_Algo_typeConvergence() ";
// dans le cas où un comptage du calcul est en cours on l'arrête
if (tempsCalEquilibre.Comptage_en_cours())

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -421,6 +421,20 @@ void Algori::Passage_de_grandeurs_globales_vers_noeuds_pour_variables_globales(L
// Temps_CPU_HZpp temps_metrique_K_SM; // lesTempsCpu(14)
// Temps_CPU_HZpp temps_chargement; // lesTempsCpu(15)
// Temps_CPU_HZpp temps_rech_contact; // lesTempsCpu(16)
// si calcul //
//Temps_CPU_HZpp temps_transfert_court_algo ; // lesTempsCpu(17)
//Temps_CPU_HZpp temps_transfert_long_algo ; // lesTempsCpu(18)
//Temps_CPU_HZpp temps_attente_algo ; // lesTempsCpu(19)
//Temps_CPU_HZpp temps_transfert_court_matSm ; // lesTempsCpu(20)
//Temps_CPU_HZpp temps_transfert_long_matSm ; // lesTempsCpu(21)
//Temps_CPU_HZpp temps_attente_matSm ; // lesTempsCpu(22)
//Temps_CPU_HZpp temps_transfert_court_charge ; // lesTempsCpu(23)
//Temps_CPU_HZpp temps_transfert_long_charge ; // lesTempsCpu(24)
//Temps_CPU_HZpp temps_attente_charge ; // lesTempsCpu(25)
//Temps_CPU_HZpp temps_transfert_court_contact ; // lesTempsCpu(26)
//Temps_CPU_HZpp temps_transfert_long_contact ; // lesTempsCpu(27)
//Temps_CPU_HZpp temps_attente_contact ; // lesTempsCpu(28)
//
// Tableau <Coordonnee3> lesTempsCpu; // un tableau intermédiaire qui récupère et globalise les temps pour les sorties
// // via listeVarGlob, mais c'est les variables Temps_CPU_HZpp qui stockent
@ -475,10 +489,35 @@ void Algori::Temps_CPU_HZpp_to_lesTempsCpu
lesTempsCpu(15)(1)= temps_chargement.Temps_CPU_User();
temps_rech_contact = contact.Temps_cpu_Contact();
lesTempsCpu(16)(1)= temps_rech_contact.Temps_CPU_User();
#ifdef UTILISATION_MPI
// cas des temps de l'algorithme
lesTempsCpu(17)(1)= temps_transfert_court_algo.Temps_CPU_User();
lesTempsCpu(18)(1)= temps_transfert_long_algo.Temps_CPU_User();
lesTempsCpu(19)(1)= temps_attente_algo.Temps_CPU_User();
// des mat et SM locaux
lesTempsCpu(20)(1)= temps_transfert_court_matSm.Temps_CPU_User();
lesTempsCpu(21)(1)= temps_transfert_long_matSm.Temps_CPU_User();
lesTempsCpu(22)(1)= temps_attente_matSm.Temps_CPU_User();
// du chargement
temps_transfert_court_charge = charge.Temps_transfert_court();
lesTempsCpu(23)(1)= temps_transfert_court_charge.Temps_CPU_User();
temps_transfert_long_charge = charge.Temps_transfert_long();
lesTempsCpu(24)(1)= temps_transfert_long_charge.Temps_CPU_User();
temps_attente_charge = charge.Temps_attente();
lesTempsCpu(25)(1)= temps_attente_charge.Temps_CPU_User();
// du contact
temps_transfert_court_contact = contact.Temps_transfert_court();
lesTempsCpu(26)(1)= temps_transfert_court_contact.Temps_CPU_User();
temps_transfert_long_contact = contact.Temps_transfert_long();
lesTempsCpu(27)(1)= temps_transfert_long_contact.Temps_CPU_User();
temps_attente_contact = contact.Temps_attente();
lesTempsCpu(28)(1)= temps_attente_contact.Temps_CPU_User();
#endif
};
// idem la méthode de transfert si-dessus mais concerne uniquement les temps internes à l'algo
// utilisé par l'algo combiné
// ajoute au tableau passé en paramètre, les temps de l'algo
Tableau <Temps_CPU_HZpp> & Algori::Ajout_Temps_CPU_HZpp_to_lesTempsCpu(Tableau <Temps_CPU_HZpp> & lesTsCpu)
{ // test éventuel de la taille du tableau
@ -502,6 +541,20 @@ Tableau <Temps_CPU_HZpp> & Algori::Ajout_Temps_CPU_HZpp_to_lesTempsCpu(Tableau <
lesTsCpu(8) += tempsSortieFilCalcul; // conversion de long long en double
lesTsCpu(9) += tempsRaidSmEnerContact; // conversion de long long en double
lesTsCpu(10) += tempsSecondMembreEnergContact; // conversion de long long en double
#ifdef UTILISATION_MPI
lesTsCpu(17) += temps_transfert_court_algo;
lesTsCpu(18) += temps_transfert_long_algo;
lesTsCpu(19) += temps_attente_algo;
lesTsCpu(20) += temps_transfert_court_matSm;
lesTsCpu(21) += temps_transfert_long_matSm;
lesTsCpu(22) += temps_attente_matSm;
lesTsCpu(23) += temps_transfert_court_charge;
lesTsCpu(24) += temps_transfert_long_charge;
lesTsCpu(25) += temps_attente_charge;
lesTsCpu(26) += temps_transfert_court_contact;
lesTsCpu(27) += temps_transfert_long_contact;
lesTsCpu(28) += temps_attente_contact;
#endif
// retour
return lesTsCpu;
@ -526,6 +579,20 @@ void Algori::Arret_du_comptage_CPU()
temps_metrique_K_SM.Arret_du_comptage();
temps_chargement.Arret_du_comptage();
temps_rech_contact.Arret_du_comptage();
#ifdef UTILISATION_MPI
temps_transfert_court_algo.Arret_du_comptage();
temps_transfert_long_algo.Arret_du_comptage();
temps_attente_algo.Arret_du_comptage();
temps_transfert_court_matSm.Arret_du_comptage();
temps_transfert_long_matSm.Arret_du_comptage();
temps_attente_matSm.Arret_du_comptage();
temps_transfert_court_charge.Arret_du_comptage();
temps_transfert_long_charge.Arret_du_comptage();
temps_attente_charge.Arret_du_comptage();
temps_transfert_court_contact.Arret_du_comptage();
temps_transfert_long_contact.Arret_du_comptage();
temps_attente_contact.Arret_du_comptage();
#endif
};
// sortie sur fichier des temps cpu
@ -561,7 +628,11 @@ void Algori::Sortie_temps_cpu(const LesCondLim& lesCondLim
// écriture des temps cpu de l'algo:
sort_cpu << "\n==========================================================================";
#ifndef UTILISATION_MPI
sort_cpu << "\n Herezh++ : bilan temps cpu pour l'algorithme: " << Nom_TypeCalcul(TypeDeCalcul());;
#else
sort_cpu << "\n Herezh++ : (CPU "<< ParaGlob::Monde()->rank() << ") bilan temps cpu pour l'algorithme: " << Nom_TypeCalcul(TypeDeCalcul());;
#endif
sort_cpu << "\n==========================================================================\n";
// puis affichage de la version
ParaGlob::Sortie_Version(sort_cpu);
@ -642,6 +713,57 @@ void Algori::Sortie_temps_cpu(const LesCondLim& lesCondLim
<< "("<< std::setw(nbdigit) << (100*tempsSortieFilCalcul.Temps_CPU_User()/total_cpu) << " % ) "
<< tempsSortieFilCalcul.Temps_CPU_User_milli()
;
#ifdef UTILISATION_MPI
sort_cpu << "\n --------- dialogue inter cpu --------- ";
sort_cpu << "\n tps__transfert_court_Algo "
<< "("<< std::setw(nbdigit) << (100*temps_transfert_court_algo.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_transfert_court_algo.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__transfert_long_Algo "
<< "("<< std::setw(nbdigit) << (100*temps_transfert_long_algo.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_transfert_long_algo.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__attente_Algo "
<< "("<< std::setw(nbdigit) << (100*temps_attente_algo.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_attente_algo.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__transfert_court-Mat-Smloc "
<< "("<< std::setw(nbdigit) << (100*temps_transfert_court_matSm.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_transfert_court_matSm.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__transfert_long-Mat-Smloc "
<< "("<< std::setw(nbdigit) << (100*temps_transfert_long_matSm.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_transfert_long_matSm.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__attente-Mat-Smloc "
<< "("<< std::setw(nbdigit) << (100*temps_attente_matSm.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_attente_matSm.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__transfert_court_charge "
<< "("<< std::setw(nbdigit) << (100*temps_transfert_court_charge.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_transfert_court_charge.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__transfert_long_charge "
<< "("<< std::setw(nbdigit) << (100*temps_transfert_long_charge.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_transfert_long_charge.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__attente_charge "
<< "("<< std::setw(nbdigit) << (100*temps_attente_charge.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_attente_charge.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__transfert_court_contact "
<< "("<< std::setw(nbdigit) << (100*temps_transfert_court_contact.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_transfert_court_contact.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__transfert_long_contact "
<< "("<< std::setw(nbdigit) << (100*temps_transfert_long_contact.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_transfert_long_contact.Temps_CPU_User_milli()
;
sort_cpu << "\n tps__attente_contact "
<< "("<< std::setw(nbdigit) << (100*temps_attente_contact.Temps_CPU_User()/total_cpu) << " % ) "
<< temps_attente_contact.Temps_CPU_User_milli()
;
#endif
sort_cpu << "\n";
};
@ -856,24 +978,34 @@ bool Algori::Gestion_stockage_et_renumerotation_avec_contact(bool premier_calcul
,LesCondLim* lesCondLim,LesReferences* lesRef
,Tableau <Mat_abstraite* >& tab_mato,const Nb_assemb& nb_casAssemb
,LesContacts* lescontacts,int niveau_substitution)
{ // --- calcul des éléments de contact: (correspond à la définition de la surface de contact)
// definition ou mise à jour, des elements de contact eventuels
// - imposition (en fonction de l'algorithme de contact) de conditions particulières de penetration (nulle par exemple)
{
#ifdef UTILISATION_MPI
// cas d'un calcul //, seule la (ou les) matrices du CPU 0 sont concernées
// donc s'il s'agit d'un CPU différent, on revient immédiatement
if (ParaGlob::Monde()->rank() != 0)
return false;
#endif
TroisEntiers nevez_largeurs;
bool retour = false; // init pas de changement a priori au niveau des matrices
if (premier_calcul)
{// si demandé, renumérotation en fonction des éléments en contact
if ((ParaGlob::param->ParaAlgoControleActifs().Optimisation_numerotation())
|| (ParaGlob::param->ParaAlgoControleActifs().Optimisation_numerotation())
)
if (ParaGlob::param->ParaAlgoControleActifs().Optimisation_numerotation())
{ // récup des connexions entre noeud dues aux contacts
const Tableau <Condilineaire>& tabCondLine= lescontacts->ConnectionCLL();
if (tabCondLine.Taille() > 0) //cas où il faut en tenir compte
list <Condilineaire>& listCondLine= lescontacts->ConnectionCLL();
if (listCondLine.size() > 0) //cas où il faut en tenir compte
{// récup des connexions entre noeuds dues aux CLL externes
Tableau <Tableau <Condilineaire> > tabCLL(lesCondLim->ConnectionCLL(lesMail,lesRef));
int tailtabCLL = tabCLL.Taille();tabCLL.Change_taille(tailtabCLL+1);
tabCLL(tailtabCLL+1) = tabCondLine; // ajout de la partie contact
if (ParaGlob::NiveauImpression() >= 3)
// tabCLL(tailtabCLL+1) = listCondLine;
// ajout de la partie contact
Tableau <Condilineaire>& tabCLL_contact = tabCLL(tailtabCLL+1); // pour simplifier
tabCLL_contact.Change_taille(listCondLine.size());
list <Condilineaire>::iterator il,ilfin = listCondLine.end();
int i=1;
for (il = listCondLine.begin();il != ilfin;il++,i++)
tabCLL_contact(i) = (*il);
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 2))
cout << "\n -- renumerotation en tenant compte des elements de contact ";
// appel de l'utilitaire dans lesMaillages: avec mise à jour dans la foulée de l'assemblage
bool calcul_ok = lesMail->Renumerotation(*lesRef,tabCLL,nevez_largeurs,&nb_casAssemb,true);
@ -902,19 +1034,23 @@ bool Algori::Gestion_stockage_et_renumerotation_avec_contact(bool premier_calcul
} //-- fin du cas si premier calcul
else
{if (nouvelle_situation_contact)
{if ((ParaGlob::param->ParaAlgoControleActifs().Optimisation_numerotation())
|| (ParaGlob::param->ParaAlgoControleActifs().Optimisation_numerotation())
)
{if (ParaGlob::param->ParaAlgoControleActifs().Optimisation_numerotation())
{ // récup des connexions entre noeud dues aux contacts
const Tableau <Condilineaire>& tabCondLine= lescontacts->ConnectionCLL();
if (tabCondLine.Taille() > 0) //cas où il faut en tenir compte
list <Condilineaire>& listCondLine= lescontacts->ConnectionCLL();
if (listCondLine.size() > 0) //cas où il faut en tenir compte
{// récup des connexions entre noeuds dues aux CLL externes: comme les cll ont été mises à jour
// on récupère directement le tableau
Tableau <Tableau <Condilineaire> > tabCLL(lesCondLim->Tab_CLinApplique());
int tailtabCLL = tabCLL.Taille();tabCLL.Change_taille(tailtabCLL+1);
tabCLL(tailtabCLL+1) = tabCondLine; // ajout de la partie contact
if (ParaGlob::NiveauImpression() >= 3)
cout << "\n -- renumerotation en tenant compte des elements de contact ";
// ajout de la partie contact
Tableau <Condilineaire>& tabCLL_contact = tabCLL(tailtabCLL+1); // pour simplifier
tabCLL_contact.Change_taille(listCondLine.size());
list <Condilineaire>::iterator il,ilfin = listCondLine.end();
int i=1;
for (il = listCondLine.begin();il != ilfin;il++,i++)
tabCLL_contact(i) = (*il);
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 2))
cout << "\n -- renumerotation en tenant compte d'un changement de contact ";
// appel de l'utilitaire dans lesMaillages: avec mise à jour dans la foulée de l'assemblage
bool calcul_ok = lesMail->Renumerotation(*lesRef,tabCLL,nevez_largeurs,&nb_casAssemb,true);
if (calcul_ok) // cas où il y a eu effectivement un changement de numérotation
@ -968,7 +1104,15 @@ bool Algori::Gestion_stockage_et_renumerotation_sans_contact(LesContacts* lesco
,LesCondLim* lesCondLim,LesReferences* lesRef
,Tableau <Mat_abstraite* >& tab_mato,const Nb_assemb& nb_casAssemb
,int niveau_substitution)
{ TroisEntiers nevez_largeurs;
{
#ifdef UTILISATION_MPI
// cas d'un calcul //, seule la (ou les) matrices du CPU 0 sont concernées
// donc s'il s'agit d'un CPU différent, on revient immédiatement
if (ParaGlob::Monde()->rank() != 0)
return false;
#endif
TroisEntiers nevez_largeurs;
bool retour = false; // init pas de changement a priori au niveau des matrices
if (premier_calcul)
{// si demandé, renumérotation des pointeurs d'assemblage
@ -976,8 +1120,8 @@ bool Algori::Gestion_stockage_et_renumerotation_sans_contact(LesContacts* lesco
{ // récup des connexions entre noeuds dues aux CLL externes
Tableau <Tableau <Condilineaire> > tabCLL(lesCondLim->ConnectionCLL(lesMail,lesRef));
// int tailtabCLL = tabCLL.Taille();tabCLL.Change_taille(tailtabCLL+1);
// tabCLL(tailtabCLL+1) = tabCondLine; // ajout de la partie contact
if (ParaGlob::NiveauImpression() >= 3)
// tabCLL(tailtabCLL+1) = listCondLine; // ajout de la partie contact
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 2))
cout << "\n -- renumerotation des pointeurs d'assemblage en tenant compte des CLL ";
// appel de l'utilitaire dans lesMaillages: avec mise à jour dans la foulée de l'assemblage
bool calcul_ok = lesMail->Renumerotation(*lesRef,tabCLL,nevez_largeurs,&nb_casAssemb,true);
@ -1001,7 +1145,7 @@ bool Algori::Gestion_stockage_et_renumerotation_sans_contact(LesContacts* lesco
{ // récup des connexions entre noeuds dues aux CLL externes: comme les cll ont été mises à jour
// on récupère directement le tableau
Tableau <Tableau <Condilineaire> > tabCLL(lesCondLim->Tab_CLinApplique());
if (ParaGlob::NiveauImpression() >= 3)
if ( ((permet_affichage==0) && (ParaGlob::NiveauImpression() > 2)) || (permet_affichage > 2))
cout << "\n -- renumerotation des pointeurs d'assemblage en tenant compte des CLL ";
// appel de l'utilitaire dans lesMaillages: avec mise à jour dans la foulée de l'assemblage
bool calcul_ok = lesMail->Renumerotation(*lesRef,tabCLL,nevez_largeurs,&nb_casAssemb,true);
@ -1046,7 +1190,8 @@ void Algori::Cal_Transfert_delta_et_var_X(double& max_delta_X, double& max_var_d
Algori* Algori::New_Agori(EnumTypeCalcul id_TypeCalcul,const bool avec_typeDeCalcul
,const list <EnumSousTypeCalcul>& soustype
,const list <bool>& avec_soustypeDeCalcul
,UtilLecture& entreePrinc)
,UtilLecture& entreePrinc
)
{ // définition du pointeur de retour
Algori* algo_specifique;
@ -1149,7 +1294,8 @@ Tableau <Algori *> Algori::New_tous_les_Algo
,UtilLecture& entreePrinc)
{ // définition du tableau de pointeurs de retour
Tableau <Algori* > tab_algo_specifique(15);
// la méthode ne doit pas fonctionner dans le cas d'un calcul //
#ifndef UTILISATION_MPI
tab_algo_specifique(1) = new AlgoriNonDyna
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
tab_algo_specifique(2) = new ImpliNonDynaCont
@ -1180,7 +1326,214 @@ Tableau <Algori *> Algori::New_tous_les_Algo
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
tab_algo_specifique(15) = new AlgoriCombine
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
#else
// c'est une erreur
cout << "\n *** erreur: la methode Algori::New_tous_les_Algo n'est pas prevu "
<< " pour fonctionner en calcul parallele, veuillez utiliser la version "
<< " mono processeur! "<< endl;
Sortie(1);
#endif
return tab_algo_specifique;
};
#ifdef UTILISATION_MPI
// cas d'un calcul parallèle, passage des indicateurs
// calculés par le process 0 aux process de calcul
void Algori::Passage_indicConvergenceAuxProcCalcul()
{// seule le process 0 a fait la résolution globale
// il gère seul également la convergence, mais il doit tenir au courant les autres process
// on utilise un std::array pour passer en une fois les infos
temps_transfert_court_algo.Mise_en_route_du_comptage(); // comptage cpu
std::array<int,6> indic_convergence = {phase_de_convergence,nombre_de_bonnes_convergences
,nombre_de_mauvaises_convergences,a_converge
,a_converge_iterMoins1,nb_cycle_test_max_var_residu
};
broadcast(*ParaGlob::Monde(), indic_convergence, 0);
// ParaGlob::Monde()->barrier();
if (ParaGlob::Monde()->rank() != 0)
// on récupère les grandeurs
{phase_de_convergence = indic_convergence[0];
nombre_de_bonnes_convergences = indic_convergence[1];
nombre_de_mauvaises_convergences = indic_convergence[2];
a_converge = indic_convergence[3];
a_converge_iterMoins1 = indic_convergence[4];
nb_cycle_test_max_var_residu = indic_convergence[5];
};
temps_transfert_court_algo.Arret_du_comptage(); // fin comptage cpu
};
// globalisation des grandeurs globales: proc de calcul -> maitre puis transmission à ParaGlob
// et transmission aux proc de calcul:
// on ne demande pas à ParaGlob de faire la transmission, car il ne sait pas ce qu'il transmet
// et les infos ne sont pas contigües, le transfert ne sera pas performant
void Algori::Globalisation_et_transfert_auxProcCalcul_grandeurs_globales()
{ // on s'occupe tout d'abord des grandeurs directement gérées par Algori
Vecteur inter(10); // vecteur de passage
// inter(1) =
// ENERGIE_CINETIQUE -> inter(1)
// ENERGIE_EXTERNE -> 2
// ENERGIE_INTERNE -> 3
// PUISSANCE_ACCELERATION);
// PUISSANCE_INTERNE);
// PUISSANCE_EXTERNE);
// PUISSANCE_BILAN);
// ENERGIE_ELASTIQUE);
// ENERGIE_PLASTIQUE);
// ENERGIE_VISQUEUSE);
// ENERGIE_BILAN);
// QUANTITE_MOUVEMENT);
// ENERGIE_PENALISATION);
// ENERGIE_FROT_ELAST);
// ENERGIE_FROT_PLAST);
// ENERGIE_FROT_VISQ);
// ENERGIE_VISCO_NUMERIQUE);
// ENERGIE_BULK_VISCOSITY);
// ENERGIE_HOURGLASS_);
// ENERGIE_STABILISATION_MEMB_BIEL);
// VOLUME_TOTAL_MATIERE);
// MAXPUISSEXT);
// MAXPUISSINT);
// MAXREACTION);
// MAXRESIDUGLOBAL);
// MAXdeltaX);
// MAXvarDeltaX);
// MAXvarDdl);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_CINETIQUE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_EXTERNE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_INTERNE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,PUISSANCE_ACCELERATION);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,PUISSANCE_INTERNE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,PUISSANCE_EXTERNE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,PUISSANCE_BILAN);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_ELASTIQUE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_PLASTIQUE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_VISQUEUSE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_BILAN);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,QUANTITE_MOUVEMENT);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_PENALISATION);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_FROT_ELAST);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_FROT_PLAST);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_FROT_VISQ);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_VISCO_NUMERIQUE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_BULK_VISCOSITY);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_HOURGLASS_);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,ENERGIE_STABILISATION_MEMB_BIEL);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,VOLUME_TOTAL_MATIERE);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,MAXPUISSEXT);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,MAXPUISSINT);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,MAXREACTION);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,MAXRESIDUGLOBAL);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,MAXdeltaX);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,MAXvarDeltaX);
// ParaGlob::param->Ajout_grandeur_consultable(&typQ1,MAXvarDdl);
};
// cas d'un calcul parallèle, passage des énergies, volumes
// a priori utilisée dans le calcul de raideur et second membres
void Algori::Passage_energiesEtVolumes()
{ mpi::request reqs1;
bool premier_passage = true;
// récupération de toutes les énergies par le cpu 0
// on dit à tous les process d'attendre sauf le master
////------------- debug --------
//cout << "\n debug Algori::Passage_energiesEtVolumes() "
// << "\n barriere avant transfert énergies , proc= "<< ParaGlob::Monde()->rank() << flush;
//
////------------- fin debug --------
// ParaGlob::Monde()->barrier(); // synchronisation ici de tous les process
// on crée un vecteur intermédiaire pour le passage d'information
int dim_tav_double = 0;int tail_tab = vol_total2D_avec_plan_ref.Taille();
for (int i=1;i<= tail_tab;i++)
dim_tav_double += vol_total2D_avec_plan_ref(i).Dimension();
Vecteur v_val_inter(8+dim_tav_double);
int num_process = ParaGlob::Monde()->rank();
if (num_process != 0)
{temps_transfert_court_matSm.Mise_en_route_du_comptage(); // comptage cpu
//on rempli le vecteur de passage
v_val_inter(1) =energTotal.EnergieElastique();
v_val_inter(2) =energTotal.DissipationPlastique();
v_val_inter(3) =energTotal.DissipationVisqueuse();
v_val_inter(4)=energHourglass;
v_val_inter(5)=energStabiliMembBiel;
v_val_inter(6)=E_bulk;
v_val_inter(7)=P_bulk;
v_val_inter(8)=volume_total_matiere;
int indice = 1;
for (int i=1;i<= tail_tab;i++)
{ int dim_coord = vol_total2D_avec_plan_ref(i).Dimension();
if (dim_coord)
for (int j=1;j<= dim_coord;j++,indice++)
v_val_inter(8+indice)=vol_total2D_avec_plan_ref(i)(j);
};
// //------------- debug --------
// cout << "\n debug Algori::Passage_energiesEtVolumes() num_process= "<< num_process;
// cout << "\n v_val_inter= "<<v_val_inter;
//
// //------------- fin debug --------
temps_transfert_court_matSm.Arret_du_comptage();
// on récupère un signal du process 0
temps_attente_matSm.Mise_en_route_du_comptage(); // comptage cpu
if (premier_passage) {premier_passage = false;}
else // on attend que les transferts soient finis
{reqs1.wait();
};
temps_attente_matSm.Arret_du_comptage(); // fin comptage cpu
temps_transfert_court_matSm.Mise_en_route_du_comptage(); // comptage cpu
// on transmet le vecteur intermédiaire
reqs1 = v_val_inter.Ienvoi_MPI(0,27);
temps_transfert_court_matSm.Arret_du_comptage(); // fin comptage cpu
}
else // cas du proocess 0
{int nb_process = ParaGlob::Monde()->size();
for (int i=1;i<nb_process;i++) // < absolu, donc le max c'est nb_process-1
{temps_transfert_court_matSm.Mise_en_route_du_comptage(); // comptage cpu
reqs1 = v_val_inter.Irecup_MPI(mpi::any_source, 27);
temps_transfert_court_matSm.Arret_du_comptage(); // fin comptage cpu
temps_attente_matSm.Mise_en_route_du_comptage(); // comptage cpu
reqs1.wait(); // on attend que le conteneur soit rempli
temps_attente_matSm.Arret_du_comptage(); // fin comptage cpu
temps_transfert_court_matSm.Mise_en_route_du_comptage(); // comptage cpu
//on récupère les info via le vecteur de passage
EnergieMeca inter(v_val_inter(1),v_val_inter(2),v_val_inter(3));
energTotal += inter;
energHourglass += v_val_inter(4);
energStabiliMembBiel += v_val_inter(5);
E_bulk += v_val_inter(6);
P_bulk += v_val_inter(7);
volume_total_matiere += v_val_inter(8);
int indice = 1;
for (int i=1;i<= tail_tab;i++)
{ int dim_coord = vol_total2D_avec_plan_ref(i).Dimension();
if (dim_coord)
for (int j=1;j<= dim_coord;j++,indice++)
vol_total2D_avec_plan_ref(i)(j) += v_val_inter(8+indice);
};
temps_transfert_court_matSm.Arret_du_comptage(); // fin comptage cpu
};
};
////------------- debug --------
//cout << "\n debug Algori::Passage_energiesEtVolumes() ";
//cout << "\n energTotal "<<energTotal
// << " volume_total_matiere "<< volume_total_matiere;
//
////------------- fin debug --------
};
#endif

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -90,6 +90,7 @@ class AlgoInformations : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoInformations* inter = (AlgoInformations*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -522,7 +522,7 @@ void AlgoUmatAbaqus::Calcul_Umat(ParaGlob * paraGlob,LesMaillages * lesMail,
void AlgoUmatAbaqus::Ecrit_Base_info_Parametre(UtilLecture& entreePrinc,const int& cas)
{
// récup du flot
ofstream * sort = entreePrinc.Sort_BI();
// ofstream * sort = entreePrinc.Sort_BI();
// (*sort) << "\n parametres_algo_specifiques_ "<< Nom_TypeCalcul(this->TypeDeCalcul());
// ecriture: rien pour l'instant
// if (cas == 1)
@ -542,7 +542,7 @@ void AlgoUmatAbaqus::Lecture_Base_info_Parametre(UtilLecture& entreePrinc,const
{if (choix)
{// cas d'une lecture normale
// récup du flot
ifstream * ent = entreePrinc.Ent_BI();
// ifstream * ent = entreePrinc.Ent_BI();
// pour l'instant on ne lit rien
}
}

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -91,10 +91,13 @@ void AlgoUtils::Execution(ParaGlob * p,LesMaillages * lesMail
// on vérifie que les noeuds sont bien attachés à un élément sinon on met un warning si niveau > 2
if (ParaGlob::NiveauImpression() > 2)
lesMail->AffichageNoeudNonReferencer();
// definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// dans le cas d'un contact éventuel on initialise les frontières et la répartition esclave et maître
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
if (lesContacts->Init_contact_pas_effectue())
{// initialisation des zones de contacts éventuelles

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -94,6 +94,7 @@ class AlgoUtils : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoUtils* inter = (AlgoUtils*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -244,7 +244,7 @@ void AlgoriCombine::Execution(ParaGlob * paraGlob,LesMaillages * lesMail
};// fin du cas sans commandes interactives
// ensuite on teste en fonction des calculs complémentaires
// dépendant des sous_types. Pour l'instant ici uniquement la remontée
list <EnumSousTypeCalcul>::const_iterator ili,ili_fin = soustypeDeCalcul->end();
list <EnumSousTypeCalcul>::const_iterator ili,ili_fin = soustypeDeCalcul->end();
list <bool>::const_iterator ila;
for (ili = soustypeDeCalcul->begin(),ila = avec_soustypeDeCalcul->begin();
ili!=ili_fin;ili++,ila++)
@ -316,7 +316,7 @@ void AlgoriCombine::lecture_Parametres(UtilLecture& entreePrinc)
while ( !motCle.SimotCle(entreePrinc.tablcar)) ;
// si le mot clé est "PARA_TYPE_DE_CALCUL" cela signifie
// qu'il y a un paramètre à lire
bool lecture_effective = false;
// bool lecture_effective = false;
if (strstr(entreePrinc.tablcar,"PARA_TYPE_DE_CALCUL")!=NULL)
{ //cas de la définition de paramètres
// on signale à Algori qu'il y a eu déjà une lecture de paramètre
@ -846,7 +846,8 @@ void AlgoriCombine::Lecture_algo_interne(const bool avec_typeDeCal
string nom_class_methode("AlgoriCombine::Lecture_algo_interne(..."); // pour info lecture
// on passe le mot clé de début de liste
string mot_cle = "liste_algorithmes_a_combiner_";
bool lec_eff = entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
// bool lec_eff = entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
entreePrinc.Lecture_et_verif_mot_cle(nom_class_methode,mot_cle);
list < Algori * > list_algori_inter; // une liste de travail pour la lecture
// maintenant on va lire chaque algorithme
entreePrinc.NouvelleDonnee();
@ -924,6 +925,16 @@ void AlgoriCombine::AutreSortieTempsCPU(ofstream& sort,const int ) const
// Temps_CPU_HZpp temps_metrique_K_SM; // lesTempsCpu(14)
// Temps_CPU_HZpp temps_chargement; // lesTempsCpu(15)
// Temps_CPU_HZpp temps_rech_contact; // lesTempsCpu(16)
// cas d'un calcul parallèle: // passage des infos entre process
// Temps_CPU_HZpp temps_transfert_court ; // lesTempsCpu(17)
// Temps_CPU_HZpp temps_transfert_long ; // lesTempsCpu(18)
// Temps_CPU_HZpp temps_attente ; // lesTempsCpu(19)
// Temps_CPU_HZpp temps_transfert_court_charge ; // lesTempsCpu(20)
// Temps_CPU_HZpp temps_transfert_long_charge ; // lesTempsCpu(21)
// Temps_CPU_HZpp temps_attente_charge ; // lesTempsCpu(22)
// Temps_CPU_HZpp temps_transfert_court_contact ; // lesTempsCpu(23)
// Temps_CPU_HZpp temps_transfert_long_contact ; // lesTempsCpu(24)
// Temps_CPU_HZpp temps_attente_contact ; // lesTempsCpu(25)
sort << "\n tps_InitAlgo " << lesTsCpu(1);
sort << "\n tps_MiseAJourAlgo "<< lesTsCpu(2);
sort << "\n tps_CalEquilibre "<< lesTsCpu(3);

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -94,6 +94,7 @@ class AlgoriCombine : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoriCombine* inter = (AlgoriCombine*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -47,7 +47,19 @@ void AlgoriCombine::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(COMBINER); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
// on s'occupe des fonctions nD de pilotage
// 1) cas de choix_algo
if ((nom_choix_algo.length()) && (choix_algo == NULL))
@ -117,6 +129,13 @@ void AlgoriCombine::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
int nb_algo = tab_algo.Taille();
for (int i=1;i<=nb_algo;i++)
{ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
tab_algo(i)->InitAlgorithme(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor
,lesLoisDeComp,diversStockage,charge,lesCondLim,lesContacts,resultats);
@ -170,6 +189,13 @@ void AlgoriCombine::MiseAJourAlgo(ParaGlob * paraGlob,LesMaillages * lesMail,
int nb_algo = tab_algo.Taille();
for (int i=1;i<=nb_algo;i++)
{ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
tab_algo(i)->MiseAJourAlgo(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor
,lesLoisDeComp,diversStockage,charge,lesCondLim,lesContacts,resultats);
@ -241,6 +267,14 @@ void AlgoriCombine::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// << "\n tab_algo(3)->pa.Deltat()= " << tab_algo(3)->pa.Deltat() << flush;
// //--- fin debug
ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
bool aff_incr=pa.Vrai_commande_sortie(icharge,temps_derniere_sauvegarde); // pour simplifier
if (aff_incr)
@ -306,6 +340,14 @@ void AlgoriCombine::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
if ((i >0)&&(i <= nb_algo))
{// on met à jour
ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
bool aff_incr=pa.Vrai_commande_sortie(icharge,temps_derniere_sauvegarde); // pour simplifier
if (aff_incr)
@ -374,10 +416,18 @@ void AlgoriCombine::FinCalcul(ParaGlob * paraGlob,LesMaillages * lesMail,LesRefe
// // on passe en revue tous les algorithmes et on demande la fin des calculs
// non, sinon on a plusieurs dernières sauvegardes !!
// donc on ne sauvegarde la fin que via le dernier sous_algo qui a sauvegardé
int nb_algo = tab_algo.Taille();
// int nb_algo = tab_algo.Taille();
// for (int i=1;i<=nb_algo;i++)
int i=nb_dernier_algo_qui_a_fait_une_sauvegarde;
{ParaGlob::param->Change_ParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
#ifdef UTILISATION_MPI
// passage de l'équilibrage à ParaGlob
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
#endif
charge->ChangeParaAlgoControle(tab_algo(i)->ParaAlgoControle_de_lalgo());
tab_algo(i)->FinCalcul(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,varExpor
,lesLoisDeComp,diversStockage,charge,lesCondLim,lesContacts,resultats);

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -957,7 +957,19 @@ void AlgoriRungeKutta::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_RUNGE_KUTTA); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
// avant toute chose, au cas où l'algo interviendrait après un autre algo
// on inactive tous les ddl existants
lesMail->Inactive_ddl();
@ -1092,6 +1104,10 @@ void AlgoriRungeKutta::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
// initialisation du compteur d'increments de charge
icharge = 0;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -1099,7 +1115,6 @@ void AlgoriRungeKutta::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -1108,6 +1123,7 @@ void AlgoriRungeKutta::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
// definition des elements de contact eventuels
lesContacts->DefElemCont(0.); // au début le déplacement des noeuds est nul
};
//--cas de restart et/ou de sauvegarde------------
// tout d'abord récup du restart si nécessaire
// dans le cas ou un incrément différent de 0 est demandé -> seconde lecture à l'incrément
@ -1129,7 +1145,7 @@ void AlgoriRungeKutta::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -1169,9 +1185,6 @@ void AlgoriRungeKutta::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
}
}
//--fin cas de restart et/ou de sauvegarde--------
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// ajout d'un conteneur pour les coordonnées à l'itération 0
{Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -89,6 +89,7 @@ class AlgoriRungeKutta : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoriRungeKutta* inter = (AlgoriRungeKutta*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -288,6 +288,9 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// cas du chargement, on verifie egalement la bonne adequation des references
charge->Initialise(lesMail,lesRef,pa,*lesCourbes1D,*lesFonctionsnD);
// on indique que l'on ne souhaite pas le temps fin stricte
@ -392,6 +395,10 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
// initialisation du compteur d'increments de charge
icharge = 1;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -399,7 +406,6 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -430,7 +436,7 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -542,10 +548,10 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
double maxPuissInt; // maxi de la puissance des efforts internes
double maxReaction; // maxi des reactions
int inReaction = 0; // pointeur d'assemblage pour le maxi de reaction
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
// double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t
@ -749,9 +755,9 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -773,7 +779,7 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
@ -866,7 +872,7 @@ void AlgoriDynaExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
Algori::TdtversT();
if (pa.ContactType())
{ // actualisation des éléments de contact et éventuellement inactivation d'éléments
lesContacts->Actualisation(); // si on n'a plus de projection
lesContacts->Actualisation(0); // si on n'a plus de projection
// on inactive les éléments de contact qui se relache: testé soit via la réaction
lesContacts->RelachementNoeudcolle(); // ou via la sortie d'une zone d'accostage (dépend de l'algo)
};

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -93,6 +93,7 @@ class AlgoriDynaExpli : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoriDynaExpli* inter = (AlgoriDynaExpli*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -43,6 +43,8 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// cas du chargement, on verifie egalement la bonne adequation des references
charge->Initialise(lesMail,lesRef,pa,*lesCourbes1D,*lesFonctionsnD);
// on indique que l'on ne souhaite pas le temps fin stricte
@ -148,6 +150,10 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
// au premier passage il y a un traitement spécial: pas d'incrémentation du temps, pas de sauvegarde
// in s'agit d'un incrément de mise en place, l'équilibre se faisant à la fin
icharge = 0;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -155,7 +161,6 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -188,7 +193,7 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -304,10 +309,10 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
double maxPuissInt; // maxi de la puissance des efforts internes
double maxReaction; // maxi des reactions
int inReaction = 0; // pointeur d'assemblage pour le maxi de reaction
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
// double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t
@ -531,9 +536,9 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -555,7 +560,7 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
@ -653,7 +658,7 @@ void AlgoriDynaExpli::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMa
// actualisation des éléments de contact et éventuellement suppression
if (pa.ContactType())
{ // actualisation des éléments de contact et éventuellement inactivation d'éléments
lesContacts->Actualisation(); // si on n'a plus de projection
lesContacts->Actualisation(0); // si on n'a plus de projection
// on inactive les éléments de contact qui se relache: testé soit via la réaction
lesContacts->RelachementNoeudcolle(); // ou via la sortie d'une zone d'accostage (dépend de l'algo)
};
@ -794,7 +799,19 @@ void AlgoriDynaExpli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
// avant toute chose, au cas où l'algo interviendrait après un autre algo
// on inactive tous les ddl existants
lesMail->Inactive_ddl();
@ -927,6 +944,10 @@ void AlgoriDynaExpli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// in s'agit d'un incrément de mise en place, l'équilibre se faisant à la fin
compteur_demarrage = 0; // pas vraiment utile, car sera redéfini dans CalEquilibre
icharge = 0;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -934,7 +955,6 @@ void AlgoriDynaExpli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -943,6 +963,7 @@ void AlgoriDynaExpli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// definition des elements de contact eventuels
lesContacts->DefElemCont(0.); // au début le déplacement des noeuds est nul
};
//--cas de restart et/ou de sauvegarde------------
// tout d'abord récup du restart si nécessaire
// dans le cas ou un incrément différent de 0 est demandé -> seconde lecture à l'incrément
@ -964,7 +985,7 @@ void AlgoriDynaExpli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -1004,9 +1025,6 @@ void AlgoriDynaExpli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
}
};
//--fin cas de restart et/ou de sauvegarde--------
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// ajout d'un conteneur pour les coordonnées à l'itération 0
{Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique
@ -1119,8 +1137,12 @@ void AlgoriDynaExpli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
{
tempsCalEquilibre.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// récup des entités
Assemblage& Ass1 = *Ass1_;Assemblage& Ass2 = *Ass2_;Assemblage& Ass3 = *Ass3_;
Assemblage& Ass1 = *Ass1_;
// Assemblage& Ass2 = *Ass2_;
Assemblage& Ass3 = *Ass3_;
// préparation pour les aspects validation du calcul et sortie contrôlée des incréments
int validation_calcul = 1; // init : par défaut la validation est effective si le calcul converge
@ -1135,7 +1157,7 @@ void AlgoriDynaExpli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
bool arret=false; // booleen pour arrêter indépendamment de la charge
bool premier_calcul = true; // utilisé pour le contact
icharge++; // on incrémente le chargement -> donne le num d'incr du prochain incr chargé
int icharge_precedent = icharge; // pour se souvenir du précédent icharge, ne sert que pour l'initialisation
// int icharge_precedent = icharge; // pour se souvenir du précédent icharge, ne sert que pour l'initialisation
// au premier passage il y a un traitement spécial: pas d'incrémentation du temps, pas de sauvegarde
compteur_demarrage=0; // donc compteur pour les premiers incréments
double max_delta_X=0.; // le maxi du delta X
@ -1149,10 +1171,10 @@ void AlgoriDynaExpli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
double maxPuissInt; // maxi de la puissance des efforts internes
double maxReaction; // maxi des reactions
int inReaction = 0; // pointeur d'assemblage pour le maxi de reaction
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
// double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t
@ -1232,7 +1254,7 @@ void AlgoriDynaExpli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
{lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_tdt);
if (pa.ContactType()==4) // dans le cas d'un contact de type 4
// on actualise évenuellement la position des noeuds esclaves sur la surface maître
lesContacts->Actualisation();
lesContacts->Actualisation(0);
};
// dans le cas ou il y a changement de statut il faut remettre à jour
@ -1399,9 +1421,9 @@ void AlgoriDynaExpli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if ((pa.ContactType())&&(compteur_demarrage > 0))
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -1424,7 +1446,7 @@ void AlgoriDynaExpli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if ((pa.ContactType()==1)&&(compteur_demarrage > 0)) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
// ***donc pour l'instant du a un bug je commente
@ -1538,7 +1560,7 @@ void AlgoriDynaExpli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
if (compteur_demarrage != 0) Algori::TdtversT();
if ((pa.ContactType())&&(compteur_demarrage > 0))
{ // actualisation des éléments de contact et éventuellement inactivation d'éléments
lesContacts->Actualisation(); // si on n'a plus de projection
lesContacts->Actualisation(0); // si on n'a plus de projection
// on inactive les éléments de contact qui se relache: testé soit via la réaction
lesContacts->RelachementNoeudcolle(); // ou via la sortie d'une zone d'accostage (dépend de l'algo)
};

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -290,7 +290,19 @@ void AlgoriDynaExpli_zhai::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * les
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_ZHAI); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
// avant toute chose, au cas où l'algo interviendrait après un autre algo
// on inactive tous les ddl existants
lesMail->Inactive_ddl();
@ -422,6 +434,10 @@ void AlgoriDynaExpli_zhai::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * les
// initialisation du compteur d'increments de charge
icharge = 0;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -429,7 +445,6 @@ void AlgoriDynaExpli_zhai::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * les
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -438,6 +453,7 @@ void AlgoriDynaExpli_zhai::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * les
// definition des elements de contact eventuels
lesContacts->DefElemCont(0.); // au début le déplacement des noeuds est nul
};
//--cas de restart et/ou de sauvegarde------------
// tout d'abord récup du restart si nécessaire
// dans le cas ou un incrément différent de 0 est demandé -> seconde lecture à l'incrément
@ -459,7 +475,7 @@ void AlgoriDynaExpli_zhai::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * les
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -499,9 +515,6 @@ void AlgoriDynaExpli_zhai::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * les
}
};
//--fin cas de restart et/ou de sauvegarde--------
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// ajout d'un conteneur pour les coordonnées à l'itération 0
{Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique
@ -610,8 +623,11 @@ void AlgoriDynaExpli_zhai::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMa
{
tempsCalEquilibre.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_ZHAI); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// récup des entités
Assemblage& Ass1 = *Ass1_;Assemblage& Ass2 = *Ass2_;Assemblage& Ass3 = *Ass3_;
Assemblage& Ass1 = *Ass1_;//Assemblage& Ass2 = *Ass2_;
Assemblage& Ass3 = *Ass3_;
// préparation pour les aspects validation du calcul et sortie contrôlée des incréments
int validation_calcul = 1; // init : par défaut la validation est effective si le calcul converge
@ -628,7 +644,7 @@ void AlgoriDynaExpli_zhai::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMa
bool arret=false; // booleen pour arrêter indépendamment de la charge
bool premier_calcul = true; // utilisé pour le contact
icharge++; // on incrémente le chargement -> donne le num d'incr du prochain incr chargé
int icharge_precedent = icharge; // pour se souvenir du précédent icharge, ne sert que pour l'initialisation
// int icharge_precedent = icharge; // pour se souvenir du précédent icharge, ne sert que pour l'initialisation
while (((!charge->Fin(icharge))||(icharge == 1))
&& (charge->Fin(icharge,true)!=2) // si on a dépassé le nombre d'incrément permis on s'arrête dans tous les cas
&& (charge->Fin(icharge,false)!=3) // idem si on a dépassé le nombre d'essai d'incrément permis
@ -640,10 +656,10 @@ void AlgoriDynaExpli_zhai::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMa
double maxPuissInt; // maxi de la puissance des efforts internes
double maxReaction; // maxi des reactions
int inReaction = 0; // pointeur d'assemblage pour le maxi de reaction
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
// double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t
@ -867,9 +883,9 @@ void AlgoriDynaExpli_zhai::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMa
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -892,7 +908,7 @@ void AlgoriDynaExpli_zhai::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMa
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,(vglobaal),Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,(vglobaal),*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,(vglobaal),*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
// ***donc pour l'instant du a un bug je commente
@ -1003,7 +1019,7 @@ void AlgoriDynaExpli_zhai::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMa
if (pa.ContactType())
{ // actualisation des éléments de contact et éventuellement inactivation d'éléments
lesContacts->Actualisation(); // si on n'a plus de projection
lesContacts->Actualisation(0); // si on n'a plus de projection
// on inactive les éléments de contact qui se relache: testé soit via la réaction
lesContacts->RelachementNoeudcolle(); // ou via la sortie d'une zone d'accostage (dépend de l'algo)
};
@ -1084,6 +1100,8 @@ void AlgoriDynaExpli_zhai::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * l
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_ZHAI); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// cas du chargement, on verifie egalement la bonne adequation des references
charge->Initialise(lesMail,lesRef,pa,*lesCourbes1D,*lesFonctionsnD);
// on indique que l'on ne souhaite pas le temps fin stricte
@ -1188,6 +1206,10 @@ void AlgoriDynaExpli_zhai::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * l
// initialisation du compteur d'increments de charge
icharge = 1;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -1195,7 +1217,6 @@ void AlgoriDynaExpli_zhai::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * l
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -1335,10 +1356,10 @@ void AlgoriDynaExpli_zhai::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * l
double maxPuissInt; // maxi de la puissance des efforts internes
double maxReaction; // maxi des reactions
int inReaction = 0; // pointeur d'assemblage pour le maxi de reaction
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
// double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -94,6 +94,7 @@ class AlgoriDynaExpli_zhai : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoriDynaExpli_zhai* inter = (AlgoriDynaExpli_zhai*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -280,6 +280,18 @@ void Algori_chung_lee::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_CHUNG_LEE); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
// avant toute chose, au cas où l'algo interviendrait après un autre algo
// on inactive tous les ddl existants
lesMail->Inactive_ddl();
@ -415,6 +427,10 @@ void Algori_chung_lee::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
// initialisation du compteur d'increments de charge
icharge = 0;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -422,7 +438,6 @@ void Algori_chung_lee::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -432,6 +447,7 @@ void Algori_chung_lee::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
// definition des elements de contact eventuels
lesContacts->DefElemCont(0.); // au début le déplacement des noeuds est nul
};
//--cas de restart et/ou de sauvegarde------------
// tout d'abord récup du restart si nécessaire
// dans le cas ou un incrément différent de 0 est demandé -> seconde lecture à l'incrément
@ -453,7 +469,7 @@ void Algori_chung_lee::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -493,9 +509,6 @@ void Algori_chung_lee::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail
}
};
//--fin cas de restart et/ou de sauvegarde--------
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// ajout d'un conteneur pour les coordonnées à l'itération 0
{Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique
@ -612,8 +625,11 @@ void Algori_chung_lee::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail,
{
tempsCalEquilibre.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_CHUNG_LEE); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// récup des entités
Assemblage& Ass1 = *Ass1_;Assemblage& Ass2 = *Ass2_;Assemblage& Ass3 = *Ass3_;
Assemblage& Ass1 = *Ass1_;//Assemblage& Ass2 = *Ass2_;
Assemblage& Ass3 = *Ass3_;
// préparation pour les aspects validation du calcul et sortie contrôlée des incréments
int validation_calcul = 1; // init : par défaut la validation est effective si le calcul converge
@ -630,7 +646,7 @@ void Algori_chung_lee::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail,
bool arret=false; // booleen pour arrêter indépendamment de la charge
bool premier_calcul = true; // utilisé pour le contact
icharge++; // on incrémente le chargement -> donne le num d'incr du prochain incr chargé
int icharge_precedent = icharge; // pour se souvenir du précédent icharge, ne sert que pour l'initialisation
// int icharge_precedent = icharge; // pour se souvenir du précédent icharge, ne sert que pour l'initialisation
while (((!charge->Fin(icharge))||(icharge == 1))
&& (charge->Fin(icharge,true)!=2) // si on a dépassé le nombre d'incrément permis on s'arrête dans tous les cas
&& (charge->Fin(icharge,false)!=3) // idem si on a dépassé le nombre d'essai d'incrément permis
@ -640,10 +656,10 @@ void Algori_chung_lee::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail,
double maxPuissInt; // maxi de la puissance des efforts internes
double maxReaction; // maxi des reactions
int inReaction = 0; // pointeur d'assemblage pour le maxi de reaction
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
// double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t
@ -713,7 +729,7 @@ void Algori_chung_lee::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail,
{lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_tdt);
if (pa.ContactType()==4) // dans le cas d'un contact de type 4
// on actualise évenuellement la position des noeuds esclaves sur la surface maître
lesContacts->Actualisation();
lesContacts->Actualisation(0);
};
// dans le cas ou il y a changement de statut il faut remettre à jour
@ -792,9 +808,9 @@ void Algori_chung_lee::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail,
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -817,7 +833,7 @@ void Algori_chung_lee::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail,
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
// ***donc pour l'instant du a un bug je commente
@ -996,7 +1012,7 @@ void Algori_chung_lee::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail,
Algori::TdtversT();
if (pa.ContactType())
{ // actualisation des éléments de contact et éventuellement inactivation d'éléments
lesContacts->Actualisation(); // si on n'a plus de projection
lesContacts->Actualisation(0); // si on n'a plus de projection
// on inactive les éléments de contact qui se relache: testé soit via la réaction
lesContacts->RelachementNoeudcolle(); // ou via la sortie d'une zone d'accostage (dépend de l'algo)
};
@ -1081,6 +1097,8 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_CHUNG_LEE); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// 000 --<C L>-- valeurs figées pour les paramètres de l'algorithme
const double betachapeau = 0.5 - (*beta_cl);
const double gammaa = 1.5; const double gammachapeau = 1.-gammaa;
@ -1183,10 +1201,13 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
F_int_tdt.Change_taille(nbddl_X); F_ext_tdt.Change_taille(nbddl_X); // forces généralisées int et ext au pas actuel
residu_final.Change_taille(nbddl_X); // pour la sauvegarde du résidu pour le post-traitement
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// cas avec contact potentiel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -1222,7 +1243,7 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -1342,10 +1363,10 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
double maxPuissInt; // maxi de la puissance des efforts internes
double maxReaction; // maxi des reactions
int inReaction = 0; // pointeur d'assemblage pour le maxi de reaction
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
// double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// gestion du pas de temps, vérif / pas critique
this->Gestion_pas_de_temps(false,lesMail,2); // 2 signifie cas courant
bool modif_temps = charge->Avance(); // avancement de la charge et donc du temps courant
@ -1379,7 +1400,7 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
{lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_tdt);
if (pa.ContactType()==4) // dans le cas d'un contact de type 4
// on actualise évenuellement la position des noeuds esclaves sur la surface maître
lesContacts->Actualisation();
lesContacts->Actualisation(0);
};
// mise en place des conditions linéaires
@ -1467,9 +1488,9 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -1490,7 +1511,7 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
@ -1665,7 +1686,7 @@ void Algori_chung_lee::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
Algori::TdtversT();
if (pa.ContactType())
{ // actualisation des éléments de contact et éventuellement inactivation d'éléments
lesContacts->Actualisation(); // si on n'a plus de projection
lesContacts->Actualisation(0); // si on n'a plus de projection
// on inactive les éléments de contact qui se relache: testé soit via la réaction
lesContacts->RelachementNoeudcolle(); // ou via la sortie d'une zone d'accostage (dépend de l'algo)
};

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -95,6 +95,7 @@ class Algori_chung_lee : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ Algori_chung_lee* inter = (Algori_chung_lee*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -1102,12 +1102,12 @@ void AlgoriRelaxDyna::Info_commande_parametres(UtilLecture& entreePrinc)
<< "\n # (ici apres la transition vers l'amortissement visqueux, option_recalcul_mass "
<< "\n # initialement a 0, passe à 3) "
<< "\n # "
<< "\n # typeCalRelaxation= 4 lambda= 0.6 type_calcul_mass= 2 option_recalcul_mass= 0 \ "
<< "\n # typeCalRelaxation= 4 lambda= 0.6 type_calcul_mass= 2 option_recalcul_mass= 0 \\ "
<< "\n # opt_visqueux_recal_mass= 3 "
<< "\n # parametre_calcul_de_la_masse_ casMass_relax= 3 "
<< "\n # proportion_cinetique= 0.1 "
<< "\n # parametre_recalcul_de_la_masse_ ncycle_calcul= 100 et_pas_recalcul_masse_a_la_transition_"
<< "\n # parametre_calcul_de_la_viscosite_ type_calcul_visqu_critique= 2 \ "
<< "\n # parametre_calcul_de_la_viscosite_ type_calcul_visqu_critique= 2 \\ "
<< "\n # opt_cal_C_critique= 1 f_= 0.9 "
<< "\n # mode_debug_= 100 "
<< "\n # "
@ -1311,7 +1311,23 @@ void AlgoriRelaxDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(RELAX_DYNA); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
tempsInitialisation.Arret_du_comptage(); // temps cpu
temps_transfert_court_algo.Mise_en_route_du_comptage(); // comptage cpu
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
temps_transfert_court_algo.Arret_du_comptage(); // comptage cpu
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
// avant toute chose, au cas où l'algo interviendrait après un autre algo
// on inactive tous les ddl existants
lesMail->Inactive_ddl();
@ -1452,6 +1468,10 @@ void AlgoriRelaxDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
compteur_demarrage = -1; // pas vraiment utile, car sera redéfini dans CalEquilibre
icharge = 0; // par défaut
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -1459,7 +1479,6 @@ void AlgoriRelaxDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t); //
// initialisation des zones de contacts éventuelles
lescontacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -1499,7 +1518,7 @@ void AlgoriRelaxDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
////--debug
@ -1545,9 +1564,6 @@ void AlgoriRelaxDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
}
};
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// ajout d'un conteneur pour les coordonnées à l'itération 0
{Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique
Grandeur_coordonnee gt(coor); // une grandeur typique de type Grandeur_coordonnee
@ -1564,11 +1580,19 @@ void AlgoriRelaxDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// choix de la matrice de masse, qui est en fait celle qui correspond au ddl Xi
// ici le numéro d'assemblage est celui de X car on projette bien sur des vitesses virtuelles c-a-d ddl X*.
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la sortie
if (ParaGlob::Monde()->rank() == 0)
#endif
if (ParaGlob::NiveauImpression() > 2)
cout << "\n matrice masse principale: ";
mat_masse = Choix_matrice_masse(nbddl_X,mat_masse,lesMail,lesRef
,Ass1.Nb_cas_assemb(),lescontacts,lesCondLim);
if (ParaGlob::NiveauImpression() > 2)
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la sortie
if (ParaGlob::Monde()->rank() == 0)
#endif
if (ParaGlob::NiveauImpression() > 2)
cout << "\n matrice masse secondaire: ";
mat_masse_sauve = Choix_matrice_masse(nbddl_X,mat_masse_sauve,lesMail,lesRef
,Ass1.Nb_cas_assemb(),lescontacts,lesCondLim);
@ -1825,7 +1849,11 @@ Vecteur V_ext(F_int_tdt);
// def d'un type quelconque représentatif pour un vecteur force à chaque noeud
TypeQuelconque typQ_gene_int(FORCE_GENE_INT,X1,gt);
// on définit un type générique qui sert pour passer aux noeuds les positions à l'itération 0
TypeQuelconque typQ_XI_ITER_0(XI_ITER_0,X1,gt);
bool arret=false; // booleen pour arrêter indépendamment de la charge
bool arret_pilotage=false; // pour arrêt du calcul au niveau du pilotage
bool premier_calcul = true; // utilisé pour l'initialisation de l'incrément avec le pas précédent
int indicCycleContact = 0; // def d'un indicateur donnant la situation dans le cycle de contact
// un booléen pour uniquement gérer le fait que dans la boucle globale on fait le test après le test du while
@ -1838,9 +1866,10 @@ Vecteur V_ext(F_int_tdt);
// que si on a eu convergence
|| pas_de_convergence_pour_l_instant ||(compteur_demarrage <= 1)
)
&& (charge->Fin(icharge,true)!=1) // si on a dépassé le temps fin on s'arrête
// si on a dépassé le nombre d'incrément permis on s'arrête dans tous les cas
&& ((compteur_demarrage < 1)? (charge->Fin(icharge,false)!=2) : (charge->Fin(icharge,true)!=2))
&& (charge->Fin(icharge,false)!=3) // idem si on a dépassé le nombre d'essai d'incrément permis
&& (charge->Fin(icharge,true)!=3) // idem si on a dépassé le nombre d'essai d'incrément permis
// 1er appel avec true: pour affichage et second avec false car c'est déjà affiché
&& (!pa.EtatSortieEquilibreGlobal())
)
@ -1865,6 +1894,19 @@ Vecteur V_ext(F_int_tdt);
// bilan: on traite différamment selon que c'est le premier passage le second et les autres
bool aff_incr = true; // par défaut, est ensuite renseigné dans le switch qui suit
bool change_statut = false; // init des changements de statut
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t
// comme on est au début de l'incrément, la géométrie à tdt est identique à celle à t
// sauf "au premier incrément", si l'algo est un sous algo d'un algo combiné
// et que l'on suit un précédent algo sur un même pas de temps
// qui a aboutit à une géométrie à tdt différente de celle de t
// du coup cela permet d'utiliser la nouvelle géométrie pour ce premier incrément
lesMail->MiseAjourNormaleAuxNoeuds_de_tdt_vers_T();
// passage aux noeuds des vecteurs globaux: F_INT, F_EXT
Algori::Passage_aux_noeuds_F_int_t_et_F_ext_t(lesMail);
// qui, pour provoquer un arrêt de la boucle sur les incrément
switch (compteur_demarrage)
{case -1:
{// gestion du pas de temps, mis transitoirement à 0
@ -1882,12 +1924,17 @@ Vecteur V_ext(F_int_tdt);
this->Gestion_pas_de_temps(false,lesMail,2); // 2 signifie cas courant
if (!indicCycleContact) // modification de la charge et du pas de temps qu'au premier passage
// mais pas après un changement de statut
{ bool modif_temps = Pilotage_du_temps(charge,arret); // appel du Pilotage
{ bool modif_temps = Pilotage_du_temps(charge,arret_pilotage); // appel du Pilotage
//-- si le temps a changé il faut de nouveau appeler la gestion du pas de temps
// car il y a des grandeurs reliées au pas de temps qui y sont calculé
if (modif_temps)
this->Gestion_pas_de_temps(true,lesMail,2); // 2 signifie cas courant
if (arret) break; // pilotage -> arret du calcul
if (arret_pilotage) break; // pilotage -> arret du calcul, on sort du switch
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la sortie
if (ParaGlob::Monde()->rank() == 0)
{
#endif
// affichage de l'increment de charge
aff_incr=pa.Vrai_commande_sortie(icharge,temps_derniere_sauvegarde); // pour simplifier
if (aff_incr)
@ -1898,7 +1945,12 @@ Vecteur V_ext(F_int_tdt);
<< " dt= " << ParaGlob::Variables_de_temps().IncreTempsCourant()
<< "\n======================================================================";
};
// -- initialisation des coordonnees et des ddl a tdt en fonctions des
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la sortie
}
else {aff_incr = false;};
#endif
// -- initialisation des coordonnees et des ddl a tdt en fonctions des
// ddl imposes et de l'increment du chargement: change_statut sera recalculé ensuite
lesCondLim->MiseAJour_tdt
(pa.Multiplicateur(),lesMail,charge->Increment_de_Temps(),lesRef,charge->Temps_courant()
@ -1935,7 +1987,11 @@ Vecteur V_ext(F_int_tdt);
};
}
else
{ if (arret) break; // pilotage -> arret du calcul
{ if (arret_pilotage) break; // pilotage -> arret du calcul
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la sortie
if (ParaGlob::Monde()->rank() == 0)
#endif
cout << "\n============================================================================="
<< "\n ....... re-analyse du contact ........ "
<< "\nINCREMENT DE CHARGE : " << icharge << " intensite " << charge->IntensiteCharge()
@ -1945,11 +2001,20 @@ Vecteur V_ext(F_int_tdt);
};
};
}; // fin du switch sur compteur_demarrage
#ifdef UTILISATION_MPI
tempsCalEquilibre.Arret_du_comptage(); // temps cpu
temps_transfert_court_algo.Mise_en_route_du_comptage(); // comptage cpu
broadcast(*ParaGlob::Monde(), arret_pilotage, 0);
temps_transfert_court_algo.Arret_du_comptage(); // fin comptage cpu
tempsCalEquilibre.Mise_en_route_du_comptage(); // temps cpu
#endif
if (arret_pilotage) break; // si dans le switch précédent on a un arret de pilotage qui est demandé
lesLoisDeComp->MiseAJour_umat_nbincr(icharge); // init pour les lois Umat éventuelles
// mise à jour éventuelle de la matrice de raideur en fonction de l'existence du contact et du type de modèle de contact
// if (pa.ContactType())
// mato = Mise_a_jour_Choix_matriciel_contact(mato,Ass.Nb_cas_assemb(),lescontacts);
// Mise_a_jour_Choix_matriciel_contact(mato,Ass.Nb_cas_assemb(),lescontacts);
// --- récupération (initialisation) des ddl position, vitesse et accélération
// récupe X_t initiale
@ -1990,6 +2055,11 @@ Vecteur V_ext(F_int_tdt);
// force_recalcul_masse : un indicateur de retour pour la méthode Cinetique_ou_visqueux:
bool force_recalcul_masse= false; // par défaut on ne force pas
// on démarre avec le compteur à 0 et on sauvegarde la position finale à l'itération 0
lesMail->Quelconque_glob_vers_local(X1,X_tdt,typQ_XI_ITER_0);
// boucle de convergence sur un increment
Vecteur * sol; // pointeur du vecteur solution
for (compteur = 0; (compteur<= pa.Iterations())&&(!pa.EtatSortieEquilibreGlobal()); compteur++)
//---//\\//\\// début de la boucle sur les itérations d'équilibres //\\//\\//
@ -2040,7 +2110,12 @@ Vecteur V_ext(F_int_tdt);
lesMail->Force_Ddl_etendu_aux_noeuds_a_zero(Ddl_enum_etendu::Tab_FN_FT()); // idem pour les composantes normales et tangentielles
// affichage ou non de l'itération
bool aff_iteration = (pa.freq_affich_iter() > 0) ?
(aff_incr && (compteur % pa.freq_affich_iter()==0) &&(compteur!=0)) : false ;
(aff_incr && (compteur % pa.freq_affich_iter()==0) &&(compteur!=0)) : false ;
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la sortie
if (ParaGlob::Monde()->rank() != 0) aff_iteration=false;
#endif
/* // --- imposition des ddls bloqués
// initialisation des coordonnees et des ddl a tdt en fonctions des
// ddl imposes et de l'increment du chargement et des conditions linéaires imposées
@ -2166,14 +2241,14 @@ Vecteur V_ext(F_int_tdt);
// quand un noeud glisse d'une facette sur une voisine, peut changer la position du noeud
// qui est projeté sur la facette dans le cas de l'algorithme cinématique
if (((compteur != 0)&&(pa.ContactType()))&&(compteur_demarrage > 0))
{ lescontacts->Actualisation(); // en particulier: pour le type 4 on a projection
{ lescontacts->Actualisation(0); // en particulier: pour le type 4 on a projection
// des noeuds sur les facettes maîtres
// mise à jour éventuelle des répercussions du contact sur les noeuds en contact
AlgoriRelaxDyna::Repercussion_algo_sur_cinematique(lescontacts,X_tdt,vitesse_tdt);
// lesMail->Vect_loc_vers_glob(TEMPS_tdt,X1,X_tdt,X1);
// lesMail->Vect_loc_vers_glob(TEMPS_tdt,V1,vitesse_tdt,V1);
// mise à jour éventuelle de la matrice de raideur en fonction du contact
// mato = Mise_a_jour_Choix_matriciel_contact(mato,Ass.Nb_cas_assemb(),lescontacts);
// Mise_a_jour_Choix_matriciel_contact(mato,Ass.Nb_cas_assemb(),lescontacts);
};
// -+-+ sinon l'actualisation du contact s'effectue à la fin de l'itération (un peu plus loin)
@ -2192,10 +2267,21 @@ Vecteur V_ext(F_int_tdt);
// mise en place du chargement impose, c-a-d calcul de la puissance externe
// si pb on sort de la boucle
//// debug
//cout << "\n debug algo relax "
// << " barriere avant chargement , proc= "<< ParaGlob::Monde()->rank()
// << " compteur = " << compteur << " compteur_demarrage= " << compteur_demarrage<< flush;
//// fin debug
// ParaGlob::Monde()->barrier(); // synchronisation ici de tous les process
if (!(charge->ChargeSecondMembre_Ex_mecaSolid
(Ass1,lesMail,lesRef,vglobex,pa,lesCourbes1D,lesFonctionsnD)))
{ Change_PhaseDeConvergence(-10);break;};
//// debug
//cout << "\n debug algo relax "
// << " après chargement , proc= "<< ParaGlob::Monde()->rank()
// << " compteur = " << compteur << " compteur_demarrage= " << compteur_demarrage<< flush;
//// fin debug
//// autre essai !!
//if (pa.ContactType()==4) // dans le cas d'un contact de type 4
//{V_ext = F_int_tdt; V_ext += F_ext_tdt;
@ -2218,13 +2304,23 @@ Vecteur V_ext(F_int_tdt);
vglobaal += vglobex ;vglobaal += vglobin ;
// on calcul la matrice de masse qui est très particulière dans le cas de la relaxation dynamique
// c'est la partie la plus importante de l'algo: l'adaptation de la masse en continue
//-- *** on utilise le volume de chaque élément, donc il doit avoir été calculé
//-- *** dans le cas historique : type_calcul_mass ==1
// on utilise le volume de chaque élément, donc il doit avoir été calculé
// -- ** ce qui est le cas au moment du calcul des forces internes
// sauf en MPI
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe du calcul de la masse
if (ParaGlob::Monde()->rank() == 0)
{
#endif
CalculEnContinuMatriceMasse
(relax_vit_acce,lesMail,Ass1,compteur
,diversStockage,lesRef,X1,premier_calcul,lescontacts
,force_recalcul_masse,lesFonctionsnD);
#ifdef UTILISATION_MPI
};
#endif
// calcul des reactions de contact pour les noeuds esclaves
// dans le repere absolu ( pour la sortie des infos sur le contact)
// et test s'il y a decollement de noeud en contact (pour les contacts actifs)
@ -2234,9 +2330,9 @@ Vecteur V_ext(F_int_tdt);
lescontacts->CalculReaction(vglobin,decol,Ass1.Nb_cas_assemb(),aff_iteration);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire> *listCondLine = NULL; // init donc sans élément
if (((pa.ContactType()==1) || (pa.ContactType()==3))&&(compteur_demarrage > 0))
tabCondLine = &(lescontacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lescontacts->ConditionLin(Ass1.Nb_cas_assemb()));
// -- dans le cas d'un amortissement visqueux critique ou
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
@ -2282,7 +2378,7 @@ Vecteur V_ext(F_int_tdt);
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,vglobaal,Ass3.Nb_cas_assemb(),vglob_stat);
if ((pa.ContactType()==1)&&(compteur_demarrage > 0)) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,vglobaal,*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
@ -2309,8 +2405,14 @@ Vecteur V_ext(F_int_tdt);
InfoIncrementReac(lesMail,inReaction,maxReaction,Ass3.Nb_cas_assemb());
};
bool arretResidu = false; // pour gérer le cas particulier ou on veut un arrêt et sur le résidu et sur le déplacement
bool demande_de_break=false; // pour gestion du break en tenant compte ou non du MPI
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la convergence
if (ParaGlob::Monde()->rank() == 0)
{
#endif
// examen de la convergence si nécessaire, utilisant le résidu
bool arretResidu = false; // pour gérer le cas particulier ou on veut un arrêt et sur le résidu et sur le déplacement
if (ArretEquilibreStatique() && (compteur>1) && (compteur_demarrage != 0) )// cas d'une convergence en utilisant le résidu
{ double toto=0.; int itera = 0; // valeur par defaut pour ne pas se mettre dans un cas itératif de type algo de Newton
bool arret_demande = false; // normalement n'intervient pas ici, car il n'y a pas de prise en compte d'iteration
@ -2329,12 +2431,61 @@ Vecteur V_ext(F_int_tdt);
)
)
{ arretResidu=true;} // cas relaxation avec amortissement cinétique
else {break;}; // cas normal,
else {demande_de_break=true;}//break;}; // cas normal,
};
};
};
#ifdef UTILISATION_MPI
};
tempsCalEquilibre.Arret_du_comptage(); // temps cpu
temps_transfert_court_algo.Mise_en_route_du_comptage(); // comptage cpu
// TroisEntiers les_arrets(arretResidu,arret,demande_de_break);
Vecteur trois_faux_entiers(3);
trois_faux_entiers(1) = (double) arretResidu;
trois_faux_entiers(2) = (double) arret;
trois_faux_entiers(3) = (double) demande_de_break;
////---- debug
//cout << "\n debug algo relax : barriere avant transfert les_arrets proc = " << ParaGlob::Monde()->rank()
// << " les_arrets= " << les_arrets << " compteur= " << compteur << " compteur_demarrage= " << compteur_demarrage << flush;
////--- fin debug
//// debug
//cout << "\n debug algo relax "
// << " barriere avant transfert les_arrets , proc= "<< ParaGlob::Monde()->rank() << flush;
//// fin debug
// ParaGlob::Monde()->barrier(); // synchronisation ici de tous les process
// broadcast(*ParaGlob::Monde(), les_arrets, 0);
// broadcast(*ParaGlob::Monde(), trois_faux_entiers, 0);
trois_faux_entiers.Broadcast(0);
// operator MPI_Comm() const;
if (ParaGlob::Monde()->rank() != 0)
{arretResidu= (int) trois_faux_entiers(1); //les_arrets.un;
arret = (int) trois_faux_entiers(2); //les_arrets.deux;
demande_de_break = (int) trois_faux_entiers(3); //les_arrets.trois;
};
////---- debug
//cout << "\n debug algo relax : proc = " << ParaGlob::Monde()->rank()
// << " après transfer: les_arrets= " << les_arrets << " compteur= " << compteur << " compteur_demarrage= " << compteur_demarrage<< flush;
////--- fin debug
////---- debug
//cout << "\n debug algo relax : proc = " << ParaGlob::Monde()->rank()
// << "\n on continue "<< flush;
////--- fin debug
temps_transfert_court_algo.Arret_du_comptage(); // fin comptage cpu
tempsCalEquilibre.Mise_en_route_du_comptage(); // temps cpu
#endif
if (demande_de_break)
break;
// 4 --<ARD>-- calcul des nouvelles accélérations
#ifdef UTILISATION_MPI
// seule le process 0 fait la résolution globale
if (ParaGlob::Monde()->rank() == 0)
{
#endif
// resolution simple (fonction du type de matrice)
// ou non suivant modif_repere
tempsResolSystemLineaire.Mise_en_route_du_comptage(); // temps cpu
@ -2351,10 +2502,48 @@ Vecteur V_ext(F_int_tdt);
// affichage éventuelle du vecteur solution : accélération
if (ParaGlob::NiveauImpression() >= 10)
{ string entete = " affichage du vecteur solution acceleration ";
acceleration_tdt.Affichage_ecran(entete); };
acceleration_tdt.Affichage_ecran(entete);
};
// retour des accélération dans les reperes generaux, dans le cas où ils ont ete modifie
// par des conditions linéaires
lesCondLim->RepInitiaux( acceleration_tdt,Ass3.Nb_cas_assemb());
#ifdef UTILISATION_MPI
}
// s'il s'agit d'un process de calcul élémentaire ou non
// sol = &vglobaal; // il faut affecter sol pour récupérer ensuite la solution
// le process 0 transmet aux autres process le vecteur résultat
tempsCalEquilibre.Arret_du_comptage(); // temps cpu
temps_transfert_long_algo.Mise_en_route_du_comptage(); // comptage cpu
// sol->Broadcast(0);
//// debug
//cout << "\n debug algo relax "
// << " barriere avant transfert acceleration_tdt , proc= "<< ParaGlob::Monde()->rank()
// << " compteur = " << compteur << " compteur_demarrage= " << compteur_demarrage<< flush;
//// fin debug
// ParaGlob::Monde()->barrier(); // synchronisation ici de tous les process
acceleration_tdt.Broadcast(0);
//// debug
//cout << "\n debug algo relax "
// << " barriere après transfert acceleration_tdt , proc= "<< ParaGlob::Monde()->rank()
// << " compteur = " << compteur << " compteur_demarrage= " << compteur_demarrage<< flush;
//// fin debug
temps_transfert_long_algo.Arret_du_comptage(); // fin comptage cpu
tempsCalEquilibre.Mise_en_route_du_comptage(); // temps cpu
// // debug
// cout << "\n debug algo relax , proc= "<< ParaGlob::Monde()->rank()
// << " compteur = " << compteur << " compteur_demarrage= " << compteur_demarrage << " acceleration: "
// << acceleration_tdt << flush;
// // fin debug
#else
// // debug
// cout << "\n debug algo relax "
// << " compteur = " << compteur << " compteur_demarrage= " << compteur_demarrage << " acceleration: ";
// acceleration_tdt.Affiche(); cout << flush;
// // fin debug
#endif
// effacement du marquage de ddl bloque du au conditions lineaire imposée par l'entrée
lesCondLim->EffMarque();
if (pa.ContactType()) lescontacts->EffMarque();
@ -2374,7 +2563,7 @@ Vecteur V_ext(F_int_tdt);
// dans le cas ou la recherche de nouveaux contacts est effectuée à chaque itération
if (((type_activation_contact== 1) && (pa.ContactType()))&&(compteur_demarrage > 0))
{ // actualisation des éléments de contact et éventuellement inactivation d'éléments
lescontacts->Actualisation(); // si on n'a plus de projection
lescontacts->Actualisation(0); // si on n'a plus de projection
// on inactive les éléments de contact qui se relache: testé soit via la réaction
lescontacts->RelachementNoeudcolle(); // ou via la sortie d'une zone d'accostage (dépend de l'algo)
};
@ -2394,8 +2583,13 @@ Vecteur V_ext(F_int_tdt);
|| ((typeCalRelaxation == 4) && (Cinetique_ou_visqueux(force_recalcul_masse)))
)
{ relax_vit_acce = AmortissementCinetique(delta_X,1.,X_tdt,*mat_masse_sauve,compteur,vitesse_tdt);
////---- debug
//cout << "\n debug algo relax : proc = " << ParaGlob::Monde()->rank()
// << "\n sortie relaxation: relax_vit_acce= " << relax_vit_acce << " compteur= " << compteur << flush;
////--- fin debug
// il faut re-updater les vitesses
// if (Abs(relax_vit_acce) == 1)
// if (Abs(relax_vit_acce) == 1)
if (relax_vit_acce == 1) // il y a eu relaxation
{lesMail->Vect_glob_vers_local(TEMPS_tdt,V1,vitesse_tdt,V1);
list_iter_relax.push_front(compteur); // on sauvegarde l'iter relaxé
@ -2451,6 +2645,15 @@ Vecteur V_ext(F_int_tdt);
};
// gestion de la fin des itérations
#ifdef UTILISATION_MPI
// seule le process 0 a fait la résolution globale
// il gère seul également la convergence, mais il doit tenir au courant les autres process
tempsCalEquilibre.Arret_du_comptage(); // fin comptage cpu
Algori::Passage_indicConvergenceAuxProcCalcul();
tempsCalEquilibre.Mise_en_route_du_comptage(); // temps cpu
// ce qui permet le déroulement correct de la suite pour tous les process
#endif
if ( ((compteur_demarrage > 0) && (!Pilotage_fin_iteration_implicite(compteur))))
{ // cas d'une non convergence
pas_de_convergence_pour_l_instant = 1;
@ -2471,7 +2674,7 @@ Vecteur V_ext(F_int_tdt);
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -2494,9 +2697,9 @@ Vecteur V_ext(F_int_tdt);
cout << " \n ... convergence en " << compteur << " iterations "<< endl ;
// traitement du contact dans le cas où son activation n'a pas été faite à chaque itération
if ((pa.ContactType()) && (type_activation_contact != 1))
{ lescontacts->Actualisation(); // actualisation du contact en fonction du dernier incrément
{ lescontacts->Actualisation(0); // actualisation du contact en fonction du dernier incrément
// mise à jour éventuelle de la matrice de raideur en fonction du contact
// mato = Mise_a_jour_Choix_matriciel_contact(mato,Ass.Nb_cas_assemb(),lescontacts);
// Mise_a_jour_Choix_matriciel_contact(mato,Ass.Nb_cas_assemb(),lescontacts);
// réexamen du contact pour voir s'il n'y a pas de nouveau element de contact
// en fait on fera au plus deux passages supplémentaire, sinon la boucle peut être infini,
// à la fin du second passage, on regarde s'il y a décollement, si oui on relâche et on refait un passage
@ -2549,7 +2752,7 @@ Vecteur V_ext(F_int_tdt);
// cas du calcul des énergies, passage des grandeurs de tdt à t
if (compteur_demarrage != -1) Algori::TdtversT();
// actualisation des éléments de contact et éventuellement suppression
if (pa.ContactType()) lescontacts->Actualisation(); // des éléments qui ne sont plus en contact
if (pa.ContactType()) lescontacts->Actualisation(0); // des éléments qui ne sont plus en contact
if (compteur_demarrage != -1)
{// on valide l'activité des conditions limites et condition linéaires
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -2742,6 +2945,15 @@ void AlgoriRelaxDyna::CalculMatriceMasse
dima--;
int nbddl_X = mat_masse->Nb_ligne();
int nbNoe = nbddl_X / dima;
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe du calcul de la masse
// et celui-ci ne peut pas être le type historique : 1, car le volume de chaque élément
// n'est pas dispo (il est dispo dans les processus != 0)
if (type_calcul_mass == 1)
{ cout << "\n erreur : en calcul MPI, le type 1 de calcul de la masse n'est pas implante ";
Sortie(1);
};
#endif
switch (type_calcul_mass)

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -868,7 +868,19 @@ void AlgoriTchamwa::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_TCHAMWA); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
// avant toute chose, au cas où l'algo interviendrait après un autre algo
// on inactive tous les ddl existants
lesMail->Inactive_ddl();
@ -994,6 +1006,10 @@ void AlgoriTchamwa::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// initialisation du compteur d'increments de charge
icharge = 0;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -1001,7 +1017,6 @@ void AlgoriTchamwa::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -1010,7 +1025,7 @@ void AlgoriTchamwa::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// definition des elements de contact eventuels
lesContacts->DefElemCont(0.); // au début le déplacement des noeuds est nul
};
//--cas de restart et/ou de sauvegarde------------
// tout d'abord récup du restart si nécessaire
// dans le cas ou un incrément différent de 0 est demandé -> seconde lecture à l'incrément
@ -1033,7 +1048,7 @@ void AlgoriTchamwa::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -1074,9 +1089,6 @@ void AlgoriTchamwa::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
}
}
//--fin cas de restart et/ou de sauvegarde--------
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// ajout d'un conteneur pour les coordonnées à l'itération 0
{Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique
@ -1188,8 +1200,11 @@ void AlgoriTchamwa::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
{
tempsCalEquilibre.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_TCHAMWA); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// récup des entités
Assemblage& Ass1 = *Ass1_;Assemblage& Ass2 = *Ass2_;Assemblage& Ass3 = *Ass3_;
Assemblage& Ass1 = *Ass1_;//Assemblage& Ass2 = *Ass2_;
Assemblage& Ass3 = *Ass3_;
// préparation pour les aspects validation du calcul et sortie contrôlée des incréments
int validation_calcul = 1; // init : par défaut la validation est effective si le calcul converge
@ -1217,7 +1232,7 @@ void AlgoriTchamwa::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t
@ -1484,9 +1499,9 @@ void AlgoriTchamwa::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
lesContacts->CalculReaction(F_ext_tdt,decol,Ass1.Nb_cas_assemb(),aff_incr);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lesContacts->ConditionLin(Ass1.Nb_cas_assemb()));
// dans le cas où l'on utilise de l'amortissement numérique le second membre est modifiée
if (pa.Amort_visco_artificielle())
@ -1509,7 +1524,7 @@ void AlgoriTchamwa::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
bool modif_repere = lesCondLim->CoLinCHrepere_int(*mat_masse,(vglobaal),Ass3.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1) // idem pour le contact conduisant à des conditions linéaires
modif_repere = modif_repere ||
lesCondLim->CoLinCHrepere_ext(*mat_masse,(vglobaal),*tabCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(*mat_masse,(vglobaal),*listCondLine,Ass3.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// ***dans le cas statique il semble (cf. commentaire dans l'algo) que ce soit inutile donc a voir
@ -1619,7 +1634,7 @@ void AlgoriTchamwa::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
Algori::TdtversT();
if (pa.ContactType())
{ // actualisation des éléments de contact et éventuellement inactivation d'éléments
lesContacts->Actualisation(); // si on n'a plus de projection
lesContacts->Actualisation(0); // si on n'a plus de projection
// on inactive les éléments de contact qui se relache: testé soit via la réaction
lesContacts->RelachementNoeudcolle(); // ou via la sortie d'une zone d'accostage (dépend de l'algo)
};

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -91,16 +91,19 @@ class AlgoriTchamwa : public Algori
// constructeur de copie à partie d'une instance indifférenciée
Algori * New_idem(const Algori* algo) const
{// on vérifie qu'il s'agit bien d'une instance
Algori * retour = NULL;
if (algo->TypeDeCalcul() != DYNA_EXP_TCHAMWA)
{ cout << "\n *** erreur lors de la creation par copie d'un algo DYNA_EXP_TCHAMWA "
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
retour = NULL;
}
else
{ AlgoriTchamwa* inter = (AlgoriTchamwa*) algo;
return ((Algori *) new AlgoriTchamwa(*inter));
retour = ((Algori *) new AlgoriTchamwa(*inter));
};
return retour;
};
// DESTRUCTEUR :

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -40,6 +40,8 @@ void AlgoriTchamwa::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMail
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_TCHAMWA); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// cas du chargement, on verifie egalement la bonne adequation des references
charge->Initialise(lesMail,lesRef,pa,*lesCourbes1D,*lesFonctionsnD);
// on indique que l'on ne souhaite pas le temps fin stricte
@ -181,7 +183,7 @@ void AlgoriTchamwa::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMail
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -294,7 +296,7 @@ void AlgoriTchamwa::Calcul_Equilibre2(ParaGlob * paraGlob,LesMaillages * lesMail
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t
@ -626,6 +628,8 @@ void AlgoriTchamwa::Calcul_Equilibre4(ParaGlob * paraGlob,LesMaillages * lesMail
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_TCHAMWA); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
// cas du chargement, on verifie egalement la bonne adequation des references
charge->Initialise(lesMail,lesRef,pa,*lesCourbes1D,*lesFonctionsnD);
// on indique que l'on ne souhaite pas le temps fin stricte
@ -762,7 +766,7 @@ void AlgoriTchamwa::Calcul_Equilibre4(ParaGlob * paraGlob,LesMaillages * lesMail
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -880,7 +884,7 @@ void AlgoriTchamwa::Calcul_Equilibre4(ParaGlob * paraGlob,LesMaillages * lesMail
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -92,6 +92,7 @@ class AlgoriNewmark : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoriNewmark* inter = (AlgoriNewmark*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -46,7 +46,19 @@ void AlgoriNewmark::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
{ // INITIALISATION globale
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_IMP); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
// avant toute chose, au cas où l'algo interviendrait après un autre algo
// on inactive tous les ddl existants
lesMail->Inactive_ddl();
@ -211,6 +223,10 @@ void AlgoriNewmark::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// boucle sur les increments de charge
icharge = 0; // init
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -220,7 +236,6 @@ void AlgoriNewmark::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
bool premier_calcul = true;
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -229,7 +244,8 @@ void AlgoriNewmark::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// definition des elements de contact eventuels
bool nevez_contact = lesContacts->DefElemCont(0.); // au début le déplacement des noeuds est nul
// mise à jour éventuelle de la matrice de raideur en fonction du contact
bool changement_sur_matrice = Gestion_stockage_et_renumerotation_avec_contact
//bool changement_sur_matrice =
Gestion_stockage_et_renumerotation_avec_contact
(premier_calcul,lesMail,nevez_contact,lesCondLim
,lesRef,tab_mato,Ass1.Nb_cas_assemb(),lesContacts,niveau_substitution);
matglob=tab_mato(1);
@ -263,7 +279,7 @@ void AlgoriNewmark::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on réinitialise des ddl avec les conditions initiales because on vient de tout libérer les ddl
// or dans Initial, il y a des inits à faire au niveau des statuts
// lesCondLim->Initial(lesMail,lesRef,lesCourbes1D,lesFonctionsnD,true,cas_combi_ddl);
@ -286,9 +302,10 @@ void AlgoriNewmark::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
if (lesMail->NbEsclave() != 0)
{// on met à jour la boite d'encombrement compte tenue des nouvelles coordonnées
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
bool nevez_contact = lesContacts->Actualisation();
bool nevez_contact = lesContacts->Actualisation(0);
// mise à jour éventuelle de la matrice de raideur en fonction du contact
bool changement_sur_matrice = Gestion_stockage_et_renumerotation_avec_contact
//bool changement_sur_matrice =
Gestion_stockage_et_renumerotation_avec_contact
(premier_calcul,lesMail,nevez_contact,lesCondLim
,lesRef,tab_mato,Ass1.Nb_cas_assemb(),lesContacts,niveau_substitution);
matglob=tab_mato(1);
@ -331,9 +348,6 @@ void AlgoriNewmark::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
};
};
//--fin cas de restart et/ou de sauvegarde--------
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// ajout d'un conteneur pour les coordonnées à l'itération 0
{Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique
@ -787,10 +801,11 @@ void AlgoriNewmark::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
{ int niveau_substitution = 0; // on intervient sur toutes les matrices
bool a_changer = false; // init
if (compteur != 0)
a_changer = lescontacts->Actualisation();
a_changer = lescontacts->Actualisation(1);
// mise à jour éventuelle des matrices de raideur en fonction du contact
if (a_changer)
{bool changement_sur_matrice = Gestion_stockage_et_renumerotation_avec_contact
{//bool changement_sur_matrice =
Gestion_stockage_et_renumerotation_avec_contact
(premier_calcul,lesMail,a_changer,lesCondLim,lesRef
,tab_mato,Ass1.Nb_cas_assemb(),lescontacts,niveau_substitution);
matglob=tab_mato(1);
@ -860,9 +875,9 @@ void AlgoriNewmark::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
lescontacts->CalculReaction(vglobin,decol,Ass1.Nb_cas_assemb(),aff_iteration);
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if (pa.ContactType())
tabCondLine = &(lescontacts->ConditionLin(Ass1.Nb_cas_assemb()));
listCondLine = &(lescontacts->ConditionLin(Ass1.Nb_cas_assemb()));
//------ fin de la partie pour laquelle je m'interroge --------------------
// dans le cas où l'on utilise de l'amortissement numérique, calcul de la part visqueuse dans SM et K
@ -915,7 +930,7 @@ void AlgoriNewmark::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// -->> expression de la raideur et du second membre dans un nouveau repere
lesCondLim->CoLinCHrepere_int((*matglob),vglobaal,Ass1.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1)
lesCondLim->CoLinCHrepere_ext((*matglob),vglobaal,*tabCondLine,Ass1.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext((*matglob),vglobaal,*listCondLine,Ass1.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// en fait ne sert à rien, car les réactions maxi sont calculées dans condlin, mais comme c'est peut-être un peu spécial ici on laisse
// mais dans les autres algos c'est supprimé !!!!!
@ -1129,7 +1144,7 @@ void AlgoriNewmark::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -1153,7 +1168,7 @@ void AlgoriNewmark::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
{ cout << "\n --- |max_var_DeltaDdl|= "<< max_var_delta_X
<< " , |max_deltaDdl|= " << max_delta_X << flush;};
if (pa.ContactType())
{ bool nevez_contact = lescontacts->Actualisation(); // actualisation du contact en fonction du dernier incrément
{ bool nevez_contact = lescontacts->Actualisation(0); // actualisation du contact en fonction du dernier incrément
// réexamen du contact pour voir s'il n'y a pas de nouveau element de contact
// en fait on fera au plus deux passages supplémentaire, sinon la boucle peut être infini,
// à la fin du second passage, on regarde s'il y a décollement, si oui on relâche et on refait un passage

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -390,6 +390,10 @@ void AlgoristatExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
// initialisation du compteur d'increments de charge
icharge = 1;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -397,7 +401,6 @@ void AlgoristatExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -427,7 +430,7 @@ void AlgoristatExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -538,10 +541,10 @@ void AlgoristatExpli::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMai
double maxPuissInt; // maxi de la puissance des efforts internes
double maxReaction; // maxi des reactions
int inReaction = 0; // pointeur d'assemblage pour le maxi de reaction
int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
double maxDeltaDdl=0; // // maxi de variation de ddl
// int inSol =0 ; // pointeur d'assemblage du maxi de variation de ddl
// double maxDeltaDdl=0; // // maxi de variation de ddl
// initialisation de la variable puissance_précédente d'une itération à l'autre
double puis_precedente = 0.;
// double puis_precedente = 0.;
// mise à jour du calcul éventuel des normales aux noeuds -> mise à jour des normales à t
// mais ici, on calcule les normales à tdt, et on transfert à t

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -90,6 +90,7 @@ class AlgoristatExpli : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoristatExpli* inter = (AlgoristatExpli*) algo;
@ -240,7 +241,7 @@ class AlgoristatExpli : public Algori
// écoute et prise en compte d'une commande interactive
// ramène true tant qu'il y a des commandes en cours
///**** inexploitable pour l'instant
bool ActionInteractiveAlgo(){};
bool ActionInteractiveAlgo(){return false;};

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -162,6 +162,10 @@ void AlgoriFlambLineaire::Execution(ParaGlob * paraGlob,LesMaillages * lesMail,
// boucle sur les increments de charge
icharge = 1;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -169,7 +173,6 @@ void AlgoriFlambLineaire::Execution(ParaGlob * paraGlob,LesMaillages * lesMail,
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -194,7 +197,7 @@ void AlgoriFlambLineaire::Execution(ParaGlob * paraGlob,LesMaillages * lesMail,
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -251,7 +254,7 @@ void AlgoriFlambLineaire::Execution(ParaGlob * paraGlob,LesMaillages * lesMail,
// de calculer meme si l'utilisateur indique un increment de charge supÈrieur
// au temps final
bool arret=false; // pour arrÍt du calcul au niveau du pilotage
while ((!charge->Fin(icharge))||(icharge == 1)
while (((!charge->Fin(icharge))||(icharge == 1))
&& (charge->Fin(icharge,true)!=2) // si on a dépassé le nombre d'incrément permis on s'arrête dans tous les cas
&& (charge->Fin(icharge,false)!=3) // idem si on a dépassé le nombre d'essai d'incrément permis
// 1er appel avec true: pour affichage et second avec false car c'est déjà affiché
@ -308,7 +311,7 @@ void AlgoriFlambLineaire::Execution(ParaGlob * paraGlob,LesMaillages * lesMail,
else
lesLoisDeComp->Loi_simplifie(false);
// bool sur_raideur = false; // pour l'instant pas de prise en compte sur la raideur
bool sur_raideur = true; // essai
// bool sur_raideur = true; // essai
// mise en place du chargement impose, c-a-d calcul de la puissance externe
// si pb on sort de la boucle
if (!(charge->ChargeSMembreRaideur_Im_mecaSolid

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -91,6 +91,7 @@ class AlgoriFlambLineaire : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoriFlambLineaire* inter = (AlgoriFlambLineaire*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -269,10 +269,6 @@ void AlgoriNonDyna::Execution(ParaGlob * paraGlob,LesMaillages * lesMail
,divStock,charge,lesCondLim,lesContacts,resultats );
};
//---- fonction obsolete >> a virer !! ---------------------
// Calcul_Equilibre(paraGlob,lesMail,lesRef,lesCourbes1D,lesLoisDeComp
// ,divStock,charge,lesCondLim,lesContacts,resultats );
//---- fin fonction obsolete >> a virer !! -----------------
};// fin du cas sans commandes interactives
// ensuite on teste en fonction des calculs complémentaires

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -91,6 +91,7 @@ class AlgoriNonDyna : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoriNonDyna* inter = (AlgoriNonDyna*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -48,6 +48,31 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(NON_DYNA); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
tempsInitialisation.Arret_du_comptage(); // temps cpu
temps_transfert_court_algo.Mise_en_route_du_comptage(); // comptage cpu
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
temps_transfert_court_algo.Arret_du_comptage(); // comptage cpu
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
////------- debug
//cout << "\n debug AlgoriNonDyna::InitAlgorithme ";
//lesMail->Noeud_LesMaille(1,120).Affiche(9);
//cout << endl;
////-------- fin debug
// avant toute chose, au cas où l'algo interviendrait après un autre algo
// on inactive tous les ddl existants
lesMail->Inactive_ddl();
@ -168,7 +193,7 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// vérification d'une singularité éventuelle de la matrice de raideur
// à cause d'un trop faible nombre de pti
VerifSingulariteRaideurMeca(nbddl_X,*lesMail);
// def vecteurs globaux
// def vecteurs globaux
vglobin.Change_taille(nbddl_X); // puissance interne
vglobex.Change_taille(nbddl_X); // puissance externe
vglobaal.Change_taille(nbddl_X,0.); // puissance totale
@ -218,22 +243,24 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// initi boucle sur les increments de charge
icharge = 0;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
// par exemple il faut initialiser les frontières et la répartition esclave et maître
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
{ lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
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
// // 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
@ -247,11 +274,14 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// double diam_mini = lesMail->Min_dist2Noeud_des_elements(TEMPS_0);
// lesContacts->DefElemCont(2. * diam_mini);
try {
// definition des elements de contact eventuels
// et imposition éventuel de certaines des conditions de contact (dépend du modèle de contact)
bool nevez_contact = lesContacts->DefElemCont(0.); // au début le déplacement des noeuds est nul
int niveau_substitution = 0; // on intervient sur toutes les matrices
bool premier_calcul = true;
// mise à jour éventuelle de la matrice de raideur en fonction du contact
bool changement_sur_matrice = Gestion_stockage_et_renumerotation_avec_contact
//bool changement_sur_matrice =
Gestion_stockage_et_renumerotation_avec_contact
(premier_calcul,lesMail,nevez_contact,lesCondLim
,lesRef,tab_mato,Ass.Nb_cas_assemb(),lesContacts,niveau_substitution);
matglob=tab_mato(1);
@ -272,6 +302,7 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
};
//--cas de restart et/ou de sauvegarde------------
// tout d'abord récup du restart si nécessaire
// dans le cas ou un incrément différent de 0 est demandé -> seconde lecture à l'incrément
@ -311,8 +342,7 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -334,11 +364,15 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
};
// sinon ok, et on met à jour la boite d'encombrement compte tenue des nouvelles coordonnées
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
bool nevez_contact = lesContacts->Actualisation();
bool nevez_contact = lesContacts->Actualisation(0);
// *** test
bool nevez_bis_contact = lesContacts->Nouveau(0.);
nevez_contact = (nevez_contact || nevez_bis_contact); //double dep_max)
int niveau_substitution = 0; // on intervient sur toutes les matrices
bool premier_calcul = true;
// mise à jour éventuelle de la matrice de raideur en fonction du contact
bool changement_sur_matrice = Gestion_stockage_et_renumerotation_avec_contact
//bool changement_sur_matrice =
Gestion_stockage_et_renumerotation_avec_contact
(premier_calcul,lesMail,nevez_contact,lesCondLim
,lesRef,tab_mato,Ass.Nb_cas_assemb(),lesContacts,niveau_substitution);
matglob=tab_mato(1);
@ -382,14 +416,11 @@ void AlgoriNonDyna::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
};
};
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// init de var glob
Transfert_ParaGlob_COMPTEUR_INCREMENT_CHARGE_ALGO_GLOBAL(icharge);
//--fin cas de restart et/ou de sauvegarde--------
type_incre = OrdreVisu::PREMIER_INCRE; // pour la visualisation au fil du calcul
// ajout d'un conteneur pour les coordonnées à l'itération 0
{Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique
Grandeur_coordonnee gt(coor); // une grandeur typique de type Grandeur_coordonnee
@ -552,6 +583,10 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// mais pas après un changement de statut
{ Pilotage_du_temps(charge,arret_pilotage); // appel du Pilotage
if (arret_pilotage) break; // pilotage -> arret du calcul
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la sortie
if (ParaGlob::Monde()->rank() == 0)
#endif
if (aff_incr)
{cout << "\n======================================================================"
<< "\nINCREMENT DE CHARGE : " << icharge
@ -593,11 +628,13 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
else
{ // on supprime les éléments inactifs testés à l'incr prec dans Actualisation()
a_changer = lescontacts->SuppressionDefinitiveElemInactif();
a_changer = a_changer || lescontacts->Nouveau(max_delta_X);
bool a_changer_nouveau = lescontacts->Nouveau(max_delta_X);
a_changer = a_changer || a_changer_nouveau;
};
int niveau_substitution = 0; // on intervient sur toutes les matrices
if (premier_calcul || a_changer)
{bool changement_sur_matrice = Gestion_stockage_et_renumerotation_avec_contact
{//bool changement_sur_matrice =
Gestion_stockage_et_renumerotation_avec_contact
(premier_calcul,lesMail,a_changer,lesCondLim,lesRef
,tab_mato,Ass.Nb_cas_assemb(),lescontacts,niveau_substitution);
matglob=tab_mato(1);
@ -607,7 +644,11 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
}
else
{if (arret_pilotage) break; // pilotage -> arret du calcul
cout << "\n============================================================================="
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la sortie
if (ParaGlob::Monde()->rank() == 0)
#endif
cout << "\n============================================================================="
<< "\n ....... re-analyse du contact ........ "
<< "\nINCREMENT DE CHARGE : " << icharge << " intensite " << charge->IntensiteCharge()
<< " t= " << charge->Temps_courant()
@ -693,10 +734,11 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// qui est projeté sur la facette dans le cas de l'algorithme cinématique
if (pa.ContactType())
{ int niveau_substitution = 0; // on intervient sur toutes les matrices
bool a_changer = lescontacts->Actualisation();
bool a_changer = lescontacts->Actualisation(1);
// mise à jour éventuelle des matrices de raideur en fonction du contact
if (a_changer)
{bool changement_sur_matrice = Gestion_stockage_et_renumerotation_avec_contact
{//bool changement_sur_matrice =
Gestion_stockage_et_renumerotation_avec_contact
(premier_calcul,lesMail,a_changer,lesCondLim,lesRef
,tab_mato,Ass.Nb_cas_assemb(),lescontacts,niveau_substitution);
matglob=tab_mato(1);
@ -830,9 +872,9 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// - definition éventuelle de conditions limites linéaires de contact, en fonction des éléments du contact existant à ce niveau
// (certains contacts (par pénalisation par exemple) ne produise pas de conditions linéaires)
const Tableau <Condilineaire>* tabCondLine=NULL;
list <Condilineaire>* listCondLine=NULL;
if ((pa.ContactType()==1) || (pa.ContactType()==3))
tabCondLine = &(lescontacts->ConditionLin(Ass.Nb_cas_assemb()));
listCondLine = &(lescontacts->ConditionLin(Ass.Nb_cas_assemb()));
// - initialisation des sauvegardes sur matrice et second membre
lesCondLim->InitSauve(Ass.Nb_cas_assemb());
@ -852,9 +894,9 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// mais ici on n'impose pas les conditons, on fait simplement le changement de repère
lesCondLim->CoLinCHrepere_int((*matglob),vglobaal,Ass.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==1)
lesCondLim->CoLinCHrepere_ext((*matglob),vglobaal,*tabCondLine,Ass.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext((*matglob),vglobaal,*listCondLine,Ass.Nb_cas_assemb(),vglob_stat);
if (pa.ContactType()==3) // *** exploratoire
lesCondLim->CoLinUneOpe_ext((*matglob),vglobaal,*tabCondLine,Ass.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinUneOpe_ext((*matglob),vglobaal,*listCondLine,Ass.Nb_cas_assemb(),vglob_stat);
// sauvegarde des reactions pour les ddl bloques (simplement)
// en fait ne sert à rien, car les réactions maxi sont calculées dans condlin, mais comme c'est peut-être un peu spécial ici on laisse
// mais dans les autres algos c'est supprimé !!!!!
@ -879,7 +921,12 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// calcul de la variation de ddl / delta t
// delta_X = X_tdt; delta_X -= X_t; // X_tdt - X_t
Algori::Cal_Transfert_delta_et_var_X(max_delta_X,max_var_delta_X);
#ifdef UTILISATION_MPI
// cas d'un calcul //, pour l'instant seul le CPU 0 sont concerné
if ((ParaGlob::Monde()->rank() == 0)&&(permet_affichage > 3))
#else
if (permet_affichage > 3)
#endif
{ cout << "\n --- |max_var_DeltaDdl|= "<< max_var_delta_X
<< " , |max_deltaDdl|= " << max_delta_X << flush;};
// ---dans le cas du mode debug on sort éventuellement les infos au fil du calcul (un peu bricolé)
@ -906,7 +953,13 @@ void AlgoriNonDyna::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
// en tenant compte éventuellement du contact (non decollement) decol = false systématiquement si pas de contact
decol = false; // pour debugger
bool arret_iteration = false;
#ifdef UTILISATION_MPI
// seule le process 0 s'occupe de la convergence
if (ParaGlob::Monde()->rank() == 0)
{
#endif
if (Convergence(aff_iteration,last_var_ddl_max,vglobaal,maxPuissExt,maxPuissInt,maxReaction,compteur,arret_convergence)
&& !decol)
{ // on sort de la boucle des itérations sauf si l'on est en loi simplifiée
@ -915,10 +968,19 @@ decol = false; // pour debugger
{ lesLoisDeComp->Loi_simplifie(false);}
else
// cas normal,
{break;};
{arret_iteration = true; }; //break;};
}
else if (arret_convergence)
{break;} // cas ou la méthode Convergence() demande l'arret
{arret_iteration = true; }; //break;} // cas ou la méthode Convergence() demande l'arret
#ifdef UTILISATION_MPI
};
temps_transfert_court_algo.Mise_en_route_du_comptage(); // comptage cpu
broadcast(*ParaGlob::Monde(), arret_iteration, 0);
temps_transfert_court_algo.Arret_du_comptage(); // fin comptage cpu
#endif
if (arret_iteration)
break;
// sinon on continue
// pour le pilotage ou pour l'accélération de convergence, sauvegarde du résidu
if (pa.Line_search() || (acceleration_convergence))
@ -929,6 +991,11 @@ decol = false; // pour debugger
bool erreur_resolution_syst_lineaire = false; // init
int nb_matrice_secondaire = tab_mato.Taille(); // = 1 par défaut, mais on peut en avoir d'autre
int niveau_substitution = 1; // par défaut on utilise la matrice de raideur matglob = tab_mato(1)
#ifdef UTILISATION_MPI
// seule le process 0 fait la résolution globale
if (ParaGlob::Monde()->rank() == 0)
{
#endif
while (niveau_substitution <= nb_matrice_secondaire)
{ // on sauvegarde éventuellement le second membre
if (nb_matrice_secondaire > 1) // cela veut dire que l'on est suceptible de faire plusieurs boucles
@ -984,11 +1051,6 @@ decol = false; // pour debugger
};
tempsResolSystemLineaire.Arret_du_comptage(); // temps cpu
// effacement du marquage de ddl bloque du au conditions lineaire imposée par l'entrée
lesCondLim->EffMarque();
if ((pa.ContactType()==1) || (pa.ContactType()==3))
lescontacts->EffMarque();
// cas où on a eu au final une erreur de résolution
if (erreur_resolution_syst_lineaire)
{Change_PhaseDeConvergence(-9); // on signale une divergence due à la résolution
@ -1015,6 +1077,44 @@ decol = false; // pour debugger
// sortie d'info sur l'increment concernant les variations de ddl
if ((aff_iteration)&&(ParaGlob::NiveauImpression() > 1))
InfoIncrementDdl(lesMail,inSol,maxDeltatDdl_signe,Ass.Nb_cas_assemb());
#ifdef UTILISATION_MPI
}
else // s'il s'agit d'un process de calcul élémentaire
{sol = &vglobaal; // il faut affecter sol pour récupérer ensuite la solution
};
// le process 0 transmet aux autres process le vecteur résultat
temps_transfert_long_algo.Mise_en_route_du_comptage(); // comptage cpu
//// essai pour remplacer broadcast
// int nb_process = ParaGlob::Monde()->size();
// mpi::request reqs1;
// if (ParaGlob::Monde()->rank() == 0)
// // NB: le process 0 c'est le main
// {for (int i=1;i<nb_process;i++) // < absolu, donc le max c'est nb_process-1
// {reqs1 = sol->Ienvoi_MPI(i, 38);}
// }
// else
// {reqs1 = sol->Irecup_MPI(0,38);};
//// ParaGlob::Monde()->barrier();
// reqs1.wait();
// mpi::request Ienvoi_MPI(int dest, int tag) const
// {return ParaGlob::Monde()->isend(dest,tag,v,taille);};
// mpi::request Irecup_MPI(int source, int tag) const
sol->Broadcast(0);
// broadcast(*ParaGlob::Monde(), *sol, 0);
// synchronisation ici de tous les process (à supprimer par la suite car n'est
// pas nécessaire pour le déroulementa priori ?? )
// ParaGlob::Monde()->barrier();
temps_transfert_long_algo.Arret_du_comptage(); // fin comptage cpu
#endif
// effacement du marquage de ddl bloque du au conditions lineaire imposée par l'entrée
lesCondLim->EffMarque();
if ((pa.ContactType()==1) || (pa.ContactType()==3))
lescontacts->EffMarque();
// suite du pilotage
// ------------------------------------------------------------
@ -1070,7 +1170,15 @@ decol = false; // pour debugger
};
if ((pa.ContactType()==1) || (pa.ContactType()==3)) lescontacts->EffMarque();
// gestion de la fin des itérations
// === gestion de la fin des itérations ===
#ifdef UTILISATION_MPI
// seule le process 0 a fait la résolution globale
// il gère seul également la convergence, mais il doit tenir au courant les autres process
Algori::Passage_indicConvergenceAuxProcCalcul();
// ce qui permet le déroulement correct de la suite pour tous les process
#endif
if ((!Pilotage_fin_iteration_implicite(compteur))||(pa.EtatSortieEquilibreGlobal()))
// if ((!Pilotage_fin_iteration_implicite(compteur))
// && (!pa.EtatSortieEtatActuelDansBI()))
@ -1097,7 +1205,7 @@ decol = false; // pour debugger
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -1118,14 +1226,15 @@ decol = false; // pour debugger
<< " , |max_deltaDdl|= " << max_delta_X << flush;};
if (pa.ContactType())
{ // actualisation du contact en fonction du dernier incrément
bool nevez_contact = lescontacts->Actualisation();
bool nevez_contact = lescontacts->Actualisation(0);
// réexamen du contact pour voir s'il n'y a pas de nouveau element de contact
// en fait on fera au plus deux passages supplémentaire, sinon la boucle peut être infini,
// à la fin du second passage, on regarde s'il y a décollement, si oui on relâche et on refait un passage
// sinon on valide
//I)--------------
if (indicCycleContact == 0 )
{ nevez_contact = nevez_contact || lescontacts->Nouveau(lesMail->Max_var_dep_t_a_tdt());
{ bool nouveau_contact = lescontacts->Nouveau(lesMail->Max_var_dep_t_a_tdt());
nevez_contact = nevez_contact || nouveau_contact;
if (nevez_contact)
{indicCycleContact=1;} // on a de nouveau contact on refait le deuxième cycle
else
@ -1150,7 +1259,8 @@ decol = false; // pour debugger
)
{int niveau_substitution = 0; // on intervient sur toutes les matrices
bool nouveau = (nevez_contact || relachement_contact);
bool changement_sur_matrice = Gestion_stockage_et_renumerotation_avec_contact
//bool changement_sur_matrice =
Gestion_stockage_et_renumerotation_avec_contact
(premier_calcul,lesMail,nouveau,lesCondLim
,lesRef,tab_mato,Ass.Nb_cas_assemb(),lescontacts,niveau_substitution);
matglob=tab_mato(1);
@ -1662,6 +1772,10 @@ void AlgoriNonDyna::Calcul_Equilibre_longueur_arc
// boucle sur les increments de charge
icharge = 1;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -1669,7 +1783,6 @@ void AlgoriNonDyna::Calcul_Equilibre_longueur_arc
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -1683,7 +1796,8 @@ void AlgoriNonDyna::Calcul_Equilibre_longueur_arc
int niveau_substitution = 0; // on intervient sur toutes les matrices
bool premier_calcul = true;
// mise à jour éventuelle de la matrice de raideur en fonction du contact
bool changement_sur_matrice = Gestion_stockage_et_renumerotation_avec_contact
//bool changement_sur_matrice =
Gestion_stockage_et_renumerotation_avec_contact
(premier_calcul,lesMail,nevez_contact,lesCondLim
,lesRef,tab_mato,Ass.Nb_cas_assemb(),lesContacts,niveau_substitution);
matglob=tab_mato(1);
@ -1718,7 +1832,7 @@ void AlgoriNonDyna::Calcul_Equilibre_longueur_arc
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -1765,7 +1879,7 @@ void AlgoriNonDyna::Calcul_Equilibre_longueur_arc
// de calculer meme si l'utilisateur indique un increment de charge supérieur
// au temps final
bool arret_pilotage=false; // pour arrêt du calcul au niveau du pilotage
while ((!charge->Fin(icharge))||(icharge == 1)
while (((!charge->Fin(icharge))||(icharge == 1))
&& (charge->Fin(icharge,true)!=2) // si on a dépassé le nombre d'incrément permis on s'arrête dans tous les cas
&& (charge->Fin(icharge,false)!=3) // idem si on a dépassé le nombre d'essai d'incrément permis
// 1er appel avec true: pour affichage et second avec false car c'est déjà affiché
@ -1873,7 +1987,7 @@ void AlgoriNonDyna::Calcul_Equilibre_longueur_arc
(aff_incr && (compteur % pa.freq_affich_iter()==0) &&(compteur!=0)) : false ;
lesLoisDeComp->MiseAJour_umat_nbiter(compteur); // init pour les lois Umat éventuelles
// bool sur_raideur = false; // pour l'instant pas de prise en compte sur la raideur
bool sur_raideur = true; // essai
// bool sur_raideur = true; // essai
// mise en place du chargement impose, c-a-d calcul de la puissance externe
// si pb on sort de la boucle
if (!(charge->ChargeSMembreRaideur_Im_mecaSolid

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -255,6 +255,10 @@ void ImpliNonDynaCont::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
//--** // un premier increment pour demmarer le processus
//--** charge->Avance(); // premier increment de charge ????????? différent des autres algos
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -262,7 +266,6 @@ void ImpliNonDynaCont::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lescontacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -478,7 +481,7 @@ void ImpliNonDynaCont::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
// actualisation des conditions de contact qui peuvent changer
// la largeur de bande, quand un noeud glisse d'une facette sur une voisine
if (compteur != 0)
{ lescontacts->Actualisation();
{ lescontacts->Actualisation(1);
// mise à jour éventuelle de la matrice de raideur en fonction du contact
Mise_a_jour_Choix_matriciel_contact(tab_mato,Ass.Nb_cas_assemb(),lescontacts,niveau_substitution);
mato=tab_mato(1);
@ -495,7 +498,7 @@ void ImpliNonDynaCont::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
maxPuissExt = vglobex.Max_val_abs();
F_ext_tdt = vglobex; // sauvegarde des forces généralisées extérieures
// - definition des conditions limites de contact
const Tableau <Condilineaire>& tabCondLine = lescontacts->ConditionLin(Ass.Nb_cas_assemb());
list <Condilineaire>& listCondLine = lescontacts->ConditionLin(Ass.Nb_cas_assemb());
// -- appel du calcul de la raideur et du second membre, énergies
// dans le cas d'un calcul inexploitable arrêt de la boucle
if (!RaidSmEner(lesMail,Ass,vglobin,matglob)) break;
@ -522,7 +525,7 @@ void ImpliNonDynaCont::Calcul_Equilibre(ParaGlob * paraGlob,LesMaillages * lesMa
vglobal.Affiche();*/
// cout <<" \n une valeur continuer ? "; cin >> toti;
// expression de la raideur et du second membre dans un nouveau repere
lesCondLim->CoLinCHrepere_ext(matglob,vglobaal,tabCondLine,Ass.Nb_cas_assemb(),vglob_stat);
lesCondLim->CoLinCHrepere_ext(matglob,vglobaal,listCondLine,Ass.Nb_cas_assemb(),vglob_stat);
/* cout << "\n matrice et second membre dans le nouveau repere";
matglob.Affiche1(1,4,1,1,4,1);
vglobal.Affiche(); */

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -88,6 +88,7 @@ class ImpliNonDynaCont : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ ImpliNonDynaCont* inter = (ImpliNonDynaCont*) algo;

View file

@ -7,7 +7,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -320,7 +320,7 @@ void AlgoBonelli::Gestion_pas_de_temps(LesMaillages * lesMail,int cas,int )
case 1 :
{ // --<DG>-- récup du pas de temps, proposé par l'utilisateur
delta_t = pa.Deltat(); double delta_t_old = delta_t;
double delta_tSauve = delta_t; // sauvegarde de la situation actuelle
// double delta_tSauve = delta_t; // sauvegarde de la situation actuelle
// --<DG>-- on calcul le pas de temps minimal pour cela on utilise
// les caractéristiques dynamiques d'une biellette de longueur
// valant le minimum d'un coté d'arrête
@ -647,6 +647,18 @@ void AlgoBonelli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
tempsInitialisation.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_BONELLI); // transfert info
#ifdef UTILISATION_MPI
// calcul de l'équilibrage initiale par le cpu 0
if (distribution_CPU_algo.Tableau_element_CPU_en_cours()->Taille() == 0 )
{distribution_CPU_algo.Calcul_Equilibrage_initiale(lesMail);
distribution_CPU_algo.Passage_Equilibrage_aux_CPU();
paraGlob->Init_tableau(distribution_CPU_algo.Tableau_element_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_CPU_en_cours()
,distribution_CPU_algo.Tableau_noeud_CPU_en_cours()
,distribution_CPU_algo.Tab_indique_noeud_CPU_en_cours());
};
#endif
// avant toute chose, au cas où l'algo interviendrait après un autre algo
// on inactive tous les ddl existants
lesMail->Inactive_ddl();
@ -780,6 +792,10 @@ void AlgoBonelli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// initialisation du compteur d'increments de charge
icharge = 0;
// definition des elements de frontiere, ces elements sont utilises pour le contact
lesMail->CreeElemFront();
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// --- init du contact ---
// doit-être avant la lecture d'un restart, car il y a une initialisation de conteneurs qui est faites
// qui ensuite est utilisée en restart
@ -787,7 +803,8 @@ void AlgoBonelli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// pour préparer la lecture de restart éventuel
if (lesMail->NbEsclave() != 0)
{ // definition des elements de frontiere, ces elements sont utilises pour le contact
int cal_front = lesMail->CreeElemFront();
// int cal_front =
lesMail->CreeElemFront();
lesMail->Mise_a_jour_boite_encombrement_elem_front(TEMPS_t);
// initialisation des zones de contacts éventuelles
lesContacts->Init_contact(*lesMail,*lesRef,lesFonctionsnD);
@ -796,6 +813,7 @@ void AlgoBonelli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
// definition des elements de contact eventuels
lesContacts->DefElemCont(0.); // au début le déplacement des noeuds est nul
};
//--cas de restart et/ou de sauvegarde------------
// tout d'abord récup du restart si nécessaire
// dans le cas ou un incrément différent de 0 est demandé -> seconde lecture à l'incrément
@ -817,7 +835,7 @@ void AlgoBonelli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
lesMail->ChangeStatut(cas_combi_ddl,LIBRE);
// dans le cas d'un calcul axisymétrique on bloque le ddl 3
if (ParaGlob::AxiSymetrie())
lesMail->Inactive_un_type_ddl_particulier(X3);
lesMail->Inactive_un_ddl_particulier(X3);
// on valide l'activité des conditions limites et condition linéaires, pour le temps initial
// en conformité avec les conditions lues (qui peuvent éventuellement changé / aux calcul qui a donné le .BI)
lesCondLim->Validation_blocage (lesRef,charge->Temps_courant());
@ -857,9 +875,6 @@ void AlgoBonelli::InitAlgorithme(ParaGlob * paraGlob,LesMaillages * lesMail,
}
}
//--fin cas de restart et/ou de sauvegarde--------
// calcul éventuel des normales aux noeuds -> init des normales pour t=0
lesMail->InitNormaleAuxNoeuds(); //utilisé pour la stabilisation des membranes par ex
// ajout d'un conteneur pour les coordonnées à l'itération 0
{Coordonnee coor(ParaGlob::Dimension()); // un type coordonnee typique
@ -972,6 +987,8 @@ void AlgoBonelli::CalEquilibre(ParaGlob * paraGlob,LesMaillages * lesMail
{
tempsCalEquilibre.Mise_en_route_du_comptage(); // temps cpu
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(DYNA_EXP_BONELLI); // transfert info
// init var glob: du num d'itération. De manière arbitraire, en dynamique explicite
Transfert_ParaGlob_COMPTEUR_ITERATION_ALGO_GLOBAL(1); // on a toujours une seule itération
OrdreVisu::EnumTypeIncre type_incre = OrdreVisu::PREMIER_INCRE; // pour la visualisation au fil du calcul
// préparation pour les aspects validation du calcul et sortie contrôlée des incréments
@ -1424,8 +1441,8 @@ void AlgoBonelli::AvanceDDL_avec_CL(const Vecteur & phii,enuTypePhase phasage)
for(ie=li_gene_asso.begin(),ih=1;ie!=iefin;ie++,ih++)
{LesCondLim::Gene_asso & s = (*ie); // pour simplifier
int ix=s.pointe(1); // début des Xi
int iv=s.pointe(2); // début des Vi
int ig=s.pointe(3); // début des gammai
// int iv=s.pointe(2); // début des Vi
// int ig=s.pointe(3); // début des gammai
q_2(ix) = X_Bl(ih);
q_1(ix) = X_t(ix);
};
@ -1474,8 +1491,8 @@ void AlgoBonelli::AvanceDDL_avec_CL(const Vecteur & phii,enuTypePhase phasage)
for(ie=li_gene_asso.begin(),ih=1;ie!=iefin;ie++,ih++)
{LesCondLim::Gene_asso & s = (*ie); // pour simplifier
int ix=s.pointe(1); // début des Xi
int iv=s.pointe(2); // début des Vi
int ig=s.pointe(3); // début des gammai
// int iv=s.pointe(2); // début des Vi
// int ig=s.pointe(3); // début des gammai
q_2(ix) = X_Bl(ih);
q_1(ix) = X_t(ix);
};

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -107,6 +107,7 @@ class AlgoBonelli : public Algori
<< " l'algo passe en parametre est en fait : " << Nom_TypeCalcul(algo->TypeDeCalcul())
<< " arret !! " << flush;
Sortie(1);
return NULL;
}
else
{ AlgoBonelli* inter = (AlgoBonelli*) algo;

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -93,7 +93,7 @@ void BlocScalVecTypeCharge::Lecture_champ_de_valeurs(UtilLecture & entreePrinc)
{ list <double> lili; // une liste de travail
// on va lire tant que l'on n'aura pas trouvé le mot clé de fin de champ
entreePrinc.NouvelleDonnee(); // lecture d'un nouvelle enregistrement
while (strstr(entreePrinc.tablcar,"fin_champ_de_valeurs:")!=NULL)
while (strstr(entreePrinc.tablcar,"fin_champ_de_valeurs:")==NULL)
{ double grandeur;
*(entreePrinc.entree) >> grandeur;
// on contrôle le flux
@ -873,7 +873,7 @@ void PTorseurPonct::Force(const Tableau <Coordonnee >& tab_P, Tableau <Coordonne
{for (int i =1; i<= nb_Pi; i++)
{Coordonnee& tab_P_i = tab_P(i);
t_force(i) = Re ; // première partie du calcul de force
G += tab_P(i) ;
G += tab_P_i ;
poids_total += 1.;
};
// d'où

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

137
herezh_pp/Chargement/Charge.cc → Chargement/Charge.cc Executable file → Normal file
View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -198,11 +198,30 @@ Charge::Charge () : // constructeur par defaut
,temps_fin_non_stricte(0)
,nomtypeCharge(),ancien_num_pt_type5(0),num_pt_courant_type5(0)
,temps_cpu_chargement()
#ifdef UTILISATION_MPI
,temps_transfert_court(),temps_transfert_long(),temps_attente()
,tab_reqs1(),tab_reqs2(),tab_reqs3()
,tabV_transfert(),tabMat_transfert(),tab_six_faux_entiers()
#endif
{// mise à jour de la valeur par défaut du chargement au cas où aucun chargement
// n'est définit
nomtypeCharge ="TYPE1";
tabType.Change_taille(1);
tabType(1) = 1.;
#ifdef UTILISATION_MPI
// on définit les conteneurs de passage d'info
int taille_passage = 8;
tab_reqs1.Change_taille(taille_passage);
tab_reqs2.Change_taille(taille_passage);
tab_reqs3.Change_taille(taille_passage);
tabV_transfert.Change_taille(taille_passage);
tabMat_transfert.Change_taille(taille_passage);
tab_six_faux_entiers.Change_taille(taille_passage);
for (int i=1;i<=taille_passage;i++)tab_six_faux_entiers(i).Change_taille(6);
#endif
}
Charge::~Charge ()
{ if (f_charge != NULL)
@ -758,7 +777,7 @@ void Charge::Initialise(LesMaillages * lesmail,LesReferences* lesRef,ParaAlgoCon
// dans le cas où il s'agit d'une ref relative à un champ, on vérifie que le nombre
// de valeurs enregistrées correspond bien au nombre de noeuds
if (tabPresUnif(i).Champ() != 0)
{ if (tabPresUnif(i).DimVect() != ref.Taille())
{ if (tabPresUnif(i).DimVal() != ref.Taille())
{ cout << "\n ERREUR la reference: " << ref.Nom()
<< " contiens "<<ref.Taille() << " facette "
<< " alors que le champ de valeurs lues stocke "
@ -1041,7 +1060,7 @@ void Charge::Initialise(LesMaillages * lesmail,LesReferences* lesRef,ParaAlgoCon
for (int i=1;i<= tabTorseurPonct.Taille();i++)
{ { // recup de la reference correspondant au mot cle
const Reference& ref = lesRef->Trouve(tabTorseurPonct(i).NomRef(),tabTorseurPonct(i).NomMaillage());
const ReferenceNE & refN = ((ReferenceNE &) ref);
//const ReferenceNE & refN = ((ReferenceNE &) ref);
if (ref.Indic() != 1)
// cas où la référence ne correspond pas à des noeuds
{ cout << "\n ERREUR la reference: " << ref.Nom()
@ -1301,5 +1320,115 @@ void Charge::Ecriture_base_info(ofstream& sort,const int cas)
};
};
#ifdef UTILISATION_MPI
// transfert du second membre "SM_transfert" et mise à jour
// de l'index des tableaux "index_transfert" par rotation cyclique
// NB: tous les tableaux doivent avoir la même taille
void Charge::Transfert_SM(bool& premier_passage,
const int& tyfront,
const int& num_front,
Vecteur & SM_transfert,
int& index_transfert,
const int & numail,
const int & numelem
)
{
temps_attente.Mise_en_route_du_comptage(); // comptage cpu
mpi::request & reqs1 = tab_reqs1(index_transfert); // pour simplifier
mpi::request & reqs2 = tab_reqs2(index_transfert); // pour simplifier
int taille_tableau = tab_six_faux_entiers.Taille();
// on récupère un signal du process 0
if (premier_passage) {premier_passage = false;}
else // on regarde l'activité , car au début avant le balayage de tous les éléments des tableaux
{if (reqs1.active()) reqs1.wait(); // les requests ne sont pas alimentés
if (reqs2.active()) reqs2.wait(); // car aucun transfert n'a encore été effectué
};
temps_attente.Arret_du_comptage(); // fin comptage cpu
temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu
Vecteur& six_faux_entiers = tab_six_faux_entiers(index_transfert); // pour simplifier
six_faux_entiers(1) = (double) numelem;
six_faux_entiers(2) = (double) numail;
six_faux_entiers(3) = (double) tyfront;
six_faux_entiers(4) = (double) num_front;
six_faux_entiers(5) = (double) SM_transfert.Taille();
six_faux_entiers(6) = (double) index_transfert;
// on transmet les numéros d'élément et de maillage etc.
reqs1 = six_faux_entiers.Ienvoi_MPI(0, 34);
temps_transfert_court.Arret_du_comptage(); // fin comptage cpu
// puis on transmets le vecteur résidu sauf si tyfront est négatif
if (tyfront > 0)
{temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu
reqs2 = SM_transfert.Ienvoi_MPI(0,35);
temps_transfert_long.Arret_du_comptage(); // fin comptage cpu
// // debug
// cout << "\n debug Charge::Transfert_SM( proc= "<< ParaGlob::Monde()->rank()
// << " six_faux_entiers= " << six_faux_entiers
// << " SM_transfert= " << SM_transfert << flush;
// // fin debug
};
// ici on utilise un nouveau élément de tableau pour éviter d'écraser la précédente version qui peut être encore
// en transfert vers le proc 0
index_transfert++;
if (index_transfert > taille_tableau) // on fait une permutation circulaire
index_transfert = 1;// on revient au premier élément des tableaux de transfert
};
// transfert du second membre "SM_transfert" et de la matrice "MAT_transfert" et mise à jour
// de l'index des tableaux "index_transfert" par rotation cyclique
// NB: tous les tableaux doivent avoir la même taille
void Charge::Transfert_MatSm(bool& premier_passage,
const int& tyfront,
const int& num_front,
Vecteur & SM_transfert,
Mat_pleine * MAT_transfert,
int& index_transfert,
const int & numail,
const int & numelem
)
{
temps_attente.Mise_en_route_du_comptage(); // comptage cpu
mpi::request & reqs1 = tab_reqs1(index_transfert); // pour simplifier
mpi::request & reqs2 = tab_reqs2(index_transfert); // pour simplifier
mpi::request & reqs3 = tab_reqs3(index_transfert); // pour simplifier
int taille_tableau = tab_six_faux_entiers.Taille();
// on récupère un signal du process 0
if (premier_passage) {premier_passage = false;}
else // on regarde l'activité , car au début avant le balayage de tous les éléments des tableaux
{if (reqs1.active()) reqs1.wait(); // les requests ne sont pas alimentés
if (reqs2.active()) reqs2.wait(); // car aucun transfert n'a encore été effectué
if (reqs3.active()) reqs3.wait(); // car aucun transfert n'a encore été effectué
};
temps_attente.Arret_du_comptage(); // fin comptage cpu
temps_transfert_court.Mise_en_route_du_comptage(); // comptage cpu
Vecteur& six_faux_entiers = tab_six_faux_entiers(index_transfert); // pour simplifier
six_faux_entiers(1) = (double) numelem;
six_faux_entiers(2) = (double) numail;
six_faux_entiers(3) = (double) tyfront;
six_faux_entiers(4) = (double) num_front;
six_faux_entiers(5) = (double) SM_transfert.Taille();
six_faux_entiers(6) = (double) index_transfert;
// on transmet les numéros d'élément et de maillage etc.
reqs1 = six_faux_entiers.Ienvoi_MPI(0, 34);
// // debug
// cout << "\n debug Charge::Transfert_SM( proc= "<< ParaGlob::Monde()->rank()
// << " six_faux_entiers= " << six_faux_entiers
// << " SM_transfert= " << SM_transfert << flush;
// // fin debug
temps_transfert_court.Arret_du_comptage(); // fin comptage cpu
// puis on transmets le vecteur résidu
temps_transfert_long.Mise_en_route_du_comptage(); // comptage cpu
reqs2 = SM_transfert.Ienvoi_MPI(0,35);
// puis on transmets éventuellementla matrice de raideur
if (MAT_transfert != NULL)
reqs3 = MAT_transfert->Ienvoi_MPI(0,36);
// ici on utilise un nouveau élément de tableau pour éviter d'écraser la précédente version qui peut être encore
// en transfert vers le proc 0
index_transfert++;
if (index_transfert > taille_tableau) // on fait une permutation circulaire
index_transfert = 1;// on revient au premier élément des tableaux de transfert
temps_transfert_long.Arret_du_comptage(); // fin comptage cpu
};
#endif

51
herezh_pp/Chargement/Charge.h → Chargement/Charge.h Executable file → Normal file
View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -257,6 +257,13 @@ class Charge
void Change_temps_fin_non_stricte(int methode)
{temps_fin_non_stricte = methode;};
#ifdef UTILISATION_MPI
// cas d'un calcul parallèle: // passage des infos entre process
const Temps_CPU_HZpp& Temps_transfert_court() const {return temps_transfert_court;} ;
const Temps_CPU_HZpp& Temps_transfert_long() const {return temps_transfert_long;} ;
const Temps_CPU_HZpp& Temps_attente() const {return temps_attente;} ;
#endif
// retourne le temps cumulés relatif à tous les chargements
const Temps_CPU_HZpp& Temps_cpu_chargement() const {return temps_cpu_chargement;};
@ -362,7 +369,47 @@ class Charge
// de la variation du pas de temps
// mise à jour avec la méthode : Change_temps_fin_non_stricte(int methode)
Temps_CPU_HZpp temps_cpu_chargement; // le temps cpu du à tous les chargements
Temps_CPU_HZpp temps_cpu_chargement; // le temps cpu du à tous les chargements
#ifdef UTILISATION_MPI
// cas d'un calcul parallèle: // passage des infos entre process
Temps_CPU_HZpp temps_transfert_court ;
Temps_CPU_HZpp temps_transfert_long ;
Temps_CPU_HZpp temps_attente ;
// on définit les conteneurs de passage d'info
Tableau <mpi::request > tab_reqs1;
Tableau <mpi::request > tab_reqs2;
Tableau <mpi::request > tab_reqs3;
Tableau <Vecteur > tabV_transfert;
Tableau <Mat_pleine> tabMat_transfert;
Tableau <Vecteur > tab_six_faux_entiers;
// transfert du second membre "SM_transfert" et mise à jour
// de l'index des tableaux "index_transfert" par rotation cyclique
// NB: tous les tableaux doivent avoir la même taille
void Transfert_SM(bool& premier_passage,
const int& tyfront,
const int& num_front,
Vecteur & SM_transfert,
int& index_transfert,
const int & numail,
const int & numelem
);
// transfert du second membre "SM_transfert" et de la matrice "MAT_transfert" et mise à jour
// de l'index des tableaux "index_transfert" par rotation cyclique
// NB: tous les tableaux doivent avoir la même taille
void Transfert_MatSm(bool& premier_passage,
const int& tyfront,
const int& num_front,
Vecteur & SM_transfert,
Mat_pleine * MAT_transfert,
int& index_transfert,
const int & numail,
const int & numelem
);
#endif
// les autres parametres relatif au temps
//-// double deltatmaxi; // increment de temps maxi

1428
herezh_pp/Chargement/Charge2.cc → Chargement/Charge2.cc Executable file → Normal file

File diff suppressed because it is too large Load diff

122
herezh_pp/Chargement/Charge3.cc → Chargement/Charge3.cc Executable file → Normal file
View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -1256,19 +1256,31 @@ void Charge::Precedent7()
int Charge::Fin1(const int & icharge,bool affichage)
{ double temps = paAlgo->Variables_de_temps().TempsCourant();
if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
{ if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{ cout << "\n >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps << endl ;};
return 1;
}
// else if (icharge >= paAlgo->Maxincre())
else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
{if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
<< "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
<< endl ;
return 2;
}
else if (compteur_essai_increment > paAlgo->Max_essai_incre())
{if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
return 3;
}
else
@ -1277,17 +1289,25 @@ int Charge::Fin1(const int & icharge,bool affichage)
int Charge::Fin2(const int & icharge,bool affichage)
{ double temps = paAlgo->Variables_de_temps().TempsCourant();
if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
{ if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{ cout << "\n >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps << endl ;};
return 1;
}
}
// else if (icharge >= paAlgo->Maxincre())
else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
{if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
<< "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
<< endl ;
return 2;
}
}
else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
{if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
return 3;
@ -1298,42 +1318,66 @@ int Charge::Fin2(const int & icharge,bool affichage)
int Charge::Fin3(const int & icharge,bool affichage)
{ double temps = paAlgo->Variables_de_temps().TempsCourant();
if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
{ if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{ cout << "\n >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps << endl ;};
return 1;
}
}
// else if (icharge >= paAlgo->Maxincre())
else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
{if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
<< "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
<< endl ;
return 2;
return 2;
}
else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
{if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
return 3;
}
}
else
return 0;
};
int Charge::Fin4(const int & icharge,bool affichage)
{ double temps = paAlgo->Variables_de_temps().TempsCourant();
if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
{ if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{ cout << "\n >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps << endl ;};
return 1;
}
}
// else if (icharge >= paAlgo->Maxincre())
else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
{if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
<< "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
<< endl ;
return 2;
}
return 2;
}
else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
{if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
return 3;
}
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
return 3;
}
else
return 0;
};
@ -1342,25 +1386,41 @@ int Charge::Fin5(const int & icharge,bool affichage)
CourbePolyLineaire1D* fconnue_charge = (CourbePolyLineaire1D*) f_charge;
double temps = paAlgo->Variables_de_temps().TempsCourant(); // puis le temps
if ((temps > paAlgo->Tempsfin()) || (Dabs(temps - paAlgo->Tempsfin()) <= paAlgo->Prectemps()))
{ if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if ((ParaGlob::NiveauImpression() >= 1)&& affichage)
{ cout << "\n >>>> temps fin ("<<paAlgo->Tempsfin()<<") atteint <<<<< " << temps << endl ;};
return 1;
}
}
else if ( num_pt_courant_type5 == fconnue_charge->NombrePoint())
{ if (affichage) cout << "\n >>>> dernier temps de la courbe de charge atteint <<<<< " << endl ;
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n >>>> dernier temps de la courbe de charge atteint <<<<< " << endl ;
return 1;
}
}
// else if (icharge >= paAlgo->Maxincre())
else if (icharge > paAlgo->Maxincre()) // modif 14 sept 2015
{if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n maximum d'increments fixes atteint : "<< paAlgo->Maxincre()
<< "\n (pour info: maximum d'essai calcul increments = "<< paAlgo->Max_essai_incre()<<") "
<< endl ;
return 2;
return 2;
}
else if (compteur_essai_increment >= paAlgo->Max_essai_incre())
{if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
return 3;
}
{
#ifdef UTILISATION_MPI
if (ParaGlob::Monde()->rank() == 0)
#endif
if (affichage) cout << "\n maximum d'essai d'increments fixes atteint : "<< paAlgo->Max_essai_incre() << endl ;
return 3;
}
else
return 0;
};

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

43
herezh_pp/Elements/Element.cc → Elements/Element.cc Executable file → Normal file
View file

@ -11,7 +11,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -792,7 +792,7 @@ Element::operator= (Element& elt)
// en 2D: quadrangle: racine carré de la surface; triangle: racine carré de 2*surface
// en 3D: hexa: racine cubique de vol; penta: racine cub de 2*vol, tétra: racine cub 6*vol
// cas = 3: 1D idem cas 2, 2D: distance mini noeud arrête opposée, 3D: distance mini noeud face opposé
double Element::LongueurGeometrique(int cas) const
double Element::LongueurGeometrique_mini(int cas) const
{ double longueur=0.; // valeur de retour
switch (cas)
{ case 1:
@ -823,7 +823,7 @@ double Element::LongueurGeometrique(int cas) const
// traitement d'une erreur éventuelle
if (dist <= ConstMath::petit)
{ cout << "\n **** ERREUR une longueur d'arrête de l'element est nulle"
<< "\n Element::LongueurGeometrique(int cas)"
<< "\n Element::LongueurGeometrique_mini(int cas)"
<< "\n element: "; this->Affiche(1);
#ifdef MISE_AU_POINT
cout << "\n *** version mise au point: on continue neanmoins avec une longueur "
@ -837,7 +837,7 @@ double Element::LongueurGeometrique(int cas) const
}
default :
cout << "\nErreur : cas:" << cas <<" non encore traite !\n"
<< "Element::LongueurGeometrique(int cas) ) \n";
<< "Element::LongueurGeometrique_mini(int cas) ) \n";
Sortie(1);
}
//cout << " longueur= "<< longueur << endl;
@ -917,29 +917,34 @@ int Element::Num_de_frontiere_dans_le_type(int i) const
{ // on supprime les cas hors du tableau tabb
if (i<1) return 0;
int tailletab = tabb.Taille();
if (i>tailletab) return 0;
// cas normal
if (i <= posi_tab_front_lin)
// cela veut dire que i est une surface car les premières frontières sont les surfaces, de plus i est directement le numéro de surface
{ return i;}
else if (i <= posi_tab_front_point)
// cela veut dire que i est une ligne car les frontières après les surfaces sont les lignes
{ return (i-posi_tab_front_lin); }
else
// cela veut dire que i est un point car les frontières après les lignes sont des points
{ return (i-posi_tab_front_point);};
};
if (i>tailletab) return 0;
// cas normal
if (i <= posi_tab_front_lin)
// cela veut dire que i est une surface car les premières frontières sont les surfaces, de plus i est directement le numéro de surface
{ return i;}
else if (i <= posi_tab_front_point)
// cela veut dire que i est une ligne car les frontières après les surfaces sont les lignes
{ return (i-posi_tab_front_lin); }
else
// cela veut dire que i est un point car les frontières après les lignes sont des points
{ return (i-posi_tab_front_point);};
};
// ramene le numero de la frontière passée en argument si elle existe actuellement au niveau de l'élément
// sinon ramène 0
// ramene également type_front: qui indique le type de frontière: POINT_G, LIGNE ou SURFACE
// c'est une méthode très longue, a utiliser avec précaution
int Element::Num_frontiere(const ElFrontiere& fronti, Enum_type_geom& type_front)
int Element::Num_frontiere(const ElFrontiere& fronti, Enum_type_geom& type_front) const
{ int num=0; type_front = RIEN_TYPE_GEOM; // initialisation du retour
// on commence par balayer toutes les frontières pour trouver le numéro global
int tail_tab=tabb.Taille();
for (int i=1;i<=tail_tab;i++)
if (fronti == (*tabb(i))) {num = i; break;}
{// le tableau global peut avoir été correctement dimensionné
// mais les éléments frontières peuvent avoir été supprimés
if (tabb(i) != NULL) // cas où la frontière existe
{if (fronti == (*tabb(i))) {num = i; break;}
}
};
// si num est diff de 0 c'est ok, on recherche le type de frontière
if (num != 0)
{ // les frontières sont rangées selon: surface, ligne, point
@ -950,7 +955,7 @@ int Element::Num_frontiere(const ElFrontiere& fronti, Enum_type_geom& type_front
else if ((num > posi_tab_front_lin)&&(ind_front_lin!=0)) {type_front = LIGNE;num -= posi_tab_front_lin;}
// si ce n'est ni un point ni une ligne, vue que ça doit-être quelque chose ça ne peut être qu'une surface
else {type_front = SURFACE;}; // et num a directement la bonne valeur que ce sont d'abord les faces qui sont stockées
}
};
// retour des infos
return num;
};

33
herezh_pp/Elements/Element.h → Elements/Element.h Executable file → Normal file
View file

@ -10,7 +10,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -39,6 +39,8 @@
#ifndef ELEMENT_H
#define ELEMENT_H
using namespace std;
#include <iostream>
#include <stdlib.h>
@ -297,6 +299,8 @@ class Element
// pour le schema implicite
class ResRaid { public : Vecteur* res; Mat_pleine * raid ; };
virtual ResRaid Calcul_implicit (const ParaAlgoControle & pa ) = 0;
// récup uniquement du conteneur raideur (pas forcément rempli, mais de la bonne taille)
Mat_pleine * Conteneur_raideur () {return raideur; };
// Calcul du residu local a l'instant t
// pour le schema explicit, resultat dans le vecteur pointe
@ -305,7 +309,9 @@ class Element
// Calcul du residu local a l'instant tdt
// pour le schema explicit, resultat dans le vecteur pointe
virtual Vecteur* CalculResidu_tdt (const ParaAlgoControle & pa) = 0;
// récup uniquement du conteneur résidu (pas forcément rempli, mais de la bonne taille)
Vecteur* Conteneur_Residu () {return residu;};
// Calcul de la matrice masse pour l'élément
virtual Mat_pleine * CalculMatriceMasse (Enum_calcul_masse id_calcul_masse) = 0;
@ -336,7 +342,7 @@ class Element
// en 2D: quadrangle: racine carré de la surface; triangle: racine carré de 2*surface
// en 3D: hexa: racine cubique de vol; penta: racine cub de 2*vol, tétra: racine cub 6*vol
// cas = 3: 1D idem cas 2, 2D: distance mini noeud arrête opposée, 3D: distance mini noeud face opposé
double LongueurGeometrique(int cas) const;
double LongueurGeometrique_mini(int cas) const;
// récupération du volume de l'élément (qui doit avoir été calculé dans une des classes dérivées
// par exemple en mécanique via un calcul explicite ou implicite d'équilibre mécanique
// pour un élément 3D: le volume au sens classique
@ -601,14 +607,14 @@ class Element
// ============ Calcul des frontieres de l'element================
// tout d'abord une explication sur la terminologie
// on appelle frontières de l'éléments les frontières naturelles c'est-à-dire
// on appelle frontières minimales de l'éléments les frontières naturelles c'est-à-dire
// pour les éléments 1D : les noeuds aux l'extrémitées en monde 1D
// sinon également l'élément en monde 2D et 3D
// pour les éléments 2D : les arrêtes de l'élément en monde 2D
// sinon également la surface de l'élément en monde 2D et 3D
// pour les éléments 3D : les surfaces externes de l'élément
// Calcul des frontieres de l'element et retour d'un tableau tabb des frontières
// Calcul des frontieres minimales de l'element et retour d'un tableau tabb des frontières
// creation des elements frontieres et stockage dans l'element
// si c'est la première fois sinon il y a seulement retour du tableau de ces elements
// a moins que le paramètre force est mis a true dans ce dernier cas seul les frontière effacées sont recréée
@ -675,7 +681,22 @@ class Element
// sinon ramène 0
// ramene également type_front: qui indique le type de frontière: POINT_G, LIGNE ou SURFACE
// c'est une méthode très longue, a utiliser avec précaution
int Num_frontiere(const ElFrontiere& fronti, Enum_type_geom& type_front);
int Num_frontiere(const ElFrontiere& fronti, Enum_type_geom& type_front) const;
// Calcul spécifiques des frontieres de l'element et retour d'un tableau tabb des frontières
// creation des elements frontieres et stockage dans l'element
// la création n'a lieu qu'au premier appel
// ou lorsque l'on force le paramètre force a true
// dans ce dernier cas seul les frontière effacées sont recréée
// cas :
// = 0 -> on veut toutes les frontières
// = 1 -> on veut uniquement les surfaces
// = 2 -> on veut uniquement les lignes
// = 3 -> on veut uniquement les points
// = 4 -> on veut les surfaces + les lignes
// = 5 -> on veut les surfaces + les points
// = 6 -> on veut les lignes + les points
// virtual Tableau <ElFrontiere*> const & Frontiere_specifique(int cas, bool force = false) = 0;
// mise à jour de la boite d'encombrement de l'élément, suivant les axes I_a globales
// en retour coordonnées du point mini dans retour.Premier() et du point maxi dans .Second()

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -114,13 +114,13 @@ class ElemGeomC0
// retourne les coordonnees du point d'integration i
inline Coordonnee const & CoorPtInteg(int i) const { return ptInteg(i);};
// retourne les fonctions d'interpolation au point d'integration i
inline Vecteur const & Phi(int i) { return tabPhi(i);};
inline Vecteur const & Phi(int i) const { return tabPhi(i);};
// retourne les tableau de fonctions d'interpolation
inline Tableau <Vecteur> const & TaPhi() const { return tabPhi;};
// retourne les derivees des fonctions d'interpolation au point d'integration i
inline Mat_pleine const& Dphi(int i) { return tabDPhi(i);};
// retourne le tableau des derivees des fonctions d'interpolation
inline Tableau < Mat_pleine > const& TaDphi() { return tabDPhi;};
inline Tableau < Mat_pleine > const& TaDphi() const { return tabDPhi;};
// retourne les poids d'integration du point d'integration i
inline double Wi(int i) const { return WI(i);};
// retourne le vecteur des poids d'integration
@ -200,9 +200,9 @@ class ElemGeomC0
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
virtual const Vecteur& Phi(const Coordonnee& M) = 0;
virtual const Vecteur& Phi_point(const Coordonnee& M) = 0;
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
virtual const Mat_pleine& Dphi(const Coordonnee& M) = 0;
virtual const Mat_pleine& Dphi_point(const Coordonnee& M) = 0;
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
virtual bool Interieur(const Coordonnee& M) = 0;

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -339,7 +339,7 @@ ElemGeomC0 * GeomSeg::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomSeg::Phi(const Coordonnee& M)
const Vecteur& GeomSeg::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -381,7 +381,7 @@ const Vecteur& GeomSeg::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomSeg::Dphi(const Coordonnee& M)
const Mat_pleine& GeomSeg::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -114,9 +114,9 @@ class GeomSeg : public ElemGeomC0
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
bool Interieur(const Coordonnee& M);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -82,7 +82,7 @@ ElemGeomC0 * GeomPoint::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomPoint::Phi(const Coordonnee& M)
const Vecteur& GeomPoint::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -99,7 +99,7 @@ const Vecteur& GeomPoint::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomPoint::Dphi(const Coordonnee& M)
const Mat_pleine& GeomPoint::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -84,9 +84,9 @@ class GeomPoint : public ElemGeomC0
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
bool Interieur(const Coordonnee& M);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -531,7 +531,7 @@ ElemGeomC0 * GeomQuadrangle::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomQuadrangle::Phi(const Coordonnee& M)
const Vecteur& GeomQuadrangle::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -559,7 +559,7 @@ const Vecteur& GeomQuadrangle::Phi(const Coordonnee& M)
Vecteur tabPhiT(NBNE);
for (int iy = 1;iy<= nbnes; iy++)
for (int ix =1;ix<=nbnes;ix++)
{ tabPhiT(ne) = seg(1)->Phi(X)(ix) * seg(1)->Phi(Y)(iy);
{ tabPhiT(ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Phi_point(Y)(iy);
ne++;
}
// numerotation suivant le standard habituel
@ -644,7 +644,7 @@ const Vecteur& GeomQuadrangle::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomQuadrangle::Dphi(const Coordonnee& M)
const Mat_pleine& GeomQuadrangle::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -673,8 +673,8 @@ const Mat_pleine& GeomQuadrangle::Dphi(const Coordonnee& M)
Mat_pleine tabDPhiT(2,NBNE);
for (int iy = 1;iy<= nbnes; iy++)
for (int ix =1;ix<=nbnes;ix++)
{ tabDPhiT(1,ne) = seg(1)->Dphi(X)(1,ix) * seg(1)->Phi(Y)(iy);
tabDPhiT(2,ne) = seg(1)->Phi(X)(ix) * seg(1)->Dphi(Y)(1,iy);
{ tabDPhiT(1,ne) = seg(1)->Dphi_point(X)(1,ix) * seg(1)->Phi_point(Y)(iy);
tabDPhiT(2,ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Dphi_point(Y)(1,iy);
ne++;
}
// numerotation suivant le standard habituel

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -162,9 +162,9 @@ class GeomQuadrangle : public ElemGeomC0
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
bool Interieur(const Coordonnee& M);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -590,7 +590,7 @@ ElemGeomC0 * GeomTriangle::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomTriangle::Phi(const Coordonnee& M)
const Vecteur& GeomTriangle::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -692,7 +692,7 @@ const Vecteur& GeomTriangle::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomTriangle::Dphi(const Coordonnee& M)
const Mat_pleine& GeomTriangle::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -147,9 +147,9 @@ class GeomTriangle : public ElemGeomC0
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
bool Interieur(const Coordonnee& M);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -172,9 +172,9 @@ GeomHexaCubique::GeomHexaCubique(int nbi) :
// on utilise les méthodes internes pour calculer les fonctions
// d'interpolation aux points d'intégrations
for (int ptint=1;ptint<= Nbi(); ptint++)
tabPhi(ptint) = Phi( ptInteg(ptint));
tabPhi(ptint) = Phi_point( ptInteg(ptint));
for (int ptint=1;ptint<= Nbi(); ptint++)
tabDPhi(ptint) = Dphi( ptInteg(ptint));
tabDPhi(ptint) = Dphi_point( ptInteg(ptint));
// ---- constitution du tableau Extrapol -----
Calcul_extrapol(nbi);
@ -246,7 +246,7 @@ ElemGeomC0 * GeomHexaCubique::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomHexaCubique::Phi(const Coordonnee& M)
const Vecteur& GeomHexaCubique::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -274,7 +274,7 @@ const Vecteur& GeomHexaCubique::Phi(const Coordonnee& M)
for (int iz = 1;iz<= nbnes; iz++)
for (int iy = 1;iy<= nbnes; iy++)
for (int ix =1;ix<=nbnes;ix++)
{ tabPhiT(ne) = seg(1)->Phi(X)(ix) * seg(1)->Phi(Y)(iy) * seg(1)->Phi(Z)(iz);
{ tabPhiT(ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Phi_point(Y)(iy) * seg(1)->Phi_point(Z)(iz);
ne++;
}
// numerotation suivant le standard habituel
@ -307,7 +307,7 @@ const Vecteur& GeomHexaCubique::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomHexaCubique::Dphi(const Coordonnee& M)
const Mat_pleine& GeomHexaCubique::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -336,9 +336,9 @@ const Mat_pleine& GeomHexaCubique::Dphi(const Coordonnee& M)
for (int iz = 1;iz<= nbnes; iz++)
for (int iy = 1;iy<= nbnes; iy++)
for (int ix =1;ix<=nbnes;ix++)
{ tabDPhiT(1,ne) = seg(1)->Dphi(X)(1,ix) * seg(1)->Phi(Y)(iy) * seg(1)->Phi(Z)(iz);
tabDPhiT(2,ne) = seg(1)->Phi(X)(ix) * seg(1)->Dphi(Y)(1,iy) * seg(1)->Phi(Z)(iz);
tabDPhiT(3,ne) = seg(1)->Phi(X)(ix) * seg(1)->Phi(Y)(iy) * seg(1)->Dphi(Z)(1,iz);
{ tabDPhiT(1,ne) = seg(1)->Dphi_point(X)(1,ix) * seg(1)->Phi_point(Y)(iy) * seg(1)->Phi_point(Z)(iz);
tabDPhiT(2,ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Dphi_point(Y)(1,iy) * seg(1)->Phi_point(Z)(iz);
tabDPhiT(3,ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Phi_point(Y)(iy) * seg(1)->Dphi_point(Z)(1,iz);
ne++;
}
// numerotation suivant le standard habituel

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -59,7 +59,7 @@
// l'élément cubique complet
/*
//***********************************************************************
// ***********************************************************************
// *
// ELEMENT DE REFERENCE , POINTS D'INTEGRATION: *
// *
@ -262,9 +262,9 @@ class GeomHexaCubique : public GeomHexaCom
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
protected :

View file

@ -10,7 +10,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -146,21 +146,21 @@ GeomHexaQuad::GeomHexaQuad(int nbi) :
{ // on utilise les méthodes internes pour calculer les fonctions
// d'interpolation aux points d'intégrations
for (int ptint=1;ptint<= Nbi(); ptint++)
tabPhi(ptint) = Phi( ptInteg(ptint));
tabPhi(ptint) = Phi_point( ptInteg(ptint));
for (int ptint=1;ptint<= Nbi(); ptint++)
tabDPhi(ptint) = Dphi( ptInteg(ptint));
tabDPhi(ptint) = Dphi_point( ptInteg(ptint));
}
// vérification suivant OK a priori
// essai de calcul directe des fonctions d'interpolation
for (int ptint=1;ptint<= Nbi(); ptint++)
tabPhi(ptint) = Phi( ptInteg(ptint));
tabPhi(ptint) = Phi_point( ptInteg(ptint));
for (int ptint=1;ptint<= Nbi(); ptint++)
tabDPhi(ptint) = Dphi( ptInteg(ptint)); //*/
tabDPhi(ptint) = Dphi_point( ptInteg(ptint)); //*/
// vérification des fonctions d'interpolation analytique et numériques
for (int ptint=1;ptint<= Nbi(); ptint++)
{
Vecteur a = tabPhi(ptint);Vecteur b = Phi( ptInteg(ptint));
Vecteur a = tabPhi(ptint);Vecteur b = Phi_point( ptInteg(ptint));
for (int ne=1;ne<= NBNE;ne++)
if (Dabs(a(ne) - b(ne)) >= 1.E-14)
{
@ -173,7 +173,7 @@ GeomHexaQuad::GeomHexaQuad(int nbi) :
// et numériques
for (int ptint=1;ptint<= Nbi(); ptint++)
{
Mat_pleine a = tabDPhi(ptint);Mat_pleine b = Dphi( ptInteg(ptint));
Mat_pleine a = tabDPhi(ptint);Mat_pleine b = Dphi_point( ptInteg(ptint));
for (int ne=1;ne<= NBNE;ne++)
for (int ia =1; ia<= 3; ia++)
if (Dabs(a(ia,ne) - b(ia,ne)) >= 1.E-14)
@ -218,7 +218,7 @@ ElemGeomC0 * GeomHexaQuad::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomHexaQuad::Phi(const Coordonnee& M)
const Vecteur& GeomHexaQuad::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -275,7 +275,7 @@ const Vecteur& GeomHexaQuad::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomHexaQuad::Dphi(const Coordonnee& M)
const Mat_pleine& GeomHexaQuad::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -428,7 +428,7 @@ void GeomHexaQuad::Calcul_extrapol(int nbi)
// maintenant on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta
const Vecteur& phiphi = hexa.Phi(theta);
const Vecteur& phiphi = hexa.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(8);
tab(ne).Change_taille(nbi);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -239,9 +239,9 @@ class GeomHexaQuad : public GeomHexaCom
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
protected :

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -149,9 +149,9 @@ GeomHexaQuadComp::GeomHexaQuadComp(int nbi) :
// on utilise les méthodes internes pour calculer les fonctions
// d'interpolation aux points d'intégrations
for (int ptint=1;ptint<= Nbi(); ptint++)
tabPhi(ptint) = Phi( ptInteg(ptint));
tabPhi(ptint) = Phi_point( ptInteg(ptint));
for (int ptint=1;ptint<= Nbi(); ptint++)
tabDPhi(ptint) = Dphi( ptInteg(ptint));
tabDPhi(ptint) = Dphi_point( ptInteg(ptint));
// ---- constitution du tableau Extrapol -----
Calcul_extrapol(nbi);
@ -223,7 +223,7 @@ ElemGeomC0 * GeomHexaQuadComp::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomHexaQuadComp::Phi(const Coordonnee& M)
const Vecteur& GeomHexaQuadComp::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -251,7 +251,7 @@ const Vecteur& GeomHexaQuadComp::Phi(const Coordonnee& M)
for (int iz = 1;iz<= nbnes; iz++)
for (int iy = 1;iy<= nbnes; iy++)
for (int ix =1;ix<=nbnes;ix++)
{ tabPhiT(ne) = seg(1)->Phi(X)(ix) * seg(1)->Phi(Y)(iy) * seg(1)->Phi(Z)(iz);
{ tabPhiT(ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Phi_point(Y)(iy) * seg(1)->Phi_point(Z)(iz);
ne++;
}
// numerotation suivant le standard habituel
@ -284,7 +284,7 @@ const Vecteur& GeomHexaQuadComp::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomHexaQuadComp::Dphi(const Coordonnee& M)
const Mat_pleine& GeomHexaQuadComp::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -313,9 +313,9 @@ const Mat_pleine& GeomHexaQuadComp::Dphi(const Coordonnee& M)
for (int iz = 1;iz<= nbnes; iz++)
for (int iy = 1;iy<= nbnes; iy++)
for (int ix =1;ix<=nbnes;ix++)
{ tabDPhiT(1,ne) = seg(1)->Dphi(X)(1,ix) * seg(1)->Phi(Y)(iy) * seg(1)->Phi(Z)(iz);
tabDPhiT(2,ne) = seg(1)->Phi(X)(ix) * seg(1)->Dphi(Y)(1,iy) * seg(1)->Phi(Z)(iz);
tabDPhiT(3,ne) = seg(1)->Phi(X)(ix) * seg(1)->Phi(Y)(iy) * seg(1)->Dphi(Z)(1,iz);
{ tabDPhiT(1,ne) = seg(1)->Dphi_point(X)(1,ix) * seg(1)->Phi_point(Y)(iy) * seg(1)->Phi_point(Z)(iz);
tabDPhiT(2,ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Dphi_point(Y)(1,iy) * seg(1)->Phi_point(Z)(iz);
tabDPhiT(3,ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Phi_point(Y)(iy) * seg(1)->Dphi_point(Z)(1,iz);
ne++;
}
// numerotation suivant le standard habituel
@ -435,7 +435,7 @@ void GeomHexaQuadComp::Calcul_extrapol(int nbi)
// maintenant on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta
const Vecteur& phiphi = hexa.Phi(theta);
const Vecteur& phiphi = hexa.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(8);
tab(ne).Change_taille(nbi);
@ -738,7 +738,7 @@ void GeomHexaQuadComp::Calcul_extrapol(int nbi)
// maintenant on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta
const Vecteur& phiphi = hexa.Phi(theta);
const Vecteur& phiphi = hexa.Phi_point(theta);
// et on enregistre
// on boucle sur les pti de l'hexa linéaire d'interpolation
tab(ne).Change_taille(nbi);
@ -991,7 +991,7 @@ void GeomHexaQuadComp::Calcul_extrapol(int nbi)
}
// maintenant on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta
const Vecteur& phiphi = hexa.Phi(theta);
const Vecteur& phiphi = hexa.Phi_point(theta);
// et on enregistre
tab(ne).Change_taille(nbi);
// on boucle sur les pti de l'hexa linéaire d'interpolation

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -60,7 +60,7 @@
/*
//***********************************************************************
// ***********************************************************************
// *
// ELEMENT DE REFERENCE , POINTS D'INTEGRATION: *
// *
@ -243,9 +243,9 @@ class GeomHexaQuadComp : public GeomHexaCom
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
protected :

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -114,9 +114,9 @@ GeomHexalin::GeomHexalin(int nbi ) :
{ // on utilise les méthodes internes pour calculer les fonctions
// d'interpolation aux points d'intégrations
for (int ptint=1;ptint<= Nbi(); ptint++)
tabPhi(ptint) = Phi( ptInteg(ptint));
tabPhi(ptint) = Phi_point( ptInteg(ptint));
for (int ptint=1;ptint<= Nbi(); ptint++)
tabDPhi(ptint) = Dphi( ptInteg(ptint));
tabDPhi(ptint) = Dphi_point( ptInteg(ptint));
};
// ---- constitution du tableau Extrapol -----
@ -153,7 +153,7 @@ ElemGeomC0 * GeomHexalin::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomHexalin::Phi(const Coordonnee& M)
const Vecteur& GeomHexalin::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -180,7 +180,7 @@ const Vecteur& GeomHexalin::Phi(const Coordonnee& M)
for (int iz = 1;iz<= nbnes; iz++)
for (int iy = 1;iy<= nbnes; iy++)
for (int ix =1;ix<=nbnes;ix++)
{ tabPhiT(ne) = seg(1)->Phi(X)(ix) * seg(1)->Phi(Y)(iy) * seg(1)->Phi(Z)(iz);
{ tabPhiT(ne) = seg(1)->Phi_point(X)(ix) * seg(1)->Phi_point(Y)(iy) * seg(1)->Phi_point(Z)(iz);
ne++;
}
// numerotation suivant le standard habituel
@ -202,7 +202,7 @@ const Vecteur& GeomHexalin::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomHexalin::Dphi(const Coordonnee& M)
const Mat_pleine& GeomHexalin::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -234,12 +234,12 @@ const Mat_pleine& GeomHexalin::Dphi(const Coordonnee& M)
//tabDPhiT(2,ne) = seg(1)->Phi(X)(ix) * seg(1)->Dphi(Y)(1,iy) * seg(1)->Phi(Z)(iz);
//tabDPhiT(3,ne) = seg(1)->Phi(X)(ix) * seg(1)->Phi(Y)(iy) * seg(1)->Dphi(Z)(1,iz);
double phi_X_ix = seg(1)->Phi(X)(ix);
double phi_Y_iy = seg(1)->Phi(Y)(iy);
double phi_Z_iz = seg(1)->Phi(Z)(iz);
tabDPhiT(1,ne) = seg(1)->Dphi(X)(1,ix) * phi_Y_iy * phi_Z_iz;
tabDPhiT(2,ne) = phi_X_ix * seg(1)->Dphi(Y)(1,iy) * phi_Z_iz;
tabDPhiT(3,ne) = phi_X_ix * phi_Y_iy * seg(1)->Dphi(Z)(1,iz);
double phi_X_ix = seg(1)->Phi_point(X)(ix);
double phi_Y_iy = seg(1)->Phi_point(Y)(iy);
double phi_Z_iz = seg(1)->Phi_point(Z)(iz);
tabDPhiT(1,ne) = seg(1)->Dphi_point(X)(1,ix) * phi_Y_iy * phi_Z_iz;
tabDPhiT(2,ne) = phi_X_ix * seg(1)->Dphi_point(Y)(1,iy) * phi_Z_iz;
tabDPhiT(3,ne) = phi_X_ix * phi_Y_iy * seg(1)->Dphi_point(Z)(1,iz);
ne++;
}
@ -345,7 +345,7 @@ void GeomHexalin::Calcul_extrapol(int nbi)
// maintenant on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta
const Vecteur& phiphi = this->Phi(theta);
const Vecteur& phiphi = this->Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -534,7 +534,7 @@ void GeomHexalin::Calcul_extrapol(int nbi)
}
// maintenant on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta
const Vecteur& phiphi = this->Phi(theta);
const Vecteur& phiphi = this->Phi_point(theta);
// et on enregistre
tab(ne).Change_taille(nbi);
// on boucle sur les pti de l'hexa linéaire d'interpolation
@ -658,7 +658,7 @@ void GeomHexalin::Calcul_extrapol(int nbi)
}
// maintenant on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta
const Vecteur& phiphi = this->Phi(theta);
const Vecteur& phiphi = this->Phi_point(theta);
// et on enregistre
tab(ne).Change_taille(nbi);
// on boucle sur les pti de l'hexa linéaire d'interpolation

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -234,9 +234,9 @@ class GeomHexalin : public GeomHexaCom
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
protected :

View file

@ -9,7 +9,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -113,12 +113,12 @@ bool GeomPentaCom::Interieur(const Coordonnee& M)
// dont les coordonnées sont sur la droite GM: c-a-d GP = alpha GM, avec apha maxi et P appartenant à la frontière
// de l'élément, G étant le centre de gravité, sauf si GM est nul, dans ce cas retour de M
Coordonnee GeomPentaCom::Maxi_Coor_dans_directionGM(const Coordonnee& M)
{ // on décompose la recherche en segment et facette
double x=M(1); double y=M(2); double z=M(3);
// tout d'abord on calcul le point maxi dans le plan 1 2 et dans z indépendemment
Coordonnee XY(x,y); Coordonnee Z(z);
Coordonnee Pxy= face(1)->Maxi_Coor_dans_directionGM(XY);
Coordonnee Pz = seg(1)->Maxi_Coor_dans_directionGM(Z);
{ // on décompose la recherche en segment et facette
double x=M(1); double y=M(2); double z=M(3);
// tout d'abord on calcul le point maxi dans le plan 1 2 et dans z indépendemment
Coordonnee XY(x,y); Coordonnee Z(z);
Coordonnee Pxy= face(1)->Maxi_Coor_dans_directionGM(XY);
Coordonnee Pz = seg(1)->Maxi_Coor_dans_directionGM(Z);
Coordonnee P(0.,0.,0.); // le retour
// G le centre de gravité: il a la cote nulle et il est centre de gravité du triangle médian
@ -143,10 +143,10 @@ Coordonnee GeomPentaCom::Maxi_Coor_dans_directionGM(const Coordonnee& M)
if (gmxy > ConstMath::trespetit)
{ double z_P = z * ( (Pxy-Gxy).Norme()) / gmxy;
if (Abs(z_P) <= 1.) // là c'est ok on sort par un rectangle
{P(1)=Pxy(1); P(2)=Pxy(2); P(3)=z_P;
fin_traitement = true;// pour indiquer que c'est ok
};
};
{P(1)=Pxy(1); P(2)=Pxy(2); P(3)=z_P;
fin_traitement = true;// pour indiquer que c'est ok
};
};
// 2)----
// dans le cas où fin_traitement est toujours faux, cela signifie que le cas sortie par un quadrangle n'a pas marché
// donc cela signifie que le point P est sur la face sup ou inf. En fait cela dépend de z_M si c'est positif alors
@ -155,31 +155,31 @@ Coordonnee GeomPentaCom::Maxi_Coor_dans_directionGM(const Coordonnee& M)
// d'où GPxy = z_P * GMxy/z_M = e (en module) d'où \vec{GPxy} = e * \vec{GMxy)/||GMxy|| = z_P / z_M * \vec{GMxy) d'où P
if (! fin_traitement)
{ if (z > ConstMath::trespetit)
{ // cas d'une sortie par la facette supérieure, z_P = 1.
Coordonnee GPxy = GMxy / z;
P(1) = untiers + GPxy(1); P(2) = untiers + GPxy(2); P(3) = 1.;
fin_traitement = true;// pour indiquer que c'est ok
}
else if (z < -ConstMath::trespetit)
{ // cas d'une sortie par la facette inférieure, z_P = -1.
Coordonnee GPxy = (-1./z) * GMxy ;
P(1) = untiers + GPxy(1); P(2) = untiers + GPxy(2); P(3) = -1.;
fin_traitement = true;// pour indiquer que c'est ok
}
else
// arrivée ici, cela veut dire que z est quasiment nulle, et pourtant due au 1)---
// - soit Abs(z_P) est > 1 , ce qui n'est pas possible car on vient de trouver z quasiment nulle
// - soit gmxy est également quasiment nulle : dans ce cas on choisit arbitrairement P(0,0,0)
{ P.Zero();};
};
{ // cas d'une sortie par la facette supérieure, z_P = 1.
Coordonnee GPxy = GMxy / z;
P(1) = untiers + GPxy(1); P(2) = untiers + GPxy(2); P(3) = 1.;
fin_traitement = true;// pour indiquer que c'est ok
}
else if (z < -ConstMath::trespetit)
{ // cas d'une sortie par la facette inférieure, z_P = -1.
Coordonnee GPxy = (-1./z) * GMxy ;
P(1) = untiers + GPxy(1); P(2) = untiers + GPxy(2); P(3) = -1.;
fin_traitement = true;// pour indiquer que c'est ok
}
else
// arrivée ici, cela veut dire que z est quasiment nulle, et pourtant due au 1)---
// - soit Abs(z_P) est > 1 , ce qui n'est pas possible car on vient de trouver z quasiment nulle
// - soit gmxy est également quasiment nulle : dans ce cas on choisit arbitrairement P(0,0,0)
{ P.Zero();};
};
#ifdef MISE_AU_POINT
if ((P(1) + P(2)) > (1. + ConstMath::petit))
{ cout << "\n petit soucis, le point maxi calcule n'est pas correcte ";
P.Affiche(cout);
cout << "\n GeomPentaCom::Maxi_Coor_dans_directionGM(.." << endl;
};
#endif
#ifdef MISE_AU_POINT
if ((P(1) + P(2)) > (1. + ConstMath::petit))
{ cout << "\n petit soucis, le point maxi calcule n'est pas correcte ";
P.Affiche(cout);
cout << "\n GeomPentaCom::Maxi_Coor_dans_directionGM(.." << endl;
};
#endif
/*
// en fait il y a un pb, car la suite à l'air correcte si on cherche l'intersection de OM avec la frontière

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -115,10 +115,10 @@ GeomPentaL::GeomPentaL(int nbi) :
};
// fonctions d'interpolation globales aux points d'intégrations
for (int ptint=1;ptint<= nbi; ptint++)
tabPhi(ptint) = Phi( ptInteg(ptint));
tabPhi(ptint) = Phi_point( ptInteg(ptint));
// derivees des fonctions d'interpolations aux points d'intégrations
for (int ptint=1;ptint<= nbi; ptint++)
tabDPhi(ptint) = Dphi( ptInteg(ptint));
tabDPhi(ptint) = Dphi_point( ptInteg(ptint));
// ---- constitution du tableau Extrapol -----
Calcul_extrapol(nbi);
@ -158,7 +158,7 @@ ElemGeomC0 * GeomPentaL::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomPentaL::Phi(const Coordonnee& M)
const Vecteur& GeomPentaL::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -182,14 +182,14 @@ const Vecteur& GeomPentaL::Phi(const Coordonnee& M)
int ne = 1;
for (int iz = 1;iz<= nbnel; iz++)
for (int ix = 1;ix<= nbnes; ix++)
{ phi_M(ne) = seg(1)->Phi(Z)(iz) * face(1)->Phi(X)(ix) ;
{ phi_M(ne) = seg(1)->Phi_point(Z)(iz) * face(1)->Phi_point(X)(ix) ;
ne++;
};
// retour de phi_M
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomPentaL::Dphi(const Coordonnee& M)
const Mat_pleine& GeomPentaL::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -213,9 +213,9 @@ const Mat_pleine& GeomPentaL::Dphi(const Coordonnee& M)
int ne = 1;
for (int iz = 1;iz<= nbnel; iz++)
for (int ix = 1;ix<= nbnes; ix++)
{ dphi_M(1,ne) = seg(1)->Phi(Z)(iz) * face(1)->Dphi(X)(1,ix) ;
dphi_M(2,ne) = seg(1)->Phi(Z)(iz) * face(1)->Dphi(X)(2,ix) ;
dphi_M(3,ne) = seg(1)->Dphi(Z)(1,iz) * face(1)->Phi(X)(ix) ;
{ dphi_M(1,ne) = seg(1)->Phi_point(Z)(iz) * face(1)->Dphi_point(X)(1,ix) ;
dphi_M(2,ne) = seg(1)->Phi_point(Z)(iz) * face(1)->Dphi_point(X)(2,ix) ;
dphi_M(3,ne) = seg(1)->Dphi_point(Z)(1,iz) * face(1)->Phi_point(X)(ix) ;
ne++;
};
// retour des derivees
@ -454,7 +454,7 @@ void GeomPentaL::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud de la facette la valeur extrapolée
// maintenant on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre this
const Vecteur& phiphi = this->Phi(theta);
const Vecteur& phiphi = this->Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -504,7 +504,7 @@ void GeomPentaL::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud de la facette la valeur extrapolée
// maintenant on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre this
const Vecteur& phiphi = this->Phi(theta);
const Vecteur& phiphi = this->Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -650,7 +650,7 @@ void GeomPentaL::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = this->Phi(theta);
const Vecteur& phiphi = this->Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(6);
tab(ne).Change_taille(nbi);
@ -752,7 +752,7 @@ void GeomPentaL::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = this->Phi(theta);
const Vecteur& phiphi = this->Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -902,7 +902,7 @@ void GeomPentaL::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = this->Phi(theta);
const Vecteur& phiphi = this->Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -1080,7 +1080,7 @@ void GeomPentaL::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = this->Phi(theta);
const Vecteur& phiphi = this->Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -139,9 +139,9 @@ class GeomPentaL : public GeomPentaCom
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
protected :

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -143,10 +143,10 @@ GeomPentaQ::GeomPentaQ(int nbi) :
// fonctions d'interpolation globales aux points d'intégrations
for (int ptint=1;ptint<= nbi; ptint++)
tabPhi(ptint) = Phi( ptInteg(ptint));
tabPhi(ptint) = Phi_point( ptInteg(ptint));
// derivees des fonctions d'interpolations aux points d'intégrations
for (int ptint=1;ptint<= nbi; ptint++)
tabDPhi(ptint) = Dphi( ptInteg(ptint));
tabDPhi(ptint) = Dphi_point( ptInteg(ptint));
// ---- constitution du tableau Extrapol -----
Calcul_extrapol(nbi);
@ -186,7 +186,7 @@ ElemGeomC0 * GeomPentaQ::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomPentaQ::Phi(const Coordonnee& M)
const Vecteur& GeomPentaQ::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -202,7 +202,7 @@ const Vecteur& GeomPentaQ::Phi(const Coordonnee& M)
phi_M.Change_taille(NBNE); // si la taille est identique -> aucune action
// construction à partir des triangles des faces
Vecteur phisurf=face(1)->Phi(Coordonnee(M(1),M(2)));
Vecteur phisurf=face(1)->Phi_point(Coordonnee(M(1),M(2)));
double KSI = M(1); double ETA = M(2); double DZETA = M(3);
double fsup=(1.+ DZETA)*DZETA/2.; double finf=-(1.-DZETA)*DZETA/2.;
double LAMBDA= 1. - KSI - ETA; double C = 1. - DZETA*DZETA;
@ -250,7 +250,7 @@ const Vecteur& GeomPentaQ::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomPentaQ::Dphi(const Coordonnee& M)
const Mat_pleine& GeomPentaQ::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -266,8 +266,8 @@ const Mat_pleine& GeomPentaQ::Dphi(const Coordonnee& M)
if ((dphi_M.Nb_ligne() != 3)&&(dphi_M.Nb_colonne() != NBNE))
dphi_M.Initialise (3,NBNE,0.);
// construction à partir des triangles des faces
Vecteur phisurf=face(1)->Phi(Coordonnee(M(1),M(2)));
Mat_pleine dphisurf=face(1)->Dphi(Coordonnee(M(1),M(2)));
Vecteur phisurf=face(1)->Phi_point(Coordonnee(M(1),M(2)));
Mat_pleine dphisurf=face(1)->Dphi_point(Coordonnee(M(1),M(2)));
double KSI = M(1); double ETA = M(2); double DZETA = M(3);
double fsup=(1.+ DZETA)*DZETA/2.; double finf=-(1.-DZETA)*DZETA/2.;
double dfsup=(1.+ 2.*DZETA)/2.; double dfinf=(2.*DZETA-1.)/2.;
@ -847,7 +847,7 @@ void GeomPentaQ::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -1013,7 +1013,7 @@ void GeomPentaQ::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(6);
tab(ne).Change_taille(nbi);
@ -1148,7 +1148,7 @@ void GeomPentaQ::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -1316,7 +1316,7 @@ void GeomPentaQ::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -1517,7 +1517,7 @@ void GeomPentaQ::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -139,9 +139,9 @@ class GeomPentaQ : public GeomPentaCom
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
protected :

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -144,10 +144,10 @@ GeomPentaQComp::GeomPentaQComp(int nbi) :
// fonctions d'interpolation globales aux points d'intégrations
for (int ptint=1;ptint<= nbi; ptint++)
tabPhi(ptint) = Phi( ptInteg(ptint));
tabPhi(ptint) = Phi_point( ptInteg(ptint));
// derivees des fonctions d'interpolations aux points d'intégrations
for (int ptint=1;ptint<= nbi; ptint++)
tabDPhi(ptint) = Dphi( ptInteg(ptint));
tabDPhi(ptint) = Dphi_point( ptInteg(ptint));
// ---- constitution du tableau Extrapol -----
Calcul_extrapol(nbi);
@ -187,7 +187,7 @@ ElemGeomC0 * GeomPentaQComp::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomPentaQComp::Phi(const Coordonnee& M)
const Vecteur& GeomPentaQComp::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -214,7 +214,7 @@ const Vecteur& GeomPentaQComp::Phi(const Coordonnee& M)
Vecteur tabPhiT(NBNE);
for (int ifa = 1;ifa<= nbnef; ifa++)
for (int iz = 1;iz<= nbnes; iz++)
{ tabPhiT(ne) = face(1)->Phi(XY)(ifa) * seg(1)->Phi(Z)(iz);
{ tabPhiT(ne) = face(1)->Phi_point(XY)(ifa) * seg(1)->Phi_point(Z)(iz);
ne++;
}
// numerotation suivant le standard habituel
@ -243,7 +243,7 @@ const Vecteur& GeomPentaQComp::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomPentaQComp::Dphi(const Coordonnee& M)
const Mat_pleine& GeomPentaQComp::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -271,9 +271,9 @@ const Mat_pleine& GeomPentaQComp::Dphi(const Coordonnee& M)
Mat_pleine tabDPhiT(3,NBNE);
for (int ifa = 1;ifa<= nbnef; ifa++)
for (int iz = 1;iz<= nbnes; iz++)
{ tabDPhiT(1,ne) = face(1)->Dphi(XY)(1,ifa) * seg(1)->Phi(Z)(iz);
tabDPhiT(2,ne) = face(1)->Dphi(XY)(2,ifa) * seg(1)->Phi(Z)(iz);
tabDPhiT(3,ne) = face(1)->Phi(XY)(ifa) * seg(1)->Dphi(Z)(1,iz);
{ tabDPhiT(1,ne) = face(1)->Dphi_point(XY)(1,ifa) * seg(1)->Phi_point(Z)(iz);
tabDPhiT(2,ne) = face(1)->Dphi_point(XY)(2,ifa) * seg(1)->Phi_point(Z)(iz);
tabDPhiT(3,ne) = face(1)->Phi_point(XY)(ifa) * seg(1)->Dphi_point(Z)(1,iz);
ne++;
}
// numerotation suivant le standard habituel
@ -517,7 +517,7 @@ void GeomPentaQComp::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -698,7 +698,7 @@ void GeomPentaQComp::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(6);
tab(ne).Change_taille(nbi);
@ -843,7 +843,7 @@ void GeomPentaQComp::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -1018,7 +1018,7 @@ void GeomPentaQComp::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);
@ -1223,7 +1223,7 @@ void GeomPentaQComp::Calcul_extrapol(int nbi)
// maintenant on va attribuer au noeud la valeur extrapolée
// on calcule les fct d'interpolation au noeud ne
// via ses coordonnées locales theta: on utilise le pentaèdre linéaire
const Vecteur& phiphi = penta.Phi(theta);
const Vecteur& phiphi = penta.Phi_point(theta);
// et on enregistre
indir(ne).Change_taille(nbi);
tab(ne).Change_taille(nbi);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -141,9 +141,9 @@ class GeomPentaQComp : public GeomPentaCom
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
protected :

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -149,9 +149,9 @@ class GeomHexalin : public ElemGeomC0
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
bool Interieur(const Coordonnee& M);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -106,10 +106,10 @@ GeomTetraL::GeomTetraL(int nbi) :
}
// calcul des fonctions d'interpolations aux points d'intégration
for (int i =1;i<=Nbi();i++)
tabPhi(i)= Phi(ptInteg(i));
tabPhi(i)= Phi_point(ptInteg(i));
// calcul des dérivées des fonctions d'interpolations aux points d'intégration
for (int i =1;i<=Nbi();i++)
tabDPhi(i)= Dphi(ptInteg(i));
tabDPhi(i)= Dphi_point(ptInteg(i));
// ---- constitution du tableau Extrapol -----
Calcul_extrapol(nbi);
};
@ -144,7 +144,7 @@ ElemGeomC0 * GeomTetraL::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomTetraL::Phi(const Coordonnee& M)
const Vecteur& GeomTetraL::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -168,7 +168,7 @@ const Vecteur& GeomTetraL::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomTetraL::Dphi(const Coordonnee& M)
const Mat_pleine& GeomTetraL::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -145,9 +145,9 @@ class GeomTetraL : public GeomTetraCom
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
bool Interieur(const Coordonnee& M);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -122,7 +122,7 @@ GeomTetraQ::GeomTetraQ(int nbi) :
// calcul des fonctions d'interpolations aux points d'intégration
for (int i =1;i<=Nbi();i++)
tabPhi(i)= Phi(ptInteg(i));
tabPhi(i)= Phi_point(ptInteg(i));
////---debug
//// for (int i =1;i<=10;i++)
@ -150,7 +150,7 @@ GeomTetraQ::GeomTetraQ(int nbi) :
// calcul des dérivées des fonctions d'interpolations aux points d'intégration
for (int i =1;i<=Nbi();i++)
tabDPhi(i)= Dphi(ptInteg(i));
tabDPhi(i)= Dphi_point(ptInteg(i));
// ---- constitution du tableau Extrapol -----
Calcul_extrapol(nbi);
};
@ -185,7 +185,7 @@ ElemGeomC0 * GeomTetraQ::newElemGeomC0(ElemGeomC0 * pt)
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& GeomTetraQ::Phi(const Coordonnee& M)
const Vecteur& GeomTetraQ::Phi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales
@ -223,7 +223,7 @@ const Vecteur& GeomTetraQ::Phi(const Coordonnee& M)
return phi_M;
};
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& GeomTetraQ::Dphi(const Coordonnee& M)
const Mat_pleine& GeomTetraQ::Dphi_point(const Coordonnee& M)
{
#ifdef MISE_AU_POINT
// verification de la dimension des coordonnees locales

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -147,9 +147,9 @@ class GeomTetraQ : public GeomTetraCom
//--------- cas de coordonnees locales quelconques ----------------
// retourne les fonctions d'interpolation au point M (en coordonnees locales)
const Vecteur& Phi(const Coordonnee& M);
const Vecteur& Phi_point(const Coordonnee& M);
// retourne les derivees des fonctions d'interpolation au point M (en coordonnees locales)
const Mat_pleine& Dphi(const Coordonnee& M);
const Mat_pleine& Dphi_point(const Coordonnee& M);
// en fonction de coordonnees locales, retourne true si le point est a l'interieur
// de l'element, false sinon
bool Interieur(const Coordonnee& M);

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -91,7 +91,7 @@ bool ElFrontiere::operator == ( const ElFrontiere& a) const
{int ta = this->tabNoeud.Taille(); // nb de noeud
switch (ta)
{ case 1 : // cas d'une frontière point, on simplifie
if (this->tabNoeud(1) == a.tabNoeud(1)) {return true;} else {return false;}
if (this->tabNoeud(1) == a.tabNoeud(1)) {return true;} else {return false;}
break;
case 2 : // cas où la frontière est à 2 noeuds uniquement
{if (this->tabNoeud(1) == a.tabNoeud(1))
@ -102,84 +102,84 @@ bool ElFrontiere::operator == ( const ElFrontiere& a) const
break;
}
default : // les autres cas
{// récup de l'élément géométrique
const ElemGeomC0 & elemgeom = this->ElementGeometrique();
const Tableau <int> & ind = elemgeom.Ind(); // récup du tableau des tranches
int nb_tranche = ind.Taille(); // le nombre d'intervalle de numéros de noeuds constituant la numérotation
// vérification que la taille de toutes les tranches est au moins supérieure à 1
#ifdef MISE_AU_POINT
if (nb_tranche == 0)
{cout << "\n *** erreur, pas de tranche de nb de noeud definie "
<< "\n ElFrontiere::MemeNoeud(... " << endl;
Sortie(1);
};
for (int i1=1;i1<=nb_tranche;i1++)
if (ind(i1) < 1)
{cout << "\n *** erreur, une tranche de nb de noeud est nulle "
<< " tableau ind: " << ind
<< "\n ElFrontiere::MemeNoeud(... " << endl;
Sortie(1);
};
#endif
// on balaie chaque intervalle
int deb_intervalle = 0; int fin_intervalle = 0; // init
for (int iter =1;iter<= nb_tranche;iter++)
{ int tranche = ind(iter);
deb_intervalle = fin_intervalle+1; // mise à jour des bornes de l'intervalle de scrutation
fin_intervalle += tranche; // " "
// on commence par chercher un premier noeud identique dans l'intervalle
bool res = false;
int nd; // indice du cote this
Noeud * ptNoeud_a = a.tabNoeud(deb_intervalle);
for (nd=deb_intervalle; nd<= fin_intervalle; nd++)
{if (this->tabNoeud(nd) == ptNoeud_a)
{ res = true; break; };
};
if (!res) // on arrête de suite si
{return false;}; // on n'a pas trouvé de premier noeud !!
// s'il n'y a qu'un seule noeud dans la tranche, on a finit cette tranche sinon on continue
if (tranche > 1)
{ // on regarde dans quel sens il faut tourner
int ndplus = nd + 1; if (ndplus > fin_intervalle) ndplus -= tranche;
int ndmoins = nd - 1; if (ndmoins < deb_intervalle) ndmoins += tranche;
if (this->tabNoeud(ndplus) == a.tabNoeud(deb_intervalle+1))
{// on est dans le bon sens en augmentant, et c'est ok pour le 2ième noeud,
// continue que s'il y a plus de 2 noeuds dans la tranche
if (tranche > 2)
{ for (int i=1;i<= (tranche-2);i++)
{ ndplus++; if (ndplus > fin_intervalle) ndplus -= tranche;
if (this->tabNoeud(ndplus) != a.tabNoeud(deb_intervalle+i+1))
return false;
};
};
// sinon ok, on vient de balayer tous les noeuds, on continue
}
// le sens 1 ne marche pas , on regarde l'autre sens
else if (this->tabNoeud(ndmoins) == a.tabNoeud(deb_intervalle+1))
{// le bon sens est finalement en diminuant
// continue que s'il y a plus de 2 noeuds dans la tranche
if (tranche > 2)
{ for (int i=1;i<= (tranche-2);i++)
{ ndmoins--; if (ndmoins < deb_intervalle) ndmoins += tranche;
if (this->tabNoeud(ndmoins) != a.tabNoeud(deb_intervalle+i+1))
return false;
};
};
// sinon ok, on vient de balayer tous les noeuds, on continue
}
else // sinon ne marche pas dans les deux sens
{ return false;};
};
}; // fin de la boucle sur les tranches
{// récup de l'élément géométrique
const ElemGeomC0 & elemgeom = this->ElementGeometrique();
const Tableau <int> & ind = elemgeom.Ind(); // récup du tableau des tranches
int nb_tranche = ind.Taille(); // le nombre d'intervalle de numéros de noeuds constituant la numérotation
// vérification que la taille de toutes les tranches est au moins supérieure à 1
#ifdef MISE_AU_POINT
if (nb_tranche == 0)
{cout << "\n *** erreur, pas de tranche de nb de noeud definie "
<< "\n ElFrontiere::MemeNoeud(... " << endl;
Sortie(1);
};
for (int i1=1;i1<=nb_tranche;i1++)
if (ind(i1) < 1)
{cout << "\n *** erreur, une tranche de nb de noeud est nulle "
<< " tableau ind: " << ind
<< "\n ElFrontiere::MemeNoeud(... " << endl;
Sortie(1);
};
#endif
// on balaie chaque intervalle
int deb_intervalle = 0; int fin_intervalle = 0; // init
for (int iter =1;iter<= nb_tranche;iter++)
{ int tranche = ind(iter);
deb_intervalle = fin_intervalle+1; // mise à jour des bornes de l'intervalle de scrutation
fin_intervalle += tranche; // " "
// on commence par chercher un premier noeud identique dans l'intervalle
bool res = false;
int nd; // indice du cote this
Noeud * ptNoeud_a = a.tabNoeud(deb_intervalle);
for (nd=deb_intervalle; nd<= fin_intervalle; nd++)
{if (this->tabNoeud(nd) == ptNoeud_a)
{ res = true; break; };
};
if (!res) // on arrête de suite si
{return false;}; // on n'a pas trouvé de premier noeud !!
// s'il n'y a qu'un seule noeud dans la tranche, on a finit cette tranche sinon on continue
if (tranche > 1)
{ // on regarde dans quel sens il faut tourner
int ndplus = nd + 1; if (ndplus > fin_intervalle) ndplus -= tranche;
int ndmoins = nd - 1; if (ndmoins < deb_intervalle) ndmoins += tranche;
if (this->tabNoeud(ndplus) == a.tabNoeud(deb_intervalle+1))
{// on est dans le bon sens en augmentant, et c'est ok pour le 2ième noeud,
// continue que s'il y a plus de 2 noeuds dans la tranche
if (tranche > 2)
{ for (int i=1;i<= (tranche-2);i++)
{ ndplus++; if (ndplus > fin_intervalle) ndplus -= tranche;
if (this->tabNoeud(ndplus) != a.tabNoeud(deb_intervalle+i+1))
return false;
};
};
// sinon ok, on vient de balayer tous les noeuds, on continue
}
// le sens 1 ne marche pas , on regarde l'autre sens
else if (this->tabNoeud(ndmoins) == a.tabNoeud(deb_intervalle+1))
{// le bon sens est finalement en diminuant
// continue que s'il y a plus de 2 noeuds dans la tranche
if (tranche > 2)
{ for (int i=1;i<= (tranche-2);i++)
{ ndmoins--; if (ndmoins < deb_intervalle) ndmoins += tranche;
if (this->tabNoeud(ndmoins) != a.tabNoeud(deb_intervalle+i+1))
return false;
};
};
// sinon ok, on vient de balayer tous les noeuds, on continue
}
else // sinon ne marche pas dans les deux sens
{ return false;};
};
}; // fin de la boucle sur les tranches
}; // fin du cas courant (default du switch)
}; // fin du switch sur le nombre de noeuds
}
else // le type est different et ou le numéro de maillage est différent
return false;
// si on arrive ici, cela veut dire que toutes les égalités sont bonnes pour un cas autre que
// point ou frontière à 2 noeuds
return true;
// si on arrive ici, cela veut dire que toutes les égalités sont bonnes pour un cas autre que
// point ou frontière à 2 noeuds
return true;
};
// retourne un element frontiere ayant une orientation opposee
@ -205,6 +205,101 @@ ElFrontiere * ElFrontiere::Oppose() const
return pt;
};
// calcul éventuel de la normale à un noeud
// ce calcul existe pour les éléments 2D, 1D axi, et aussi pour les éléments 1D
// qui possède un repère d'orientation
// en retour coor = la normale si coor.Dimension() est = à la dimension de l'espace
// si le calcul n'existe pas --> coor.Dimension() = 0
// ramène un entier :
// == 1 : calcul normal
// == 0 : problème de calcul -> coor.Dimension() = 0
// == 2 : indique que le calcul n'est pas licite pour le noeud passé en paramètre
// mais il n'y a pas d'erreur, c'est seulement que l'élément n'est pas ad hoc pour
// calculer la normale à ce noeud là
// temps: indique à quel moment on veut le calcul
int ElFrontiere::CalculNormale_noeud(Enum_dure temps,const Noeud& noe,Coordonnee& coor)
{
int retour = 1; // init du retour : on part d'un bon a priori
Enum_type_geom enutygeom = Type_geom_front();
int dima = ParaGlob::Dimension();
// on exclue les cas à pb
if ( ((dima == 3) && (!ParaGlob::AxiSymetrie()) && ((enutygeom == LIGNE)||(enutygeom == POINT_G)))
|| ((dima == 3) && (ParaGlob::AxiSymetrie()) && (enutygeom == POINT_G))
|| ((dima == 2) && (enutygeom == POINT_G))
)
// on n'a pas d'information particulière pour calculer la normale
// donc on ne peut pas calculer
{ retour = 2;
}
else // sinon le calcul est possible
{ // on commence par repérer le noeud dans la numérotation locale
int nuoe=0;
int borne_nb_noeud=tabNoeud.Taille()+1;
for (int i=1;i< borne_nb_noeud;i++)
{Noeud& noeloc = *tabNoeud(i);
if ( (noe.Num_noeud() == noeloc.Num_noeud())
&& (noe.Num_Mail() == noeloc.Num_Mail())
)
{nuoe = i; break;
};
};
// on ne continue que si on a trouvé le noeud
if (nuoe != 0)
{ ElemGeomC0& elemgeom = ElementGeometrique(); // récup de la géométrie
// récup des coordonnées locales du noeuds
const Coordonnee& theta_noeud = elemgeom.PtelemRef()(nuoe);
// récup de la métrique associée à l'élément
Met_abstraite * met = this->Metrique();
// récup des phi et dphi au noeud
const Vecteur & phi = elemgeom.Phi_point(theta_noeud);
const Mat_pleine& dphi = elemgeom.Dphi_point(theta_noeud);
switch (temps)
{case TEMPS_0 :
{const BaseB& baseB = met->BaseNat_0(tabNoeud,dphi,phi);
coor = Util::ProdVec_coor( baseB.Coordo(1), baseB.Coordo(2));
coor.Normer();
break;
}
case TEMPS_t :
{const BaseB& baseB = met->BaseNat_t(tabNoeud,dphi,phi);
coor = Util::ProdVec_coor( baseB.Coordo(1), baseB.Coordo(2));
coor.Normer();
break;
}
case TEMPS_tdt :
{const BaseB& baseB = met->BaseNat_tdt(tabNoeud,dphi,phi);
coor = Util::ProdVec_coor( baseB.Coordo(1), baseB.Coordo(2));
coor.Normer();
break;
}
default :
cout << "\nErreur : valeur incorrecte du temps demande = "
<< Nom_dure(temps) << " !\n";
cout << "\n ElFrontiere::CalculNormale_noeud(Enum_dure temps... \n";
retour = 0;
Sortie(1);
};
}
else
{cout << "\n *** erreur le noeud demande num= "<<noe.Num_noeud()
<< " du maillage "<< noe.Num_Mail()
<< " ne fait pas parti de l'element de frontiere FrontSegLine "
<< "contenant les noeuds: \n";
for (int i=1;i< borne_nb_noeud;i++)
{Noeud& noeloc = *tabNoeud(i);
cout << " num "<< noe.Num_noeud() << " mail " << noeloc.Num_Mail() << ", ";
};
cout << " on ne peut pas calculer la normale au noeud !!"
<< "\n ElFrontiere::CalculNormale_noeud(...";
retour = 0;
Sortie(1);
};
};
// retour
return retour;
};
// effacement de la place memoire des frontieres de l'element frontiere
void ElFrontiere::EffaceFrontiere()
{ for (int i=1; i<= tabfront.Taille(); i++)
@ -250,8 +345,8 @@ double ElFrontiere::MaxDiagonale_tdt()
{ double dist= (tabNoeud(i)->Coord2() - tabNoeud(j)->Coord2()).Norme();
maxdiagonale = MaX(maxdiagonale,dist);
};
return maxdiagonale;
};
return maxdiagonale;
};
// met à jour la boite d'encombrement
void ElFrontiere::AjourBoiteEncombrement()

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -35,7 +35,7 @@
* PROJET: Herezh++ *
* $ *
************************************************************************
* BUT: Classe generique des elements frontieres *
* BUT: Classe generique des elements frontieres. *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
* VERIFICATION: *
@ -105,7 +105,7 @@ class ElFrontiere
Enum_type_geom Type_geom_front() const
{return Type_geom_generique(ElementGeometrique().TypeGeometrie());};
// retourne l'élément géométrique attaché à l'élément frontière
virtual ElemGeomC0 const & ElementGeometrique() const = 0;
virtual ElemGeomC0 & ElementGeometrique() const = 0;
// surcharge des tests
// ========================================================================
// IMPORTANT !!!
@ -140,6 +140,20 @@ class ElFrontiere
// ramene et calcul les coordonnees du point de reference de l'element
virtual Coordonnee Ref() = 0;
// calcul éventuel de la normale à un noeud
// ce calcul existe pour les éléments 2D, 1D axi, et aussi pour les éléments 1D
// qui possède un repère d'orientation
// en retour coor = la normale si coor.Dimension() est = à la dimension de l'espace
// si le calcul n'existe pas --> coor.Dimension() = 0
// ramène un entier :
// == 1 : calcul normal
// == 0 : problème de calcul -> coor.Dimension() = 0
// == 2 : indique que le calcul n'est pas licite pour le noeud passé en paramètre
// mais il n'y a pas d'erreur, c'est seulement que l'élément n'est pas ad hoc pour
// calculer la normale à ce noeud là
// temps: indique à quel moment on veut le calcul
int CalculNormale_noeud(Enum_dure temps,const Noeud& noe,Coordonnee& coor);
// ramene un plan tangent ou une droite tangente au point de reference
// si indic = 1 -> une droite, =2 -> un plan
// ces infos sont stocke et sauvegardees dans l'element de frontiere

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -37,8 +37,9 @@ Front::Front() :
boite_Front(),num_frontiere(0),elem(NULL)
{ptEl = NULL; tabmitoyen=NULL; };
// normal
Front::Front ( const ElFrontiere& el, Element * pt, int num_front ) :
Front::Front ( const ElFrontiere& el, Element * pt, int num_front ,int ang_mort) :
boite_Front(ParaGlob::Dimension()),num_frontiere(num_front)
,angle_mort(ang_mort)
,elem(el.NevezElemFront())
{ ptEl =(Element *) pt;
tabmitoyen=NULL;
@ -51,7 +52,7 @@ Front::Front ( const ElFrontiere& el, Element * pt, int num_front ) :
// de copie
Front::Front ( const Front& a) :
boite_Front(a.boite_Front),num_frontiere(a.num_frontiere)
,elem(a.elem->NevezElemFront())
,elem(a.elem->NevezElemFront()),angle_mort(a.angle_mort)
{ ptEl = (Element *) a.ptEl;
if (a.tabmitoyen != NULL)
{ int tabtaille = (a.tabmitoyen)->Taille();
@ -69,34 +70,47 @@ Front::Front ( const Front& a) :
Front::~Front()
{ if (elem != NULL)
delete elem;
// on efface le tableau mais pas les objets pointés
if (tabmitoyen != NULL)
delete tabmitoyen;
};
// ============= METHODES ==========
// affichage à l'écran des informations liées au contact
void Front::Affiche() const
// cas = 0 : affichage en fonction du niveau de commentaire voulu
// cas = 1 : affichage minimal nécessaire pour repérer l'élément
void Front::Affiche(int cas) const
{ if (elem != NULL)
{ cout << "\n element de frontiere du maillage " << ptEl->Num_maillage() <<" , cree par l'element "
<< ptEl->Num_elt() << " de numero " << num_frontiere << " , de type de geometrie: "
<< Nom_type_geom(elem->Type_geom_front()) << " , avec une interpolation:"
<< Nom_interpol(elem->ElementGeometrique().TypeInterpolation())
<< " , constitue des noeuds: " ;
const Tableau <Noeud *>& tabnoeud = elem->TabNoeud_const();
int tabtaille = tabnoeud.Taille();
for (int i=1;i<=tabtaille;i++)
{if (cas == 1)
{ cout << " front " ;
if (angle_mort)
cout << "(angle mort) ";
cout << num_frontiere << " de l'EF " << ptEl->Num_elt() << " du mail. "
<< ptEl->Num_maillage() << flush;
}
else
{cout << "\n element de frontiere du maillage " << ptEl->Num_maillage() <<" , cree par l'element "
<< ptEl->Num_elt() << " de numero " << num_frontiere << " , de type de geometrie: "
<< Nom_type_geom(elem->Type_geom_front()) << " , avec une interpolation:"
<< Nom_interpol(elem->ElementGeometrique().TypeInterpolation());
if (angle_mort) cout << " ( represente un angle mort) , ";
cout << " , constitue des noeuds: " ;
const Tableau <Noeud *>& tabnoeud = elem->TabNoeud_const();
int tabtaille = tabnoeud.Taille();
for (int i=1;i<=tabtaille;i++)
cout << tabnoeud(i)->Num_noeud() << " , ";
cout << " , et contiend les degres de liberte suivants: "
cout << " , et contiend les degres de liberte suivants: "
<< elem->DdlElem_const();
if (this->tabmitoyen != NULL)
if (this->tabmitoyen != NULL)
{int tai = this->tabmitoyen->Taille();
cout << "\n " << tai << " elements mitoyens: ( ";
for (int i=1;i<=tai;i++)
cout << (*tabmitoyen)(i)->PtEI()->Num_elt() << " , ";
cout << ") ";
}
else
cout << "\n *** aucun element mitoyen !!!! *** ";
else
cout << "\n *** aucun element mitoyen !!!! *** ";
};
}
else
{ cout << "\n element de frontiere associe a un element fini: FRONTIERE NON DEFINIE !! "; };
@ -130,11 +144,13 @@ Front& Front::operator = ( const Front& a)
};
// boite d'encombrement
boite_Front = a.boite_Front;
// angle mort
angle_mort = a.angle_mort;
return *this;
};
// definition des elements mitoyens
void Front::DefMitoyen(Tableau <Front*>& tab)
void Front::DefMitoyen(const Tableau <Front*>& tab)
{
int tabtaille = tab.Taille();
if (tabtaille != 0)
@ -149,7 +165,29 @@ void Front::DefMitoyen(Tableau <Front*>& tab)
};
};
};
// ajout d'un élément mitoyens (l'ajout est effectif uniquement s'il n'existe pas déjà)
void Front::AjoutMitoyen(Front * mitoyen)
{ if (tabmitoyen == NULL)
// si le tableau n'existe pas, on le dimensionne à 1 et on ajoute l'unique élément
{tabmitoyen= new Tableau <Front*>;
tabmitoyen->Change_taille(1);
(*tabmitoyen)(1) = mitoyen;
}
else // sinon on commence par regarder si mitoyen existe déjà
{int tail = tabmitoyen->Taille();
bool trouver = false;
for (int i=1;i<= tail; i++ )
if (*(*tabmitoyen)(i) == *mitoyen)
{trouver = true; break;}
// s'il n'existe pas on l'ajoute
if (!trouver)
// on augmente la taille et on ajoute
{tabmitoyen->Change_taille(tail+1);
(*tabmitoyen)(tail+1)= mitoyen;
};
};
};
// test si le point passé en argument appartient à la boite d'encombrement de la frontière
// tous les points sont supposées avoir la même dimension
bool Front::In_boite_emcombrement_front(const Coordonnee& M) const
@ -214,6 +252,8 @@ void Front::Lecture_base_info_front(ifstream& ent)
ent >> test;
if (test)
{elem->Lecture_base_info_ElFrontiere_pour_projection(ent);}
// on réutilise nom_type pour lire la chaine: am=
ent >> nom_type >> angle_mort;
// // la boite d'encombrement de la frontière
// ent >> nom_type >> boite_Front.Premier() >> boite_Front.Second() ;
@ -229,7 +269,9 @@ void Front::Ecriture_base_info_front(ofstream& sort)
// les éléments spécifiques à l'élément frontière
if (elem != NULL)
{ sort << " 1 "; elem->Ecriture_base_info_ElFrontiere_pour_projection(sort);}
else { sort << " 0 ";};
else { sort << " 0 ";};
sort << " am= " << angle_mort << " ";
// la boite d'encombrement
// sort << "encombrements_surf " << boite_Front.Premier() << " " << boite_Front.Second() << " \n";
};

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -36,9 +36,12 @@
* $ *
************************************************************************
* BUT: definir un element de stockage de frontiere relatif à un *
* éléments finis. *
* éléments finis. *
* Ce conteneur est utilisé en dehors d'un élément, par exemple*
* pour le contact *
* $ *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
* *
* VERIFICATION: *
* *
* ! date ! auteur ! but ! *
@ -71,7 +74,7 @@ class Front
//par defaut
Front();
// normal
Front ( const ElFrontiere& el, Element * pt, int num_front) ;
Front ( const ElFrontiere& el, Element * pt, int num_front,int angle_mort=0) ;
// de copie
Front ( const Front& a);
// destructeur
@ -80,7 +83,9 @@ class Front
// ============= METHODES ==========
// affichage à l'écran des informations liées au contact
void Affiche() const ;
// cas = 0 : affichage en fonction du niveau de commentaire voulu
// cas = 1 : affichage minimal nécessaire pour repérer l'élément
void Affiche(int cas=0) const ;
// operator
// affectation de toute les donnees
@ -90,13 +95,16 @@ class Front
inline bool operator == ( const Front& a) const
{ if ((*(this->elem) == *(a.elem))
&& (this->ptEl == a.ptEl) && (this->tabmitoyen == a.tabmitoyen)
&& (num_frontiere == a.num_frontiere) )
&& (num_frontiere == a.num_frontiere)
&& (angle_mort == a.angle_mort)
)
return true;
else
return false;
};
// test d'egalite sur les éléments originaux :
// l'élément elem, ptEI, et num_frontiere, mais qui ne comprend pas tabmitoyen
// Important**: ne comprend pas angle_mort contrairement à la méthode de même nom dans Contact
inline bool MemeOrigine( const Front& a) const
{ if ( (*(this->elem) == *(a.elem)) && (this->ptEl == a.ptEl)
&& (num_frontiere == a.num_frontiere))
@ -109,7 +117,9 @@ class Front
{ if (*this == a) return false; else return true;};
// definition des elements mitoyens
void DefMitoyen(Tableau <Front*>& tabmitoyen);
void DefMitoyen(const Tableau <Front*>& tabmitoyen);
// ajout d'un élément mitoyens (l'ajout est effectif uniquement s'il n'existe pas déjà)
void AjoutMitoyen(Front * mitoyen);
// retourne les donnees
inline const Tableau <Front*>* TabMitoyen() const { return tabmitoyen;};
@ -165,6 +175,11 @@ class Front
Element * PtEI() const { return ptEl;};
// récup du numéro de frontière associé à l'élément fini
int Num_frontiere() const {return num_frontiere;};
// récupération de l'indicateur d'angle mort
int Angle_mort() const {return angle_mort;};
// changement de l'indicateur d'angle mort
void Change_angle_mort(int new_angle_mort) {angle_mort= new_angle_mort;};
// test si la position d'un point est du bon cote ( c-a-d hors matiere) ou non
// si le point est sur la surface, ramène false
@ -197,6 +212,9 @@ class Front
DeuxCoordonnees boite_Front; // le premier le min, le second le max
Tableau <Front*>* tabmitoyen; // tableau des elements mitoyens
int angle_mort; // indicateur par défaut = 0, ==1 s'il s'agit d'un front
// qui est construit pour représenter un angle mort
// fonctions internes
static double prop_mini; // mini proportion à ajouter à l'encombrement

View file

@ -8,7 +8,7 @@
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
@ -62,10 +62,10 @@ FrontSegCub::FrontSegCub ( const Tableau <Noeud *>& tab, const DdlElement& ddlEl
{ // au premier appel on construit la metrique associee
if ( met == NULL)
DefMetrique();
// définition de d_T
int nb_ddl = 4 * tab(1)->Coord0().Dimension();
d_T.Change_taille(nb_ddl);
};
// définition de d_T
int nb_ddl = 4 * tab(1)->Coord0().Dimension();
d_T.Change_taille(nb_ddl);
};
// de copie
FrontSegCub::FrontSegCub( const FrontSegCub& a) :
ElFrontiere(a),refP(a.refP),droite(a.droite),theta(a.theta),theta_repere(a.theta_repere)
@ -117,13 +117,14 @@ Coordonnee FrontSegCub::Ref()
Coordonnee A0(0.);
// appel de la routine de metrique, 4 noeuds
if (tabNoeud(1)->ExisteCoord2())
{refP = met->PointM_tdt(tabNoeud,segment.Phi(A0));}
{refP = met->PointM_tdt(tabNoeud,segment.Phi_point(A0));}
else if (tabNoeud(1)->ExisteCoord1())
{refP = met->PointM_t(tabNoeud,segment.Phi(A0));}
{refP = met->PointM_t(tabNoeud,segment.Phi_point(A0));}
else
{refP = met->PointM_0(tabNoeud,segment.Phi(A0));};
{refP = met->PointM_0(tabNoeud,segment.Phi_point(A0));};
return refP;
};
// ramene une droite tangente au point de reference
// si indic = 1 -> une droite
// ces infos sont stocke et sauvegardees dans l'element
@ -132,7 +133,7 @@ void FrontSegCub::TangentRef(Droite& dr, Plan& , int& indic)
// le point de ref en coordonnees locale
Coordonnee A0(0.);
BaseB giB;
met->BaseND_tdt(tabNoeud,segment.Dphi(A0),segment.Phi(A0),giB,giH);
met->BaseND_tdt(tabNoeud,segment.Dphi_point(A0),segment.Phi_point(A0),giB,giH);
droite.Change_ptref(Ref());
droite.Change_vect(giB(1).Coor());
theta(1) = 0.;theta_repere=theta;
@ -145,7 +146,7 @@ void FrontSegCub::TangentRef(Droite& dr, Plan& , int& indic)
// ces infos sont stocke et sauvegardees dans l'element
void FrontSegCub::Tangent(const Coordonnee& M,Coordonnee& M1, Droite& dr, Plan& , int& indic)
{ // récup des bases au point courant projeté
met->BaseND_tdt(tabNoeud,segment.Dphi(theta_repere),segment.Phi(theta_repere),giB,giH);
met->BaseND_tdt(tabNoeud,segment.Dphi_point(theta_repere),segment.Phi_point(theta_repere),giB,giH);
// on incremente la coordonnee curviligne
Coordonnee M1M = M - droite.PointDroite();
theta(1) += M1M * giH.Coordo(1);
@ -156,16 +157,16 @@ void FrontSegCub::Tangent(const Coordonnee& M,Coordonnee& M1, Droite& dr, Plan&
// calcul d'un point extreme de l'élément dans le sens de M
{ theta_repere = segment.Maxi_Coor_dans_directionGM(theta);
// on recalcule le repère local
phi = segment.Phi(theta_repere); // fonctions d'interpolation au point limite dans l'élément
met->BaseND_tdt(tabNoeud,segment.Dphi(theta_repere),phi,giB,giH);
phi = segment.Phi_point(theta_repere); // fonctions d'interpolation au point limite dans l'élément
met->BaseND_tdt(tabNoeud,segment.Dphi_point(theta_repere),phi,giB,giH);
// on recalcule les coodonnées locales
theta(1) += M1M * giH.Coordo(1);
}
else
// sinon le point est correcte, on peut y calculer le nouveau repère
{ theta_repere = theta;
phi = segment.Phi(theta_repere); // fonctions d'interpolation au point
met->BaseND_tdt(tabNoeud,segment.Dphi(theta_repere),phi,giB,giH);
phi = segment.Phi_point(theta_repere); // fonctions d'interpolation au point
met->BaseND_tdt(tabNoeud,segment.Dphi_point(theta_repere),phi,giB,giH);
};
// calcul du point correspondant au theta_i
@ -192,14 +193,14 @@ void FrontSegCub::AutreTangent(Droite& dr, Plan& , int& indic)
// calcul d'un point extreme de l'élément dans le sens de M
{ theta_repere = segment.Maxi_Coor_dans_directionGM(theta);
// on recalcule le repère local
phi = segment.Phi(theta_repere); // fonctions d'interpolation au point limite dans l'élément
met->BaseND_tdt(tabNoeud,segment.Dphi(theta_repere),phi,giB,giH);
phi = segment.Phi_point(theta_repere); // fonctions d'interpolation au point limite dans l'élément
met->BaseND_tdt(tabNoeud,segment.Dphi_point(theta_repere),phi,giB,giH);
}
else
// sinon le point est correcte, on peut y calculer le nouveau repère
{ theta_repere = theta;
phi = segment.Phi(theta_repere); // fonctions d'interpolation au point
met->BaseND_tdt(tabNoeud,segment.Dphi(theta_repere),phi,giB,giH);
phi = segment.Phi_point(theta_repere); // fonctions d'interpolation au point
met->BaseND_tdt(tabNoeud,segment.Dphi_point(theta_repere),phi,giB,giH);
};
// calcul du point correspondant au theta_i
@ -233,14 +234,14 @@ Tableau <Coordonnee >* FrontSegCub::DernierTangent(Droite& dr, Plan& , int& indi
// calcul d'un point extreme de l'élément dans le sens de M
{ theta_repere = segment.Maxi_Coor_dans_directionGM(theta);
// on recalcule le repère local
phi = segment.Phi(theta_repere); // fonctions d'interpolation au point limite dans l'élément
met->BaseND_tdt(tabNoeud,segment.Dphi(theta_repere),phi,giB,giH);
phi = segment.Phi_point(theta_repere); // fonctions d'interpolation au point limite dans l'élément
met->BaseND_tdt(tabNoeud,segment.Dphi_point(theta_repere),phi,giB,giH);
}
else
// sinon le point est correcte, on peut y calculer le nouveau repère
{ theta_repere = theta;
phi = segment.Phi(theta_repere); // fonctions d'interpolation au point
met->BaseND_tdt(tabNoeud,segment.Dphi(theta_repere),phi,giB,giH);
phi = segment.Phi_point(theta_repere); // fonctions d'interpolation au point
met->BaseND_tdt(tabNoeud,segment.Dphi_point(theta_repere),phi,giB,giH);
};
// calcul du point correspondant au theta_i
@ -256,7 +257,7 @@ Tableau <Coordonnee >* FrontSegCub::DernierTangent(Droite& dr, Plan& , int& indi
Tableau <Coordonnee >* pt_varT = NULL; // par défaut
if (avec_var)
{ // calcul de la variation des vecteurs de base: donc ici d'un seul vecteur
const Tableau <BaseB>& d_giB_tdt = met->d_BaseNat_tdt(tabNoeud,segment.Dphi(theta_repere),phi);
const Tableau <BaseB>& d_giB_tdt = met->d_BaseNat_tdt(tabNoeud,segment.Dphi_point(theta_repere),phi);
// calcul de la variation de la tangente normée
Util::VarUnVect_coorBN( giB(1),d_giB_tdt,giB(1).Coor().Norme(),d_T);
if (ParaGlob::Dimension() == 2)
@ -277,7 +278,7 @@ Tableau <Coordonnee >* FrontSegCub::DernierTangent(Droite& dr, Plan& , int& indi
// calcul les fonctions d'interpolation au dernier point de projection sauvegarde
const Vecteur& FrontSegCub::Phi()
{ return segment.Phi(theta);};
{ return segment.Phi_point(theta);};
// test si la position d'un point est du bon cote ( c-a-d hors matiere) ou non
// si le point est sur la surface, ramène false
@ -294,9 +295,9 @@ bool FrontSegCub::BonCote_t( const Coordonnee& a,double& r) const // cas ou on
{// def des infos de la droite tangente a t en theta
// devrait également marcher pour l'axisymétrie en 3D
int dim = ParaGlob::Dimension();
phi = segment.Phi(theta_repere); // fonctions d'interpolation au point
phi = segment.Phi_point(theta_repere); // fonctions d'interpolation au point
// calcul des bases et du plan tangent et de giH
met->BaseND_tdt(tabNoeud,segment.Dphi(theta_repere),phi,giB,giH);
met->BaseND_tdt(tabNoeud,segment.Dphi_point(theta_repere),phi,giB,giH);
// def des infos du plan tangent a t en theta
Coordonnee delta_theta = theta - theta_repere;
Coordonnee M1 = met->PointM_t(tabNoeud,phi) + delta_theta(1) * giB.Coordo(1);

Some files were not shown because too many files have changed in this diff Show more