1539 lines
81 KiB
C++
1539 lines
81 KiB
C++
// This file is part of the Herezh++ application.
|
|
//
|
|
// The finite element software Herezh++ is dedicated to the field
|
|
// of mechanics for large transformations of solid structures.
|
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
|
//
|
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
|
//
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
|
// AUTHOR : Gérard Rio
|
|
// E-MAIL : gerardrio56@free.fr
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License,
|
|
// or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
|
|
|
|
|
#include "Algori.h"
|
|
#include "string"
|
|
#include "MathUtil.h"
|
|
#include <iostream> // pour utiliser la classe istrstream
|
|
#include <strstream> // nouveau dans CW5.3
|
|
// -- la liste des algorithems actuellement disponibles#include "Projet.h"
|
|
#include "AlgoriNonDyna.h"
|
|
#include "ImpliNonDynaCont.h"
|
|
#include "AlgoriFlambLineaire.h"
|
|
#include "AlgoInformations.h"
|
|
#include "AlgoUtils.h"
|
|
#include "AlgoriDynaExpli.h"
|
|
#include "AlgoriNewmark.h"
|
|
#include "Algori_chung_lee.h"
|
|
#include "AlgoriDynaExpli_zhai.h"
|
|
#include "Algori_tchamwa.h"
|
|
#include "AlgoUmatAbaqus.h"
|
|
#include "AlgoRungeKutta.h"
|
|
#include "AlgoBonelli.h"
|
|
#include "Algori_relax_dyna.h"
|
|
#include "AlgoriCombine.h"
|
|
//-- fin liste algo
|
|
|
|
#include "ReferenceNE.h"
|
|
#include "ReferenceAF.h"
|
|
|
|
|
|
// passage aux noeuds éventuellement des grandeurs globales, pour une sortie de post-traitement par exemple
|
|
// mais pas seulement, c'est aussi utilisé pour récupérer des infos dans le contact avec le type 4
|
|
// le principe est que ce passage s'effectue si les conteneurs existent au niveau des noeuds
|
|
void Algori::Passage_aux_noeuds_grandeurs_globales(LesMaillages * lesMail)
|
|
{ // on va boucler sur tous les grandeurs, mais on utilise le premier noeud actif pour savoir si
|
|
// a priori le transfert est à faire
|
|
int nb_maillage = lesMail->NbMaillage(); // récup du nombre de maillage
|
|
List_io < TypeQuelconque >::iterator il,ilfin=listeVecGlob.end();
|
|
for (il=listeVecGlob.begin();il!=ilfin;il++)
|
|
{TypeQuelconque& tq = (*il);
|
|
TypeQuelconque_enum_etendu enuq = tq.EnuTypeQuelconque(); // l'enumeré du type
|
|
Enum_ddl enuDdl = tq.Enum(); // de ddl associé definissant le point ou est calculé tq
|
|
Noeud* noe=NULL;
|
|
// on recherche un noeud où enuDdl est actif
|
|
for (int imail=1;imail<=nb_maillage;imail++)
|
|
{int nb_N = lesMail->Nombre_noeud(imail);
|
|
for (int inoe=1;inoe<=nb_N;inoe++)
|
|
if (lesMail->Noeud_LesMaille(imail,inoe).En_service(enuDdl))
|
|
{noe=&lesMail->Noeud_LesMaille(imail,inoe); break;}; // sort de la première boucle
|
|
if (noe != NULL) break; // sortie de la boucle sur les maillages
|
|
};
|
|
if (noe == NULL) // cela veut que la grandeur n'est pas active et donc pas à transférer
|
|
break; // on sort de la boucle sur les grandeurs globales
|
|
// arrivée ici la suite est spécifique à chaque grandeur
|
|
switch (enuq.EnumTQ())
|
|
{ case FORCE_GENE_EXT:
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,F_ext_tdt,tq);
|
|
//debug
|
|
//cout << "\n debug: Algori::Passage_aux_noeuds_grandeurs_globales ";
|
|
//F_ext_tdt.Affiche();
|
|
//fin debug
|
|
break;
|
|
case FORCE_GENE_INT:
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,F_int_tdt,tq);
|
|
break;
|
|
case FORCE_GENE_TOT:
|
|
F_totale_tdt.Change_taille(F_ext_tdt.Taille()); // au cas où
|
|
F_totale_tdt = F_ext_tdt; F_totale_tdt += F_int_tdt;
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,F_totale_tdt,tq);
|
|
break;
|
|
case RESIDU_GLOBAL:
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,residu_final,tq);
|
|
break;
|
|
case DELTA_XI:
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,delta_X,tq);
|
|
break;
|
|
default:
|
|
cout << "\n ** erreur, pour l'instant le transfert depuis global vers noeud de "
|
|
<< enuq.NomPlein() << " n'est pas implante ... le demander !! "
|
|
<< "\n Algori::Passage_aux_noeuds_grandeurs_globales(..."<<endl;
|
|
// dans le cas où un comptage du calcul est en cours on l'arrête
|
|
if (tempsCalEquilibre.Comptage_en_cours()) tempsCalEquilibre.Arret_du_comptage();
|
|
if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
|
|
if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
|
|
if (tempsSortieFilCalcul.Comptage_en_cours()) tempsSortieFilCalcul.Arret_du_comptage();
|
|
if (tempsSauvegarde.Comptage_en_cours()) tempsSauvegarde.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
|
|
// passage aux noeuds de F_int_t et F_ext_t
|
|
void Algori::Passage_aux_noeuds_F_int_t_et_F_ext_t(LesMaillages * lesMail)
|
|
{ int dim = ParaGlob::Dimension(); // dimension du pb
|
|
if(ParaGlob::AxiSymetrie())
|
|
dim--; // en axisymétrie on récupère uniquement les forces en x et y
|
|
// def d'un type générique, utilisé pour le transfert des forces internes, vers les conteneurs noeuds
|
|
Coordonnee coor(dim); // un type coordonnee typique
|
|
Grandeur_coordonnee gt(coor); // une grandeur typique de type Grandeur_coordonnee
|
|
// def d'un type quelconque représentatif pour un vecteur force à chaque noeud
|
|
TypeQuelconque typQ_gene_int_t(FORCE_GENE_INT_t,X1,gt);
|
|
TypeQuelconque typQ_gene_ext_t(FORCE_GENE_EXT_t,X1,gt);
|
|
|
|
lesMail->Quelconque_glob_vers_local(X1,F_ext_t,typQ_gene_ext_t);
|
|
lesMail->Quelconque_glob_vers_local(X1,F_int_t,typQ_gene_int_t);
|
|
|
|
};
|
|
|
|
// passage aux noeuds éventuellement d'une grandeur globale particulière,
|
|
// typeGeneriqu : indique le type de grandeur à passer
|
|
// Le passage s'effectue si le conteneur existe au niveau des noeuds sinon erreur
|
|
// seules les grandeurs globales qui n'ont pas été transférées par la méthode
|
|
// Passage_aux_noeuds_grandeurs_globales , sont concernées
|
|
void Algori::Passage_aux_noeuds_grandeur_globale_particuliere(const TypeQuelconque& typeGeneriqu, LesMaillages * lesMail)
|
|
{ TypeQuelconque_enum_etendu enuq = typeGeneriqu.EnuTypeQuelconque(); // l'enumeré du type
|
|
Enum_ddl enuDdl = typeGeneriqu.Enum(); // de ddl associé definissant le point ou est calculé tq
|
|
// arrivée ici la suite est spécifique à chaque grandeur
|
|
switch (enuq.EnumTQ())
|
|
{ case FORCE_GENE_EXT:
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,F_ext_tdt,typeGeneriqu);
|
|
//debug
|
|
//cout << "\n debug: Algori::Passage_aux_noeuds_grandeurs_globales ";
|
|
//F_ext_tdt.Affiche();
|
|
//fin debug
|
|
break;
|
|
case FORCE_GENE_INT:
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,F_int_tdt,typeGeneriqu);
|
|
break;
|
|
case FORCE_GENE_TOT:
|
|
F_totale_tdt.Change_taille(F_ext_tdt.Taille()); // au cas où
|
|
F_totale_tdt = F_ext_tdt; F_totale_tdt += F_int_tdt;
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,F_totale_tdt,typeGeneriqu);
|
|
break;
|
|
case RESIDU_GLOBAL:
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,residu_final,typeGeneriqu);
|
|
break;
|
|
case DELTA_XI:
|
|
lesMail->Quelconque_glob_vers_local(enuDdl,delta_X,typeGeneriqu);
|
|
break;
|
|
default:
|
|
cout << "\n ** erreur, pour l'instant le transfert depuis global vers noeud de "
|
|
<< enuq.NomPlein() << " n'est pas implante ... le demander !! "
|
|
<< "\n Algori::Passage_aux_noeuds_grandeur_globale(..."<<endl;
|
|
// dans le cas où un comptage du calcul est en cours on l'arrête
|
|
if (tempsCalEquilibre.Comptage_en_cours()) tempsCalEquilibre.Arret_du_comptage();
|
|
if (tempsInitialisation.Comptage_en_cours()) tempsInitialisation.Arret_du_comptage();
|
|
if (tempsMiseAjourAlgo.Comptage_en_cours()) tempsMiseAjourAlgo.Arret_du_comptage();
|
|
if (tempsSortieFilCalcul.Comptage_en_cours()) tempsSortieFilCalcul.Arret_du_comptage();
|
|
if (tempsSauvegarde.Comptage_en_cours()) tempsSauvegarde.Arret_du_comptage();
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|
|
|
|
// 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 Algori::Passage_de_grandeurs_globales_vers_noeuds_pour_variables_globales(LesMaillages * lesMail
|
|
,VariablesExporter* varExpor,const Nb_assemb& nb_casAssemb,const LesReferences& lesRef)
|
|
{ int dim = ParaGlob::Dimension(); // dimension du pb
|
|
if(ParaGlob::AxiSymetrie())
|
|
dim--; // en axisymétrie on récupère uniquement les forces en x et y
|
|
// récupération de la liste des variables en type quelconque
|
|
const List_io <VariablesExporter::Quelconque_a_un_noeud>& liQuel = varExpor->List_noeud_type_quelconque();
|
|
List_io <VariablesExporter::Quelconque_a_un_noeud>::const_iterator it,itfin=liQuel.end();
|
|
for (it = liQuel.begin(); it!=itfin;it++)
|
|
{ const TypeQuelconque_enum_etendu& ty = (*it).Quelc_const(); // la grandeur constante
|
|
switch (ty.EnumTQ())
|
|
{ case FORCE_GENE_EXT:
|
|
{// récup de la reférence
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef.Trouve((*it).Ref_const(),&(*it).Nom_mail_const()));
|
|
int ne = ref.Numero(1); // le num du noeud: uniquement le premier
|
|
|
|
// int ne = (*it).Num_NE_const(); // le num du noeud
|
|
int nmail = 1;
|
|
if ((*it).Nom_mail_const() != "")
|
|
nmail = lesMail->NumMaillage((*it).Nom_mail_const()); // num du maillage
|
|
// recup du noeud
|
|
Noeud * noo = & lesMail->Noeud_LesMaille(nmail,ne);
|
|
// si le noeud n'est pas actif pour ce ddl, on ne continue pas
|
|
if (noo->Existe_ici(X1)) // ellimine les noeuds non concernés
|
|
// ** en fait cela pourrait changer pour la thermique pure, mais pour l'instant ce n'est
|
|
// pas pris en compte, a voir si on veut les forces généralisées associées à de la thermique pure
|
|
{if ((noo->Existe_ici(ty)) && (noo->En_service(X1)))
|
|
{// FORCE_GENE_EXT est associé au type coordonnée
|
|
TypeQuelconque& typQ = noo->ModifGrandeur_quelconque(ty); // récup du conteneur du noeud
|
|
// récup de la grandeur
|
|
Grandeur_coordonnee* gcoor = (Grandeur_coordonnee*) typQ.Grandeur_pointee();
|
|
Coordonnee& conoe = *(gcoor->ConteneurCoordonnee()); // les coordonnées
|
|
int iglob = noo->Pointeur_assemblage(X1,nb_casAssemb.n);
|
|
#ifdef MISE_AU_POINT
|
|
if ( iglob == -1 )
|
|
{ cout << "\nErreur : ddl " << X1
|
|
<< " inexistant pour le cas de charge " << nb_casAssemb.n
|
|
<< '\n'
|
|
<< "Algori::Passage_de_grandeurs_globales_vers_noeuds_pour_variables_globales(\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
switch (dim) // on rempli les coordonnées
|
|
{ case 3: conoe(3)=F_ext_tdt(iglob+2);
|
|
case 2: conoe(2)=F_ext_tdt(iglob+1);
|
|
case 1: conoe(1)=F_ext_tdt(iglob);
|
|
};
|
|
};
|
|
};
|
|
break;
|
|
}
|
|
case FORCE_GENE_INT:
|
|
{// récup de la reférence
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef.Trouve((*it).Ref_const(),&(*it).Nom_mail_const()));
|
|
int ne = ref.Numero(1); // le num du noeud: uniquement le premier
|
|
// int ne = (*it).Num_NE_const(); // le num du noeud
|
|
int nmail = 1;
|
|
if ((*it).Nom_mail_const() != "")
|
|
nmail = lesMail->NumMaillage((*it).Nom_mail_const()); // num du maillage
|
|
// recup du noeud
|
|
Noeud * noo = & lesMail->Noeud_LesMaille(nmail,ne);
|
|
// le type FORCE_GENE_INT est associé au ddl X1
|
|
// si le noeud n'est pas actif pour ce ddl, on ne continue pas
|
|
if (noo->Existe_ici(X1)) // ellimine les noeuds non concernés
|
|
// ** en fait cela pourrait changer pour la thermique pure, mais pour l'instant ce n'est
|
|
// pas pris en compte, a voir si on veut les forces généralisées associées à de la thermique pure
|
|
{if ((noo->Existe_ici(ty)) && (noo->En_service(X1)))
|
|
{// FORCE_GENE_INT est associé au type coordonnée
|
|
TypeQuelconque& typQ = noo->ModifGrandeur_quelconque(ty); // récup du conteneur du noeud
|
|
// récup de la grandeur
|
|
Grandeur_coordonnee* gcoor = (Grandeur_coordonnee*) typQ.Grandeur_pointee();
|
|
Coordonnee& conoe = *(gcoor->ConteneurCoordonnee()); // les coordonnées
|
|
int iglob = noo->Pointeur_assemblage(X1,nb_casAssemb.n);
|
|
#ifdef MISE_AU_POINT
|
|
if ( iglob == -1 )
|
|
{ cout << "\nErreur : ddl " << X1
|
|
<< " inexistant pour le cas de charge " << nb_casAssemb.n
|
|
<< '\n'
|
|
<< "Algori::Passage_de_grandeurs_globales_vers_noeuds_pour_variables_globales(\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
switch (dim) // on rempli les coordonnées
|
|
{ case 3: conoe(3)=F_int_tdt(iglob+2);
|
|
case 2: conoe(2)=F_int_tdt(iglob+1);
|
|
case 1: conoe(1)=F_int_tdt(iglob);
|
|
};
|
|
};
|
|
};
|
|
break;
|
|
}
|
|
case FORCE_GENE_TOT:
|
|
{// récup de la reférence
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef.Trouve((*it).Ref_const(),&(*it).Nom_mail_const()));
|
|
int ne = ref.Numero(1); // le num du noeud: uniquement le premier
|
|
//int ne = (*it).Num_NE_const(); // le num du noeud
|
|
int nmail = 1;
|
|
if ((*it).Nom_mail_const() != "")
|
|
nmail = lesMail->NumMaillage((*it).Nom_mail_const()); // num du maillage
|
|
// recup du noeud
|
|
Noeud * noo = & lesMail->Noeud_LesMaille(nmail,ne);
|
|
// le type FORCE_GENE_TOT est associé au ddl X1
|
|
// si le noeud n'est pas actif pour ce ddl, on ne continue pas
|
|
if (noo->Existe_ici(X1)) // ellimine les noeuds non concernés
|
|
// ** en fait cela pourrait changer pour la thermique pure, mais pour l'instant ce n'est
|
|
// pas pris en compte, a voir si on veut les forces généralisées associées à de la thermique pure
|
|
{if ((noo->Existe_ici(ty)) && (noo->En_service(X1)))
|
|
{// FORCE_GENE_TOT est associé au type coordonnée
|
|
TypeQuelconque& typQ = noo->ModifGrandeur_quelconque(ty); // récup du conteneur du noeud
|
|
// récup de la grandeur
|
|
Grandeur_coordonnee* gcoor = (Grandeur_coordonnee*) typQ.Grandeur_pointee();
|
|
Coordonnee& conoe = *(gcoor->ConteneurCoordonnee()); // les coordonnées
|
|
int iglob = noo->Pointeur_assemblage(X1,nb_casAssemb.n);
|
|
#ifdef MISE_AU_POINT
|
|
if ( iglob == -1 )
|
|
{ cout << "\nErreur : ddl " << X1
|
|
<< " inexistant pour le cas de charge " << nb_casAssemb.n
|
|
<< '\n'
|
|
<< "Algori::Passage_de_grandeurs_globales_vers_noeuds_pour_variables_globales(\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
switch (dim) // on rempli les coordonnées
|
|
{ case 3: conoe(3)=F_int_tdt(iglob+2)+F_ext_tdt(iglob+2);
|
|
case 2: conoe(2)=F_int_tdt(iglob+1)+F_ext_tdt(iglob+1);
|
|
case 1: conoe(1)=F_int_tdt(iglob)+F_ext_tdt(iglob);
|
|
};
|
|
};
|
|
};
|
|
break;
|
|
}
|
|
case RESIDU_GLOBAL:
|
|
{// récup de la reférence
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef.Trouve((*it).Ref_const(),&(*it).Nom_mail_const()));
|
|
int ne = ref.Numero(1); // le num du noeud: uniquement le premier
|
|
|
|
// int ne = (*it).Num_NE_const(); // le num du noeud
|
|
int nmail = 1;
|
|
if ((*it).Nom_mail_const() != "")
|
|
nmail = lesMail->NumMaillage((*it).Nom_mail_const()); // num du maillage
|
|
// recup du noeud
|
|
Noeud * noo = & lesMail->Noeud_LesMaille(nmail,ne);
|
|
// le type RESIDU_GLOBAL est associé au ddl X1
|
|
// si le noeud n'est pas actif pour ce ddl, on ne continue pas
|
|
if (noo->Existe_ici(X1)) // ellimine les noeuds non concernés
|
|
// ** en fait cela pourrait changer pour la thermique pure, mais pour l'instant ce n'est
|
|
// pas pris en compte, a voir si on veut les forces généralisées associées à de la thermique pure
|
|
{if ((noo->Existe_ici(ty)) && (noo->En_service(X1)))
|
|
{// RESIDU_GLOBAL est associé au type coordonnée
|
|
TypeQuelconque& typQ = noo->ModifGrandeur_quelconque(ty); // récup du conteneur du noeud
|
|
// récup de la grandeur
|
|
Grandeur_coordonnee* gcoor = (Grandeur_coordonnee*) typQ.Grandeur_pointee();
|
|
Coordonnee& conoe = *(gcoor->ConteneurCoordonnee()); // les coordonnées
|
|
int iglob = noo->Pointeur_assemblage(X1,nb_casAssemb.n);
|
|
#ifdef MISE_AU_POINT
|
|
if ( iglob == -1 )
|
|
{ cout << "\nErreur : ddl " << X1
|
|
<< " inexistant pour le cas de charge " << nb_casAssemb.n
|
|
<< '\n'
|
|
<< "Algori::Passage_de_grandeurs_globales_vers_noeuds_pour_variables_globales(\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
switch (dim) // on rempli les coordonnées
|
|
{ case 3: conoe(3)=residu_final(iglob+2);
|
|
case 2: conoe(2)=residu_final(iglob+1);
|
|
case 1: conoe(1)=residu_final(iglob);
|
|
};
|
|
};
|
|
};
|
|
break;
|
|
}
|
|
case DELTA_XI:
|
|
{// récup de la reférence
|
|
const ReferenceNE & ref =
|
|
((ReferenceNE &) lesRef.Trouve((*it).Ref_const(),&(*it).Nom_mail_const()));
|
|
int ne = ref.Numero(1); // le num du noeud: uniquement le premier
|
|
//int ne = (*it).Num_NE_const(); // le num du noeud
|
|
int nmail = 1;
|
|
if ((*it).Nom_mail_const() != "")
|
|
nmail = lesMail->NumMaillage((*it).Nom_mail_const()); // num du maillage
|
|
// recup du noeud
|
|
Noeud * noo = & lesMail->Noeud_LesMaille(nmail,ne);
|
|
// le type DELTA_XI est associé au ddl X1
|
|
// si le noeud n'est pas actif pour ce ddl, on ne continue pas
|
|
if (noo->Existe_ici(X1)) // ellimine les noeuds non concernés
|
|
// ** en fait cela pourrait changer pour la thermique pure, mais pour l'instant ce n'est
|
|
// pas pris en compte, a voir si on veut les forces généralisées associées à de la thermique pure
|
|
{if ((noo->Existe_ici(ty)) && (noo->En_service(X1)))
|
|
{// DELTA_XI est associé au type coordonnée
|
|
TypeQuelconque& typQ = noo->ModifGrandeur_quelconque(ty); // récup du conteneur du noeud
|
|
// récup de la grandeur
|
|
Grandeur_coordonnee* gcoor = (Grandeur_coordonnee*) typQ.Grandeur_pointee();
|
|
Coordonnee& conoe = *(gcoor->ConteneurCoordonnee()); // les coordonnées
|
|
int iglob = noo->Pointeur_assemblage(X1,nb_casAssemb.n);
|
|
#ifdef MISE_AU_POINT
|
|
if ( iglob == -1 )
|
|
{ cout << "\nErreur : ddl " << X1
|
|
<< " inexistant pour le cas de charge " << nb_casAssemb.n
|
|
<< '\n'
|
|
<< "Algori::Passage_de_grandeurs_globales_vers_noeuds_pour_variables_globales(\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
switch (dim) // on rempli les coordonnées
|
|
{ case 3: conoe(3)=delta_X(iglob+2);
|
|
case 2: conoe(2)=delta_X(iglob+1);
|
|
case 1: conoe(1)=delta_X(iglob);
|
|
};
|
|
};
|
|
};
|
|
break;
|
|
}
|
|
default: // on ne fait rien
|
|
break;
|
|
};
|
|
};
|
|
|
|
};
|
|
|
|
// //------- temps cpu -----
|
|
// Temps_CPU_HZpp tempsInitialisation; // lesTempsCpu(1)
|
|
// Temps_CPU_HZpp tempsMiseAjourAlgo; // lesTempsCpu(2)
|
|
// Temps_CPU_HZpp tempsCalEquilibre; // lesTempsCpu(3)
|
|
// Temps_CPU_HZpp tempsRaidSmEner; // lesTempsCpu(4)
|
|
// Temps_CPU_HZpp tempsSecondMembreEnerg; // lesTempsCpu(5)
|
|
// Temps_CPU_HZpp tempsResolSystemLineaire; // lesTempsCpu(6)
|
|
// Temps_CPU_HZpp tempsSauvegarde; // lesTempsCpu(7)
|
|
// Temps_CPU_HZpp tempsSortieFilCalcul; // lesTempsCpu(8)
|
|
// Temps_CPU_HZpp tempsRaidSmEnerContact; // lesTempsCpu(9)
|
|
// Temps_CPU_HZpp tempsSecondMembreEnergContact; // lesTempsCpu(10)
|
|
// Temps_CPU_HZpp temps_CL; // lesTempsCpu(11)
|
|
// Temps_CPU_HZpp temps_CLL; // lesTempsCpu(12)
|
|
// Temps_CPU_HZpp temps_lois_comportement; // lesTempsCpu(13)
|
|
// 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
|
|
// // réellement les temps
|
|
// méthode qui sert au transfert entre les variables "Temps_CPU_HZpp" et le tableau "lesTempsCpu"
|
|
// et qui doit-être appelé avant l'utilisation du tableau via listeVarGlob par exemple
|
|
void Algori::Temps_CPU_HZpp_to_lesTempsCpu
|
|
(const LesCondLim& lesCondLim, const Charge& charge, const LesContacts& contact)
|
|
{ lesTempsCpu(1)(1)=tempsInitialisation.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(1)(2)=tempsInitialisation.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(1)(3)=tempsInitialisation.Temps_CPU_System(); // conversion de long long en double
|
|
lesTempsCpu(2)(1)=tempsMiseAjourAlgo.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(2)(2)=tempsMiseAjourAlgo.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(2)(3)=tempsMiseAjourAlgo.Temps_CPU_System(); // conversion de long long en double
|
|
lesTempsCpu(3)(1)=tempsCalEquilibre.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(3)(2)=tempsCalEquilibre.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(3)(3)=tempsCalEquilibre.Temps_CPU_System(); // conversion de long long en double
|
|
lesTempsCpu(4)(1)=tempsRaidSmEner.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(4)(2)=tempsRaidSmEner.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(4)(3)=tempsRaidSmEner.Temps_CPU_System(); // conversion de long long en double
|
|
lesTempsCpu(5)(1)=tempsSecondMembreEnerg.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(5)(2)=tempsSecondMembreEnerg.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(5)(3)=tempsSecondMembreEnerg.Temps_CPU_System(); // conversion de long long en double
|
|
lesTempsCpu(6)(1)=tempsResolSystemLineaire.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(6)(2)=tempsResolSystemLineaire.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(6)(3)=tempsResolSystemLineaire.Temps_CPU_System(); // conversion de long long en double
|
|
lesTempsCpu(7)(1)=tempsSauvegarde.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(7)(2)=tempsSauvegarde.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(7)(3)=tempsSauvegarde.Temps_CPU_System(); // conversion de long long en double
|
|
lesTempsCpu(8)(1)=tempsSortieFilCalcul.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(8)(2)=tempsSortieFilCalcul.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(8)(3)=tempsSortieFilCalcul.Temps_CPU_System(); // conversion de long long en double
|
|
lesTempsCpu(9)(1)=tempsRaidSmEnerContact.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(9)(2)=tempsRaidSmEnerContact.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(9)(3)=tempsRaidSmEnerContact.Temps_CPU_System(); // conversion de long long en double
|
|
lesTempsCpu(10)(1)=tempsSecondMembreEnergContact.Temps_CPU_User(); // conversion de long long en double
|
|
// lesTempsCpu(10)(2)=tempsSecondMembreEnergContact.Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(10)(3)=tempsSecondMembreEnergContact.Temps_CPU_System(); // conversion de long long en double
|
|
// pour les temps cpu relatifs aux CL et CLL, on les récupères
|
|
temps_CL=lesCondLim.Temps_cpu_CL();
|
|
lesTempsCpu(11)(1)=temps_CL.Temps_CPU_User();
|
|
// lesTempsCpu(11)(2)=lesCondLim.Temps_cpu_CL().Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(11)(3)=lesCondLim.Temps_cpu_CL().Temps_CPU_System(); // conversion de long long en double
|
|
temps_CLL=lesCondLim.Temps_cpu_CLL();
|
|
lesTempsCpu(12)(1)=temps_CLL.Temps_CPU_User();
|
|
// lesTempsCpu(12)(2)=lesCondLim.Temps_cpu_CLL().Temps_CPU_Reel(); // conversion de long long en double
|
|
// lesTempsCpu(12)(3)=lesCondLim.Temps_cpu_CLL().Temps_CPU_System(); // conversion de long long en double
|
|
|
|
lesTempsCpu(13)(1)=temps_lois_comportement.Temps_CPU_User();
|
|
lesTempsCpu(14)(1)=temps_metrique_K_SM.Temps_CPU_User();
|
|
temps_chargement = charge.Temps_cpu_chargement();
|
|
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
|
|
#ifdef MISE_AU_POINT
|
|
if (lesTsCpu.Taille() != 10)
|
|
{cout << "\n erreur de dim de tableau: dim lesTsCpu= " << lesTsCpu.Taille()
|
|
<< " au lieu de 10 !! "
|
|
<< "\n Algori::Ajout_Temps_CPU_HZpp_to_lesTempsCpu(... " ;
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
|
|
// on stocke les infos
|
|
lesTsCpu(1) += tempsInitialisation; // conversion de long long en double
|
|
lesTsCpu(2) += tempsMiseAjourAlgo; // conversion de long long en double
|
|
lesTsCpu(3) += tempsCalEquilibre; // conversion de long long en double
|
|
lesTsCpu(4) += tempsRaidSmEner; // conversion de long long en double
|
|
lesTsCpu(5) += tempsSecondMembreEnerg; // conversion de long long en double
|
|
lesTsCpu(6) += tempsResolSystemLineaire; // conversion de long long en double
|
|
lesTsCpu(7) += tempsSauvegarde; // conversion de long long en double
|
|
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;
|
|
|
|
};
|
|
|
|
// une méthode qui a pour objectif de terminer tous les comptages, utile
|
|
// dans le cas d'un arrêt impromptu
|
|
void Algori::Arret_du_comptage_CPU()
|
|
{ tempsInitialisation.Arret_du_comptage();
|
|
tempsMiseAjourAlgo.Arret_du_comptage();
|
|
tempsCalEquilibre.Arret_du_comptage();
|
|
tempsRaidSmEner.Arret_du_comptage();
|
|
tempsSecondMembreEnerg.Arret_du_comptage();
|
|
tempsResolSystemLineaire.Arret_du_comptage();
|
|
tempsSauvegarde.Arret_du_comptage();
|
|
tempsSortieFilCalcul.Arret_du_comptage();
|
|
tempsRaidSmEnerContact.Arret_du_comptage();
|
|
tempsSecondMembreEnergContact.Arret_du_comptage();
|
|
temps_CL.Arret_du_comptage();
|
|
temps_CLL.Arret_du_comptage();
|
|
temps_lois_comportement.Arret_du_comptage();
|
|
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
|
|
void Algori::Sortie_temps_cpu(const LesCondLim& lesCondLim
|
|
, const Charge& charge,const LesContacts & contact)
|
|
{ // la petite méthode qui sert au transfert et qui doit-être appelé avant les sorties
|
|
Temps_CPU_HZpp_to_lesTempsCpu(lesCondLim,charge,contact);
|
|
// on récupère le fichier des temps cpu
|
|
entreePrinc->Ouverture_fichier_temps_cpu(); // ouverture au cas où
|
|
// récupération du fichier des temps cpu
|
|
ofstream & sort_cpu = entreePrinc->Sort_temps_cpu();
|
|
// on concatène la totalité pour ensuite sortir également des pourcentage
|
|
double total_cpu = tempsInitialisation.Temps_CPU_User();
|
|
total_cpu += tempsMiseAjourAlgo.Temps_CPU_User();
|
|
total_cpu += tempsCalEquilibre.Temps_CPU_User();
|
|
// total_cpu += tempsRaidSmEner.Temps_CPU_User();
|
|
// total_cpu += tempsSecondMembreEnerg.Temps_CPU_User();
|
|
// total_cpu += tempsResolSystemLineaire.Temps_CPU_User();
|
|
total_cpu += tempsSauvegarde.Temps_CPU_User();
|
|
total_cpu += tempsSortieFilCalcul.Temps_CPU_User();
|
|
// total_cpu += tempsRaidSmEnerContact.Temps_CPU_User();
|
|
// total_cpu += tempsSecondMembreEnergContact.Temps_CPU_User();
|
|
// total_cpu += temps_CL.Temps_CPU_User();
|
|
// total_cpu += temps_CLL.Temps_CPU_User();
|
|
// total_cpu += temps_lois_comportement.Temps_CPU_User();
|
|
// total_cpu += temps_metrique_K_SM.Temps_CPU_User(); // il ne faut pas ajouter la métrique
|
|
// total_cpu += temps_chargement.Temps_CPU_User();
|
|
// total_cpu += temps_rech_contact.Temps_CPU_User();
|
|
int nbdigit = 6; // pour le pourcentage
|
|
// int nbdigit_temps = 14; // pour les temps
|
|
|
|
|
|
// é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);
|
|
#ifndef MISE_AU_POINT
|
|
sort_cpu << " (version la plus rapide )";
|
|
#endif
|
|
#ifdef MISE_AU_POINT
|
|
sort_cpu << " (version avec le plus de verifications pendant le calcul et les I/O ) ";
|
|
#endif
|
|
sort_cpu << "\n \n --------------- temps_locaux_cpu_en_milliseconde: ---------";
|
|
sort_cpu << fixed;
|
|
sort_cpu.precision(2);
|
|
// pour éviter de faire une division par 0
|
|
total_cpu = MaX(ConstMath::trespetit, total_cpu);
|
|
sort_cpu << "\n ---> tps_total_algo "
|
|
<< "("<< std::setw(nbdigit) << total_cpu/1000. << " ) ";
|
|
|
|
sort_cpu << "\n tps_InitAlgo "
|
|
<< "("<< std::setw(nbdigit) << (100*tempsInitialisation.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< tempsInitialisation.Temps_CPU_User_milli();
|
|
sort_cpu << "\n tps_MiseAJourAlgo "
|
|
<< "("<< std::setw(nbdigit) << (100*tempsMiseAjourAlgo.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< tempsMiseAjourAlgo.Temps_CPU_User_milli();
|
|
sort_cpu << "\n tps_CalEquilibre "
|
|
<< "("<< std::setw(nbdigit) << (100*tempsCalEquilibre.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< tempsCalEquilibre.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_MatSmLoc "
|
|
<< ".("<< std::setw(nbdigit) << (100*tempsRaidSmEner.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< tempsRaidSmEner.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_SmLoc "
|
|
<< ".("<< std::setw(nbdigit) << (100*tempsSecondMembreEnerg.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< tempsSecondMembreEnerg.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_lois_comp "
|
|
<< "..("<< std::setw(nbdigit) << (100*temps_lois_comportement.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< temps_lois_comportement.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_metrique_KSM "
|
|
<< "...("<< std::setw(nbdigit) << (100*temps_metrique_K_SM.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< temps_metrique_K_SM.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_chargement "
|
|
<< ".("<< std::setw(nbdigit) << (100*temps_chargement.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< temps_chargement.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_rech_contact "
|
|
<< ".("<< std::setw(nbdigit) << (100*temps_rech_contact.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< temps_rech_contact.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_contactMatSmLoc "
|
|
<< ".("<< std::setw(nbdigit) << (100*tempsRaidSmEnerContact.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< tempsRaidSmEnerContact.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_contactSmLoc "
|
|
<< ".("<< std::setw(nbdigit) << (100*tempsSecondMembreEnergContact.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< tempsSecondMembreEnergContact.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_CL "
|
|
<< ".("<< std::setw(nbdigit) << (100*temps_CL.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< temps_CL.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_CLL "
|
|
<< ".("<< std::setw(nbdigit) << (100*temps_CLL.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< temps_CLL.Temps_CPU_User_milli()
|
|
;
|
|
|
|
sort_cpu << "\n tps_ResSystLineaire "
|
|
<< "("<< std::setw(nbdigit) << (100*tempsResolSystemLineaire.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< tempsResolSystemLineaire.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_Sauvegarde "
|
|
<< "("<< std::setw(nbdigit) << (100*tempsSauvegarde.Temps_CPU_User()/total_cpu) << " % ) "
|
|
<< tempsSauvegarde.Temps_CPU_User_milli()
|
|
;
|
|
sort_cpu << "\n tps_SortieFilCalcul "
|
|
<< "("<< 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";
|
|
};
|
|
|
|
// mise à jour qui sont gérées par la classe mère algo
|
|
// a priori que des choses génériques du type gestion des variables privées
|
|
void Algori::MiseAJourAlgoMere(ParaGlob * paraGlob,LesMaillages * lesMail,LesReferences* lesRef
|
|
,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
|
|
,VariablesExporter* varExpor
|
|
,LesLoisDeComp* lesLoisDeComp,DiversStockage* diversStockage
|
|
,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
|
|
,Resultats* resultats)
|
|
{
|
|
// ---------- on initialise les conteneurs quelconques pour varExpor
|
|
varExpor->InitialisationConteneursQuelconques(*lesMail,listeVecGlob,*lesRef);
|
|
|
|
// -- modif concernant le stockage global pour volume déplacé: cas d'élément 2D dans un calcul 3D
|
|
// on met à jour le tableau de volume déplacé en fonction du nombre de maillage effectif
|
|
int nbMailMax = lesMail->NbMaillage();
|
|
// normalement ne fait rien si la taille n'est pas changé
|
|
if (vol_total2D_avec_plan_ref.Taille() != nbMailMax)
|
|
{vol_total2D_avec_plan_ref.Change_taille(nbMailMax,Coordonnee(ParaGlob::Dimension()));
|
|
// on remet à jour le stockage des grandeurs globales
|
|
if (pa.CalVolTotalEntreSurfaceEtPlansRef())
|
|
{ listeVarGlob["vol_total2D_avec_plan_yz"]=&(vol_total2D_avec_plan_ref(1)(1));
|
|
listeVarGlob["vol_total2D_avec_plan_xz"]=&(vol_total2D_avec_plan_ref(1)(2));
|
|
listeVarGlob["vol_total2D_avec_plan_xy"]=&(vol_total2D_avec_plan_ref(1)(3));
|
|
};
|
|
// s'il y a plus de 1 maillage, on définit de nouvelles variables globales
|
|
if (pa.CalVolTotalEntreSurfaceEtPlansRef())
|
|
for (int nbMail =2; nbMail<= nbMailMax; nbMail++)
|
|
{ // l'ordre des string est fait pour que le switch ensuite soit ok
|
|
string nom1("vol_total2D_avec_plan_xy_"+ChangeEntierSTring(nbMail));
|
|
listeVarGlob[nom1]=&(vol_total2D_avec_plan_ref(nbMail)(3));
|
|
TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
|
(VOL_ELEM_AVEC_PLAN_REF,nom1,SCALAIRE_DOUBLE);
|
|
string nom2("vol_total2D_avec_plan_yz_"+ChangeEntierSTring(nbMail));
|
|
listeVarGlob[nom2]=&(vol_total2D_avec_plan_ref(nbMail)(1));
|
|
TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
|
(VOL_ELEM_AVEC_PLAN_REF,nom2,SCALAIRE_DOUBLE);
|
|
string nom3("vol_total2D_avec_plan_xz_"+ChangeEntierSTring(nbMail));
|
|
listeVarGlob[nom3]=&(vol_total2D_avec_plan_ref(nbMail)(2));
|
|
TypeQuelconque_enum_etendu::Ajout_un_TypeQuelconque_enum_etendu
|
|
(VOL_ELEM_AVEC_PLAN_REF,nom3,SCALAIRE_DOUBLE);
|
|
|
|
// --- on ajoute les grandeurs au niveau de paraglob
|
|
// si elles n'existent pas
|
|
double titi=0.; // une grandeur de travail
|
|
Grandeur_scalaire_double grand_courant(titi); // idem
|
|
TypeQuelconque typQ1(GENERIQUE_UNE_GRANDEUR_GLOBALE,NU_DDL,grand_courant); // idem
|
|
switch (ParaGlob::Dimension())
|
|
{ case 3: if (ParaGlob::param->GrandeurGlobal(nom1) == NULL)
|
|
ParaGlob::param->Ajout_grandeur_consultable(&typQ1,nom1);
|
|
case 2: if (ParaGlob::param->GrandeurGlobal(nom2) == NULL)
|
|
ParaGlob::param->Ajout_grandeur_consultable(&typQ1,nom2);
|
|
case 1: if (ParaGlob::param->GrandeurGlobal(nom3) == NULL)
|
|
ParaGlob::param->Ajout_grandeur_consultable(&typQ1,nom1);
|
|
default: break;
|
|
};
|
|
};
|
|
};
|
|
// on récupère éventuellement la modulation de précision
|
|
if (nom_modulation_precision.length())
|
|
{modulation_precision = lesFonctionsnD->Trouve(nom_modulation_precision);
|
|
if (modulation_precision->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
|
|
{// on vérifie qu'en retour on a un scalaire
|
|
modulation_precision->Valeur_pour_variables_globales(); // pour simplifier
|
|
if (modulation_precision->NbComposante() != 1)
|
|
{cout << "\n *** erreur parametre algorithme: la fonction nD " << nom_modulation_precision
|
|
<< " de modulation de la precision d'equilibre globale "
|
|
<< " ne retourne pas un scalaire unique !! a priori ce n'est pas correct ";
|
|
Sortie(1);
|
|
};
|
|
}
|
|
else
|
|
{cout << "\n *** erreur parametre algorithme: la fonction nD " << nom_modulation_precision
|
|
<< " de modulation de la precision d'equilibre globale "
|
|
<< " utilise des variables autres que globales, ce n'est pas possible ! ";
|
|
Sortie(1);
|
|
};
|
|
};
|
|
// on récupère éventuellement la fonction nD définissant la norme
|
|
if (pa.Norme().nom1 == "fonction_nD:")
|
|
{fct_norme = lesFonctionsnD->Trouve(pa.Norme().nom2);
|
|
if (fct_norme->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
|
|
{// on vérifie qu'en retour on a un scalaire
|
|
fct_norme->Valeur_pour_variables_globales(); // pour simplifier
|
|
if (fct_norme->NbComposante() != 1)
|
|
{cout << "\n *** erreur parametre algorithme: la fonction nD " << pa.Norme().nom2
|
|
<< " de definition de la norme de convergence d'equilibre globale "
|
|
<< " ne retourne pas un scalaire unique !! a priori ce n'est pas correct ";
|
|
Sortie(1);
|
|
};
|
|
}
|
|
else
|
|
{cout << "\n *** erreur parametre algorithme: la fonction nD " << pa.Norme().nom2
|
|
<< " de definition de la norme de convergence d'equilibre globale "
|
|
<< " utilise des variables autres que globales, ce n'est pas possible ! ";
|
|
Sortie(1);
|
|
};
|
|
};
|
|
// on récupère éventuellement la fonction correspondant à nom_fct_nD_inter_nb_entre_relax
|
|
if (nom_fct_nD_inter_nb_entre_relax.length())
|
|
{fct_nD_inter_nb_entre_relax = lesFonctionsnD->Trouve(nom_fct_nD_inter_nb_entre_relax);
|
|
if (fct_nD_inter_nb_entre_relax->Nom_variables().Taille() == 0) // cas où il n'y a que des variables globales
|
|
{// on vérifie qu'en retour on a un scalaire
|
|
fct_nD_inter_nb_entre_relax->Valeur_pour_variables_globales(); // pour simplifier
|
|
if (fct_nD_inter_nb_entre_relax->NbComposante() != 1)
|
|
{cout << "\n *** erreur parametre algorithme: la fonction nD " << nom_fct_nD_inter_nb_entre_relax
|
|
<< " qui permet de cacluler la valeur du parametre inter_nb_entre_relax "
|
|
<< " ne retourne pas un scalaire unique !! a priori ce n'est pas correct ";
|
|
Sortie(1);
|
|
};
|
|
}
|
|
else
|
|
{cout << "\n *** erreur parametre algorithme: la fonction nD " << nom_fct_nD_inter_nb_entre_relax
|
|
<< " qui permet de cacluler la valeur du parametre inter_nb_entre_relax "
|
|
<< " utilise des variables autres que globales, ce n'est pas possible ! ";
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|
|
// on met à jour les repères d'anisotropie éventuelle
|
|
lesMail->Mise_a_jour_repere_anisotropie(diversStockage,lesFonctionsnD);
|
|
|
|
// on introduit au niveau des noeuds, si cela n'est pas déjà fait
|
|
// les conteneurs pour les forces internes et externes à t
|
|
{// 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
|
|
Grandeur_coordonnee gt(coor); // une grandeur typique de type Grandeur_coordonnee
|
|
// def d'un type quelconque représentatif pour un vecteur force à chaque noeud
|
|
TypeQuelconque typQ_gene_int(FORCE_GENE_INT_t,X1,gt);
|
|
lesMail->AjoutConteneurAuNoeud(typQ_gene_int);
|
|
TypeQuelconque typQ_gene_ext(FORCE_GENE_EXT_t,X1,gt);
|
|
lesMail->AjoutConteneurAuNoeud(typQ_gene_ext);
|
|
};
|
|
|
|
// on initialise certaines énergies qui sont stockées au niveau de l'algo
|
|
// mais qui sont en fait indépendantes de l'algo, donc il faut que ces énergies soient à jour
|
|
// elles sont donc initialisées à partir des grandeurs globales qui elles mêmes ont été mise à jour
|
|
// l'objectif est d'éviter une initialisation par défaut à 0 lorsque l'algo fait suite à un autre algo
|
|
// du coup, avant tout calcul du nouvel algo, on utilise les grandeurs déjà calculées par le précédent algo
|
|
//
|
|
// --- cas des énergies internes venants des lois de comportement :
|
|
// ENERGIE_ELASTIQUE,ENERGIE_PLASTIQUE,ENERGIE_VISQUEUSE,
|
|
{{void* pt_void = ParaGlob::param->Mise_a_jour_grandeur_consultable(ENERGIE_ELASTIQUE);
|
|
TypeQuelconque* pt_quelc = (TypeQuelconque*) pt_void;
|
|
Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier
|
|
energTotal.ChangeEnergieElastique(*(gr.ConteneurDouble())) ;
|
|
};
|
|
{void* pt_void = ParaGlob::param->Mise_a_jour_grandeur_consultable(ENERGIE_PLASTIQUE);
|
|
TypeQuelconque* pt_quelc = (TypeQuelconque*) pt_void;
|
|
Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier
|
|
energTotal.ChangeDissipationPlastique( *(gr.ConteneurDouble()) );
|
|
};
|
|
{void* pt_void = ParaGlob::param->Mise_a_jour_grandeur_consultable(ENERGIE_VISQUEUSE);
|
|
TypeQuelconque* pt_quelc = (TypeQuelconque*) pt_void;
|
|
Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier
|
|
energTotal.ChangeDissipationVisqueuse(*(gr.ConteneurDouble()));
|
|
};
|
|
};
|
|
// --- cas des énergies de contact :
|
|
// ENERGIE_PENALISATION,ENERGIE_FROT_ELAST,ENERGIE_FROT_PLAST,ENERGIE_FROT_VISQ
|
|
{{void* pt_void = ParaGlob::param->Mise_a_jour_grandeur_consultable(ENERGIE_PENALISATION);
|
|
TypeQuelconque* pt_quelc = (TypeQuelconque*) pt_void;
|
|
Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier
|
|
////------- debug
|
|
//cout << "\n debug*** Algori::MiseAJourAlgoMere "
|
|
// << "\n pt_void= " << pt_void << " gr.ContDouble()= " << gr.ContDouble()
|
|
// << " (*(gr.ConteneurDouble())) = " << (*(gr.ConteneurDouble()))
|
|
// << flush;
|
|
//
|
|
//// --- fin debug
|
|
energPenalisation = *(gr.ConteneurDouble());
|
|
};
|
|
{void* pt_void = ParaGlob::param->Mise_a_jour_grandeur_consultable(ENERGIE_FROT_ELAST);
|
|
TypeQuelconque* pt_quelc = (TypeQuelconque*) pt_void;
|
|
Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier
|
|
energFrottement.ChangeEnergieElastique(*(gr.ConteneurDouble()));
|
|
};
|
|
{void* pt_void = ParaGlob::param->Mise_a_jour_grandeur_consultable(ENERGIE_FROT_PLAST);
|
|
TypeQuelconque* pt_quelc = (TypeQuelconque*) pt_void;
|
|
Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier
|
|
energFrottement.ChangeDissipationPlastique( *(gr.ConteneurDouble()) );
|
|
};
|
|
{void* pt_void = ParaGlob::param->Mise_a_jour_grandeur_consultable(ENERGIE_FROT_VISQ);
|
|
TypeQuelconque* pt_quelc = (TypeQuelconque*) pt_void;
|
|
Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) pt_quelc->Grandeur_pointee()); // pour simplifier
|
|
energFrottement.ChangeDissipationVisqueuse(*(gr.ConteneurDouble()));
|
|
};
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
// gestion éventuelle d'une renumérotation, qui prend en compte les éléments de contact
|
|
// premier_calcul: indique s'il s'agit d'un premier calcul on non
|
|
// nouvelle_situation_contact : indique s'il y a du nouveau sur le contact
|
|
// 1) si niveau_substitution =0 : -> mise à jour de toutes les matrices
|
|
// 2) si niveau_substitution = i : -> uniquement mise à jour de la matrices i
|
|
// par contre la dimension de tab_matglob est toujours mis à jour si c'est nécessaire
|
|
// ramène true si la matrice a été changée
|
|
bool Algori::Gestion_stockage_et_renumerotation_avec_contact(bool premier_calcul
|
|
,LesMaillages * lesMail, bool & nouvelle_situation_contact
|
|
,LesCondLim* lesCondLim,LesReferences* lesRef
|
|
,Tableau <Mat_abstraite* >& tab_mato,const Nb_assemb& nb_casAssemb
|
|
,LesContacts* lescontacts,int niveau_substitution)
|
|
{
|
|
#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())
|
|
{ // récup des connexions entre noeud dues aux contacts
|
|
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) = 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);
|
|
if (calcul_ok) // cas où il y a eu effectivement un changement de numérotation
|
|
{//lesMail->MiseAJourPointeurAssemblage(nb_casAssemb);// mise a jour des pointeurs d'assemblage
|
|
// il faut regarder un peu partout: élément, frontière etc
|
|
// on met à jour le tableau indice pour LesContacts
|
|
lescontacts->Mise_a_jour_indice(lesMail->Indice());
|
|
// enfin il faut renuméroter la matrice
|
|
Mise_a_jour_Choix_matriciel_contact
|
|
(tab_mato,nb_casAssemb,lescontacts,niveau_substitution,&nevez_largeurs);
|
|
retour = true;
|
|
}
|
|
else
|
|
{ Mise_a_jour_Choix_matriciel_contact
|
|
(tab_mato,nb_casAssemb,lescontacts,niveau_substitution,NULL);
|
|
retour = true;
|
|
};
|
|
};
|
|
}
|
|
else
|
|
{ Mise_a_jour_Choix_matriciel_contact
|
|
(tab_mato,nb_casAssemb,lescontacts,niveau_substitution,NULL);
|
|
retour = true;
|
|
};
|
|
} //-- fin du cas si premier calcul
|
|
else
|
|
{if (nouvelle_situation_contact)
|
|
{if (ParaGlob::param->ParaAlgoControleActifs().Optimisation_numerotation())
|
|
{ // récup des connexions entre noeud dues aux contacts
|
|
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);
|
|
// 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
|
|
{
|
|
// on met à jour le tableau indice pour LesContacts
|
|
lescontacts->Mise_a_jour_indice(lesMail->Indice());
|
|
//lesMail->MiseAJourPointeurAssemblage(nb_casAssemb);// mise a jour des pointeurs d'assemblage
|
|
Mise_a_jour_Choix_matriciel_contact
|
|
(tab_mato,nb_casAssemb,lescontacts,niveau_substitution,&nevez_largeurs);
|
|
retour = true;
|
|
}
|
|
else
|
|
{ Mise_a_jour_Choix_matriciel_contact
|
|
(tab_mato,nb_casAssemb,lescontacts,niveau_substitution,NULL);
|
|
retour = true;
|
|
};
|
|
};
|
|
}
|
|
else
|
|
{ Mise_a_jour_Choix_matriciel_contact
|
|
(tab_mato,nb_casAssemb,lescontacts,niveau_substitution,NULL);
|
|
retour = true;
|
|
};
|
|
}
|
|
else
|
|
{retour = false; };
|
|
}; //-- fin du cas si ce n'est pas un premier calcul
|
|
// retour
|
|
return retour;
|
|
};
|
|
|
|
|
|
// --- même chose mais sans le contact, par contre prise en compte d'un changement éventuelle
|
|
// imposé par exemple par les CLL
|
|
// gestion éventuelle d'une renumérotation des pointeurs d'assemblage , qui prend en compte les CLL
|
|
// premier_calcul : indique s'il s'agit d'un premier calcul on non
|
|
// nouvelle_situation_CLL : indique s'il y a du nouveau sur les CLL
|
|
// -> la renumérotation des pointeurs s'effectue que si:
|
|
// a) ParaAlgoControleActifs().Optimisation_pointeur_assemblage() est ok
|
|
// b) soit c'est un premier calcul, soit il y a du nouveau sur les CLL
|
|
|
|
// 1) si niveau_substitution =0 : -> mise à jour de toutes les matrices
|
|
// 2) si niveau_substitution = i : -> uniquement mise à jour de la matrices i
|
|
// par contre la dimension de tab_matglob est toujours mis à jour si c'est nécessaire
|
|
// ramène true si la matrice a été changée
|
|
// NB: lescontacts est quand même passé en paramètre, car on doit le renseigner au niveau d'un
|
|
// tableau d'indice (num de noeuds) lorsque les num ont changés, ceci pour être opérationnel
|
|
// par la suite si le contact devient actif
|
|
bool Algori::Gestion_stockage_et_renumerotation_sans_contact(LesContacts* lescontacts,bool premier_calcul
|
|
,LesMaillages * lesMail, bool & nouvelle_situation_CLL
|
|
,LesCondLim* lesCondLim,LesReferences* lesRef
|
|
,Tableau <Mat_abstraite* >& tab_mato,const Nb_assemb& nb_casAssemb
|
|
,int niveau_substitution)
|
|
{
|
|
#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
|
|
if (ParaGlob::param->ParaAlgoControleActifs().Optimisation_pointeur_assemblage())
|
|
{ // 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) = 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);
|
|
if (calcul_ok) // cas où il y a eu effectivement un changement de numérotation
|
|
{//lesMail->MiseAJourPointeurAssemblage(nb_casAssemb);// mise a jour des pointeurs d'assemblage
|
|
// il faut regarder un peu partout: élément, frontière etc
|
|
// on met à jour le tableau indice pour LesContacts
|
|
lescontacts->Mise_a_jour_indice(lesMail->Indice());
|
|
// enfin il faut renuméroter la matrice
|
|
// ici on ne se sert pas du contact
|
|
Mise_a_jour_Choix_matriciel_contact
|
|
(tab_mato,nb_casAssemb,NULL,niveau_substitution,&nevez_largeurs);
|
|
retour = true;
|
|
};
|
|
// sinon on ne fait rien
|
|
};
|
|
} //-- fin du cas si premier calcul
|
|
else
|
|
{if (nouvelle_situation_CLL)
|
|
{if (ParaGlob::param->ParaAlgoControleActifs().Optimisation_pointeur_assemblage())
|
|
{ // 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 ( ((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);
|
|
if (calcul_ok) // cas où il y a eu effectivement un changement de numérotation
|
|
{
|
|
// on met à jour le tableau indice pour LesContacts
|
|
lescontacts->Mise_a_jour_indice(lesMail->Indice());
|
|
//lesMail->MiseAJourPointeurAssemblage(nb_casAssemb);// mise a jour des pointeurs d'assemblage
|
|
Mise_a_jour_Choix_matriciel_contact
|
|
(tab_mato,nb_casAssemb,NULL,niveau_substitution,&nevez_largeurs);
|
|
retour = true;
|
|
};
|
|
// sinon on ne fait rien
|
|
};
|
|
};
|
|
}; //-- fin du cas si ce n'est pas un premier calcul
|
|
// retour
|
|
return retour;
|
|
};
|
|
|
|
|
|
// mise à jour de delta_X, var_delta_X et passage en global des maxi
|
|
void Algori::Cal_Transfert_delta_et_var_X(double& max_delta_X, double& max_var_delta_X)
|
|
{ var_delta_X = -delta_X; // sauvegarde de la dernière valeur
|
|
// calcul du nouveau delta_X
|
|
delta_X.Zero(); delta_X += X_tdt; delta_X -= X_t;// X_tdt - X_t
|
|
// calcul de la variation de delta_X
|
|
var_delta_X += delta_X;
|
|
// calcul des maxis en valeurs absolue
|
|
max_delta_X = delta_X.Max_val_abs();
|
|
max_var_delta_X = var_delta_X.Max_val_abs();
|
|
// passage au niveau global
|
|
ParaGlob::param->Mise_a_jour_grandeur_consultable_Scalaire_double(MAXdeltaX,max_delta_X);
|
|
ParaGlob::param->Mise_a_jour_grandeur_consultable_Scalaire_double(MAXvarDeltaX,max_var_delta_X);
|
|
|
|
};
|
|
|
|
|
|
// ---------- static pour la création d'un algorithme particulier ---------
|
|
// ramène un pointeur sur l'algorithme spécifique correspondant aux paramètres
|
|
// IMPORTANT : il y a création de l'algorithme correspondant (utilisation d'un new)
|
|
Algori* Algori::New_Agori(EnumTypeCalcul id_TypeCalcul,const bool avec_typeDeCalcul
|
|
,const list <EnumSousTypeCalcul>& soustype
|
|
,const list <bool>& avec_soustypeDeCalcul
|
|
,UtilLecture& entreePrinc
|
|
)
|
|
|
|
{ // définition du pointeur de retour
|
|
Algori* algo_specifique;
|
|
|
|
switch (id_TypeCalcul)
|
|
{case NON_DYNA :
|
|
{ algo_specifique = new AlgoriNonDyna
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case NON_DYNA_CONT :
|
|
{ algo_specifique = new ImpliNonDynaCont
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case FLAMB_LINEAIRE :
|
|
{ algo_specifique = new AlgoriFlambLineaire
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case INFORMATIONS :
|
|
{ algo_specifique = new AlgoInformations
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case UTILITAIRES :
|
|
{ algo_specifique = new AlgoUtils
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case DYNA_EXP :
|
|
{ algo_specifique = new AlgoriDynaExpli
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case DYNA_EXP_TCHAMWA :
|
|
{ algo_specifique = new AlgoriTchamwa
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case DYNA_EXP_CHUNG_LEE :
|
|
{ algo_specifique = new Algori_chung_lee
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case DYNA_EXP_ZHAI :
|
|
{ algo_specifique = new AlgoriDynaExpli_zhai
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case DYNA_IMP :
|
|
{ algo_specifique = new AlgoriNewmark
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case UMAT_ABAQUS :
|
|
{ algo_specifique = new AlgoUmatAbaqus
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case DYNA_RUNGE_KUTTA :
|
|
{ algo_specifique = new AlgoriRungeKutta
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case DYNA_EXP_BONELLI :
|
|
{ algo_specifique = new AlgoBonelli
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case RELAX_DYNA :
|
|
{ algo_specifique = new AlgoriRelaxDyna
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
case COMBINER :
|
|
{ algo_specifique = new AlgoriCombine
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
break;
|
|
}
|
|
default :
|
|
{ cout << "\n type d\'algorithme non encore implante, desole ! \n";
|
|
cout << " agorithme demande = " << Nom_TypeCalcul(id_TypeCalcul);
|
|
cout << endl;
|
|
entreePrinc.MessageBuffer("** lecture du type d\'algorithme **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|
|
return algo_specifique;
|
|
};
|
|
|
|
// 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)
|
|
Tableau <Algori *> Algori::New_tous_les_Algo
|
|
(const bool avec_typeDeCalcul
|
|
,const list <EnumSousTypeCalcul>& soustype
|
|
,const list <bool>& avec_soustypeDeCalcul
|
|
,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
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(3) = new AlgoriFlambLineaire
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(4) = new AlgoInformations
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(5) = new AlgoUtils
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(6) = new AlgoriDynaExpli
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(7) = new AlgoriTchamwa
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(8) = new Algori_chung_lee
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(9) = new AlgoriDynaExpli_zhai
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(10) = new AlgoriNewmark
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(11) = new AlgoUmatAbaqus
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(12) = new AlgoriRungeKutta
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(13) = new AlgoBonelli
|
|
(avec_typeDeCalcul,soustype,avec_soustypeDeCalcul,entreePrinc);
|
|
tab_algo_specifique(14) = new AlgoriRelaxDyna
|
|
(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
|
|
|
|
|
|
|
|
|