2021-09-26 14:31:23 +02:00
|
|
|
// 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.
|
|
|
|
//
|
2023-05-03 17:23:49 +02:00
|
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
2021-09-26 14:31:23 +02:00
|
|
|
// 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 "AlgoUmatAbaqus.h"
|
|
|
|
#include "ConstMath.h"
|
|
|
|
#include "ElemPoint.h"
|
|
|
|
#include "ElemPoint_CP.h"
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
|
|
// CONSTRUCTEURS :
|
|
|
|
AlgoUmatAbaqus::AlgoUmatAbaqus () : // par defaut
|
|
|
|
Algori()
|
|
|
|
{ };
|
|
|
|
|
|
|
|
// constructeur en fonction du type de calcul et du sous type
|
|
|
|
// il y a ici lecture des parametres attaches au type
|
|
|
|
AlgoUmatAbaqus::AlgoUmatAbaqus (const bool avec_typeDeCal
|
|
|
|
,const list <EnumSousTypeCalcul>& soustype
|
|
|
|
,const list <bool>& avec_soustypeDeCal
|
|
|
|
,UtilLecture& entreePrinc) :
|
|
|
|
Algori(UMAT_ABAQUS,avec_typeDeCal,soustype,avec_soustypeDeCal,entreePrinc)
|
|
|
|
{ // lecture des paramètres attachés au type de calcul (ici aucun)
|
|
|
|
switch (entreePrinc.Lec_ent_info())
|
|
|
|
{ case 0 :
|
|
|
|
{// pour signaler à Algori qu'il n'y a pas eu de lecture de paramètre
|
|
|
|
deja_lue_entete_parametre=0;
|
|
|
|
// puis appel de la méthode de la classe mère
|
|
|
|
Algori::lecture_Parametres(entreePrinc); break;}
|
|
|
|
case -11 : // cas de la création d'un fichier de commande
|
|
|
|
{ Info_commande_parametres(entreePrinc); break;}
|
|
|
|
case -12 : // cas de la création d'un schéma XML, on ne fait rien à ce niveau
|
|
|
|
{ break;}
|
|
|
|
default:
|
|
|
|
Sortie(1);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// constructeur de copie
|
|
|
|
AlgoUmatAbaqus::AlgoUmatAbaqus (const AlgoUmatAbaqus& algo):
|
|
|
|
Algori(algo)
|
|
|
|
{ };
|
|
|
|
|
|
|
|
// destructeur
|
|
|
|
AlgoUmatAbaqus::~AlgoUmatAbaqus ()
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
// execution de l'algorithme dans le cas non dynamique, implicit, sans contact
|
|
|
|
void AlgoUmatAbaqus::Execution(ParaGlob * paraGlob,LesMaillages * lesMail
|
|
|
|
,LesReferences* lesRef,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
|
|
|
|
,VariablesExporter* varExpor,LesLoisDeComp* lesLoisDeComp, DiversStockage* divStock
|
|
|
|
,Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts,Resultats* resultats)
|
|
|
|
{ // on traite le cas particulier de maillage avec des éléments points, sans noeud référencé
|
|
|
|
// dans le cas où il n'y a pas de noeud rattaché, on ajoute un noeud par défaut
|
|
|
|
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(UMAT_ABAQUS); // transfert info
|
|
|
|
int nbmaillage = lesMail->NbMaillage();
|
|
|
|
int dima = ParaGlob::Dimension();
|
|
|
|
string nom_rien("");
|
|
|
|
Element::Signature elempoint(CONSTANT,POINT, MECA_SOLIDE_DEFORMABLE,nom_rien);
|
|
|
|
Element::Signature elempoint_CP(CONSTANT,POINT_CP, MECA_SOLIDE_DEFORMABLE,nom_rien);
|
|
|
|
for (int im = 1;im<=nbmaillage;im++)
|
|
|
|
{ list <Noeud*> listeNoeudSup; // liste des noeuds supplémentaires
|
|
|
|
int num_noeud = 0;
|
|
|
|
// le traitement ne concerne que le cas où il n'existe aucun noeud dans le maillage
|
|
|
|
if ((lesMail->Nombre_element(im) !=0) && (lesMail->Nombre_noeud(im) == 0))
|
|
|
|
{ int nbN=lesMail->Nombre_element(im);
|
|
|
|
for (int ine=1;ine<=nbN;ine++)
|
|
|
|
{ Element & elem = lesMail->Element_LesMaille(im,ine);
|
|
|
|
Element::Signature signa = elem.Signature_element();
|
|
|
|
// le traitement ne concerne que les éléments points
|
|
|
|
if (signa == elempoint)
|
|
|
|
{ ElemPoint& elemP = *((ElemPoint *) &elem);
|
|
|
|
// on crée un noeud par défaut qui sera ajouté au maillage à la fin
|
|
|
|
Coordonnee coorRef(dima); // un point en 0 par défaut
|
|
|
|
num_noeud++;
|
|
|
|
Noeud* nevez_noeud = new Noeud(num_noeud,coorRef,im);
|
|
|
|
listeNoeudSup.push_back(nevez_noeud);
|
|
|
|
// on complète l'élément
|
|
|
|
elemP.Associer_noeud (nevez_noeud);
|
|
|
|
nevez_noeud->Travail_tdt(); // a priori on travaillera à tdt aussi
|
|
|
|
}
|
|
|
|
else if (signa == elempoint_CP)
|
|
|
|
{ ElemPoint_CP& elemP = *((ElemPoint_CP *) &elem);
|
|
|
|
// on crée un noeud par défaut qui sera ajouté au maillage à la fin
|
|
|
|
Coordonnee coorRef(dima); // un point en 0 par défaut
|
|
|
|
num_noeud++;
|
|
|
|
Noeud* nevez_noeud = new Noeud(num_noeud,coorRef,im);
|
|
|
|
listeNoeudSup.push_back(nevez_noeud);
|
|
|
|
// on complète l'élément
|
|
|
|
elemP.Associer_noeud (nevez_noeud);
|
|
|
|
nevez_noeud->Travail_tdt(); // a priori on travaillera à tdt aussi
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// on s'occupe maintenant d'ajouter les noeuds
|
|
|
|
lesMail->Ajout_de_Noeuds(listeNoeudSup,im);
|
|
|
|
};
|
|
|
|
|
|
|
|
// on définit le type de calcul a effectuer :
|
|
|
|
// ici par défaut (pour l'instant) on ne calcul que l'umat
|
|
|
|
Calcul_Umat(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,lesLoisDeComp
|
|
|
|
,divStock,charge,lesCondLim,lesContacts,resultats );
|
|
|
|
};
|
|
|
|
|
|
|
|
// Calcul: umat abaqus -> en fait uniquement la loi de comportement pour un point d'intégration
|
|
|
|
void AlgoUmatAbaqus::Calcul_Umat(ParaGlob * paraGlob,LesMaillages * lesMail,
|
|
|
|
LesReferences* lesRef,LesCourbes1D* lesCourbes1D,LesFonctions_nD* lesFonctionsnD
|
|
|
|
,LesLoisDeComp* lesLois,DiversStockage* diversStockage,
|
|
|
|
Charge* charge,LesCondLim* lesCondLim,LesContacts* lesContacts
|
|
|
|
,Resultats* resultats)
|
|
|
|
{ // on met en route une boucle qui ne s'arrête normalement que si on reçoit le signal:
|
|
|
|
// incre = -1
|
|
|
|
Transfert_ParaGlob_ALGO_GLOBAL_ACTUEL(UMAT_ABAQUS); // transfert info
|
|
|
|
// dans une première étape on effectue une lecture des grandeurs umat transmises par abaqus
|
|
|
|
// ceci dans le conteneur commun de tous les éléments ElemPoint
|
|
|
|
// ceci permet d'initialiser le processus
|
|
|
|
bool utilisation_umat_interne = false; // on utilise des pipes
|
|
|
|
|
|
|
|
// on utilise le premier élément du premier maillage pour faire le choix entre POINT et POINT_CP
|
|
|
|
const ElemPoint::inNeNpti* inne = NULL;
|
|
|
|
Enum_geom type_point = lesMail->Element_LesMaille(1,1).Id_geometrie();
|
|
|
|
switch (type_point)
|
|
|
|
{case POINT: inne =
|
|
|
|
(ElemPoint::inNeNpti*) & ElemPoint::Lecture_Abaqus(utilisation_umat_interne);
|
|
|
|
break;
|
|
|
|
case POINT_CP:inne =
|
|
|
|
(ElemPoint::inNeNpti*) & ElemPoint_CP::Lecture_Abaqus(utilisation_umat_interne);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cout << "\n *** erreur de def d'un element point, le type "
|
|
|
|
<< Nom_geom(type_point)
|
|
|
|
<< " n'est pas pris en compte !! "
|
|
|
|
<< "\n AlgoUmatAbaqus::Calcul_Umat(...";
|
|
|
|
Sortie(1);
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
|
|
|
// const ElemPoint::inNeNpti& inne = ElemPoint::Lecture_Abaqus(utilisation_umat_interne);
|
|
|
|
int nb_maillage_umat = 0; // le numéro de maillage umat
|
|
|
|
int dernier_increment = *(inne->incre);
|
|
|
|
int increment_courant = *(inne->incre);
|
|
|
|
int der_iteration = 0; // = 0 la première fois par défaut car on n'a aucune info sur ce point
|
|
|
|
int iteration_courante = 0; // avec les paramètes de l'umat
|
|
|
|
int nbmaillage = lesMail->NbMaillage(); //le nombre actuel de maillage
|
|
|
|
|
|
|
|
bool premier_passage = true;
|
|
|
|
OrdreVisu::EnumTypeIncre type_incre = OrdreVisu::PREMIER_INCRE; // pour la visualisation au fil du calcul
|
|
|
|
vector <Element*> tab_element; // pour n'attribuer qu'une fois chaque élément
|
|
|
|
int nb_max_element_enreg=0;
|
|
|
|
// on vérifie que le premier numéro est non nul
|
|
|
|
if (*(inne->nbe) <= 0)
|
|
|
|
{ cout << "\n erreur **** le numero de l'element lu= " << *(inne->nbe)
|
|
|
|
<< "\n n'est pas utilisable avec la version actuelle d'herezh++ "
|
|
|
|
<< "\n AlgoUmatAbaqus::Calcul_Umat(..." << endl;
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
// --- on complète le maillage initiale: température, loi de comp etc. ---
|
|
|
|
// def éventuelle de la loi de comp à partir des données du .info
|
|
|
|
lesMail->Completer(diversStockage,lesLois,lesFonctionsnD);
|
|
|
|
// deux refs d'éléments qui servent pour les tests
|
|
|
|
ElemPoint el_ref_point;
|
|
|
|
ElemPoint_CP el_ref_point_cp;
|
|
|
|
|
|
|
|
// normalement on ne sort plus de la boucle suivante
|
|
|
|
do
|
|
|
|
{ // affichage pour la mise au point
|
|
|
|
if (ParaGlob::NiveauImpression() > 6)
|
|
|
|
{ cout << "\n numero de l'increment = " << *(inne->incre)
|
|
|
|
<< "\n numero du step = " << *(inne->step)
|
|
|
|
<< "\n numero de l'element = " << *(inne->nbe)
|
|
|
|
<< "\n numero du pt integ = " << *(inne->nbpti) << endl;
|
|
|
|
};
|
|
|
|
if (premier_passage) // premier passage
|
|
|
|
{ // création de la liste des éléments
|
|
|
|
list <Element*> list_elem; // liste de tous les éléments
|
|
|
|
list <Noeud* > li_noeud; // liste de tous les noeuds
|
|
|
|
// on récupère "le" noeud lu, qui contient éventuellement des initialisations
|
|
|
|
// telles que la présence du ddl température, ce qui nous permettra de répercuter
|
|
|
|
// ces infos sur tous les noeuds créés
|
|
|
|
Noeud & noeud_de_reference = lesMail->Noeud_LesMaille(1, 1);
|
|
|
|
// idem pour l'élément
|
|
|
|
Element & elem_de_reference = lesMail->Element_LesMaille(1,1);
|
|
|
|
|
|
|
|
int dima = ParaGlob::Dimension();
|
|
|
|
int num_noeud=0;
|
|
|
|
int num_nouveau_maillage=nbmaillage+1;
|
|
|
|
// // on crée un nouveau maillage vide
|
|
|
|
// string nom_maillage_N="maillage_intermediaire";
|
|
|
|
// int num_nouveau_maillage = lesMail->Creation_nouveau_maillage(li_noeud,list_elem,nom_maillage_N);
|
|
|
|
// modification du temps de manière arbitraire
|
|
|
|
pa.Modif_temps(*(inne->temps_tdt),*(inne->delta_t));
|
|
|
|
// deux variables pour sauvegarder les temps utilisés au premier passage
|
|
|
|
double temps_tdt_premier_passage = *(inne->temps_tdt);
|
|
|
|
double delta_t_premier_passage = *(inne->delta_t);
|
|
|
|
do
|
|
|
|
{ // création de la liste des éléments
|
|
|
|
Element* elnevez = NULL;
|
|
|
|
bool element_a_creer = true;
|
|
|
|
// tout d'abord on regarde si le numéro d'élément a déjà été affecté
|
|
|
|
// si oui on se sert de l'élément, sinon, on crée un élément nouveau
|
|
|
|
int nbe = *(inne->nbe);
|
|
|
|
if (nbe <= nb_max_element_enreg)
|
|
|
|
{// cas où le numéro est succeptible d'être enregistré
|
|
|
|
if (tab_element[nbe-1] != NULL)
|
|
|
|
{ elnevez = tab_element[nbe-1];
|
|
|
|
element_a_creer = false; // on signale qu'il ne faut pas creer de nouvel élément
|
|
|
|
};
|
|
|
|
// sinon l'élément n'existe pas mais la place dans le tableau est disponible
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{// cas où l'élément n'existe pas et la place dans le tableau non plus
|
|
|
|
// on crée donc la place
|
|
|
|
Element* elnull = NULL;
|
|
|
|
for (int i=nb_max_element_enreg+1;i<=nbe;i++)
|
|
|
|
tab_element.push_back(elnull);
|
|
|
|
nb_max_element_enreg = nbe;
|
|
|
|
};
|
|
|
|
// maintenant on crée si necessaire un nouvel élément
|
|
|
|
if (element_a_creer)
|
|
|
|
{ switch (type_point)
|
|
|
|
{case POINT:
|
|
|
|
{if (!(el_ref_point.Signature_element() == elem_de_reference.Signature_element()))
|
|
|
|
{cout << "\n *** erreur: l'element du maillage de base doit etre de type POINT ";
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
// sinon c'est ok
|
|
|
|
ElemPoint& el_ref_po = *((ElemPoint*) &elem_de_reference);
|
|
|
|
elnevez = new ElemPoint(el_ref_po); // création d'un nouvel élément
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case POINT_CP:
|
|
|
|
{if (!(el_ref_point_cp.Signature_element() == elem_de_reference.Signature_element()))
|
|
|
|
{cout << "\n *** erreur: l'element du maillage de base doit etre de type POINT_CP ";
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
// sinon c'est ok
|
|
|
|
ElemPoint_CP& el_ref_po = *((ElemPoint_CP*) &elem_de_reference);
|
|
|
|
elnevez = new ElemPoint_CP(el_ref_po); // création d'un nouvel élément
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// elnevez = new ElemPoint_CP(); // création d'un nouvel élément
|
|
|
|
// break;
|
|
|
|
default:
|
|
|
|
cout << "\n *** erreur de def d'un element point, le type "
|
|
|
|
<< Nom_geom(type_point)
|
|
|
|
<< " n'est pas pris en compte !! "
|
|
|
|
<< "\n AlgoUmatAbaqus::Calcul_Umat(...";
|
|
|
|
Sortie(1);
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
|
|
|
list_elem.push_back(elnevez);
|
|
|
|
// on ajoute un noeud par défaut
|
|
|
|
num_noeud++;
|
|
|
|
Coordonnee coorRef(dima); // un point en 0 par défaut
|
|
|
|
|
|
|
|
//Noeud* nevez_noeud = new Noeud(num_noeud,coorRef,num_nouveau_maillage);
|
|
|
|
// ** modif 18 avril 2016 : on recopie le noeud initial plutôt qu'une
|
|
|
|
// création entièrement nouvelle, ceci nous permet d'intégrer des ddl que l'utilisation
|
|
|
|
// veut, par exemple la température
|
|
|
|
Noeud* nevez_noeud = new Noeud(noeud_de_reference);
|
|
|
|
nevez_noeud->Change_num_noeud(num_noeud);
|
|
|
|
nevez_noeud->Change_num_Mail(num_nouveau_maillage);
|
|
|
|
nevez_noeud->Change_coord0(coorRef);
|
|
|
|
|
|
|
|
li_noeud.push_back(nevez_noeud) ;
|
|
|
|
// on complète l'élément
|
|
|
|
ElemPoint* elnew = NULL; // pour simplifier
|
|
|
|
switch (type_point)
|
|
|
|
{case POINT: elnew = (ElemPoint*) elnevez; break; // pour simplifier
|
|
|
|
case POINT_CP: elnew = (ElemPoint_CP*) elnevez; break; // pour simplifier
|
|
|
|
default:break;
|
|
|
|
};
|
|
|
|
elnew->Associer_noeud (nevez_noeud);
|
|
|
|
nevez_noeud->Travail_tdt(); // a priori on travaillera à tdt aussi
|
|
|
|
// affichage pour la mise au point
|
|
|
|
if (ParaGlob::NiveauImpression() > 8)
|
|
|
|
cout << "\n creation element = " << *(inne->nbe) << endl;
|
|
|
|
tab_element[nbe-1] = elnevez;
|
|
|
|
elnevez->Change_num_elt (*(inne->nbe));
|
|
|
|
// // ------ ensuite l'idée est de complèter l'élément avec les infos lues
|
|
|
|
// // cependant le nouvel élément n'appartient encore à aucun maillage,
|
|
|
|
// //donc on l'ajoute au
|
|
|
|
// // au premier maillage
|
|
|
|
// list <Noeud *> taN; // liste de noeud à ajouter ici le nouveau
|
|
|
|
// taN.push_back(nevez_noeud);
|
|
|
|
// list <Element *> taE;taE.push_back(elnevez); // l'élément à ajouter
|
|
|
|
// list <const Reference*>* lref=NULL; // rien ici
|
|
|
|
// lesMail->Ajout_elements_et_noeuds(taN,taE,lref,lesRef,num_nouveau_maillage);
|
|
|
|
// // ---- cas de la loi de comp -----
|
|
|
|
// // on complète l'élément éventuellement: en particulier
|
|
|
|
// // def éventuelle de la loi de comp à partir des données du .info
|
|
|
|
// lesMail->Completer(diversStockage,lesLois,lesFonctionsnD);
|
|
|
|
// en fait la vérif suivante ne fonctionne pas, car à ce stade l'élément créé n'appartient
|
|
|
|
// à aucun maillage, donc la loi choisit dans le .info n'est pas affecté
|
|
|
|
// donc seule la loi définie par l'appel d'umat, est toujours prise en compte
|
|
|
|
// on laisse la vérif quand même pour l'instant bien que cela ne sert à rien
|
|
|
|
// -- vérif de la définition de la loi de comportement
|
|
|
|
// recup du pointeur le loi
|
|
|
|
LoiAbstraiteGeneral * pt = lesLois->PtLoi_abstraite(*(inne->nom_loi));
|
|
|
|
if (pt == NULL)
|
|
|
|
{ cout << "\n *** erreur, la loi definie dans le .info "<< (*(inne->nom_loi))
|
|
|
|
<< " n'existe pas !! "
|
|
|
|
" on stoppe l'execution pour eviter des pb de coherence eventuelles ";
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
|
|
|
|
// récup de la loi éventuellement déjà enregistrée
|
|
|
|
const Loi_comp_abstraite* loi_actuelle = elnew->LoiDeComportement();
|
|
|
|
if (loi_actuelle == NULL) // s'il n'y a aucune loi de définie on le fait
|
|
|
|
{ elnew->DefLoi(pt); }
|
|
|
|
else if ((pt) != (loi_actuelle))
|
|
|
|
{ cout << "\n *** erreur, la loi definie dans le .info pour l'element est differente "
|
|
|
|
" de celle demandee par le programme utilisateur de l'UMAT !! "
|
|
|
|
" on stoppe l'execution pour eviter des pb de coherence eventuelles ";
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// arrivée ici on a l'élément adoc on peut donc calculer
|
|
|
|
ElemPoint* elnew = (ElemPoint*) elnevez; // pour simplifier
|
|
|
|
// les cas en initialisation, calcul et écriture sont identique
|
|
|
|
// pour ElemPoint et ElemPoint_CP donc on garde le pointeur sur
|
|
|
|
// ElemPoint
|
|
|
|
// initialisation éventuelle: en particulier def de la loi de comp
|
|
|
|
// en fonction du nombre de pt d'integ qui a pu changer
|
|
|
|
elnew->InitialisationUmatAbaqus();
|
|
|
|
// calcul de l'UMat pour abaqus
|
|
|
|
elnew->CalculUmatAbaqus(pa);
|
|
|
|
// écriture du résultat
|
|
|
|
elnew->Ecriture_Abaqus(utilisation_umat_interne);
|
|
|
|
|
|
|
|
// modif: 12 nov 2018: on affiche le num d'incrément avant la lecture pour le prochain
|
|
|
|
// calcul
|
|
|
|
increment_courant = *(inne->incre);
|
|
|
|
if ((ParaGlob::NiveauImpression() > 2) && premier_passage)
|
|
|
|
{cout << "\n======================================================================"
|
|
|
|
<< "\nINCREMENT DE CHARGE : " << (*(inne->incre))
|
|
|
|
<< "\n======================================================================"
|
|
|
|
<< endl;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// comme la lecture est une méthode statique donc non virtualisable
|
|
|
|
// il est nécessaire de différencier le cas ElemPoint avec le cas ElemPoint_CP
|
|
|
|
switch (type_point)
|
|
|
|
{case POINT:
|
|
|
|
{ElemPoint* elnew1 = (ElemPoint*) elnevez; // pour simplifier
|
|
|
|
// lecture de nouvelles données
|
|
|
|
elnew1->Lecture_Abaqus(utilisation_umat_interne);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case POINT_CP:
|
|
|
|
{ElemPoint_CP* elnew1 = (ElemPoint_CP*) elnevez; // pour simplifier
|
|
|
|
// lecture de nouvelles données
|
|
|
|
elnew1->Lecture_Abaqus(utilisation_umat_interne);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:break;
|
|
|
|
};
|
|
|
|
// increment_courant = *(inne->incre);
|
|
|
|
// if ((ParaGlob::NiveauImpression() > 2) && premier_passage)
|
|
|
|
// {cout << "\n======================================================================"
|
|
|
|
// << "\nINCREMENT DE CHARGE : " << (*(inne->incre))
|
|
|
|
// << "\n======================================================================"
|
|
|
|
// << endl;
|
|
|
|
// };
|
|
|
|
premier_passage = false;
|
|
|
|
iteration_courante = elnew->NbIteration();
|
|
|
|
// on affiche éventuellement si l'on passe d'une itération à l'autre
|
|
|
|
if (iteration_courante != der_iteration)
|
|
|
|
{ der_iteration = iteration_courante;
|
|
|
|
if (ParaGlob::NiveauImpression() > 3)
|
|
|
|
cout << "\n ITERATION : " << iteration_courante << endl;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
while ( increment_courant == dernier_increment);
|
|
|
|
// maintenant on a changé de numéro d'incrément, et l'increment est > 1
|
|
|
|
// on crée le maillage correspondant, avec les noeuds et éléments déjà créé
|
|
|
|
// (il n'y a pas de création de nouveaux noeuds ou de nouveaux éléments, ainsi
|
|
|
|
// toutes les infos déjà calculées et stockées sont gardées)
|
|
|
|
string nom_maillage="maillage_umat";
|
|
|
|
nb_maillage_umat = lesMail->Creation_nouveau_maillage(li_noeud,list_elem,nom_maillage);
|
|
|
|
// on supprime les 2 maillages initiaux, sans supprimer les noeuds et éléments créés,
|
|
|
|
// car ce sont également les noeuds et éléments du nouveau maillage
|
|
|
|
bool sans_conservation_noeuds_elements = false;
|
|
|
|
// for (int i=1;i<nb_maillage_umat;i++)
|
|
|
|
// lesMail->Suppression_maillage(lesMail->NomMaillage(i),sans_conservation_noeuds_elements);
|
|
|
|
lesMail->Suppression_maillage(lesMail->NomMaillage(1),sans_conservation_noeuds_elements);
|
|
|
|
// on met à jour le compteur d'itération
|
|
|
|
der_iteration = iteration_courante;
|
|
|
|
// modification du temps correspondant au premier passage
|
|
|
|
pa.Modif_temps(temps_tdt_premier_passage,delta_t_premier_passage);
|
|
|
|
// on s'occupe d'une sortie si necessaire
|
|
|
|
if (this->Active_sauvegarde())
|
|
|
|
{ // si le fichier base_info n'est pas en service on l'ouvre
|
|
|
|
entreePrinc->Ouverture_base_info("ecriture");
|
|
|
|
// dans le cas ou se n'est pas un restart on sauvegarde l'incrément actuel
|
|
|
|
// c'est-à-dire le premier incrément
|
|
|
|
// après s'être positionné au début du fichier
|
|
|
|
if (this->Num_restart() == 0)
|
|
|
|
{ (entreePrinc->Sort_BI())->seekp(0);
|
|
|
|
int cas = 1;
|
|
|
|
paraGlob->Ecriture_base_info(*(entreePrinc->Sort_BI()),cas);
|
|
|
|
this->Ecriture_base_info
|
|
|
|
(cas,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,lesLois,diversStockage
|
|
|
|
,charge,lesCondLim,lesContacts,resultats,OrdreVisu::INCRE_0);
|
|
|
|
// visualisation éventuelle au fil du calcul
|
|
|
|
VisuAuFilDuCalcul(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,lesLois,diversStockage,charge
|
|
|
|
,lesCondLim,lesContacts,resultats,type_incre,(*(inne->incre)-1));
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // ----- cas des incréments courants > 1------
|
|
|
|
// récupération de l'élément
|
|
|
|
if (ParaGlob::NiveauImpression() > 8)
|
|
|
|
cout << "\n numero de l'element = " <<*(inne->nbe) << endl;
|
|
|
|
//Element& elem = lesMail->Element_LesMaille(nb_maillage_umat,*(inne->nbe));
|
|
|
|
// pour éviter des pb d'adressage indirecte on utilise directement le tableau
|
|
|
|
// de pointeur pour retrouver l'élément plutôt que lesMail
|
|
|
|
Element* elem = NULL;
|
|
|
|
if (tab_element[*(inne->nbe)-1] != NULL)
|
|
|
|
{elem = tab_element[*(inne->nbe)-1];}
|
|
|
|
else
|
|
|
|
{ cout << "\n erreur l'element demande (nb=" << *(inne->nbe)-1 << ") n'a pas ete attribue "
|
|
|
|
<< "dans la phase d'initialisation c-a-d lors du premier increment"
|
|
|
|
<< "\n AlgoUmatAbaqus::Calcul_Umat(...";
|
|
|
|
Sortie(1);
|
|
|
|
};
|
|
|
|
ElemPoint* el = (ElemPoint*) elem; // pour simplifier
|
|
|
|
// calcul de l'UMat pour abaqus
|
|
|
|
el->CalculUmatAbaqus(pa);
|
|
|
|
// écriture du résultat
|
|
|
|
el->Ecriture_Abaqus(utilisation_umat_interne);
|
|
|
|
// comme la lecture est une méthode statique donc non virtualisable
|
|
|
|
// il est nécessaire de différencier le cas ElemPoint avec le cas ElemPoint_CP
|
|
|
|
switch (type_point)
|
|
|
|
{case POINT:
|
|
|
|
{ElemPoint* el1 = (ElemPoint*) elem; // pour simplifier
|
|
|
|
// lecture de nouvelles données
|
|
|
|
el1->Lecture_Abaqus(utilisation_umat_interne);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case POINT_CP:
|
|
|
|
{ElemPoint_CP * el1 = (ElemPoint_CP*) elem; // pour simplifier
|
|
|
|
// lecture de nouvelles données
|
|
|
|
el1->Lecture_Abaqus(utilisation_umat_interne);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:break;
|
|
|
|
};
|
|
|
|
// // lecture de nouvelles données
|
|
|
|
// el->Lecture_Abaqus(utilisation_umat_interne);
|
|
|
|
increment_courant = *(inne->incre);
|
|
|
|
iteration_courante = el->NbIteration();;
|
|
|
|
};
|
|
|
|
// on note si l'on passe d'une itération à l'autre
|
|
|
|
if (iteration_courante != der_iteration)
|
|
|
|
{ der_iteration = iteration_courante;
|
|
|
|
if (ParaGlob::NiveauImpression() > 3)
|
|
|
|
cout << "\n ITERATION : " << iteration_courante << endl;
|
|
|
|
};
|
|
|
|
// mise à jour de t à tdt
|
|
|
|
if (increment_courant != dernier_increment)
|
|
|
|
{// modification du temps
|
|
|
|
pa.Modif_temps(*(inne->temps_tdt),*(inne->delta_t));
|
|
|
|
lesMail->TdtversT();
|
|
|
|
dernier_increment = increment_courant;
|
|
|
|
// --- traitement des sauvegardes éventuelles ---
|
|
|
|
// sauvegarde de l'incrément si nécessaire
|
|
|
|
Ecriture_base_info(2,lesMail,lesRef,lesCourbes1D,lesFonctionsnD
|
|
|
|
,lesLois,diversStockage,charge,lesCondLim,lesContacts
|
|
|
|
,resultats,type_incre,(*(inne->incre)-1));
|
|
|
|
// enregistrement du num d'incrément et du temps correspondant
|
|
|
|
list_incre_temps_calculer.push_front(Entier_et_Double((*(inne->incre)-1),pa.Variables_de_temps().TempsCourant()));
|
|
|
|
// visualisation éventuelle au fil du calcul
|
|
|
|
VisuAuFilDuCalcul(paraGlob,lesMail,lesRef,lesCourbes1D,lesFonctionsnD,lesLois,diversStockage,charge
|
|
|
|
,lesCondLim,lesContacts,resultats,type_incre,(*(inne->incre)-1));
|
|
|
|
// on affiche éventuellement le prochain incrément
|
|
|
|
if (ParaGlob::NiveauImpression() > 1)
|
|
|
|
{cout << "\n======================================================================"
|
|
|
|
<< "\nINCREMENT DE CHARGE : " << (*(inne->incre))
|
|
|
|
<< "\n======================================================================"
|
|
|
|
<< endl;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
} while (*(ElemPoint::IncreElemPtint_encours().incre)!=-1);
|
|
|
|
// fin
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// écriture des paramètres dans la base info
|
|
|
|
// = 1 : on écrit tout
|
|
|
|
// = 2 : on écrot uniquement les données variables (supposées comme telles)
|
|
|
|
void AlgoUmatAbaqus::Ecrit_Base_info_Parametre(UtilLecture& entreePrinc,const int& cas)
|
|
|
|
{
|
|
|
|
// récup du flot
|
2023-05-03 17:23:49 +02:00
|
|
|
// ofstream * sort = entreePrinc.Sort_BI();
|
2021-09-26 14:31:23 +02:00
|
|
|
// (*sort) << "\n parametres_algo_specifiques_ "<< Nom_TypeCalcul(this->TypeDeCalcul());
|
|
|
|
// ecriture: rien pour l'instant
|
|
|
|
// if (cas == 1)
|
|
|
|
// {
|
|
|
|
// } ;
|
|
|
|
// (*sort) << "\n fin_parametres_algo_specifiques_ ";
|
|
|
|
};
|
|
|
|
|
|
|
|
// lecture des paramètres dans la base info
|
|
|
|
// = 1 : on récupère tout
|
|
|
|
// = 2 : on récupère uniquement les données variables (supposées comme telles)
|
|
|
|
// choix = true : fonctionnememt normal
|
|
|
|
// choix = false : la méthode ne doit pas lire mais initialiser les données à leurs valeurs par défaut
|
|
|
|
// car la lecture est impossible
|
|
|
|
void AlgoUmatAbaqus::Lecture_Base_info_Parametre(UtilLecture& entreePrinc,const int& cas,bool choix)
|
|
|
|
{if (cas == 1)
|
|
|
|
{if (choix)
|
|
|
|
{// cas d'une lecture normale
|
|
|
|
// récup du flot
|
2023-05-03 17:23:49 +02:00
|
|
|
// ifstream * ent = entreePrinc.Ent_BI();
|
2021-09-26 14:31:23 +02:00
|
|
|
// pour l'instant on ne lit rien
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// création d'un fichier de commande: cas des paramètres spécifiques
|
|
|
|
void AlgoUmatAbaqus::Info_commande_parametres(UtilLecture& entreePrinc)
|
|
|
|
{ // écriture dans le fichier de commande
|
|
|
|
ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
|
|
|
|
sort << "\n#--------------------------------------------------------------------"
|
|
|
|
<< "\n| parametres (falcultatifs) associes l'algorithme umat pour abaqus |"
|
|
|
|
<< "\n#--------------------------------------------------------------------"
|
|
|
|
<< "\n"
|
|
|
|
<< "\n # aucun parametre pour l'instant ";
|
|
|
|
|
|
|
|
sort << "\n" << endl;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|