TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Ecr_fic_Ansys.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
16#include <Ecr_fic_Ansys.h>
17#include <Domaine.h>
18#include <SFichier.h>
19
20Implemente_instanciable(Ecr_fic_Ansys,"Ecrire_fichier_Ansys",Interprete);
21
23{
24 return Interprete::printOn(os);
25}
26//
27//
29{
30 return Interprete::readOn(is);
31}
32//
33//
35{
36 Cerr << "Debut Ecr_fic_Ansys::interpreter" << finl;
37 Nom nom_dom, nom_fic;
38 // Option faces non cachees, nombre de domaines (precision), decoupage en teta si axi
39 int non_hidden,domaines,tetas;
40 int i,j,k;
41 is >> nom_dom >> nom_fic >> non_hidden >> domaines >> tetas;
42 if(! sub_type(Domaine, objet(nom_dom)))
43 {
44 Cerr << nom_dom << " est du type " << objet(nom_dom).que_suis_je() << finl;
45 Cerr << "On attendait un objet de type Domaine" << finl;
47 }
48 // On recupere le domaine a partir du nom de domaine
49 const Domaine& dom=ref_cast(Domaine, objet(nom_dom));
50 const Domaine& domaine=dom;
51 SFichier fic(nom_fic);
52 // On ecrit l'en tete du fichier Ansys
53 fic << "/BATCH" << finl;
54 fic << "/PREP7" << finl;
55 fic << "/TITLE,none" << finl;
56 // Si NOPR NUMBER OF ELEMENTS= n'est pas affiche dans le .vf
57 // Faire NOPR puis GOPR ?
58 // fic << "/NOPR" << finl;
59 fic << "ANTYPE,STATIC" << finl;
60
61 // Ecriture du systeme de coordonnees
62 // C'est important de l'ecrire en 1er
63 if (bidim_axi)
64 fic << "CSYS,0" << finl;
65 else if (axi)
66 fic << "CSYS,1" << finl;
67 else
68 fic << "CSYS,0" << finl;
69 fic << "/NOPR" << finl;
70 // On ecrit tous les sommets
71 DoubleVect xyz(dimension);
72 int n=1;
73 int z=1;
74 if (non_hidden>1 && dimension==2)
75 z=1;
76 int nb_som=domaine.nb_som();
77 for (j=0; j<z; j++)
78 {
79 for (i=0; i<nb_som; i++)
80 {
81 for (k=0; k<dimension; k++)
82 xyz(k)=dom.coord(i,k);
83 // Dans Ansys, teta est en degres et non en radians comme dans TRUST
84 if (axi)
85 xyz(1)*=180/M_PI;
86 fic<<"N,"<<n++;
87 // On ecrit les coordonnees
88 for (k=0; k<dimension; k++)
89 {
90 if (j==0)
91 fic<<","<<xyz(k);
92 else
93 {
94
95 }
96 }
97 fic << finl;
98 }
99 }
100 Nom type=dom.type_elem()->que_suis_je();
101 if (non_hidden>1)
102 {
103 // Quel que soit le type et la dimension du probleme
104 fic << "ET,1,SHELL57" << finl;
105 }
106 else
107 {
108 // Ecriture du type d'element pour la methode Radiation Matrix
109 if (type=="Rectangle" || type=="Triangle" || type=="Hexaedre" || type=="Tetraedre" || type=="Quadrangle" || type=="Hexaedre_VEF")
110 {
111 if (dimension==2)
112 fic << "ET,1,LINK32" << finl;
113 else
114 {
115 fic << "ET,1,SURF152" << finl;
116 fic << "KEYOPT,1,4,1" << finl;
117 fic << "KEYOPT,1,5,0" << finl;
118 }
119 }
120 else if (type=="Rectangle_axi" || type=="Hexaedre_axi")
121 {
122 if (dimension==2)
123 fic << "ET,1,LINK32" << finl;
124 else
125 {
126 fic << "ET,1,SURF152" << finl;
127 fic << "KEYOPT,1,4,1" << finl;
128 fic << "KEYOPT,1,5,0" << finl;
129 }
130 }
131 else if (type=="Rectangle_2D_axi")
132 {
133 fic << "ET,1,LINK32" << finl;
134 }
135 else
136 {
137 Cerr << "Element " << type << " inexistant." << finl;
139 }
140 }
141 // Tableau de travail pour reordonner les sommets des faces de bord
142 // pour que Ansys connaisse la face rayonnante (Voir Doc Ansys AUX12)
143 IntVect elem(1);
144 DoubleTab pos(1,dimension);
145 double e=0.001;
146 // Ecriture de la definition des faces de bord
147 int num_globale=0;
148 const DoubleTab& c=dom.coord_sommets();
149 // Nombre de faces rayonnantes, total des bords et des raccords !
150 int nombre_faces_rayonnantes=domaine.nb_bords()+domaine.nb_raccords();
151 for (i=0; i<nombre_faces_rayonnantes; i++)
152 {
153 const IntTab& som=(i<domaine.nb_bords()?domaine.bord(i).faces().les_sommets():domaine.raccord(i-domaine.nb_bords())->faces().les_sommets());
154 int nb_faces=som.dimension(0);
155 for (j=0; j<nb_faces; j++)
156 {
157 if (dimension==2)
158 {
159
160 if (axi)
161 {
162 double r0,t0,r1,t1;
163 r0=c(som(j,0),0);
164 t0=c(som(j,0),1);
165 r1=c(som(j,1),0);
166 t1=c(som(j,1),1);
167 if (t1<t0) t1+=2*M_PI;
168 if (est_egal(r0,r1))
169 {
170 pos(0,1)=0.5*(t0+t1);
171 if (t0<t1)
172 pos(0,0)=(1-e)*r0;
173 else
174 pos(0,0)=(1+e)*r0;
175 }
176 else if (est_egal(t0,t1))
177 {
178 pos(0,0)=0.5*(r0+r1);
179 if (r0<r1)
180 pos(0,1)=(1+e)*t0;
181 else
182 pos(0,1)=(1-e)*t0;
183 }
184 }
185 else
186 {
187 double x0,y0,x1,y1;
188 x0=c(som(j,0),0);
189 y0=c(som(j,0),1);
190 x1=c(som(j,1),0);
191 y1=c(som(j,1),1);
192 double nx=y0-y1;
193 double ny=x1-x0;
194 double alpha=10*Objet_U::precision_geom/(sqrt(nx*nx+ny*ny));
195 pos(0,0)=0.5*(x0+x1)+alpha*nx;
196 pos(0,1)=0.5*(y0+y1)+alpha*ny;
197 }
198 dom.chercher_elements(pos,elem);
199 if (elem(0)!=-1)
200 {
201 fic<<"EN,"<<num_globale+j+1<<","<<som(j,0)+1<<","<<som(j,1)+1;
202 if (non_hidden>1 && dimension==2)
203 fic<<",,";
204 }
205 else
206 {
207 fic<<"EN,"<<num_globale+j+1<<","<<som(j,1)+1<<","<<som(j,0)+1;
208 if (non_hidden>1 && dimension==2)
209 fic<<",,";
210 }
211 fic<<finl;
212 }
213 else
214 {
215 if (axi)
216 {
217 double r0,t0,z0,r3,t3,z3;
218 r0=c(som(j,0),0);
219 t0=c(som(j,0),1);
220 z0=c(som(j,0),2);
221 r3=c(som(j,3),0);
222 t3=c(som(j,3),1);
223 z3=c(som(j,3),2);
224 // Cas ou on repasse a teta=0;
225 if (t3<t0) t3+=2*M_PI;
226
227 if (est_egal(r0,r3))
228 {
229 pos(0,1)=0.5*(t0+t3);
230 if (t0<t3)
231 pos(0,0)=(1+e)*r0;
232 else
233 pos(0,0)=(1-e)*r0;
234 pos(0,2)=0.5*(z0+z3);
235 }
236 else if (est_egal(z0,z3))
237 {
238 pos(0,0)=0.5*(r0+r3);
239 pos(0,1)=0.5*(t0+t3);
240 if (r0<r3)
241 pos(0,2)=(1+e)*z0;
242 else
243 pos(0,2)=(1-e)*z0;
244 }
245 else if (est_egal(t0,t3))
246 {
247 pos(0,0)=0.5*(r0+r3);
248 pos(0,2)=0.5*(z0+z3);
249 if (r0<r3)
250 pos(0,1)=(1+e)*t0;
251 else
252 pos(0,1)=(1-e)*t0;
253 }
254 dom.chercher_elements(pos,elem);
255 if (elem(0)!=-1)
256 fic<<"EN,"<<num_globale+j+1<<","<<som(j,0)+1<<","<<som(j,1)+1<<","<<som(j,3)+1<<","<<som(j,2)+1<<finl;
257 else
258 fic<<"EN,"<<num_globale+j+1<<","<<som(j,0)+1<<","<<som(j,2)+1<<","<<som(j,3)+1<<","<<som(j,1)+1<<finl;
259 }
260 else
261 {
262 double x0,y0,z0,x1,y1,z1,x2,y2,z2;
263 x0=c(som(j,0),0);
264 y0=c(som(j,0),1);
265 z0=c(som(j,0),2);
266 x1=c(som(j,1),0);
267 y1=c(som(j,1),1);
268 z1=c(som(j,1),2);
269 x2=c(som(j,2),0);
270 y2=c(som(j,2),1);
271 z2=c(som(j,2),2);
272 double nx=(y1-y0)*(z2-z0)-(z1-z0)*(y2-y0);
273 double ny=(z1-z0)*(x2-x0)-(x1-x0)*(z2-z0);
274 double nz=(x1-x0)*(y2-y0)-(y1-y0)*(x2-x0);
275 double alpha=100*Objet_U::precision_geom/(sqrt(nx*nx+ny*ny+nz*nz));
276 pos(0,0)=(x0+x1+x2)/3.+alpha*nx;
277 pos(0,1)=(y0+y1+y2)/3.+alpha*ny;
278 pos(0,2)=(z0+z1+z2)/3.+alpha*nz;
279 dom.chercher_elements(pos,elem);
280 if (elem(0)!=-1)
281 {
282 if (type=="Tetraedre")
283 fic<<"EN,"<<num_globale+j+1<<","<<som(j,0)+1<<","<<som(j,1)+1<<","<<som(j,2)+1<<finl;
284 else
285 fic<<"EN,"<<num_globale+j+1<<","<<som(j,0)+1<<","<<som(j,1)+1<<","<<som(j,3)+1<<","<<som(j,2)+1<<finl;
286 }
287 else
288 {
289 if (type=="Tetraedre")
290 fic<<"EN,"<<num_globale+j+1<<","<<som(j,0)+1<<","<<som(j,2)+1<<","<<som(j,1)+1<<finl;
291 else
292 fic<<"EN,"<<num_globale+j+1<<","<<som(j,0)+1<<","<<som(j,2)+1<<","<<som(j,3)+1<<","<<som(j,1)+1<<finl;
293 }
294 if (elem(0)!=-1)
295 {
296 int el=elem(0);
297 pos(0,0)=(x0+x1+x2)/3.-alpha*nx;
298 pos(0,1)=(y0+y1+y2)/3.-alpha*ny;
299 pos(0,2)=(z0+z1+z2)/3.-alpha*nz;
300 dom.chercher_elements(pos,elem);
301 if (elem(0)!=-1)
302 {
303 Cerr << "Cas non prevu dans l'algorithme de Ecr_fic_Ansys::interpreter ! " << finl;
304 Cerr << "La face " << j << " est entouree de deux elements " << el << " " << elem(0) << finl;
305 Cerr << alpha*nx << finl;
306 Cerr << alpha*ny << finl;
307 Cerr << alpha*nz << finl;
308 Cerr << "Contacter le support TRUST." <<finl;
310 }
311 }
312 }
313 }
314 }
315 num_globale+=nb_faces;
316 }
317 fic << "/GOPR" << finl;
318 Cerr << "Nombre de faces: " << num_globale << finl;
319 // Ecriture calcul des facteurs de forme
320 if (non_hidden>1)
321 {
322 Cerr << "Methode Radiosity Solver" << finl;
323 Cerr << "La RAM necessaire pour le calcul va etre de " << 16*num_globale*num_globale/1024/1024 << " Mo." << finl;
324 Cerr << "26Mo <->1.8Mo" << finl;
325 Cerr << "25Mo <->2.6Mo" << finl;
326 fic << "SFE,ALL,2,RDSF,2,1" << finl;
327 fic << "/AUX12" << finl;
328 }
329 else
330 {
331 Cerr << "Methode Radiation Matrix" << finl;
332 Cerr << "La RAM necessaire pour le calcul va etre de " << 16*num_globale*num_globale/1024/1024 << " Mo." << finl;
333 fic << "/AUX12" << finl;
334 // A tester le nombre de domaines sur la precision...
335 if (non_hidden==0)
336 fic << "VTYPE,0," << domaines << finl;
337 else if (non_hidden==1)
338 fic << "VTYPE,1" << finl;
339 // A tester le nombre de camenberts pour l'axi RZ (entre 6 et 90)...
340 if (bidim_axi)
341 fic << "GEOM,1," << tetas << finl;
342 else if (dimension==2)
343 fic << "GEOM,1" << finl;
344 else
345 fic << "GEOM,0" << finl;
346 fic << "MPRINT,1" << finl;
347 }
348 Nom vf=nom_du_cas();
349 vf+=".vf";
350 if (non_hidden>1)
351 {
352 // On le fait en dimension 3 egalement pour eviter le message:
353 // No Space Temperature or Space Node specified for open Enclosure 1.
354 fic << "SPCTEMP,1,0.E+00" << finl;
355 //if (dimension==2) fic << "SPCTEMP,1,0.E+00" << finl;
356 fic << "HEMIOPT,"<<domaines<< finl;
357 fic << "TOFFST,100" << finl;
358 fic << "VFOPT,NEW" << finl;
359 if (non_hidden==3)
360 {
361 // Si vf_non_groupe rediriger vers /dev/null
362 Nom vf_non_groupe(vf);
363 vf_non_groupe+=".non_groupe";
364 vf_non_groupe="trash";
365 fic << "VFCALC," << vf_non_groupe << finl;
366 fic << "/OUT,trash" << finl;
367 }
368 else
369 {
370 fic << "VFCALC," << vf << finl;
371 }
372 // Ecriture du regroupement des faces sur les bords
373 if (non_hidden==3)
374 {
375 num_globale=0;
376 for (i=0; i<nombre_faces_rayonnantes; i++)
377 {
378 const IntTab& som=(i<domaine.nb_bords()?domaine.bord(i).faces().les_sommets():domaine.raccord(i-domaine.nb_bords())->faces().les_sommets());
379 int nb_faces=som.dimension(0);
380 fic<<"ESEL,S,,,"<<num_globale+1<<","<<num_globale+nb_faces<<finl;
381 fic<<"CM,B"<<i<<",ELEM"<<finl;
382 fic<<"F"<<i<<"=0."<<finl;
383 num_globale+=nb_faces;
384 }
385 for (i=0; i<nombre_faces_rayonnantes; i++)
386 {
387 for (j=0; j<nombre_faces_rayonnantes; j++)
388 {
389 fic<<"VFQUERY,B"<<i<<",B"<<j<<finl;
390 fic<<"*GET,F"<<i<<j<<",RAD,,VFAVG"<<finl;
391 fic<<"F"<<i<<"=F"<<i<<"+F"<<i<<j<<finl;
392 }
393 }
394 fic << "/OUT," << vf << finl;
395 fic << "*VWRITE,1"<<finl;
396 fic << "('Number of Enclosures = ',F3.1)"<<finl;
397 fic << "*VWRITE,"<< nombre_faces_rayonnantes <<finl;
398 fic << "('Facteurs de forme',F6.1,' Number of Surfaces = "<< nombre_faces_rayonnantes << "')";
399 for (i=0; i<nombre_faces_rayonnantes; i++)
400 {
401 fic << finl;
402 fic << "*VWRITE,F"<<i<<finl;
403 fic << "('TOTAL= '1(F12.10,1X))"<<finl;
404 fic << "*VWRITE";
405 int colonne=0;
406 for (j=0; j<nombre_faces_rayonnantes; j++)
407 {
408 // On ecrit 10 colonnes par 10 colonnes car sinon Ansys tronque apres 17 colonnes
409 if (colonne == 10)
410 {
411 fic << finl;
412 fic << "("<<colonne<<"(F12.10,1X))"<<finl;
413 fic << "*VWRITE";
414 colonne=0;
415 }
416 colonne++;
417 fic << ",F" << i << j;
418 }
419 fic << finl;
420 fic << "(" << colonne << "(F12.10,1X))";
421 }
422 fic << finl;
423 }
424 }
425 else
426 {
427 fic << "/OUT," << vf << finl;
428 fic << "WRITE,radiation_matrix" << finl;
429 }
430 fic << "FINISH" << finl;
431 fic.close();
432 Cerr << "Fin Ecr_fic_Ansys::interpreter" << finl;
433 Cerr << "Lancement d'Ansys." << finl;
434 Cerr << "Cela peut prendre du temps..." << finl;
435 Cerr << (int) system("./.run_ansys") << finl;
436 return is;
437}
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Recherche des elements contenant les points dont les coordonnees sont specifiees.
Definition Domaine.cpp:405
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
double coord(int_t i, int j) const
Definition Domaine.h:110
Entree & interpreter(Entree &) override
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Classe de base des objets "interprete".
Definition Interprete.h:38
static Objet_U & objet(const Nom &)
Voir Interprete_bloc::objet_global() BM: la classe Interprete n'est pas le meilleur endroit pour cett...
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
friend class Entree
Definition Objet_U.h:76
static int dimension
Definition Objet_U.h:99
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
static double precision_geom
Definition Objet_U.h:86
static const Nom & nom_du_cas()
Renvoie une reference constante vers le nom du cas.
Definition Objet_U.cpp:146
static int bidim_axi
Definition Objet_U.h:102
static int axi
Definition Objet_U.h:101
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133