// 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) . // // 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 . // // For more information, please consult: . #include "TypeQuelconqueParticulier.h" #include "Tenseur1.h" #include "Tenseur2.h" #include "Tenseur3.h" #include "MathUtil2.h" //----------------------------------------------------------------------------- //| grandeur Vecteur: TypeQuelconque::Grandeur::Grandeur_Vecteur | //----------------------------------------------------------------------------- // surcharge de l'operator de lecture istream & operator >> (istream & ent, Grandeur_Vecteur & a) { string toto; ent >> toto; // passage de l'entête #ifdef MISE_AU_POINT if (toto != "Grandeur_Vecteur=") {cout << "\n erreur en lecteur, on attendait le mot cle: Grandeur_Vecteur= " << "\n operator << (ostream & sort , const Grandeur_Vecteur & a)"; Sortie(1); }; #endif ent >> a.ve; return ent; }; // surcharge de l'operator d'ecriture ostream & operator << (ostream & sort , const Grandeur_Vecteur & a) {sort << " Grandeur_Vecteur= " << a.ve << " " ; return sort; }; // constructeur par défaut: Grandeur_Vecteur::Grandeur_Vecteur(): ve() {}; // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale Grandeur_Vecteur::Grandeur_Vecteur(istream & ent): ve() { string entete,nom; ent >> entete >> nom; // passage de l'entête #ifdef MISE_AU_POINT if (entete != "Grandeur_Vecteur=") {cout << "\n erreur en lecteur, on attendait le mot cle: Grandeur_Vecteur= " << "\n Grandeur_Vecteur::Grandeur_Vecteur(istream & ent)"; Sortie(1); }; #endif // lecture de la dimension int dim; ent >> dim; ve.Change_taille(dim); // fin de la lecture ent >> ve; }; // sauvegarde sur le stream des informations permettant ensuite en lecture de créer via // le constructeur adoc l'objet correcte et valide void Grandeur_Vecteur::EcriturePourLectureAvecCreation(ostream & sort) {sort << " Grandeur_Vecteur= " << ve.Taille() << " "<< ve << " ";}; // surcharge d'affectation TypeQuelconque::Grandeur & Grandeur_Vecteur::operator = ( const TypeQuelconque::Grandeur & a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur a l'affectation: type de l'objet: " << "\n Grandeur_Vecteur::operator = (.."; Sortie(1); } #endif Grandeur_Vecteur& aa= *((Grandeur_Vecteur*) &a); ve=aa.ve;return *this; }; // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs de même type // affectation uniquement des données numériques (pas les pointeurs, pas les string) void Grandeur_Vecteur::Affectation_numerique( const TypeQuelconque::Grandeur & a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur sur le : type de l'objet: " << "\n Grandeur_Vecteur::Affectation_numerique(.."; Sortie(1); } #endif Grandeur_Vecteur& aa= *((Grandeur_Vecteur*) &a); ve=aa.ve; }; // Surcharge de l'operateur += void Grandeur_Vecteur::operator+= (const Grandeur& a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur sur le : type de l'objet: " << "\n Grandeur_Vecteur::operator+= (.."; Sortie(1); } #endif Grandeur_Vecteur& aa= *((Grandeur_Vecteur*) &a); ve+=aa.ve; }; // Surcharge de l'operateur -= void Grandeur_Vecteur::operator-= (const Grandeur& a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur sur le : type de l'objet: " << "\n Grandeur_Vecteur::operator-= (.."; Sortie(1); } #endif Grandeur_Vecteur& aa= *((Grandeur_Vecteur*) &a); ve-=aa.ve; }; // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double Grandeur_Vecteur::GrandeurNumOrdre(int num) const {if((num>0)&&(num<=ve.Taille())) return ve(num); else return 0.;}; // modification void Grandeur_Vecteur::Change_GrandeurNumOrdre(int num, const double& val) {if((num>0)&&(num<=ve.Taille())) ve(num)=val; // sinon rien }; // change de repère de la grandeur void Grandeur_Vecteur::Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma ) {cout << "\n **** non implante !!! " << "\n Grandeur_Vecteur::Change_repere("; Sortie(1); }; //------------------------------------------------------------------------------------ // grandeur un tableau de Vecteur: TypeQuelconque::Grandeur::Tab_Grandeur_Vecteur | // tous les coordonnees doivent avoir la même dimension !! pour la routine GrandeurNumOrdre //------------------------------------------------------------------------------------ // surcharge de l'operator de lecture istream & operator >> (istream & ent, Tab_Grandeur_Vecteur & a) { int taille = a.tabVe.Taille(); string entete; ent >> entete; // passage de l'entête #ifdef MISE_AU_POINT if (entete != "Tableau_de_Vecteur_nb=") {cout << "\n erreur en lecteur, on attendait le mot cle: Tableau_de_Vecteur_nb= " << "\n istream & operator >> (istream & ent, Tab_Grandeur_Vecteur & a)"; Sortie(1); }; #endif int nb; ent >> nb; if (nb != taille) { cout << "\n erreur en lecteur, la taille actuelle du tableau: " << taille << " est differente de la taille lue: " << nb << "\n operator >> (istream & ent, Tab_Grandeur_Vecteur & a)"; Sortie(1); }; for (int i=1;i<=taille;i++) ent >> *(a.tabVe(i)); // on utilise la lecture de Grandeur_Vecteur return ent; }; // surcharge de l'operator d'ecriture ostream & operator << (ostream & sort , const Tab_Grandeur_Vecteur & a) { int taille = a.tabVe.Taille(); sort << " Tableau_de_Vecteur_nb= " << taille ; for (int i=1;i<=taille;i++) sort << *(a.tabVe(i)); // on utilise l'écriture de Grandeur_Vecteur return sort; }; // constructeur par défaut: ne doit pas être utilisé, car on doit toujours avoir la variable // ptTens défini, donc -> erreur Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur() : tabVe() { cout << "\n erreur! ce constructeur ne doit pas etre utilise !!" << "\n Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur()"; }; // constructeur légal // nb indique le nombre de tenseur Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur( Vecteur& tens,int nb) : tabVe(nb) { for (int i=1;i<=nb;i++) tabVe(i) = new Grandeur_Vecteur(tens); }; // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur(istream & ent) : tabVe() { string entete,nom; ent >> entete ; // passage de l'entête #ifdef MISE_AU_POINT if (entete != "Tableau_de_Vecteur_nb=") {cout << "\n erreur en lecteur, on attendait le mot cle: Tableau_de_Vecteur_nb= " << "\n Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur(istream & ent)"; Sortie(1); }; #endif // lecture de la taille int taille; ent >> taille ; if (taille <= 0) // dans le cas où la taille est nulle on définit simplement un tableau nul {tabVe.Change_taille(0);} else // sinon il nous faut définir les éléments du tableau au fur et à mesure de la lecture { tabVe.Change_taille(taille); for (int i=1;i<=taille;i++) tabVe(i) = new Grandeur_Vecteur(ent); // lecture au moment de la création de chaque Vecteur }; }; // constructeur de copie Tab_Grandeur_Vecteur::Tab_Grandeur_Vecteur(const Tab_Grandeur_Vecteur& a): tabVe(a.tabVe.Taille()) { int taille = tabVe.Taille(); for (int i=1;i<=taille;i++) tabVe(i) = new Grandeur_Vecteur(*(a.tabVe(i))); }; // destructeur Tab_Grandeur_Vecteur::~Tab_Grandeur_Vecteur() { int taille = tabVe.Taille(); for (int i=1;i<=taille;i++) delete tabVe(i); }; // sauvegarde sur le stream des informations permettant ensuite en lecture de créer via // le constructeur adoc l'objet correcte et valide void Tab_Grandeur_Vecteur::EcriturePourLectureAvecCreation(ostream & sort) { int taille = tabVe.Taille(); sort << " Tableau_de_Vecteur_nb= " << taille << " "; //<< " dim= "; for (int i=1;i<=taille;i++) tabVe(i)->EcriturePourLectureAvecCreation(sort); }; // surcharge d'affectation TypeQuelconque::Grandeur & Tab_Grandeur_Vecteur::operator = ( const TypeQuelconque::Grandeur & b) { #ifdef MISE_AU_POINT if ((b.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (b.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur a l'affectation: type de l'objet: " << "\n Tab_Grandeur_Vecteur::operator = (.."; Sortie(1); } #endif Tab_Grandeur_Vecteur& a= *((Tab_Grandeur_Vecteur*) &b); // maintenant l'affectation int taille = tabVe.Taille(); #ifdef MISE_AU_POINT if (taille != a.tabVe.Taille()) { cout << "\n erreur a l'affectation: la taille de this " << taille << " n'est pas egale a celle " << " du parametre " << a.tabVe.Taille() << "\n Tab_Grandeur_Vecteur::operator = (.."; Sortie(1); } #endif for (int i=1;i<=taille;i++) // ici on fait une grosse manip d'écriture qui revient au même qu'à la ligne suivante // mais il y a un pb sur linux que je ne comprend pas ((Grandeur_Vecteur*) tabVe(i))->operator = (*((TypeQuelconque::Grandeur*) a.tabVe(i))); return *this; }; // surcharge d'affectation TypeQuelconque::Grandeur & Tab_Grandeur_Vecteur::operator = ( const Tab_Grandeur_Vecteur & a) { // maintenant l'affectation int taille = tabVe.Taille(); #ifdef MISE_AU_POINT if (taille != a.tabVe.Taille()) { cout << "\n erreur a l'affectation: la taille de this " << taille << " n'est pas egale a celle " << " du parametre " << a.tabVe.Taille() << "\n Tab_Grandeur_Vecteur::operator = (.."; Sortie(1); } #endif for (int i=1;i<=taille;i++) *(tabVe(i))= *(a.tabVe(i)); return *this; }; // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs de même type // affectation uniquement des données numériques (pas les pointeurs, pas les string) void Tab_Grandeur_Vecteur::Affectation_numerique( const TypeQuelconque::Grandeur & a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur sur le : type de l'objet: " << "\n Tab_Grandeur_Vecteur::Affectation_numerique(.."; Sortie(1); } #endif Tab_Grandeur_Vecteur& aa= *((Tab_Grandeur_Vecteur*) &a); int taille = tabVe.Taille(); int tailleN = aa.tabVe.Taille(); if (taille != tailleN) { cout << "\n erreur sur les dimensions des tableaux taille de this puis de a " << taille << " " << tailleN << " " << "\n Tab_Grandeur_Vecteur::Affectation_numerique(.."; Sortie(1); }; for (int i=1;i<=taille;i++) (tabVe(i))->Affectation_numerique(*(aa.tabVe(i))); }; // Surcharge de l'operateur += void Tab_Grandeur_Vecteur::operator+= (const Grandeur& a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur sur le : type de l'objet: " << "\n Tab_Grandeur_Vecteur::operator+= (.."; Sortie(1); } #endif Tab_Grandeur_Vecteur& aa= *((Tab_Grandeur_Vecteur*) &a); int taille = tabVe.Taille(); int tailleN = aa.tabVe.Taille(); if (taille != tailleN) { cout << "\n erreur sur les dimensions des tableaux taille de this puis de a " << taille << " " << tailleN << " " << "\n Tab_Grandeur_Vecteur::operator+= (.."; Sortie(1); }; for (int i=1;i<=taille;i++) //(*tabVe(i)) += (*(aa.tabVe(i))); *(tabVe(i)) += *(aa.tabVe(i)); }; // Surcharge de l'operateur -= void Tab_Grandeur_Vecteur::operator-= (const Grandeur& a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur sur le : type de l'objet: " << "\n Tab_Grandeur_Vecteur::operator-= (.."; Sortie(1); } #endif Tab_Grandeur_Vecteur& aa= *((Tab_Grandeur_Vecteur*) &a); int taille = tabVe.Taille(); int tailleN = aa.tabVe.Taille(); if (taille != tailleN) { cout << "\n erreur sur les dimensions des tableaux taille de this puis de a " << taille << " " << tailleN << " " << "\n Tab_Grandeur_Vecteur::operator-= (.."; Sortie(1); }; for (int i=1;i<=taille;i++) //(*tabVe(i)) -= (*(aa.tabVe(i))); *(tabVe(i)) -= *(aa.tabVe(i)); }; // Surcharge de l'operateur *= void Tab_Grandeur_Vecteur::operator*= (double val) { int taille = tabVe.Taille(); for (int i=1;i<=taille;i++) //(*tabVe(i))*=val; *(tabVe(i)) *=val; }; // Surcharge de l'operateur /= : division par un scalaire void Tab_Grandeur_Vecteur::operator/= (double val) { int taille = tabVe.Taille(); for (int i=1;i<=taille;i++) //(*tabVe(i))/=val; *(tabVe(i)) /=val; }; // récupération de la valeur numérique d'une grandeur correspondant à un numéro d'ordre // si pas possible, ramène 0 double Tab_Grandeur_Vecteur::GrandeurNumOrdre(int n) const { int taille = tabVe.Taille(); if (taille == 0) return 0; // cas d'un tableau vide int nbparcoor=tabVe(1)->NbMaxiNumeroOrdre(); int indice_tableau = (n-1)/nbparcoor + 1; int r_div = (n-1)%nbparcoor+1; return tabVe(indice_tableau)->GrandeurNumOrdre(r_div); }; // modification void Tab_Grandeur_Vecteur::Change_GrandeurNumOrdre(int n, const double& val) { int taille = tabVe.Taille(); if (taille == 0) return ; // cas d'un tableau vide int nbparcoor=tabVe(1)->NbMaxiNumeroOrdre(); int indice_tableau = (n-1)/nbparcoor + 1; int r_div = (n-1)%nbparcoor+1; tabVe(indice_tableau)->Change_GrandeurNumOrdre(r_div,val); }; // récup du nb maxi de numéros d'ordres int Tab_Grandeur_Vecteur::NbMaxiNumeroOrdre() const { if (tabVe.Taille() == 0) return 0; // cas d'un tableau vide int nbparcoor=tabVe(1)->NbMaxiNumeroOrdre(); return (tabVe.Taille() * nbparcoor); }; void Tab_Grandeur_Vecteur::Grandeur_brut(ostream & sort,int nbcar) const { int taille = tabVe.Taille(); for (int k=1;k<=taille;k++) tabVe(k)->Grandeur_brut(sort,nbcar); }; // changement de taille -> n : // si n < taille_actuelle --> les taille_actuelle - n sont supprimé // si n > taille_actuelle --> le dernier élément existant est dupliqué n-taille_actuelle fois, void Tab_Grandeur_Vecteur::Change_taille(int n) { int taille = tabVe.Taille(); if (n < taille) { for (int i=n;i<=taille;i++) delete tabVe(i); tabVe.Change_taille(n); } else // sinon on augmente { tabVe.Change_taille(n); for (int i=taille;i<=n;i++) tabVe(i) = new Grandeur_Vecteur(*tabVe(taille)); }; }; // change de repère de la grandeur void Tab_Grandeur_Vecteur::Change_repere(const Mat_pleine& beta,const Mat_pleine& gamma) { int taille = tabVe.Taille(); for (int i=1;i<=taille;i++) tabVe(i)->Change_repere(beta,gamma); }; // initialise la grandeur à une valeur par défaut: = 0 pour les grandeurs numériques void Tab_Grandeur_Vecteur::InitParDefaut() {int taille = tabVe.Taille(); for (int i=1;i<=taille;i++) tabVe(i)->InitParDefaut(); }; //------------------------------------------------------------------------------------------------------ //| grandeur scalaire double nommé + indice: TypeQuelconque::Grandeur::Grandeur_Double_Nommer_indicer | //| contient un nom d'identificateur et un indice qui est sensé resté fixe pendant les opérations | //| la seule grandeur qui varie c'est le double: c'est donc équivalent à un scalaire double | //| l'indice et le nom_ref, servent pour la gestion | //------------------------------------------------------------------------------------------------------ // surcharge de l'operator de lecture istream & operator >> (istream & ent, Grandeur_Double_Nommer_indicer & a) { string toto; ent >> toto; // passage de l'entête #ifdef MISE_AU_POINT if (toto != "Grandeur_Double_Nommer_indicer=") {cout << "\n erreur en lecteur, on attendait le mot cle: Grandeur_Double_Nommer_indicer= " << "\n operator << (ostream & sort , const Grandeur_Double_Nommer_indicer & a)"; Sortie(1); }; #endif ent >> a.nom_ref >> a.val >> a.indice; return ent; }; // surcharge de l'operator d'ecriture ostream & operator << (ostream & sort , const Grandeur_Double_Nommer_indicer & a) {sort << " Grandeur_Double_Nommer_indicer= " << a.nom_ref << " " << a.val << " " << a.indice << " "; return sort; }; // constructeur par défaut: Grandeur_Double_Nommer_indicer::Grandeur_Double_Nommer_indicer(): nom_ref(""),val(),indice(1) {}; // constructeur qui effectue la construction en lisant les informations sur le stream d'entrée // nécessite d'utiliser la fonction EcriturePourLectureAvecCreation() pour la fonction // inverse c'est-à-dire l'écriture sur le stream, au lieu de la surcharge d'écriture normale Grandeur_Double_Nommer_indicer::Grandeur_Double_Nommer_indicer(istream & ent): nom_ref(""),val(),indice(1) { string entete,nom; ent >> entete >> nom; // passage de l'entête #ifdef MISE_AU_POINT if (entete != "Grandeur_Double_Nommer_indicer=") {cout << "\n erreur en lecteur, on attendait le mot cle: Grandeur_Double_Nommer_indicer= " << "\n Grandeur_Double_Nommer_indicer::Grandeur_Double_Nommer_indicer(istream & ent)"; Sortie(1); }; #endif // fin de la lecture ent >> nom_ref >> val >> indice; }; // sauvegarde sur le stream des informations permettant ensuite en lecture de créer via // le constructeur adoc l'objet correcte et valide void Grandeur_Double_Nommer_indicer::EcriturePourLectureAvecCreation(ostream & sort) {sort << " Grandeur_Double_Nommer_indicer= " << nom_ref << " " << val << " "<< indice << " ";}; // surcharge d'affectation TypeQuelconque::Grandeur & Grandeur_Double_Nommer_indicer::operator = ( const TypeQuelconque::Grandeur & a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur a l'affectation: type de l'objet: " << "\n Grandeur_Double_Nommer_indicer::operator = (.."; Sortie(1); } #endif Grandeur_Double_Nommer_indicer& aa= *((Grandeur_Double_Nommer_indicer*) &a); val=aa.val;nom_ref = aa.nom_ref; indice = aa.indice; return *this; }; // ** operations simples: si l'opération ne veut rien dire pour le type quelconque -> erreur // ** les opérations entre deux types quelconques ne doivent concerner que des grandeurs de même type // affectation uniquement des données numériques (pas les pointeurs, pas les string) void Grandeur_Double_Nommer_indicer::Affectation_numerique( const TypeQuelconque::Grandeur & a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur sur le : type de l'objet: " << "\n Grandeur_Double_Nommer_indicer::Affectation_numerique(.."; Sortie(1); } #endif Grandeur_Double_Nommer_indicer& aa= *((Grandeur_Double_Nommer_indicer*) &a); val = aa.val; }; // Surcharge de l'operateur += void Grandeur_Double_Nommer_indicer::operator+= (const Grandeur& a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur sur le : type de l'objet: " << "\n Grandeur_Double_Nommer_indicer::operator+= (.."; Sortie(1); } #endif Grandeur_Double_Nommer_indicer& aa= *((Grandeur_Double_Nommer_indicer*) &a); val +=aa.val; }; // Surcharge de l'operateur -= void Grandeur_Double_Nommer_indicer::operator-= (const Grandeur& a) { #ifdef MISE_AU_POINT if ((a.Type_grandeurAssocie() != this->Type_grandeurAssocie()) || (a.Type_structure_grandeurAssocie() != this->Type_structure_grandeurAssocie())) { cout << "\n erreur sur le : type de l'objet: " << "\n Grandeur_Double_Nommer_indicer::operator-= (.."; Sortie(1); } #endif Grandeur_Double_Nommer_indicer& aa= *((Grandeur_Double_Nommer_indicer*) &a); val -=aa.val; };