274 lines
12 KiB
C++
274 lines
12 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 "Condilineaire.h"
|
|
|
|
// surcharge de l'opérateur =
|
|
Condilineaire& Condilineaire::operator = (const Condilineaire& cond)
|
|
{ pt = cond.pt;
|
|
val = cond.val;
|
|
beta = cond.beta;
|
|
Uk_impose = cond.Uk_impose;
|
|
iddl =cond.iddl;
|
|
t_enu = cond.t_enu;
|
|
t_noeud = cond.t_noeud;
|
|
casAssemb = cond.casAssemb;
|
|
return *this;
|
|
};
|
|
|
|
// mise en place des pointeurs de ddl d'assemblage
|
|
const Condilineaire& Condilineaire::ConditionPourPointeursAssemblage(const Nb_assemb& nb_casAssemb)
|
|
{ // pour les appels aux noeuds
|
|
casAssemb = nb_casAssemb; int nb_assemb = casAssemb.n;
|
|
// il s'agit ici de construire la condition pour les pointeurs d'assemblage
|
|
int taille = pt.Taille();
|
|
int nb_noeud = t_noeud.Taille();int itab=1;
|
|
int nbddlfamille = taille / nb_noeud;
|
|
for (int i_noe=1;i_noe <= nb_noeud;i_noe++)
|
|
for (int i =1; i<= nbddlfamille; i++,itab++)
|
|
// récup du pointeur d'assemblage
|
|
{ Enum_ddl enu = t_enu(itab); // pour simplifier
|
|
pt(itab) = t_noeud(i_noe)->Pointeur_assemblage(enu,nb_assemb);
|
|
// dans le cas où le pointeur n'existe pas, on regarde si l'on est en dynamique et que la condition linéaire est
|
|
// sur des positions, déplacement. Si le cas d'assemblage est de type dynamique, c'est sur les gammas qu'il faut récupérer les infos
|
|
if (pt(itab) == -1)
|
|
{ if (Evolution_temporelle_du_calcul(ParaGlob::param->TypeCalcul_maitre()) == DYNAMIQUE)
|
|
if (Dans_combinaison(1,enu)) //1 pour la combinaison dynamique
|
|
{ //on construit le ddl en gama équivalent aux ddl donné
|
|
Enum_ddl enugamma = Enum_ddl(((int)enu)-((int)PremierDdlFamille(enu)) + ((int)GAMMA1));
|
|
// on récupère le pointeur éventuelle
|
|
pt(itab) = t_noeud(i_noe)->Pointeur_assemblage(enugamma,nb_assemb);
|
|
};
|
|
};
|
|
#ifdef MISE_AU_POINT
|
|
if ( pt(itab) == -1 )
|
|
{ cout << "\nErreur : ddl X1 inexistant pour le cas de charge " << nb_assemb
|
|
<< '\n'
|
|
<< "Condilineaire::ConditionPourPointeursAssemblage(.. 3\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
};
|
|
// retour
|
|
return *this;
|
|
};
|
|
|
|
|
|
// ramène la différence maxi qui existe entre les numéros de noeuds de la condition linéaire
|
|
// peut-être utilisé pour calculer une largeur de bande par exemple
|
|
// important: cette méthode n'est valide que si les numéros de noeuds sont tous différents
|
|
// donc que la numérotation interne des noeuds a été changé pour cela
|
|
// NB: en fonctionnement normal, ce n'est pas le cas ! sauf dans le cas où un seul maillage existe
|
|
// voir LesMaillages::Renumerotation( pour un exemple d'utilisation
|
|
int Condilineaire::DiffMaxiNumeroNoeud()const
|
|
{ // on va parcourir les noeuds de la condition
|
|
int nb_noeud = t_noeud.Taille();
|
|
int num_mini = t_noeud(1)->Num_noeud(); // initialisation
|
|
int num_maxi = num_mini; // init
|
|
for (int i_noe=2;i_noe <= nb_noeud;i_noe++)
|
|
{ Noeud & noe = *t_noeud(i_noe); // pour simplifier
|
|
num_mini = MiN (num_mini, noe.Num_noeud());
|
|
num_maxi = MaX(num_maxi,noe.Num_noeud());
|
|
};
|
|
return (num_maxi-num_mini);
|
|
};
|
|
|
|
|
|
// ramène la largeur de bande en ddl
|
|
// à cause de la condition linéaire
|
|
// casAssemb : donne le cas d'assemblage a prendre en compte
|
|
// les condi linéaires ne donnent pas des largeurs de bande sup et inf égales !!!
|
|
// I/O : demi = la demi largeur de bande maxi ,
|
|
// total = le maxi = la largeur sup + la largeur inf +1
|
|
void Condilineaire::Largeur_Bande(int& demi,int& total,const Nb_assemb& casAssemb)
|
|
{ int nb_Assemb = casAssemb.n; // récup du numéro d'assemblage
|
|
// on va parcourir les noeuds de la condition
|
|
int nb_noeud = t_noeud.Taille();
|
|
int noe=1;
|
|
Noeud & nne = *t_noeud(noe);
|
|
for ( int no=noe+1; no<=nb_noeud;no++)
|
|
{ Noeud & nno = *t_noeud(no);
|
|
int di;
|
|
if (nne.PosiAssemb(nb_Assemb) >= nno.PosiAssemb(nb_Assemb))
|
|
di = nne.PosiAssemb(nb_Assemb) - nno.PosiAssemb(nb_Assemb)
|
|
+ nne.NB_ddl_actif_casAssemb(nb_Assemb);
|
|
else
|
|
di = nno.PosiAssemb(nb_Assemb) - nne.PosiAssemb(nb_Assemb)
|
|
+ nno.NB_ddl_actif_casAssemb(nb_Assemb);
|
|
if ( di > demi) demi = di;
|
|
if ( 2*di > total) total = 2*di;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// affichaga à l'écran des infos de la CL
|
|
void Condilineaire::Affiche() const
|
|
{ cout << "\n --- condition lineaire ---\n";
|
|
cout << "\n tableau pt: " << pt;
|
|
// le tableau des coefficients
|
|
cout << "\n val= "<< val;
|
|
// la valeur de la condition linéaire
|
|
cout << "\n beta= " << beta << " Uk_impose= "<< Uk_impose << " ";
|
|
// le repérage des noeuds supportant la condition linéaire
|
|
int nb_noeud = t_noeud.Taille();
|
|
cout << "\n les noeuds: nb_noeud= " << nb_noeud << " ";
|
|
for (int i=1; i<= nb_noeud; i++)
|
|
cout << " num_mail= " << t_noeud(i)->Num_Mail() << " num_noeud= " << t_noeud(i)->Num_noeud() << " ";
|
|
// le tableau des énumérés
|
|
cout << "\n enumeres: t_enu= " << t_enu << " ";
|
|
// le numéro d'ordre du ddl modifié dans noeud
|
|
cout << "\n numero d'ordre du ddl modifie dans le noeud " << iddl << " \n";
|
|
};
|
|
|
|
//----- lecture écriture de restart -----
|
|
void Condilineaire::Lecture_base_info
|
|
(Tableau <int>& numMaillage, ifstream& ent,Tableau <int>& numNoeud)
|
|
{ // lecture du tableau
|
|
pt.Entree(ent);
|
|
// le tableau des coefficients
|
|
ent >> val;
|
|
// la valeur de la condition linéaire
|
|
ent >> beta >> Uk_impose;
|
|
// le repérage des noeud supportant la condition linéaire
|
|
string nom;int taille;
|
|
ent >> nom >> taille;
|
|
t_noeud.Change_taille(taille,NULL);
|
|
numMaillage.Change_taille(taille);
|
|
numNoeud.Change_taille(taille);
|
|
for (int i=1;i<= taille; i++)
|
|
ent >> numMaillage(i) >>numNoeud(i);
|
|
// lecture des énumérés
|
|
ent >> t_enu;
|
|
// lecture du numéro d'ordre du ddl modifié dans noeud
|
|
ent >> iddl;
|
|
};
|
|
void Condilineaire::Ecriture_base_info(ofstream& sort)
|
|
{ // sauvegarde du tableau
|
|
pt.Sortir(sort);
|
|
// le tableau des coefficients
|
|
sort << val;
|
|
// la valeur de la condition linéaire
|
|
sort << beta << " "<< Uk_impose << " ";
|
|
// le repérage des noeuds supportant la condition linéaire
|
|
int nb_noeud = t_noeud.Taille();
|
|
sort << " nb_noeud= " << nb_noeud << " ";
|
|
for (int i=1; i<= nb_noeud; i++)
|
|
sort << t_noeud(i)->Num_Mail() << " " << t_noeud(i)->Num_noeud() << " ";
|
|
// le tableau des énumérés
|
|
sort << t_enu << " ";
|
|
// le numéro d'ordre du ddl modifié dans noeud
|
|
sort << iddl << " \n";
|
|
};
|
|
|
|
#ifdef UTILISATION_MPI // spécifique au calcul parallèle
|
|
// stockage dans un unique vecteur, des infos à partir de l'indice rang inclus
|
|
// correspond à une sérialisation des infos
|
|
// ramène le positionnement dans v pour un prochain enreg, sauf si > à la taille de v
|
|
// dans ce cas ramène 0
|
|
int Condilineaire::Pack_vecteur(Vecteur& v,int rang) const
|
|
{ // le tableau de pointeurs
|
|
int taille_pt = pt.Taille();
|
|
v(rang) = taille_pt;rang++;
|
|
for (int i=1;i<=taille_pt;i++)
|
|
{v(rang)= pt(i);rang++;};
|
|
// le vecteur val
|
|
int taille_val = val.Taille();
|
|
v(rang) = taille_val;
|
|
for (int i=1;i<=taille_val;i++)
|
|
{v(rang)= val(i);rang++;};
|
|
// beta
|
|
v(rang)=beta; rang++;
|
|
// Uk_impose
|
|
v(rang)=Uk_impose; rang++;
|
|
// le cas d'assemblage associé
|
|
rang = casAssemb.Pack_vecteur(v,rang);
|
|
// le tableau t_enu
|
|
int taille_t_enu = t_enu.Taille();
|
|
v(rang) = taille_t_enu;rang++;
|
|
for (int i=1;i<=taille_t_enu;i++)
|
|
{v(rang)= t_enu(i);rang++;};
|
|
// iddl
|
|
v(rang)=iddl; rang++;
|
|
// le taleau t_noeud
|
|
// on considère que la numérotation est la même pour tous les cpu
|
|
// du coup on sauvegarde le numéro de maillage et le numéro de noeud
|
|
int taille_t_noeud = t_noeud.Taille();rang++;
|
|
v(rang)= taille_t_noeud;
|
|
for (int i=1;i<=taille_t_noeud;i++)
|
|
{v(rang)= t_noeud(i)->Num_Mail();rang++;
|
|
v(rang)= t_noeud(i)->Num_noeud();rang++;
|
|
};
|
|
if (rang > v.Taille()) rang = 0;
|
|
return rang;
|
|
};
|
|
|
|
// taille du conteneur actuel de la condition linéaire
|
|
int Condilineaire::Taille_Pack() const
|
|
{int taille_pack = 0; // init
|
|
taille_pack += pt.Taille() + 1;
|
|
taille_pack += val.Taille() + 1;
|
|
taille_pack += 2;
|
|
taille_pack += casAssemb.Taille_Pack();
|
|
taille_pack += t_enu.Taille()+1;
|
|
taille_pack += 1;
|
|
taille_pack += 2*t_noeud.Taille()+1;
|
|
return taille_pack;
|
|
};
|
|
|
|
#endif
|
|
|
|
/*
|
|
|
|
// VARIABLES PROTEGEES :
|
|
Tableau<int> pt; //tableau des pointeurs de ddl concerne, pt(i) = la position du ddl i
|
|
// dans la matrice globale
|
|
Vecteur val; // tableau des coefficients de la condition lineaire
|
|
double beta; // valeur beta a laquelle est egale la condition lineaire
|
|
// dans le cas de la mise en place de la CL à partir d'un changement de repère, on peut stocker la valeur imposée avant chg de repère
|
|
double Uk_impose; // valeur a imposer sur le ddl avant changement de repère, qui correspondra à beta après chg de repère
|
|
// Uk_impose sert uniquement de stockage, mais n'est pas forcément cohérent avec la CL, sa manipulation est faite en dehors de la classe
|
|
// via : ChangeUk_impose et Val_Uk_impose
|
|
Nb_assemb casAssemb; // le cas d'assemblage associé
|
|
|
|
// le blocage de condition est appliquee sur le ddl numero "iddl" du noeud "noe"
|
|
Tableau <Enum_ddl > t_enu; // tableau des identificateur de ddl de la CLL
|
|
// t_enu(1) est l'identificateur du ddl qui est bloqué pour la CLL
|
|
// lorsque seul t_enu(1) existe, cela signifie qu'il faut construire
|
|
// les indices,
|
|
|
|
// iddl -> le numéro d'ordre dans sa famille, du ddl bloqué
|
|
// NB: ce n'est pas la position du ddl dans le noeud !!, cette dernière est: Tab_Enum()(1)
|
|
int iddl;
|
|
// le tableau des noeuds de la CLL, le premier contient la condition
|
|
Tableau < Noeud *> t_noeud;
|
|
|
|
*/
|
|
|
|
|