2216 lines
108 KiB
C++
2216 lines
108 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 "I_O_Condilineaire.h"
|
|
#include "CharUtil.h"
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <cstring>
|
|
#include <limits>
|
|
|
|
|
|
# include <iostream>
|
|
using namespace std; //introduces namespace std
|
|
|
|
// par défaut
|
|
I_O_Condilineaire::I_O_Condilineaire():
|
|
Condilineaire()
|
|
,nom_maillage(NULL),refe("")
|
|
,t_min(0.),t_max(ConstMath::tresgrand),echelle(1.)
|
|
,precedent(false),valeur_precedente_t(0.)
|
|
,tab_co_charge(),refs_associe(),enu(NU_DDL)
|
|
,nom_mail_associe()
|
|
,condition_relative(false)
|
|
,fctch(),delta_fctch(),nbddlfamille(0)
|
|
,def_auto_par_rotation(false),stricte_egalite(false)
|
|
,type_centre(1),mailEtNumCentreNoeud(),centre_noeud(NULL)
|
|
,pl(),dr()
|
|
{};
|
|
|
|
|
|
// de copie
|
|
I_O_Condilineaire::I_O_Condilineaire(const I_O_Condilineaire& nd):
|
|
Condilineaire(nd)
|
|
,nom_maillage(NULL),refe(nd.refe)
|
|
,t_min(nd.t_min),t_max(nd.t_max),echelle(nd.echelle)
|
|
,precedent(nd.precedent),valeur_precedente_t(nd.valeur_precedente_t)
|
|
,tab_co_charge(nd.tab_co_charge),refs_associe(nd.refs_associe)
|
|
,nom_mail_associe(nd.nom_mail_associe),enu(nd.enu)
|
|
,condition_relative(nd.condition_relative)
|
|
,fctch(nd.fctch),delta_fctch(nd.delta_fctch),nbddlfamille(nd.nbddlfamille)
|
|
,def_auto_par_rotation(nd.def_auto_par_rotation),stricte_egalite(nd.stricte_egalite)
|
|
,type_centre(nd.type_centre),centre_rotation(nd.centre_rotation)
|
|
,mailEtNumCentreNoeud(nd.mailEtNumCentreNoeud),centre_noeud(nd.centre_noeud)
|
|
,pl(nd.pl),dr(nd.dr)
|
|
{if (nd.nom_maillage != NULL)
|
|
nom_maillage = new string (*(nd.nom_maillage));
|
|
};
|
|
|
|
// DESTRUCTEUR :
|
|
I_O_Condilineaire::~I_O_Condilineaire()
|
|
{ if (nom_maillage != NULL)
|
|
delete nom_maillage;
|
|
};
|
|
|
|
// examine si la condition passée en argument possède les mêmes cibles que this
|
|
// mais que les data associés sont différents
|
|
// ramène true si c'est vrai, false sinon
|
|
// en fait cette fonction est définit par conformité avec le programme de lecture
|
|
// LectBloc<T>::Lecture(.. mais ici on peut avoir plusieurs conditions linéaire
|
|
// sur la même référence, donc on ramène toujours false
|
|
bool I_O_Condilineaire::MemeCibleMaisDataDifferents(I_O_Condilineaire& )
|
|
{ return false;
|
|
};
|
|
|
|
|
|
// Affiche les donnees
|
|
void I_O_Condilineaire::Affiche () const
|
|
{ // affichage éventuelle du nom de maillage
|
|
if (nom_maillage != NULL)
|
|
{ cout << "\n nom_mail= " << *nom_maillage;} else cout << "\n";
|
|
// puis le reste
|
|
cout << " ref_princ= " << refe ;
|
|
if (refs_associe.Taille() != 0)
|
|
{int tai = refs_associe.Taille();
|
|
cout << " ref_associe= ";
|
|
for (int i=1;i<=tai;i++)
|
|
if (nom_maillage != NULL)
|
|
{cout << nom_mail_associe(i) << " " << refs_associe(i) << " ";}
|
|
else
|
|
{cout << refs_associe(i) << " ";}
|
|
};
|
|
cout << "\n type_ddl= " << Nom_ddl(enu) ;
|
|
cout << " def_auto_par_rotation= " << def_auto_par_rotation;
|
|
cout << " stricte_egalite= " << stricte_egalite;
|
|
// if (!def_auto_par_rotation)
|
|
// { cout << " val_condi= " << this->beta << " coefficients= " << val;}
|
|
// else
|
|
// {if (type_centre == 1)
|
|
// { cout << " centre_fixe= " ;
|
|
// if (ParaGlob::Dimension() == 2) {cout << dr.PointDroite() << " " ;}
|
|
// else {cout << pl.PointPlan() << " " ;};
|
|
// }
|
|
// else if (type_centre == 2)
|
|
// { cout << " centre_noeud_t0= " << mailEtNumCentreNoeud << " ";}
|
|
// else if (type_centre == 3)
|
|
// { cout << " centre_noeud_t= " << mailEtNumCentreNoeud << " ";};
|
|
// if (ParaGlob::Dimension() == 2)
|
|
// {cout << " dir_droite_now= " << dr.VecDroite() << " dir_droite0= " << val;}
|
|
// else // cas dimension 3
|
|
// {cout << " normal_plan_now= " << pl.Vecplan() << " normal_plan0= " << val;}
|
|
// };
|
|
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
|
|
if (def_auto_par_rotation)
|
|
{if (type_centre == 1)
|
|
{ cout << " centre_fixe= " ;
|
|
if (dima == 2) {cout << dr.PointDroite() << " " ;}
|
|
else {cout << pl.PointPlan() << " " ;};
|
|
}
|
|
else if (type_centre == 2)
|
|
{ cout << " centre_noeud_t0= " << mailEtNumCentreNoeud << " ";}
|
|
else if (type_centre == 3)
|
|
{ cout << " centre_noeud_t= " << mailEtNumCentreNoeud << " ";};
|
|
if (dima == 2)
|
|
{cout << " dir_droite_now= " << dr.VecDroite() << " dir_droite0= " << val;}
|
|
else // cas dimension 3
|
|
{cout << " normal_plan_now= " << pl.Vecplan() << " normal_plan0= " << val;}
|
|
}
|
|
else if (stricte_egalite)
|
|
{ }
|
|
else
|
|
{ cout << " val_condi= " << this->beta << " coefficients= " << val;};
|
|
|
|
|
|
|
|
cout << " temps_mini= " << t_min << " temps_maxi= " << t_max
|
|
<< " echelle= " << echelle
|
|
<< " activite_actuelle: " << precedent
|
|
<< " condition_relative= " << condition_relative << " ";
|
|
cout << " courbe_charge= " << tab_co_charge;
|
|
cout << endl;
|
|
};
|
|
|
|
|
|
// Realise l'egalite
|
|
I_O_Condilineaire& I_O_Condilineaire::operator= (const I_O_Condilineaire& d)
|
|
{// traitement du nom de maillage éventuel
|
|
if (d.nom_maillage == NULL)
|
|
{if (nom_maillage != NULL)
|
|
{delete nom_maillage;nom_maillage=NULL; nom_mail_associe.Change_taille(0);}
|
|
}
|
|
else
|
|
{if (nom_maillage == NULL)
|
|
{nom_maillage = new string (*(d.nom_maillage));
|
|
nom_mail_associe = d.nom_mail_associe;
|
|
}
|
|
else
|
|
{*nom_maillage = *(d.nom_maillage);
|
|
nom_mail_associe = d.nom_mail_associe;
|
|
};
|
|
};
|
|
// nom de la référence
|
|
refe = d.refe;
|
|
// tableau de références associé
|
|
refs_associe = d.refs_associe;
|
|
// les temps
|
|
t_min = d.t_min; t_max = d.t_max;
|
|
echelle = d.echelle;
|
|
precedent = d.precedent;
|
|
valeur_precedente_t = d.valeur_precedente_t;
|
|
// l'énuméré
|
|
enu = d.enu;
|
|
nbddlfamille = d.nbddlfamille;
|
|
// la relativité de la condition
|
|
condition_relative = d.condition_relative;
|
|
// les courbes de charge
|
|
tab_co_charge = d.tab_co_charge;
|
|
def_auto_par_rotation = d.def_auto_par_rotation;
|
|
stricte_egalite = d.stricte_egalite;
|
|
type_centre = d.type_centre;
|
|
centre_rotation = d.centre_rotation;
|
|
mailEtNumCentreNoeud = d.mailEtNumCentreNoeud;
|
|
centre_noeud = d.centre_noeud;
|
|
pl = d.pl;
|
|
dr = d.dr;
|
|
|
|
// la condition linéaire
|
|
this->Condilineaire::operator=(d);
|
|
// retour
|
|
return *this;
|
|
};
|
|
|
|
//Surcharge d'operateur logique
|
|
bool I_O_Condilineaire::operator == ( I_O_Condilineaire& a) const
|
|
{ // traitement du nom de maillage éventuel
|
|
if (nom_maillage == NULL)
|
|
{ if (a.nom_maillage != NULL) return false;
|
|
}
|
|
else
|
|
{ if (a.nom_maillage == NULL) return false;
|
|
// sinon les deux sont non null: on test leur égalité
|
|
if (*nom_maillage != *(a.nom_maillage)) return false;
|
|
};
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
// cas des centres de rotation éventuelles, il peut y avoir des données qui ne servent pas
|
|
// qui soient différentes, alors que celles qui servent sont identiques !
|
|
if (def_auto_par_rotation != a.def_auto_par_rotation) return false;
|
|
if (stricte_egalite != a.stricte_egalite) return false;
|
|
if (def_auto_par_rotation)
|
|
{ if (type_centre != a.type_centre) return false;
|
|
switch (type_centre)
|
|
{ case 1: switch (dima)
|
|
{ case 2: if (dr.PointDroite() != a.dr.PointDroite()) return false; break;
|
|
case 3: if (pl.PointPlan() != a.pl.PointPlan()) return false; break;
|
|
};
|
|
case 2: case 3: if (centre_noeud != a.centre_noeud) return false; break;
|
|
};
|
|
switch (dima)
|
|
{ case 2: if (dr.VecDroite() != a.dr.VecDroite()) return false; break;
|
|
case 3: if (pl.Vecplan() != a.pl.Vecplan()) return false; break;
|
|
};
|
|
}
|
|
else if (stricte_egalite)
|
|
{ }
|
|
else
|
|
{if (this->beta != a.beta) return false;
|
|
if (val != a.val) return false;
|
|
};
|
|
|
|
// les autres données
|
|
if ( (refe==a.refe) && (refs_associe==a.refs_associe)
|
|
&& (nom_mail_associe == a.nom_mail_associe)
|
|
&& (t_min == a.t_min) && (t_max == a.t_max)
|
|
&& (echelle == a.echelle)
|
|
&& (precedent ==a.precedent)
|
|
&& (enu == a.enu) && (tab_co_charge == a.tab_co_charge)
|
|
&& (condition_relative == a.condition_relative)
|
|
)
|
|
{return true;}
|
|
else
|
|
{return false; };
|
|
} ;
|
|
|
|
|
|
// lecture de la condition linéaire sur le fichier d'entree
|
|
void I_O_Condilineaire::Lecture(UtilLecture & entreePrinc)
|
|
{ // on regarde tout d'abord si il y a un nom de maillage, qui doit être le premier nom
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
string nom;
|
|
*(entreePrinc.entree) >> nom;
|
|
if (nom == "nom_mail=")
|
|
{ // cas où il y a un nom de maillage
|
|
*(entreePrinc.entree) >> nom; // lecture du nom
|
|
if (nom_maillage == NULL) { nom_maillage = new string(nom);}
|
|
else { *nom_maillage = nom;};
|
|
// puis on prépare la suite en lisant la référence principale
|
|
*(entreePrinc.entree) >> nom;
|
|
};
|
|
// lecture de la reference
|
|
refe = nom;
|
|
if (refe.length() == 0)
|
|
{ // pas de reference
|
|
cout << "\n erreur de lecture d'une reference de condition limite lineaire "
|
|
<< " le nom de la reference a une longueur nulle \n";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// maintenant on lit les autres informations
|
|
// on lit l'énuméré
|
|
*(entreePrinc.entree) >> nom;
|
|
if (nom != "enu=")
|
|
{ // pas d'énuméré
|
|
cout << "\n erreur de lecture d'une reference de condition limite lineaire "
|
|
<< " on attendait enu= , et on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{ *(entreePrinc.entree) >> nom;
|
|
if (!ExisteEnum_ddl(nom))
|
|
{ // énuméré incorrecte
|
|
cout << "\n erreur de lecture de l'enumere de condition limite lineaire, il n'existe pas "
|
|
<< " dans la liste des enumeres correctes: on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else // on sauvegarde le premier ddl de la famille
|
|
{enu = PremierDdlFamille(Id_nom_ddl(nom));};
|
|
};
|
|
// on passe une ligne
|
|
entreePrinc.NouvelleDonnee(); // on passe un enregistrement
|
|
bool passer_une_ligne = false;
|
|
// lecture des références associées éventuellement
|
|
if (strstr(entreePrinc.tablcar,"refs_associe=")!=NULL)
|
|
{ *(entreePrinc.entree) >> nom;
|
|
if (nom != "refs_associe=")
|
|
{ // pas de mot clé
|
|
cout << "\n erreur de lecture des references associees pour un condition limite lineaire "
|
|
<< " on attendait refs_associe= , et on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{ // lecture de la liste demandée
|
|
int compteur=0; // pour éviter une boucle infinie
|
|
// il y a deux types de lecture suivant qu'il doit y avoir un nom de maillage ou pas
|
|
if (nom_maillage == NULL)
|
|
{list <string> list_inter;
|
|
while (compteur < 1000)
|
|
{(*entreePrinc.entree) >> nom; compteur++;
|
|
// gestion d'erreur
|
|
if (nom == "nom_mail=")
|
|
{ // cas où il y a un nom de maillage
|
|
cout << "\n erreur en lecture : on a lue: " << nom << " or la ref "
|
|
<< " principal ne comporte pas de nom de maillage, dans ce cas les ref"
|
|
<< " secondaires ne doivent pas comporter de nom de maillage !! ";
|
|
entreePrinc.MessageBuffer("*** lecture des references secondaire d'une condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// suite normale
|
|
if (nom != "fin_list_refs_associe_")
|
|
{list_inter.push_back(nom);}
|
|
else break;
|
|
};
|
|
// recopie dans le tableau
|
|
int taille = list_inter.size();
|
|
refs_associe.Change_taille(taille);
|
|
list <string>::iterator it,itfin=list_inter.end();
|
|
int i=1;
|
|
for (it = list_inter.begin();it!=itfin;it++,i++)
|
|
refs_associe(i)=*it;
|
|
}
|
|
else
|
|
// cas où il est possible qu'on lise nom de maillage
|
|
// de plus il faut attribuer un nom de maillage à chaque ref associé
|
|
{list <Deux_String> list_inter;
|
|
string nom_mail;
|
|
while (compteur < 1000)
|
|
{(*entreePrinc.entree) >> nom;
|
|
if (nom == "nom_mail=")
|
|
// cas où il y a un nom de maillage
|
|
{*(entreePrinc.entree) >> nom_mail; // lecture du nom
|
|
*(entreePrinc.entree) >> nom; // lecture de la référence
|
|
}
|
|
else
|
|
{nom_mail=*nom_maillage;}; // attribution du nom de maillage générique
|
|
compteur++;
|
|
if (nom != "fin_list_refs_associe_")
|
|
{list_inter.push_back(Deux_String(nom_mail,nom));}
|
|
else break;
|
|
};
|
|
// recopie dans le tableau
|
|
int taille = list_inter.size();
|
|
refs_associe.Change_taille(taille);nom_mail_associe.Change_taille(taille);
|
|
list <Deux_String>::iterator it,itfin=list_inter.end();
|
|
int i=1;
|
|
for (it = list_inter.begin();it!=itfin;it++,i++)
|
|
{nom_mail_associe(i)=(*it).nom1;refs_associe(i)=(*it).nom2;}
|
|
};
|
|
passer_une_ligne = true;
|
|
};
|
|
};
|
|
// on récupère l'échelle globale éventuellement
|
|
if(strstr(entreePrinc.tablcar,"ECHELLE:")!=0)
|
|
{ // cas où il y a un facteur d'échelle
|
|
*(entreePrinc.entree) >> nom;
|
|
if (nom != "ECHELLE:")
|
|
{cout << "\n erreur de syntaxe en lecture du facteur d'echelle "
|
|
<< " on attendait le mot cle ECHELLE: et on a lue " << nom << " ";
|
|
entreePrinc.MessageBuffer("**erreur lecture d'une reference de condition lineaire **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
// lecture du facteur
|
|
*(entreePrinc.entree) >> echelle;
|
|
}
|
|
else
|
|
// sinon on met l'échelle à 1
|
|
{ echelle = 1. ;}; //-- fin récup de l'échelle
|
|
|
|
// lecture d'un tmin et/ou tmax éventuel
|
|
if (strstr(entreePrinc.tablcar,"TEMPS_MINI=")!=NULL)
|
|
{ *(entreePrinc.entree) >> nom;
|
|
if (nom != "TEMPS_MINI=")
|
|
{ // pas d'énuméré
|
|
cout << "\n erreur de lecture: position du TEMPS_MINI= pour un condition limite lineaire "
|
|
<< " on attendait TEMPS_MINI= , et on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{(*entreePrinc.entree) >> t_min;passer_une_ligne = true;};
|
|
};
|
|
if (strstr(entreePrinc.tablcar,"TEMPS_MAXI=")!=NULL)
|
|
{ *(entreePrinc.entree) >> nom;
|
|
if (nom != "TEMPS_MAXI=")
|
|
{ // pas d'énuméré
|
|
cout << "\n erreur de lecture: position du TEMPS_MAXI= pour un condition limite lineaire "
|
|
<< " on attendait TEMPS_MAXI= , et on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{(*entreePrinc.entree) >> t_max;passer_une_ligne = true;};
|
|
};
|
|
// lecture éventuel de l'indicateur de condition relative
|
|
condition_relative = false; // faux par défaut
|
|
if (strstr(entreePrinc.tablcar,"CONDITION_RELATIVE=")!=NULL)
|
|
{*(entreePrinc.entree) >> nom;
|
|
if (nom != "CONDITION_RELATIVE=")
|
|
{ cout << "\n erreur de lecture: position de CONDITION_RELATIVE= erronee, pour un condition "
|
|
<< " limite lineaire, on attendait CONDITION_RELATIVE= , et on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{(*entreePrinc.entree) >> condition_relative; passer_une_ligne = true;};
|
|
// il y a une vérification concernant la présence de courbe de charge après la lecture de ces dernières
|
|
};
|
|
|
|
// on passe une ligne pour lire les coefficients de la condition linéaire
|
|
if (passer_une_ligne) entreePrinc.NouvelleDonnee(); // on passe éventuellement un enregistrement
|
|
passer_une_ligne = false;
|
|
|
|
// --- on regarde s'il s'agit d'une définition de linéarité / à une droit ou un plan
|
|
if (strstr(entreePrinc.tablcar,"def_auto_coef_planOuDroite_")!=NULL)
|
|
{ if (dima == 1)
|
|
{ cout << "\n erreur de lecture: on ne peut pas faire de definition automatique avec la dimension 1 ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
def_auto_par_rotation = true; // on signale une condition automatique
|
|
*(entreePrinc.entree) >> nom; // on passe le mot clé
|
|
if (nom != "def_auto_coef_planOuDroite_")
|
|
{ cout << "\n erreur de lecture: position de def_auto_coef_planOuDroite_ erronee, pour un condition "
|
|
<< " limite lineaire, on attendait def_auto_coef_planOuDroite_ , et on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// on vérifie qu'il n'y a pas de référence associée car ce cas n'est pas prévu (ni possible a priori)
|
|
if (refs_associe.Taille() != 0)
|
|
{ cout << "\n erreur de lecture: dans le cas du condition lineaire automatique avec ligne ou plan "
|
|
<< " on ne peut pas avoir de reference associe ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// dans le cas où on a lue un enum UX pb, car la projection concerne les positions et non les déplacements
|
|
// sinon il faut utiliser une condition générale
|
|
if (enu != X1)
|
|
{ cout << "\n erreur de coherence: dans le cas du condition lineaire automatique avec ligne ou plan "
|
|
<< " on ne peut pas utiliser comme enumere: " << Nom_ddl(enu) ;
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// ici l'échelle doit être égale à 1, on vérifie, pour des pb de projection et d'algo d'ensemble
|
|
if (echelle != 1.)
|
|
{ cout << "\n erreur de coherence: dans le cas du condition lineaire automatique avec ligne ou plan "
|
|
<< " on ne peut pas utiliser une echelle (ici= " << echelle << " ) differente de 1. !! " ;
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// ici on ne doit pas avoir de condition relative car ça ne signifie rien pour la projection, on vérifie,
|
|
if (condition_relative)
|
|
{ cout << "\n erreur de coherence: dans le cas du condition lineaire automatique avec ligne ou plan "
|
|
<< " on ne peut pas utiliser une condition relative (cela ne signifie rien dans le cas d'une projection ) !! " ;
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
|
|
|
|
// maintenant on lit le centre
|
|
*(entreePrinc.entree) >> nom;
|
|
// on met à jour la dimension des plan droite
|
|
switch (dima)
|
|
{ case 2: dr.Change_dim(dima);break;
|
|
case 3: pl.Change_dim(dima);break;
|
|
};
|
|
|
|
if (nom == "centre_fixe_")
|
|
{ type_centre = 1;
|
|
Coordonnee centre_rotation(dima);
|
|
centre_rotation.Lecture(entreePrinc);
|
|
switch (dima)
|
|
{ case 2: dr.Change_ptref(centre_rotation); break;
|
|
case 3: pl.Change_ptref(centre_rotation); break;
|
|
}
|
|
}
|
|
else if ((nom == "centre_noeud_a_t0_") || (nom == "centre_noeud_a_t_"))
|
|
{ if (nom == "centre_noeud_a_t0_") {type_centre = 2;}
|
|
else if (nom == "centre_noeud_a_t_") {type_centre = 3;};
|
|
// cas d'un centre donné par un numero de noeud
|
|
string nom_mail;
|
|
*(entreePrinc.entree) >> nom_mail;
|
|
if (nom_mail == "nom_mail=")
|
|
{ // cas où il y a un nom de maillage
|
|
*(entreePrinc.entree) >> mailEtNumCentreNoeud.nom; // lecture du nom
|
|
*(entreePrinc.entree) >> mailEtNumCentreNoeud.n; // lecture du numero de noeud
|
|
}
|
|
else
|
|
{ // sinon cela veut dire que l'on vient de lire un numéro de noeud du premier maillage
|
|
mailEtNumCentreNoeud.nom = "";
|
|
mailEtNumCentreNoeud.n = ChangeEntier(nom_mail);
|
|
};
|
|
}
|
|
else
|
|
{ cout << "\n erreur de lecture: on attendait : centre_fixe_ ou centre_noeud_a_t0_ "
|
|
<< " ou centre_noeud_a_t_ et on a lue: " << nom ;
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
// puis on lit la normale ou la direction de la droite qui correspond aux composantes de val ici
|
|
}
|
|
else {def_auto_par_rotation = false; };
|
|
|
|
// -- on regarde s'il s'agit d'une condition de stricte egalité entre noeud pour le type enu
|
|
if (strstr(entreePrinc.tablcar,"stricte_egalite_")!= NULL)
|
|
{ }
|
|
else {stricte_egalite = false;};
|
|
|
|
// dans un cas normal on lit une valeur de la condition linéaire
|
|
if ((!def_auto_par_rotation)&&(!stricte_egalite))
|
|
{// lecture de la valeur de la condition limite
|
|
*(entreePrinc.entree) >> nom;
|
|
if (nom != "val_condi_lineaire=")
|
|
{ cout << "\n erreur de lecture: val_condi_lineaire pour un condition limite lineaire "
|
|
<< " on attendait val_condi_lineaire= , et on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{ (*entreePrinc.entree) >> beta;};
|
|
};
|
|
|
|
if (!stricte_egalite) // dans le cas stricte_egalité, la lecture est finie
|
|
{ // lecture des coefficients de la condition linéaire
|
|
*(entreePrinc.entree) >> nom;
|
|
if (nom != "coefficients=")
|
|
{ // pas d'énuméré
|
|
cout << "\n erreur de lecture des coefficients de la condition limite lineaire "
|
|
<< " on attendait coefficients= , et on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{ // lecture de la liste demandée
|
|
int compteur=0; // pour éviter une boucle infinie
|
|
list <double> list_inter;
|
|
while (compteur < 1000)
|
|
{ (*entreePrinc.entree) >> nom; compteur++;
|
|
if (nom != "fin_list_coefficients_")
|
|
{ list_inter.push_back(ChangeReel(nom));}
|
|
else break;
|
|
};
|
|
// recopie dans le tableau
|
|
int taille = list_inter.size();
|
|
val.Change_taille(taille);
|
|
list <double>::iterator it,itfin=list_inter.end();
|
|
int i=1;
|
|
for (it = list_inter.begin();it!=itfin;it++,i++)
|
|
val(i)=*it;
|
|
// on vérifie que le nombre de coefficients est correcte
|
|
Tableau<Enum_ddl> tab_enu = TableauTypeDdlmobileAvecAxi(enu);
|
|
nbddlfamille = tab_enu.Taille();
|
|
if (taille != nbddlfamille * (1+refs_associe.Taille()))
|
|
{ cout << "\n erreur de lecture des coefficients de la condition lineaire, leur nombre " << taille
|
|
<< " est differente de (1 + le nombre de reference associe)*le nombre de ddl de la famille = "
|
|
<< nbddlfamille * (1+refs_associe.Taille()) << " ";
|
|
if(ParaGlob::AxiSymetrie()) cout << "(ici en axi) ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
if (def_auto_par_rotation)
|
|
{// on met à jour la direction ou la normale droite plan
|
|
switch (dima)
|
|
{ case 2: dr.Change_vect(val.Coordo()); break;
|
|
case 3: pl.Change_normal(val.Coordo()); break;
|
|
}
|
|
};
|
|
};
|
|
// on regarde s'il faut considérer des fonctions de charge
|
|
tab_co_charge.Libere(); // par défaut on initialise le tableau à 0
|
|
if (strstr(entreePrinc.tablcar,"AvecFonctionsDeCharges_")!=NULL)
|
|
{entreePrinc.NouvelleDonnee(); // on passe un enregistrement
|
|
// lecture du mot clé de début
|
|
(*entreePrinc.entree) >> nom;
|
|
if (nom != "deb_fonction_de_charge=")
|
|
{ cout << "\n erreur de lecture d'une liste de fonctions de charge "
|
|
<< " pour un condition limite lineaire "
|
|
<< " on attendait deb_fonction_de_charge= , et on a lue: " << nom << " ";
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else
|
|
{ // lecture de la liste demandée
|
|
int compteur=0; // pour éviter une boucle infinie
|
|
list <string> list_inter;
|
|
while (compteur < 1000)
|
|
{ (*entreePrinc.entree) >> nom; compteur++;
|
|
if (nom != "fin_list_fonctions_de_charges_")
|
|
{ list_inter.push_back(nom);}
|
|
else break;
|
|
};
|
|
// recopie dans le tableau
|
|
int taille = list_inter.size();
|
|
int i=1;
|
|
// dans le cas plan ou droite, par analogie au cas générale on considère une taille
|
|
// telle que c'est seulement à partir du second élément que l'on travaille
|
|
// on double le premier élément, pour permettre aux boucles de fonctionner, mais le premier
|
|
// élément ne sert pas dans le calcul de la condition !!
|
|
if (def_auto_par_rotation) {taille++;i=2;};
|
|
|
|
tab_co_charge.Change_taille(taille);
|
|
list <string>::iterator it,itfin=list_inter.end();
|
|
for (it = list_inter.begin();it!=itfin;it++,i++)
|
|
tab_co_charge(i)=*it;
|
|
if (def_auto_par_rotation) tab_co_charge(1) = tab_co_charge(2); // doublage du premier élément
|
|
};
|
|
// il doit y avoir autant de nom de fonction de charge que de coef + 1 pour la valeur
|
|
if (tab_co_charge.Taille() != (val.Taille() + 1))
|
|
{ cout << "\n erreur de lecture d'une liste de fonctions de charge "
|
|
<< " pour un condition limite lineaire "
|
|
<< " le nombre de fonctions de charge lue (ici: " << tab_co_charge.Taille();
|
|
if (def_auto_par_rotation)
|
|
{ cout << " ) doit etre egal au nombre de coefficient pour la valeur de condition lineaire de projection "
|
|
<< " ce qui devrait faire : " << (val.Taille()) << " ";
|
|
}
|
|
else
|
|
{ cout << " ) doit etre egal au nombre de coefficient + 1 pour la valeur de condition lineaire "
|
|
<< " ce qui devrait faire : " << (val.Taille() + 1) << " ";
|
|
};
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
}
|
|
else if (condition_relative)
|
|
{// cas où il n'y a pas de fonction de charge, mais que l'on a indiqué une condition relative
|
|
cout << "\n **** Warning !!! les conditions lineaires relatives ne fonctionnent que avec des courbes de charge "
|
|
<< " dans le cas de conditions simples (fixes) on se refere toujours a la situation a t=0 " << endl;
|
|
condition_relative = false;
|
|
};
|
|
}
|
|
else
|
|
{// quelques vérifs au cas où
|
|
if (echelle != 1.)
|
|
{ cout << "\n erreur de coherence: dans le cas d'une condition stricte_egalite_ "
|
|
<< " on ne peut pas utiliser une echelle (ici= " << echelle << " ) differente de 1. !! " ;
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
if ( (strstr(entreePrinc.tablcar,"coefficients=")!= NULL)
|
|
||(strstr(entreePrinc.tablcar,"CONDITION_RELATIVE=")!= NULL)
|
|
)
|
|
{ cout << "\n erreur de coherence: dans le cas d'une condition stricte_egalite_ "
|
|
<< " on ne peut pas utiliser les mots cles coefficients= , CONDITION_RELATIVE= !! " ;
|
|
entreePrinc.MessageBuffer("*** lecture d'une reference de condition lineaire ****" );
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
condition_relative = false;
|
|
tab_co_charge.Libere();
|
|
};
|
|
// initialisation des grandeurs de travail
|
|
Initialisation_condil();
|
|
};
|
|
|
|
// affichage des commandes particulières à la définition d'une condition linéaire
|
|
void I_O_Condilineaire::Info_commande_conditionLineaire(ofstream & sort,bool plusieurs_maillages)
|
|
{
|
|
//On va proposer un menu pour choisir entre différents types de conditions linéaires
|
|
int type_CLL=0; // =0 non défini, =1 -> projection sur un plan ou une droite
|
|
// =2 -> condition générale
|
|
{string rep=" ";
|
|
// tableau des choix possibles
|
|
Tableau <string> tab_choix(6);
|
|
tab_choix(1) = "\n (0 ou f) (fin) ";
|
|
tab_choix(2) = "\n (1) info detaillees dans le fichier .info";
|
|
tab_choix(3) = "\n (2 ou ?) informations succinctes a l ecran";
|
|
tab_choix(4) = "\n (3) CLL: proj sur plan en 3D (droite en 2D) ";
|
|
tab_choix(5) = "\n (4) CLL: generale ";
|
|
tab_choix(6) = "\n (5) CLL: stricte_egalite ";
|
|
|
|
while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
|
|
{
|
|
try
|
|
{ for (int i=1;i<=tab_choix.Taille();i++)
|
|
cout << tab_choix(i);
|
|
cout << "\n rep : ";
|
|
rep = lect_return_defaut(false,"f"); cout << " grandeur lue " << rep;
|
|
int num = 0; // par défaut
|
|
if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie
|
|
// on ne fait rien
|
|
{num = 0;}
|
|
else
|
|
{ num = ChangeEntier(rep);
|
|
if (Minuscules(rep) == "?")
|
|
num = 2;
|
|
bool choix_valide=false;
|
|
if ((num >= 0)&&(num<=5))
|
|
{ choix_valide=true; }
|
|
else { cout << "\n Erreur on attendait un entier entre 0 et 5 !!, "
|
|
<< "\n redonnez une bonne valeur"
|
|
<< "\n ou taper f ou 0 pour arreter le programme";
|
|
choix_valide=false;
|
|
};
|
|
switch (num)
|
|
{ case 0: // sortie
|
|
{ break;}
|
|
case 1: // sortie documentation détaillée sur le fichier .info
|
|
{
|
|
sort << "\n# .............................. condition lineaire: mode d'emploi ................................................."
|
|
<< "\n# | NB: de nombreuse grandeurs sont optionelles, par contre l'ordre d'apparition est impose!! |"
|
|
<< "\n# | constituee : d'une reference principal de noeud qui peut etre precedee (eventuellement) d'un nom de maillage, |"
|
|
<< "\n# | ex1: N_avant , ex2: nom_mail= solide1 N_avant |"
|
|
<< "\n# | suivi sur la meme ligne du type de la famille de ddl sur laquelle s'applique la condition lineaire |"
|
|
<< "\n# | ex1: enu= UX , ex2: enu= X1 , ex3 enu= TEMP |"
|
|
<< "\n# | puis sur la ligne qui suit une suite eventuelle de references secondaires, (s'il n'y en a pas, on met rien ) |"
|
|
<< "\n# | sinon on utilise deux mots cle pour encadrer la liste |"
|
|
<< "\n# | ex1: refs_associe= N_arriere N_milieu fin_list_refs_associe_ |"
|
|
<< "\n# | Dans le cas ou la reference principal comporte un nom de maillage, il est possible d'indiquer ou non avant |"
|
|
<< "\n# | chaque reference secondaire, un nom de maillage. Si ce nom de maillage est absent, c'est celui de la reference|"
|
|
<< "\n# | principale qui est retenue a la place. Ainsi, on peut definir une CLL entre des noeuds de maillages |"
|
|
<< "\n# | differents. Par contre, si la reference principale ne contient pas de nom de maillage, les references |"
|
|
<< "\n# | secondaires ne doivent pas en comporer, sinon cela genere une erreur ! |"
|
|
<< "\n# | les references secondaires doivent avoir exactement le meme nombre de noeud que la reference principal |"
|
|
<< "\n# | la condition linaire s'appliquera sur chaque noeud de la reference principal, associe aux noeuds de |"
|
|
<< "\n# | du meme rang des references secondaires: par exemple pour les ex1, la condition lineaire s'applique |"
|
|
<< "\n# | successivement pour tous noeud i de N_avant, sur le groupe (noeud i de N_avant + noeud i de N_arriere |"
|
|
<< "\n# | + noeud i de N_milieu). Comme il s'agit de la famille de ddl de type UX, donc deplacement, en 3D |"
|
|
<< "\n# | on doit donc avoir 3*3 coef + 1 pour la valeur de la condition = 10 coef pour la condition qui s'ecrit |"
|
|
<< "\n# | donc : a1 UX(1) + a2 UY(1) + a3 UZ(1) + a4 UX(2) +..... + a9 UZ(3) = a10 |"
|
|
<< "\n# | UX(1) correspond au deplacement du noeud de la reference de N_avant, UX(2) pour N_arriere, UX(3) pour |"
|
|
<< "\n# | N_milieu, a10 est la condition imposee |"
|
|
<< "\n# | Ensuite toujours sur la meme ligne on peut eventuellement indiquer un temps mini et un temps maxi |"
|
|
<< "\n# | ex1 TEMPS_MINI= 0.1 TEMPS_MAXI= 5. |"
|
|
<< "\n# | Puis toujours sur la meme ligne, on peut eventuellement indiquer que la condition est relative ou non |"
|
|
<< "\n# | par defaut la condition est absolue, cela signifie que l'on se refere a la situation a t=0 |"
|
|
<< "\n# | dans le cas d'une condition relative, on se refere a la situation precedente: cependant, ce mecanisme |"
|
|
<< "\n# | ne fonctionne que si dans le cas de l'utilisation de fonction de charge (cf. suite des infos) |"
|
|
<< "\n# | ex1 CONDITION_RELATIVE= 1 # =0 absolue, =1 relative |"
|
|
<< "\n# | NB: tous la ligne: ref secondaire, temps mini maxi, condition realtive, est optionnelle, cela signifie |"
|
|
<< "\n# | quelle peut ne pas exister du tout, ou comporter quelques elements seulement. |"
|
|
<< "\n# | |"
|
|
<< "\n# | Ensuite sur la ligne suivante et on indique tout d'abord la valeur de la condition lineaire, (correspond à a10|"
|
|
<< "\n# | dans l'exemple 1 ) puis la la liste des coefficients de la conditions lineaire encadre par 2 mots cle |"
|
|
<< "\n# | ex1 val_condi_lineaire= 10 coefficients= 1 2 3 4 5 6 7 8 9 10 fin_list_coefficients_ |"
|
|
<< "\n# | ensuite on indique eventuellement s'il y a des fonctions de charges pour les coefficients avec la presence |"
|
|
<< "\n# | ou non du mot cle AvecFonctionsDeCharges_ |"
|
|
<< "\n# | ex1 val_condi_lineaire= 10 coefficients= 1 2 3 4 5 6 7 8 9 10 fin_list_coefficients_ AvecFonctionsDeCharges_ |"
|
|
<< "\n# | s'il y a des fonctions de charge, il doit y en avoir exactement le meme nombre que de coefficient+1 (pour |"
|
|
<< "\n# | la valeur de la condition limite ) on a donc une liste de nom de fonction de charge encadree par 2 mots cle |"
|
|
<< "\n# | la premiere fonction de charge s'applique sur la condition, la deuxieme sur le coefficient 1, la ieme sur le |"
|
|
<< "\n# | coefficient i-1. La liste des noms des fct de charge s'indique sur la ligne qui suit |"
|
|
<< "\n# | ex1 deb_fonction_de_charge= chc ch1 ch2 ch3 ch4 ch5 ch6 ch7 ch8 ch9 fin_list_fonctions_de_charges_ |"
|
|
<< "\n#........................................................................................................................."
|
|
<< "\n# exemple complet"
|
|
<< "\n nom_mail= solide1 N_avant enu= UX "
|
|
<< "\n refs_associe= nom_mail= solide2 N_arriere N_milieu fin_list_refs_associe_ TEMPS_MINI= 0.1 TEMPS_MAXI= 5. "
|
|
<< "\n val_condi_lineaire= 10 coefficients= 1 2 3 4 5 6 7 8 9 fin_list_coefficients_ AvecFonctionsDeCharges_ "
|
|
<< "\n deb_fonction_de_charge= chc ch1 ch2 ch3 ch4 ch5 ch6 ch7 ch8 ch9 fin_list_fonctions_de_charges_ "
|
|
<< "\n#........................................................................................................................."
|
|
<< endl;
|
|
}
|
|
case 2: // informations succinctes a l'écran
|
|
{ cout << "\n cas particulier 1 : CLL: proj sur plan en 3D (droite en 2D) "
|
|
<< " --> permet de construire les parametres d'une CLL a partir de la "
|
|
<< " def d'un plan de projection en 3D (ou d'une droite de projection pour le 2D)"
|
|
<< "\n ** warning ** un noeud qui supporte une CLL de projection ne peut pas supporter une autre"
|
|
<< " condition : CL ou CLL !!! ";
|
|
cout << "\n cas particulier 2 : stricte_egalite_ : c-a-d stricte egalite entre ddl de type enu "
|
|
<< " --> aucune donnee supplementaire n'est necessaire apres le mot cle stricte_egalite_ "
|
|
<< "\n ** warning ** contrairement aux autres cas : un noeud qui supporte une CLL stricte "
|
|
<< "\n egalite peut egalement supporter une autre condition : CL ou CLL !!! ";
|
|
cout << "\n CLL: generale --> permet de construire une relation lineaire quelconque entre "
|
|
<< " les ddl d'un ou plusieurs noeuds. Contrairement aux CLL de projection, un noeud peut"
|
|
<< " supporter autant de CL et/ou de CLL qu'il a de ddl libres (mais pas plus sinon une "
|
|
<< " erreur est generee ) "
|
|
<< endl;
|
|
break;
|
|
}
|
|
case 3: // CLL: proj sur plan en 3D (droite en 2D)
|
|
{ type_CLL = 1; rep = "f"; break;}
|
|
case 4: // CLL: generale
|
|
{ type_CLL = 2; rep = "f";break;}
|
|
case 5: // CLL: stricte_egalite_
|
|
{ type_CLL = 3; rep = "f";break;}
|
|
default:
|
|
cout << "\n le cas "<<rep<<" n'est pas traite !!, bizarre, il faut se plaindre !! ";
|
|
};
|
|
};
|
|
}
|
|
catch (ErrSortieFinale)
|
|
// cas d'une direction voulue vers la sortie
|
|
// on relance l'interuption pour le niveau supérieur
|
|
{ ErrSortieFinale toto;
|
|
throw (toto);
|
|
}
|
|
catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
|
|
{ cout << "\n Erreur on attendait un des mots cles proposes !!, "
|
|
<< "\n redonnez une bonne valeur"
|
|
<< "\n ou taper f ou 0 pour sortir ";
|
|
};
|
|
}; //-- fin du while
|
|
sort << flush;
|
|
};
|
|
|
|
//maintenant on va renseigner les CLL en fonction du choix effectué
|
|
int dim = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dim--;
|
|
if ((type_CLL == 1) && ( dim != 1))
|
|
{//On va proposer un menu
|
|
string rep=" ";
|
|
string nom_courbe="_";
|
|
double temps_mini = - ConstMath::trespetit;
|
|
double temps_maxi = ConstMath::tresgrand;
|
|
Coordonnee M(dim); // coordonnées d'un point fixe du plan ou droite
|
|
string nom_mail_centre=" "; // éventuellement
|
|
int numNoeud_0=0; // ou numéro du noeud du plan a t= 0
|
|
int numNoeud_t=0; // ou numéro du noeud du plan a t
|
|
int type_point=0; // =1 pt fixe, =2 noeud initial, =3 noeud final
|
|
Coordonnee N(0); // coordonnées de la normale du plan ou droite
|
|
Tableau <string> tab_Co_charges; // tableau des noms de fonctions de charges
|
|
// tableau des choix possibles
|
|
Tableau <string> tab_choix(9);
|
|
tab_choix(1) = "\n (0 ou f) (fin) ";
|
|
tab_choix(2) = "\n (1) reference des noeuds ";
|
|
tab_choix(3) = "\n (2) def d'1 pt fixe du plan via coordonnees ";
|
|
tab_choix(4) = "\n (3) ou def d'1 pt fixe du plan = noeud a t=0 ";
|
|
tab_choix(5) = "\n (4) ou def d'1 pt mobile du plan = noeud a tdt ";
|
|
tab_choix(6) = "\n (5) normale au plan ";
|
|
tab_choix(7) = "\n (6) temps mini ";
|
|
tab_choix(8) = "\n (7) temps maxi ";
|
|
tab_choix(9) = "\n (8) def fonctions de charge ";
|
|
string nom_ref="";
|
|
ostringstream flux;
|
|
|
|
while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
|
|
{
|
|
try
|
|
{ for (int i=1;i<=tab_choix.Taille();i++)
|
|
cout << tab_choix(i);
|
|
cout << "\n >>> il faut obligatoirement definir (1)+{(2)ou(3)ou(4)}+(5) <<< ";
|
|
cout << "\n rep : ";
|
|
rep = lect_return_defaut(false,"f"); cout << " grandeur lue " << rep;
|
|
if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie
|
|
// c'est à la sortie que ce fait l'écriture donc ici
|
|
{sort << "\n";
|
|
if ((nom_ref == " ")||(type_point==0)||(N.Dimension()==0))
|
|
{cout <<"\n ** CLL incomplete, pas d'ecriture ";
|
|
break;
|
|
};
|
|
if (plusieurs_maillages)
|
|
{ cout << "\n nom du maillage ? ";
|
|
string nom_mail;
|
|
nom_mail= lect_chaine(); cout << " nom lu = "<< nom_mail;
|
|
sort << "nom_mail= "<< nom_mail << " ";
|
|
};
|
|
sort << nom_ref <<" enu= X1 ";
|
|
// temps mini et maxi éventuel
|
|
if ((temps_mini != - ConstMath::trespetit)||(temps_maxi != ConstMath::tresgrand))
|
|
{sort << "\n";
|
|
if (temps_mini != (- ConstMath::trespetit))
|
|
sort << " TEMPS_MINI= "<< temps_mini<<" ";
|
|
if (temps_maxi != ConstMath::tresgrand)
|
|
sort << " TEMPS_MAXI= "<< temps_maxi<<" ";
|
|
};
|
|
// la condition
|
|
sort << "\n def_auto_coef_planOuDroite_ ";
|
|
switch (type_point)
|
|
{ case 1: sort << " centre_fixe_ "; M.Affiche_1(sort);break;
|
|
case 2: sort << " centre_noeud_a_t0_ " << nom_mail_centre << numNoeud_0; break;
|
|
case 3: sort << " centre_noeud_a_t_ " << nom_mail_centre << numNoeud_t; break;
|
|
};
|
|
// les coefficients
|
|
sort << " coefficients= "; N.Affiche_1(sort);
|
|
sort << " fin_list_coefficients_ ";
|
|
// fonctions de charge éventuelles
|
|
if (tab_Co_charges.Taille() != 0)
|
|
{sort << " AvecFonctionsDeCharges_ \n deb_fonction_de_charge= ";
|
|
for (int i=1;i<=tab_Co_charges.Taille();i++)
|
|
sort << tab_Co_charges(i) << " ";
|
|
sort << " fin_list_fonctions_de_charges_ "<< endl;
|
|
};
|
|
break;
|
|
};
|
|
int num = ChangeEntier(rep);
|
|
bool choix_valide=false;
|
|
if ((num >= 0)&&(num<=8))
|
|
{ choix_valide=true; }
|
|
else { cout << "\n Erreur on attendait un entier entre 0 et 8 !!, "
|
|
<< "\n redonnez une bonne valeur"
|
|
<< "\n ou taper f ou 0 pour arreter le programme";
|
|
choix_valide=false;
|
|
}
|
|
switch (num)
|
|
{ case 0: // sortie
|
|
{ break;}
|
|
case 1: // reference des noeuds
|
|
{ cout << "\n nom de la ref de noeud pour l'application de la condition ? ";
|
|
nom_ref= lect_chaine();cout << " nom lu = "<< nom_ref;
|
|
if (nom_ref.at(0) != 'N')
|
|
{cout << "\n *** erreur, la premiere lettre de la ref de noeuds "
|
|
<< " doit etre N et non "<< nom_ref.at(0)<< " !! *** "
|
|
<< " \n ** cette ref n'est pas valide !! ** \n ";
|
|
nom_ref = " "; // on re init
|
|
break;
|
|
};
|
|
break;
|
|
}
|
|
case 2: // def d'1 pt fixe du plan via coordonnees
|
|
{ if (type_point != 0)
|
|
cout << "\n ** warning vous definissez un nouveau point du plan "
|
|
<< " qui va donc remplasser votre precedent point ";
|
|
|
|
switch (dim)
|
|
{case 3:
|
|
{cout << "\n def d'un pt du plan via la def de ses coordonnees: ";
|
|
// comme on a plusieurs entrée on va utiliser un cin
|
|
cout << "\n donner 3 reels "; for (int i=1;i<4;i++) cin >> M(i);
|
|
type_point=1; cout << " valeurs lue =";M.Affiche();
|
|
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// vide cin
|
|
break;
|
|
}
|
|
case 2:
|
|
// comme on a plusieurs entrée on va utiliser un cin
|
|
{cout << "\n donner 2 reels "; for (int i=1;i<3;i++) cin >> M(i);
|
|
type_point=1; cout << " valeurs lue =";M.Affiche();
|
|
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// vide cin
|
|
break;
|
|
}
|
|
default: choix_valide=false; break;
|
|
};
|
|
break;
|
|
}
|
|
case 3: // ou def d'1 pt fixe du plan = noeud a t=0
|
|
{ if (type_point != 0)
|
|
cout << "\n (** warning vous definissez un nouveau point du plan "
|
|
<< " qui va donc remplasser votre precedent point) ";
|
|
|
|
cout << "\n def numero du noeud dont la position initiale sera un point du plan"
|
|
<< "\n numero ? : ";
|
|
numNoeud_0 = (int) lect_double();cout << " valeur lue ="<< numNoeud_0;
|
|
if (plusieurs_maillages)
|
|
{ cout << "\n nom du maillage associe ? ";
|
|
string nom_mail_centre;
|
|
nom_mail_centre= lect_chaine(); cout << " nom lu = "<< nom_mail_centre;
|
|
};
|
|
type_point=2;
|
|
break;
|
|
}
|
|
case 4: //ou def d'1 pt mobile du plan = noeud a tdt
|
|
{ if (type_point != 0)
|
|
cout << "\n (** warning vous definissez un nouveau point du plan "
|
|
<< " qui va donc remplasser votre precedent point) ";
|
|
|
|
cout << "\n def numero du noeud dont la position finale sera un point du plan "
|
|
<< "\n numero ? : ";
|
|
numNoeud_t=(int)lect_double();cout << " valeur lue ="<< numNoeud_t;
|
|
if (plusieurs_maillages)
|
|
{ cout << "\n nom du maillage associe ? ";
|
|
string nom_mail_centre;
|
|
nom_mail_centre= lect_chaine(); cout << " nom lu = "<< nom_mail_centre;
|
|
};
|
|
type_point=3;
|
|
break;
|
|
}
|
|
case 5: // def normale au plan
|
|
{ cout << "\n normale au plan (ou droite) ? ";
|
|
N.Change_dim(dim);
|
|
switch (dim)
|
|
{case 3:
|
|
{cout << "\n donner 3 reels "; for (int i=1;i<4;i++) cin >> N(i);
|
|
cout << " valeurs lue =";N.Affiche();
|
|
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );//on vide cin
|
|
break;
|
|
}
|
|
case 2:
|
|
{cout << "\n donner 2 reels "; for (int i=1;i<3;i++) cin >> N(i);
|
|
cout << " valeurs lue =";N.Affiche();
|
|
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );//on vide cin
|
|
break;
|
|
}
|
|
default:
|
|
cout << "\n en 1D les CLL de projection ne sont pas possible ";
|
|
choix_valide=false; break;
|
|
};
|
|
break;
|
|
}
|
|
case 6: // temps mini
|
|
{ cout << "\n valeur du temps mini (un reel) ? ";
|
|
temps_mini=lect_double();cout << " valeur lue ="<< temps_mini;
|
|
break;
|
|
}
|
|
case 7: // temps maxi
|
|
{ cout << "\n valeur du temps maxi (un reel) ? ";
|
|
temps_maxi=lect_double();cout << " valeur lue ="<< temps_maxi;
|
|
break;
|
|
}
|
|
case 8: // def des courbes de charges
|
|
{ tab_Co_charges.Change_taille(dim);
|
|
cout << "\n il faut definir "<<dim<<"courbes de charge";
|
|
for (int i=1;i<=dim;i++)
|
|
{cout << "\n nom de la "<<i<<" ieme courbe de charge ? ";
|
|
tab_Co_charges(i)= lect_chaine();cout << " nom lu = "<< tab_Co_charges(i);
|
|
};
|
|
break;
|
|
}
|
|
default:
|
|
cout << "\n le cas "<<rep<<" n'est pas traite !!, bizarre, il faut se plaindre !! ";
|
|
};
|
|
}
|
|
catch (ErrSortieFinale)
|
|
// cas d'une direction voulue vers la sortie
|
|
// on relance l'interuption pour le niveau supérieur
|
|
{ ErrSortieFinale toto;
|
|
throw (toto);
|
|
}
|
|
catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
|
|
{ cout << "\n Erreur on attendait un des mots cles proposes !!, "
|
|
<< "\n redonnez une bonne valeur"
|
|
<< "\n ou taper f ou 0 pour sortir ";
|
|
};
|
|
}; //-- fin du while
|
|
|
|
}
|
|
else if (type_CLL == 2)
|
|
{//On va proposer un menu
|
|
string rep=" ";
|
|
string nom_courbe="_";
|
|
double temps_mini = - ConstMath::trespetit;
|
|
double temps_maxi = ConstMath::tresgrand;
|
|
Coordonnee M(dim); // coordonnées d'un point fixe du plan ou droite
|
|
string nom_mail_centre=" "; // éventuellement
|
|
Coordonnee N(0); // coordonnées de la normale du plan ou droite
|
|
|
|
Enum_ddl enu=NU_DDL; // enuméré des ddl de la cll
|
|
double val_condi=0.; // valeur par défaut de la condition linéaire
|
|
list <string> list_ref_secondaires; // liste des références secondaires
|
|
list <string> list_mail_secondaires; // la liste des maillages associées à list_ref_secondaires
|
|
Tableau <double> tab_coef_CLL; // tableau des coef de la CLL
|
|
Tableau <string> tab_Co_charges; // tableau des noms de fonctions de charges
|
|
bool condition_relative = false; // par défaut
|
|
// tableau des choix possibles
|
|
Tableau <string> tab_choix(11);
|
|
tab_choix(1) = "\n (0 ou f) (fin) ";
|
|
tab_choix(2) = "\n (1) reference principale de noeuds ";
|
|
tab_choix(3) = "\n (2) references secondaires de noeuds ";
|
|
tab_choix(4) = "\n (3) type de degre de liberte ";
|
|
tab_choix(5) = "\n (4) valeur de la CLL ";
|
|
tab_choix(6) = "\n (5) coefficients de la CLL ";
|
|
tab_choix(7) = "\n (6) condition relative ";
|
|
tab_choix(8) = "\n (7) temps mini ";
|
|
tab_choix(9) = "\n (8) temps maxi ";
|
|
tab_choix(10) = "\n (9) def fonctions de charge ";
|
|
tab_choix(11) = "\n (10) test si la CLL est recevable ";
|
|
string nom_ref="";
|
|
ostringstream flux;
|
|
|
|
while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
|
|
{
|
|
try
|
|
{ for (int i=1;i<=tab_choix.Taille();i++)
|
|
cout << tab_choix(i);
|
|
cout << "\n >>> il faut obligatoirement definir a minima (1)+(3)+(4)+(5) <<< "
|
|
<< "\n et de preference dans l'ordre indique ";
|
|
cout << "\n rep : ";
|
|
rep = lect_return_defaut(false,"f"); cout << " grandeur lue " << rep;
|
|
if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie
|
|
// c'est à la sortie que ce fait l'écriture donc ici
|
|
{sort << "\n";
|
|
int nb_val = (dim*(list_ref_secondaires.size()+1));
|
|
if ((nom_ref == " ")||(tab_coef_CLL.Taille()!=nb_val)
|
|
||((tab_Co_charges.Taille()!=0)&&(tab_Co_charges.Taille()!=nb_val))
|
|
)
|
|
{cout <<"\n ** CLL incomplete, pas d'ecriture ";
|
|
break;
|
|
};
|
|
if (plusieurs_maillages)
|
|
{ cout << "\n nom du maillage pour la ref principale ? ";
|
|
string nom_mail;
|
|
nom_mail= lect_chaine(); cout << " nom lu = "<< nom_mail;
|
|
sort << "nom_mail= "<< nom_mail << " ";
|
|
};
|
|
sort << nom_ref <<" enu= " << Nom_ddl(enu);
|
|
// références secondaires éventuelles et / ou
|
|
// temps mini et maxi éventuel
|
|
if ( ((temps_mini != - ConstMath::trespetit)||(temps_maxi != ConstMath::tresgrand))
|
|
|| (list_ref_secondaires.size() != 0))
|
|
{sort << "\n";
|
|
// les ref secondaires
|
|
if (list_ref_secondaires.size() != 0)
|
|
{list <string>::iterator ideb = list_ref_secondaires.begin();
|
|
list <string>::iterator idfin = list_ref_secondaires.end();
|
|
list <string>::iterator ill = list_mail_secondaires.begin();
|
|
sort << " refs_associe= ";
|
|
if (plusieurs_maillages)
|
|
{for (;ideb != idfin;ideb++, ill++)
|
|
sort << "nom_mail= "<< (*ill) << " " << (*ideb) << " ";
|
|
}
|
|
else
|
|
{for (;ideb != idfin;ideb++, ill++)
|
|
sort << (*ideb) << " ";
|
|
};
|
|
sort << " fin_list_refs_associe_ ";
|
|
};
|
|
// encadrement en temps
|
|
if (temps_mini != (- ConstMath::trespetit))
|
|
sort << " TEMPS_MINI= "<< temps_mini<<" ";
|
|
if (temps_maxi != ConstMath::tresgrand)
|
|
sort << " TEMPS_MAXI= "<< temps_maxi<<" ";
|
|
// le cas d'une condition relative ou pas
|
|
if (condition_relative)
|
|
sort << " CONDITION_RELATIVE= 1 ";
|
|
};
|
|
// la condition
|
|
sort << "\n val_condi_lineaire= " << val_condi << " coefficients= ";
|
|
// les coefficients
|
|
for (int i=1;i<=nb_val;i++)
|
|
sort << tab_coef_CLL(i) << " ";
|
|
sort << " fin_list_coefficients_ ";
|
|
// fonctions de charge éventuelles
|
|
if (tab_Co_charges.Taille() != 0)
|
|
{sort << " AvecFonctionsDeCharges_ \n deb_fonction_de_charge= ";
|
|
for (int i=1;i<=tab_Co_charges.Taille();i++)
|
|
sort << tab_Co_charges(i) << " ";
|
|
sort << " fin_list_fonctions_de_charges_ ";
|
|
};
|
|
sort << endl << std::flush;
|
|
break;
|
|
};
|
|
int num = ChangeEntier(rep);
|
|
bool choix_valide=false;
|
|
if ((num >= 0)&&(num<=10))
|
|
{ choix_valide=true; }
|
|
else { cout << "\n Erreur on attendait un entier entre 0 et 8 !!, "
|
|
<< "\n redonnez une bonne valeur"
|
|
<< "\n ou taper f ou 0 pour arreter le programme";
|
|
choix_valide=false;
|
|
}
|
|
switch (num)
|
|
{ case 0: // sortie
|
|
{ break;}
|
|
case 1: // reference principale de noeuds
|
|
{ cout << "\n nom de la ref de noeud pour l'application de la condition ? ";
|
|
nom_ref= lect_chaine();cout << " nom lu = "<< nom_ref;
|
|
if (nom_ref.at(0) != 'N')
|
|
{cout << "\n *** erreur, la premiere lettre de la ref de noeuds "
|
|
<< " doit etre N et non "<< nom_ref.at(0)<< " !! *** "
|
|
<< " \n ** cette ref n'est pas valide !! ** \n ";
|
|
nom_ref = " "; // on re init
|
|
break;
|
|
};
|
|
break;
|
|
}
|
|
case 2: // references secondaires de noeuds
|
|
{ bool fin = false;
|
|
string nom_ref_inter=" ";
|
|
while (!fin)
|
|
{ cout << "\n nom d'une ref de noeud secondaire ou f (ou 0 ou o) pour finir ? ";
|
|
nom_ref_inter= lect_chaine();cout << " nom lu = "<< nom_ref_inter;
|
|
if ((Minuscules(nom_ref_inter) == "f")||(Minuscules(nom_ref_inter)=="o") ||(Minuscules(nom_ref_inter)=="0"))
|
|
{break;}
|
|
else if (nom_ref_inter.at(0) != 'N')
|
|
{cout << "\n *** erreur, la premiere lettre de la ref de noeuds "
|
|
<< " doit etre N et non "<< nom_ref_inter.at(0)<< " !! *** "
|
|
<< " \n ** cette ref n'est pas valide !! ** \n ";
|
|
nom_ref_inter = " "; // on re init
|
|
}
|
|
else
|
|
{ if (plusieurs_maillages)
|
|
{ cout << "\n nom du maillage associe ? ";
|
|
string nom_mail_associe;
|
|
nom_mail_associe= lect_chaine(); cout << " nom lu = "<< nom_mail_associe;
|
|
list_mail_secondaires.push_back(nom_mail_associe);
|
|
};
|
|
list_ref_secondaires.push_back(nom_ref_inter);
|
|
};
|
|
};
|
|
break;
|
|
}
|
|
case 3: // type de degre de liberte
|
|
{ cout << "\n type d'un ddl de la condition lineaire: (ex: UX ou UY ou X1 ou V1 ...): ";
|
|
string enu_essai;
|
|
enu_essai= lect_chaine();cout << " valeur lue ="<<enu_essai;
|
|
if (ExisteEnum_ddl(enu_essai))
|
|
{ if (Id_nom_ddl(enu_essai) != NU_DDL)
|
|
{enu = PremierDdlFamille(Id_nom_ddl(enu_essai));}
|
|
else {cout << "*** type de ddl non valide !! " << endl;};
|
|
}
|
|
else {cout << "*** type de ddl non valide !! " << endl;};
|
|
break;
|
|
}
|
|
case 4: // valeur de la CLL
|
|
{ cout << "\n valeur de condition lineaire: (un reel): ";
|
|
val_condi=lect_double();cout << " valeur lue ="<< val_condi;
|
|
break;
|
|
}
|
|
case 5: // coefficients de la CLL
|
|
{ cout << "\n avertissement: le nombre de coefficient doit etre identique a la dimension "
|
|
<< " * (le nombre de ref secondaire + 1) , ici cf. vos precedentes reponses, il faut donc "
|
|
<< "\n "<<dim<<" * ("<<list_ref_secondaires.size()<<"+ 1) = "
|
|
<< (dim*(list_ref_secondaires.size()+1)) ;
|
|
int nb_val = (dim*(list_ref_secondaires.size()+1));
|
|
tab_coef_CLL.Change_taille(nb_val);
|
|
for (int i=1;i<= nb_val;i++)
|
|
{ cout << "\n coefficient ("<<i<<")= ? ";cin >> tab_coef_CLL(i);
|
|
cout << " ( valeur lue : "<<tab_coef_CLL(i) << ") "<< endl;
|
|
};
|
|
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// on vide cin
|
|
break;
|
|
}
|
|
case 6: // condition relative
|
|
{ string reponse;
|
|
cout << "\n condition relative (rep: o ou n ) ? ";
|
|
reponse = lect_o_n(false);
|
|
cout << " (valeurs lue = "<<reponse<<") "<<endl;
|
|
if (Minuscules(reponse) == "o") { condition_relative=true;}
|
|
else {condition_relative = false;};
|
|
break;
|
|
}
|
|
case 7: // temps mini
|
|
{ cout << "\n valeur du temps mini (un reel) ? ";
|
|
temps_mini=lect_double();cout << " valeur lue ="<< temps_mini;
|
|
break;
|
|
}
|
|
case 8: // temps maxi
|
|
{ cout << "\n valeur du temps maxi (un reel) ? ";
|
|
temps_maxi=lect_double();cout << " valeur lue ="<< temps_maxi;
|
|
break;
|
|
}
|
|
case 9: // def des courbes de charges
|
|
{ int nb_val = tab_coef_CLL.Taille();
|
|
tab_Co_charges.Change_taille(nb_val);
|
|
cout << "\n compte tenu de vos precedentes reponses il faut definir "<<nb_val<<" courbes de charge";
|
|
for (int i=1;i<=nb_val;i++)
|
|
{cout << "\n nom de la "<<i<<" ieme courbe de charge ? ";
|
|
tab_Co_charges(i)= lect_chaine();cout << " nom lu = "<< tab_Co_charges(i);
|
|
};
|
|
break;
|
|
}
|
|
case 10: // test si la CLL est recevable
|
|
{ int nb_val = (dim*(list_ref_secondaires.size()+1));
|
|
if (nom_ref == " ")
|
|
{cout <<"\n ** CLL incomplete, il manque le nom de la reference principale " << endl;}
|
|
else if (tab_coef_CLL.Taille()!=nb_val)
|
|
{cout <<"\n ** CLL incomplete, le nombre de coef n'est pas coherent avec le nb de "
|
|
<<"ref et la dimension " << endl;}
|
|
else if ((tab_Co_charges.Taille()!=0)&&(tab_Co_charges.Taille()!=nb_val))
|
|
{cout <<"\n ** CLL incomplete, le nombre de courbe de charge n'est pas coherent avec le nb de "
|
|
<<"ref et la dimension " << endl;}
|
|
else if (temps_mini > temps_maxi)
|
|
{cout <<"\n ** CLL complete mais inchoerente car le temps mini ("<<temps_mini<<") est "
|
|
<< "superieur au temps maxi ("<<temps_maxi<<") "<< endl;}
|
|
else {cout << "\n a priori la condition est coherente et recevable "<<endl;};
|
|
break;
|
|
}
|
|
default:
|
|
cout << "\n le cas "<<rep<<" n'est pas traite !!, bizarre, il faut se plaindre !! ";
|
|
};
|
|
}
|
|
catch (ErrSortieFinale)
|
|
// cas d'une direction voulue vers la sortie
|
|
// on relance l'interuption pour le niveau supérieur
|
|
{ ErrSortieFinale toto;
|
|
throw (toto);
|
|
}
|
|
catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
|
|
{ cout << "\n Erreur on attendait un des mots cles proposes !!, "
|
|
<< "\n redonnez une bonne valeur"
|
|
<< "\n ou taper f ou 0 pour sortir ";
|
|
};
|
|
}; //-- fin du while
|
|
|
|
}
|
|
else if (type_CLL == 3)
|
|
{//On va proposer un menu
|
|
string rep=" ";
|
|
double temps_mini = - ConstMath::trespetit;
|
|
double temps_maxi = ConstMath::tresgrand;
|
|
Enum_ddl enu=NU_DDL; // enuméré des ddl de la cll
|
|
list <string> list_ref_secondaires; // liste des références secondaires
|
|
list <string> list_mail_secondaires; // la liste des maillages associées à list_ref_secondaires
|
|
bool condition_relative = false; // par défaut
|
|
// tableau des choix possibles
|
|
Tableau <string> tab_choix(7);
|
|
tab_choix(1) = "\n (0 ou f) (fin) ";
|
|
tab_choix(2) = "\n (1) reference principale de noeuds ";
|
|
tab_choix(3) = "\n (2) references secondaires de noeuds ";
|
|
tab_choix(4) = "\n (3) type de degre de liberte ";
|
|
tab_choix(5) = "\n (4) temps mini ";
|
|
tab_choix(6) = "\n (5) temps maxi ";
|
|
tab_choix(7) = "\n (6) test si la CLL est recevable ";
|
|
string nom_ref="";
|
|
ostringstream flux;
|
|
|
|
while ((Minuscules(rep) != "f")&&(Minuscules(rep) != "0"))
|
|
{
|
|
try
|
|
{ for (int i=1;i<=tab_choix.Taille();i++)
|
|
cout << tab_choix(i);
|
|
cout << "\n >>> il faut obligatoirement definir a minima (1)+(2) <<< "
|
|
<< "\n et de preference dans l'ordre indique ";
|
|
cout << "\n rep : ";
|
|
rep = lect_return_defaut(false,"f"); cout << " grandeur lue " << rep;
|
|
if ((Minuscules(rep) == "f") || (Minuscules(rep) == "0"))// sortie
|
|
// c'est à la sortie que ce fait l'écriture donc ici
|
|
{sort << "\n";
|
|
if ((nom_ref == " ")||(list_ref_secondaires.size()==0)
|
|
)
|
|
{cout <<"\n ** CLL incomplete, pas d'ecriture ";
|
|
break;
|
|
};
|
|
if (plusieurs_maillages)
|
|
{ cout << "\n nom du maillage pour la ref principale ? ";
|
|
string nom_mail;
|
|
nom_mail= lect_chaine(); cout << " nom lu = "<< nom_mail;
|
|
sort << "nom_mail= "<< nom_mail << " ";
|
|
};
|
|
sort << nom_ref <<" enu= " << Nom_ddl(enu);
|
|
// références secondaires éventuelles et / ou
|
|
// temps mini et maxi éventuel
|
|
if ( ((temps_mini != - ConstMath::trespetit)||(temps_maxi != ConstMath::tresgrand))
|
|
|| (list_ref_secondaires.size() != 0))
|
|
{sort << "\n";
|
|
// les ref secondaires
|
|
if (list_ref_secondaires.size() != 0)
|
|
{list <string>::iterator ideb = list_ref_secondaires.begin();
|
|
list <string>::iterator idfin = list_ref_secondaires.end();
|
|
list <string>::iterator ill = list_mail_secondaires.begin();
|
|
sort << " refs_associe= ";
|
|
if (plusieurs_maillages)
|
|
{for (;ideb != idfin;ideb++, ill++)
|
|
sort << "nom_mail= "<< (*ill) << " " << (*ideb) << " ";
|
|
}
|
|
else
|
|
{for (;ideb != idfin;ideb++, ill++)
|
|
sort << (*ideb) << " ";
|
|
};
|
|
sort << " fin_list_refs_associe_ ";
|
|
};
|
|
// encadrement en temps
|
|
if (temps_mini != (- ConstMath::trespetit))
|
|
sort << " TEMPS_MINI= "<< temps_mini<<" ";
|
|
if (temps_maxi != ConstMath::tresgrand)
|
|
sort << " TEMPS_MAXI= "<< temps_maxi<<" ";
|
|
// le cas d'une condition relative ou pas
|
|
if (condition_relative)
|
|
sort << " CONDITION_RELATIVE= 1 ";
|
|
};
|
|
// la condition
|
|
sort << "\n stricte_egalite_ " ;
|
|
sort << endl << std::flush;
|
|
break;
|
|
};
|
|
int num = ChangeEntier(rep);
|
|
bool choix_valide=false;
|
|
if ((num >= 0)&&(num<=6))
|
|
{ choix_valide=true; }
|
|
else { cout << "\n Erreur on attendait un entier entre 0 et 6 !!, "
|
|
<< "\n redonnez une bonne valeur"
|
|
<< "\n ou taper f ou 0 pour arreter le programme";
|
|
choix_valide=false;
|
|
}
|
|
switch (num)
|
|
{ case 0: // sortie
|
|
{ break;}
|
|
case 1: // reference principale de noeuds
|
|
{ cout << "\n nom de la ref de noeud pour l'application de la condition ? ";
|
|
nom_ref= lect_chaine();cout << " nom lu = "<< nom_ref;
|
|
if (nom_ref.at(0) != 'N')
|
|
{cout << "\n *** erreur, la premiere lettre de la ref de noeuds "
|
|
<< " doit etre N et non "<< nom_ref.at(0)<< " !! *** "
|
|
<< " \n ** cette ref n'est pas valide !! ** \n ";
|
|
nom_ref = " "; // on re init
|
|
break;
|
|
};
|
|
break;
|
|
}
|
|
case 2: // references secondaires de noeuds
|
|
{ bool fin = false;
|
|
string nom_ref_inter=" ";
|
|
while (!fin)
|
|
{ cout << "\n nom d'une ref de noeud secondaire ou f (ou 0 ou o) pour finir ? ";
|
|
nom_ref_inter= lect_chaine();cout << " nom lu = "<< nom_ref_inter;
|
|
if ((Minuscules(nom_ref_inter) == "f")||(Minuscules(nom_ref_inter)=="o") ||(Minuscules(nom_ref_inter)=="0"))
|
|
{break;}
|
|
else if (nom_ref_inter.at(0) != 'N')
|
|
{cout << "\n *** erreur, la premiere lettre de la ref de noeuds "
|
|
<< " doit etre N et non "<< nom_ref_inter.at(0)<< " !! *** "
|
|
<< " \n ** cette ref n'est pas valide !! ** \n ";
|
|
nom_ref_inter = " "; // on re init
|
|
}
|
|
else
|
|
{ if (plusieurs_maillages)
|
|
{ cout << "\n nom du maillage associe ? ";
|
|
string nom_mail_associe;
|
|
nom_mail_associe= lect_chaine(); cout << " nom lu = "<< nom_mail_associe;
|
|
list_mail_secondaires.push_back(nom_mail_associe);
|
|
};
|
|
list_ref_secondaires.push_back(nom_ref_inter);
|
|
};
|
|
};
|
|
break;
|
|
}
|
|
case 3: // type de degre de liberte
|
|
{ cout << "\n type d'un ddl de la condition lineaire: (ex: UX ou UY ou X1 ou V1 ...): ";
|
|
string enu_essai;
|
|
enu_essai= lect_chaine();cout << " valeur lue ="<<enu_essai;
|
|
if (ExisteEnum_ddl(enu_essai))
|
|
{ if (Id_nom_ddl(enu_essai) != NU_DDL)
|
|
{enu = PremierDdlFamille(Id_nom_ddl(enu_essai));}
|
|
else {cout << "*** type de ddl non valide !! " << endl;};
|
|
}
|
|
else {cout << "*** type de ddl non valide !! " << endl;};
|
|
break;
|
|
}
|
|
case 4: // temps mini
|
|
{ cout << "\n valeur du temps mini (un reel) ? ";
|
|
temps_mini=lect_double();cout << " valeur lue ="<< temps_mini;
|
|
break;
|
|
}
|
|
case 5: // temps maxi
|
|
{ cout << "\n valeur du temps maxi (un reel) ? ";
|
|
temps_maxi=lect_double();cout << " valeur lue ="<< temps_maxi;
|
|
break;
|
|
}
|
|
case 6: // test si la CLL est recevable
|
|
{ if (nom_ref == " ")
|
|
{cout <<"\n ** CLL incomplete, il manque le nom de la reference principale " << endl;}
|
|
else if (list_ref_secondaires.size()==0)
|
|
{cout <<"\n ** CLL incomplete, il n'y a pas de liste secondaire "
|
|
<<"ref et la dimension " << endl;}
|
|
else if (temps_mini > temps_maxi)
|
|
{cout <<"\n ** CLL complete mais inchoerente car le temps mini ("<<temps_mini<<") est "
|
|
<< "superieur au temps maxi ("<<temps_maxi<<") "<< endl;}
|
|
else {cout << "\n a priori la condition est coherente et recevable "<<endl;};
|
|
break;
|
|
}
|
|
default:
|
|
cout << "\n le cas "<<rep<<" n'est pas traite !!, bizarre, il faut se plaindre !! ";
|
|
};
|
|
}
|
|
catch (ErrSortieFinale)
|
|
// cas d'une direction voulue vers la sortie
|
|
// on relance l'interuption pour le niveau supérieur
|
|
{ ErrSortieFinale toto;
|
|
throw (toto);
|
|
}
|
|
catch (...)//(UtilLecture::ErrNouvelleDonnee erreur)
|
|
{ cout << "\n Erreur on attendait un des mots cles proposes !!, "
|
|
<< "\n redonnez une bonne valeur"
|
|
<< "\n ou taper f ou 0 pour sortir ";
|
|
};
|
|
}; //-- fin du while
|
|
|
|
}
|
|
else if ((type_CLL == 1) && (dim == 1))
|
|
{ // cas particulier du 1D
|
|
cout << "\n *** en 1D les CLL de projection ne sont pas possibles ";
|
|
};
|
|
};
|
|
|
|
|
|
// Construction de la condition : 1) mise en place d'une valeur imposée due à la condition linéaire
|
|
// def des coefficients en fonction éventuellement des fonctions de charges et du paramètre condition_relative
|
|
// NB: pour les conditions correspondant à une projection sur un plan ou une droite, il faut que la direction du plan
|
|
// ou de la droite ait déjà été affecté auparavant
|
|
// !! la condition sur le ddl n'est pas imposée à ce niveau, par contre elle est stockée dans Condilineaire
|
|
|
|
Condilineaire& I_O_Condilineaire::ConstructionCondition
|
|
(Tableau <Noeud *> & t_noe,Condilineaire& condi_actuelle)
|
|
{ // tout d'abord on évacue le cas de l'égalité stricte qui implique : rien n'a faire !
|
|
if (stricte_egalite)
|
|
return condi_actuelle; // condi_actuelle inchangée et ne doit servir à rien
|
|
|
|
// on renseigne la condition
|
|
Noeud * noe = t_noe(1); // le premier noeud est celui où on met la condition
|
|
condi_actuelle.ChangeTabNoeud(t_noe); // on renseigne la condition
|
|
|
|
// dimensionnement de la condition de retour, car val peut avoir été changé indépendamment
|
|
condi_actuelle.Change_taille(val.Taille());
|
|
Vecteur val_inter(val); // le vecteur qui contient les coeffs, est utiliser car dans le cas
|
|
// d'une def auto droite plan, les coeffs sont récupéré donc modifié
|
|
|
|
if (def_auto_par_rotation)
|
|
{ // cas d'une définition par rapport à une droite ou un plan
|
|
// on récupère les valeurs qui ont été calculées au moment des projections
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
// la valeur de la condition a déjà été calculée au moment de la projection
|
|
switch (dima)
|
|
{case 2: // on tourne autour de z
|
|
{ val_inter(1) = -dr.VecDroite()(2);
|
|
val_inter(2) = dr.VecDroite()(1);
|
|
break;
|
|
}
|
|
case 3:
|
|
{ val_inter = (pl.Vecplan()).Vect(); // pour simplifier
|
|
break;
|
|
}
|
|
};
|
|
};
|
|
|
|
// --- on met la condition -----
|
|
if ((tab_co_charge.Taille() == 0) || def_auto_par_rotation)
|
|
// cas sans fonction de charge, on applique la valeur complète
|
|
// dans le cas d'une projection plan ou droite, l'échelle est systématiquement = 1. (vérif à la lecture)
|
|
// et on ne tient pas compte de la première fonction de charge
|
|
{ condi_actuelle.BetaChange() = echelle * beta ;}
|
|
else
|
|
// cas avec fonction de charge, que ce soit en relatif ou pas, on applique la valeur à t
|
|
// (le coté relatif est a appliqué au niveau des ddl des noeuds, qui sont des valeurs issues
|
|
// du calcul d'équilibre, et non au niveau des valeurs fixés qui elles peuvent être déterminées
|
|
// à l'avance, donc pour ces dernières aucun intérêts de faire du relatif, par contre pour les ddl
|
|
// des noeuds, là le coté relatif est important car il permet d'ajouter à un ddl dont la valeur
|
|
// est issue du précédent calcul, donc pas connue à l'avance)
|
|
{ condi_actuelle.BetaChange() = echelle * beta * fctch(1) ;};
|
|
|
|
// --- maintenant on s'occupe des pointeurs et des coefficients
|
|
double valfinalSurddlAbloquer = 0; // on calcul en même temps la valeur à imposer
|
|
Tableau <Enum_ddl > t_enu(val.Taille()); // tableau des identificateur de ddl de la CLL
|
|
|
|
// $-$ NB: on traite différemment selon qu'il s'agisse de conditions linéaires entre position ou déplacement,
|
|
// $-$ ou sur des autres ddl, because, le cas déplacement-position est un peu particulier mais cependant
|
|
// $-$ globalement c'est très ressemblant
|
|
|
|
if (Meme_famille(enu,X1) || Meme_famille(enu,UX))
|
|
{ // le premier indice correspondra a la direction bloquee, il faut s'assurer qu'il ne
|
|
// soit pas nul et qu'il ne correspond pas a une direction deja bloquee par les conditions
|
|
// limites de depart
|
|
// on boucle sur la dim pour trouver le coef le plus grand correspondant a une direction
|
|
// non bloquee
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
int iti=0;int indi = 0; double maxi = ConstMath::petit;
|
|
int posi = Id_nom_ddl("X1") -1; // position du ddl X1
|
|
// on cherche le numero de ddl libre qui est associé à la valeur maxi différente de 0
|
|
if ((!def_auto_par_rotation)&&(tab_co_charge.Taille() != 0))
|
|
// dans le cas normal, avec fonction de charge, on tiens compte de ces fonctions
|
|
{for (iti=1; iti<= dima; iti++)
|
|
{ if (!noe->Ddl_fixe(Enum_ddl(posi+iti))) // cas d'un ddl libre
|
|
{double coef_reel = Dabs(val_inter(iti) * fctch(iti+1));
|
|
if (coef_reel > maxi) // cas d'une valeur de coefficient non nul
|
|
{ maxi = coef_reel;
|
|
indi = iti;
|
|
};
|
|
}
|
|
};
|
|
}
|
|
else
|
|
// autres cas: cas des projections ou cas sans fonction de charge
|
|
{for (iti=1; iti<= dima; iti++)
|
|
{ if (!noe->Ddl_fixe(Enum_ddl(posi+iti))) // cas d'un ddl libre
|
|
if (Dabs(val_inter(iti)) > maxi) // cas d'une valeur de coefficient non nul
|
|
{ maxi = Dabs(val_inter(iti));
|
|
indi = iti;
|
|
};
|
|
};
|
|
};
|
|
if (indi ==0)
|
|
{ // cas ou soit les dima ddl sont bloque, soit le vecteur normal = 0
|
|
cout << "\n erreur dans une condition limite lineaire , on ne peut pas imposer de condition lineaire"
|
|
<< " car soit les ddl de deplacement du noeud principal de la condition sont deja tous bloque, "
|
|
<< " soit le vecteur condition (les coeffs) est nul \n";
|
|
noe->Affiche();
|
|
cout << "\n les coeff : " ; val_inter.Affiche();
|
|
cout << "Condilineaire& I_O_Condilineaire::ConstructionCondition(.." << endl;
|
|
Sortie (1);
|
|
};
|
|
// on indique que la nouvelle direction "indi" est bloque, ceci permet
|
|
// pour une autre condition, de ne pas reprendre cette direction
|
|
// --> ce marquage est effacer apres resolution, par la fonction efface blocage
|
|
Enum_ddl leEnuAChanger = Enum_ddl(posi+indi); // le enu du ddl_k de la condition
|
|
noe->Change_fixe(leEnuAChanger,true);
|
|
condi_actuelle.ChangeIddl() = indi; // on enregistre la position
|
|
// on avance dans la constitution de valfinalSurddlAbloquer
|
|
double unsurcoef1 = 1./val_inter(condi_actuelle.Iddl()); // correspond à 1/alph_k de la condition
|
|
if ((!def_auto_par_rotation)&&(tab_co_charge.Taille() != 0))
|
|
// dans le cas normal, avec fonction de charge, on tiens compte de ces fonctions
|
|
unsurcoef1 = 1./fctch(indi+1);
|
|
// constitution de la condition lineaire
|
|
int itab = 0.; // définit à l'extérieur car va continuer à s'incrémenter sur la deuxième boucle qui suit
|
|
for (itab=1;itab<= dima;itab++)
|
|
{ // condi_actuelle.val_inter(1) correspond à coef(indi), puis les autres suivent
|
|
double coefindi =0.;
|
|
if (!def_auto_par_rotation)
|
|
{ if (tab_co_charge.Taille() == 0)
|
|
{ coefindi = val(indi) ; }
|
|
else { coefindi = val(indi) * fctch(indi+1) ;};
|
|
}
|
|
else // dans le cas plan droite les coef sont déjà intégrés
|
|
{coefindi = val_inter(indi);};
|
|
t_enu(itab)= Enum_ddl(posi+indi); // sauvegarde de l'enum associé
|
|
condi_actuelle.Valchange()(itab) = echelle * coefindi; // pour le coefficient
|
|
//--------------
|
|
// suite constitution de valfinalSurddlAbloquer :
|
|
if (itab == 1)
|
|
// correspond à beta/alpha_k
|
|
{ valfinalSurddlAbloquer = condi_actuelle.Beta() * unsurcoef1; }
|
|
else
|
|
// correspond à -alph_i/alph_k * U_i
|
|
// il faut distinguer les cas suivant que c'est une condition linéaire entre Xi ou entre Ui
|
|
// et que l'on est en relatif ou pas
|
|
{ if (condition_relative)
|
|
// dans le cas d'une projection, par construction (vérif à la lecture), la condition n'est pas relative !!
|
|
{ // que ce soit en Xi ou en Ui, comme on est en relatif il faut considérer l'accroissement
|
|
valfinalSurddlAbloquer -= echelle * coefindi * unsurcoef1
|
|
// **** a priori une erreur : 23 sep 2014 * (noe->Valeur_tdt(Enum_ddl(posi+itab)) - noe->Valeur_t(Enum_ddl(posi+itab)) ) ;
|
|
* (noe->Valeur_tdt(Enum_ddl(posi+indi)) - noe->Valeur_t(Enum_ddl(posi+indi)) ) ;
|
|
}
|
|
else
|
|
// donc ici il s'agit d'une condition absolue
|
|
{ if (Meme_famille(enu,X1))
|
|
// cas d'une CLL entre Xi on y accède directement
|
|
// **** a priori une erreur : 23 sep 2014 { valfinalSurddlAbloquer -= echelle * coefindi * unsurcoef1 * noe->Valeur_tdt(Enum_ddl(posi+itab)) ;}
|
|
{ valfinalSurddlAbloquer -= echelle * coefindi * unsurcoef1 * noe->Valeur_tdt(Enum_ddl(posi+indi)) ;
|
|
////--debug
|
|
//cout << "\n debug I_O_Condilineaire::ConstructionCondition noe_val= " << noe->Valeur_tdt(Enum_ddl(posi+indi))
|
|
// << " valfinalSurddlAbloquer= " << valfinalSurddlAbloquer << " coefindi= " << coefindi << " unsurcoef1= " << unsurcoef1
|
|
// << "Enum_ddl(posi+indi)= " << Enum_ddl(posi+indi) << endl ;
|
|
////--fin debug
|
|
}
|
|
else
|
|
// cas d'une CLL entre Ui, il faut donc prendre en compte le delta Xi entre 0 et tdt
|
|
{ valfinalSurddlAbloquer -= echelle * coefindi * unsurcoef1
|
|
// **** a priori une erreur : 23 sep 2014 * (noe->Valeur_tdt(Enum_ddl(posi+itab)) - noe->Valeur_0(Enum_ddl(posi+itab)) ) ;
|
|
* (noe->Valeur_tdt(Enum_ddl(posi+indi)) - noe->Valeur_0(Enum_ddl(posi+indi)) ) ;
|
|
};
|
|
};
|
|
};
|
|
//-------------------
|
|
indi ++;
|
|
if (indi > dima) indi = 1; // on fait une rotation circulaire
|
|
};
|
|
// cas des noeuds des références secondaires
|
|
int nbnsecondaire = refs_associe.Taille();
|
|
for (int nn=2; nn<=nbnsecondaire+1; nn++) // le premier noeud secondaire est pour nn=2
|
|
{ Noeud & noese = *(t_noe(nn));
|
|
// récup du pointeur d'assemblage -1
|
|
#ifdef MISE_AU_POINT
|
|
if (def_auto_par_rotation)
|
|
{ cout << "\nErreur : on ne doit pas avoir de ref secondaire avec la def auto "
|
|
<< '\n'
|
|
<< "Condilineaire& I_O_Condilineaire::ConstructionCondition(.. 3\n";
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
for (int ia=1;ia<= dima;ia++,itab++)
|
|
{ double coefitab =0.;
|
|
if (tab_co_charge.Taille() == 0)
|
|
{ coefitab = val_inter(itab) ; }
|
|
else { coefitab = val_inter(itab) * fctch(itab+1) ;};
|
|
t_enu(itab)= Enum_ddl(posi+ia); // sauvegarde de l'enum associé
|
|
condi_actuelle.Valchange()(itab) = echelle * coefitab; // pour le coefficient
|
|
// suite constitution de valfinalSurddlAbloquer : correspond à -alph_i/alph_k * U_i
|
|
// il faut distinguer les cas suivant que c'est une condition linéaire entre Xi ou entre Ui
|
|
// et que l'on est en relatif ou pas
|
|
if (condition_relative)
|
|
// dans le cas d'une projection, par construction (vérif à la lecture), la condition n'est pas relative !!
|
|
{ // que ce soit en Xi ou en Ui, comme on est en relatif il faut considérer l'accroissement
|
|
valfinalSurddlAbloquer -= echelle * coefitab * unsurcoef1
|
|
* (noese.Valeur_tdt(Enum_ddl(posi+ia)) - noese.Valeur_t(Enum_ddl(posi+ia)) ) ;
|
|
}
|
|
else
|
|
// donc ici il s'agit d'une condition absolue
|
|
{ if (Meme_famille(enu,X1))
|
|
// cas d'une CLL entre Xi on y accède directement
|
|
{ valfinalSurddlAbloquer -= echelle * coefitab * unsurcoef1 * noese.Valeur_tdt(Enum_ddl(posi+ia)) ;}
|
|
else
|
|
// cas d'une CLL entre Ui, il faut donc prendre en compte le delta Xi entre 0 et tdt
|
|
{ valfinalSurddlAbloquer -= echelle * coefitab * unsurcoef1
|
|
* (noese.Valeur_tdt(Enum_ddl(posi+ia)) - noese.Valeur_0(Enum_ddl(posi+ia)) ) ;
|
|
|
|
};
|
|
};
|
|
};
|
|
};
|
|
// on met à jour le tableau d'enum de la condition
|
|
condi_actuelle.Change_tab_enum(t_enu);
|
|
|
|
// on finit le calcul de la valeur du ddl imposé
|
|
if (condition_relative)
|
|
{ // que ce soit en Xi ou en Ui, comme on est en relatif
|
|
// comme le ddl au niveau du noeud est Xi, il faut le rajouter
|
|
valfinalSurddlAbloquer += noe->Valeur_t(leEnuAChanger);
|
|
}
|
|
else
|
|
// donc ici il s'agit d'une condition absolue
|
|
{ if (Meme_famille(enu,X1))
|
|
// cas d'une CLL entre Xi on a rien à faire, valfinalSurddlAbloquer est directement = à
|
|
// la valeur a imposer
|
|
{ }
|
|
else
|
|
// cas d'une CLL entre Ui, il faut donc prendre en compte le delta Xi entre 0 et tdt
|
|
// comme le ddl au niveau du noeud est Xi, il faut le rajouter
|
|
{ valfinalSurddlAbloquer += noe->Valeur_0(leEnuAChanger);};
|
|
};
|
|
|
|
// et maintenant on sauvegarde la valeur a bloquer sur le noeud dans la condition linéaire
|
|
// cette condition correspondra au ddl_i' dans le nouveau repèrere qui recevra la condition bloqué
|
|
// en fait ddl_i sera la seule modification de ddl due à la mise en place de la CLL
|
|
// !!! par contre ce changement de valeur n'est pas à effectuer dans le cas des projections,
|
|
// car dans ce cas, d'une part valfinalSurddlAbloquer doit toujours être à 0 et d'autre part
|
|
// la valeur des coordonnées est fixées lors de la projection et non ici
|
|
if (!def_auto_par_rotation)
|
|
{ condi_actuelle.ChangeUk_impose(valfinalSurddlAbloquer);}
|
|
else
|
|
{ condi_actuelle.ChangeUk_impose(ConstMath::tresgrand);};
|
|
/*
|
|
on met en place la condition limite sur le ddl ddl_i du noeud principal
|
|
// qui correspond au ddl_i' dans le nouveau repèrere qui recevra la condition bloqué
|
|
// en fait ddl_i sera la seule modification de ddl due à la mise en place de la CLL
|
|
// !!! par contre ce changement de valeur n'est pas à effectuer dans le cas des projections,
|
|
// car dans ce cas, d'une part valfinalSurddlAbloquer doit toujours être à 0 et d'autre part
|
|
// la valeur des coordonnées est fixées lors de la projection et non ici
|
|
noe->Change_val_tdt(leEnuAChanger,valfinalSurddlAbloquer);
|
|
*/
|
|
|
|
|
|
} // -- fin du cas d'une condition linéaire sur un déplacement ou position
|
|
else
|
|
{ // -- cas d'une famille autre que déplacement ou position
|
|
// (en fait pas de diff mais je préfère pour l'instant séparer les deux )
|
|
// le premier indice correspondra a la direction bloquee, il faut s'assurer qu'il ne
|
|
// soit pas nul et qu'il ne correspond pas a une direction deja bloquee par les conditions
|
|
// limites de depart
|
|
// on boucle pour trouver le coef le plus grand correspondant a une direction non bloquee
|
|
int iti=0;int indi = 0; double maxi = ConstMath::petit;
|
|
int posi = enu -1; // position du premier ddl de la famille
|
|
// on cherche le nb de ddl libre qui est associé à la valeur maxi différente de 0
|
|
for (iti=1; iti<= nbddlfamille; iti++)
|
|
{ if (!noe->Ddl_noeud_tdt(Enum_ddl(posi+iti)).Fixe()) // cas d'un ddl libre
|
|
if (Dabs(val(iti)) > maxi) // cas d'une valeur de coefficient non nul
|
|
{ maxi = Dabs(val(iti));
|
|
indi = iti;
|
|
};
|
|
};
|
|
if (indi ==0)
|
|
{ // cas ou soit les dima ddl sont bloque, soit le vecteur normal = 0
|
|
cout << "\n erreur dans une condition limite lineaire , "
|
|
<< " soit les ddl de la famille " << Nom_ddl(enu) << " du noeud principal sont deja tous bloque, "
|
|
<< " soit le vecteur condition (les coeffs) est entierement nul \n";
|
|
noe->Affiche();
|
|
cout << "\n les coeff : " ; condi_actuelle.Valchange().Affiche();
|
|
cout << "Condilineaire& I_O_Condilineaire::ConstructionCondition(.." << endl;
|
|
Sortie (1);
|
|
};
|
|
// on indique que la nouvelle direction "indi" est bloque, ceci permet
|
|
// pour une autre condition, de ne pas reprendre cette direction
|
|
// --> ce marquage est effacer apres resolution, par la fonction efface blocage
|
|
Enum_ddl leEnuAChanger = Enum_ddl(posi+indi); // le enu du ddl_k de la condition
|
|
noe->Change_fixe(leEnuAChanger,true);
|
|
condi_actuelle.ChangeIddl() = indi; // on enregistre la position
|
|
// on avance dans la constitution de valfinalSurddlAbloquer
|
|
double unsurcoef1 = 1./val_inter(condi_actuelle.Iddl()); // correspond à 1/alph_k de la condition
|
|
// constitution de la condition lineaire
|
|
int itab = 0.; // définit à l'extérieur car va continuer à s'incrémenter sur deuxième boucle qui suit
|
|
for (itab=1;itab<= nbddlfamille;itab++)
|
|
{ // condi_actuelle.val(1) correspond à coeff(indi), puis les autres suivent
|
|
double coefindi =0.;
|
|
if (tab_co_charge.Taille() == 0)
|
|
{ coefindi = val(indi) ; }
|
|
else { coefindi = val(indi) * fctch(indi+1) ;};
|
|
t_enu(itab)= Enum_ddl(posi+indi); // sauvegarde de l'enum associé
|
|
condi_actuelle.Valchange()(itab) = echelle * coefindi; // pour le coefficient
|
|
//--------------
|
|
// suite constitution de valfinalSurddlAbloquer :
|
|
if (itab == 1)
|
|
// correspond à beta/alpha_k
|
|
{ valfinalSurddlAbloquer = condi_actuelle.Beta() * unsurcoef1;}
|
|
else
|
|
// correspond à -alph_i/alph_k * U_i
|
|
// il faut distinguer les cas suivant que c'est une condition linéaire entre Xi ou entre Ui
|
|
// et que l'on est en relatif ou pas
|
|
{ if (condition_relative)
|
|
// dans le cas d'une projection, par construction (vérif à la lecture), la condition n'est pas relative !!
|
|
{ // que ce soit en Xi ou en Ui, comme on est en relatif il faut considérer l'accroissement
|
|
valfinalSurddlAbloquer -= echelle * coefindi * unsurcoef1
|
|
// **** a priori une erreur : 23 sep 2014 * (noe->Valeur_tdt(Enum_ddl(posi+itab)) - noe->Valeur_t(Enum_ddl(posi+itab)) ) ;
|
|
* (noe->Valeur_tdt(Enum_ddl(posi+indi)) - noe->Valeur_t(Enum_ddl(posi+indi)) ) ;
|
|
}
|
|
else
|
|
// donc ici il s'agit d'une condition absolue on y accède directement
|
|
// **** a priori une erreur : 23 sep 2014 { valfinalSurddlAbloquer -= echelle * coefindi * unsurcoef1 * noe->Valeur_tdt(Enum_ddl(posi+itab)) ;
|
|
{ valfinalSurddlAbloquer -= echelle * coefindi * unsurcoef1 * noe->Valeur_tdt(Enum_ddl(posi+indi)) ;
|
|
};
|
|
}
|
|
//-------------------
|
|
indi ++;
|
|
if (indi > nbddlfamille) indi = 1; // on fait une rotation circulaire
|
|
};
|
|
// cas des noeuds des références secondaires
|
|
int nbnsecondaire = refs_associe.Taille();
|
|
for (int nn=2; nn<=nbnsecondaire+1; nn++) // le premier noeud secondaire est pour nn=2
|
|
{ Noeud & noese = *(t_noe(nn));
|
|
for (int ia=1;ia<= nbddlfamille;ia++,itab++)
|
|
{double coefitab =0.;
|
|
if (tab_co_charge.Taille() == 0)
|
|
{ coefitab = val(itab) ; }
|
|
else { coefitab = val(itab) * fctch(itab+1) ;};
|
|
condi_actuelle.Valchange()(itab) = echelle * coefitab; // pour le coefficient
|
|
t_enu(itab)= Enum_ddl(posi+ia); // sauvegarde de l'enum associé
|
|
// suite constitution de valfinalSurddlAbloquer : correspond à -alph_i/alph_k * U_i
|
|
// il faut distinguer les cas suivant que c'est une condition linéaire entre Xi ou entre Ui
|
|
// et que l'on est en relatif ou pas
|
|
if (condition_relative)
|
|
{ // comme on est en relatif il faut considérer l'accroissement
|
|
valfinalSurddlAbloquer -= echelle * coefitab * unsurcoef1
|
|
* (noese.Valeur_tdt(Enum_ddl(posi+ia)) - noese.Valeur_t(Enum_ddl(posi+ia)) ) ;
|
|
}
|
|
else
|
|
// donc ici il s'agit d'une condition absolue on y accède directement
|
|
{ valfinalSurddlAbloquer -= echelle * coefitab * unsurcoef1 * noese.Valeur_tdt(Enum_ddl(posi+ia)) ;
|
|
};
|
|
};
|
|
};
|
|
// on met à jour le tableau d'enum de la condition
|
|
condi_actuelle.Change_tab_enum(t_enu);
|
|
|
|
// on finit le calcul de la valeur du ddl imposé
|
|
if (condition_relative)
|
|
{ // comme on est en relatif il faut rajouter la valeur à t
|
|
valfinalSurddlAbloquer += noe->Valeur_t(leEnuAChanger);
|
|
};
|
|
// sinon il n'y a rien à faire, valfinalSurddlAbloquer est directement = à
|
|
// la valeur a imposer
|
|
|
|
// et maintenant on sauvegarde la valeur a bloquer sur le noeud dans la condition linéaire
|
|
// qui correspond au ddl_i' dans le nouveau repèrere qui recevra la condition bloqué
|
|
// en fait ddl_i sera la seul modification de ddl due à la mise en place de la CLL
|
|
condi_actuelle.ChangeUk_impose(valfinalSurddlAbloquer);
|
|
|
|
/*
|
|
// et maintenant on met en place la condition limite sur le ddl ddl_i du noeud principal
|
|
// qui correspond au ddl_i' dans le nouveau repèrere qui recevra la condition bloqué
|
|
// en fait ddl_i sera la seul modification de ddl due à la mise en place de la CLL
|
|
noe->Change_val_tdt(leEnuAChanger,valfinalSurddlAbloquer);
|
|
*/
|
|
|
|
}; // -- fin du cas d'une condition linéaire une famille quelconque autre que position et déplacement
|
|
|
|
// retour
|
|
// //--- debug
|
|
// cout << "\n la condition lineaire : I_O_Condli ";
|
|
// this->Affiche();
|
|
// cout << "\n la condition resultat ";
|
|
// condi_actuelle.Affiche();
|
|
// // fin debug ---
|
|
|
|
return condi_actuelle;
|
|
};
|
|
|
|
// initialisation des grandeurs de travail
|
|
void I_O_Condilineaire::Initialisation_condil()
|
|
{Tableau<Enum_ddl> tab_enu = TableauTypeDdlmobileAvecAxi(enu);
|
|
nbddlfamille = tab_enu.Taille();
|
|
if (!stricte_egalite) // dans le cas stricte_egalité il n'y a pas de coef
|
|
{// on vérifie l'adéquation des dimensions
|
|
int ndimvec = nbddlfamille * (1+ refs_associe.Taille()); // nombre total de ddl concerné
|
|
if (ndimvec != val.Taille())
|
|
{ cout << "\n erreur de dimension: le nombre de coefficient de la condition limite = " << val.Taille()
|
|
<< " est different du nombre de ddl de la famille concernee " << nbddlfamille << " fois le nombre de noeud "
|
|
<< " c'est-a-dire (1 + le nombre de ref secondaire) = " << (1+ refs_associe.Taille()) << " ce qui fait: "
|
|
<< ndimvec << endl;
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
|
|
// definition du noeud: centre rotation
|
|
void I_O_Condilineaire::ChangeCentreNoeudRotation( Noeud* noe)
|
|
{centre_noeud = noe;
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
|
|
switch (dima)
|
|
{ case 2: switch(type_centre)
|
|
{case 2 : dr.Change_ptref(noe->Coord0()); break;
|
|
case 3 : dr.Change_ptref(noe->Coord2()); break;
|
|
}
|
|
break;
|
|
case 3: switch(type_centre)
|
|
{case 2 : pl.Change_ptref(noe->Coord0()); break;
|
|
case 3 : pl.Change_ptref(noe->Coord2()); break;
|
|
}
|
|
break;
|
|
};
|
|
// dans le cas ou type_centre = 1, on ne fait rien, donc le centre actuellement enregistré est maintenu
|
|
};
|
|
|
|
// indique si le blocage qui existe déjà sur les noeuds à projeter, est cohérent
|
|
// avec la projection:
|
|
// typiquement si la direction de blocage est normale au plan de rotation
|
|
// ramène true si on peut concerver la condition de projection
|
|
// en entrée: indi qui donne la direction déjà bloquée
|
|
bool I_O_Condilineaire::Coherence_condi_PlanDroite(int indi)const
|
|
{ bool retour = false;
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
switch (dima)
|
|
{ case 2:
|
|
{ const Coordonnee& dro = dr.VecDroite();
|
|
if (Dabs(dro(indi)) < ConstMath::pasmalpetit)
|
|
retour = true;
|
|
break;
|
|
}
|
|
case 3:
|
|
{ const Coordonnee& N = pl.Vecplan();
|
|
if (Dabs(N(indi)) < ConstMath::pasmalpetit)
|
|
retour = true;
|
|
break;
|
|
}
|
|
default:
|
|
break; // pour les autres dimensions on ne fait rien
|
|
};
|
|
// retour
|
|
return retour;
|
|
};
|
|
|
|
// définition de la direction actuelle ou normale pour plan droite
|
|
void I_O_Condilineaire::ActualiseDirectionPlanDroite()
|
|
{// exécution en fonction de la présence de fonction de charge ou non
|
|
Coordonnee dir(val.Coordo()); // val doit avoir la dimension du pb
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
if (tab_co_charge.Taille() != 0)
|
|
{ for (int i=1;i<=dima;i++)
|
|
dir(i) *= fctch(i+1) ;
|
|
};
|
|
switch (dima)
|
|
{ case 2: dr.Change_vect(dir); break; // on met à jour la direction
|
|
case 3: pl.Change_normal(dir); break; // on met à jour la direction
|
|
};
|
|
};
|
|
|
|
// projection (normale) du point M sur le plan ou droite, ramène le point M à la place du
|
|
// projeté, et calcul de la condition linéaire correspondant à la projection
|
|
Coordonnee& I_O_Condilineaire::ProjectionSurPlanDroite_et_calValCondiLin(Coordonnee& M )
|
|
{int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
switch (dima)
|
|
{ case 2:{ M = dr.Projete(M);
|
|
beta = -dr.VecDroite()(2)*M(1)+dr.VecDroite()(1)*M(2);
|
|
break;
|
|
}
|
|
case 3:{ M = pl.Projete(M);
|
|
beta = pl.Vecplan() * M ;
|
|
break;
|
|
}
|
|
default: break; // pour les autres dimensions on ne fait rien
|
|
};
|
|
// retour
|
|
return M;
|
|
};
|
|
|
|
|
|
// surcharge de l'operateur de lecture typée
|
|
istream & operator >> (istream & entree, I_O_Condilineaire & cLL)
|
|
{ // vérification du type
|
|
string type;
|
|
entree >> type;
|
|
if (type != "I_O_Condilineaire___ref_princ=")
|
|
{cout << "\n erreur en lecture d'une condition lineaire "
|
|
<< "\n operator >> (istream & entree, I_O_Condilineaire & cLL) ";
|
|
Sortie (1);
|
|
return entree;
|
|
}
|
|
// lecture d'un nom de maillage éventuel
|
|
bool existe_nom_maillage; entree >> existe_nom_maillage;
|
|
string nom;
|
|
if (existe_nom_maillage)
|
|
{ entree >> nom;
|
|
if (cLL.nom_maillage == NULL)
|
|
{cLL.nom_maillage = new string(nom);}
|
|
else
|
|
{*(cLL.nom_maillage) = nom;};
|
|
};
|
|
// maintenant la référence principale
|
|
entree >> cLL.refe ;
|
|
// les références associés
|
|
int tai=0;
|
|
entree >> nom >> tai;
|
|
if (tai != 0)
|
|
{cLL.refs_associe.Change_taille(tai);
|
|
if (cLL.nom_maillage != NULL)
|
|
{cLL.nom_mail_associe.Change_taille(tai);
|
|
for (int i=1;i<=tai;i++)
|
|
{entree >> cLL.nom_mail_associe(i) >> cLL.refs_associe(i); };
|
|
}
|
|
else
|
|
{for (int i=1;i<=tai;i++)
|
|
{entree >> cLL.refs_associe(i); };
|
|
};
|
|
};
|
|
entree >> nom >> cLL.enu ;
|
|
entree >> nom >> cLL.def_auto_par_rotation;
|
|
entree >> nom >> cLL.stricte_egalite;
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
|
|
if (cLL.stricte_egalite)
|
|
{ }
|
|
else
|
|
{if (cLL.def_auto_par_rotation)
|
|
{entree >> nom >> cLL.type_centre;
|
|
if (cLL.type_centre == 1)
|
|
{ entree >> nom;
|
|
Coordonnee B;
|
|
entree >> nom >> B;
|
|
if (dima == 2)
|
|
{cLL.dr.Change_ptref(B) ;}
|
|
else
|
|
{cLL.pl.Change_ptref(B) ;};
|
|
}
|
|
else if ((cLL.type_centre == 2) || (cLL.type_centre == 3))
|
|
{ entree >> nom >> cLL.mailEtNumCentreNoeud ;}
|
|
Coordonnee V;
|
|
entree >> nom >> V >> nom >> cLL.val;
|
|
if (dima == 2)
|
|
{cLL.dr.Change_vect(V);}
|
|
else // cas dimension 3
|
|
{cLL.pl.Change_normal(V);};
|
|
}
|
|
else
|
|
{ entree >> nom >> cLL.beta >> nom >> cLL.val;};
|
|
entree >> nom >> cLL.condition_relative
|
|
>> nom >> cLL.echelle;
|
|
entree >> nom >> cLL.tab_co_charge;
|
|
};
|
|
|
|
// if (!cLL.def_auto_par_rotation)
|
|
// { entree >> nom >> cLL.beta >> nom >> cLL.val;}
|
|
// else
|
|
// {entree >> nom >> cLL.type_centre;
|
|
// if (cLL.type_centre == 1)
|
|
// { entree >> nom;
|
|
// Coordonnee B;
|
|
// entree >> nom >> B;
|
|
// if (ParaGlob::Dimension() == 2)
|
|
// {cLL.dr.Change_ptref(B) ;}
|
|
// else
|
|
// {cLL.pl.Change_ptref(B) ;};
|
|
// }
|
|
// else if ((cLL.type_centre == 2) || (cLL.type_centre == 3))
|
|
// { entree >> nom >> cLL.mailEtNumCentreNoeud ;}
|
|
// Coordonnee V;
|
|
// entree >> nom >> V >> nom >> cLL.val;
|
|
// if (ParaGlob::Dimension() == 2)
|
|
// {cLL.dr.Change_vect(V);}
|
|
// else // cas dimension 3
|
|
// {cLL.pl.Change_normal(V);};
|
|
// };
|
|
|
|
entree >> nom >> cLL.t_min >> nom >> cLL.t_max
|
|
>> nom >> cLL.precedent;
|
|
|
|
return entree;
|
|
};
|
|
|
|
// surcharge de l'operateur d'ecriture typée
|
|
ostream & operator << ( ostream & sort,const I_O_Condilineaire & cLL)
|
|
{ // tout d'abord un indicateur donnant le type
|
|
sort << " I_O_Condilineaire___ref_princ= " ;
|
|
// puis le maillage éventuelle
|
|
if (cLL.nom_maillage == NULL)
|
|
{sort << false << " ";}
|
|
else
|
|
{sort << true << " " << *(cLL.nom_maillage) << " ";};
|
|
// maintenant la référence principale
|
|
sort << cLL.refe << " ";
|
|
// les références associés
|
|
if (cLL.refs_associe.Taille() != 0)
|
|
{int tai = cLL.refs_associe.Taille();
|
|
sort << " ref_associe___taille= " << tai << " ";
|
|
for (int i=1;i<=tai;i++)
|
|
if (cLL.nom_maillage != NULL)
|
|
{sort << cLL.nom_mail_associe(i) << " " << cLL.refs_associe(i) << " ";}
|
|
else
|
|
{sort << cLL.refs_associe(i) << " ";}
|
|
};
|
|
sort << "\n type_ddl= " << Nom_ddl(cLL.enu) ;
|
|
sort << " def_auto_par_rotation= " << cLL.def_auto_par_rotation;
|
|
sort << " stricte_egalite= " << cLL.stricte_egalite;
|
|
int dima = ParaGlob::Dimension();
|
|
if(ParaGlob::AxiSymetrie())
|
|
// cas d'élément axisymétrique, dans ce cas on ne prend en compte que les
|
|
// dimension-1 coordonnées donc on décrémente
|
|
dima--;
|
|
|
|
if (cLL.stricte_egalite)
|
|
{ }
|
|
else
|
|
{if (cLL.def_auto_par_rotation)
|
|
{sort << " type_centre= " << cLL.type_centre;
|
|
if (cLL.type_centre == 1)
|
|
{ sort << " centre_fixe= " ;
|
|
if (dima == 2) {sort << cLL.dr.PointDroite() << " " ;}
|
|
else {sort << cLL.pl.PointPlan() << " " ;};
|
|
}
|
|
else if (cLL.type_centre == 2)
|
|
{ sort << " centre_noeud_t0= " << cLL.mailEtNumCentreNoeud << " ";}
|
|
else if (cLL.type_centre == 3)
|
|
{ sort << " centre_noeud_t= " << cLL.mailEtNumCentreNoeud << " ";};
|
|
if (dima == 2)
|
|
{sort << " dir_droite_now= " << cLL.dr.VecDroite() << " dir_droite0= " << cLL.val;}
|
|
else // cas dimension 3
|
|
{sort << " normal_plan_now= " << cLL.pl.Vecplan() << " normal_plan0= " << cLL.val;}
|
|
}
|
|
else
|
|
{ sort << " val_condi= " << cLL.beta << " coefficients= " << cLL.val;};
|
|
sort << " condition_relative= " << cLL.condition_relative << " "
|
|
<< " echelle= " << cLL.echelle;
|
|
sort << "\n courbe_charge= " << cLL.tab_co_charge;
|
|
};
|
|
|
|
|
|
// if (!cLL.def_auto_par_rotation)
|
|
// { sort << " val_condi= " << cLL.beta << " coefficients= " << cLL.val;}
|
|
// else
|
|
// {sort << " type_centre= " << cLL.type_centre;
|
|
// if (cLL.type_centre == 1)
|
|
// { sort << " centre_fixe= " ;
|
|
// if (ParaGlob::Dimension() == 2) {sort << cLL.dr.PointDroite() << " " ;}
|
|
// else {sort << cLL.pl.PointPlan() << " " ;};
|
|
// }
|
|
// else if (cLL.type_centre == 2)
|
|
// { sort << " centre_noeud_t0= " << cLL.mailEtNumCentreNoeud << " ";}
|
|
// else if (cLL.type_centre == 3)
|
|
// { sort << " centre_noeud_t= " << cLL.mailEtNumCentreNoeud << " ";};
|
|
// if (ParaGlob::Dimension() == 2)
|
|
// {sort << " dir_droite_now= " << cLL.dr.VecDroite() << " dir_droite0= " << cLL.val;}
|
|
// else // cas dimension 3
|
|
// {sort << " normal_plan_now= " << cLL.pl.Vecplan() << " normal_plan0= " << cLL.val;}
|
|
// };
|
|
|
|
sort << "\n tmin= " << cLL.t_min << " tmax= " << cLL.t_max
|
|
<< " prec " << cLL.precedent;
|
|
|
|
return sort;
|
|
};
|
|
|
|
|
|
|