TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Tube_base.cpp
1/****************************************************************************
2* Copyright (c) 2015 - 2016, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15#include <Parser.h>
16#include <Tube_base.h>
17#include <Param.h>
18#include <IJK_Field.h>
19
20Implemente_base(Tube_base, "Tube_base", Objet_U);
21Implemente_instanciable(Faisceau_Tubes, "Faisceau_Tubes", VECT(OWN_PTR(Tube_base)));
22
23static void evaluer_f_et_df_dt_et_df2_dt2(const Noms& expressions, const double t, const double dt, Vecteur3& f, Vecteur3& df_dt, Vecteur3& df2_dt2)
24{
25 for (int dir = 0; dir < 3; dir++)
26 {
27 // Pour chaque direction, evaluer l'expression mathematique
28 Parser parser;
29 parser.setString(std::string(expressions[dir]));
30 parser.setNbVar(1); // il n'y a qu'une variable dans l'expression : le temps t; si on avait eu deux variables ca aurait ete : parser.setNbVar(2);
31 parser.addVar("t"); // la premiere variable, d'indice zero sera le temps
32 parser.parseString(); // Lance la conversion de la chaine en une succession d'operations mathematiques
33
34 // Calcul de la position au temps courant:
35 parser.setVar((int)0, t); // variable numero zero = "t"
36 f[dir] = parser.eval(); // permet d'evaluer l'expression donc la position
37
38 // Calcul de la vitesse au temps courant:
39 double delta_t = dt; // on fait une difference finie avec ce pas de temps, on peut aussi prendre dt/10 par ex...
40 parser.setVar((int)0, t + delta_t); // l'expression est prise au temps t + delta_t
41 double f2 = parser.eval(); // on evalue l'expression au temps t + delat_t
42 df_dt[dir] = (f2 - f[dir]) / delta_t;
43
44 // Calcul de l'acceleration au temps courant par difference finie centree:
45 parser.setVar((int)0, t + delta_t); // l'expression est prise au temps t + delta_t
46 double x_p1 = parser.eval(); // position au temps n+1
47 parser.setVar((int)0, t - delta_t); // l'expression est prise au temps t - delta_t
48 double x_m1 = parser.eval(); // position au temps n-1
49 df2_dt2[dir] = (x_p1 - 2 * f[dir] + x_m1) / ( delta_t * delta_t); // a = (xn+1 -2*xn + xn-1) / (dt*dt)
50 }
51}
52
54{
55 ref_domaine_ = x;
56}
57
59{
60 return os;
61}
62
64{
65 return is;
66}
67
68Implemente_instanciable(Tube_impose, "Tube_impose", Tube_base);
69
71{
72 // On ecrit ce qu'il faut pour relire l'objet lors d'une reprise:
73 os << " { ";
74 if (nom_ != "??")
75 os << " nom " << nom_;
76 if (omega_ != 0)
77 os << " omega " << omega_;
78 os << " pos_x " << expressions_position_[0] ;
79 os << " pos_y " << expressions_position_[1] ;
80 os << " pos_z " << expressions_position_[2] ;
81 os << " rayon " << rayon_ ;
82 os << " }";
83 // On ecrit position, vitesse et acceleration actuelle en commentaires
84 os << " # pos=[ " << pos_[0] << " " << pos_[1] << " " << pos_[2] ;
85 os << " ] v=[ " << v_[0] << " " << v_[1] << " " << v_[2] ;
86 os << " ] a=[ " << acceleration_[0] << " " << acceleration_[1] << " " << acceleration_[2] << " ] # " << finl;
87 return os;
88}
89
91{
92 omega_ = 0.;
93 expressions_position_.dimensionner(3);
94 Param param(que_suis_je());
95 param.ajouter("pos_x", &expressions_position_[0], Param::REQUIRED);
96 param.ajouter("pos_y", &expressions_position_[1], Param::REQUIRED);
97 param.ajouter("pos_z", &expressions_position_[2], Param::REQUIRED);
98 param.ajouter("rayon", &rayon_, Param::REQUIRED);
99 param.ajouter("nom", &nom_);
100 param.ajouter("omega", &omega_);
101 param.lire_avec_accolades(is);
102
103 // Initialisation a t=0
104 update_vitesse_position(0., 1e-6, Vecteur3(0,0,0));
105
106 return is;
107}
108
109void Tube_impose::update_vitesse_position(double current_time, double dt, const Vecteur3& force_appliquee)
110{
111 evaluer_f_et_df_dt_et_df2_dt2(expressions_position_, current_time, dt, pos_, v_, acceleration_);
112}
113
114
115Implemente_instanciable(Tube_libre, "Tube_libre", Tube_base);
116
118{
119 // On ecrit ce qu'il faut pour relire l'objet lors d'une reprise:
120 os << " { ";
121 if (nom_ != "??")
122 os << " nom " << nom_;
123 if (omega_ != 0)
124 os << " omega " << omega_;
125 os << " pos_x " << pos_[0] ;
126 os << " pos_y " << pos_[1] ;
127 os << " pos_z " << pos_[2] ;
128 os << " v_x " << v_[0] ; ;
129 os << " v_y " << v_[1] ;
130 os << " v_z " << v_[2] ;
131 os << " a_x " << acceleration_[0] ;
132 os << " a_y " << acceleration_[1] ;
133 os << " a_z " << acceleration_[2] ;
134 os << " pos_eq_x " << position_equilibre_[0] ;
135 os << " pos_eq_y " << position_equilibre_[1] ;
136 os << " pos_eq_z " << position_equilibre_[2]; ;
137 if (blocage_[DIRECTION_I]) os << " blocage_i";
138 if (blocage_[DIRECTION_J]) os << " blocage_j";
139 if (blocage_[DIRECTION_K]) os << " blocage_k";
140 os << " rho_s " << rho_cylindre_;
141 os << " c " << amortissement_;
142 os << " k " << raideur_;
143 os << " rayon " << rayon_;
144 os << " }";
145 return os;
146}
147
149{
150 omega_ = 0.;
151 pos_ = Vecteur3(1e38, 1e38, 1e38);
152 // Par defaut, vitesse initiale nulle
153 v_ = Vecteur3(0,0,0);
154 // Par defaut, acceleration initiale nulle
155 acceleration_ = Vecteur3(0,0,0);
156
157 Param param(que_suis_je());
158 // Position initiale
159 param.ajouter("pos_x", &pos_[0]);
160 param.ajouter("pos_y", &pos_[1]);
161 param.ajouter("pos_z", &pos_[2]);
162 // Vitesse initiale
163 param.ajouter("v_x", &v_[0]);
164 param.ajouter("v_y", &v_[1]);
165 param.ajouter("v_z", &v_[2]);
166 // Acceleration initiale
167 param.ajouter("a_x", &acceleration_[0]);
168 param.ajouter("a_y", &acceleration_[1]);
169 param.ajouter("a_z", &acceleration_[2]);
170
171 // Position d'equilibre
172 param.ajouter("pos_eq_x", &position_equilibre_[0], Param::REQUIRED);
173 param.ajouter("pos_eq_y", &position_equilibre_[1], Param::REQUIRED);
174 param.ajouter("pos_eq_z", &position_equilibre_[2], Param::REQUIRED);
175 // Degres de liberte du tube
176 param.ajouter_flag("blocage_i", &blocage_[DIRECTION_I]);
177 param.ajouter_flag("blocage_j", &blocage_[DIRECTION_J]);
178 param.ajouter_flag("blocage_k", &blocage_[DIRECTION_K]);
179 // Parametres mecaniques
180 param.ajouter("rho_s", &rho_cylindre_, Param::REQUIRED);
181 param.ajouter("c", &amortissement_, Param::REQUIRED);
182 param.ajouter("k", &raideur_, Param::REQUIRED);
183
184 param.ajouter("rayon", &rayon_, Param::REQUIRED);
185 param.ajouter("nom", &nom_);
186
187 param.lire_avec_accolades(is);
188
189 // Si on n'a pas donne de position initiale, prendre la position d'equilibre
190 for (int i = 0; i < 3; i++)
191 if (pos_[i] > 1e37)
193
194 return is;
195}
196
197void Tube_libre::update_vitesse_position(double current_time, double dt, const Vecteur3& force_appliquee)
198{
199 // constante du Newmark
200 const double beta = 0.25;
201 const double gamma = 0.5;
202 const double timestep = dt;
203 ArrOfDouble a(8);
204 a[0] = 1/( beta * timestep * timestep);
205 a[1] = gamma /( beta * timestep);
206 a[2] = 1 /( beta * timestep);
207 a[3] = 1/(2 *beta)-1;
208 a[4] = gamma/ beta -1;
209 a[5] = 0.5* timestep * (gamma/ beta -2);
210 a[6] = timestep * (1- gamma);
211 a[7] = gamma * timestep;
212 Cout << "Coefficients newmark: " << a;
213 // Calcul de la masse du tube:
214 const double surface = M_PI * rayon_ * rayon_; // surface analytique
215 // Calcul de la hauteur du tube
216 const Domaine_IJK& geom = ref_domaine_.valeur();
217 ArrOfDouble noeuds_y;
218 noeuds_y = geom.get_node_coordinates(1); // rentre les coordonnees des noeuds selon y dans le tableau noeuds_y
219 const int n_element_y = noeuds_y.size_array()-1; // nombre d'elements selon y = nombre de noeuds -1
220 const double delta_y = geom.get_constant_delta(1);
221 const double hauteur_cylindre = n_element_y * delta_y;
222 // Calcul du volume du tube
223 double volume_cylindre = surface * hauteur_cylindre; // Vol analytique : vol = pi*rayon*rayon*h
224 Cout << "Volume du tube: " << volume_cylindre << finl;;
225 // Faire le calcul du volume avec la surface discretisee
226 //Calcul de la masse du cylindre
227 double m_s = rho_cylindre_ * volume_cylindre;
228 double c= amortissement_;
229 double k= raideur_;
230 Vecteur3 pos_newmark;
231
232 Vecteur3 F_droite, K_droite;
233 // ATTENTION les matrices de M, C et K sont des matrices identites *m, c et k!!!
234 // Donc on ne resout pas une equation matricielle
235 double K_gauche = a[0] * m_s + a[1] * c + k; // cas particulier!! Dans le cas general K_gauche est une matrice
236
237 for (int dir = 0; dir < 3; dir++)
238 {
239 if (blocage_[dir])
240 {
241 v_[dir] = acceleration_[dir] = 0.;
242 acceleration_[dir] = 0.;
243 continue;
244 }
245 // pos_newmark = pos_tube - pos_eq; donc v_newmark=v_ et a_newmark=acceleration_
246 pos_newmark[dir] = pos_[dir] - position_equilibre_[dir];
247 // ce qu'on resout : K_gauche * position(n+1) = Force_appliquee - K_droite = D_droite
248 // K_gauche est ici la matrice identite * (a[0] * m_s + a[1] * c + k), mais on pourrait mettre une raideur, masse, amortissement different selon la direction
249 // K_droite est un vecteur car c'est : M * (a[0] * z_newmark[dir] + a[2] * v_newmark[dir] + a[3] * a_newmark[dir]) + C *(a[1] * z_newmark[dir] + a[4] * v_newmark[dir] + a[5] * a_newmark[dir])
250 //ici comme M=Id * m_s et C=Id*c alors ca donne ce cas particulier :
251 K_droite[dir] = m_s * (a[0] * pos_newmark[dir] + a[2] * v_[dir] + a[3] * acceleration_[dir]) + c * (a[1] * pos_newmark[dir] + a[4] * v_[dir] + a[5] * acceleration_[dir]);
252 F_droite[dir] = force_appliquee[dir] + K_droite[dir];
253 double tmp_pos = pos_newmark[dir]; // copie de pos_newmark au temps n
254 // Calcul de la position au temps n+1 //
255 pos_newmark[dir] = F_droite[dir] / K_gauche; // pos_newmark au temps n+1
256 pos_[dir] = pos_newmark[dir] + position_equilibre_[dir]; // pos du tube au temps n+1
257 // Calcul de l'acceleration au temps n+1 //
258 double tmp_acceleration = acceleration_[dir]; // copie de l'acceleration au temps n
259 acceleration_[dir] = a[0] * (pos_newmark[dir] - tmp_pos) - a[2] * v_[dir] - a[3] * acceleration_[dir]; // a(n+1) = a_0 * (pos_nwemark(n+1) - pos_newmark(n)) - a_2 v(n) - a_3 a(n)
260 // Calcul de la vitesse au temps n+1 //
261 v_[dir] += a[6] * tmp_acceleration + a[7] * acceleration_[dir]; // vz(n+1) = vz(n) + a_6 * az(n) + a_7 * az (n+1)
262
263 }
264
265}
266
267
268// Les formats d'entree et de sortie sont ceux de VECT(xxx)
269// c'est a dire
270// N ( nombre d'objets dans le vecteur)
271// objet[0]
272// objet[1]
273// ...
274Entree& Faisceau_Tubes::readOn(Entree& is)
275{
276 return VECT(OWN_PTR(Tube_base))::readOn(is);
277}
278
279Sortie& Faisceau_Tubes::printOn(Sortie& is) const
280{
281 return VECT(OWN_PTR(Tube_base))::printOn(is);
282}
This class encapsulates all the information related to the eulerian mesh for TrioIJK.
Definition Domaine_IJK.h:47
double get_constant_delta(int direction) const
Returns the size of cells in a direction.
const ArrOfDouble & get_node_coordinates(int direction) const
Returns an array with the coordinates of all nodes in the mesh in requested direction.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
@ REQUIRED
Definition Param.h:115
Representation des donnees de la classe Parser.
Definition Parser.h:39
void addVar(const char *)
Definition Parser.cpp:565
virtual void setNbVar(int nvar)
Definition Parser.cpp:116
void setVar(const char *sv, double val)
Definition Parser.h:73
double eval()
Definition Parser.h:68
void setString(const std::string &s)
Definition Parser.h:102
virtual void parseString()
Definition Parser.cpp:124
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size_array() const
Vecteur3 pos_
Definition Tube_base.h:64
Vecteur3 acceleration_
Definition Tube_base.h:66
void initialize(const Domaine_IJK &)
Definition Tube_base.cpp:53
double rayon_
Definition Tube_base.h:63
Vecteur3 v_
Definition Tube_base.h:65
double omega_
Definition Tube_base.h:62
void update_vitesse_position(double current_time, double dt, const Vecteur3 &force_appliquee) override
Noms expressions_position_
Definition Tube_base.h:78
double rho_cylindre_
Definition Tube_base.h:90
Vecteur3 position_equilibre_
Definition Tube_base.h:88
bool blocage_[3]
Definition Tube_base.h:89
double raideur_
Definition Tube_base.h:90
void update_vitesse_position(double current_time, double dt, const Vecteur3 &force_appliquee) override
double amortissement_
Definition Tube_base.h:90