]> SALOME platform Git repositories - modules/hexablock.git/blob - src/HEXABLOCK/HexElements_grid.cxx
Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/hexablock.git] / src / HEXABLOCK / HexElements_grid.cxx
1 // Copyright (C) 2009-2012  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // C++ : Table des noeuds
21
22 #include "HexElements.hxx"
23
24 #include "HexDocument.hxx"
25 #include "HexVector.hxx"
26 #include "HexVertex.hxx"
27 #include "HexHexa.hxx"
28 #include "HexEdge.hxx"
29
30 #include "HexGlobale.hxx"
31
32 #include <cmath>
33
34 BEGIN_NAMESPACE_HEXA
35 // ====================================================== makeBasicCylinder
36 int Elements::makeBasicCylinder (double dr, double da, double dl, int nr, 
37                                  int na, int nl, bool fill)
38 {
39    cyl_dispo = CYL_NOFILL;
40    if (fill && na > 3)
41       {
42       if (cyl_closed)
43          {
44          if (na==4)
45             cyl_dispo = CYL_CL4;
46          else if (na==6)
47             cyl_dispo = CYL_CL6;
48          else if (na MODULO 2 == 0)
49             cyl_dispo = CYL_CLOSED;
50          }
51       else if ((na MODULO 2)==0)
52          cyl_dispo = CYL_PEER;
53       else 
54          cyl_dispo = CYL_ODD;
55       }
56
57    cyl_fill = cyl_dispo != CYL_NOFILL;
58
59    double alpha  = M_PI*da/180;
60    double beta   = alpha / na;
61    double theta  = 0;
62    int    nb_secteurs = cyl_closed ? size_vy-1 : size_vy;
63
64    for (int ny=0 ; ny<nb_secteurs ; ny++)
65        {
66        double cos_theta = cos (theta);
67        double sin_theta = sin (theta);
68        theta += beta;
69
70        for (int nx=0 ; nx<size_vx ; nx++)
71            {
72            double rayon = dr*(nx+1);
73            double px = rayon*cos_theta;
74            double py = rayon*sin_theta;
75
76            for (int nz=0 ; nz<size_vz ; nz++)
77                {
78                double pz = dl*nz;
79                //   getCylPoint (nx, ny, nz, px, py, pz);
80                Vertex* node = el_root->addVertex (px, py, pz);
81                setVertex (node, nx, ny, nz);
82                }
83            }
84        }
85
86    if (cyl_closed) 
87       {
88       for (int nx=0 ; nx<size_vx ; nx++)
89           for (int nz=0 ; nz<size_vz ; nz++)
90               {
91               Vertex* node = getVertexIJK (nx, 0, nz);
92               setVertex (node, nx, size_vy-1, nz);
93               }
94       }
95
96                       // Les vertex centraux
97    if (cyl_fill) 
98       {
99       ker_vertex = nbr_vertex;
100       for (int nz=0 ; nz<size_vz ; nz++)
101           {
102           Vertex* node = el_root->addVertex (0, 0, nz*dl);
103           tab_vertex.push_back (node);
104           nbr_vertex ++;
105           }
106       }
107
108    return HOK;
109 }
110 // ====================================================== fillGrid
111 int Elements::fillGrid ()
112 {
113    if (cyl_closed)
114       for (int nx=0 ; nx<size_vx ; nx++)
115            for (int nz=0 ; nz<size_vz ; nz++)
116                setVertex (getVertexIJK (nx, 0, nz), nx, size_vy-1, nz);
117
118    for (int nz=0 ; nz<size_vz ; nz++)
119        for (int ny=0 ; ny<size_vy ; ny++)
120            for (int nx=0 ; nx<size_vx ; nx++)
121                {
122                Vertex* v0 = getVertexIJK (nx, ny, nz  );
123                Vertex* vx = getVertexIJK (nx+1, ny, nz);
124                Vertex* vy = getVertexIJK (nx, ny+1, nz);
125                Vertex* vz = getVertexIJK (nx, ny, nz+1);
126
127                Edge* e1 = NULL;
128                Edge* e2 = newEdge (v0, vy);
129                Edge* e3 = NULL;
130
131                if (cyl_closed && ny==size_vy-1)
132                   {
133                   e1 = getEdgeI (nx, 0, nz);
134                   e3 = getEdgeK (nx, 0, nz);
135                   }
136                else
137                   {
138                   e3 = newEdge (v0, vz);
139                   e1 = newEdge (v0, vx);
140                   }
141
142                setEdge (e1, dir_x, nx, ny, nz);
143                setEdge (e2, dir_y, nx, ny, nz);
144                setEdge (e3, dir_z, nx, ny, nz);
145                }
146
147    for (int nz=0 ; nz<size_vz ; nz++)
148        for (int ny=0 ; ny<size_vy ; ny++)
149            for (int nx=0 ; nx<size_vx ; nx++)
150                {
151                Edge* eae = getEdgeI (nx, ny,   nz);
152                Edge* ebe = getEdgeI (nx, ny,   nz+1);
153                Edge* eaf = getEdgeI (nx, ny+1, nz);
154
155                Edge* eac = getEdgeJ (nx,   ny, nz);
156                Edge* ead = getEdgeJ (nx+1, ny, nz);
157                Edge* ebc = getEdgeJ (nx,   ny, nz+1);
158
159                Edge* ece = getEdgeK (nx,   ny,   nz);
160                Edge* ede = getEdgeK (nx+1, ny,   nz);
161                Edge* ecf = getEdgeK (nx,   ny+1, nz);
162                
163                Quad* q1 = newQuad (eac, eaf, ead, eae);
164                Quad* q2 = newQuad (eac, ecf, ebc, ece);
165                Quad* q3 = NULL;
166                Quad* q30 = getQuadIK (nx, 0 ,nz);
167
168                if (cyl_closed && ny==size_vy-1 && q30!= NULL)
169                   {
170                   q3 = q30;
171                   // Display(q3);
172                   }
173                else
174                   {
175                   q3 = newQuad (eae, ede, ebe, ece);
176                   }
177
178                setQuad (q1, dir_z, nx,ny,nz);
179                setQuad (q2, dir_x, nx,ny,nz);
180                setQuad (q3, dir_y, nx,ny,nz);
181                }
182
183    for (int nz=0 ; nz<size_hz ; nz++)
184        for (int ny=0 ; ny<size_hy ; ny++)
185            for (int nx=0 ; nx<size_hx ; nx++)
186                {
187                Quad* qa = getQuadIJ (nx, ny, nz);
188                Quad* qb = getQuadIJ (nx, ny, nz+1);
189
190                Quad* qc = getQuadIK (nx, ny,   nz);
191                Quad* qd = getQuadIK (nx, ny+1, nz);
192
193                Quad* qe = getQuadJK (nx,   ny, nz);
194                Quad* qf = getQuadJK (nx+1, ny, nz);
195
196                setHexa (newHexa (qa, qb, qc, qd, qe, qf), nx, ny, nz);
197                }
198
199    switch (cyl_dispo)
200       {
201       case CYL_CLOSED :
202       case CYL_PEER   :  fillCenter ();
203            break ; 
204       case CYL_CL4 :     fillCenter4 ();
205            break ; 
206       case CYL_CL6 :     fillCenter6 ();
207            break ; 
208       case CYL_ODD :     fillCenterOdd ();
209            break ; 
210       case CYL_NOFILL  :
211       default : ;
212       }
213    return HOK;
214 }
215 // ====================================================== fillCenter
216 // === Remplissage radial
217 #define IndElt(nc,nz)   (nbsecteurs*(nz) + nc)
218 #define IndRedge(nc,nz) (nbrayons  *(nz) + nc)
219 #define IndVquad(nc,nz) (nbrayons  *(nz-1) + nc)
220 void Elements::fillCenter ()
221 {
222    int nx0 = 0;
223    int nbsecteurs = size_hy / 2;
224    int nbrayons   = cyl_closed ? nbsecteurs : nbsecteurs + 1;
225
226    size_hplus  = nbsecteurs * size_hz;
227    size_qhplus = nbsecteurs * size_vz;
228    size_qvplus = nbrayons   * size_hz;
229    size_ehplus = nbrayons   * size_vz;
230    size_evplus = size_hz;
231
232    ker_hexa .resize (size_hplus);
233    ker_hquad.resize (size_qhplus);
234    ker_vquad.resize (size_qvplus);
235    ker_hedge.resize (size_ehplus);
236    ker_vedge.resize (size_evplus);
237
238    Vertex* pcenter = NULL;
239
240    for (int nz=0 ; nz<size_vz ; nz++)
241        {
242                                  //   Vertex central
243        Vertex* center = getVertex (ker_vertex+nz);
244                                  //   Edges horizontaux radiaux
245        for (int nc=0 ; nc<nbrayons ; nc++)
246            {
247            Vertex* vv = getVertexIJK (nx0, 2*nc, nz);
248            Edge*   edge = newEdge (center, vv);
249            ker_hedge [IndRedge(nc,nz)] = edge;
250            }
251                                  //   Quads horizontaux
252        for (int nc=0; nc<nbsecteurs ; nc++)
253            {
254            int nc1  = (nc + 1) MODULO nbrayons;
255            Edge* e1 = ker_hedge [IndRedge (nc, nz)];
256            Edge* e2 = getEdgeJ (nx0, 2*nc,  nz);
257            Edge* e3 = getEdgeJ (nx0, 2*nc+1,nz);
258            Edge* e4 = ker_hedge [IndRedge (nc1, nz)];
259
260            ker_hquad [IndElt (nc,nz)] = newQuad (e1, e2, e3, e4);
261            if (debug()) 
262               {
263               printf ("hquad (%d,%d) = ", nc, nz);
264               ker_hquad [IndElt (nc,nz)]->dumpPlus();
265               }
266            }
267
268        if (nz>0)
269           {
270                                  //   Edges verticaux + cloisons interieures
271           Edge* pilier = ker_vedge [nz-1] = newEdge (pcenter, center);
272
273           for (int nc=0 ; nc<nbrayons ; nc++)
274               {
275               Edge* e1 = ker_hedge [IndRedge (nc, nz)];
276               Edge* e2 = getEdgeK (nx0, 2*nc,  nz-1);
277               Edge* e3 = ker_hedge [IndRedge (nc, nz-1)];
278               ker_vquad [IndVquad (nc,nz)] = newQuad (e1, e2, e3, pilier);
279               if (debug()) 
280                  {
281                  printf ("vquad (%d,%d) = ", nc, nz);
282                  ker_vquad [IndVquad (nc,nz)]->dumpPlus();
283                  }
284               }
285                                  //   Hexas
286           for (int nc=0 ; nc < nbsecteurs ; nc++)
287               {
288               int nc1  = nc + 1;
289               if (cyl_closed) 
290                   nc1  = nc1 MODULO nbsecteurs;
291               Quad* qa = ker_hquad [IndElt (nc, nz-1)];
292               Quad* qb = ker_hquad [IndElt (nc, nz)];
293
294               Quad* qc = ker_vquad [IndVquad (nc, nz)];
295               Quad* qd = getQuadJK (nx0, 2*nc+1, nz-1);
296
297               Quad* qe = getQuadJK (nx0, 2*nc,   nz-1);
298               Quad* qf = ker_vquad [IndVquad (nc1,  nz)];
299
300               if (debug()) 
301                  {
302                  printf (" --------------- Hexa : nc=%d, nz=%d\n", nc, nz);
303                  HexDump (qa);
304                  HexDump (qb);
305                  HexDump (qc);
306                  HexDump (qd);
307                  HexDump (qe);
308                  HexDump (qf);
309                  }
310               Hexa* cell = newHexa (qa, qb, qc, qd, qe, qf);
311               tab_hexa.push_back (cell);
312               ker_hexa [IndElt (nc,  nz-1)] = cell;
313               }
314           }
315        pcenter = center;
316        }
317 }
318 // ====================================================== fillCenter4
319 // === Remplissage radial
320 void Elements::fillCenter4 ()
321 {
322    int   nx0  = 0;
323    Quad* sol = NULL;
324
325    for (int nz=0 ; nz<size_vz ; nz++)
326        {
327                                  //   Quad horizontal
328
329        Quad* plafond = newQuad (getEdgeJ (nx0, 0,  nz), getEdgeJ (nx0, 1, nz), 
330                                 getEdgeJ (nx0, 2,  nz), getEdgeJ (nx0, 3, nz));
331
332        if (nz>0)
333           {
334           Quad* qc = getQuadJK (nx0, 0, nz-1);
335           Quad* qd = getQuadJK (nx0, 2, nz-1);
336           Quad* qe = getQuadJK (nx0, 1, nz-1);
337           Quad* qf = getQuadJK (nx0, 3, nz-1);
338
339           if (debug()) 
340              {
341              printf (" --------------- Hexa grille4 : nz=%d\n", nz);
342              HexDump (plafond);
343              HexDump (sol);
344              HexDump (qc);
345              HexDump (qd);
346              HexDump (qe);
347              HexDump (qf);
348              }
349           Hexa* cell = newHexa (plafond, sol, qc, qd, qe, qf);
350           tab_hexa.push_back (cell);
351           }
352        sol = plafond;
353        }
354 }
355 // ====================================================== fillCenter6
356 void Elements::fillCenter6 ()
357 {
358    int nx0 = 0;
359    int nydemi = size_hy / 2;
360
361    Edge* s_barre = NULL;
362    Quad* sr_quad = NULL;
363    Quad* sl_quad = NULL;
364
365    for (int nz=0 ; nz<size_vz ; nz++)
366        {
367                                  //   Edges horizontal radial
368        Edge* p_barre = newEdge (getVertexIJK (nx0, 0,      nz),
369                                 getVertexIJK (nx0, nydemi, nz));
370                                  //   Quads horizontaux
371        Edge* e0 = getEdgeJ (nx0, 0,  nz);
372        Edge* e1 = getEdgeJ (nx0, 1,  nz);
373        Edge* e2 = getEdgeJ (nx0, 2,  nz);
374        Edge* e3 = getEdgeJ (nx0, 3,  nz);
375        Edge* e4 = getEdgeJ (nx0, 4,  nz);
376        Edge* e5 = getEdgeJ (nx0, 5,  nz);
377
378        Quad* pl_quad = newQuad (e0, e1, e2, p_barre);
379        Quad* pr_quad = newQuad (e3, e4, e5, p_barre);
380
381        if (nz>0)
382           {
383                                  //   Cloison interieure
384           Quad* cloison = newQuad (p_barre, getEdgeK (nx0, 0,       nz-1), 
385                                    s_barre, getEdgeK (nx0, nydemi,  nz-1));
386                                  //   Hexas
387           Quad* q0 = getQuadJK (nx0, 0, nz-1);
388           Quad* q1 = getQuadJK (nx0, 1, nz-1);
389           Quad* q2 = getQuadJK (nx0, 2, nz-1);
390           Quad* q3 = getQuadJK (nx0, 3, nz-1);
391           Quad* q4 = getQuadJK (nx0, 4, nz-1);
392           Quad* q5 = getQuadJK (nx0, 5, nz-1);
393
394           Hexa* left  = newHexa (sl_quad, pl_quad, q0, q2,  q1, cloison);
395           Hexa* right = newHexa (sr_quad, pr_quad, q3, q5,  q4, cloison);
396           tab_hexa.push_back (left);
397           tab_hexa.push_back (right);
398           }
399        s_barre = p_barre;
400        sr_quad = pr_quad;
401        sl_quad = pl_quad;
402        }
403 }
404 // ====================================================== fillCenterOdd
405 #undef  IndElt
406 #define IndElt(nc,nz) (nbsecteurs*(nz) + nc)
407 void Elements::fillCenterOdd ()
408 {
409    int nx0 = 0;
410    int nbsecteurs = size_hy / 2;
411
412    vector <Edge*> ker_hedge (nbsecteurs*size_vz);
413    vector <Quad*> ker_hquad (nbsecteurs*size_vz);
414    vector <Quad*> ker_vquad (nbsecteurs*size_vz);
415
416    for (int nz=0 ; nz<size_vz ; nz++)
417        {
418                                  //   Edges horizontaux radiaux
419        for (int nc=0 ; nc<nbsecteurs ; nc++)
420            {
421            int nc1 = size_hy - nc;
422            Edge* edge = newEdge (getVertexIJK (nx0, nc,  nz), 
423                                  getVertexIJK (nx0, nc1, nz));
424            ker_hedge [IndElt(nc,nz)] = edge;
425            }
426                                  //   Quads horizontaux
427        for (int nc=0; nc<nbsecteurs ; nc++)
428            {
429            Edge* e1 = ker_hedge [IndElt (nc, nz)];
430            Edge* e2 = getEdgeJ (nx0, nc,           nz);
431            Edge* e4 = getEdgeJ (nx0, size_hy-nc-1, nz);
432
433            Edge* e3 = nc<nbsecteurs-1 ? ker_hedge [IndElt (nc+1, nz)]
434                                       : getEdgeJ (nx0, nbsecteurs, nz);
435
436            ker_hquad [IndElt (nc,nz)] = newQuad (e1, e2, e3, e4);
437            if (debug()) 
438               {
439               printf ("hquad (%d,%d) = ", nc, nz);
440               ker_hquad [IndElt (nc,nz)]->dumpPlus();
441               }
442            }
443
444        if (nz>0)
445           {
446                                  //   Edges verticaux + cloisons interieures
447           for (int nc=0 ; nc<nbsecteurs ; nc++)
448               {
449               int nc1 = size_hy - nc;
450               Edge* e1 = ker_hedge [IndElt (nc, nz)];
451               Edge* e3 = ker_hedge [IndElt (nc, nz-1)];
452               Edge* e2 = getEdgeK (nx0, nc,   nz-1);
453               Edge* e4 = getEdgeK (nx0, nc1,  nz-1);
454               ker_vquad [IndElt (nc,nz)] = newQuad (e1, e2, e3, e4);
455               if (debug()) 
456                  {
457                  printf ("vquad (%d,%d) = ", nc, nz);
458                  ker_vquad [IndElt (nc,nz)]->dumpPlus();
459                  }
460               }
461                                  //   Hexas
462           for (int nc=0 ; nc < nbsecteurs ; nc++)
463               {
464               int nc1 = size_hy - nc-1;
465               Quad* qa = ker_hquad [IndElt (nc, nz-1)];
466               Quad* qb = ker_hquad [IndElt (nc, nz)];
467
468               Quad* qc = getQuadJK (nx0, nc,  nz-1);
469               Quad* qd = getQuadJK (nx0, nc1, nz-1);
470
471               Quad* qe = ker_vquad [IndElt (nc, nz)];
472               Quad* qf = nc<nbsecteurs-1 ? ker_vquad [IndElt (nc+1,  nz)]
473                                          : getQuadJK (nx0, nbsecteurs, nz-1);
474               if (debug()) 
475                  {
476                  printf (" --------------- Hexa : nc=%d, nz=%d\n", nc, nz);
477                  HexDump (qa);
478                  HexDump (qb);
479                  HexDump (qc);
480                  HexDump (qd);
481                  HexDump (qe);
482                  HexDump (qf);
483                  }
484               Hexa* cell = newHexa (qa, qb, qc, qd, qe, qf);
485               tab_hexa.push_back (cell);
486               }
487           }
488        }
489 }
490 // --------------------------------------------------------------------------
491 // ----------------------------------------- Evols Hexa 3
492 // --------------------------------------------------------------------------
493 // ====================================================== makeCylindricalGrid
494 // ==== Version avec vecteurs
495 int Elements::makeCylindricalGrid (Vertex* orig, Vector* base, Vector* haut, 
496                             RealVector& tdr, RealVector& tda, RealVector& tdh, 
497                             bool fill)
498 {
499    int nr = tdr.size() - 1;
500    int na = tda.size();
501    int nl = tdh.size();
502    double angle = 0;
503
504    for (int nro=0 ; nro<na ; nro++)
505        angle += tda[nro];
506
507    resize (GR_CYLINDRIC, nr, na, nl);
508    cyl_closed = angle >= 360.0;
509
510    int ier = makeBasicCylinder (tdr, tda, tdh, fill);
511    if (ier!=HOK) 
512        return ier;
513
514    transfoVertices  (orig,  base, haut);
515
516    fillGrid ();
517    assoCylinders (orig, haut, angle, tda);
518    return HOK;
519 }
520 // ====================================================== makeBasicCylinder
521 // ==== Version avec vecteurs
522 int Elements::makeBasicCylinder (RealVector& tdr, RealVector& tda, 
523                                  RealVector& tdh, bool fill)
524 {
525    int na = tda.size();
526
527    cyl_dispo = CYL_NOFILL;
528    if (fill && na > 3)
529       {
530       if (cyl_closed)
531          {
532          if (na==4)
533             cyl_dispo = CYL_CL4;
534          else if (na==6)
535             cyl_dispo = CYL_CL6;
536          else if (na MODULO 2 == 0)
537             cyl_dispo = CYL_CLOSED;
538          }
539       else if ((na MODULO 2)==0)
540          cyl_dispo = CYL_PEER;
541       else 
542          cyl_dispo = CYL_ODD;
543       }
544
545    cyl_fill = cyl_dispo != CYL_NOFILL;
546
547    double alpha  = 0;
548    int    nb_secteurs = cyl_closed ? size_vy-1 : size_vy;
549
550    for (int ny=0 ; ny<nb_secteurs ; ny++)
551        {
552        if (ny>0)
553           alpha  += tda[ny-1];
554
555        double theta     = M_PI*alpha/180;
556        double cos_theta = cos (theta);
557        double sin_theta = sin (theta);
558        double rayon = 0;
559
560        for (int nx=0 ; nx<size_vx ; nx++)
561            {
562            //  double rayon = dr*(nx+1);
563            rayon += tdr [nx];
564            double px = rayon*cos_theta;
565            double py = rayon*sin_theta;
566            double pz = 0;
567
568            for (int nz=0 ; nz<size_vz ; nz++)
569                {
570                if (nz > 0)
571                    pz += tdh [nz-1];
572                Vertex* node = el_root->addVertex (px, py, pz);
573                setVertex (node, nx, ny, nz);
574                }
575            }
576        }
577
578    if (cyl_closed) 
579       {
580       for (int nx=0 ; nx<size_vx ; nx++)
581           for (int nz=0 ; nz<size_vz ; nz++)
582               {
583               Vertex* node = getVertexIJK (nx, 0, nz);
584               setVertex (node, nx, size_vy-1, nz);
585               }
586       }
587                       // Les vertex centraux
588    if (cyl_fill) 
589       {
590       double pz = 0;
591       ker_vertex = nbr_vertex;
592       for (int nz=0 ; nz<size_vz ; nz++)
593           {
594           if (nz > 0)
595               pz += tdh [nz-1];
596           Vertex* node = el_root->addVertex (0, 0, pz);
597           tab_vertex.push_back (node);
598           nbr_vertex ++;
599           }
600       }
601
602    return HOK;
603 }
604 END_NAMESPACE_HEXA
605