1 From 8b92e13269c76f0c4b3422cd2774412bb24368b7 Mon Sep 17 00:00:00 2001
2 From: Antoine Gerschenfeld <antoine.gerschenfeld@cea.fr>
3 Date: Sun, 19 May 2019 20:24:42 +0200
4 Subject: [PATCH 1/3] LATA reader
7 databases/CMakeLists.txt | 1 +
8 databases/readers/Lata/ArrOfBit.C | 179 ++
9 databases/readers/Lata/ArrOfBit.h | 110 +
10 databases/readers/Lata/ArrOfDouble.C | 1185 +++++++++
11 databases/readers/Lata/ArrOfDouble.h | 353 +++
12 databases/readers/Lata/ArrOfFloat.C | 1185 +++++++++
13 databases/readers/Lata/ArrOfFloat.h | 353 +++
14 databases/readers/Lata/ArrOfInt.C | 1110 ++++++++
15 databases/readers/Lata/ArrOfInt.h | 343 +++
16 .../readers/Lata/ArrOf_Scalar_Prototype.cpp.h | 1168 +++++++++
17 .../readers/Lata/ArrOf_Scalar_Prototype.h | 357 +++
18 databases/readers/Lata/CMakeLists.txt | 35 +
19 .../readers/Lata/Connectivite_som_elem.C | 189 ++
20 .../readers/Lata/Connectivite_som_elem.h | 44 +
21 databases/readers/Lata/DoubleTab.h | 30 +
22 databases/readers/Lata/EFichier.h | 60 +
23 databases/readers/Lata/Entree.h | 77 +
24 databases/readers/Lata/FloatTab.h | 30 +
25 databases/readers/Lata/IntTab.h | 31 +
26 databases/readers/Lata/LataDB.C | 2313 +++++++++++++++++
27 databases/readers/Lata/LataDB.h | 303 +++
28 databases/readers/Lata/LataDBmed.h | 586 +++++
29 databases/readers/Lata/LataFilter.C | 1106 ++++++++
30 databases/readers/Lata/LataFilter.h | 261 ++
31 databases/readers/Lata/LataJournal.h | 36 +
32 databases/readers/Lata/LataStructures.C | 743 ++++++
33 databases/readers/Lata/LataStructures.h | 332 +++
34 .../readers/Lata/LataV1_field_definitions.C | 84 +
35 .../readers/Lata/LataV1_field_definitions.h | 35 +
36 databases/readers/Lata/LataVector.h | 64 +
37 databases/readers/Lata/LataWriter.C | 331 +++
38 databases/readers/Lata/LataWriter.h | 61 +
39 databases/readers/Lata/Lata_tools.C | 128 +
40 databases/readers/Lata/Lata_tools.h | 194 ++
41 databases/readers/Lata/LmlReader.C | 435 ++++
42 databases/readers/Lata/LmlReader.h | 38 +
43 databases/readers/Lata/Motcle.C | 142 +
44 databases/readers/Lata/Motcle.h | 150 ++
45 databases/readers/Lata/Noms.h | 29 +
46 databases/readers/Lata/Objet_U.h | 41 +
47 databases/readers/Lata/Octree_Double.C | 395 +++
48 databases/readers/Lata/Octree_Double.h | 89 +
49 databases/readers/Lata/Octree_Int.C | 485 ++++
50 databases/readers/Lata/Octree_Int.h | 103 +
51 databases/readers/Lata/OpenDXWriter.C | 335 +++
52 databases/readers/Lata/OpenDXWriter.h | 83 +
53 databases/readers/Lata/Operator.h | 224 ++
54 databases/readers/Lata/OperatorBoundary.C | 227 ++
55 databases/readers/Lata/OperatorDualMesh.C | 222 ++
56 databases/readers/Lata/OperatorFacesMesh.C | 130 +
57 databases/readers/Lata/OperatorReconnect.C | 125 +
58 databases/readers/Lata/OperatorRegularize.C | 296 +++
59 .../readers/Lata/Rebuild_virtual_layer.C | 141 +
60 .../readers/Lata/Rebuild_virtual_layer.h | 35 +
61 databases/readers/Lata/Sortie.h | 44 +
62 databases/readers/Lata/Static_Int_Lists.C | 128 +
63 databases/readers/Lata/Static_Int_Lists.h | 110 +
64 databases/readers/Lata/UserFields.C | 1038 ++++++++
65 databases/readers/Lata/UserFields.h | 108 +
66 databases/readers/Lata/Vect.h | 34 +
67 databases/readers/Lata/VectArrOfInt.h | 34 +
68 databases/readers/Lata/arch.h | 34 +
69 databases/readers/Lata/avtlataFileFormat.C | 865 ++++++
70 databases/readers/Lata/avtlataFileFormat.h | 114 +
71 databases/readers/Lata/simd_interface.h | 31 +
72 databases/visit_readers.xml | 13 +
73 66 files changed, 19695 insertions(+)
74 create mode 100644 databases/readers/Lata/ArrOfBit.C
75 create mode 100644 databases/readers/Lata/ArrOfBit.h
76 create mode 100644 databases/readers/Lata/ArrOfDouble.C
77 create mode 100644 databases/readers/Lata/ArrOfDouble.h
78 create mode 100644 databases/readers/Lata/ArrOfFloat.C
79 create mode 100644 databases/readers/Lata/ArrOfFloat.h
80 create mode 100644 databases/readers/Lata/ArrOfInt.C
81 create mode 100644 databases/readers/Lata/ArrOfInt.h
82 create mode 100644 databases/readers/Lata/ArrOf_Scalar_Prototype.cpp.h
83 create mode 100644 databases/readers/Lata/ArrOf_Scalar_Prototype.h
84 create mode 100644 databases/readers/Lata/CMakeLists.txt
85 create mode 100644 databases/readers/Lata/Connectivite_som_elem.C
86 create mode 100644 databases/readers/Lata/Connectivite_som_elem.h
87 create mode 100644 databases/readers/Lata/DoubleTab.h
88 create mode 100644 databases/readers/Lata/EFichier.h
89 create mode 100644 databases/readers/Lata/Entree.h
90 create mode 100644 databases/readers/Lata/FloatTab.h
91 create mode 100644 databases/readers/Lata/IntTab.h
92 create mode 100644 databases/readers/Lata/LataDB.C
93 create mode 100644 databases/readers/Lata/LataDB.h
94 create mode 100644 databases/readers/Lata/LataDBmed.h
95 create mode 100644 databases/readers/Lata/LataFilter.C
96 create mode 100644 databases/readers/Lata/LataFilter.h
97 create mode 100644 databases/readers/Lata/LataJournal.h
98 create mode 100644 databases/readers/Lata/LataStructures.C
99 create mode 100644 databases/readers/Lata/LataStructures.h
100 create mode 100644 databases/readers/Lata/LataV1_field_definitions.C
101 create mode 100644 databases/readers/Lata/LataV1_field_definitions.h
102 create mode 100644 databases/readers/Lata/LataVector.h
103 create mode 100644 databases/readers/Lata/LataWriter.C
104 create mode 100644 databases/readers/Lata/LataWriter.h
105 create mode 100644 databases/readers/Lata/Lata_tools.C
106 create mode 100644 databases/readers/Lata/Lata_tools.h
107 create mode 100644 databases/readers/Lata/LmlReader.C
108 create mode 100644 databases/readers/Lata/LmlReader.h
109 create mode 100644 databases/readers/Lata/Motcle.C
110 create mode 100644 databases/readers/Lata/Motcle.h
111 create mode 100644 databases/readers/Lata/Noms.h
112 create mode 100644 databases/readers/Lata/Objet_U.h
113 create mode 100644 databases/readers/Lata/Octree_Double.C
114 create mode 100644 databases/readers/Lata/Octree_Double.h
115 create mode 100644 databases/readers/Lata/Octree_Int.C
116 create mode 100644 databases/readers/Lata/Octree_Int.h
117 create mode 100644 databases/readers/Lata/OpenDXWriter.C
118 create mode 100644 databases/readers/Lata/OpenDXWriter.h
119 create mode 100644 databases/readers/Lata/Operator.h
120 create mode 100644 databases/readers/Lata/OperatorBoundary.C
121 create mode 100644 databases/readers/Lata/OperatorDualMesh.C
122 create mode 100644 databases/readers/Lata/OperatorFacesMesh.C
123 create mode 100644 databases/readers/Lata/OperatorReconnect.C
124 create mode 100644 databases/readers/Lata/OperatorRegularize.C
125 create mode 100644 databases/readers/Lata/Rebuild_virtual_layer.C
126 create mode 100644 databases/readers/Lata/Rebuild_virtual_layer.h
127 create mode 100644 databases/readers/Lata/Sortie.h
128 create mode 100644 databases/readers/Lata/Static_Int_Lists.C
129 create mode 100644 databases/readers/Lata/Static_Int_Lists.h
130 create mode 100644 databases/readers/Lata/UserFields.C
131 create mode 100644 databases/readers/Lata/UserFields.h
132 create mode 100644 databases/readers/Lata/Vect.h
133 create mode 100644 databases/readers/Lata/VectArrOfInt.h
134 create mode 100644 databases/readers/Lata/arch.h
135 create mode 100644 databases/readers/Lata/avtlataFileFormat.C
136 create mode 100644 databases/readers/Lata/avtlataFileFormat.h
137 create mode 100644 databases/readers/Lata/simd_interface.h
139 diff --git a/databases/CMakeLists.txt b/databases/CMakeLists.txt
140 index a3d1b03..7b4bd48 100644
141 --- a/databases/CMakeLists.txt
142 +++ b/databases/CMakeLists.txt
143 @@ -35,6 +35,7 @@ set(DEFAULT_BRIDGE_READERS
151 diff --git a/databases/readers/Lata/ArrOfBit.C b/databases/readers/Lata/ArrOfBit.C
153 index 0000000..c1b4b45
155 +++ b/databases/readers/Lata/ArrOfBit.C
157 +/*****************************************************************************
159 +* Copyright (c) 2011 - 2013, CEA
160 +* All rights reserved.
161 +* Redistribution and use in source and binary forms, with or without
162 +* modification, are permitted provided that the following conditions are met:
164 +* * Redistributions of source code must retain the above copyright
165 +* notice, this list of conditions and the following disclaimer.
166 +* * Redistributions in binary form must reproduce the above copyright
167 +* notice, this list of conditions and the following disclaimer in the
168 +* documentation and/or other materials provided with the distribution.
169 +* * Neither the name of CEA, nor the
170 +* names of its contributors may be used to endorse or promote products
171 +* derived from this software without specific prior written permission.
173 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
174 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
175 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
176 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
177 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
178 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
179 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
180 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
181 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
182 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
184 +*****************************************************************************/
186 +#include <ArrOfBit.h>
188 +//Implemente_instanciable_sans_constructeur_ni_destructeur(ArrOfBit,"ArrOfBit",Objet_U);
190 +const unsigned int ArrOfBit::SIZE_OF_INT_BITS = 5;
191 +const unsigned int ArrOfBit::DRAPEAUX_INT = 31;
193 +// Description: Constructeur d'un tableau de taille n, non initialise
194 +ArrOfBit::ArrOfBit(entier n)
201 +// Description: Destructeur.
202 +ArrOfBit::~ArrOfBit()
209 +// Description: Constructeur par copie (deep copy)
210 +ArrOfBit::ArrOfBit(const ArrOfBit& array)
218 +// Taille en "int" du tableau requis pour stocker un tableau de bits
219 +// de taille donnees.
220 +entier ArrOfBit::calculer_int_size(entier taille) const
222 + assert(taille >= 0);
223 + entier siz = taille >> SIZE_OF_INT_BITS;
224 + if (taille & DRAPEAUX_INT)
229 +// Description: Change la taille du tableau et copie les donnees
230 +// existantes. Si la taille est plus petite, les donnees sont
231 +// tronquees, et si la taille est plus grande, les nouveaux elements
232 +// ne sont pas initialises.
233 +ArrOfBit& ArrOfBit::resize_array(entier n)
240 + entier oldsize = calculer_int_size(taille);
241 + entier newsize = calculer_int_size(n);
242 + unsigned int * newdata = new unsigned int[newsize];
243 + entier size_copy = (newsize > oldsize) ? oldsize : newsize;
246 + memcpy(newdata, data, size_copy);
254 + delete[] data; // data!=0 sinon taille==n et on ne serait pas ici
261 +// Description: Operateur copie (deep copy).
262 +ArrOfBit& ArrOfBit::operator=(const ArrOfBit& array)
264 + entier newsize = calculer_int_size(array.taille);
265 + if (taille != array.taille)
273 + data = new unsigned int[newsize];
275 + taille = array.taille;
277 + memcpy(data, array.data, newsize * sizeof(unsigned int));
281 +// Description: Si la valeur est non nulle, met la valeur 1 dans
282 +// tous les elements du tableau, sinon met la valeur 0.
284 +ArrOfBit& ArrOfBit::operator=(entier val)
286 + unsigned int valeur = val ? (~((unsigned int) 0)) : 0;
287 + entier size = calculer_int_size(taille);
289 + for (i = 0; i < size; i++)
294 +// Description: Ecriture du tableau. Format:
296 +// 0 1 0 0 1 0 ... (n valeurs)
297 +Sortie& ArrOfBit::printOn(Sortie& os) const
299 + os << taille << finl;
301 + // Un retour a la ligne tous les 32 bits,
302 + // Une espace tous les 8 bits
303 + for (i = 0; i < taille; i++)
305 + os << operator[](i);
308 + if ((i & 31) == 31)
311 + // Un retour a la ligne si la derniere ligne n'etait pas terminee
317 +// Description: Lecture du tableau. Format:
319 +// 0 1 0 0 1 0 ... (n valeurs)
320 +Entree& ArrOfBit::readOn(Entree& is)
324 + resize_array(newsize);
328 + for (i = 0; i < taille; i++)
332 + if (bit) setbit(i);
336 diff --git a/databases/readers/Lata/ArrOfBit.h b/databases/readers/Lata/ArrOfBit.h
338 index 0000000..ed21f48
340 +++ b/databases/readers/Lata/ArrOfBit.h
342 +/*****************************************************************************
344 +* Copyright (c) 2011 - 2013, CEA
345 +* All rights reserved.
346 +* Redistribution and use in source and binary forms, with or without
347 +* modification, are permitted provided that the following conditions are met:
349 +* * Redistributions of source code must retain the above copyright
350 +* notice, this list of conditions and the following disclaimer.
351 +* * Redistributions in binary form must reproduce the above copyright
352 +* notice, this list of conditions and the following disclaimer in the
353 +* documentation and/or other materials provided with the distribution.
354 +* * Neither the name of CEA, nor the
355 +* names of its contributors may be used to endorse or promote products
356 +* derived from this software without specific prior written permission.
358 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
359 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
360 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
361 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
362 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
363 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
364 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
365 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
366 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
367 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
369 +*****************************************************************************/
376 +#include <Objet_U.h>
378 +class ArrOfBit // : public Objet_U
380 +// Declare_instanciable_sans_constructeur_ni_destructeur(ArrOfBit);
382 + Entree& readOn(Entree& is);
383 + Sortie& printOn(Sortie& os) const;
385 + ArrOfBit(entier n=0);
386 + ArrOfBit(const ArrOfBit& array); // Constructeur par copie
387 + ~ArrOfBit(); // Destructeur
388 + ArrOfBit& operator=(const ArrOfBit& array); // Operateur copie
389 + ArrOfBit& operator=(entier i);
390 + inline entier operator[](entier i) const;
391 + inline void setbit(entier i) const;
392 + inline entier testsetbit(entier i) const;
393 + inline void clearbit(entier i) const;
394 + inline entier size_array() const;
395 + ArrOfBit& resize_array(entier n);
396 + entier calculer_int_size(entier taille) const;
399 + unsigned int *data;
400 + static const unsigned int SIZE_OF_INT_BITS;
401 + static const unsigned int DRAPEAUX_INT;
404 +// Description: Renvoie 1 si le bit e est mis, 0 sinon.
405 +inline entier ArrOfBit::operator[](entier e) const
407 + assert(e >= 0 && e < taille);
408 + unsigned int i = (unsigned int) e;
409 + unsigned int x = data[i >> SIZE_OF_INT_BITS];
410 + unsigned int flag = 1 << (i & DRAPEAUX_INT);
411 + entier resultat = ((x & flag) != 0) ? 1 : 0;
415 +// Description: Met le bit e a 1.
416 +inline void ArrOfBit::setbit(entier e) const
418 + assert(e >= 0 && e < taille);
419 + unsigned int i = (unsigned int) e;
420 + unsigned int flag = 1 << (i & DRAPEAUX_INT);
421 + data[i >> SIZE_OF_INT_BITS] |= flag;
424 +// Description: Renvoie la valeur du bit e, puis met le bit e a 1.
425 +inline entier ArrOfBit::testsetbit(entier e) const
427 + assert(e >= 0 && e < taille);
428 + unsigned int i = (unsigned int) e;
429 + unsigned int flag = 1 << (i & DRAPEAUX_INT);
430 + entier index = i >> SIZE_OF_INT_BITS;
431 + unsigned int old = data[index];
432 + data[index] = old | flag;
433 + return ((old & flag) != 0) ? 1 : 0;
436 +// Description: Met le bit e a 0.
437 +inline void ArrOfBit::clearbit(entier e) const
439 + assert(e >= 0 && e < taille);
440 + unsigned int i = (unsigned int) e;
441 + unsigned int flag = 1 << (i & DRAPEAUX_INT);
442 + data[i >> SIZE_OF_INT_BITS] &= ~flag;
445 +// Description: Renvoie la taille du tableau en bits
446 +inline entier ArrOfBit::size_array() const
452 diff --git a/databases/readers/Lata/ArrOfDouble.C b/databases/readers/Lata/ArrOfDouble.C
454 index 0000000..5605a0d
456 +++ b/databases/readers/Lata/ArrOfDouble.C
458 +/*****************************************************************************
460 +* Copyright (c) 2011 - 2013, CEA
461 +* All rights reserved.
462 +* Redistribution and use in source and binary forms, with or without
463 +* modification, are permitted provided that the following conditions are met:
465 +* * Redistributions of source code must retain the above copyright
466 +* notice, this list of conditions and the following disclaimer.
467 +* * Redistributions in binary form must reproduce the above copyright
468 +* notice, this list of conditions and the following disclaimer in the
469 +* documentation and/or other materials provided with the distribution.
470 +* * Neither the name of CEA, nor the
471 +* names of its contributors may be used to endorse or promote products
472 +* derived from this software without specific prior written permission.
474 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
475 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
476 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
477 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
478 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
479 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
480 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
481 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
482 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
483 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
485 +*****************************************************************************/
487 +////////////////////////////////////////////////////////////
489 +// Warning : DO NOT EDIT !
490 +// Please update ArrOf_Scalar_Prototype.cpp.h
491 +// and this file will be generated automatically
492 +// by the script file check.sh
493 +////////////////////////////////////////////////////////////
495 +#include <ArrOfDouble.h>
498 +#include <Objet_U.h>
502 +#include "simd_interface.h"
504 +using namespace std;
506 +// ******************************************************************
508 +// Implementation des methodes de VDoubledata
510 +// ******************************************************************
511 +////////////////////////////////////////////////////////////////////
513 +// .ENTETE TRUST Math
514 +// .LIBRAIRIE libtmath
515 +// .FILE ArrOfDouble.h
516 +// .FILE ArrOfDouble.cpp
519 +// VDoubledata alloue une zone de memoire de la taille specifiee au
520 +// constructeur, et libere la zone de memoire a la destruction.
522 +// "ref_count" compte le nombre de pointeurs qui font reference a "this".
523 +// (permet au dernier utilisateur de l'objet de le detruire), voir
526 +// .SECTION voir aussi
531 +///////////////////////////////////////////////////////////////////
536 + VDoubledata(entier size, ArrOfDouble::Storage storage);
538 + entier add_one_ref();
539 + entier suppr_one_ref();
540 + double * get_data();
541 + const double * get_data() const;
542 + inline entier ref_count() const;
543 + inline entier get_size() const;
545 + // Le constructeur par copie et l'operateur= sont interdits.
546 + VDoubledata(const VDoubledata& v);
547 + VDoubledata& operator=(const VDoubledata& v);
549 + // "data" est un pointeur sur une zone de memoire de taille
550 + // sz * sizeof(double), allouee par le
551 + // constructeur et liberee par le destructeur.
552 + // Ce pointeur n'est jamais nul meme si size_==0
554 + // Compteur incremente par add_one_ref et decremente par suppr_one_ref.
555 + // Contient le nombre d'objets ArrOfDouble dont le membre "p" pointe
556 + // vers "this". On a ref_count_ >= 0.
558 + // "sz" est la taille du tableau "data_" alloue
561 + ArrOfDouble::Storage storage_;
566 +// Construit un VDoubledata de taille size >= 0
567 +// Parametre: entier s
568 +// Signification: taille du VDoubledata, il faut size >= 0
569 +// Parametre: Storage storage
570 +// Signification: indique si la memoire doit etre allouee
571 +// avec "new" ou avec "simd_malloc"
572 +// Valeurs par defaut: STANDARD (allocation avec "new")
574 +// data_ n'est jamais nul, meme si size==0
575 +VDoubledata::VDoubledata(entier size, ArrOfDouble::Storage storage)
578 + storage = ArrOfDouble::STANDARD;
582 + case ArrOfDouble::STANDARD:
585 + // Allocation de la memoire sur le tas
588 + data_ = new double[size];
592 + Cerr << "impossible d'allouer " << size << " double " << finl;
596 + data_ = new double[size];
599 + Cerr << "impossible d'allouer " << size << "double " << finl;
605 + case ArrOfDouble::SIMD_ALIGNED:
608 + data_ = (double*) simd_malloc (sizeof(double) * size);
610 + Cerr<<"unable to allocate simd_aligned, version compiled without simd "<<finl;
620 + storage_ = storage;
621 + assert(data_ != 0);
625 +// Detruit la zone de memoire allouee.
627 +// ref_count == 0 (la zone de memoire ne doit etre referencee nulle part)
628 +VDoubledata::~VDoubledata()
630 + assert(ref_count_ == 0);
632 + // Stockage STANDARD
635 + case ArrOfDouble::STANDARD:
638 + case ArrOfDouble::SIMD_ALIGNED:
642 + Cerr<<"unable to allocate simd_aligned, version compiled without simd "<<finl;
650 + data_ = 0; // paranoia: si size_==-1 c'est qu'on pointe sur un zombie
651 + size_ = -1; // (pointeur vers un objet qui a ete detruit)
652 + storage_ = ArrOfDouble::STANDARD;
655 +// Description: renvoie ref_count_
656 +inline entier VDoubledata::ref_count() const
661 +// Description: renvoie size_
662 +inline entier VDoubledata::get_size() const
668 +// Un nouveau tableau utilise cette zone memoire :
669 +// incremente ref_count
671 +// Signification: ref_count
672 +inline entier VDoubledata::add_one_ref()
674 + return ++ref_count_;
678 +// Un tableau de moins utilise cette zone memoire
679 +// decremente ref_count
683 +// Signification: ref_count
684 +inline entier VDoubledata::suppr_one_ref()
686 + assert(ref_count_ > 0);
687 + return (--ref_count_);
690 +// Description: renvoie data_
691 +inline double * VDoubledata::get_data()
696 +// Description: renvoie data_
697 +inline const double * VDoubledata::get_data() const
702 +// Description: Constructeur par copie. Interdit : genere une erreur !
703 +VDoubledata::VDoubledata(const VDoubledata& v)
705 + Cerr << "Erreur dans VDoubledata::VDoubledata(const VDoubledata & v)" << finl;
709 +// Description: Operateur= interdit. Genere une erreur !
710 +VDoubledata& VDoubledata::operator=(const VDoubledata& v)
712 + Cerr << "Erreur dans VDoubledata::operator=(const VDoubledata & v)" << finl;
717 +// ******************************************************************
719 +// Implementation des methodes de ArrOfDouble
721 +// ******************************************************************
724 +// Definition des constantes pour les options de memory_resize
725 +const entier ArrOfDouble::COPY_OLD = 1;
726 +const entier ArrOfDouble::INITIALIZE_NEW = 2;
729 +// Destructeur : appelle detach_array()
730 +ArrOfDouble::~ArrOfDouble()
733 + size_array_ = -1; // Paranoia: si size_array_==-1, c'est un zombie
737 +// Constructeur par defaut: cree un tableau "detache",
738 +// soit p_==0, data_==0, size_array_==0, smart_resize_==0
739 +ArrOfDouble::ArrOfDouble() :
745 + storage_type_(STANDARD)
750 +// Cree un tableau de taille n avec allocation standard
751 +// (voir set_mem_storage).
752 +// Valeur de remplissage par defaut: voir fill_default_value
754 +// Parametre: entier n
755 +// Signification: taille du tableau
756 +ArrOfDouble::ArrOfDouble(entier n) :
757 + p_(new VDoubledata(n, STANDARD)),
758 + data_(p_->get_data()),
762 + storage_type_(STANDARD)
765 + fill_default_value(0, n);
769 +// Cree un tableau de taille n
770 +// toutes les cases sont initialisees a x
772 +// Parametre: entier n
773 +// Signification: taille du tableau
774 +// Parametre: double x
775 +// Signification: valeur pour initialiser le tableau
776 +ArrOfDouble::ArrOfDouble(entier n, double x) :
777 + p_(new VDoubledata(n, STANDARD)),
778 + data_(p_->get_data()),
782 + storage_type_(STANDARD)
788 +// Constructeur par copie. On alloue une nouvelle zone de memoire
789 +// et on copie le contenu du tableau. L'attribut smart_resize_ est
791 +// Si le tableau A est de taille nulle, on cree un tableau "detache",
792 +// sinon on cree un tableau "normal".
793 +// Parametre: const ArrOfDouble& A
794 +// Signification: le tableau a copier
795 +ArrOfDouble::ArrOfDouble(const ArrOfDouble& A)
797 + const entier size = A.size_array();
800 + // Creation d'un tableau "normal"
801 + storage_type_ = STANDARD;
802 + p_ = new VDoubledata(size, STANDARD);
803 + data_ = p_->get_data();
804 + size_array_ = size;
805 + memory_size_ = size;
806 + smart_resize_ = A.smart_resize_;
811 + // Creation d'un tableau "detache"
817 + storage_type_ = STANDARD;
822 +// Change le mode d'allocation memoire lors des resize
823 +// (voir VDoubledata et Double_ptr_trav)
824 +// Exemple pour creer un tableau avec allocation temporaire:
825 +// DoubleTab tab; // Creation d'un tableau vide
826 +// tab.set_mem_storage(TEMP_STORAGE); // Changement de mode d'allocation
827 +// tab.resize(n); // Allocation memoire
828 +void ArrOfDouble::set_mem_storage(const Storage storage)
830 + storage_type_ = storage;
834 +// Renvoie le mode d'allocation du tableau (qui sera utilise
835 +// lors du prochain resize si changement de taille).
836 +// (voir VDoubledata et Double_ptr_trav)
837 +enum ArrOfDouble::Storage ArrOfDouble::get_mem_storage() const
839 + return storage_type_;
843 +// Change le mode l'allocation memoire: reallocation d'un tableau
844 +// a chaque changement de taille (flag = 0) ou reallocation
845 +// uniquement si la taille augmente et par doublement de la taille
846 +// du tableau (flag = 1).
847 +void ArrOfDouble::set_smart_resize(entier flag)
849 + assert(flag == 0 || flag == 1);
850 + smart_resize_ = flag;
854 +// Remet le tableau dans l'etat obtenu avec le constructeur par defaut
855 +// (libere la memoire mais conserve le mode d'allocation memoire actuel)
856 +void ArrOfDouble::reset()
862 +// Copie les donnees du tableau m.
863 +// Si "m" n'a pas la meme taille que "*this", on fait un resize_array.
864 +// Ensuite, on copie les valeurs de "m" dans "*this".
865 +// Le type de tableau (methode d'allocation) n'est pas copie.
867 +// Si le tableau n'a pas la meme taille que "m", alors *this doit
868 +// etre "resizable" (ne pas etre de type "ref_data" et "ref_count == 1")
869 +// Parametre: const ArrOfDouble& m
870 +// Signification: la tableau a copier
871 +// Retour: ArrOfDouble&
872 +// Signification: *this
873 +ArrOfDouble& ArrOfDouble::operator=(const ArrOfDouble& m)
877 + const entier new_size = m.size_array();
878 + // Le code suivant est quasiment une copie de ArrOfDouble::resize()
879 + // SAUF: memory_resize est appele avec NO_INITIALIZE (la zone de memoire
880 + // n'est pas initialisee)
881 + if (new_size != size_array())
883 + if ((smart_resize_ == 0) || (new_size > memory_size_))
884 + memory_resize(new_size, 0); // Pas d'initialisation
885 + size_array_ = new_size;
894 +// x est affecte a toutes les cases
896 +// Parametre: double x
897 +// Signification: la valeur a affecter a toutes les cases du tableau
898 +// Valeurs par defaut:
901 +// Retour: ArrOfDouble&
902 +// Signification: *this
907 +ArrOfDouble& ArrOfDouble::operator=(double x)
909 + const entier n = size_array();
910 + double *data = addr();
911 + for (entier i = 0; i < n; i++)
918 +// Description: appelle operator=(a)
919 +ArrOfDouble& ArrOfDouble::copy_array(const ArrOfDouble& a)
926 +// Si besoin, alloue une nouvelle zone de memoire,
927 +// copie les donnees et efface l'ancienne zone de memoire.
928 +// Attention, on suppose que cette methode est appelee par
930 +// Attention: si ref_count_>1, l'appel a resize_array() est
931 +// autorise uniquement si la nouvelle taille est identique
934 +// Le tableau doit etre de type "detache" ou "normal" avec
935 +// ref_count==1, et il faut new_size >= 0
936 +// On suppose que size_array contient encore le nombre d'elements
937 +// valides avant changement de taille.
938 +// Parametre: new_size
939 +// Signification: nouvelle taille demandee pour le tableau.
940 +// Parametre: options
941 +// Signification: COPY_OLD => on recopie les anciennes donnees dans le nouveau
942 +// tableau (jusqu'au max de l'ancienne et de la nouvelle taille).
943 +// INITIALIZE_NEW => initialisation des cases non copiees
945 +// p_ et data_ sont mis a jour, mais pas size_array_ !!!
946 +// (on suppose que c'est fait dans resize_array()).
947 +// Si la nouvelle taille est nulle, on detache le tableau.
948 +void ArrOfDouble::memory_resize(entier new_size, entier options)
950 + assert(new_size >= 0);
952 + // Occupation memoire de l'ancien tableau:
953 + entier old_mem_size = 0;
955 + old_mem_size = p_->get_size();
957 + // Occupation memoire du nouveau tableau :
958 + // Si smart_resize, on prend au moins deux fois la taille
959 + // precedente, ou new_size
960 + entier new_mem_size = new_size;
961 + if (smart_resize_ && (old_mem_size * 2 > new_size))
962 + new_mem_size = old_mem_size * 2;
964 + if (new_mem_size != old_mem_size)
966 + // detach_array() efface le contenu de size_array_. On le met de cote:
967 + const entier old_size_array = size_array_;
968 + // On va reellement changer l'adresse du tableau.
969 + // Il ne faut pas qu'il existe d'autre reference a ce tableau.
970 + assert(data_ == 0 || (p_ != 0 && ref_count() == 1));
971 + if (new_mem_size == 0)
973 + // La nouvelle taille est nulle, on cree un tableau "detache"
978 + // Allocation d'une nouvelle zone
979 + VDoubledata * new_p = new VDoubledata(new_mem_size, storage_type_);
980 + double * new_data = new_p->get_data();
981 + // Raccourci si le tableau etait "detache", inutile de copier
982 + // les anciennes donnees. On copie si COPY_OLD est demande
983 + entier copy_size = 0;
986 + // Calcul du nombre d'elements a copier vers la nouvelle
987 + // zone de memoire : c'est le min de l'ancienne et de
988 + // la nouvelle taille.
989 + if (options & COPY_OLD)
991 + copy_size = size_array_;
992 + if (new_size < copy_size)
993 + copy_size = new_size;
994 + // Copie des valeurs dans le nouveau tableau
995 + for (entier i = 0; i < copy_size; i++)
996 + new_data[i] = data_[i];
998 + // Destruction de l'ancienne zone (si plus aucune reference)
1001 + // On attache la nouvelle zone de memoire
1004 + memory_size_ = new_mem_size;
1005 + // Initialisation des cases supplementaires avec une valeur par defaut
1006 + if (options & INITIALIZE_NEW)
1007 + fill_default_value(copy_size, new_mem_size - copy_size);
1008 + // Restaure l'ancienne valeur de size_array_
1009 + size_array_ = old_size_array;
1015 +// Remplit "nb" cases consecutives du tableau a partir de la case "first"
1016 +// avec une valeur par defaut.
1017 +// Cette fonction est appelee lors d'un resize pour initialiser les
1018 +// cases nouvellement creees.
1019 +// Le comportement depend actuellement du type de tableau :
1020 +// * Tableau de type "smart_resize":
1021 +// * en mode debug (macro NDEBUG non definie) le tableau est initialise
1022 +// avec une valeur invalide.
1023 +// * en optimise, le tableau n'est pas initialise
1024 +// * Tableau normal :
1025 +// Le tableau est initialise avec la valeur 0. Ce comportement est choisi
1026 +// pour des raisons de compatibilite avec l'implementation precedente.
1027 +// Cette specification pourrait etre modifiee prochainement pour des raisons
1028 +// de performances (pour ne pas avoir a initialiser inutilement les tableaux).
1029 +// DONC: il faut supposer desormais que les nouvelles cases ne sont pas
1030 +// initialisees lors d'un resize.
1031 +// Parametre: first
1032 +// Signification: premiere case a initialiser.
1033 +// Contrainte: (nb==0) ou (0 <= first < memory_size_)
1035 +// Signification: nombre de cases a initialiser.
1036 +// Contrainte: (nb==0) ou (0 < nb <= memory_size_ - first)
1037 +void ArrOfDouble::fill_default_value(entier first, entier nb)
1039 + assert((nb == 0) || (first >= 0 && first < memory_size_));
1040 + assert((nb == 0) || (nb > 0 && nb <= memory_size_ - first));
1041 + double * data = addr();
1042 + assert(data!=0 || nb==0);
1044 + if (smart_resize_)
1047 + // On initialise uniquement en mode debug
1049 + // Ceci represente un NAN. N'importe quelle operation avec ca fait encore un NAN.
1050 + // Si c'est pas portable, on peut remplacer par DMAX_FLOAT sur les autres machines.
1051 + static const unsigned long long VALEUR_INVALIDE =
1052 + 0x7ff7ffffffffffffULL;
1054 + // On utilise "memcpy" et non "=" car "=" peut provoquer une exception
1055 + // si la copie passe par le fpu.
1056 + for (entier i = 0; i < nb; i++)
1057 + memcpy(data + i, & VALEUR_INVALIDE, sizeof(double));
1063 + // Comportement pour les tableaux normaux : compatibilite avec la
1064 + // version precedente : on initialise avec 0.
1065 + for (entier i = 0; i < nb; i++)
1066 + data[i] = (double) 0;
1070 +// ****************************************************************
1072 +// Fonctions non membres de la classe ArrOfDouble
1074 +// ****************************************************************
1077 +// Renvoie 1 si les tableaux "v" et "a" sont de la meme taille
1078 +// et contiennent les memes valeurs au sens strict, sinon renvoie 0.
1079 +// Le test est !(v[i]!=a[i])
1080 +entier operator==(const ArrOfDouble& v, const ArrOfDouble& a)
1082 + const entier n = v.size_array();
1083 + const entier na = a.size_array();
1091 + const double* vv = v.addr();
1092 + const double* av = a.addr();
1094 + for (i = 0; i < n; i++)
1096 + if (av[i] != vv[i])
1107 +// Retourne l'indice du min ou -1 si le tableau est vide
1109 +// Parametre: const ArrOfDouble& dx
1110 +// Signification: tableau a utiliser
1112 +// Signification: indice du min
1113 +entier imin_array(const ArrOfDouble& dx)
1115 + entier indice_min = -1;
1116 + const entier size = dx.size_array();
1120 + double valeur_min = dx[0];
1121 + for(entier i = 1; i < size; i++)
1123 + const double val = dx[i];
1124 + if(val < valeur_min)
1131 + return indice_min;
1135 +// Retourne l'indice du max ou -1 si le tableau est vide
1137 +// Parametre: const ArrOfDouble& dx
1138 +// Signification: tableau a utiliser
1140 +// Signification: indice du max
1141 +entier imax_array(const ArrOfDouble& dx)
1143 + entier indice_max = -1;
1144 + const entier size = dx.size_array();
1148 + double valeur_max = dx[0];
1149 + for(entier i = 1; i < size; i++)
1151 + const double val = dx[i];
1152 + if(val > valeur_max)
1159 + return indice_max;
1163 +// Retourne la valeur minimale
1165 +// Le tableau doit contenir au moins une valeur
1166 +// Parametre: const ArrOfDouble& dx
1167 +// Signification: tableau a utiliser
1169 +// Signification: valeur du min
1170 +double min_array(const ArrOfDouble& dx)
1172 + const entier size = dx.size_array();
1174 + double valeur_min = dx[0];
1175 + for(entier i = 1; i < size; i++)
1177 + const double val = dx[i];
1178 + if (val < valeur_min)
1181 + return valeur_min;
1185 +// Retourne la valeur maximale
1187 +// Le tableau doit contenir au moins une valeur
1188 +// Parametre: const ArrOfDouble& dx
1189 +// Signification: tableau a utiliser
1191 +// Signification: valeur du max
1192 +double max_array(const ArrOfDouble& dx)
1194 + const entier size = dx.size_array();
1196 + double valeur_max = dx[0];
1197 + for(entier i = 1; i < size; i++)
1199 + const double val = dx[i];
1200 + if (val > valeur_max)
1203 + return valeur_max;
1207 +// Fonction de comparaison utilisee pour trier le tableau
1208 +// dans ArrOfDouble::trier(). Voir man qsort
1209 +static int fonction_compare_arrofdouble_ordonner(const void * data1, const void * data2)
1211 + const double x = *(const double*)data1;
1212 + const double y = *(const double*)data2;
1222 +// Tri des valeurs du tableau dans l'ordre croissant.
1223 +// La fonction utilisee est qsort de stdlib (elle est en n*log(n)).
1224 +void ArrOfDouble::ordonne_array()
1226 + const entier size = size_array();
1229 + double * data = addr();
1230 + qsort(data, size, sizeof(double),
1231 + fonction_compare_arrofdouble_ordonner);
1236 +// Fait pointer le tableau vers les memes donnees qu'un tableau
1237 +// existant. Le tableau sera du meme type que le tableau m ("detache",
1238 +// "normal"). Le tableau m ne doit pas etre de type "ref_data"
1239 +// Les donnes existantes sont perdues si elles
1240 +// ne sont pas referencees ailleurs.
1242 +// Parametre: const ArrOfDouble& m
1243 +// Signification: le tableau a referencer (pas de type "ref_data"
1244 +// et different de *this !!!)
1245 +// Retour: ArrOfDouble&
1246 +// Signification: *this
1251 +ArrOfDouble& ArrOfDouble::ref_array(const ArrOfDouble& m)
1253 + assert(&m != this);
1254 + // La condition 'm n'est pas de type "ref_data"' est necessaire pour
1255 + // attach_array().
1262 +// Fait pointer le tableau vers la zone de memoire "data_".
1263 +// On detache la zone de memoire existante. Le tableau devient
1264 +// de type "ref_data". Attention : ptr doit etre non nul.
1265 +// La taille est initialisee avec size.
1266 +// Cette methode est appelee notamment par DoubleVect::adopter.
1267 +// Parametre: double*
1268 +// Signification: le tableau a recuperer. Si pointeur nul alors size
1269 +// doit etre nulle aussi et le tableau reste detache
1270 +// Parametre: entier size
1271 +// Signification: le nombre d'elements du tableau.
1272 +// Retour: ArrOfDouble&
1273 +// Signification: *this
1274 +ArrOfDouble& ArrOfDouble::ref_data(double* ptr, entier size)
1276 + assert(ptr != 0 || size == 0);
1277 + assert(size >= 0);
1280 + size_array_ = size;
1285 +// Amene le tableau dans l'etat "detache". C'est a dire:
1286 +// Si le tableau est "detache" :
1288 +// Si le tableau est "normal" :
1289 +// * decremente le nombre de references a *p
1290 +// * detruit *p si p->ref_count==0
1291 +// * annule p_, data_ et size_array_
1292 +// Si le tableau est "ref_data" :
1293 +// * annule data_ et size_array_
1295 +// Signification: 1 si les donnees du tableau ont ete supprimees
1298 +// On a p_==0, data_==0 et size_array_==0, memory_size_ = 0
1299 +// L'attribut smart_resize_ est conserve.
1300 +entier ArrOfDouble::detach_array()
1302 + entier retour = 0;
1305 + // Le tableau est de type "normal"
1306 + // Si la zone de memoire n'est plus utilisee par personne,
1308 + if ((p_->suppr_one_ref()) == 0)
1322 +// Amene le tableau dans l'etat "normal", "detache" ou "ref_array"
1323 +// en associant la meme zone de memoire que le tableau m.
1325 +// Le tableau doit etre "detache"
1326 +// Parametre: const ArrOfDouble& m
1327 +// Signification: tableau a utiliser
1328 +// le tableau doit etre different de *this !!!
1335 +// Si m est detache, le tableau reste detache,
1336 +// si m est "ref_array", le tableau devient "ref_array",
1337 +// sinon le tableau est "normal", avec ref_count > 1
1338 +// Si m est de taille nulle, le tableau reste detache + Warning dans fichier .log
1339 +void ArrOfDouble::attach_array(const ArrOfDouble& m)
1341 + // Le tableau doit etre detache
1342 + assert(data_ == 0 && p_ == 0);
1343 + // Le tableau doit etre different de *this
1344 + assert(&m != this);
1346 + if (m.size_array() > 0)
1350 + p_->add_one_ref();
1352 + size_array_ = m.size_array_;
1353 + memory_size_ = m.memory_size_;
1354 + smart_resize_ = m.smart_resize_;
1358 + // Cas particulier ou on attache un tableau de taille nulle:
1359 + // en theorie, c'est pareil qu'un tableau de taille non nulle, MAIS
1360 + // dans les operateurs (ex:Op_Dift_VDF_Face_Axi), une ref est construite
1361 + // avant que le tableau ne prenne sa taille definitive. Donc, pour ne pas
1362 + // empecher le resize, il ne faut pas attacher le tableau s'il n'a pas
1363 + // encore la bonne taille. Solution propre: reecrire les operateurs pour
1364 + // qu'ils ne prennent pas une ref avant que le tableau ne soit valide
1365 + // et faire p_ = m.p_ dans tous les cas.
1370 +// Copie les elements source[first_element_source + i]
1371 +// dans les elements (*this)[first_element_dest + i] pour 0 <= i < nb_elements
1372 +// Les autres elements de (*this) sont inchanges.
1374 +// Parametre: const ArrOfDouble& m
1375 +// Signification: le tableau a utiliser, doit etre different de *this !
1376 +// Parametre: entier nb_elements
1377 +// Signification: nombre d'elements a copier, nb_elements >= -1.
1378 +// Si nb_elements==-1, on copie tout le tableau m.
1379 +// Valeurs par defaut: -1
1380 +// Parametre: entier first_element_dest
1381 +// Valeurs par defaut: 0
1382 +// Parametre: entier first_element_source
1383 +// Valeurs par defaut: 0
1384 +// Retour: ArrOfDouble&
1385 +// Signification: *this
1388 +// Sort en erreur si la taille du tableau m est plus grande que la
1389 +// taille de tableau this.
1392 +ArrOfDouble& ArrOfDouble::inject_array(const ArrOfDouble& source,
1393 + entier nb_elements,
1394 + entier first_element_dest,
1395 + entier first_element_source)
1397 + assert(&source != this);
1398 + assert(nb_elements >= -1);
1399 + assert(first_element_dest >= 0);
1400 + assert(first_element_source >= 0);
1402 + if (nb_elements < 0)
1403 + nb_elements = source.size_array();
1405 + assert(first_element_source + nb_elements <= source.size_array());
1406 + assert(first_element_dest + nb_elements <= size_array());
1408 + if (nb_elements > 0)
1410 + double * addr_dest = addr() + first_element_dest;
1411 + const double * addr_source = source.addr() + first_element_source;
1412 + // memcpy(addr_dest , addr_source, nb_elements * sizeof(double));
1414 + for (i = 0; i < nb_elements; i++)
1416 + addr_dest[i] = addr_source[i];
1423 +// Retourne le nombre de references des donnees du tableau
1424 +// si le tableau est "normal", -1 s'il est "detache" ou "ref_data"
1426 +// Signification: ref_count_
1427 +entier ArrOfDouble::ref_count() const
1430 + return p_->ref_count();
1436 +// Addition case a case sur toutes les cases du tableau
1438 +// la taille de y doit etre au moins egale a la taille de this
1439 +// Parametre: const ArrOfDouble& y
1440 +// Signification: tableau a ajouter
1441 +// Valeurs par defaut:
1444 +// Retour: ArrOfDouble&
1445 +// Signification: *this
1450 +ArrOfDouble& ArrOfDouble::operator+=(const ArrOfDouble& y)
1452 + assert(size_array()==y.size_array());
1453 + double* dx = addr();
1454 + const double* dy = y.addr();
1455 + const entier n = size_array();
1456 + for (entier i=0; i<n; i++)
1462 +// ajoute la meme valeur a toutes les cases du tableau
1464 +// Parametre: const double dy
1465 +// Signification: valeur a ajouter
1466 +// Valeurs par defaut:
1469 +// Retour: ArrOfDouble
1470 +// Signification: *this
1475 +ArrOfDouble& ArrOfDouble::operator+=(const double dy)
1477 + double * data = addr();
1478 + const entier n = size_array();
1479 + for(entier i=0; i < n; i++)
1484 +// Soustraction case a case sur toutes les cases du tableau
1485 +// Parametre: const ArrOfDouble& y
1486 +// Signification: tableau de meme taille que *this
1487 +// Retour: ArrOfDouble&
1488 +// Signification: *this
1489 +ArrOfDouble& ArrOfDouble::operator-=(const ArrOfDouble& y)
1491 + const entier size = size_array();
1492 + assert(size == y.size_array());
1493 + double * data = addr();
1494 + const double * data_y = y.addr();
1495 + for (entier i=0; i < size; i++)
1496 + data[i] -= data_y[i];
1502 +// soustrait la meme valeur a toutes les cases
1503 +// Retour: ArrOfDouble &
1504 +// Signification: *this
1505 +ArrOfDouble& ArrOfDouble::operator-=(const double dy)
1507 + double * data = addr();
1508 + const entier n = size_array();
1509 + for(entier i=0; i < n; i++)
1515 +// Renvoie un pointeur sur le premier element du tableau.
1516 +// Le pointeur est nul si le tableau est "detache".
1517 +// Attention, l'adresse peut changer apres un appel
1518 +// a resize_array(), ref_data, ref_array, ...
1520 +// Retour: const double*
1521 +// Signification: pointeur sur le premier element du tableau
1522 +const double* ArrOfDouble::addr() const
1528 +// Renvoie un pointeur sur le premier element du tableau.
1529 +// Le pointeur est nul si le tableau est "detache".
1531 +// Retour: const double*
1532 +// Signification: la zone memoire du tableau
1533 +double* ArrOfDouble::addr()
1540 +// Retourne le max des abs(i)
1542 +// Le tableau doit contenir au moins une valeur
1543 +// Parametre: const ArrOfDouble& dx
1544 +// Signification: tableau a utiliser
1545 +// Valeurs par defaut:
1549 +// Signification: valeur du max des valeurs absolues
1554 +double max_abs_array(const ArrOfDouble& dx)
1556 + const entier size = dx.size_array();
1558 + double valeur_max = fabs(dx[0]);
1559 + for(entier i = 1; i < size; i++)
1561 + const double val = fabs(dx[i]);
1562 + if (val > valeur_max)
1565 + return valeur_max;
1569 +// muliplie toutes les cases par dy
1570 +// Retour: ArrOfDouble &
1571 +// Signification: *this
1572 +ArrOfDouble& ArrOfDouble::operator*= (const double dy)
1574 + double * data = addr();
1575 + const entier n = size_array();
1576 + for(entier i=0; i < n; i++)
1583 +// divise toutes les cases par dy
1584 +// Retour: ArrOfDouble &
1585 +// Signification: *this
1586 +ArrOfDouble& ArrOfDouble::operator/= (const double dy)
1588 + // En theorie: les deux lignes suivantes sont plus efficaces, mais
1589 + // cela produit des differences sur certains cas tests
1590 + // (Hyd_C_VEF_Smago et Lambda_var_VEF_turb). Ca veut dire qu'il y
1591 + // a un probleme autre part mais pour l'instant on laisse l'ancien
1593 + // const double i_dy = 1. / dy;
1594 + // operator*=(i_dy);
1596 + double * data = addr();
1597 + const entier n = size_array();
1598 + for(entier i=0; i < n; i++)
1604 +DoubleTab::DoubleTab()
1607 + dimensions_[0] = 0;
1608 + dimensions_[1] = 0;
1611 +DoubleTab::DoubleTab(const DoubleTab& tab) :
1614 + // nb_dim_ = tab.nb_dim_;
1615 + dimensions_[0] = tab.dimensions_[0];
1616 + dimensions_[1] = tab.dimensions_[1];
1618 +DoubleTab::DoubleTab(const entier i, const entier j) :
1622 + dimensions_[0] = i;
1623 + dimensions_[1] = j;
1626 +DoubleTab& DoubleTab::operator=(const DoubleTab& tab)
1628 + ArrOfDouble::operator=(tab);
1629 + // nb_dim_ = tab.nb_dim_;
1630 + dimensions_[0] = tab.dimensions_[0];
1631 + dimensions_[1] = tab.dimensions_[1];
1635 +void DoubleTab::reset()
1637 + ArrOfDouble::reset();
1639 + dimensions_[0] = 0;
1640 + dimensions_[1] = 0;
1643 diff --git a/databases/readers/Lata/ArrOfDouble.h b/databases/readers/Lata/ArrOfDouble.h
1644 new file mode 100644
1645 index 0000000..fcc08f1
1647 +++ b/databases/readers/Lata/ArrOfDouble.h
1649 +/*****************************************************************************
1651 +* Copyright (c) 2011 - 2013, CEA
1652 +* All rights reserved.
1653 +* Redistribution and use in source and binary forms, with or without
1654 +* modification, are permitted provided that the following conditions are met:
1656 +* * Redistributions of source code must retain the above copyright
1657 +* notice, this list of conditions and the following disclaimer.
1658 +* * Redistributions in binary form must reproduce the above copyright
1659 +* notice, this list of conditions and the following disclaimer in the
1660 +* documentation and/or other materials provided with the distribution.
1661 +* * Neither the name of CEA, nor the
1662 +* names of its contributors may be used to endorse or promote products
1663 +* derived from this software without specific prior written permission.
1665 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
1666 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1667 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1668 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
1669 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1670 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1671 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1672 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1673 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1674 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1676 +*****************************************************************************/
1678 +////////////////////////////////////////////////////////////
1680 +// Warning : DO NOT EDIT !
1681 +// Please update ArrOf_Scalar_Prototype.h.P
1682 +// and this file will be generated automatically
1683 +// by the script file check.sh
1684 +////////////////////////////////////////////////////////////
1686 +#ifndef ArrOfDouble_H
1687 +#define ArrOfDouble_H
1689 +#include <assert.h>
1691 +#include <Objet_U.h>
1693 +#if ! defined(DMAXFLOAT)
1694 +#define DMAXFLOAT 1e40
1705 + virtual ~ArrOfDouble();
1710 + ArrOfDouble(entier size);
1711 + ArrOfDouble(entier size, double initial_value);
1712 + // Constructeur par copie : deep copy (on duplique les donnees)
1713 + ArrOfDouble(const ArrOfDouble& );
1715 + // Methodes de construction tardive (on cree un tableau vide avec ArrOfDouble()
1716 + // puis on appelle ces methodes pour modifier les caracteristiques du tableau :
1718 + // Change le nombre d'elements du tableau
1719 + inline ArrOfDouble& resize_array(entier new_size);
1721 + // Methodes de gestion de l'allocation memoire:
1722 + // Assigne une valeur au drapeau "smart_resize"
1723 + // (reallocation uniquement si la taille augmente)
1724 + void set_smart_resize(entier flag);
1725 + // Gestion du type de memoire alouee (standard ou pool de memoire Trio-U)
1726 + enum Storage { STANDARD, TEMP_STORAGE, SIMD_ALIGNED };
1727 + void set_mem_storage(const Storage storage);
1728 + Storage get_mem_storage() const;
1730 + // Construction de tableaux qui pointent vers des donnees existantes
1731 + // !!! Utiliser ref_data avec precaution (attention a size_array_)
1732 + ArrOfDouble& ref_data(double* ptr, entier size);
1733 + ArrOfDouble& ref_array(const ArrOfDouble&);
1734 + // Operateur copie
1735 + ArrOfDouble& operator=(const ArrOfDouble&);
1736 + // Remise du tableau dans l'etat initial (obtenu par le constructeur par defaut)
1737 + virtual void reset();
1740 + // Methodes d'acces aux donnees et aux caracteristiques du tableau
1742 + // Remplit le tableau avec la valeur en parametre
1743 + ArrOfDouble& operator=(double valeur);
1745 + inline double& operator[](entier i);
1746 + inline const double& operator[](entier i) const;
1748 + // Ces methodes renvoient un pointeur vers le premier element du tableau.
1749 + const double * addr() const;
1751 + // Renvoie le nombre d'elements du tableau (et non la taille allouee)
1752 + inline entier size_array() const;
1753 + // Renvoie le nombre de tableaux qui pointent vers la stucture "*p_"
1754 + entier ref_count() const;
1755 + // Ajoute une case en fin de tableau et y stocke la "valeur"
1756 + inline void append_array(double valeur);
1759 + // Operateurs divers
1761 + ArrOfDouble& operator+=(const ArrOfDouble&);
1762 + ArrOfDouble& operator+=(const double);
1763 + ArrOfDouble& operator-=(const ArrOfDouble&);
1764 + ArrOfDouble& operator-=(const double);
1765 + ArrOfDouble& inject_array(const ArrOfDouble& source,
1766 + entier nb_elements = -1,
1767 + entier first_element_dest = 0,
1768 + entier first_element_source = 0);
1769 + ArrOfDouble& copy_array(const ArrOfDouble&);
1771 + ArrOfDouble& operator*= (const double) ;
1772 + ArrOfDouble& operator/= (const double) ;
1774 + void ordonne_array();
1778 + // Methodes accessibles depuis les descendants de ArrOfDouble
1780 + void attach_array(const ArrOfDouble&);
1781 + entier detach_array();
1782 + void fill_default_value(entier first, entier nb);
1784 + // B. Mathieu 22/06/2004 : je mets ces membres "private" pour forcer
1785 + // le passage par les accesseurs dans les classes derivees, au cas ou
1786 + // on voudrait modifier l'implementation.
1788 + // Zone de memoire contenant les valeurs du tableau.
1789 + // Pointeur nul => le tableau est "detache" ou "ref_data"
1790 + // Pointeur non nul => le tableau est "normal"
1793 + // Pointeur vers le premier element du tableau (egal a p_->data si p_!=0)
1794 + // Pointeur nul => le tableau est "detache".
1795 + // Pointeur non nul => le tableau est "normal" ou "ref_data"
1798 + // Nombre d'elements du tableau (inferieur ou egal a memory_size_).
1799 + // Si le tableau est "detache", alors size_array_=0
1800 + entier size_array_;
1801 + // Taille memoire reellement allouee pour le tableau
1802 + // (pour le mecanisme smart_resize_). memory_size_ est nul
1803 + // si le tableau est de type "ref_data". Sinon memory_size_
1804 + // est egal a p_->size_.
1805 + entier memory_size_;
1807 + // Drapeau indiquant si on applique une strategie d'allocation
1808 + // preventive (la memoire alouee augmente d'un facteur constant
1809 + // si la taille devient insuffisante).
1810 + // Si smart_resize_ == 0, alors on a toujours p_->size_ == size
1811 + entier smart_resize_;
1813 + // Drapeau indiquant si l'allocation memoire a lieu avec un new classique
1814 + // ou dans le pool de memoire temporaire de Trio
1815 + Storage storage_type_;
1817 + // Partie non inline de resize_array():
1818 + // Declaration des constantes pour les options de memory_resize
1819 + static const entier COPY_OLD;
1820 + static const entier INITIALIZE_NEW;
1821 + void memory_resize(entier new_size, entier options);
1824 +#define MAXDIMDoubleTab 2
1826 +class DoubleTab : public ArrOfDouble
1830 + DoubleTab(const DoubleTab&);
1831 + DoubleTab(const entier i, const entier j);
1832 + DoubleTab& operator=(const DoubleTab&);
1835 + inline double& operator()(entier i, entier j);
1836 + inline double operator()(entier i, entier j) const;
1838 + inline entier resize(entier i, entier j);
1839 + inline entier dimension(entier i) const;
1840 + inline entier dimension_tot(entier i) const;
1843 + // In order to mimic TRUST behavior, operator[] is forbidden
1844 + // for 2 dimensionnal matrices, you must cast to ArrOf to use it..
1845 + double& operator[](entier i);
1846 + const double& operator[](entier i) const;
1849 + // entier nb_dim_;
1850 + entier dimensions_[MAXDIMDoubleTab];
1853 +inline double& DoubleTab::operator()(entier i, entier j)
1855 + // assert(nb_dim_ == 2);
1856 + assert(i >= 0 && i < dimensions_[0] && j >= 0 && j < dimensions_[1]);
1857 + const entier n = i * dimensions_[1] + j;
1858 + double& x = ArrOfDouble::operator[] (n);
1862 +inline double DoubleTab::operator()(entier i, entier j) const
1864 + // assert(nb_dim_ == 2);
1865 + assert(i >= 0 && i < dimensions_[0] && j >= 0 && j < dimensions_[1]);
1866 + const entier n = i * dimensions_[1] + j;
1867 + double x = ArrOfDouble::operator[] (n);
1871 +inline entier DoubleTab::resize(entier i, entier j)
1873 + assert(i >= 0 && j >= 0);
1875 + dimensions_[0] = i;
1876 + dimensions_[1] = j;
1877 + ArrOfDouble::resize_array(i * j);
1881 +inline entier DoubleTab::dimension(entier i) const
1883 + assert(i >= 0 && i < 2);
1884 + return dimensions_[i];
1887 +// Description: renvoie la meme valeur que dimension.
1888 +inline entier DoubleTab::dimension_tot(entier i) const
1890 + return dimension(i);
1894 +// Declarations des fonctions non membres de la classe ArrOfDouble
1896 +entier operator==(const ArrOfDouble& x, const ArrOfDouble& y) ;
1897 +entier imin_array(const ArrOfDouble&) ;
1898 +entier imax_array(const ArrOfDouble&) ;
1899 +double min_array(const ArrOfDouble&) ;
1900 +double max_array(const ArrOfDouble&) ;
1902 +double max_abs_array(const ArrOfDouble&) ;
1904 +// ******************************************************************
1905 +// FONCTIONS MEMBRES DE ArrOfDouble
1906 +// ******************************************************************
1909 +// Change le nombre d'elements du tableau. Cette fonction est inline
1910 +// car elle doit etre tres rapide dans le cas ou smart_resize_==1
1911 +// (utilisation frequente de resize_array())
1912 +// Si smart_resize est non nul :
1913 +// Si la nouvelle taille est inferieure ou egale a la taille
1914 +// alouee (p->get_size()) on ne realloue pas de memoire
1915 +// sinon, on realloue et on copie les donnees existantes.
1916 +// Astuce pour ne pas copier les anciennes donnees:
1917 +// resize(0); resize(n);
1918 +// Si smart_resize est nul, on realloue une nouvelle zone memoire
1919 +// uniquement si la nouvelle taille est differente de l'ancienne.
1921 +// Si "new_size" est egal a la taille du tableau, aucune condition.
1922 +// Sinon, le tableau doit etre soit detache, soit normal (pas de type "ref_data")
1923 +// et ref_count doit etre egal a 1 (pas d'autre reference au tableau).
1925 +inline ArrOfDouble& ArrOfDouble::resize_array(entier new_size)
1927 + assert(new_size >= 0);
1928 + // Soit le tableau est detache (data_==0), soit il est normal (p_!=0)
1929 + // S'il est normal, il ne faut pas qu'il y ait d'autre reference au tableau,
1930 + // ou alors la taille ne doit pas changer.
1931 + assert(new_size == size_array_ || data_ == 0 || (p_ != 0 && ref_count() == 1));
1933 + if ((smart_resize_ == 0) || (new_size > memory_size_))
1934 + memory_resize(new_size, COPY_OLD + INITIALIZE_NEW);
1935 + size_array_ = new_size;
1940 +// operateur [] retourne le ieme element du tableau
1942 +// Parametre: entier i
1943 +// Signification: indice dans l'intervalle 0 <= i < size_array()
1945 +// assert si la valeur sort de l'intervalle : [ -DMAXFLOAT,DMAXFLOAT ]
1946 +// assert si i n'est pas dans l'intervalle
1947 +inline double& ArrOfDouble::operator[](entier i)
1949 + assert(i >= 0 && i < size_array_);
1950 + assert((smart_resize_==1)|| (data_[i] > -DMAXFLOAT && data_[i] < DMAXFLOAT));
1955 +// operateur [] retourne le ieme element du tableau
1957 +// Parametre: entier i
1958 +// Signification: indice dans l'intervalle 0 <= i < size_array()
1960 +// assert si la valeur sort de l'intervalle : [ -DMAXFLOAT,DMAXFLOAT ]
1961 +// assert si i n'est pas dans l'intervalle
1962 +inline const double& ArrOfDouble::operator[](entier i) const
1964 + assert(i >= 0 && i < size_array_);
1965 + assert(data_[i] > -DMAXFLOAT && data_[i] < DMAXFLOAT);
1970 +// Renvoie la taille du tableau (nombre d'elements declares
1971 +// a la construction ou a resize_array()).
1972 +// C'est le nombre d'elements accessibles a operator[]
1974 +inline entier ArrOfDouble::size_array() const
1976 + return size_array_;
1980 +// Ajoute une case en fin de tableau et y stocke la "valeur"
1982 +// Tableau doit etre de type "smart_resize" (sinon, ecroulement
1983 +// des performances). De plus, le tableau ne doit pas etre "ref_data",
1984 +// et il ne doit pas y avoir plus d'une reference a la zone de
1985 +// memoire pointee (meme precondition que resize_array())
1986 +inline void ArrOfDouble::append_array(double valeur)
1988 + assert(smart_resize_);
1989 + // Soit le tableau est detache (data_==0), soit il est normal (p_!=0)
1990 + // S'il est normal, il ne faut pas qu'il y ait d'autre reference au tableau.
1991 + assert(data_ == 0 || (p_ != 0 && ref_count() == 1));
1993 + if (size_array_+1 > memory_size_)
1994 + memory_resize(size_array_+1, COPY_OLD);
1995 + data_[size_array_] = valeur;
2002 diff --git a/databases/readers/Lata/ArrOfFloat.C b/databases/readers/Lata/ArrOfFloat.C
2003 new file mode 100644
2004 index 0000000..dd59a24
2006 +++ b/databases/readers/Lata/ArrOfFloat.C
2008 +/*****************************************************************************
2010 +* Copyright (c) 2011 - 2013, CEA
2011 +* All rights reserved.
2012 +* Redistribution and use in source and binary forms, with or without
2013 +* modification, are permitted provided that the following conditions are met:
2015 +* * Redistributions of source code must retain the above copyright
2016 +* notice, this list of conditions and the following disclaimer.
2017 +* * Redistributions in binary form must reproduce the above copyright
2018 +* notice, this list of conditions and the following disclaimer in the
2019 +* documentation and/or other materials provided with the distribution.
2020 +* * Neither the name of CEA, nor the
2021 +* names of its contributors may be used to endorse or promote products
2022 +* derived from this software without specific prior written permission.
2024 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
2025 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2026 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2027 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
2028 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2029 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2030 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2031 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2032 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2033 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2035 +*****************************************************************************/
2037 +////////////////////////////////////////////////////////////
2039 +// Warning : DO NOT EDIT !
2040 +// Please update ArrOf_Scalar_Prototype.cpp.h
2041 +// and this file will be generated automatically
2042 +// by the script file check.sh
2043 +////////////////////////////////////////////////////////////
2045 +#include <ArrOfFloat.h>
2047 +#include <stdlib.h>
2048 +#include <Objet_U.h>
2049 +#include <iostream>
2050 +#include <stdlib.h>
2051 +#include <string.h>
2052 +#include "simd_interface.h"
2054 +using namespace std;
2056 +// ******************************************************************
2058 +// Implementation des methodes de VFloatdata
2060 +// ******************************************************************
2061 +////////////////////////////////////////////////////////////////////
2063 +// .ENTETE TRUST Math
2064 +// .LIBRAIRIE libtmath
2065 +// .FILE ArrOfFloat.h
2066 +// .FILE ArrOfFloat.cpp
2069 +// VFloatdata alloue une zone de memoire de la taille specifiee au
2070 +// constructeur, et libere la zone de memoire a la destruction.
2072 +// "ref_count" compte le nombre de pointeurs qui font reference a "this".
2073 +// (permet au dernier utilisateur de l'objet de le detruire), voir
2076 +// .SECTION voir aussi
2081 +///////////////////////////////////////////////////////////////////
2086 + VFloatdata(entier size, ArrOfFloat::Storage storage);
2088 + entier add_one_ref();
2089 + entier suppr_one_ref();
2090 + float * get_data();
2091 + const float * get_data() const;
2092 + inline entier ref_count() const;
2093 + inline entier get_size() const;
2095 + // Le constructeur par copie et l'operateur= sont interdits.
2096 + VFloatdata(const VFloatdata& v);
2097 + VFloatdata& operator=(const VFloatdata& v);
2099 + // "data" est un pointeur sur une zone de memoire de taille
2100 + // sz * sizeof(float), allouee par le
2101 + // constructeur et liberee par le destructeur.
2102 + // Ce pointeur n'est jamais nul meme si size_==0
2104 + // Compteur incremente par add_one_ref et decremente par suppr_one_ref.
2105 + // Contient le nombre d'objets ArrOfFloat dont le membre "p" pointe
2106 + // vers "this". On a ref_count_ >= 0.
2107 + entier ref_count_;
2108 + // "sz" est la taille du tableau "data_" alloue
2111 + ArrOfFloat::Storage storage_;
2116 +// Construit un VFloatdata de taille size >= 0
2117 +// Parametre: entier s
2118 +// Signification: taille du VFloatdata, il faut size >= 0
2119 +// Parametre: Storage storage
2120 +// Signification: indique si la memoire doit etre allouee
2121 +// avec "new" ou avec "simd_malloc"
2122 +// Valeurs par defaut: STANDARD (allocation avec "new")
2124 +// data_ n'est jamais nul, meme si size==0
2125 +VFloatdata::VFloatdata(entier size, ArrOfFloat::Storage storage)
2128 + storage = ArrOfFloat::STANDARD;
2132 + case ArrOfFloat::STANDARD:
2135 + // Allocation de la memoire sur le tas
2138 + data_ = new float[size];
2142 + Cerr << "impossible d'allouer " << size << " float " << finl;
2146 + data_ = new float[size];
2149 + Cerr << "impossible d'allouer " << size << "float " << finl;
2155 + case ArrOfFloat::SIMD_ALIGNED:
2157 +#ifdef SIMD_TOOLS_H
2158 + data_ = (float*) simd_malloc (sizeof(float) * size);
2160 + Cerr<<"unable to allocate simd_aligned, version compiled without simd "<<finl;
2170 + storage_ = storage;
2171 + assert(data_ != 0);
2175 +// Detruit la zone de memoire allouee.
2177 +// ref_count == 0 (la zone de memoire ne doit etre referencee nulle part)
2178 +VFloatdata::~VFloatdata()
2180 + assert(ref_count_ == 0);
2182 + // Stockage STANDARD
2185 + case ArrOfFloat::STANDARD:
2188 + case ArrOfFloat::SIMD_ALIGNED:
2189 +#ifdef SIMD_TOOLS_H
2192 + Cerr<<"unable to allocate simd_aligned, version compiled without simd "<<finl;
2200 + data_ = 0; // paranoia: si size_==-1 c'est qu'on pointe sur un zombie
2201 + size_ = -1; // (pointeur vers un objet qui a ete detruit)
2202 + storage_ = ArrOfFloat::STANDARD;
2205 +// Description: renvoie ref_count_
2206 +inline entier VFloatdata::ref_count() const
2208 + return ref_count_;
2211 +// Description: renvoie size_
2212 +inline entier VFloatdata::get_size() const
2218 +// Un nouveau tableau utilise cette zone memoire :
2219 +// incremente ref_count
2221 +// Signification: ref_count
2222 +inline entier VFloatdata::add_one_ref()
2224 + return ++ref_count_;
2228 +// Un tableau de moins utilise cette zone memoire
2229 +// decremente ref_count
2233 +// Signification: ref_count
2234 +inline entier VFloatdata::suppr_one_ref()
2236 + assert(ref_count_ > 0);
2237 + return (--ref_count_);
2240 +// Description: renvoie data_
2241 +inline float * VFloatdata::get_data()
2246 +// Description: renvoie data_
2247 +inline const float * VFloatdata::get_data() const
2252 +// Description: Constructeur par copie. Interdit : genere une erreur !
2253 +VFloatdata::VFloatdata(const VFloatdata& v)
2255 + Cerr << "Erreur dans VFloatdata::VFloatdata(const VFloatdata & v)" << finl;
2259 +// Description: Operateur= interdit. Genere une erreur !
2260 +VFloatdata& VFloatdata::operator=(const VFloatdata& v)
2262 + Cerr << "Erreur dans VFloatdata::operator=(const VFloatdata & v)" << finl;
2267 +// ******************************************************************
2269 +// Implementation des methodes de ArrOfFloat
2271 +// ******************************************************************
2274 +// Definition des constantes pour les options de memory_resize
2275 +const entier ArrOfFloat::COPY_OLD = 1;
2276 +const entier ArrOfFloat::INITIALIZE_NEW = 2;
2279 +// Destructeur : appelle detach_array()
2280 +ArrOfFloat::~ArrOfFloat()
2283 + size_array_ = -1; // Paranoia: si size_array_==-1, c'est un zombie
2287 +// Constructeur par defaut: cree un tableau "detache",
2288 +// soit p_==0, data_==0, size_array_==0, smart_resize_==0
2289 +ArrOfFloat::ArrOfFloat() :
2295 + storage_type_(STANDARD)
2300 +// Cree un tableau de taille n avec allocation standard
2301 +// (voir set_mem_storage).
2302 +// Valeur de remplissage par defaut: voir fill_default_value
2304 +// Parametre: entier n
2305 +// Signification: taille du tableau
2306 +ArrOfFloat::ArrOfFloat(entier n) :
2307 + p_(new VFloatdata(n, STANDARD)),
2308 + data_(p_->get_data()),
2312 + storage_type_(STANDARD)
2315 + fill_default_value(0, n);
2319 +// Cree un tableau de taille n
2320 +// toutes les cases sont initialisees a x
2322 +// Parametre: entier n
2323 +// Signification: taille du tableau
2324 +// Parametre: float x
2325 +// Signification: valeur pour initialiser le tableau
2326 +ArrOfFloat::ArrOfFloat(entier n, float x) :
2327 + p_(new VFloatdata(n, STANDARD)),
2328 + data_(p_->get_data()),
2332 + storage_type_(STANDARD)
2338 +// Constructeur par copie. On alloue une nouvelle zone de memoire
2339 +// et on copie le contenu du tableau. L'attribut smart_resize_ est
2341 +// Si le tableau A est de taille nulle, on cree un tableau "detache",
2342 +// sinon on cree un tableau "normal".
2343 +// Parametre: const ArrOfFloat& A
2344 +// Signification: le tableau a copier
2345 +ArrOfFloat::ArrOfFloat(const ArrOfFloat& A)
2347 + const entier size = A.size_array();
2350 + // Creation d'un tableau "normal"
2351 + storage_type_ = STANDARD;
2352 + p_ = new VFloatdata(size, STANDARD);
2353 + data_ = p_->get_data();
2354 + size_array_ = size;
2355 + memory_size_ = size;
2356 + smart_resize_ = A.smart_resize_;
2361 + // Creation d'un tableau "detache"
2366 + smart_resize_ = 0;
2367 + storage_type_ = STANDARD;
2372 +// Change le mode d'allocation memoire lors des resize
2373 +// (voir VFloatdata et Float_ptr_trav)
2374 +// Exemple pour creer un tableau avec allocation temporaire:
2375 +// DoubleTab tab; // Creation d'un tableau vide
2376 +// tab.set_mem_storage(TEMP_STORAGE); // Changement de mode d'allocation
2377 +// tab.resize(n); // Allocation memoire
2378 +void ArrOfFloat::set_mem_storage(const Storage storage)
2380 + storage_type_ = storage;
2384 +// Renvoie le mode d'allocation du tableau (qui sera utilise
2385 +// lors du prochain resize si changement de taille).
2386 +// (voir VFloatdata et Float_ptr_trav)
2387 +enum ArrOfFloat::Storage ArrOfFloat::get_mem_storage() const
2389 + return storage_type_;
2393 +// Change le mode l'allocation memoire: reallocation d'un tableau
2394 +// a chaque changement de taille (flag = 0) ou reallocation
2395 +// uniquement si la taille augmente et par doublement de la taille
2396 +// du tableau (flag = 1).
2397 +void ArrOfFloat::set_smart_resize(entier flag)
2399 + assert(flag == 0 || flag == 1);
2400 + smart_resize_ = flag;
2404 +// Remet le tableau dans l'etat obtenu avec le constructeur par defaut
2405 +// (libere la memoire mais conserve le mode d'allocation memoire actuel)
2406 +void ArrOfFloat::reset()
2412 +// Copie les donnees du tableau m.
2413 +// Si "m" n'a pas la meme taille que "*this", on fait un resize_array.
2414 +// Ensuite, on copie les valeurs de "m" dans "*this".
2415 +// Le type de tableau (methode d'allocation) n'est pas copie.
2417 +// Si le tableau n'a pas la meme taille que "m", alors *this doit
2418 +// etre "resizable" (ne pas etre de type "ref_data" et "ref_count == 1")
2419 +// Parametre: const ArrOfFloat& m
2420 +// Signification: la tableau a copier
2421 +// Retour: ArrOfFloat&
2422 +// Signification: *this
2423 +ArrOfFloat& ArrOfFloat::operator=(const ArrOfFloat& m)
2427 + const entier new_size = m.size_array();
2428 + // Le code suivant est quasiment une copie de ArrOfFloat::resize()
2429 + // SAUF: memory_resize est appele avec NO_INITIALIZE (la zone de memoire
2430 + // n'est pas initialisee)
2431 + if (new_size != size_array())
2433 + if ((smart_resize_ == 0) || (new_size > memory_size_))
2434 + memory_resize(new_size, 0); // Pas d'initialisation
2435 + size_array_ = new_size;
2444 +// x est affecte a toutes les cases
2446 +// Parametre: float x
2447 +// Signification: la valeur a affecter a toutes les cases du tableau
2448 +// Valeurs par defaut:
2451 +// Retour: ArrOfFloat&
2452 +// Signification: *this
2457 +ArrOfFloat& ArrOfFloat::operator=(float x)
2459 + const entier n = size_array();
2460 + float *data = addr();
2461 + for (entier i = 0; i < n; i++)
2468 +// Description: appelle operator=(a)
2469 +ArrOfFloat& ArrOfFloat::copy_array(const ArrOfFloat& a)
2476 +// Si besoin, alloue une nouvelle zone de memoire,
2477 +// copie les donnees et efface l'ancienne zone de memoire.
2478 +// Attention, on suppose que cette methode est appelee par
2480 +// Attention: si ref_count_>1, l'appel a resize_array() est
2481 +// autorise uniquement si la nouvelle taille est identique
2482 +// a la precedente.
2484 +// Le tableau doit etre de type "detache" ou "normal" avec
2485 +// ref_count==1, et il faut new_size >= 0
2486 +// On suppose que size_array contient encore le nombre d'elements
2487 +// valides avant changement de taille.
2488 +// Parametre: new_size
2489 +// Signification: nouvelle taille demandee pour le tableau.
2490 +// Parametre: options
2491 +// Signification: COPY_OLD => on recopie les anciennes donnees dans le nouveau
2492 +// tableau (jusqu'au max de l'ancienne et de la nouvelle taille).
2493 +// INITIALIZE_NEW => initialisation des cases non copiees
2495 +// p_ et data_ sont mis a jour, mais pas size_array_ !!!
2496 +// (on suppose que c'est fait dans resize_array()).
2497 +// Si la nouvelle taille est nulle, on detache le tableau.
2498 +void ArrOfFloat::memory_resize(entier new_size, entier options)
2500 + assert(new_size >= 0);
2502 + // Occupation memoire de l'ancien tableau:
2503 + entier old_mem_size = 0;
2505 + old_mem_size = p_->get_size();
2507 + // Occupation memoire du nouveau tableau :
2508 + // Si smart_resize, on prend au moins deux fois la taille
2509 + // precedente, ou new_size
2510 + entier new_mem_size = new_size;
2511 + if (smart_resize_ && (old_mem_size * 2 > new_size))
2512 + new_mem_size = old_mem_size * 2;
2514 + if (new_mem_size != old_mem_size)
2516 + // detach_array() efface le contenu de size_array_. On le met de cote:
2517 + const entier old_size_array = size_array_;
2518 + // On va reellement changer l'adresse du tableau.
2519 + // Il ne faut pas qu'il existe d'autre reference a ce tableau.
2520 + assert(data_ == 0 || (p_ != 0 && ref_count() == 1));
2521 + if (new_mem_size == 0)
2523 + // La nouvelle taille est nulle, on cree un tableau "detache"
2528 + // Allocation d'une nouvelle zone
2529 + VFloatdata * new_p = new VFloatdata(new_mem_size, storage_type_);
2530 + float * new_data = new_p->get_data();
2531 + // Raccourci si le tableau etait "detache", inutile de copier
2532 + // les anciennes donnees. On copie si COPY_OLD est demande
2533 + entier copy_size = 0;
2536 + // Calcul du nombre d'elements a copier vers la nouvelle
2537 + // zone de memoire : c'est le min de l'ancienne et de
2538 + // la nouvelle taille.
2539 + if (options & COPY_OLD)
2541 + copy_size = size_array_;
2542 + if (new_size < copy_size)
2543 + copy_size = new_size;
2544 + // Copie des valeurs dans le nouveau tableau
2545 + for (entier i = 0; i < copy_size; i++)
2546 + new_data[i] = data_[i];
2548 + // Destruction de l'ancienne zone (si plus aucune reference)
2551 + // On attache la nouvelle zone de memoire
2554 + memory_size_ = new_mem_size;
2555 + // Initialisation des cases supplementaires avec une valeur par defaut
2556 + if (options & INITIALIZE_NEW)
2557 + fill_default_value(copy_size, new_mem_size - copy_size);
2558 + // Restaure l'ancienne valeur de size_array_
2559 + size_array_ = old_size_array;
2565 +// Remplit "nb" cases consecutives du tableau a partir de la case "first"
2566 +// avec une valeur par defaut.
2567 +// Cette fonction est appelee lors d'un resize pour initialiser les
2568 +// cases nouvellement creees.
2569 +// Le comportement depend actuellement du type de tableau :
2570 +// * Tableau de type "smart_resize":
2571 +// * en mode debug (macro NDEBUG non definie) le tableau est initialise
2572 +// avec une valeur invalide.
2573 +// * en optimise, le tableau n'est pas initialise
2574 +// * Tableau normal :
2575 +// Le tableau est initialise avec la valeur 0. Ce comportement est choisi
2576 +// pour des raisons de compatibilite avec l'implementation precedente.
2577 +// Cette specification pourrait etre modifiee prochainement pour des raisons
2578 +// de performances (pour ne pas avoir a initialiser inutilement les tableaux).
2579 +// DONC: il faut supposer desormais que les nouvelles cases ne sont pas
2580 +// initialisees lors d'un resize.
2581 +// Parametre: first
2582 +// Signification: premiere case a initialiser.
2583 +// Contrainte: (nb==0) ou (0 <= first < memory_size_)
2585 +// Signification: nombre de cases a initialiser.
2586 +// Contrainte: (nb==0) ou (0 < nb <= memory_size_ - first)
2587 +void ArrOfFloat::fill_default_value(entier first, entier nb)
2589 + assert((nb == 0) || (first >= 0 && first < memory_size_));
2590 + assert((nb == 0) || (nb > 0 && nb <= memory_size_ - first));
2591 + float * data = addr();
2592 + assert(data!=0 || nb==0);
2594 + if (smart_resize_)
2597 + // On initialise uniquement en mode debug
2599 + // Ceci represente un NAN. N'importe quelle operation avec ca fait encore un NAN.
2600 + // Si c'est pas portable, on peut remplacer par DMAX_FLOAT sur les autres machines.
2601 + static const unsigned long long VALEUR_INVALIDE =
2602 + 0x7ff7ffffffffffffULL;
2604 + // On utilise "memcpy" et non "=" car "=" peut provoquer une exception
2605 + // si la copie passe par le fpu.
2606 + for (entier i = 0; i < nb; i++)
2607 + memcpy(data + i, & VALEUR_INVALIDE, sizeof(float));
2613 + // Comportement pour les tableaux normaux : compatibilite avec la
2614 + // version precedente : on initialise avec 0.
2615 + for (entier i = 0; i < nb; i++)
2616 + data[i] = (float) 0;
2620 +// ****************************************************************
2622 +// Fonctions non membres de la classe ArrOfFloat
2624 +// ****************************************************************
2627 +// Renvoie 1 si les tableaux "v" et "a" sont de la meme taille
2628 +// et contiennent les memes valeurs au sens strict, sinon renvoie 0.
2629 +// Le test est !(v[i]!=a[i])
2630 +entier operator==(const ArrOfFloat& v, const ArrOfFloat& a)
2632 + const entier n = v.size_array();
2633 + const entier na = a.size_array();
2641 + const float* vv = v.addr();
2642 + const float* av = a.addr();
2644 + for (i = 0; i < n; i++)
2646 + if (av[i] != vv[i])
2657 +// Retourne l'indice du min ou -1 si le tableau est vide
2659 +// Parametre: const ArrOfFloat& dx
2660 +// Signification: tableau a utiliser
2662 +// Signification: indice du min
2663 +entier imin_array(const ArrOfFloat& dx)
2665 + entier indice_min = -1;
2666 + const entier size = dx.size_array();
2670 + float valeur_min = dx[0];
2671 + for(entier i = 1; i < size; i++)
2673 + const float val = dx[i];
2674 + if(val < valeur_min)
2681 + return indice_min;
2685 +// Retourne l'indice du max ou -1 si le tableau est vide
2687 +// Parametre: const ArrOfFloat& dx
2688 +// Signification: tableau a utiliser
2690 +// Signification: indice du max
2691 +entier imax_array(const ArrOfFloat& dx)
2693 + entier indice_max = -1;
2694 + const entier size = dx.size_array();
2698 + float valeur_max = dx[0];
2699 + for(entier i = 1; i < size; i++)
2701 + const float val = dx[i];
2702 + if(val > valeur_max)
2709 + return indice_max;
2713 +// Retourne la valeur minimale
2715 +// Le tableau doit contenir au moins une valeur
2716 +// Parametre: const ArrOfFloat& dx
2717 +// Signification: tableau a utiliser
2719 +// Signification: valeur du min
2720 +float min_array(const ArrOfFloat& dx)
2722 + const entier size = dx.size_array();
2724 + float valeur_min = dx[0];
2725 + for(entier i = 1; i < size; i++)
2727 + const float val = dx[i];
2728 + if (val < valeur_min)
2731 + return valeur_min;
2735 +// Retourne la valeur maximale
2737 +// Le tableau doit contenir au moins une valeur
2738 +// Parametre: const ArrOfFloat& dx
2739 +// Signification: tableau a utiliser
2741 +// Signification: valeur du max
2742 +float max_array(const ArrOfFloat& dx)
2744 + const entier size = dx.size_array();
2746 + float valeur_max = dx[0];
2747 + for(entier i = 1; i < size; i++)
2749 + const float val = dx[i];
2750 + if (val > valeur_max)
2753 + return valeur_max;
2757 +// Fonction de comparaison utilisee pour trier le tableau
2758 +// dans ArrOfFloat::trier(). Voir man qsort
2759 +static int fonction_compare_arroffloat_ordonner(const void * data1, const void * data2)
2761 + const float x = *(const float*)data1;
2762 + const float y = *(const float*)data2;
2772 +// Tri des valeurs du tableau dans l'ordre croissant.
2773 +// La fonction utilisee est qsort de stdlib (elle est en n*log(n)).
2774 +void ArrOfFloat::ordonne_array()
2776 + const entier size = size_array();
2779 + float * data = addr();
2780 + qsort(data, size, sizeof(float),
2781 + fonction_compare_arroffloat_ordonner);
2786 +// Fait pointer le tableau vers les memes donnees qu'un tableau
2787 +// existant. Le tableau sera du meme type que le tableau m ("detache",
2788 +// "normal"). Le tableau m ne doit pas etre de type "ref_data"
2789 +// Les donnes existantes sont perdues si elles
2790 +// ne sont pas referencees ailleurs.
2792 +// Parametre: const ArrOfFloat& m
2793 +// Signification: le tableau a referencer (pas de type "ref_data"
2794 +// et different de *this !!!)
2795 +// Retour: ArrOfFloat&
2796 +// Signification: *this
2801 +ArrOfFloat& ArrOfFloat::ref_array(const ArrOfFloat& m)
2803 + assert(&m != this);
2804 + // La condition 'm n'est pas de type "ref_data"' est necessaire pour
2805 + // attach_array().
2812 +// Fait pointer le tableau vers la zone de memoire "data_".
2813 +// On detache la zone de memoire existante. Le tableau devient
2814 +// de type "ref_data". Attention : ptr doit etre non nul.
2815 +// La taille est initialisee avec size.
2816 +// Cette methode est appelee notamment par FloatVect::adopter.
2817 +// Parametre: float*
2818 +// Signification: le tableau a recuperer. Si pointeur nul alors size
2819 +// doit etre nulle aussi et le tableau reste detache
2820 +// Parametre: entier size
2821 +// Signification: le nombre d'elements du tableau.
2822 +// Retour: ArrOfFloat&
2823 +// Signification: *this
2824 +ArrOfFloat& ArrOfFloat::ref_data(float* ptr, entier size)
2826 + assert(ptr != 0 || size == 0);
2827 + assert(size >= 0);
2830 + size_array_ = size;
2835 +// Amene le tableau dans l'etat "detache". C'est a dire:
2836 +// Si le tableau est "detache" :
2838 +// Si le tableau est "normal" :
2839 +// * decremente le nombre de references a *p
2840 +// * detruit *p si p->ref_count==0
2841 +// * annule p_, data_ et size_array_
2842 +// Si le tableau est "ref_data" :
2843 +// * annule data_ et size_array_
2845 +// Signification: 1 si les donnees du tableau ont ete supprimees
2848 +// On a p_==0, data_==0 et size_array_==0, memory_size_ = 0
2849 +// L'attribut smart_resize_ est conserve.
2850 +entier ArrOfFloat::detach_array()
2852 + entier retour = 0;
2855 + // Le tableau est de type "normal"
2856 + // Si la zone de memoire n'est plus utilisee par personne,
2858 + if ((p_->suppr_one_ref()) == 0)
2872 +// Amene le tableau dans l'etat "normal", "detache" ou "ref_array"
2873 +// en associant la meme zone de memoire que le tableau m.
2875 +// Le tableau doit etre "detache"
2876 +// Parametre: const ArrOfFloat& m
2877 +// Signification: tableau a utiliser
2878 +// le tableau doit etre different de *this !!!
2885 +// Si m est detache, le tableau reste detache,
2886 +// si m est "ref_array", le tableau devient "ref_array",
2887 +// sinon le tableau est "normal", avec ref_count > 1
2888 +// Si m est de taille nulle, le tableau reste detache + Warning dans fichier .log
2889 +void ArrOfFloat::attach_array(const ArrOfFloat& m)
2891 + // Le tableau doit etre detache
2892 + assert(data_ == 0 && p_ == 0);
2893 + // Le tableau doit etre different de *this
2894 + assert(&m != this);
2896 + if (m.size_array() > 0)
2900 + p_->add_one_ref();
2902 + size_array_ = m.size_array_;
2903 + memory_size_ = m.memory_size_;
2904 + smart_resize_ = m.smart_resize_;
2908 + // Cas particulier ou on attache un tableau de taille nulle:
2909 + // en theorie, c'est pareil qu'un tableau de taille non nulle, MAIS
2910 + // dans les operateurs (ex:Op_Dift_VDF_Face_Axi), une ref est construite
2911 + // avant que le tableau ne prenne sa taille definitive. Donc, pour ne pas
2912 + // empecher le resize, il ne faut pas attacher le tableau s'il n'a pas
2913 + // encore la bonne taille. Solution propre: reecrire les operateurs pour
2914 + // qu'ils ne prennent pas une ref avant que le tableau ne soit valide
2915 + // et faire p_ = m.p_ dans tous les cas.
2920 +// Copie les elements source[first_element_source + i]
2921 +// dans les elements (*this)[first_element_dest + i] pour 0 <= i < nb_elements
2922 +// Les autres elements de (*this) sont inchanges.
2924 +// Parametre: const ArrOfFloat& m
2925 +// Signification: le tableau a utiliser, doit etre different de *this !
2926 +// Parametre: entier nb_elements
2927 +// Signification: nombre d'elements a copier, nb_elements >= -1.
2928 +// Si nb_elements==-1, on copie tout le tableau m.
2929 +// Valeurs par defaut: -1
2930 +// Parametre: entier first_element_dest
2931 +// Valeurs par defaut: 0
2932 +// Parametre: entier first_element_source
2933 +// Valeurs par defaut: 0
2934 +// Retour: ArrOfFloat&
2935 +// Signification: *this
2938 +// Sort en erreur si la taille du tableau m est plus grande que la
2939 +// taille de tableau this.
2942 +ArrOfFloat& ArrOfFloat::inject_array(const ArrOfFloat& source,
2943 + entier nb_elements,
2944 + entier first_element_dest,
2945 + entier first_element_source)
2947 + assert(&source != this);
2948 + assert(nb_elements >= -1);
2949 + assert(first_element_dest >= 0);
2950 + assert(first_element_source >= 0);
2952 + if (nb_elements < 0)
2953 + nb_elements = source.size_array();
2955 + assert(first_element_source + nb_elements <= source.size_array());
2956 + assert(first_element_dest + nb_elements <= size_array());
2958 + if (nb_elements > 0)
2960 + float * addr_dest = addr() + first_element_dest;
2961 + const float * addr_source = source.addr() + first_element_source;
2962 + // memcpy(addr_dest , addr_source, nb_elements * sizeof(float));
2964 + for (i = 0; i < nb_elements; i++)
2966 + addr_dest[i] = addr_source[i];
2973 +// Retourne le nombre de references des donnees du tableau
2974 +// si le tableau est "normal", -1 s'il est "detache" ou "ref_data"
2976 +// Signification: ref_count_
2977 +entier ArrOfFloat::ref_count() const
2980 + return p_->ref_count();
2986 +// Addition case a case sur toutes les cases du tableau
2988 +// la taille de y doit etre au moins egale a la taille de this
2989 +// Parametre: const ArrOfFloat& y
2990 +// Signification: tableau a ajouter
2991 +// Valeurs par defaut:
2994 +// Retour: ArrOfFloat&
2995 +// Signification: *this
3000 +ArrOfFloat& ArrOfFloat::operator+=(const ArrOfFloat& y)
3002 + assert(size_array()==y.size_array());
3003 + float* dx = addr();
3004 + const float* dy = y.addr();
3005 + const entier n = size_array();
3006 + for (entier i=0; i<n; i++)
3012 +// ajoute la meme valeur a toutes les cases du tableau
3014 +// Parametre: const float dy
3015 +// Signification: valeur a ajouter
3016 +// Valeurs par defaut:
3019 +// Retour: ArrOfFloat
3020 +// Signification: *this
3025 +ArrOfFloat& ArrOfFloat::operator+=(const float dy)
3027 + float * data = addr();
3028 + const entier n = size_array();
3029 + for(entier i=0; i < n; i++)
3034 +// Soustraction case a case sur toutes les cases du tableau
3035 +// Parametre: const ArrOfFloat& y
3036 +// Signification: tableau de meme taille que *this
3037 +// Retour: ArrOfFloat&
3038 +// Signification: *this
3039 +ArrOfFloat& ArrOfFloat::operator-=(const ArrOfFloat& y)
3041 + const entier size = size_array();
3042 + assert(size == y.size_array());
3043 + float * data = addr();
3044 + const float * data_y = y.addr();
3045 + for (entier i=0; i < size; i++)
3046 + data[i] -= data_y[i];
3052 +// soustrait la meme valeur a toutes les cases
3053 +// Retour: ArrOfFloat &
3054 +// Signification: *this
3055 +ArrOfFloat& ArrOfFloat::operator-=(const float dy)
3057 + float * data = addr();
3058 + const entier n = size_array();
3059 + for(entier i=0; i < n; i++)
3065 +// Renvoie un pointeur sur le premier element du tableau.
3066 +// Le pointeur est nul si le tableau est "detache".
3067 +// Attention, l'adresse peut changer apres un appel
3068 +// a resize_array(), ref_data, ref_array, ...
3070 +// Retour: const float*
3071 +// Signification: pointeur sur le premier element du tableau
3072 +const float* ArrOfFloat::addr() const
3078 +// Renvoie un pointeur sur le premier element du tableau.
3079 +// Le pointeur est nul si le tableau est "detache".
3081 +// Retour: const float*
3082 +// Signification: la zone memoire du tableau
3083 +float* ArrOfFloat::addr()
3090 +// Retourne le max des abs(i)
3092 +// Le tableau doit contenir au moins une valeur
3093 +// Parametre: const ArrOfFloat& dx
3094 +// Signification: tableau a utiliser
3095 +// Valeurs par defaut:
3099 +// Signification: valeur du max des valeurs absolues
3104 +float max_abs_array(const ArrOfFloat& dx)
3106 + const entier size = dx.size_array();
3108 + float valeur_max = fabs(dx[0]);
3109 + for(entier i = 1; i < size; i++)
3111 + const float val = fabs(dx[i]);
3112 + if (val > valeur_max)
3115 + return valeur_max;
3119 +// muliplie toutes les cases par dy
3120 +// Retour: ArrOfFloat &
3121 +// Signification: *this
3122 +ArrOfFloat& ArrOfFloat::operator*= (const float dy)
3124 + float * data = addr();
3125 + const entier n = size_array();
3126 + for(entier i=0; i < n; i++)
3133 +// divise toutes les cases par dy
3134 +// Retour: ArrOfFloat &
3135 +// Signification: *this
3136 +ArrOfFloat& ArrOfFloat::operator/= (const float dy)
3138 + // En theorie: les deux lignes suivantes sont plus efficaces, mais
3139 + // cela produit des differences sur certains cas tests
3140 + // (Hyd_C_VEF_Smago et Lambda_var_VEF_turb). Ca veut dire qu'il y
3141 + // a un probleme autre part mais pour l'instant on laisse l'ancien
3143 + // const float i_dy = 1. / dy;
3144 + // operator*=(i_dy);
3146 + float * data = addr();
3147 + const entier n = size_array();
3148 + for(entier i=0; i < n; i++)
3154 +FloatTab::FloatTab()
3157 + dimensions_[0] = 0;
3158 + dimensions_[1] = 0;
3161 +FloatTab::FloatTab(const FloatTab& tab) :
3164 + // nb_dim_ = tab.nb_dim_;
3165 + dimensions_[0] = tab.dimensions_[0];
3166 + dimensions_[1] = tab.dimensions_[1];
3168 +FloatTab::FloatTab(const entier i, const entier j) :
3172 + dimensions_[0] = i;
3173 + dimensions_[1] = j;
3176 +FloatTab& FloatTab::operator=(const FloatTab& tab)
3178 + ArrOfFloat::operator=(tab);
3179 + // nb_dim_ = tab.nb_dim_;
3180 + dimensions_[0] = tab.dimensions_[0];
3181 + dimensions_[1] = tab.dimensions_[1];
3185 +void FloatTab::reset()
3187 + ArrOfFloat::reset();
3189 + dimensions_[0] = 0;
3190 + dimensions_[1] = 0;
3193 diff --git a/databases/readers/Lata/ArrOfFloat.h b/databases/readers/Lata/ArrOfFloat.h
3194 new file mode 100644
3195 index 0000000..f80d4ee
3197 +++ b/databases/readers/Lata/ArrOfFloat.h
3199 +/*****************************************************************************
3201 +* Copyright (c) 2011 - 2013, CEA
3202 +* All rights reserved.
3203 +* Redistribution and use in source and binary forms, with or without
3204 +* modification, are permitted provided that the following conditions are met:
3206 +* * Redistributions of source code must retain the above copyright
3207 +* notice, this list of conditions and the following disclaimer.
3208 +* * Redistributions in binary form must reproduce the above copyright
3209 +* notice, this list of conditions and the following disclaimer in the
3210 +* documentation and/or other materials provided with the distribution.
3211 +* * Neither the name of CEA, nor the
3212 +* names of its contributors may be used to endorse or promote products
3213 +* derived from this software without specific prior written permission.
3215 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
3216 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3217 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3218 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
3219 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3220 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3221 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3222 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3223 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3224 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3226 +*****************************************************************************/
3228 +////////////////////////////////////////////////////////////
3230 +// Warning : DO NOT EDIT !
3231 +// Please update ArrOf_Scalar_Prototype.h.P
3232 +// and this file will be generated automatically
3233 +// by the script file check.sh
3234 +////////////////////////////////////////////////////////////
3236 +#ifndef ArrOfFloat_H
3237 +#define ArrOfFloat_H
3239 +#include <assert.h>
3241 +#include <Objet_U.h>
3243 +#if ! defined(DMAXFLOAT)
3244 +#define DMAXFLOAT 1e40
3255 + virtual ~ArrOfFloat();
3260 + ArrOfFloat(entier size);
3261 + ArrOfFloat(entier size, float initial_value);
3262 + // Constructeur par copie : deep copy (on duplique les donnees)
3263 + ArrOfFloat(const ArrOfFloat& );
3265 + // Methodes de construction tardive (on cree un tableau vide avec ArrOfFloat()
3266 + // puis on appelle ces methodes pour modifier les caracteristiques du tableau :
3268 + // Change le nombre d'elements du tableau
3269 + inline ArrOfFloat& resize_array(entier new_size);
3271 + // Methodes de gestion de l'allocation memoire:
3272 + // Assigne une valeur au drapeau "smart_resize"
3273 + // (reallocation uniquement si la taille augmente)
3274 + void set_smart_resize(entier flag);
3275 + // Gestion du type de memoire alouee (standard ou pool de memoire Trio-U)
3276 + enum Storage { STANDARD, TEMP_STORAGE, SIMD_ALIGNED };
3277 + void set_mem_storage(const Storage storage);
3278 + Storage get_mem_storage() const;
3280 + // Construction de tableaux qui pointent vers des donnees existantes
3281 + // !!! Utiliser ref_data avec precaution (attention a size_array_)
3282 + ArrOfFloat& ref_data(float* ptr, entier size);
3283 + ArrOfFloat& ref_array(const ArrOfFloat&);
3284 + // Operateur copie
3285 + ArrOfFloat& operator=(const ArrOfFloat&);
3286 + // Remise du tableau dans l'etat initial (obtenu par le constructeur par defaut)
3287 + virtual void reset();
3290 + // Methodes d'acces aux donnees et aux caracteristiques du tableau
3292 + // Remplit le tableau avec la valeur en parametre
3293 + ArrOfFloat& operator=(float valeur);
3295 + inline float& operator[](entier i);
3296 + inline const float& operator[](entier i) const;
3298 + // Ces methodes renvoient un pointeur vers le premier element du tableau.
3299 + const float * addr() const;
3301 + // Renvoie le nombre d'elements du tableau (et non la taille allouee)
3302 + inline entier size_array() const;
3303 + // Renvoie le nombre de tableaux qui pointent vers la stucture "*p_"
3304 + entier ref_count() const;
3305 + // Ajoute une case en fin de tableau et y stocke la "valeur"
3306 + inline void append_array(float valeur);
3309 + // Operateurs divers
3311 + ArrOfFloat& operator+=(const ArrOfFloat&);
3312 + ArrOfFloat& operator+=(const float);
3313 + ArrOfFloat& operator-=(const ArrOfFloat&);
3314 + ArrOfFloat& operator-=(const float);
3315 + ArrOfFloat& inject_array(const ArrOfFloat& source,
3316 + entier nb_elements = -1,
3317 + entier first_element_dest = 0,
3318 + entier first_element_source = 0);
3319 + ArrOfFloat& copy_array(const ArrOfFloat&);
3321 + ArrOfFloat& operator*= (const float) ;
3322 + ArrOfFloat& operator/= (const float) ;
3324 + void ordonne_array();
3328 + // Methodes accessibles depuis les descendants de ArrOfFloat
3330 + void attach_array(const ArrOfFloat&);
3331 + entier detach_array();
3332 + void fill_default_value(entier first, entier nb);
3334 + // B. Mathieu 22/06/2004 : je mets ces membres "private" pour forcer
3335 + // le passage par les accesseurs dans les classes derivees, au cas ou
3336 + // on voudrait modifier l'implementation.
3338 + // Zone de memoire contenant les valeurs du tableau.
3339 + // Pointeur nul => le tableau est "detache" ou "ref_data"
3340 + // Pointeur non nul => le tableau est "normal"
3343 + // Pointeur vers le premier element du tableau (egal a p_->data si p_!=0)
3344 + // Pointeur nul => le tableau est "detache".
3345 + // Pointeur non nul => le tableau est "normal" ou "ref_data"
3348 + // Nombre d'elements du tableau (inferieur ou egal a memory_size_).
3349 + // Si le tableau est "detache", alors size_array_=0
3350 + entier size_array_;
3351 + // Taille memoire reellement allouee pour le tableau
3352 + // (pour le mecanisme smart_resize_). memory_size_ est nul
3353 + // si le tableau est de type "ref_data". Sinon memory_size_
3354 + // est egal a p_->size_.
3355 + entier memory_size_;
3357 + // Drapeau indiquant si on applique une strategie d'allocation
3358 + // preventive (la memoire alouee augmente d'un facteur constant
3359 + // si la taille devient insuffisante).
3360 + // Si smart_resize_ == 0, alors on a toujours p_->size_ == size
3361 + entier smart_resize_;
3363 + // Drapeau indiquant si l'allocation memoire a lieu avec un new classique
3364 + // ou dans le pool de memoire temporaire de Trio
3365 + Storage storage_type_;
3367 + // Partie non inline de resize_array():
3368 + // Declaration des constantes pour les options de memory_resize
3369 + static const entier COPY_OLD;
3370 + static const entier INITIALIZE_NEW;
3371 + void memory_resize(entier new_size, entier options);
3374 +#define MAXDIMFloatTab 2
3376 +class FloatTab : public ArrOfFloat
3380 + FloatTab(const FloatTab&);
3381 + FloatTab(const entier i, const entier j);
3382 + FloatTab& operator=(const FloatTab&);
3385 + inline float& operator()(entier i, entier j);
3386 + inline float operator()(entier i, entier j) const;
3388 + inline entier resize(entier i, entier j);
3389 + inline entier dimension(entier i) const;
3390 + inline entier dimension_tot(entier i) const;
3393 + // In order to mimic TRUST behavior, operator[] is forbidden
3394 + // for 2 dimensionnal matrices, you must cast to ArrOf to use it..
3395 + double& operator[](entier i);
3396 + const double& operator[](entier i) const;
3399 + // entier nb_dim_;
3400 + entier dimensions_[MAXDIMFloatTab];
3403 +inline float& FloatTab::operator()(entier i, entier j)
3405 + // assert(nb_dim_ == 2);
3406 + assert(i >= 0 && i < dimensions_[0] && j >= 0 && j < dimensions_[1]);
3407 + const entier n = i * dimensions_[1] + j;
3408 + float& x = ArrOfFloat::operator[] (n);
3412 +inline float FloatTab::operator()(entier i, entier j) const
3414 + // assert(nb_dim_ == 2);
3415 + assert(i >= 0 && i < dimensions_[0] && j >= 0 && j < dimensions_[1]);
3416 + const entier n = i * dimensions_[1] + j;
3417 + float x = ArrOfFloat::operator[] (n);
3421 +inline entier FloatTab::resize(entier i, entier j)
3423 + assert(i >= 0 && j >= 0);
3425 + dimensions_[0] = i;
3426 + dimensions_[1] = j;
3427 + ArrOfFloat::resize_array(i * j);
3431 +inline entier FloatTab::dimension(entier i) const
3433 + assert(i >= 0 && i < 2);
3434 + return dimensions_[i];
3437 +// Description: renvoie la meme valeur que dimension.
3438 +inline entier FloatTab::dimension_tot(entier i) const
3440 + return dimension(i);
3444 +// Declarations des fonctions non membres de la classe ArrOfFloat
3446 +entier operator==(const ArrOfFloat& x, const ArrOfFloat& y) ;
3447 +entier imin_array(const ArrOfFloat&) ;
3448 +entier imax_array(const ArrOfFloat&) ;
3449 +float min_array(const ArrOfFloat&) ;
3450 +float max_array(const ArrOfFloat&) ;
3452 +float max_abs_array(const ArrOfFloat&) ;
3454 +// ******************************************************************
3455 +// FONCTIONS MEMBRES DE ArrOfFloat
3456 +// ******************************************************************
3459 +// Change le nombre d'elements du tableau. Cette fonction est inline
3460 +// car elle doit etre tres rapide dans le cas ou smart_resize_==1
3461 +// (utilisation frequente de resize_array())
3462 +// Si smart_resize est non nul :
3463 +// Si la nouvelle taille est inferieure ou egale a la taille
3464 +// alouee (p->get_size()) on ne realloue pas de memoire
3465 +// sinon, on realloue et on copie les donnees existantes.
3466 +// Astuce pour ne pas copier les anciennes donnees:
3467 +// resize(0); resize(n);
3468 +// Si smart_resize est nul, on realloue une nouvelle zone memoire
3469 +// uniquement si la nouvelle taille est differente de l'ancienne.
3471 +// Si "new_size" est egal a la taille du tableau, aucune condition.
3472 +// Sinon, le tableau doit etre soit detache, soit normal (pas de type "ref_data")
3473 +// et ref_count doit etre egal a 1 (pas d'autre reference au tableau).
3475 +inline ArrOfFloat& ArrOfFloat::resize_array(entier new_size)
3477 + assert(new_size >= 0);
3478 + // Soit le tableau est detache (data_==0), soit il est normal (p_!=0)
3479 + // S'il est normal, il ne faut pas qu'il y ait d'autre reference au tableau,
3480 + // ou alors la taille ne doit pas changer.
3481 + assert(new_size == size_array_ || data_ == 0 || (p_ != 0 && ref_count() == 1));
3483 + if ((smart_resize_ == 0) || (new_size > memory_size_))
3484 + memory_resize(new_size, COPY_OLD + INITIALIZE_NEW);
3485 + size_array_ = new_size;
3490 +// operateur [] retourne le ieme element du tableau
3492 +// Parametre: entier i
3493 +// Signification: indice dans l'intervalle 0 <= i < size_array()
3495 +// assert si la valeur sort de l'intervalle : [ -DMAXFLOAT,DMAXFLOAT ]
3496 +// assert si i n'est pas dans l'intervalle
3497 +inline float& ArrOfFloat::operator[](entier i)
3499 + assert(i >= 0 && i < size_array_);
3500 + assert((smart_resize_==1)|| (data_[i] > -DMAXFLOAT && data_[i] < DMAXFLOAT));
3505 +// operateur [] retourne le ieme element du tableau
3507 +// Parametre: entier i
3508 +// Signification: indice dans l'intervalle 0 <= i < size_array()
3510 +// assert si la valeur sort de l'intervalle : [ -DMAXFLOAT,DMAXFLOAT ]
3511 +// assert si i n'est pas dans l'intervalle
3512 +inline const float& ArrOfFloat::operator[](entier i) const
3514 + assert(i >= 0 && i < size_array_);
3515 + assert(data_[i] > -DMAXFLOAT && data_[i] < DMAXFLOAT);
3520 +// Renvoie la taille du tableau (nombre d'elements declares
3521 +// a la construction ou a resize_array()).
3522 +// C'est le nombre d'elements accessibles a operator[]
3524 +inline entier ArrOfFloat::size_array() const
3526 + return size_array_;
3530 +// Ajoute une case en fin de tableau et y stocke la "valeur"
3532 +// Tableau doit etre de type "smart_resize" (sinon, ecroulement
3533 +// des performances). De plus, le tableau ne doit pas etre "ref_data",
3534 +// et il ne doit pas y avoir plus d'une reference a la zone de
3535 +// memoire pointee (meme precondition que resize_array())
3536 +inline void ArrOfFloat::append_array(float valeur)
3538 + assert(smart_resize_);
3539 + // Soit le tableau est detache (data_==0), soit il est normal (p_!=0)
3540 + // S'il est normal, il ne faut pas qu'il y ait d'autre reference au tableau.
3541 + assert(data_ == 0 || (p_ != 0 && ref_count() == 1));
3543 + if (size_array_+1 > memory_size_)
3544 + memory_resize(size_array_+1, COPY_OLD);
3545 + data_[size_array_] = valeur;
3552 diff --git a/databases/readers/Lata/ArrOfInt.C b/databases/readers/Lata/ArrOfInt.C
3553 new file mode 100644
3554 index 0000000..a4a150b
3556 +++ b/databases/readers/Lata/ArrOfInt.C
3558 +/*****************************************************************************
3560 +* Copyright (c) 2011 - 2013, CEA
3561 +* All rights reserved.
3562 +* Redistribution and use in source and binary forms, with or without
3563 +* modification, are permitted provided that the following conditions are met:
3565 +* * Redistributions of source code must retain the above copyright
3566 +* notice, this list of conditions and the following disclaimer.
3567 +* * Redistributions in binary form must reproduce the above copyright
3568 +* notice, this list of conditions and the following disclaimer in the
3569 +* documentation and/or other materials provided with the distribution.
3570 +* * Neither the name of CEA, nor the
3571 +* names of its contributors may be used to endorse or promote products
3572 +* derived from this software without specific prior written permission.
3574 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
3575 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3576 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3577 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
3578 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3579 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3580 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3581 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3582 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3583 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3585 +*****************************************************************************/
3587 +////////////////////////////////////////////////////////////
3589 +// Warning : DO NOT EDIT !
3590 +// Please update ArrOf_Scalar_Prototype.cpp.h
3591 +// and this file will be generated automatically
3592 +// by the script file check.sh
3593 +////////////////////////////////////////////////////////////
3595 +#include <ArrOfInt.h>
3596 +// limits.h definit INT_MIN, SHRT_MIN, ...
3597 +#include <limits.h>
3598 +#include <stdlib.h>
3599 +#include <Objet_U.h>
3600 +#include <iostream>
3601 +#include <stdlib.h>
3602 +#include <string.h>
3603 +#include "simd_interface.h"
3605 +using namespace std;
3607 +// ******************************************************************
3609 +// Implementation des methodes de VIntdata
3611 +// ******************************************************************
3612 +////////////////////////////////////////////////////////////////////
3614 +// .ENTETE TRUST Math
3615 +// .LIBRAIRIE libtmath
3616 +// .FILE ArrOfInt.h
3617 +// .FILE ArrOfInt.cpp
3620 +// VIntdata alloue une zone de memoire de la taille specifiee au
3621 +// constructeur, et libere la zone de memoire a la destruction.
3623 +// "ref_count" compte le nombre de pointeurs qui font reference a "this".
3624 +// (permet au dernier utilisateur de l'objet de le detruire), voir
3627 +// .SECTION voir aussi
3632 +///////////////////////////////////////////////////////////////////
3637 + VIntdata(entier size, ArrOfInt::Storage storage);
3639 + entier add_one_ref();
3640 + entier suppr_one_ref();
3641 + entier * get_data();
3642 + const entier * get_data() const;
3643 + inline entier ref_count() const;
3644 + inline entier get_size() const;
3646 + // Le constructeur par copie et l'operateur= sont interdits.
3647 + VIntdata(const VIntdata& v);
3648 + VIntdata& operator=(const VIntdata& v);
3650 + // "data" est un pointeur sur une zone de memoire de taille
3651 + // sz * sizeof(entier), allouee par le
3652 + // constructeur et liberee par le destructeur.
3653 + // Ce pointeur n'est jamais nul meme si size_==0
3655 + // Compteur incremente par add_one_ref et decremente par suppr_one_ref.
3656 + // Contient le nombre d'objets ArrOfInt dont le membre "p" pointe
3657 + // vers "this". On a ref_count_ >= 0.
3658 + entier ref_count_;
3659 + // "sz" est la taille du tableau "data_" alloue
3662 + ArrOfInt::Storage storage_;
3667 +// Construit un VIntdata de taille size >= 0
3668 +// Parametre: entier s
3669 +// Signification: taille du VIntdata, il faut size >= 0
3670 +// Parametre: Storage storage
3671 +// Signification: indique si la memoire doit etre allouee
3672 +// avec "new" ou avec "simd_malloc"
3673 +// Valeurs par defaut: STANDARD (allocation avec "new")
3675 +// data_ n'est jamais nul, meme si size==0
3676 +VIntdata::VIntdata(entier size, ArrOfInt::Storage storage)
3679 + storage = ArrOfInt::STANDARD;
3683 + case ArrOfInt::STANDARD:
3686 + // Allocation de la memoire sur le tas
3689 + data_ = new entier[size];
3693 + Cerr << "impossible d'allouer " << size << " entier " << finl;
3697 + data_ = new entier[size];
3700 + Cerr << "impossible d'allouer " << size << "entier " << finl;
3706 + case ArrOfInt::SIMD_ALIGNED:
3708 +#ifdef SIMD_TOOLS_H
3709 + data_ = (entier*) simd_malloc (sizeof(entier) * size);
3711 + Cerr<<"unable to allocate simd_aligned, version compiled without simd "<<finl;
3721 + storage_ = storage;
3722 + assert(data_ != 0);
3726 +// Detruit la zone de memoire allouee.
3728 +// ref_count == 0 (la zone de memoire ne doit etre referencee nulle part)
3729 +VIntdata::~VIntdata()
3731 + assert(ref_count_ == 0);
3733 + // Stockage STANDARD
3736 + case ArrOfInt::STANDARD:
3739 + case ArrOfInt::SIMD_ALIGNED:
3740 +#ifdef SIMD_TOOLS_H
3743 + Cerr<<"unable to allocate simd_aligned, version compiled without simd "<<finl;
3751 + data_ = 0; // paranoia: si size_==-1 c'est qu'on pointe sur un zombie
3752 + size_ = -1; // (pointeur vers un objet qui a ete detruit)
3753 + storage_ = ArrOfInt::STANDARD;
3756 +// Description: renvoie ref_count_
3757 +inline entier VIntdata::ref_count() const
3759 + return ref_count_;
3762 +// Description: renvoie size_
3763 +inline entier VIntdata::get_size() const
3769 +// Un nouveau tableau utilise cette zone memoire :
3770 +// incremente ref_count
3772 +// Signification: ref_count
3773 +inline entier VIntdata::add_one_ref()
3775 + return ++ref_count_;
3779 +// Un tableau de moins utilise cette zone memoire
3780 +// decremente ref_count
3784 +// Signification: ref_count
3785 +inline entier VIntdata::suppr_one_ref()
3787 + assert(ref_count_ > 0);
3788 + return (--ref_count_);
3791 +// Description: renvoie data_
3792 +inline entier * VIntdata::get_data()
3797 +// Description: renvoie data_
3798 +inline const entier * VIntdata::get_data() const
3803 +// Description: Constructeur par copie. Interdit : genere une erreur !
3804 +VIntdata::VIntdata(const VIntdata& v)
3806 + Cerr << "Erreur dans VIntdata::VIntdata(const VIntdata & v)" << finl;
3810 +// Description: Operateur= interdit. Genere une erreur !
3811 +VIntdata& VIntdata::operator=(const VIntdata& v)
3813 + Cerr << "Erreur dans VIntdata::operator=(const VIntdata & v)" << finl;
3818 +// ******************************************************************
3820 +// Implementation des methodes de ArrOfInt
3822 +// ******************************************************************
3825 +// Definition des constantes pour les options de memory_resize
3826 +const entier ArrOfInt::COPY_OLD = 1;
3827 +const entier ArrOfInt::INITIALIZE_NEW = 2;
3830 +// Destructeur : appelle detach_array()
3831 +ArrOfInt::~ArrOfInt()
3834 + size_array_ = -1; // Paranoia: si size_array_==-1, c'est un zombie
3838 +// Constructeur par defaut: cree un tableau "detache",
3839 +// soit p_==0, data_==0, size_array_==0, smart_resize_==0
3840 +ArrOfInt::ArrOfInt() :
3846 + storage_type_(STANDARD)
3851 +// Cree un tableau de taille n avec allocation standard
3852 +// (voir set_mem_storage).
3853 +// Valeur de remplissage par defaut: voir fill_default_value
3855 +// Parametre: entier n
3856 +// Signification: taille du tableau
3857 +ArrOfInt::ArrOfInt(entier n) :
3858 + p_(new VIntdata(n, STANDARD)),
3859 + data_(p_->get_data()),
3863 + storage_type_(STANDARD)
3866 + fill_default_value(0, n);
3870 +// Cree un tableau de taille n
3871 +// toutes les cases sont initialisees a x
3873 +// Parametre: entier n
3874 +// Signification: taille du tableau
3875 +// Parametre: entier x
3876 +// Signification: valeur pour initialiser le tableau
3877 +ArrOfInt::ArrOfInt(entier n, entier x) :
3878 + p_(new VIntdata(n, STANDARD)),
3879 + data_(p_->get_data()),
3883 + storage_type_(STANDARD)
3889 +// Constructeur par copie. On alloue une nouvelle zone de memoire
3890 +// et on copie le contenu du tableau. L'attribut smart_resize_ est
3892 +// Si le tableau A est de taille nulle, on cree un tableau "detache",
3893 +// sinon on cree un tableau "normal".
3894 +// Parametre: const ArrOfInt& A
3895 +// Signification: le tableau a copier
3896 +ArrOfInt::ArrOfInt(const ArrOfInt& A)
3898 + const entier size = A.size_array();
3901 + // Creation d'un tableau "normal"
3902 + storage_type_ = STANDARD;
3903 + p_ = new VIntdata(size, STANDARD);
3904 + data_ = p_->get_data();
3905 + size_array_ = size;
3906 + memory_size_ = size;
3907 + smart_resize_ = A.smart_resize_;
3912 + // Creation d'un tableau "detache"
3917 + smart_resize_ = 0;
3918 + storage_type_ = STANDARD;
3923 +// Change le mode d'allocation memoire lors des resize
3924 +// (voir VIntdata et Int_ptr_trav)
3925 +// Exemple pour creer un tableau avec allocation temporaire:
3926 +// DoubleTab tab; // Creation d'un tableau vide
3927 +// tab.set_mem_storage(TEMP_STORAGE); // Changement de mode d'allocation
3928 +// tab.resize(n); // Allocation memoire
3929 +void ArrOfInt::set_mem_storage(const Storage storage)
3931 + storage_type_ = storage;
3935 +// Renvoie le mode d'allocation du tableau (qui sera utilise
3936 +// lors du prochain resize si changement de taille).
3937 +// (voir VIntdata et Int_ptr_trav)
3938 +enum ArrOfInt::Storage ArrOfInt::get_mem_storage() const
3940 + return storage_type_;
3944 +// Change le mode l'allocation memoire: reallocation d'un tableau
3945 +// a chaque changement de taille (flag = 0) ou reallocation
3946 +// uniquement si la taille augmente et par doublement de la taille
3947 +// du tableau (flag = 1).
3948 +void ArrOfInt::set_smart_resize(entier flag)
3950 + assert(flag == 0 || flag == 1);
3951 + smart_resize_ = flag;
3955 +// Remet le tableau dans l'etat obtenu avec le constructeur par defaut
3956 +// (libere la memoire mais conserve le mode d'allocation memoire actuel)
3957 +void ArrOfInt::reset()
3963 +// Copie les donnees du tableau m.
3964 +// Si "m" n'a pas la meme taille que "*this", on fait un resize_array.
3965 +// Ensuite, on copie les valeurs de "m" dans "*this".
3966 +// Le type de tableau (methode d'allocation) n'est pas copie.
3968 +// Si le tableau n'a pas la meme taille que "m", alors *this doit
3969 +// etre "resizable" (ne pas etre de type "ref_data" et "ref_count == 1")
3970 +// Parametre: const ArrOfInt& m
3971 +// Signification: la tableau a copier
3972 +// Retour: ArrOfInt&
3973 +// Signification: *this
3974 +ArrOfInt& ArrOfInt::operator=(const ArrOfInt& m)
3978 + const entier new_size = m.size_array();
3979 + // Le code suivant est quasiment une copie de ArrOfInt::resize()
3980 + // SAUF: memory_resize est appele avec NO_INITIALIZE (la zone de memoire
3981 + // n'est pas initialisee)
3982 + if (new_size != size_array())
3984 + if ((smart_resize_ == 0) || (new_size > memory_size_))
3985 + memory_resize(new_size, 0); // Pas d'initialisation
3986 + size_array_ = new_size;
3995 +// x est affecte a toutes les cases
3997 +// Parametre: entier x
3998 +// Signification: la valeur a affecter a toutes les cases du tableau
3999 +// Valeurs par defaut:
4002 +// Retour: ArrOfInt&
4003 +// Signification: *this
4008 +ArrOfInt& ArrOfInt::operator=(entier x)
4010 + const entier n = size_array();
4011 + entier *data = addr();
4012 + for (entier i = 0; i < n; i++)
4019 +// Description: appelle operator=(a)
4020 +ArrOfInt& ArrOfInt::copy_array(const ArrOfInt& a)
4027 +// Si besoin, alloue une nouvelle zone de memoire,
4028 +// copie les donnees et efface l'ancienne zone de memoire.
4029 +// Attention, on suppose que cette methode est appelee par
4031 +// Attention: si ref_count_>1, l'appel a resize_array() est
4032 +// autorise uniquement si la nouvelle taille est identique
4033 +// a la precedente.
4035 +// Le tableau doit etre de type "detache" ou "normal" avec
4036 +// ref_count==1, et il faut new_size >= 0
4037 +// On suppose que size_array contient encore le nombre d'elements
4038 +// valides avant changement de taille.
4039 +// Parametre: new_size
4040 +// Signification: nouvelle taille demandee pour le tableau.
4041 +// Parametre: options
4042 +// Signification: COPY_OLD => on recopie les anciennes donnees dans le nouveau
4043 +// tableau (jusqu'au max de l'ancienne et de la nouvelle taille).
4044 +// INITIALIZE_NEW => initialisation des cases non copiees
4046 +// p_ et data_ sont mis a jour, mais pas size_array_ !!!
4047 +// (on suppose que c'est fait dans resize_array()).
4048 +// Si la nouvelle taille est nulle, on detache le tableau.
4049 +void ArrOfInt::memory_resize(entier new_size, entier options)
4051 + assert(new_size >= 0);
4053 + // Occupation memoire de l'ancien tableau:
4054 + entier old_mem_size = 0;
4056 + old_mem_size = p_->get_size();
4058 + // Occupation memoire du nouveau tableau :
4059 + // Si smart_resize, on prend au moins deux fois la taille
4060 + // precedente, ou new_size
4061 + entier new_mem_size = new_size;
4062 + if (smart_resize_ && (old_mem_size * 2 > new_size))
4063 + new_mem_size = old_mem_size * 2;
4065 + if (new_mem_size != old_mem_size)
4067 + // detach_array() efface le contenu de size_array_. On le met de cote:
4068 + const entier old_size_array = size_array_;
4069 + // On va reellement changer l'adresse du tableau.
4070 + // Il ne faut pas qu'il existe d'autre reference a ce tableau.
4071 + assert(data_ == 0 || (p_ != 0 && ref_count() == 1));
4072 + if (new_mem_size == 0)
4074 + // La nouvelle taille est nulle, on cree un tableau "detache"
4079 + // Allocation d'une nouvelle zone
4080 + VIntdata * new_p = new VIntdata(new_mem_size, storage_type_);
4081 + entier * new_data = new_p->get_data();
4082 + // Raccourci si le tableau etait "detache", inutile de copier
4083 + // les anciennes donnees. On copie si COPY_OLD est demande
4084 + entier copy_size = 0;
4087 + // Calcul du nombre d'elements a copier vers la nouvelle
4088 + // zone de memoire : c'est le min de l'ancienne et de
4089 + // la nouvelle taille.
4090 + if (options & COPY_OLD)
4092 + copy_size = size_array_;
4093 + if (new_size < copy_size)
4094 + copy_size = new_size;
4095 + // Copie des valeurs dans le nouveau tableau
4096 + for (entier i = 0; i < copy_size; i++)
4097 + new_data[i] = data_[i];
4099 + // Destruction de l'ancienne zone (si plus aucune reference)
4102 + // On attache la nouvelle zone de memoire
4105 + memory_size_ = new_mem_size;
4106 + // Initialisation des cases supplementaires avec une valeur par defaut
4107 + if (options & INITIALIZE_NEW)
4108 + fill_default_value(copy_size, new_mem_size - copy_size);
4109 + // Restaure l'ancienne valeur de size_array_
4110 + size_array_ = old_size_array;
4116 +// Remplit "nb" cases consecutives du tableau a partir de la case "first"
4117 +// avec une valeur par defaut.
4118 +// Cette fonction est appelee lors d'un resize pour initialiser les
4119 +// cases nouvellement creees.
4120 +// Le comportement depend actuellement du type de tableau :
4121 +// * Tableau de type "smart_resize":
4122 +// * en mode debug (macro NDEBUG non definie) le tableau est initialise
4123 +// avec une valeur invalide.
4124 +// * en optimise, le tableau n'est pas initialise
4125 +// * Tableau normal :
4126 +// Le tableau est initialise avec la valeur 0. Ce comportement est choisi
4127 +// pour des raisons de compatibilite avec l'implementation precedente.
4128 +// Cette specification pourrait etre modifiee prochainement pour des raisons
4129 +// de performances (pour ne pas avoir a initialiser inutilement les tableaux).
4130 +// DONC: il faut supposer desormais que les nouvelles cases ne sont pas
4131 +// initialisees lors d'un resize.
4132 +// Parametre: first
4133 +// Signification: premiere case a initialiser.
4134 +// Contrainte: (nb==0) ou (0 <= first < memory_size_)
4136 +// Signification: nombre de cases a initialiser.
4137 +// Contrainte: (nb==0) ou (0 < nb <= memory_size_ - first)
4138 +void ArrOfInt::fill_default_value(entier first, entier nb)
4140 + assert((nb == 0) || (first >= 0 && first < memory_size_));
4141 + assert((nb == 0) || (nb > 0 && nb <= memory_size_ - first));
4142 + entier * data = addr();
4143 + assert(data!=0 || nb==0);
4145 + if (smart_resize_)
4148 + // On initialise uniquement en mode debug
4150 + static const entier ENTIER_INVALIDE = INT_MIN;
4151 + for (entier i = 0; i < nb; i++)
4152 + data[i] = ENTIER_INVALIDE;
4158 + // Comportement pour les tableaux normaux : compatibilite avec la
4159 + // version precedente : on initialise avec 0.
4160 + for (entier i = 0; i < nb; i++)
4161 + data[i] = (entier) 0;
4165 +// ****************************************************************
4167 +// Fonctions non membres de la classe ArrOfInt
4169 +// ****************************************************************
4172 +// Renvoie 1 si les tableaux "v" et "a" sont de la meme taille
4173 +// et contiennent les memes valeurs au sens strict, sinon renvoie 0.
4174 +// Le test est !(v[i]!=a[i])
4175 +entier operator==(const ArrOfInt& v, const ArrOfInt& a)
4177 + const entier n = v.size_array();
4178 + const entier na = a.size_array();
4186 + const entier* vv = v.addr();
4187 + const entier* av = a.addr();
4189 + for (i = 0; i < n; i++)
4191 + if (av[i] != vv[i])
4202 +// Retourne l'indice du min ou -1 si le tableau est vide
4204 +// Parametre: const ArrOfInt& dx
4205 +// Signification: tableau a utiliser
4207 +// Signification: indice du min
4208 +entier imin_array(const ArrOfInt& dx)
4210 + entier indice_min = -1;
4211 + const entier size = dx.size_array();
4215 + entier valeur_min = dx[0];
4216 + for(entier i = 1; i < size; i++)
4218 + const entier val = dx[i];
4219 + if(val < valeur_min)
4226 + return indice_min;
4230 +// Retourne l'indice du max ou -1 si le tableau est vide
4232 +// Parametre: const ArrOfInt& dx
4233 +// Signification: tableau a utiliser
4235 +// Signification: indice du max
4236 +entier imax_array(const ArrOfInt& dx)
4238 + entier indice_max = -1;
4239 + const entier size = dx.size_array();
4243 + entier valeur_max = dx[0];
4244 + for(entier i = 1; i < size; i++)
4246 + const entier val = dx[i];
4247 + if(val > valeur_max)
4254 + return indice_max;
4258 +// Retourne la valeur minimale
4260 +// Le tableau doit contenir au moins une valeur
4261 +// Parametre: const ArrOfInt& dx
4262 +// Signification: tableau a utiliser
4264 +// Signification: valeur du min
4265 +entier min_array(const ArrOfInt& dx)
4267 + const entier size = dx.size_array();
4269 + entier valeur_min = dx[0];
4270 + for(entier i = 1; i < size; i++)
4272 + const entier val = dx[i];
4273 + if (val < valeur_min)
4276 + return valeur_min;
4280 +// Retourne la valeur maximale
4282 +// Le tableau doit contenir au moins une valeur
4283 +// Parametre: const ArrOfInt& dx
4284 +// Signification: tableau a utiliser
4286 +// Signification: valeur du max
4287 +entier max_array(const ArrOfInt& dx)
4289 + const entier size = dx.size_array();
4291 + entier valeur_max = dx[0];
4292 + for(entier i = 1; i < size; i++)
4294 + const entier val = dx[i];
4295 + if (val > valeur_max)
4298 + return valeur_max;
4302 +// Fonction de comparaison utilisee pour trier le tableau
4303 +// dans ArrOfInt::trier(). Voir man qsort
4304 +static int fonction_compare_arrofentier_ordonner(const void * data1, const void * data2)
4306 + const entier x = *(const entier*)data1;
4307 + const entier y = *(const entier*)data2;
4312 +// Tri des valeurs du tableau dans l'ordre croissant.
4313 +// La fonction utilisee est qsort de stdlib (elle est en n*log(n)).
4314 +void ArrOfInt::ordonne_array()
4316 + const entier size = size_array();
4319 + entier * data = addr();
4320 + qsort(data, size, sizeof(entier),
4321 + fonction_compare_arrofentier_ordonner);
4326 +// Fait pointer le tableau vers les memes donnees qu'un tableau
4327 +// existant. Le tableau sera du meme type que le tableau m ("detache",
4328 +// "normal"). Le tableau m ne doit pas etre de type "ref_data"
4329 +// Les donnes existantes sont perdues si elles
4330 +// ne sont pas referencees ailleurs.
4332 +// Parametre: const ArrOfInt& m
4333 +// Signification: le tableau a referencer (pas de type "ref_data"
4334 +// et different de *this !!!)
4335 +// Retour: ArrOfInt&
4336 +// Signification: *this
4341 +ArrOfInt& ArrOfInt::ref_array(const ArrOfInt& m)
4343 + assert(&m != this);
4344 + // La condition 'm n'est pas de type "ref_data"' est necessaire pour
4345 + // attach_array().
4352 +// Fait pointer le tableau vers la zone de memoire "data_".
4353 +// On detache la zone de memoire existante. Le tableau devient
4354 +// de type "ref_data". Attention : ptr doit etre non nul.
4355 +// La taille est initialisee avec size.
4356 +// Cette methode est appelee notamment par IntVect::adopter.
4357 +// Parametre: entier*
4358 +// Signification: le tableau a recuperer. Si pointeur nul alors size
4359 +// doit etre nulle aussi et le tableau reste detache
4360 +// Parametre: entier size
4361 +// Signification: le nombre d'elements du tableau.
4362 +// Retour: ArrOfInt&
4363 +// Signification: *this
4364 +ArrOfInt& ArrOfInt::ref_data(entier* ptr, entier size)
4366 + assert(ptr != 0 || size == 0);
4367 + assert(size >= 0);
4370 + size_array_ = size;
4375 +// Amene le tableau dans l'etat "detache". C'est a dire:
4376 +// Si le tableau est "detache" :
4378 +// Si le tableau est "normal" :
4379 +// * decremente le nombre de references a *p
4380 +// * detruit *p si p->ref_count==0
4381 +// * annule p_, data_ et size_array_
4382 +// Si le tableau est "ref_data" :
4383 +// * annule data_ et size_array_
4385 +// Signification: 1 si les donnees du tableau ont ete supprimees
4388 +// On a p_==0, data_==0 et size_array_==0, memory_size_ = 0
4389 +// L'attribut smart_resize_ est conserve.
4390 +entier ArrOfInt::detach_array()
4392 + entier retour = 0;
4395 + // Le tableau est de type "normal"
4396 + // Si la zone de memoire n'est plus utilisee par personne,
4398 + if ((p_->suppr_one_ref()) == 0)
4412 +// Amene le tableau dans l'etat "normal", "detache" ou "ref_array"
4413 +// en associant la meme zone de memoire que le tableau m.
4415 +// Le tableau doit etre "detache"
4416 +// Parametre: const ArrOfInt& m
4417 +// Signification: tableau a utiliser
4418 +// le tableau doit etre different de *this !!!
4425 +// Si m est detache, le tableau reste detache,
4426 +// si m est "ref_array", le tableau devient "ref_array",
4427 +// sinon le tableau est "normal", avec ref_count > 1
4428 +// Si m est de taille nulle, le tableau reste detache + Warning dans fichier .log
4429 +void ArrOfInt::attach_array(const ArrOfInt& m)
4431 + // Le tableau doit etre detache
4432 + assert(data_ == 0 && p_ == 0);
4433 + // Le tableau doit etre different de *this
4434 + assert(&m != this);
4436 + if (m.size_array() > 0)
4440 + p_->add_one_ref();
4442 + size_array_ = m.size_array_;
4443 + memory_size_ = m.memory_size_;
4444 + smart_resize_ = m.smart_resize_;
4448 + // Cas particulier ou on attache un tableau de taille nulle:
4449 + // en theorie, c'est pareil qu'un tableau de taille non nulle, MAIS
4450 + // dans les operateurs (ex:Op_Dift_VDF_Face_Axi), une ref est construite
4451 + // avant que le tableau ne prenne sa taille definitive. Donc, pour ne pas
4452 + // empecher le resize, il ne faut pas attacher le tableau s'il n'a pas
4453 + // encore la bonne taille. Solution propre: reecrire les operateurs pour
4454 + // qu'ils ne prennent pas une ref avant que le tableau ne soit valide
4455 + // et faire p_ = m.p_ dans tous les cas.
4460 +// Copie les elements source[first_element_source + i]
4461 +// dans les elements (*this)[first_element_dest + i] pour 0 <= i < nb_elements
4462 +// Les autres elements de (*this) sont inchanges.
4464 +// Parametre: const ArrOfInt& m
4465 +// Signification: le tableau a utiliser, doit etre different de *this !
4466 +// Parametre: entier nb_elements
4467 +// Signification: nombre d'elements a copier, nb_elements >= -1.
4468 +// Si nb_elements==-1, on copie tout le tableau m.
4469 +// Valeurs par defaut: -1
4470 +// Parametre: entier first_element_dest
4471 +// Valeurs par defaut: 0
4472 +// Parametre: entier first_element_source
4473 +// Valeurs par defaut: 0
4474 +// Retour: ArrOfInt&
4475 +// Signification: *this
4478 +// Sort en erreur si la taille du tableau m est plus grande que la
4479 +// taille de tableau this.
4482 +ArrOfInt& ArrOfInt::inject_array(const ArrOfInt& source,
4483 + entier nb_elements,
4484 + entier first_element_dest,
4485 + entier first_element_source)
4487 + assert(&source != this);
4488 + assert(nb_elements >= -1);
4489 + assert(first_element_dest >= 0);
4490 + assert(first_element_source >= 0);
4492 + if (nb_elements < 0)
4493 + nb_elements = source.size_array();
4495 + assert(first_element_source + nb_elements <= source.size_array());
4496 + assert(first_element_dest + nb_elements <= size_array());
4498 + if (nb_elements > 0)
4500 + entier * addr_dest = addr() + first_element_dest;
4501 + const entier * addr_source = source.addr() + first_element_source;
4502 + // memcpy(addr_dest , addr_source, nb_elements * sizeof(entier));
4504 + for (i = 0; i < nb_elements; i++)
4506 + addr_dest[i] = addr_source[i];
4513 +// Retourne le nombre de references des donnees du tableau
4514 +// si le tableau est "normal", -1 s'il est "detache" ou "ref_data"
4516 +// Signification: ref_count_
4517 +entier ArrOfInt::ref_count() const
4520 + return p_->ref_count();
4526 +// Addition case a case sur toutes les cases du tableau
4528 +// la taille de y doit etre au moins egale a la taille de this
4529 +// Parametre: const ArrOfInt& y
4530 +// Signification: tableau a ajouter
4531 +// Valeurs par defaut:
4534 +// Retour: ArrOfInt&
4535 +// Signification: *this
4540 +ArrOfInt& ArrOfInt::operator+=(const ArrOfInt& y)
4542 + assert(size_array()==y.size_array());
4543 + entier* dx = addr();
4544 + const entier* dy = y.addr();
4545 + const entier n = size_array();
4546 + for (entier i=0; i<n; i++)
4552 +// ajoute la meme valeur a toutes les cases du tableau
4554 +// Parametre: const entier dy
4555 +// Signification: valeur a ajouter
4556 +// Valeurs par defaut:
4559 +// Retour: ArrOfInt
4560 +// Signification: *this
4565 +ArrOfInt& ArrOfInt::operator+=(const entier dy)
4567 + entier * data = addr();
4568 + const entier n = size_array();
4569 + for(entier i=0; i < n; i++)
4574 +// Soustraction case a case sur toutes les cases du tableau
4575 +// Parametre: const ArrOfInt& y
4576 +// Signification: tableau de meme taille que *this
4577 +// Retour: ArrOfInt&
4578 +// Signification: *this
4579 +ArrOfInt& ArrOfInt::operator-=(const ArrOfInt& y)
4581 + const entier size = size_array();
4582 + assert(size == y.size_array());
4583 + entier * data = addr();
4584 + const entier * data_y = y.addr();
4585 + for (entier i=0; i < size; i++)
4586 + data[i] -= data_y[i];
4592 +// soustrait la meme valeur a toutes les cases
4593 +// Retour: ArrOfInt &
4594 +// Signification: *this
4595 +ArrOfInt& ArrOfInt::operator-=(const entier dy)
4597 + entier * data = addr();
4598 + const entier n = size_array();
4599 + for(entier i=0; i < n; i++)
4605 +// Renvoie un pointeur sur le premier element du tableau.
4606 +// Le pointeur est nul si le tableau est "detache".
4607 +// Attention, l'adresse peut changer apres un appel
4608 +// a resize_array(), ref_data, ref_array, ...
4610 +// Retour: const entier*
4611 +// Signification: pointeur sur le premier element du tableau
4612 +const entier* ArrOfInt::addr() const
4618 +// Renvoie un pointeur sur le premier element du tableau.
4619 +// Le pointeur est nul si le tableau est "detache".
4621 +// Retour: const entier*
4622 +// Signification: la zone memoire du tableau
4623 +entier* ArrOfInt::addr()
4632 + dimensions_[0] = 0;
4633 + dimensions_[1] = 0;
4636 +IntTab::IntTab(const IntTab& tab) :
4639 + // nb_dim_ = tab.nb_dim_;
4640 + dimensions_[0] = tab.dimensions_[0];
4641 + dimensions_[1] = tab.dimensions_[1];
4643 +IntTab::IntTab(const entier i, const entier j) :
4647 + dimensions_[0] = i;
4648 + dimensions_[1] = j;
4651 +IntTab& IntTab::operator=(const IntTab& tab)
4653 + ArrOfInt::operator=(tab);
4654 + // nb_dim_ = tab.nb_dim_;
4655 + dimensions_[0] = tab.dimensions_[0];
4656 + dimensions_[1] = tab.dimensions_[1];
4660 +void IntTab::reset()
4662 + ArrOfInt::reset();
4664 + dimensions_[0] = 0;
4665 + dimensions_[1] = 0;
4668 diff --git a/databases/readers/Lata/ArrOfInt.h b/databases/readers/Lata/ArrOfInt.h
4669 new file mode 100644
4670 index 0000000..9d9a542
4672 +++ b/databases/readers/Lata/ArrOfInt.h
4674 +/*****************************************************************************
4676 +* Copyright (c) 2011 - 2013, CEA
4677 +* All rights reserved.
4678 +* Redistribution and use in source and binary forms, with or without
4679 +* modification, are permitted provided that the following conditions are met:
4681 +* * Redistributions of source code must retain the above copyright
4682 +* notice, this list of conditions and the following disclaimer.
4683 +* * Redistributions in binary form must reproduce the above copyright
4684 +* notice, this list of conditions and the following disclaimer in the
4685 +* documentation and/or other materials provided with the distribution.
4686 +* * Neither the name of CEA, nor the
4687 +* names of its contributors may be used to endorse or promote products
4688 +* derived from this software without specific prior written permission.
4690 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
4691 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4692 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
4693 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
4694 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
4695 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4696 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
4697 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
4698 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4699 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4701 +*****************************************************************************/
4703 +////////////////////////////////////////////////////////////
4705 +// Warning : DO NOT EDIT !
4706 +// Please update ArrOf_Scalar_Prototype.h.P
4707 +// and this file will be generated automatically
4708 +// by the script file check.sh
4709 +////////////////////////////////////////////////////////////
4714 +#include <assert.h>
4716 +#include <Objet_U.h>
4727 + virtual ~ArrOfInt();
4732 + ArrOfInt(entier size);
4733 + ArrOfInt(entier size, entier initial_value);
4734 + // Constructeur par copie : deep copy (on duplique les donnees)
4735 + ArrOfInt(const ArrOfInt& );
4737 + // Methodes de construction tardive (on cree un tableau vide avec ArrOfInt()
4738 + // puis on appelle ces methodes pour modifier les caracteristiques du tableau :
4740 + // Change le nombre d'elements du tableau
4741 + inline ArrOfInt& resize_array(entier new_size);
4743 + // Methodes de gestion de l'allocation memoire:
4744 + // Assigne une valeur au drapeau "smart_resize"
4745 + // (reallocation uniquement si la taille augmente)
4746 + void set_smart_resize(entier flag);
4747 + // Gestion du type de memoire alouee (standard ou pool de memoire Trio-U)
4748 + enum Storage { STANDARD, TEMP_STORAGE, SIMD_ALIGNED };
4749 + void set_mem_storage(const Storage storage);
4750 + Storage get_mem_storage() const;
4752 + // Construction de tableaux qui pointent vers des donnees existantes
4753 + // !!! Utiliser ref_data avec precaution (attention a size_array_)
4754 + ArrOfInt& ref_data(entier* ptr, entier size);
4755 + ArrOfInt& ref_array(const ArrOfInt&);
4756 + // Operateur copie
4757 + ArrOfInt& operator=(const ArrOfInt&);
4758 + // Remise du tableau dans l'etat initial (obtenu par le constructeur par defaut)
4759 + virtual void reset();
4762 + // Methodes d'acces aux donnees et aux caracteristiques du tableau
4764 + // Remplit le tableau avec la valeur en parametre
4765 + ArrOfInt& operator=(entier valeur);
4767 + inline entier& operator[](entier i);
4768 + inline const entier& operator[](entier i) const;
4770 + // Ces methodes renvoient un pointeur vers le premier element du tableau.
4771 + const entier * addr() const;
4773 + // Renvoie le nombre d'elements du tableau (et non la taille allouee)
4774 + inline entier size_array() const;
4775 + // Renvoie le nombre de tableaux qui pointent vers la stucture "*p_"
4776 + entier ref_count() const;
4777 + // Ajoute une case en fin de tableau et y stocke la "valeur"
4778 + inline void append_array(entier valeur);
4781 + // Operateurs divers
4783 + ArrOfInt& operator+=(const ArrOfInt&);
4784 + ArrOfInt& operator+=(const entier);
4785 + ArrOfInt& operator-=(const ArrOfInt&);
4786 + ArrOfInt& operator-=(const entier);
4787 + ArrOfInt& inject_array(const ArrOfInt& source,
4788 + entier nb_elements = -1,
4789 + entier first_element_dest = 0,
4790 + entier first_element_source = 0);
4791 + ArrOfInt& copy_array(const ArrOfInt&);
4794 + void ordonne_array();
4798 + // Methodes accessibles depuis les descendants de ArrOfInt
4800 + void attach_array(const ArrOfInt&);
4801 + entier detach_array();
4802 + void fill_default_value(entier first, entier nb);
4804 + // B. Mathieu 22/06/2004 : je mets ces membres "private" pour forcer
4805 + // le passage par les accesseurs dans les classes derivees, au cas ou
4806 + // on voudrait modifier l'implementation.
4808 + // Zone de memoire contenant les valeurs du tableau.
4809 + // Pointeur nul => le tableau est "detache" ou "ref_data"
4810 + // Pointeur non nul => le tableau est "normal"
4813 + // Pointeur vers le premier element du tableau (egal a p_->data si p_!=0)
4814 + // Pointeur nul => le tableau est "detache".
4815 + // Pointeur non nul => le tableau est "normal" ou "ref_data"
4818 + // Nombre d'elements du tableau (inferieur ou egal a memory_size_).
4819 + // Si le tableau est "detache", alors size_array_=0
4820 + entier size_array_;
4821 + // Taille memoire reellement allouee pour le tableau
4822 + // (pour le mecanisme smart_resize_). memory_size_ est nul
4823 + // si le tableau est de type "ref_data". Sinon memory_size_
4824 + // est egal a p_->size_.
4825 + entier memory_size_;
4827 + // Drapeau indiquant si on applique une strategie d'allocation
4828 + // preventive (la memoire alouee augmente d'un facteur constant
4829 + // si la taille devient insuffisante).
4830 + // Si smart_resize_ == 0, alors on a toujours p_->size_ == size
4831 + entier smart_resize_;
4833 + // Drapeau indiquant si l'allocation memoire a lieu avec un new classique
4834 + // ou dans le pool de memoire temporaire de Trio
4835 + Storage storage_type_;
4837 + // Partie non inline de resize_array():
4838 + // Declaration des constantes pour les options de memory_resize
4839 + static const entier COPY_OLD;
4840 + static const entier INITIALIZE_NEW;
4841 + void memory_resize(entier new_size, entier options);
4844 +#define MAXDIMIntTab 2
4846 +class IntTab : public ArrOfInt
4850 + IntTab(const IntTab&);
4851 + IntTab(const entier i, const entier j);
4852 + IntTab& operator=(const IntTab&);
4855 + inline entier& operator()(entier i, entier j);
4856 + inline entier operator()(entier i, entier j) const;
4858 + inline entier resize(entier i, entier j);
4859 + inline entier dimension(entier i) const;
4860 + inline entier dimension_tot(entier i) const;
4863 + // In order to mimic TRUST behavior, operator[] is forbidden
4864 + // for 2 dimensionnal matrices, you must cast to ArrOf to use it..
4865 + double& operator[](entier i);
4866 + const double& operator[](entier i) const;
4869 + // entier nb_dim_;
4870 + entier dimensions_[MAXDIMIntTab];
4873 +inline entier& IntTab::operator()(entier i, entier j)
4875 + // assert(nb_dim_ == 2);
4876 + assert(i >= 0 && i < dimensions_[0] && j >= 0 && j < dimensions_[1]);
4877 + const entier n = i * dimensions_[1] + j;
4878 + entier& x = ArrOfInt::operator[] (n);
4882 +inline entier IntTab::operator()(entier i, entier j) const
4884 + // assert(nb_dim_ == 2);
4885 + assert(i >= 0 && i < dimensions_[0] && j >= 0 && j < dimensions_[1]);
4886 + const entier n = i * dimensions_[1] + j;
4887 + entier x = ArrOfInt::operator[] (n);
4891 +inline entier IntTab::resize(entier i, entier j)
4893 + assert(i >= 0 && j >= 0);
4895 + dimensions_[0] = i;
4896 + dimensions_[1] = j;
4897 + ArrOfInt::resize_array(i * j);
4901 +inline entier IntTab::dimension(entier i) const
4903 + assert(i >= 0 && i < 2);
4904 + return dimensions_[i];
4907 +// Description: renvoie la meme valeur que dimension.
4908 +inline entier IntTab::dimension_tot(entier i) const
4910 + return dimension(i);
4914 +// Declarations des fonctions non membres de la classe ArrOfInt
4916 +entier operator==(const ArrOfInt& x, const ArrOfInt& y) ;
4917 +entier imin_array(const ArrOfInt&) ;
4918 +entier imax_array(const ArrOfInt&) ;
4919 +entier min_array(const ArrOfInt&) ;
4920 +entier max_array(const ArrOfInt&) ;
4923 +// ******************************************************************
4924 +// FONCTIONS MEMBRES DE ArrOfInt
4925 +// ******************************************************************
4928 +// Change le nombre d'elements du tableau. Cette fonction est inline
4929 +// car elle doit etre tres rapide dans le cas ou smart_resize_==1
4930 +// (utilisation frequente de resize_array())
4931 +// Si smart_resize est non nul :
4932 +// Si la nouvelle taille est inferieure ou egale a la taille
4933 +// alouee (p->get_size()) on ne realloue pas de memoire
4934 +// sinon, on realloue et on copie les donnees existantes.
4935 +// Astuce pour ne pas copier les anciennes donnees:
4936 +// resize(0); resize(n);
4937 +// Si smart_resize est nul, on realloue une nouvelle zone memoire
4938 +// uniquement si la nouvelle taille est differente de l'ancienne.
4940 +// Si "new_size" est egal a la taille du tableau, aucune condition.
4941 +// Sinon, le tableau doit etre soit detache, soit normal (pas de type "ref_data")
4942 +// et ref_count doit etre egal a 1 (pas d'autre reference au tableau).
4944 +inline ArrOfInt& ArrOfInt::resize_array(entier new_size)
4946 + assert(new_size >= 0);
4947 + // Soit le tableau est detache (data_==0), soit il est normal (p_!=0)
4948 + // S'il est normal, il ne faut pas qu'il y ait d'autre reference au tableau,
4949 + // ou alors la taille ne doit pas changer.
4950 + assert(new_size == size_array_ || data_ == 0 || (p_ != 0 && ref_count() == 1));
4952 + if ((smart_resize_ == 0) || (new_size > memory_size_))
4953 + memory_resize(new_size, COPY_OLD + INITIALIZE_NEW);
4954 + size_array_ = new_size;
4959 +// operateur [] retourne le ieme element du tableau
4961 +// Parametre: entier i
4962 +// Signification: indice dans l'intervalle 0 <= i < size_array()
4964 +// assert si i n'est pas dans l'intervalle
4965 +inline entier& ArrOfInt::operator[](entier i)
4967 + assert(i >= 0 && i < size_array_);
4972 +// operateur [] retourne le ieme element du tableau
4974 +// Parametre: entier i
4975 +// Signification: indice dans l'intervalle 0 <= i < size_array()
4977 +// assert si i n'est pas dans l'intervalle
4978 +inline const entier& ArrOfInt::operator[](entier i) const
4980 + assert(i >= 0 && i < size_array_);
4985 +// Renvoie la taille du tableau (nombre d'elements declares
4986 +// a la construction ou a resize_array()).
4987 +// C'est le nombre d'elements accessibles a operator[]
4989 +inline entier ArrOfInt::size_array() const
4991 + return size_array_;
4995 +// Ajoute une case en fin de tableau et y stocke la "valeur"
4997 +// Tableau doit etre de type "smart_resize" (sinon, ecroulement
4998 +// des performances). De plus, le tableau ne doit pas etre "ref_data",
4999 +// et il ne doit pas y avoir plus d'une reference a la zone de
5000 +// memoire pointee (meme precondition que resize_array())
5001 +inline void ArrOfInt::append_array(entier valeur)
5003 + assert(smart_resize_);
5004 + // Soit le tableau est detache (data_==0), soit il est normal (p_!=0)
5005 + // S'il est normal, il ne faut pas qu'il y ait d'autre reference au tableau.
5006 + assert(data_ == 0 || (p_ != 0 && ref_count() == 1));
5008 + if (size_array_+1 > memory_size_)
5009 + memory_resize(size_array_+1, COPY_OLD);
5010 + data_[size_array_] = valeur;
5017 diff --git a/databases/readers/Lata/ArrOf_Scalar_Prototype.cpp.h b/databases/readers/Lata/ArrOf_Scalar_Prototype.cpp.h
5018 new file mode 100644
5019 index 0000000..b881750
5021 +++ b/databases/readers/Lata/ArrOf_Scalar_Prototype.cpp.h
5023 +/*****************************************************************************
5025 +* Copyright (c) 2011 - 2013, CEA
5026 +* All rights reserved.
5027 +* Redistribution and use in source and binary forms, with or without
5028 +* modification, are permitted provided that the following conditions are met:
5030 +* * Redistributions of source code must retain the above copyright
5031 +* notice, this list of conditions and the following disclaimer.
5032 +* * Redistributions in binary form must reproduce the above copyright
5033 +* notice, this list of conditions and the following disclaimer in the
5034 +* documentation and/or other materials provided with the distribution.
5035 +* * Neither the name of CEA, nor the
5036 +* names of its contributors may be used to endorse or promote products
5037 +* derived from this software without specific prior written permission.
5039 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
5040 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5041 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5042 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
5043 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5044 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5045 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5046 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5047 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5048 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5050 +*****************************************************************************/
5052 +#include <ArrOf__Scalar__.h>
5053 +__DoubleOnlyBegin__
5057 +// limits.h definit INT_MIN, SHRT_MIN, ...
5058 +#include <limits.h>
5060 +#include <stdlib.h>
5061 +#include <Objet_U.h>
5062 +#include <iostream>
5063 +#include <stdlib.h>
5065 +// ******************************************************************
5067 +// Implementation des methodes de V__Scalar__data
5069 +// ******************************************************************
5070 +////////////////////////////////////////////////////////////////////
5071 +// .NOM ArrOf__Scalar__
5072 +// .ENTETE TRUST Math
5073 +// .LIBRAIRIE libtmath
5074 +// .FILE ArrOf__Scalar__.h
5075 +// .FILE ArrOf__Scalar__.cpp
5078 +// V__Scalar__data alloue une zone de memoire de la taille specifiee au
5079 +// constructeur, et libere la zone de memoire a la destruction.
5080 +// La memoire peut etre allouee sur le tas (avec new) ou par le
5081 +// mecanisme Memoire::add_trav___scalar__.
5083 +// "ref_count" compte le nombre de pointeurs qui font reference a "this".
5084 +// (permet au dernier utilisateur de l'objet de le detruire), voir
5085 +// ArrOf__Scalar__.
5087 +// .SECTION voir aussi
5092 +///////////////////////////////////////////////////////////////////
5094 +class V__Scalar__data
5097 + V__Scalar__data(entier size, ArrOf__Scalar__::Storage storage);
5098 + ~V__Scalar__data();
5099 + entier add_one_ref();
5100 + entier suppr_one_ref();
5101 + __scalar__ * get_data();
5102 + const __scalar__ * get_data() const;
5103 + inline entier ref_count() const;
5104 + inline entier get_size() const;
5106 + // Le constructeur par copie et l'operateur= sont interdits.
5107 + V__Scalar__data(const V__Scalar__data& v);
5108 + V__Scalar__data& operator=(const V__Scalar__data& v);
5110 + // "data" est un pointeur sur une zone de memoire de taille
5111 + // sz * sizeof(__scalar__), allouee par le
5112 + // constructeur et liberee par le destructeur.
5113 + // Ce pointeur n'est jamais nul meme si size_==0
5114 + __scalar__ * data_;
5115 + // Compteur incremente par add_one_ref et decremente par suppr_one_ref.
5116 + // Contient le nombre d'objets ArrOf__Scalar__ dont le membre "p" pointe
5117 + // vers "this". On a ref_count_ >= 0.
5118 + entier ref_count_;
5119 + // "sz" est la taille du tableau "data_" alloue
5122 + // Si storage est de type TEMP_STORAGE, d_ptr_trav porte la reference
5123 + // a la zone allouee, sinon le pointeur est nul.
5124 + //__Scalar___ptr_trav * d_ptr_trav_;
5129 +// Construit un V__Scalar__data de taille size >= 0
5130 +// Parametre: entier s
5131 +// Signification: taille du V__Scalar__data, il faut size >= 0
5132 +// Parametre: Storage storage
5133 +// Signification: indique si la memoire doit etre allouee
5134 +// avec "new" ou avec "memoire.add_trav___scalar__()"
5135 +// Valeurs par defaut: STANDARD (allocation avec "new")
5137 +// data_ n'est jamais nul, meme si size==0
5138 +V__Scalar__data::V__Scalar__data(entier size, ArrOf__Scalar__::Storage storage)
5141 + storage = ArrOf__Scalar__::STANDARD;
5145 + case ArrOf__Scalar__::STANDARD:
5148 + // Allocation de la memoire sur le tas
5151 + data_ = new __scalar__[size];
5155 + Cerr << "impossible d'allouer " << size << " __scalar__ " << finl;
5159 + data_ = new __scalar__[size];
5162 + Cerr << "impossible d'allouer " << size << "__scalar__ " << finl;
5174 + assert(data_ != 0);
5178 +// Detruit la zone de memoire allouee.
5180 +// ref_count == 0 (la zone de memoire ne doit etre referencee nulle part)
5181 +V__Scalar__data::~V__Scalar__data()
5183 + assert(ref_count_ == 0);
5185 + // Stockage STANDARD
5188 + data_ = 0; // paranoia: si size_==-1 c'est qu'on pointe sur un zombie
5189 + size_ = -1; // (pointeur vers un objet qui a ete detruit)
5192 +// Description: renvoie ref_count_
5193 +inline entier V__Scalar__data::ref_count() const
5195 + return ref_count_;
5198 +// Description: renvoie size_
5199 +inline entier V__Scalar__data::get_size() const
5205 +// Un nouveau tableau utilise cette zone memoire :
5206 +// incremente ref_count
5208 +// Signification: ref_count
5209 +inline entier V__Scalar__data::add_one_ref()
5211 + return ++ref_count_;
5215 +// Un tableau de moins utilise cette zone memoire
5216 +// decremente ref_count
5220 +// Signification: ref_count
5221 +inline entier V__Scalar__data::suppr_one_ref()
5223 + assert(ref_count_ > 0);
5224 + return (--ref_count_);
5227 +// Description: renvoie data_
5228 +inline __scalar__ * V__Scalar__data::get_data()
5233 +// Description: renvoie data_
5234 +inline const __scalar__ * V__Scalar__data::get_data() const
5239 +// Description: Constructeur par copie. Interdit : genere une erreur !
5240 +V__Scalar__data::V__Scalar__data(const V__Scalar__data& v)
5242 + Cerr << "Erreur dans V__Scalar__data::V__Scalar__data(const V__Scalar__data & v)" << finl;
5246 +// Description: Operateur= interdit. Genere une erreur !
5247 +V__Scalar__data& V__Scalar__data::operator=(const V__Scalar__data& v)
5249 + Cerr << "Erreur dans V__Scalar__data::operator=(const V__Scalar__data & v)" << finl;
5254 +// ******************************************************************
5256 +// Implementation des methodes de ArrOf__Scalar__
5258 +// ******************************************************************
5261 +// Definition des constantes pour les options de memory_resize
5262 +const entier ArrOf__Scalar__::COPY_OLD = 1;
5263 +const entier ArrOf__Scalar__::INITIALIZE_NEW = 2;
5266 +// Destructeur : appelle detach_array()
5267 +ArrOf__Scalar__::~ArrOf__Scalar__()
5270 + size_array_ = -1; // Paranoia: si size_array_==-1, c'est un zombie
5274 +// Constructeur par defaut: cree un tableau "detache",
5275 +// soit p_==0, data_==0, size_array_==0, smart_resize_==0
5276 +ArrOf__Scalar__::ArrOf__Scalar__() :
5282 + storage_type_(STANDARD)
5287 +// Cree un tableau de taille n avec allocation standard
5288 +// (voir set_mem_storage).
5289 +// Valeur de remplissage par defaut: voir fill_default_value
5291 +// Parametre: entier n
5292 +// Signification: taille du tableau
5293 +ArrOf__Scalar__::ArrOf__Scalar__(entier n) :
5294 + p_(new V__Scalar__data(n, STANDARD)),
5295 + data_(p_->get_data()),
5299 + storage_type_(STANDARD)
5302 + fill_default_value(0, n);
5306 +// Cree un tableau de taille n
5307 +// toutes les cases sont initialisees a x
5309 +// Parametre: entier n
5310 +// Signification: taille du tableau
5311 +// Parametre: __scalar__ x
5312 +// Signification: valeur pour initialiser le tableau
5313 +ArrOf__Scalar__::ArrOf__Scalar__(entier n, __scalar__ x) :
5314 + p_(new V__Scalar__data(n, STANDARD)),
5315 + data_(p_->get_data()),
5319 + storage_type_(STANDARD)
5325 +// Constructeur par copie. On alloue une nouvelle zone de memoire
5326 +// et on copie le contenu du tableau. L'attribut smart_resize_ est
5328 +// Si le tableau A est de taille nulle, on cree un tableau "detache",
5329 +// sinon on cree un tableau "normal".
5330 +// Parametre: const ArrOf__Scalar__& A
5331 +// Signification: le tableau a copier
5332 +ArrOf__Scalar__::ArrOf__Scalar__(const ArrOf__Scalar__& A)
5334 + const entier size = A.size_array();
5337 + // Creation d'un tableau "normal"
5338 + storage_type_ = STANDARD;
5339 + p_ = new V__Scalar__data(size, STANDARD);
5340 + data_ = p_->get_data();
5341 + size_array_ = size;
5342 + memory_size_ = size;
5343 + smart_resize_ = A.smart_resize_;
5348 + // Creation d'un tableau "detache"
5353 + smart_resize_ = 0;
5354 + storage_type_ = STANDARD;
5359 +// Change le mode d'allocation memoire lors des resize
5360 +// (voir V__Scalar__data et __Scalar___ptr_trav)
5361 +// Exemple pour creer un tableau avec allocation temporaire:
5362 +// DoubleTab tab; // Creation d'un tableau vide
5363 +// tab.set_mem_storage(TEMP_STORAGE); // Changement de mode d'allocation
5364 +// tab.resize(n); // Allocation memoire
5365 +void ArrOf__Scalar__::set_mem_storage(const Storage storage)
5367 + storage_type_ = storage;
5371 +// Renvoie le mode d'allocation du tableau (qui sera utilise
5372 +// lors du prochain resize si changement de taille).
5373 +// (voir V__Scalar__data et __Scalar___ptr_trav)
5374 +enum ArrOf__Scalar__::Storage ArrOf__Scalar__::get_mem_storage() const
5376 + return storage_type_;
5380 +// Change le mode l'allocation memoire: reallocation d'un tableau
5381 +// a chaque changement de taille (flag = 0) ou reallocation
5382 +// uniquement si la taille augmente et par doublement de la taille
5383 +// du tableau (flag = 1).
5384 +void ArrOf__Scalar__::set_smart_resize(entier flag)
5386 + assert(flag == 0 || flag == 1);
5387 + smart_resize_ = flag;
5391 +// Remet le tableau dans l'etat obtenu avec le constructeur par defaut
5392 +// (libere la memoire mais conserve le mode d'allocation memoire actuel)
5393 +void ArrOf__Scalar__::reset()
5399 +// Copie les donnees du tableau m.
5400 +// Si "m" n'a pas la meme taille que "*this", on fait un resize_array.
5401 +// Ensuite, on copie les valeurs de "m" dans "*this".
5402 +// Le type de tableau (methode d'allocation) n'est pas copie.
5404 +// Si le tableau n'a pas la meme taille que "m", alors *this doit
5405 +// etre "resizable" (ne pas etre de type "ref_data" et "ref_count == 1")
5406 +// Parametre: const ArrOf__Scalar__& m
5407 +// Signification: la tableau a copier
5408 +// Retour: ArrOf__Scalar__&
5409 +// Signification: *this
5410 +ArrOf__Scalar__& ArrOf__Scalar__::operator=(const ArrOf__Scalar__& m)
5414 + const entier new_size = m.size_array();
5415 + // Le code suivant est quasiment une copie de ArrOf__Scalar__::resize()
5416 + // SAUF: memory_resize est appele avec NO_INITIALIZE (la zone de memoire
5417 + // n'est pas initialisee)
5418 + if (new_size != size_array())
5420 + if ((smart_resize_ == 0) || (new_size > memory_size_))
5421 + memory_resize(new_size, 0); // Pas d'initialisation
5422 + size_array_ = new_size;
5431 +// x est affecte a toutes les cases
5433 +// Parametre: __scalar__ x
5434 +// Signification: la valeur a affecter a toutes les cases du tableau
5435 +// Valeurs par defaut:
5438 +// Retour: ArrOf__Scalar__&
5439 +// Signification: *this
5444 +ArrOf__Scalar__& ArrOf__Scalar__::operator=(__scalar__ x)
5446 + const entier n = size_array();
5447 + __scalar__ *data = addr();
5448 + for (entier i = 0; i < n; i++)
5455 +// Description: appelle operator=(a)
5456 +ArrOf__Scalar__& ArrOf__Scalar__::copy_array(const ArrOf__Scalar__ & a)
5463 +// Si besoin, alloue une nouvelle zone de memoire,
5464 +// copie les donnees et efface l'ancienne zone de memoire.
5465 +// Attention, on suppose que cette methode est appelee par
5467 +// Attention: si ref_count_>1, l'appel a resize_array() est
5468 +// autorise uniquement si la nouvelle taille est identique
5469 +// a la precedente.
5471 +// Le tableau doit etre de type "detache" ou "normal" avec
5472 +// ref_count==1, et il faut new_size >= 0
5473 +// On suppose que size_array contient encore le nombre d'elements
5474 +// valides avant changement de taille.
5475 +// Parametre: new_size
5476 +// Signification: nouvelle taille demandee pour le tableau.
5477 +// Parametre: options
5478 +// Signification: COPY_OLD => on recopie les anciennes donnees dans le nouveau
5479 +// tableau (jusqu'au max de l'ancienne et de la nouvelle taille).
5480 +// INITIALIZE_NEW => initialisation des cases non copiees
5482 +// p_ et data_ sont mis a jour, mais pas size_array_ !!!
5483 +// (on suppose que c'est fait dans resize_array()).
5484 +// Si la nouvelle taille est nulle, on detache le tableau.
5485 +void ArrOf__Scalar__::memory_resize(entier new_size, entier options)
5487 + assert(new_size >= 0);
5489 + // Occupation memoire de l'ancien tableau:
5490 + entier old_mem_size = 0;
5492 + old_mem_size = p_->get_size();
5494 + // Occupation memoire du nouveau tableau :
5495 + // Si smart_resize, on prend au moins deux fois la taille
5496 + // precedente, ou new_size
5497 + entier new_mem_size = new_size;
5498 + if (smart_resize_ && (old_mem_size * 2 > new_size))
5499 + new_mem_size = old_mem_size * 2;
5501 + if (new_mem_size != old_mem_size)
5503 + // detach_array() efface le contenu de size_array_. On le met de cote:
5504 + const entier old_size_array = size_array_;
5505 + // On va reellement changer l'adresse du tableau.
5506 + // Il ne faut pas qu'il existe d'autre reference a ce tableau.
5507 + assert(data_ == 0 || (p_ != 0 && ref_count() == 1));
5508 + if (new_mem_size == 0)
5510 + // La nouvelle taille est nulle, on cree un tableau "detache"
5515 + // Allocation d'une nouvelle zone
5516 + V__Scalar__data * new_p = new V__Scalar__data(new_mem_size, storage_type_);
5517 + __scalar__ * new_data = new_p->get_data();
5518 + // Raccourci si le tableau etait "detache", inutile de copier
5519 + // les anciennes donnees. On copie si COPY_OLD est demande
5520 + entier copy_size = 0;
5523 + // Calcul du nombre d'elements a copier vers la nouvelle
5524 + // zone de memoire : c'est le min de l'ancienne et de
5525 + // la nouvelle taille.
5526 + if (options & COPY_OLD)
5528 + copy_size = size_array_;
5529 + if (new_size < copy_size)
5530 + copy_size = new_size;
5531 + // Copie des valeurs dans le nouveau tableau
5532 + for (entier i = 0; i < copy_size; i++)
5533 + new_data[i] = data_[i];
5535 + // Destruction de l'ancienne zone (si plus aucune reference)
5538 + // On attache la nouvelle zone de memoire
5541 + memory_size_ = new_mem_size;
5542 + // Initialisation des cases supplementaires avec une valeur par defaut
5543 + if (options & INITIALIZE_NEW)
5544 + fill_default_value(copy_size, new_mem_size - copy_size);
5545 + // Restaure l'ancienne valeur de size_array_
5546 + size_array_ = old_size_array;
5552 +// Remplit "nb" cases consecutives du tableau a partir de la case "first"
5553 +// avec une valeur par defaut.
5554 +// Cette fonction est appelee lors d'un resize pour initialiser les
5555 +// cases nouvellement creees.
5556 +// Le comportement depend actuellement du type de tableau :
5557 +// * Tableau de type "smart_resize":
5558 +// * en mode debug (macro NDEBUG non definie) le tableau est initialise
5559 +// avec une valeur invalide.
5560 +// * en optimise, le tableau n'est pas initialise
5561 +// * Tableau normal :
5562 +// Le tableau est initialise avec la valeur 0. Ce comportement est choisi
5563 +// pour des raisons de compatibilite avec l'implementation precedente.
5564 +// Cette specification pourrait etre modifiee prochainement pour des raisons
5565 +// de performances (pour ne pas avoir a initialiser inutilement les tableaux).
5566 +// DONC: il faut supposer desormais que les nouvelles cases ne sont pas
5567 +// initialisees lors d'un resize.
5568 +// Parametre: first
5569 +// Signification: premiere case a initialiser.
5570 +// Contrainte: (nb==0) ou (0 <= first < memory_size_)
5572 +// Signification: nombre de cases a initialiser.
5573 +// Contrainte: (nb==0) ou (0 < nb <= memory_size_ - first)
5574 +void ArrOf__Scalar__::fill_default_value(entier first, entier nb)
5576 + assert((nb == 0) || (first >= 0 && first < memory_size_));
5577 + assert((nb == 0) || (nb > 0 && nb <= memory_size_ - first));
5578 + __scalar__ * data = addr();
5579 + assert(data!=0 || nb==0);
5581 + if (smart_resize_)
5583 + // On initialise uniquement en mode debug
5586 + static const entier ENTIER_INVALIDE = INT_MIN;
5587 + for (entier i = 0; i < nb; i++)
5588 + data[i] = ENTIER_INVALIDE;
5590 + __DoubleOnlyBegin__
5591 + // Ceci represente un NAN. N'importe quelle operation avec ca fait encore un NAN.
5592 + // Si c'est pas portable, on peut remplacer par DMAX_FLOAT sur les autres machines.
5593 + static const unsigned long long VALEUR_INVALIDE =
5594 + 0x7ff7ffffffffffffULL;
5596 + // On utilise "memcpy" et non "=" car "=" peut provoquer une exception
5597 + // si la copie passe par le fpu.
5598 + for (entier i = 0; i < nb; i++)
5599 + memcpy(data + i, & VALEUR_INVALIDE, sizeof(__scalar__));
5605 + // Comportement pour les tableaux normaux : compatibilite avec la
5606 + // version precedente : on initialise avec 0.
5607 + for (entier i = 0; i < nb; i++)
5608 + data[i] = (__scalar__) 0;
5612 +// ****************************************************************
5614 +// Fonctions non membres de la classe ArrOf__Scalar__
5616 +// ****************************************************************
5619 +// Renvoie 1 si les tableaux "v" et "a" sont de la meme taille
5620 +// et contiennent les memes valeurs au sens strict, sinon renvoie 0.
5621 +// Le test est !(v[i]!=a[i])
5622 +entier operator==(const ArrOf__Scalar__& v, const ArrOf__Scalar__& a)
5624 + const entier n = v.size_array();
5625 + const entier na = a.size_array();
5633 + const __scalar__* vv = v.addr();
5634 + const __scalar__* av = a.addr();
5636 + for (i = 0; i < n; i++)
5638 + if (av[i] != vv[i])
5649 +// Retourne l'indice du min ou -1 si le tableau est vide
5651 +// Parametre: const ArrOf__Scalar__& dx
5652 +// Signification: tableau a utiliser
5654 +// Signification: indice du min
5655 +entier imin_array(const ArrOf__Scalar__& dx)
5657 + entier indice_min = -1;
5658 + const entier size = dx.size_array();
5662 + __scalar__ valeur_min = dx[0];
5663 + for(entier i = 1; i < size; i++)
5665 + const __scalar__ val = dx[i];
5666 + if(val < valeur_min)
5673 + return indice_min;
5677 +// Retourne l'indice du max ou -1 si le tableau est vide
5679 +// Parametre: const ArrOf__Scalar__& dx
5680 +// Signification: tableau a utiliser
5682 +// Signification: indice du max
5683 +entier imax_array(const ArrOf__Scalar__& dx)
5685 + entier indice_max = -1;
5686 + const entier size = dx.size_array();
5690 + __scalar__ valeur_max = dx[0];
5691 + for(entier i = 1; i < size; i++)
5693 + const __scalar__ val = dx[i];
5694 + if(val > valeur_max)
5701 + return indice_max;
5705 +// Retourne la valeur minimale
5707 +// Le tableau doit contenir au moins une valeur
5708 +// Parametre: const ArrOf__Scalar__& dx
5709 +// Signification: tableau a utiliser
5710 +// Retour: __scalar__
5711 +// Signification: valeur du min
5712 +__scalar__ min_array(const ArrOf__Scalar__& dx)
5714 + const entier size = dx.size_array();
5716 + __scalar__ valeur_min = dx[0];
5717 + for(entier i = 1; i < size; i++)
5719 + const __scalar__ val = dx[i];
5720 + if (val < valeur_min)
5723 + return valeur_min;
5727 +// Retourne la valeur maximale
5729 +// Le tableau doit contenir au moins une valeur
5730 +// Parametre: const ArrOf__Scalar__& dx
5731 +// Signification: tableau a utiliser
5732 +// Retour: __scalar__
5733 +// Signification: valeur du max
5734 +__scalar__ max_array(const ArrOf__Scalar__& dx)
5736 + const entier size = dx.size_array();
5738 + __scalar__ valeur_max = dx[0];
5739 + for(entier i = 1; i < size; i++)
5741 + const __scalar__ val = dx[i];
5742 + if (val > valeur_max)
5745 + return valeur_max;
5749 +// Fonction de comparaison utilisee pour trier le tableau
5750 +// dans ArrOf__Scalar__::trier(). Voir man qsort
5751 +static int fonction_compare_arrof__scalar___ordonner(const void * data1, const void * data2)
5753 + const __scalar__ x = *(const __scalar__*)data1;
5754 + const __scalar__ y = *(const __scalar__*)data2;
5755 + __DoubleOnlyBegin__
5769 +// Tri des valeurs du tableau dans l'ordre croissant.
5770 +// La fonction utilisee est qsort de stdlib (elle est en n*log(n)).
5771 +void ArrOf__Scalar__::ordonne_array()
5773 + const entier size = size_array();
5776 + __scalar__ * data = addr();
5777 + qsort(data, size, sizeof(__scalar__),
5778 + fonction_compare_arrof__scalar___ordonner);
5783 +// Fait pointer le tableau vers les memes donnees qu'un tableau
5784 +// existant. Le tableau sera du meme type que le tableau m ("detache",
5785 +// "normal"). Le tableau m ne doit pas etre de type "ref_data"
5786 +// Les donnes existantes sont perdues si elles
5787 +// ne sont pas referencees ailleurs.
5789 +// Parametre: const ArrOf__Scalar__& m
5790 +// Signification: le tableau a referencer (pas de type "ref_data"
5791 +// et different de *this !!!)
5792 +// Retour: ArrOf__Scalar__&
5793 +// Signification: *this
5798 +ArrOf__Scalar__& ArrOf__Scalar__::ref_array(const ArrOf__Scalar__& m)
5800 + assert(&m != this);
5801 + // La condition 'm n'est pas de type "ref_data"' est necessaire pour
5802 + // attach_array().
5809 +// Fait pointer le tableau vers la zone de memoire "data_".
5810 +// On detache la zone de memoire existante. Le tableau devient
5811 +// de type "ref_data". Attention : ptr doit etre non nul.
5812 +// La taille est initialisee avec size.
5813 +// Cette methode est appelee notamment par __Scalar__Vect::adopter.
5814 +// Parametre: __scalar__*
5815 +// Signification: le tableau a recuperer. Si pointeur nul alors size
5816 +// doit etre nulle aussi et le tableau reste detache
5817 +// Parametre: entier size
5818 +// Signification: le nombre d'elements du tableau.
5819 +// Retour: ArrOf__Scalar__&
5820 +// Signification: *this
5821 +ArrOf__Scalar__& ArrOf__Scalar__::ref_data(__scalar__* ptr, entier size)
5823 + assert(ptr != 0 || size == 0);
5824 + assert(size >= 0);
5827 + size_array_ = size;
5832 +// Amene le tableau dans l'etat "detache". C'est a dire:
5833 +// Si le tableau est "detache" :
5835 +// Si le tableau est "normal" :
5836 +// * decremente le nombre de references a *p
5837 +// * detruit *p si p->ref_count==0
5838 +// * annule p_, data_ et size_array_
5839 +// Si le tableau est "ref_data" :
5840 +// * annule data_ et size_array_
5842 +// Signification: 1 si les donnees du tableau ont ete supprimees
5845 +// On a p_==0, data_==0 et size_array_==0, memory_size_ = 0
5846 +// L'attribut smart_resize_ est conserve.
5847 +entier ArrOf__Scalar__::detach_array()
5849 + entier retour = 0;
5852 + // Le tableau est de type "normal"
5853 + // Si la zone de memoire n'est plus utilisee par personne,
5855 + if ((p_->suppr_one_ref()) == 0)
5869 +// Amene le tableau dans l'etat "normal", "detache" ou "ref_array"
5870 +// en associant la meme zone de memoire que le tableau m.
5872 +// Le tableau doit etre "detache"
5873 +// Parametre: const ArrOf__Scalar__& m
5874 +// Signification: tableau a utiliser
5875 +// le tableau doit etre different de *this !!!
5882 +// Si m est detache, le tableau reste detache,
5883 +// si m est "ref_array", le tableau devient "ref_array",
5884 +// sinon le tableau est "normal", avec ref_count > 1
5885 +// Si m est de taille nulle, le tableau reste detache + Warning dans fichier .log
5886 +void ArrOf__Scalar__::attach_array(const ArrOf__Scalar__& m)
5888 + // Le tableau doit etre detache
5889 + assert(data_ == 0 && p_ == 0);
5890 + // Le tableau doit etre different de *this
5891 + assert(&m != this);
5893 + if (m.size_array() > 0)
5897 + p_->add_one_ref();
5899 + size_array_ = m.size_array_;
5900 + memory_size_ = m.memory_size_;
5901 + smart_resize_ = m.smart_resize_;
5905 + // Cas particulier ou on attache un tableau de taille nulle:
5906 + // en theorie, c'est pareil qu'un tableau de taille non nulle, MAIS
5907 + // dans les operateurs (ex:Op_Dift_VDF_Face_Axi), une ref est construite
5908 + // avant que le tableau ne prenne sa taille definitive. Donc, pour ne pas
5909 + // empecher le resize, il ne faut pas attacher le tableau s'il n'a pas
5910 + // encore la bonne taille. Solution propre: reecrire les operateurs pour
5911 + // qu'ils ne prennent pas une ref avant que le tableau ne soit valide
5912 + // et faire p_ = m.p_ dans tous les cas.
5917 +// Copie les elements source[first_element_source + i]
5918 +// dans les elements (*this)[first_element_dest + i] pour 0 <= i < nb_elements
5919 +// Les autres elements de (*this) sont inchanges.
5921 +// Parametre: const ArrOf__Scalar__& m
5922 +// Signification: le tableau a utiliser, doit etre different de *this !
5923 +// Parametre: entier nb_elements
5924 +// Signification: nombre d'elements a copier, nb_elements >= -1.
5925 +// Si nb_elements==-1, on copie tout le tableau m.
5926 +// Valeurs par defaut: -1
5927 +// Parametre: entier first_element_dest
5928 +// Valeurs par defaut: 0
5929 +// Parametre: entier first_element_source
5930 +// Valeurs par defaut: 0
5931 +// Retour: ArrOf__Scalar__&
5932 +// Signification: *this
5935 +// Sort en erreur si la taille du tableau m est plus grande que la
5936 +// taille de tableau this.
5939 +ArrOf__Scalar__& ArrOf__Scalar__::inject_array(const ArrOf__Scalar__& source,
5940 + entier nb_elements,
5941 + entier first_element_dest,
5942 + entier first_element_source)
5944 + assert(&source != this);
5945 + assert(nb_elements >= -1);
5946 + assert(first_element_dest >= 0);
5947 + assert(first_element_source >= 0);
5949 + if (nb_elements < 0)
5950 + nb_elements = source.size_array();
5952 + assert(first_element_source + nb_elements <= source.size_array());
5953 + assert(first_element_dest + nb_elements <= size_array());
5955 + if (nb_elements > 0)
5957 + __scalar__ * addr_dest = addr() + first_element_dest;
5958 + const __scalar__ * addr_source = source.addr() + first_element_source;
5959 + // memcpy(addr_dest , addr_source, nb_elements * sizeof(__scalar__));
5961 + for (i = 0; i < nb_elements; i++)
5963 + addr_dest[i] = addr_source[i];
5970 +// Retourne le nombre de references des donnees du tableau
5971 +// si le tableau est "normal", -1 s'il est "detache" ou "ref_data"
5973 +// Signification: ref_count_
5974 +entier ArrOf__Scalar__::ref_count() const
5977 + return p_->ref_count();
5983 +// Addition case a case sur toutes les cases du tableau
5985 +// la taille de y doit etre au moins egale a la taille de this
5986 +// Parametre: const ArrOf__Scalar__& y
5987 +// Signification: tableau a ajouter
5988 +// Valeurs par defaut:
5991 +// Retour: ArrOf__Scalar__&
5992 +// Signification: *this
5997 +ArrOf__Scalar__& ArrOf__Scalar__::operator+=(const ArrOf__Scalar__& y)
5999 + assert(size_array()==y.size_array());
6000 + __scalar__* dx = addr();
6001 + const __scalar__* dy = y.addr();
6002 + const entier n = size_array();
6003 + for (entier i=0; i<n; i++)
6009 +// ajoute la meme valeur a toutes les cases du tableau
6011 +// Parametre: const __scalar__ dy
6012 +// Signification: valeur a ajouter
6013 +// Valeurs par defaut:
6016 +// Retour: ArrOf__Scalar__
6017 +// Signification: *this
6022 +ArrOf__Scalar__& ArrOf__Scalar__::operator+=(const __scalar__ dy)
6024 + __scalar__ * data = addr();
6025 + const entier n = size_array();
6026 + for(entier i=0; i < n; i++)
6031 +// Soustraction case a case sur toutes les cases du tableau
6032 +// Parametre: const ArrOf__Scalar__& y
6033 +// Signification: tableau de meme taille que *this
6034 +// Retour: ArrOf__Scalar__&
6035 +// Signification: *this
6036 +ArrOf__Scalar__& ArrOf__Scalar__::operator-=(const ArrOf__Scalar__& y)
6038 + const entier size = size_array();
6039 + assert(size == y.size_array());
6040 + __scalar__ * data = addr();
6041 + const __scalar__ * data_y = y.addr();
6042 + for (entier i=0; i < size; i++)
6043 + data[i] -= data_y[i];
6049 +// soustrait la meme valeur a toutes les cases
6050 +// Retour: ArrOf__Scalar__ &
6051 +// Signification: *this
6052 +ArrOf__Scalar__& ArrOf__Scalar__::operator-=(const __scalar__ dy)
6054 + __scalar__ * data = addr();
6055 + const entier n = size_array();
6056 + for(entier i=0; i < n; i++)
6062 +// Renvoie un pointeur sur le premier element du tableau.
6063 +// Le pointeur est nul si le tableau est "detache".
6064 +// Attention, l'adresse peut changer apres un appel
6065 +// a resize_array(), ref_data, ref_array, ...
6067 +// Retour: const __scalar__*
6068 +// Signification: pointeur sur le premier element du tableau
6069 +const __scalar__* ArrOf__Scalar__::addr() const
6075 +// Renvoie un pointeur sur le premier element du tableau.
6076 +// Le pointeur est nul si le tableau est "detache".
6078 +// Retour: const __scalar__*
6079 +// Signification: la zone memoire du tableau
6080 +__scalar__* ArrOf__Scalar__::addr()
6085 +__DoubleOnlyBegin__
6088 +// Retourne le max des abs(i)
6090 +// Le tableau doit contenir au moins une valeur
6091 +// Parametre: const ArrOf__Scalar__& dx
6092 +// Signification: tableau a utiliser
6093 +// Valeurs par defaut:
6096 +// Retour: __scalar__
6097 +// Signification: valeur du max des valeurs absolues
6102 +__scalar__ max_abs_array(const ArrOf__Scalar__& dx)
6104 + const entier size = dx.size_array();
6106 + __scalar__ valeur_max = fabs(dx[0]);
6107 + for(entier i = 1; i < size; i++)
6109 + const __scalar__ val = fabs(dx[i]);
6110 + if (val > valeur_max)
6113 + return valeur_max;
6117 +// muliplie toutes les cases par dy
6118 +// Retour: ArrOf__Scalar__ &
6119 +// Signification: *this
6120 +ArrOf__Scalar__& ArrOf__Scalar__::operator*= (const __scalar__ dy)
6122 + __scalar__ * data = addr();
6123 + const entier n = size_array();
6124 + for(entier i=0; i < n; i++)
6131 +// divise toutes les cases par dy
6132 +// Retour: ArrOf__Scalar__ &
6133 +// Signification: *this
6134 +ArrOf__Scalar__& ArrOf__Scalar__::operator/= (const __scalar__ dy)
6136 + // En theorie: les deux lignes suivantes sont plus efficaces, mais
6137 + // cela produit des differences sur certains cas tests
6138 + // (Hyd_C_VEF_Smago et Lambda_var_VEF_turb). Ca veut dire qu'il y
6139 + // a un probleme autre part mais pour l'instant on laisse l'ancien
6141 + // const __scalar__ i_dy = 1. / dy;
6142 + // operator*=(i_dy);
6144 + __scalar__ * data = addr();
6145 + const entier n = size_array();
6146 + for(entier i=0; i < n; i++)
6153 +__Scalar__Tab::__Scalar__Tab()
6156 + dimensions_[0] = 0;
6157 + dimensions_[1] = 0;
6160 +__Scalar__Tab::__Scalar__Tab(const __Scalar__Tab& tab) :
6161 + ArrOf__Scalar__(tab)
6163 + nb_dim_ = tab.nb_dim_;
6164 + dimensions_[0] = tab.dimensions_[0];
6165 + dimensions_[1] = tab.dimensions_[1];
6167 +__Scalar__Tab::__Scalar__Tab(const entier i, const entier j) :
6168 + ArrOf__Scalar__(i*j)
6171 + dimensions_[0] = i;
6172 + dimensions_[1] = j;
6175 +__Scalar__Tab& __Scalar__Tab::operator=(const __Scalar__Tab& tab)
6177 + ArrOf__Scalar__::operator=(tab);
6178 + nb_dim_ = tab.nb_dim_;
6179 + dimensions_[0] = tab.dimensions_[0];
6180 + dimensions_[1] = tab.dimensions_[1];
6184 +void __Scalar__Tab::reset()
6186 + ArrOf__Scalar__::reset();
6188 + dimensions_[0] = 0;
6189 + dimensions_[1] = 0;
6191 diff --git a/databases/readers/Lata/ArrOf_Scalar_Prototype.h b/databases/readers/Lata/ArrOf_Scalar_Prototype.h
6192 new file mode 100644
6193 index 0000000..689932f
6195 +++ b/databases/readers/Lata/ArrOf_Scalar_Prototype.h
6197 +/*****************************************************************************
6199 +* Copyright (c) 2011 - 2013, CEA
6200 +* All rights reserved.
6201 +* Redistribution and use in source and binary forms, with or without
6202 +* modification, are permitted provided that the following conditions are met:
6204 +* * Redistributions of source code must retain the above copyright
6205 +* notice, this list of conditions and the following disclaimer.
6206 +* * Redistributions in binary form must reproduce the above copyright
6207 +* notice, this list of conditions and the following disclaimer in the
6208 +* documentation and/or other materials provided with the distribution.
6209 +* * Neither the name of CEA, nor the
6210 +* names of its contributors may be used to endorse or promote products
6211 +* derived from this software without specific prior written permission.
6213 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
6214 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6215 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6216 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
6217 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6218 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6219 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6220 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6221 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6222 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6224 +*****************************************************************************/
6227 +#ifndef ArrOf__Scalar___H
6228 +#define ArrOf__Scalar___H
6230 +#include <assert.h>
6232 +#include <Objet_U.h>
6234 +__DoubleOnlyBegin__
6235 +#define DMAXFLOAT 1e40
6238 +class V__Scalar__data;
6240 +class ArrOf__Scalar__
6246 + virtual ~ArrOf__Scalar__();
6250 + ArrOf__Scalar__();
6251 + ArrOf__Scalar__(entier size);
6252 + ArrOf__Scalar__(entier size, __scalar__ initial_value);
6253 + // Constructeur par copie : deep copy (on duplique les donnees)
6254 + ArrOf__Scalar__(const ArrOf__Scalar__& );
6256 + // Methodes de construction tardive (on cree un tableau vide avec ArrOf__Scalar__()
6257 + // puis on appelle ces methodes pour modifier les caracteristiques du tableau :
6259 + // Change le nombre d'elements du tableau
6260 + inline ArrOf__Scalar__& resize_array(entier new_size);
6262 + // Methodes de gestion de l'allocation memoire:
6263 + // Assigne une valeur au drapeau "smart_resize"
6264 + // (reallocation uniquement si la taille augmente)
6265 + void set_smart_resize(entier flag);
6266 + // Gestion du type de memoire alouee (standard ou pool de memoire Trio-U)
6267 + enum Storage { STANDARD, TEMP_STORAGE };
6268 + void set_mem_storage(const Storage storage);
6269 + Storage get_mem_storage() const;
6271 + // Construction de tableaux qui pointent vers des donnees existantes
6272 + // !!! Utiliser ref_data avec precaution (attention a size_array_)
6273 + ArrOf__Scalar__& ref_data(__scalar__* ptr, entier size);
6274 + ArrOf__Scalar__& ref_array(const ArrOf__Scalar__&);
6275 + // Operateur copie
6276 + ArrOf__Scalar__& operator=(const ArrOf__Scalar__&);
6277 + // Remise du tableau dans l'etat initial (obtenu par le constructeur par defaut)
6278 + virtual void reset();
6281 + // Methodes d'acces aux donnees et aux caracteristiques du tableau
6283 + // Remplit le tableau avec la valeur en parametre
6284 + ArrOf__Scalar__& operator=(__scalar__ valeur);
6286 + inline __scalar__& operator[](entier i);
6287 + inline const __scalar__& operator[](entier i) const;
6289 + // Ces methodes renvoient un pointeur vers le premier element du tableau.
6290 + const __scalar__ * addr() const;
6291 + __scalar__ * addr();
6292 + // Renvoie le nombre d'elements du tableau (et non la taille allouee)
6293 + inline entier size_array() const;
6294 + // Renvoie le nombre de tableaux qui pointent vers la stucture "*p_"
6295 + entier ref_count() const;
6296 + // Ajoute une case en fin de tableau et y stocke la "valeur"
6297 + inline void append_array(__scalar__ valeur);
6300 + // Operateurs divers
6302 + ArrOf__Scalar__& operator+=(const ArrOf__Scalar__&);
6303 + ArrOf__Scalar__& operator+=(const __scalar__);
6304 + ArrOf__Scalar__& operator-=(const ArrOf__Scalar__&);
6305 + ArrOf__Scalar__& operator-=(const __scalar__);
6306 + ArrOf__Scalar__& inject_array(const ArrOf__Scalar__ & source,
6307 + entier nb_elements = -1,
6308 + entier first_element_dest = 0,
6309 + entier first_element_source = 0);
6310 + ArrOf__Scalar__& copy_array(const ArrOf__Scalar__&);
6312 + __DoubleOnlyBegin__
6313 + ArrOf__Scalar__& operator*= (const __scalar__) ;
6314 + ArrOf__Scalar__& operator/= (const __scalar__) ;
6317 + void ordonne_array();
6321 + // Methodes accessibles depuis les descendants de ArrOf__Scalar__
6323 + void attach_array(const ArrOf__Scalar__&);
6324 + entier detach_array();
6325 + void fill_default_value(entier first, entier nb);
6327 + // B. Mathieu 22/06/2004 : je mets ces membres "private" pour forcer
6328 + // le passage par les accesseurs dans les classes derivees, au cas ou
6329 + // on voudrait modifier l'implementation.
6331 + // Zone de memoire contenant les valeurs du tableau.
6332 + // Pointeur nul => le tableau est "detache" ou "ref_data"
6333 + // Pointeur non nul => le tableau est "normal"
6334 + V__Scalar__data* p_;
6336 + // Pointeur vers le premier element du tableau (egal a p_->data si p_!=0)
6337 + // Pointeur nul => le tableau est "detache".
6338 + // Pointeur non nul => le tableau est "normal" ou "ref_data"
6339 + __scalar__* data_;
6341 + // Nombre d'elements du tableau (inferieur ou egal a memory_size_).
6342 + // Si le tableau est "detache", alors size_array_=0
6343 + entier size_array_;
6344 + // Taille memoire reellement allouee pour le tableau
6345 + // (pour le mecanisme smart_resize_). memory_size_ est nul
6346 + // si le tableau est de type "ref_data". Sinon memory_size_
6347 + // est egal a p_->size_.
6348 + entier memory_size_;
6350 + // Drapeau indiquant si on applique une strategie d'allocation
6351 + // preventive (la memoire alouee augmente d'un facteur constant
6352 + // si la taille devient insuffisante).
6353 + // Si smart_resize_ == 0, alors on a toujours p_->size_ == size
6354 + entier smart_resize_;
6356 + // Drapeau indiquant si l'allocation memoire a lieu avec un new classique
6357 + // ou dans le pool de memoire temporaire de Trio
6358 + Storage storage_type_;
6360 + // Partie non inline de resize_array():
6361 + // Declaration des constantes pour les options de memory_resize
6362 + static const entier COPY_OLD;
6363 + static const entier INITIALIZE_NEW;
6364 + void memory_resize(entier new_size, entier options);
6367 +#define MAXDIM__Scalar__Tab 2
6369 +class __Scalar__Tab : public ArrOf__Scalar__
6373 + __Scalar__Tab(const __Scalar__Tab&);
6374 + __Scalar__Tab(const entier i, const entier j);
6375 + __Scalar__Tab& operator=(const __Scalar__Tab&);
6378 + inline __scalar__& operator()(entier i, entier j);
6379 + inline __scalar__ operator()(entier i, entier j) const;
6381 + inline entier resize(entier i, entier j);
6382 + inline entier dimension(entier i) const;
6383 + inline entier dimension_tot(entier i) const;
6386 + // In order to mimic TRUST behavior, operator[] is forbidden
6387 + // for 2 dimensionnal matrices, you must cast to ArrOf to use it..
6388 + double& operator[](entier i);
6389 + const double& operator[](entier i) const;
6393 + entier dimensions_[MAXDIM__Scalar__Tab];
6396 +inline __scalar__& __Scalar__Tab::operator()(entier i, entier j)
6398 + assert(nb_dim_ == 2);
6399 + assert(i >= 0 && i < dimensions_[0] && j >= 0 && j < dimensions_[1]);
6400 + const entier n = i * dimensions_[1] + j;
6401 + __scalar__ & x = ArrOf__Scalar__::operator[] (n);
6405 +inline __scalar__ __Scalar__Tab::operator()(entier i, entier j) const
6407 + assert(nb_dim_ == 2);
6408 + assert(i >= 0 && i < dimensions_[0] && j >= 0 && j < dimensions_[1]);
6409 + const entier n = i * dimensions_[1] + j;
6410 + __scalar__ x = ArrOf__Scalar__::operator[] (n);
6414 +inline entier __Scalar__Tab::resize(entier i, entier j)
6416 + assert(i >= 0 && j >= 0);
6418 + dimensions_[0] = i;
6419 + dimensions_[1] = j;
6420 + ArrOf__Scalar__::resize_array(i * j);
6424 +inline entier __Scalar__Tab::dimension(entier i) const
6426 + assert(i >= 0 && i < nb_dim_);
6427 + return dimensions_[i];
6430 +// Description: renvoie la meme valeur que dimension.
6431 +inline entier __Scalar__Tab::dimension_tot(entier i) const
6433 + return dimension(i);
6437 +// Declarations des fonctions non membres de la classe ArrOf__Scalar__
6439 +entier operator==(const ArrOf__Scalar__& x, const ArrOf__Scalar__& y) ;
6440 +entier imin_array(const ArrOf__Scalar__&) ;
6441 +entier imax_array(const ArrOf__Scalar__&) ;
6442 +__scalar__ min_array(const ArrOf__Scalar__&) ;
6443 +__scalar__ max_array(const ArrOf__Scalar__&) ;
6445 +__DoubleOnlyBegin__
6446 +__scalar__ max_abs_array(const ArrOf__Scalar__&) ;
6449 +// ******************************************************************
6450 +// FONCTIONS MEMBRES DE ArrOf__Scalar__
6451 +// ******************************************************************
6454 +// Change le nombre d'elements du tableau. Cette fonction est inline
6455 +// car elle doit etre tres rapide dans le cas ou smart_resize_==1
6456 +// (utilisation frequente de resize_array())
6457 +// Si smart_resize est non nul :
6458 +// Si la nouvelle taille est inferieure ou egale a la taille
6459 +// alouee (p->get_size()) on ne realloue pas de memoire
6460 +// sinon, on realloue et on copie les donnees existantes.
6461 +// Astuce pour ne pas copier les anciennes donnees:
6462 +// resize(0); resize(n);
6463 +// Si smart_resize est nul, on realloue une nouvelle zone memoire
6464 +// uniquement si la nouvelle taille est differente de l'ancienne.
6466 +// Si "new_size" est egal a la taille du tableau, aucune condition.
6467 +// Sinon, le tableau doit etre soit detache, soit normal (pas de type "ref_data")
6468 +// et ref_count doit etre egal a 1 (pas d'autre reference au tableau).
6470 +inline ArrOf__Scalar__& ArrOf__Scalar__::resize_array(entier new_size)
6472 + assert(new_size >= 0);
6473 + // Soit le tableau est detache (data_==0), soit il est normal (p_!=0)
6474 + // S'il est normal, il ne faut pas qu'il y ait d'autre reference au tableau,
6475 + // ou alors la taille ne doit pas changer.
6476 + assert(new_size == size_array_ || data_ == 0 || (p_ != 0 && ref_count() == 1));
6478 + if ((smart_resize_ == 0) || (new_size > memory_size_))
6479 + memory_resize(new_size, COPY_OLD + INITIALIZE_NEW);
6480 + size_array_ = new_size;
6485 +// operateur [] retourne le ieme element du tableau
6487 +// Parametre: entier i
6488 +// Signification: indice dans l'intervalle 0 <= i < size_array()
6490 +__DoubleOnlyBegin__
6491 +// assert si la valeur sort de l'intervalle : [ -DMAXFLOAT,DMAXFLOAT ]
6493 +// assert si i n'est pas dans l'intervalle
6494 +inline __scalar__& ArrOf__Scalar__::operator[](entier i)
6496 + assert(i >= 0 && i < size_array_);
6497 + __DoubleOnlyBegin__
6498 + assert(data_[i] > -DMAXFLOAT && data_[i] < DMAXFLOAT);
6504 +// operateur [] retourne le ieme element du tableau
6506 +// Parametre: entier i
6507 +// Signification: indice dans l'intervalle 0 <= i < size_array()
6509 +__DoubleOnlyBegin__
6510 +// assert si la valeur sort de l'intervalle : [ -DMAXFLOAT,DMAXFLOAT ]
6512 +// assert si i n'est pas dans l'intervalle
6513 +inline const __scalar__& ArrOf__Scalar__::operator[](entier i) const
6515 + assert(i >= 0 && i < size_array_);
6516 + __DoubleOnlyBegin__
6517 + assert(data_[i] > -DMAXFLOAT && data_[i] < DMAXFLOAT);
6523 +// Renvoie la taille du tableau (nombre d'elements declares
6524 +// a la construction ou a resize_array()).
6525 +// C'est le nombre d'elements accessibles a operator[]
6527 +inline entier ArrOf__Scalar__::size_array() const
6529 + return size_array_;
6533 +// Ajoute une case en fin de tableau et y stocke la "valeur"
6535 +// Tableau doit etre de type "smart_resize" (sinon, ecroulement
6536 +// des performances). De plus, le tableau ne doit pas etre "ref_data",
6537 +// et il ne doit pas y avoir plus d'une reference a la zone de
6538 +// memoire pointee (meme precondition que resize_array())
6539 +inline void ArrOf__Scalar__::append_array(__scalar__ valeur)
6541 + assert(smart_resize_);
6542 + // Soit le tableau est detache (data_==0), soit il est normal (p_!=0)
6543 + // S'il est normal, il ne faut pas qu'il y ait d'autre reference au tableau.
6544 + assert(data_ == 0 || (p_ != 0 && ref_count() == 1));
6546 + if (size_array_+1 > memory_size_)
6547 + memory_resize(size_array_+1, COPY_OLD);
6548 + data_[size_array_] = valeur;
6552 +// ArrOf__Scalar___H
6554 diff --git a/databases/readers/Lata/CMakeLists.txt b/databases/readers/Lata/CMakeLists.txt
6555 new file mode 100644
6556 index 0000000..be611f3
6558 +++ b/databases/readers/Lata/CMakeLists.txt
6561 + avtlataFileFormat.C
6566 + LataV1_field_definitions.C
6570 + OperatorBoundary.C
6571 + OperatorDualMesh.C
6572 + OperatorFacesMesh.C
6573 + OperatorReconnect.C
6574 + OperatorRegularize.C
6575 + Rebuild_virtual_layer.C
6581 + Connectivite_som_elem.C
6585 + Static_Int_Lists.C
6588 +MESSAGE("Here I am")
6590 +ADD_VISIT_READER(VisItLataReader "1.0"
6591 + VISIT_READER_TYPE "MTMD"
6592 + VISIT_READER_NAME "avtlataFileFormat"
6593 + SERVER_SOURCES ${SOURCES}
6595 diff --git a/databases/readers/Lata/Connectivite_som_elem.C b/databases/readers/Lata/Connectivite_som_elem.C
6596 new file mode 100644
6597 index 0000000..2a268cc
6599 +++ b/databases/readers/Lata/Connectivite_som_elem.C
6601 +/*****************************************************************************
6603 +* Copyright (c) 2011 - 2013, CEA
6604 +* All rights reserved.
6605 +* Redistribution and use in source and binary forms, with or without
6606 +* modification, are permitted provided that the following conditions are met:
6608 +* * Redistributions of source code must retain the above copyright
6609 +* notice, this list of conditions and the following disclaimer.
6610 +* * Redistributions in binary form must reproduce the above copyright
6611 +* notice, this list of conditions and the following disclaimer in the
6612 +* documentation and/or other materials provided with the distribution.
6613 +* * Neither the name of CEA, nor the
6614 +* names of its contributors may be used to endorse or promote products
6615 +* derived from this software without specific prior written permission.
6617 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
6618 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6619 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6620 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
6621 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6622 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6623 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6624 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6625 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6626 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6628 +*****************************************************************************/
6630 +#include <Connectivite_som_elem.h>
6631 +#include <Static_Int_Lists.h>
6632 +#include <IntTab.h>
6634 +// Description: construction de la structure som_elem pour la zone donnee
6635 +// On cree pour chaque sommet i la liste des elements adjacents a ce sommet
6636 +// (c'est la liste des elements k tels que il existe j tel que les_elems(k,j) == i)
6637 +// Parametre: nb_sommets
6638 +// Description: nombre de sommets utilises dans les elements (som_elem contiendra
6639 +// autant de listes). Si include_virtual==1, c'est le nombre de sommets
6640 +// total, sinon c'est le nombre de sommets reels
6641 +// Parametre: les_elems
6642 +// Description: tableau des elements (contient les numeros des sommets de chaque element)
6643 +// Les valeurs du tableau doivent etre inferieurs a nb_sommets.
6644 +// Parametre: som_elem
6645 +// Description: la structure dans laquelle on stocke le resultat. L'ancien
6646 +// contenu est perdu. Chaque liste d'elements est triee dans l'ordre croissant
6647 +// Parametre: include_virtual
6648 +// Description: 0 => seuls les elements reels sont inclus dans la structure
6649 +// 1 => on inclut les elements virtuels (donc les sommets virtuels)
6650 +void construire_connectivite_som_elem(const entier nb_sommets,
6651 + const IntTab& les_elems,
6652 + Static_Int_Lists& som_elem,
6653 + const entier include_virtual)
6655 + // Nombre d'elements du domaine
6656 + const entier nb_elem = (include_virtual) ? les_elems.dimension_tot(0) : les_elems.dimension(0);
6657 + // Nombre de sommets par element
6658 + const entier nb_sommets_par_element = les_elems.dimension(1);
6660 + // Construction d'un tableau initialise a zero : pour chaque sommet,
6661 + // nombre d'elements voisins de ce sommet
6662 + ArrOfInt nb_elements_voisins(nb_sommets, 0);
6664 + // Premier passage : on calcule le nombre d'elements voisins de chaque
6665 + // sommet pour creer la structure de donnees
6668 + for (elem = 0; elem < nb_elem; elem++)
6670 + for (i = 0; i < nb_sommets_par_element; i++)
6672 + entier sommet = les_elems(elem, i);
6673 + // GF cas des polyedres
6674 + if (sommet==-1) break;
6675 + nb_elements_voisins[sommet]++;
6679 + som_elem.set_list_sizes(nb_elements_voisins);
6681 + // On reutilise le tableau pour stocker le nombre d'elements dans
6682 + // chaque liste pendant qu'on la remplit
6683 + nb_elements_voisins = 0;
6685 + // Remplissage du tableau des elements voisins.
6686 + for (elem = 0; elem < nb_elem; elem++)
6688 + for (i = 0; i < nb_sommets_par_element; i++)
6690 + entier sommet = les_elems(elem, i);
6691 + // GF cas des polyedres
6692 + if (sommet==-1) break;
6693 + entier n = (nb_elements_voisins[sommet])++;
6694 + som_elem.set_value(sommet, n, elem);
6698 + // Tri de toutes les listes dans l'ordre croissant
6699 + som_elem.trier_liste(-1);
6702 +// Description: Cherche les elements qui contiennent tous les sommets
6703 +// du tableau sommets_to_find (permet de trouver les elements
6704 +// adjacents a une face ou une arete)
6705 +// Parametre: som_elem
6706 +// Signification: pour chaque sommet, liste triee des elements adjacents
6707 +// (voir construire_connectivite_som_elem)
6708 +// Parametre: sommets_to_find
6709 +// Signification: une liste de sommets
6710 +// Parametre: elements
6711 +// Signification: resultat de la recherche: la liste des elements qui
6712 +// contiennent tous les sommets de sommets_to_find.
6713 +// Si sommets_to_find est vide, on renvoie un tableau vide.
6714 +// (en cas d'appels repetes a cette fonction, il est
6715 +// conseille de mettre le drapeau "smart_resize")
6716 +void find_adjacent_elements(const Static_Int_Lists& som_elem,
6717 + const ArrOfInt& sommets_to_find,
6718 + ArrOfInt& elements)
6720 + entier nb_som_to_find = sommets_to_find.size_array();
6721 + // on retire les sommets valant -1 (cas ou plusieurs types de faces)
6722 + while (sommets_to_find[nb_som_to_find-1]==-1) nb_som_to_find--;
6723 + if (nb_som_to_find == 0)
6725 + elements.resize_array(0);
6728 + // Algorithme: on initialise elements avec tous les elements adjacents
6729 + // au premier sommet de la liste.
6730 + // Puis pour chacun des autres sommets de la liste, on retire du tableau
6731 + // "elements" les elements qui ne sont pas voisins du sommet.
6732 + // A la fin, il ne reste que les elements qui sont dans toutes les listes.
6734 + // Initialisation avec les elements adjacents au premier sommet
6735 + const entier sommet = sommets_to_find[0];
6736 + som_elem.copy_list_to_array(sommet, elements);
6738 + entier nb_elem_found = elements.size_array();
6740 + for (i_sommet = 1; i_sommet < nb_som_to_find; i_sommet++)
6742 + const entier sommet = sommets_to_find[i_sommet];
6743 + // Calcul des elements communs entre elements[.] et som_elem(sommet,.)
6744 + // Nombre d'elements communs entre elements et la nouvelle liste de sommets
6745 + entier nb_elems_restants = 0;
6746 + // Nombre d'elements adjacents au "sommet"
6747 + const entier nb_elem_liste = som_elem.get_list_size(sommet);
6748 + // On suppose que les listes d'elements sont triees dans l'ordre croissant
6749 + // On parcourt simultanement les deux listes et on conserve les elements
6753 + if (nb_elem_found == 0)
6755 + if (nb_elem_liste > 0)
6759 + const entier elem_i = elements[i];
6760 + const entier elem_j = som_elem(sommet, j);
6761 + if (elem_i == elem_j)
6763 + // Element commun aux deux listes, on le garde
6764 + elements[nb_elems_restants] = elem_i;
6765 + nb_elems_restants++;
6767 + if (elem_i >= elem_j)
6770 + if (j >= nb_elem_liste)
6773 + if (elem_j >= elem_i)
6776 + if (i >= nb_elem_found)
6783 + nb_elems_restants = 0;
6785 + nb_elem_found = nb_elems_restants;
6787 + elements.resize_array(nb_elem_found);
6790 diff --git a/databases/readers/Lata/Connectivite_som_elem.h b/databases/readers/Lata/Connectivite_som_elem.h
6791 new file mode 100644
6792 index 0000000..758b030
6794 +++ b/databases/readers/Lata/Connectivite_som_elem.h
6796 +/*****************************************************************************
6798 +* Copyright (c) 2011 - 2013, CEA
6799 +* All rights reserved.
6800 +* Redistribution and use in source and binary forms, with or without
6801 +* modification, are permitted provided that the following conditions are met:
6803 +* * Redistributions of source code must retain the above copyright
6804 +* notice, this list of conditions and the following disclaimer.
6805 +* * Redistributions in binary form must reproduce the above copyright
6806 +* notice, this list of conditions and the following disclaimer in the
6807 +* documentation and/or other materials provided with the distribution.
6808 +* * Neither the name of CEA, nor the
6809 +* names of its contributors may be used to endorse or promote products
6810 +* derived from this software without specific prior written permission.
6812 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
6813 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6814 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6815 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
6816 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6817 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6818 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6819 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6820 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6821 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6823 +*****************************************************************************/
6830 +class Static_Int_Lists;
6832 +void construire_connectivite_som_elem(const entier nb_sommets,
6833 + const IntTab& les_elems,
6834 + Static_Int_Lists& som_elem,
6835 + const entier include_virtual);
6837 +void find_adjacent_elements(const Static_Int_Lists& som_elem,
6838 + const ArrOfInt& sommets_to_find,
6839 + ArrOfInt& elements);
6840 diff --git a/databases/readers/Lata/DoubleTab.h b/databases/readers/Lata/DoubleTab.h
6841 new file mode 100644
6842 index 0000000..1731563
6844 +++ b/databases/readers/Lata/DoubleTab.h
6846 +/*****************************************************************************
6848 +* Copyright (c) 2011 - 2013, CEA
6849 +* All rights reserved.
6850 +* Redistribution and use in source and binary forms, with or without
6851 +* modification, are permitted provided that the following conditions are met:
6853 +* * Redistributions of source code must retain the above copyright
6854 +* notice, this list of conditions and the following disclaimer.
6855 +* * Redistributions in binary form must reproduce the above copyright
6856 +* notice, this list of conditions and the following disclaimer in the
6857 +* documentation and/or other materials provided with the distribution.
6858 +* * Neither the name of CEA, nor the
6859 +* names of its contributors may be used to endorse or promote products
6860 +* derived from this software without specific prior written permission.
6862 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
6863 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6864 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6865 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
6866 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6867 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6868 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6869 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6870 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6871 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6873 +*****************************************************************************/
6875 +#include <ArrOfDouble.h>
6876 diff --git a/databases/readers/Lata/EFichier.h b/databases/readers/Lata/EFichier.h
6877 new file mode 100644
6878 index 0000000..3cf0ee8
6880 +++ b/databases/readers/Lata/EFichier.h
6882 +/*****************************************************************************
6884 +* Copyright (c) 2011 - 2013, CEA
6885 +* All rights reserved.
6886 +* Redistribution and use in source and binary forms, with or without
6887 +* modification, are permitted provided that the following conditions are met:
6889 +* * Redistributions of source code must retain the above copyright
6890 +* notice, this list of conditions and the following disclaimer.
6891 +* * Redistributions in binary form must reproduce the above copyright
6892 +* notice, this list of conditions and the following disclaimer in the
6893 +* documentation and/or other materials provided with the distribution.
6894 +* * Neither the name of CEA, nor the
6895 +* names of its contributors may be used to endorse or promote products
6896 +* derived from this software without specific prior written permission.
6898 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
6899 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6900 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6901 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
6902 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6903 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6904 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6905 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6906 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6907 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6909 +*****************************************************************************/
6913 +#include <Entree.h>
6914 +class EFichier : public Entree
6917 + int ouvrir(const char *name)
6920 + return is_.good();
6922 + operator std::istream& ()
6932 + return is_.good();
6934 + std::istream& get_istream()
6939 + std::ifstream is_;
6942 diff --git a/databases/readers/Lata/Entree.h b/databases/readers/Lata/Entree.h
6943 new file mode 100644
6944 index 0000000..2f36fea
6946 +++ b/databases/readers/Lata/Entree.h
6948 +/*****************************************************************************
6950 +* Copyright (c) 2011 - 2013, CEA
6951 +* All rights reserved.
6952 +* Redistribution and use in source and binary forms, with or without
6953 +* modification, are permitted provided that the following conditions are met:
6955 +* * Redistributions of source code must retain the above copyright
6956 +* notice, this list of conditions and the following disclaimer.
6957 +* * Redistributions in binary form must reproduce the above copyright
6958 +* notice, this list of conditions and the following disclaimer in the
6959 +* documentation and/or other materials provided with the distribution.
6960 +* * Neither the name of CEA, nor the
6961 +* names of its contributors may be used to endorse or promote products
6962 +* derived from this software without specific prior written permission.
6964 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
6965 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6966 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6967 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
6968 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6969 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6970 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6971 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6972 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6973 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6975 +*****************************************************************************/
6979 +#include <iostream>
6981 +#include <Motcle.h>
6982 +// This class emulates the main functionalities of the Entree and EFichier classes in TRUST
6986 + virtual operator std::istream& () = 0;
6987 + virtual int eof() = 0;
6988 + virtual int good() = 0;
6989 + virtual ~Entree() {};
6990 + virtual std::istream& get_istream() = 0;
6993 +inline Entree& operator>>(Entree& is, double& t)
6995 + is.get_istream() >> t;
6998 +inline Entree& operator>>(Entree& is, float& t)
7000 + is.get_istream() >> t;
7003 +inline Entree& operator>>(Entree& is, Nom& n)
7005 + is.get_istream() >> n;
7008 +inline Entree& operator>>(Entree& is, Motcle& n)
7010 + is.get_istream() >> n;
7013 +inline Entree& operator>>(Entree& is, entier& n)
7015 + is.get_istream() >> n;
7019 +// For Static_Int_Lists:
7020 +inline Entree& operator>>(Entree& is, ArrOfInt& t)
7025 diff --git a/databases/readers/Lata/FloatTab.h b/databases/readers/Lata/FloatTab.h
7026 new file mode 100644
7027 index 0000000..351313d
7029 +++ b/databases/readers/Lata/FloatTab.h
7031 +/*****************************************************************************
7033 +* Copyright (c) 2011 - 2013, CEA
7034 +* All rights reserved.
7035 +* Redistribution and use in source and binary forms, with or without
7036 +* modification, are permitted provided that the following conditions are met:
7038 +* * Redistributions of source code must retain the above copyright
7039 +* notice, this list of conditions and the following disclaimer.
7040 +* * Redistributions in binary form must reproduce the above copyright
7041 +* notice, this list of conditions and the following disclaimer in the
7042 +* documentation and/or other materials provided with the distribution.
7043 +* * Neither the name of CEA, nor the
7044 +* names of its contributors may be used to endorse or promote products
7045 +* derived from this software without specific prior written permission.
7047 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
7048 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7049 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7050 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
7051 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7052 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7053 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7054 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7055 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7056 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7058 +*****************************************************************************/
7060 +#include <ArrOfFloat.h>
7061 diff --git a/databases/readers/Lata/IntTab.h b/databases/readers/Lata/IntTab.h
7062 new file mode 100644
7063 index 0000000..c8cb65c
7065 +++ b/databases/readers/Lata/IntTab.h
7067 +/*****************************************************************************
7069 +* Copyright (c) 2011 - 2013, CEA
7070 +* All rights reserved.
7071 +* Redistribution and use in source and binary forms, with or without
7072 +* modification, are permitted provided that the following conditions are met:
7074 +* * Redistributions of source code must retain the above copyright
7075 +* notice, this list of conditions and the following disclaimer.
7076 +* * Redistributions in binary form must reproduce the above copyright
7077 +* notice, this list of conditions and the following disclaimer in the
7078 +* documentation and/or other materials provided with the distribution.
7079 +* * Neither the name of CEA, nor the
7080 +* names of its contributors may be used to endorse or promote products
7081 +* derived from this software without specific prior written permission.
7083 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
7084 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7085 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7086 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
7087 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7088 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7089 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7090 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7091 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7092 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7094 +*****************************************************************************/
7096 +#include <ArrOfInt.h>
7098 diff --git a/databases/readers/Lata/LataDB.C b/databases/readers/Lata/LataDB.C
7099 new file mode 100644
7100 index 0000000..84e4cc4
7102 +++ b/databases/readers/Lata/LataDB.C
7104 +/*****************************************************************************
7106 +* Copyright (c) 2011 - 2013, CEA
7107 +* All rights reserved.
7108 +* Redistribution and use in source and binary forms, with or without
7109 +* modification, are permitted provided that the following conditions are met:
7111 +* * Redistributions of source code must retain the above copyright
7112 +* notice, this list of conditions and the following disclaimer.
7113 +* * Redistributions in binary form must reproduce the above copyright
7114 +* notice, this list of conditions and the following disclaimer in the
7115 +* documentation and/or other materials provided with the distribution.
7116 +* * Neither the name of CEA, nor the
7117 +* names of its contributors may be used to endorse or promote products
7118 +* derived from this software without specific prior written permission.
7120 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
7121 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7122 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7123 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
7124 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7125 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
7126 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7127 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7128 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
7129 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7131 +*****************************************************************************/
7134 +#include <LataDB.h>
7136 +#include <EFichier.h>
7137 +#include <LataV1_field_definitions.h>
7138 +#include <iostream>
7140 +#include <string.h>
7141 +#include <stdlib.h>
7143 +#include <LataDBmed.h>
7145 +// Verbose level for which main lata file interpretation should be printed:
7146 +// Dump one line for the whole file at verb_level-1
7147 +// Dump one line for each Geometry, Temps, or Champ at verb_level
7148 +// Detailed Geometry and Champ metadata is printed out at verb_level+1
7149 +#define verb_level 4
7150 +// Verbose level for data bloc reading:
7151 +// Dump one line for each read data bloc at this level
7152 +// Dump detailed subbloc interpretation at level+1
7153 +#define verb_level_data_bloc 5
7155 +typedef int LataDBInt32;
7156 +typedef long long int LataDBInt64;
7160 + if (sizeof(LataDBInt32)!=4)
7161 + Journal() << "Error in LataDB arch_check : wrong LataDBInt32" << endl;
7162 + if (sizeof(LataDBInt64)!=8)
7163 + Journal() << "Error in LataDB arch_check : wrong LataDBInt64" << endl;
7166 +const char * LataDBField::memory_buffer_file()
7168 + return "MEMORY_BUFFERED_DATA";
7171 +Field_UName::Field_UName()
7175 +Field_UName::Field_UName(const Field_UName & f) :
7176 + geometry_(f.geometry_), field_name_(f.field_name_), loc_(f.loc_)
7180 +Field_UName::Field_UName(const char *domain_name, const char *field_name, const char *loc) :
7181 + geometry_(domain_name), field_name_(field_name), loc_(loc)
7187 +Field_UName & Field_UName::operator=(const Field_UName & f)
7189 + geometry_ = f.geometry_;
7190 + field_name_ = f.field_name_;
7195 +Nom Field_UName::build_string() const
7200 + if (loc_ != "" && loc_ != "??") {
7207 +void Field_UName::set_field_name(const Nom & n)
7212 +int Field_UName::operator==(const Field_UName & f) const
7214 + return (geometry_ == f.geometry_) && (field_name_ == f.field_name_) && (loc_ == f.loc_);
7217 +std::ostream & operator<<(std::ostream & os, const Field_UName & uname)
7219 + os << uname.build_string();
7223 +// This is a duplicate of Domain... only used for old latav1 compatibility
7224 +// (otherwise, LataDB should not have to know about element types !)
7225 +LataDB::Element LataDB::element_type_from_string(const Motcle & type_elem)
7228 + if (type_elem == "HEXAEDRE")
7230 + else if (type_elem == "HEXAEDRE_AXI")
7232 + else if (type_elem == "HEXAEDRE_VEF")
7234 + else if (type_elem == "QUADRANGLE")
7236 + else if (type_elem == "QUADRANGLE_3D")
7238 + else if (type_elem == "RECTANGLE")
7240 + else if (type_elem == "RECTANGLE_2D_AXI")
7242 + else if (type_elem == "RECTANGLE_AXI")
7244 + else if (type_elem == "SEGMENT")
7246 + else if (type_elem == "SEGMENT_2D")
7248 + else if (type_elem == "TETRAEDRE")
7250 + else if (type_elem == "TRIANGLE")
7252 + else if (type_elem == "TRIANGLE_3D")
7254 + else if (type_elem.debute_par("POLYEDRE"))
7256 + else if (type_elem.debute_par("POLYGONE"))
7259 + Journal() << "Error in elem_type_from_string: unknown element type " << type_elem << endl;
7260 + throw(LataDBError(LataDBError::BAD_ELEM_TYPE));
7265 +void LataDB::get_element_data(const Motcle & elemtype, entier & dimension, entier & elem_shape, entier & face_shape, entier & nb_elem_faces)
7267 + Element elem = element_type_from_string(elemtype);
7269 + case line: dimension = 2; elem_shape=2; face_shape=1; nb_elem_faces=2; break;
7270 + case triangle: dimension = (elemtype=="TRIANGLE") ? 2 : 3;
7271 + elem_shape=3; face_shape=2; nb_elem_faces=3; break;
7272 + case quadri: dimension = (elemtype=="QUADRANGLE_3D") ? 3 : 2;
7273 + elem_shape=4; face_shape=2; nb_elem_faces=4; break;
7274 + case tetra: dimension = 3; elem_shape=4; face_shape=3; nb_elem_faces=4; break;
7275 + case hexa: dimension = 3; elem_shape=8; face_shape=4; nb_elem_faces=6; break;
7276 + case polyedre: dimension = 3; elem_shape=-1; face_shape=-1; nb_elem_faces=-1; break;
7277 + case polygone: dimension = 2; elem_shape=-1; face_shape=-1; nb_elem_faces=-1; break;
7279 + Journal() << "LataDB::get_element_data element is unspecified" << endl;
7280 + throw(LataDBError(LataDBError::BAD_ELEM_TYPE));
7284 +// Description: in lata v1 format, the number of components in a Champ entry
7285 +// is implicitely defined by the field name and the discretisation
7286 +entier LataDB::lata_v1_get_nb_comp(const Nom & fieldname, const Motcle & localisation,
7287 + const LataDBGeometry & dom, entier dim, LataDBField::Nature & nature,
7288 + LataDBDataType::DataOrdering & ordering)
7290 + // Search component name in std_components
7291 + entier nb_comp = latav1_component_shape(fieldname);
7292 + Motcle maj_field(fieldname);
7293 + ordering = LataDBDataType::C_ORDERING;
7294 + nature = LataDBField::SCALAR;
7295 + Journal(verb_level+1) << " LataV2 known component name found : " << fieldname << endl;
7296 + if (nb_comp == -1) {
7297 + // This is a vector component. If it's not a VDF faces, nb_comp = dimension of the problem
7298 + Element elt = element_type_from_string(dom.elem_type_);
7299 + if (localisation == "FACES" && (elt == quadri || elt == hexa)) {
7301 + Journal(verb_level+1) << " Vector field. Detected a VDF faces discretisation => nb_comp=1" << endl;
7304 + nature = LataDBField::VECTOR;
7305 + ordering = LataDBDataType::F_ORDERING;
7306 + Journal(verb_level+1) << " Vector field. nb_comp = dimension = " << nb_comp << endl;
7307 + Journal(verb_level+1) << " Assume fortran ordering" << endl;
7309 + } else if (nb_comp == -2) {
7310 + // This is the vorticity: scalar in 2D, vector in 3D
7314 + Journal(verb_level+1) << " Scalar field, nb_comp=" << nb_comp << endl;
7319 + nature = LataDBField::VECTOR;
7320 + ordering = LataDBDataType::F_ORDERING;
7321 + Journal(verb_level+1) << " Vector field. nb_comp = dimension = " << nb_comp << endl;
7322 + Journal(verb_level+1) << " Assume fortran ordering" << endl;
7325 + //if (maj_field == "K_EPS") {
7327 + ordering = LataDBDataType::F_ORDERING;
7328 + Journal(verb_level+1) << " Special K_EPS => Assume fortran ordering" << endl;
7330 + Journal(verb_level+1) << " Scalar field, nb_comp=" << nb_comp << endl;
7335 +// Description: in lata v1 format, the localisation is implicitely defined by the
7336 +// file name of the data file:
7337 +void lata_v1_get_localisation(const char * filename, Nom & localisation_)
7339 + if (strstr(filename, ".SOM."))
7340 + localisation_ = "SOM";
7341 + else if (strstr(filename, ".ELEM."))
7342 + localisation_ = "ELEM";
7343 + else if (strstr(filename, ".FACES."))
7344 + localisation_ = "FACES";
7346 + Journal() << "Error in lata_v1_get_localisation. Unable to find localisation in filename\n"
7347 + << filename << endl;
7348 + throw(LataDBError(LataDBError::READ_ERROR));
7355 + enum Mode { READ, WRITE, APPEND };
7356 + LataDataFile(std::iostream & mem_buffer, const char *prefix, const char *name, const LataDBDataType::MSB& msb, Mode mode = READ)
7360 + if (strcmp(name, LataDBField::memory_buffer_file()) == 0) {
7361 + stream_ = &mem_buffer;
7363 + Journal(verb_level_data_bloc) << "LataDB: opening internal memory_buffer for read/write" << endl;
7365 + (*stream_).seekg(0, std::ios::beg);
7366 + else if (mode == WRITE)
7367 + { // on ne repositionne pas sur un fichier vide, Visual ne supporte pas
7368 + // et c'est inutil
7369 + if ((*stream_).tellp()>=0)
7370 + (*stream_).seekp(0, std::ios::beg);
7374 + if ((*stream_).tellp()>=0)
7375 + (*stream_).seekp(0, std::ios::end);
7377 + Journal(verb_level_data_bloc+1) << " current position: " << position() << endl;
7378 + if (!fstream_.good()) {
7379 + Journal() << "LataDataFile: Memory stream error" << endl;
7380 + throw LataDBError(LataDBError::DATA_ERROR);
7383 + stream_ = &fstream_;
7386 + Journal(verb_level_data_bloc) << "LataDB: opening data file " << fname_ << endl;
7387 + if (msb_ == LataDBDataType::ASCII) {
7389 + case READ: fstream_.open(fname_, std::fstream::in); break;
7390 + case WRITE: fstream_.open(fname_, std::fstream::out); break;
7391 + case APPEND: fstream_.open(fname_, std::fstream::out | std::fstream::app); break;
7396 + if (msb_ != LataDBDataType::machine_msb_) {
7397 + Journal() << "LataDB LataDataFile::write(int) not coded for reverse binary msb" << endl;
7401 + case READ: fstream_.open(fname_, std::fstream::in|std::fstream::binary); break;
7402 + case WRITE: fstream_.open(fname_, std::fstream::out|std::fstream::binary); break;
7403 + case APPEND: fstream_.open(fname_, std::fstream::out | std::fstream::app|std::fstream::binary); break;
7406 + if (!fstream_.good()) {
7407 + Journal() << "File not found " << fname_ << endl;
7408 + throw LataDBError(LataDBError::FILE_NOT_FOUND);
7412 + void set_exception(int i) { exception_ = i; }
7413 + FileOffset position() { return (*stream_).tellp(); };
7414 + enum SeekType { ABSOLUTE, RELATIVE };
7415 + void seek(FileOffset pos, SeekType seekt) {
7416 + Journal(verb_level_data_bloc+1) << "Seeking file " << fname_
7417 + << ((seekt == ABSOLUTE) ? " absolute position " : " relative position ")
7419 + if (seekt == ABSOLUTE)
7420 + (*stream_).seekg(pos, std::ios::beg);
7422 + (*stream_).seekg(pos, std::ios::cur);
7424 + if (exception_ && !(*stream_).good()) {
7425 + Journal() << "Error seeking to position " << pos << " in file " << fname_ << endl;
7426 + throw LataDBError(LataDBError::DATA_ERROR);
7429 + void set_encoding(LataDBDataType::MSB msb, LataDBDataType::Type type) { msb_ = msb; type_ = type; };
7430 + void set_err_message(const char *message) { message_ = message; };
7431 + LataDataFile & operator>>(LataDBInt32 & x) { read(&x, 1); return *this; };
7432 + LataDataFile & operator>>(float & x) { read(&x, 1); return *this; };
7433 + LataDataFile & operator>>(Nom & n) {
7435 + if (msb_ != LataDBDataType::ASCII) {
7439 + (*stream_).get(c[0]);
7441 + if (!(*stream_).good())
7451 + (*stream_) >> tmp;
7452 + if ((*stream_).good())
7455 + if (exception_ && !(*stream_).good()) {
7456 + Journal() << "Error reading string in file " << fname_ << endl;
7457 + throw LataDBError(LataDBError::DATA_ERROR);
7461 + void read(LataDBInt32 *ptr, BigEntier n);
7462 + void read(float *ptr, BigEntier n);
7463 + LataDataFile & operator<<(LataDBInt32 & x) { write(&x, 1, 1); return *this; };
7464 + LataDataFile & operator<<(float & x) { write(&x, 1, 1); return *this; };
7465 + void write(const LataDBInt32 *ptr, BigEntier n, BigEntier col);
7466 + void write(const float *ptr, BigEntier n, BigEntier col);
7470 + const char * message_; // Message printed if error.
7471 + std::fstream fstream_;
7472 + std::iostream *stream_; // Points to fstream_ or mem_buffer passed to constructor
7473 + LataDBDataType::MSB msb_;
7474 + LataDBDataType::Type type_;
7478 +void LataDataFile::read(LataDBInt32 *ptr, BigEntier n)
7480 + if (type_ != LataDBDataType::INT32 && type_ != LataDBDataType::INT64) {
7481 + Journal() << "Error in lataDB bloc read: trying to read non integer data into integer array" << endl;
7482 + throw LataDBError(LataDBError::DATA_ERROR);
7484 + if (msb_ == LataDBDataType::ASCII) {
7487 + Journal(verb_level_data_bloc+1) << "Reading ascii int data bloc size=" << n << endl;
7489 + Journal(verb_level_data_bloc+1) << "Skipping ascii int data bloc size=" << n << endl;
7491 + for (i = 0; i < n; i++) {
7493 + (*stream_) >> ptr[i];
7495 + (*stream_) >> toto;
7496 + if (exception_ && !(*stream_).good()) {
7497 + Journal() << "Error reading ascii file " << fname_ << " LataDBInt32[" << n << "] at index "
7498 + << i << endl << (message_?message_:"") << endl;
7499 + throw LataDBError(LataDBError::DATA_ERROR);
7503 + if (type_ != LataDBDataType::INT32) {
7504 + Journal() << "Internal error in LataDB.cpp LataDataFile::read(LataDBInt32) : size conversion not coded" << endl;
7508 + Journal(verb_level_data_bloc+1) << "Reading binary int data bloc size=" << n << endl;
7509 + (*stream_).read((char*)ptr, n * sizeof(LataDBInt32));
7511 + Journal(verb_level_data_bloc+1) << "Skipping binary int data bloc size=" << n << endl;
7512 + seek(n * sizeof(LataDBInt32), RELATIVE);
7514 + if (exception_ && !(*stream_).good()) {
7515 + Journal() << "Error reading binary file " << fname_ << " LataDBInt32[" << n << "]"
7516 + << endl << (message_?message_:"") << endl;
7517 + throw LataDBError(LataDBError::DATA_ERROR);
7519 + if (msb_ != LataDBDataType::machine_msb_) {
7520 + Journal() << "LataDB LataDataFile::read(LataDBInt32) not coded for reverse binary msb" << endl;
7522 + // Put code here (and test !) to reverse bytes in the binary bloc:
7527 +void LataDataFile::read(float *ptr, BigEntier n)
7529 + if (type_ != LataDBDataType::REAL32) {
7530 + Journal() << "Error in lataDB bloc read: trying to read non float data into float array" << endl;
7531 + throw LataDBError(LataDBError::DATA_ERROR);
7533 + if (msb_ == LataDBDataType::ASCII) {
7536 + Journal(verb_level_data_bloc+1) << "Reading ascii float data bloc size=" << n << endl;
7538 + Journal(verb_level_data_bloc+1) << "Skipping ascii float data bloc size=" << n << endl;
7540 + for (i = 0; i < n; i++) {
7542 + (*stream_) >> ptr[i];
7544 + (*stream_) >> toto;
7545 + if (exception_ && !(*stream_).good()) {
7546 + Journal() << "Error reading ascii file " << fname_ << " float[" << n << "] at index "
7547 + << i << endl << message_ << endl;
7548 + throw LataDBError(LataDBError::DATA_ERROR);
7553 + Journal(verb_level_data_bloc+1) << "Reading binary float data bloc size=" << n << endl;
7554 + (*stream_).read((char*)ptr, n * sizeof(float));
7556 + Journal(verb_level_data_bloc+1) << "Skipping binary float data bloc size=" << n << endl;
7557 + seek(n * sizeof(float), RELATIVE);
7559 + if (exception_ && !(*stream_).good()) {
7560 + Journal() << "Error reading binary file " << fname_ << " float[" << n << "]"
7561 + << endl << message_ << endl;
7562 + throw LataDBError(LataDBError::DATA_ERROR);
7564 + if (msb_ != LataDBDataType::machine_msb_) {
7565 + Journal() << "LataDB LataDataFile::read(float) not coded for reverse binary msb" << endl;
7567 + // Put code here (and test !) to reverse bytes in the binary bloc:
7572 +void LataDataFile::write(const LataDBInt32 *ptr, BigEntier n, BigEntier columns)
7574 + Journal(verb_level_data_bloc+1) << "Writing int data bloc size=" << n << endl;
7575 + if (type_ != LataDBDataType::INT32) {
7576 + Journal() << "Error in lataDB bloc write: trying to write integer data to non integer file block" << endl;
7577 + throw LataDBError(LataDBError::DATA_ERROR);
7579 + if (msb_ == LataDBDataType::ASCII) {
7580 + for (BigEntier i = 0; i < n; i+=columns) {
7582 + for (j = 0; j < columns-1; j++)
7583 + (*stream_) << ptr[i+j] << " ";
7584 + (*stream_) << ptr[i+j] << endl;
7587 + if (msb_ != LataDBDataType::machine_msb_) {
7588 + Journal() << "LataDB LataDataFile::write(int) not coded for reverse binary msb" << endl;
7590 + // Put code here (and test !) to reverse bytes in the binary bloc:
7592 + (*stream_).write((char*)ptr, n * sizeof(LataDBInt32));
7594 + (*stream_).seekg(0, std::ios::end);
7595 + if (exception_ && !(*stream_).good()) {
7596 + Journal() << "Error writing file " << fname_ << " int[" << n << "]"
7597 + << endl << message_ << endl;
7598 + throw LataDBError(LataDBError::DATA_ERROR);
7602 +void LataDataFile::write(const float *ptr, BigEntier n, BigEntier columns)
7604 + Journal(verb_level_data_bloc+1) << "Writing float data bloc size=" << n << endl;
7605 + if (type_ != LataDBDataType::REAL32) {
7606 + Journal() << "Error in lataDB bloc write: trying to write float data to non float file block" << endl;
7607 + throw LataDBError(LataDBError::DATA_ERROR);
7609 + if (msb_ == LataDBDataType::ASCII) {
7610 + for (BigEntier i = 0; i < n; i+=columns) {
7612 + for (j = 0; j < columns-1; j++)
7613 + (*stream_) << ptr[i+j] << " ";
7614 + (*stream_) << ptr[i+j] << endl;
7617 + if (msb_ != LataDBDataType::machine_msb_) {
7618 + Journal() << "LataDB LataDataFile::write(float) not coded for reverse binary msb" << endl;
7620 + // Put code here (and test !) to reverse bytes in the binary bloc:
7622 + (*stream_).write((char*)ptr, n * sizeof(float));
7624 + (*stream_).seekg(0, std::ios::end);
7625 + if (exception_ && !(*stream_).good()) {
7626 + Journal() << "Error writing file " << fname_ << " float[" << n << "]"
7627 + << endl << message_ << endl;
7628 + throw LataDBError(LataDBError::DATA_ERROR);
7632 +// Description: skips a fortran bloc size descriptor.
7633 +void skip_blocksize(LataDataFile & f, const LataDBDataType & type)
7635 + if (type.fortran_bloc_markers_ == LataDBDataType::NO_BLOC_MARKER)
7637 + f.set_err_message("Error reading fortran blocsize");
7638 + f.set_encoding(type.msb_, type.bloc_marker_type_);
7641 + Journal(verb_level_data_bloc+1) << "Skipping blocsize marker value=" << i << endl;
7644 +template<class DEST_TYPE>
7645 +DEST_TYPE int_conversion(LataDBInt64 x, const char * err_msg = 0)
7647 + DEST_TYPE result = (DEST_TYPE) x;
7648 + if ((LataDBInt64) result != x) {
7650 + Journal() << "LataDB integer conversion failed: " << err_msg << endl;
7652 + Journal() << "LataDB integer conversion failed: " << endl;
7653 + throw(LataDBError(LataDBError::INTEGER_OVERFLOW));
7658 +void write_blocksize(LataDataFile & f, const LataDBDataType & type, entier sz)
7660 + if (type.fortran_bloc_markers_ == LataDBDataType::NO_BLOC_MARKER)
7663 + Journal(verb_level_data_bloc+1) << "Writing blocsize marker value=" << sz << endl;
7664 + f.set_err_message("Error writing fortran blocsize");
7665 + f.set_encoding(type.msb_, type.bloc_marker_type_);
7669 +void bloc_read_skip(LataDataFile & f, LataDBDataType::MSB msb, LataDBDataType::Type type, BigEntier size)
7671 + f.set_encoding(msb, type);
7673 + case LataDBDataType::INT32: f.read((LataDBInt32*) 0, size); break;
7674 + case LataDBDataType::REAL32: f.read((float*) 0, size); break;
7676 + Journal() << "Internal error: bloc read skip not code for this type" << endl;
7681 +// Description: Read "tab.size_array()" values from file "f" at current file location
7682 +// into the "tab" array. "msb" and "type" must match the data type written in the file.
7683 +void bloc_read(LataDataFile & f, LataDBDataType::MSB msb, LataDBDataType::Type type,
7686 + f.set_encoding(msb, type);
7687 + f.read(tab.addr(), tab.size_array());
7690 +void bloc_read(LataDataFile & f, LataDBDataType::MSB msb, LataDBDataType::Type type,
7693 + f.set_encoding(msb, type);
7694 + f.read(tab.addr(), tab.size_array());
7697 +void bloc_write(LataDataFile & f, LataDBDataType::MSB msb, LataDBDataType::Type type,
7698 + const ArrOfInt & tab, int columns)
7700 + f.set_encoding(msb, type);
7701 + f.write(tab.addr(), tab.size_array(), columns);
7704 +void bloc_write(LataDataFile & f, LataDBDataType::MSB msb, LataDBDataType::Type type,
7705 + const ArrOfFloat & tab, int columns)
7707 + f.set_encoding(msb, type);
7708 + f.write(tab.addr(), tab.size_array(), columns);
7711 +LataDBDataType::MSB LataDBDataType::machine_msb_ = (mymachine_msb) ? LataDBDataType::MSB_BIG_ENDIAN : LataDBDataType::MSB_LITTLE_ENDIAN;
7713 +void LataDB::add(entier tstep, const LataDBGeometry & item)
7715 + Noms names = geometry_names(tstep);
7716 + if (names.rang(item.name_) >= 0) {
7717 + Journal() << "Error in LataDBTimestep::add(const LataDBGeometry &): duplicate geometry name " << item.name_ << endl;
7718 + throw(LataDBError(LataDBError::READ_ERROR));
7720 + timesteps_[tstep].geoms_.add(item);
7723 +void LataDB::add(entier tstep, const LataDBField & item)
7725 + LataDBField & field = timesteps_[tstep].fields_.add(item);
7726 + field.timestep_ = tstep;
7727 + field.uname_ = Field_UName(item.geometry_, item.name_, item.localisation_);
7728 + Journal(verb_level+1) << "LataDB::add " << tstep << " " << field.uname_ << endl;
7731 +// Description: returns the number of timesteps in the database
7732 +// (timestep 0 contains geometries and fields defined before the first TEMPS entry,
7733 +// hence nb_timesteps() == number of TEMPS entries plus 1)
7734 +// Exceptions: BAD_TIMESTEP
7735 +entier LataDB::nb_timesteps() const
7737 + return timesteps_.size();
7740 +// Description: returns the physical time for this timestep
7741 +// Exceptions: BAD_TIMESTEP
7742 +double LataDB::get_time(entier tstep) const
7744 + return get_tstep(tstep).time_;
7747 +// Description: returns the requested geometry in the requested timestep
7748 +// "where" tells where to seach this geometry (in the current timestep or
7749 +// also in the first timestep.
7750 +// Exceptions: BAD_TIMESTEP NAME_NOT_FOUND
7751 +const LataDBGeometry & LataDB::get_geometry(entier tstep, const char* name,
7752 + TStepSelector where) const
7755 + throw(LataDBError(LataDBError::NAME_NOT_FOUND));
7757 + const LataDBTimestep & t = get_tstep(tstep);
7758 + const entier n = t.geoms_.size();
7759 + for (entier i = 0; i < n; i++) {
7760 + const LataDBGeometry & geom = t.geoms_[i];
7761 + if (geom.name_ == name)
7764 + if (where == FIRST_AND_CURRENT && tstep > 0)
7769 + throw(LataDBError(LataDBError::NAME_NOT_FOUND));
7772 +// Description: returns the requested field in the requested timestep.
7773 +// Exceptions: BAD_TIMESTEP NAME_NOT_FOUND
7774 +const LataDBField & LataDB::get_field(entier tstep, const Field_UName & uname,
7775 + TStepSelector where) const
7778 + const LataDBTimestep & t = get_tstep(tstep);
7779 + const entier n = t.fields_.size();
7780 + for (entier i = 0; i < n; i++) {
7781 + const LataDBField & field = t.fields_[i];
7782 + if (field.uname_ == uname)
7785 + if (where == FIRST_AND_CURRENT && tstep > 0)
7790 + throw(LataDBError(LataDBError::NAME_NOT_FOUND));
7793 +// Description: shortcut, works only if the specified field exists and is unique.
7794 +const LataDBField & LataDB::get_field(entier tstep, const char *geom, const char *name, const char *loc,
7795 + TStepSelector which_tstep) const
7797 + Field_UNames fields = field_unames(tstep, geom, name, which_tstep);
7798 + if (fields.size() > 1)
7799 + cerr << "get_field(char *geom, char *name, ...) returned more than one field !" << endl;
7800 + if (fields.size() != 1)
7801 + throw(LataDBError(LataDBError::NAME_NOT_FOUND));
7802 + return get_field(tstep, fields[0], which_tstep);
7805 +// Description: return 1 if the field exists AND is unique. (means you can call get_field with the
7806 +// same parameters)
7807 +entier LataDB::field_exists(entier tstep, const char *geom, const char *name,
7808 + TStepSelector which_tstep) const
7810 + Field_UNames fields = field_unames(tstep, geom, name, which_tstep);
7811 + return fields.size() == 1;
7815 +LataDBField & LataDB::getset_field(entier tstep, const Field_UName & uname, TStepSelector which_tstep)
7817 + return (LataDBField&) get_field(tstep, uname, which_tstep);
7820 +// Description: returns the names of all geometries defined in the timestep
7821 +// which_tstep tell where to search for geometries.
7822 +// Exceptions: BAD_TIMESTEP
7823 +Noms LataDB::geometry_names(entier tstep, TStepSelector which_tstep) const
7826 + const LataDBTimestep & t = get_tstep(tstep);
7827 + entier n = t.geoms_.size();
7828 + for (entier i = 0; i < n; i++)
7829 + names.add(t.geoms_[i].name_);
7830 + if (which_tstep == FIRST_AND_CURRENT && tstep > 0) {
7831 + const LataDBTimestep & t0 = get_tstep(0);
7832 + entier n2 = t0.geoms_.size();
7833 + for (entier i = 0; i < n2; i++)
7835 + if (names.rang(t0.geoms_[i].name_) < 0)
7836 + names.add(t0.geoms_[i].name_);
7841 +// Description: returns the unique_identifiers of all fields defined in the timestep and for which
7842 +// the associated geometry is "geometry" and the name is "name". Some fields may have no associated geometry,
7843 +// give a null pointer or empty string to get these fields.
7844 +// If geometry="*", returns list for all geometries
7845 +// If name="*", returns list for all field names
7846 +// Exceptions: BAD_TIMESTEP
7847 +LataVector<Field_UName> LataDB::field_unames(entier tstep, const char * geometry, const char * name, TStepSelector which_tstep) const
7849 + LataVector<Field_UName> unames;
7853 + const LataDBTimestep & t = get_tstep(tstep);
7854 + entier n = t.fields_.size();
7855 + for (entier i = 0; i < n; i++) {
7856 + const LataDBField & field = t.fields_[i];
7857 + if ((field.geometry_ == geometry || strcmp(geometry, "*")==0 )
7858 + && (field.name_ == name || strcmp(name,"*")==0 ))
7859 + unames.add(field.uname_);
7861 + if (tstep == 0 || which_tstep != FIRST_AND_CURRENT)
7868 +void check(Entree & is, const char * msg)
7871 + Journal() << "LataDB::read_master_file " << msg << endl;
7872 + throw(LataDBError(LataDBError::READ_ERROR));
7875 +void read_keyword_nom(Entree & is, Nom& motlu)
7879 + Journal(verb_level) << "LataDB::read_master_file end of file" << endl;
7882 + check(is, "read string error but not eof !");
7887 +void read_keyword(Entree & is, Nom& nomlu, Motcle& motlu)
7889 + read_keyword_nom(is,nomlu);
7893 +// On suppose que motlu contient "blabla=VALEUR". On extrait valeur et on la met dans "param".
7894 +// Bidouille: pour traiter le cas "blabla= VALEUR", s'il n'y a rien apres "=" dans motlu, on
7895 +// relit un mot dans is.
7896 +void read_long_param(Entree & is, const Motcle & motlu, LataDBInt64 & param, const char * err_msg)
7899 + const char *s = motlu;
7900 + while (((*s) != ('=')) && ((*s) != 0))
7903 + Journal() << "LataDB::read_master_file error: " << err_msg << endl;
7904 + throw(LataDBError(LataDBError::READ_ERROR));
7909 + // il y a une espace entre le = et le parametre ?
7910 + read_keyword_nom(is, tmp);
7914 + char *errorptr = 0;
7915 + param = strtoll(s, &errorptr, 0 /* base 10 par defaut */);
7916 + if (errno || *errorptr != 0) {
7917 + Journal() << "LataDB::read_master_file error: " << err_msg << endl
7918 + << "Error converting a string to type long int : string = " << s << endl;
7919 + throw(LataDBError(LataDBError::READ_ERROR));
7923 +void read_int_param(Entree & is, const Motcle & motlu, LataDBInt32 & param, const char * err_msg)
7926 + read_long_param(is, motlu, i, err_msg);
7927 + param = int_conversion<LataDBInt32>(i, err_msg);
7931 +// Idem que read_int_param pour des chaines de caracteres.
7932 +void read_string_param(Entree & is, const Nom & motlu, Nom & param, const char * err_msg)
7935 + const char *s = motlu;
7936 + while (((*s) != ('=')) && ((*s) != 0))
7939 + Journal() << "LataDB::read_master_file error: " << err_msg << endl;
7940 + throw(LataDBError(LataDBError::READ_ERROR));
7944 + // S'il n'y a rien apres =, on lit un mot de plus.
7946 + read_keyword_nom(is, param);
7950 +void read_noms_param(Entree & is, const Nom & motlu, Noms & param, const char * err_msg)
7953 + read_string_param(is,motlu,tmp,err_msg);
7956 + a faire extraire pour de vrai les differents mots de motlu
7960 + const char *s = tmp;
7962 + while ( ((*s) != 0))
7964 + if ((*s) == (','))
7967 + // motlu2[p]='\0';
7973 + // cerr<<nb_comp<<" "<<motlu2<<endl;
7974 + // provisoire non fini
7975 + param=Noms(nb_comp);
7977 + const char *s=motlu2;
7978 + for (int i=0;i<nb_comp;i++)
7981 + int j=motlu2.find(",");
7984 + cerr<<param[i]<<endl;
7990 +// Description: internal tool: checks for valid i and returns the timestep
7991 +// Exceptions: BAD_TIMESTEP
7992 +const LataDBTimestep & LataDB::get_tstep(entier i) const
7994 + if (i < 0 || i >= timesteps_.size()) {
7995 + Journal() << "LataDB::timestep(" << i << ") : wrong timestep" << endl;
7996 + throw(LataDBError(LataDBError::BAD_TIMESTEP));
7998 + return timesteps_[i];
8001 +// Description: clears the database
8002 +void LataDB::reset()
8004 + path_prefix_ = "";
8007 + software_id_ = "";
8008 + timesteps_.reset();
8009 + std::string empty;
8010 + internal_data_buffer_.str(empty);
8013 +// We update only fields found in the string
8014 +// A string can contain both an int type and a float type: we get both in int_type and float_type
8015 +static void read_format_string(const Motcle & n, LataDBDataType & data_type,
8016 + LataDBDataType::Type & int_type,
8017 + LataDBDataType::Type & float_type)
8019 + int_type = LataDBDataType::UNKNOWN_TYPE;
8020 + float_type = LataDBDataType::UNKNOWN_TYPE;
8022 + if (n.find("ASCII")>=0)
8023 + data_type.msb_ = LataDBDataType::ASCII;
8024 + if (n.find("BIG_ENDIAN")>=0)
8025 + data_type.msb_ = LataDBDataType::MSB_BIG_ENDIAN;
8026 + if (n.find("LITTLE_ENDIAN")>=0)
8027 + data_type.msb_ = LataDBDataType::MSB_LITTLE_ENDIAN;
8029 + if (n.find("INT32")>=0) {
8030 + int_type = data_type.type_ = LataDBDataType::INT32;
8031 + data_type.bloc_marker_type_ = LataDBDataType::INT32;
8033 + if (n.find("INT64")>=0) {
8034 + int_type = data_type.type_ = LataDBDataType::INT64;
8035 + data_type.bloc_marker_type_ = LataDBDataType::INT64;
8037 + if (n.find("REAL32")>=0)
8038 + float_type = data_type.type_ = LataDBDataType::REAL32;
8039 + if (n.find("REAL64")>=0)
8040 + float_type = data_type.type_ = LataDBDataType::REAL64;
8042 + if (n.find("C_INDEXING")>=0)
8043 + data_type.array_index_ = LataDBDataType::C_INDEXING;
8044 + if (n.find("F_INDEXING")>=0)
8045 + data_type.array_index_ = LataDBDataType::F_INDEXING;
8046 + if (n.find("NO_INDEXING")>=0)
8047 + data_type.array_index_ = LataDBDataType::NOT_AN_INDEX;
8049 + if (n.find("C_ORDERING")>=0)
8050 + data_type.data_ordering_ = LataDBDataType::C_ORDERING;
8051 + if (n.find("F_ORDERING")>=0)
8052 + data_type.data_ordering_ = LataDBDataType::F_ORDERING;
8054 + if (n.find("F_MARKERS_NO")>=0)
8055 + data_type.fortran_bloc_markers_ = LataDBDataType::NO_BLOC_MARKER;
8056 + if (n.find("F_MARKERS_SINGLE")>=0)
8057 + data_type.fortran_bloc_markers_ = LataDBDataType::BLOC_MARKERS_SINGLE_WRITE;
8058 + if (n.find("F_MARKERS_MULTIPLE")>=0)
8059 + data_type.fortran_bloc_markers_ = LataDBDataType::BLOC_MARKERS_MULTIPLE_WRITES;
8061 + // Fortran bloc markers are tested after INT32 and INT64 because they
8062 + // override the default value:
8063 + if (n.find("MARKERS32")>=0)
8064 + data_type.bloc_marker_type_ = LataDBDataType::INT32;
8065 + if (n.find("MARKERS64")>=0)
8066 + data_type.bloc_marker_type_ = LataDBDataType::INT64;
8069 +// This must work together with read_format_string:
8070 +void build_format_string(const LataDBDataType & default_type,
8071 + const LataDBDataType & type,
8075 + if (type.msb_ != default_type.msb_) {
8076 + switch(type.msb_) {
8077 + case LataDBDataType::ASCII: n += "ASCII,"; break;
8078 + case LataDBDataType::MSB_BIG_ENDIAN: n += "BIG_ENDIAN,"; break;
8079 + case LataDBDataType::MSB_LITTLE_ENDIAN: n += "LITTLE_ENDIAN,"; break;
8081 + Journal() << "write master lata: invalid MSB" << endl;
8082 + throw(LataDBError(LataDBError::INVALID_OPERATION));
8086 + // Is an integer type specified in the format string: then the default
8087 + // fortran bloc marker_type will be changed (look for MARKER32 in read_format_string)
8088 + LataDBDataType::Type default_fortran_bloc_type = default_type.bloc_marker_type_;
8090 + if (type.type_ != default_type.type_) {
8091 + switch(type.type_) {
8092 + case LataDBDataType::INT32: n += "INT32,"; default_fortran_bloc_type = LataDBDataType::INT32; break;
8093 + case LataDBDataType::INT64: n += "INT64,"; default_fortran_bloc_type = LataDBDataType::INT64; break;
8094 + case LataDBDataType::REAL32: n += "REAL32,"; break;
8095 + case LataDBDataType::REAL64: n += "REAL64,"; break;
8097 + Journal() << "write master lata: invalid type" << endl;
8098 + throw(LataDBError(LataDBError::INVALID_OPERATION));
8102 + // Specify indexing only if integer type:
8103 + if ((type.type_ == LataDBDataType::INT32 || type.type_ == LataDBDataType::INT64)
8104 + && type.array_index_ != default_type.array_index_)
8105 + switch(type.array_index_) {
8106 + case LataDBDataType::C_INDEXING: n += "C_INDEXING,"; break;
8107 + case LataDBDataType::F_INDEXING: n += "F_INDEXING,"; break;
8108 + case LataDBDataType::NOT_AN_INDEX: n += "NO_INDEXING,"; break;
8110 + Journal() << "write master lata: invalid array_index_" << endl;
8111 + throw(LataDBError(LataDBError::INVALID_OPERATION));
8114 + if (type.data_ordering_ != default_type.data_ordering_) {
8115 + switch(type.data_ordering_) {
8116 + case LataDBDataType::C_ORDERING: n += "C_ORDERING,"; break;
8117 + case LataDBDataType::F_ORDERING: n += "F_ORDERING,"; break;
8119 + Journal() << "write master lata: invalid data_ordering_" << endl;
8120 + throw(LataDBError(LataDBError::INVALID_OPERATION));
8124 + if (type.fortran_bloc_markers_ != default_type.fortran_bloc_markers_) {
8125 + switch(type.fortran_bloc_markers_) {
8126 + case LataDBDataType::NO_BLOC_MARKER: n += "F_MARKERS_NO,"; break;
8127 + case LataDBDataType::BLOC_MARKERS_SINGLE_WRITE: n += "F_MARKERS_SINGLE,"; break;
8128 + case LataDBDataType::BLOC_MARKERS_MULTIPLE_WRITES: n += "F_MARKERS_MULTIPLE,"; break;
8130 + Journal() << "write master lata: invalid fortran_bloc_markers_" << endl;
8131 + throw(LataDBError(LataDBError::INVALID_OPERATION));
8135 + // Warning : tricky code to determine if we have to specify fortran bloc marker size:
8136 + // If we specify a type_ and this type_ is an integer type, then the fortran bloc
8137 + // marker has implicitely the same type. We want to override this type if
8138 + // this assumption is wrong:
8139 + if (type.fortran_bloc_markers_ != LataDBDataType::NO_BLOC_MARKER
8140 + && default_fortran_bloc_type != type.bloc_marker_type_) {
8141 + switch(type.bloc_marker_type_) {
8142 + case LataDBDataType::INT32: n += "MARKER32,"; break;
8143 + case LataDBDataType::INT64: n += "MARKER64,"; break;
8145 + Journal() << "write master lata: invalid fortran bloc marker type" << endl;
8146 + throw(LataDBError(LataDBError::INVALID_OPERATION));
8150 + // Remove trailing "," if any.
8154 +// Description: returns the content of the third line of the file
8155 +// Exceptions: FILE_NOT_FOUND, BAD_HEADER (means that this is not a lata file)
8156 +Nom LataDB::read_master_file_options(const char *filename)
8160 + db.read_master_file_header(filename, is);
8161 + return db.software_id_; // Returns the content of the third line
8165 +// Opens the file and reads the three firt lines.
8166 +// Fills the following attributes of the class:
8171 +void LataDB::read_master_file_header(const char *filename, EFichier & is)
8174 + filename = ""; // Will trigger an error for sure !
8175 + is.ouvrir(filename);
8176 + if (!is.good()) { // isnogood ?
8177 + Journal() << "LataDB::read_master_file_options failed opening file " << filename << endl;
8178 + throw(LataDBError(LataDBError::FILE_NOT_FOUND));
8180 + Journal(verb_level-1) << "Trying to read master lata file format LATA "
8181 + << filename << endl;
8183 + const entier bufsize=1024;
8184 + char s[bufsize+1];
8185 + // Lecture de l'entete:
8186 + is.get_istream().getline(s, bufsize);
8187 + check(is, "failed reading line 1");
8188 + const char * lata_header = "LATA_V2.";
8189 + old_style_lata_ = 0;
8190 + if (strncmp(s, lata_header, strlen(lata_header)) == 0) {
8191 + Journal(2) << "LataDB::read_master_file found lata format " << lata_header << endl;
8192 + old_style_lata_ = 0;
8193 + } else if ((Motcle(s).debute_par("Trio_U"))||(Motcle(s).debute_par("TRUST"))) {
8194 + Journal(2) << "LataDB::read_master_file found old style lata format" << endl;
8195 + old_style_lata_ = 1;
8197 + Journal(2) << "LataDB::read_master_file error reading header: expected LATA_V2.0 or TRUST"
8198 + << " instead of " << s << endl;
8199 + throw(LataDBError(LataDBError::BAD_HEADER));
8202 + is.get_istream().getline(s, bufsize);
8203 + check(is, "failed reading line 2");
8205 + is.get_istream().getline(s, bufsize);
8206 + check(is, "failed reading line 3");
8210 +int is_med(const char* filename)
8212 + Motcle motcle_nom_fic(filename);
8214 + if (motcle_nom_fic.finit_par(".med"))
8219 +// Description: Reads the .lata database in the given file indicating than the
8220 +// associated data files will be found in directory "prefix".
8221 +// If not empty, "prefix" must finish with a '/'.
8222 +// For "prefix" and "filename", if they do not begin with '/', are relative to pwd.
8224 +// BAD_HEADER means that the header found in this stream is not LATA_V2
8225 +// READ_ERROR means that an error has been found in the file (premature eof,
8226 +// io error, bad keyword, ...)
8227 +// FILE_NOT_FOUND means that, well, the lata file could not be opened
8228 +void LataDB::read_master_file(const char *prefix, const char *filename)
8234 + path_prefix_ = prefix;
8236 + if (is_med(filename))
8238 + path_prefix_ = "";
8239 + read_master_file_med(prefix,filename);
8243 + //Journal() << "RECOMPILED PLUGIN !" << endl;
8246 + read_master_file_header(filename, is);
8248 + // Defaults for lataV1
8249 + default_type_int_.msb_ = LataDBDataType::ASCII;
8250 + default_type_int_.type_ = LataDBDataType::INT32;
8251 + default_type_int_.array_index_ = LataDBDataType::F_INDEXING;
8252 + default_type_int_.data_ordering_ = LataDBDataType::C_ORDERING;
8253 + default_type_int_.fortran_bloc_markers_ = LataDBDataType::BLOC_MARKERS_SINGLE_WRITE;
8254 + default_type_int_.bloc_marker_type_ = LataDBDataType::INT32;
8255 + default_float_type_ = LataDBDataType::REAL32;
8257 + // Create timestep 0 (global domain and fields)
8258 + timesteps_.add(LataDBTimestep());
8259 + entier interface_file_not_found = 0;
8262 + read_keyword(is, nomlu,motlu);
8265 + if (motlu == "Fin")
8267 + Journal(verb_level) << "End of file by FIN" << endl;
8270 + else if (motlu == "Format")
8272 + Journal(verb_level) << "Reading Format " << endl;
8273 + read_keyword(is, nomlu, motlu);
8274 + LataDBDataType::Type tmp_int_type;
8275 + read_format_string(motlu, default_type_int_, tmp_int_type, default_float_type_);
8276 + default_type_int_.type_ = tmp_int_type;
8277 + read_keyword(is, nomlu, motlu);
8279 + else if (motlu == "Temps")
8281 + LataDBTimestep & t = timesteps_.add(LataDBTimestep());
8282 + const entier i = timesteps_.size() - 1;
8284 + check(is, "failed reading time parameter");
8285 + Journal(verb_level) << "Reading timestep " << i << " t=" << t.time_ << endl;
8286 + read_keyword(is, nomlu, motlu);
8288 + else if (motlu == "Geom")
8290 + // This is the new syntax to declare a geometry.
8291 + // nodes, elements faces, files are declared in separate "champ" entries
8292 + LataDBGeometry dom;
8293 + dom.timestep_ = timesteps_.size()-1;
8295 + check(is, "failed reading domain name");
8296 + Journal(verb_level) << "New domain " << dom.name_ << endl;
8298 + read_keyword(is, nomlu, motlu);
8299 + if (motlu.debute_par("type_elem=")) {
8300 + read_string_param(is, motlu, dom.elem_type_, "error reading type_elem parameter");
8301 + Journal(verb_level+1) << " type_elem=" << dom.elem_type_ << endl;
8305 + if (dom.elem_type_ == "") {
8306 + Journal() << "Error reading Geometry: missing type_elem parameter" << endl;
8307 + throw(LataDBError(LataDBError::READ_ERROR));
8309 + add(timesteps_.size() - 1, dom);
8311 + else if (motlu == "Geometrie")
8313 + // Declare a geometry: nodes and elements are embedded in a single file described here
8314 + // (legacy syntax)
8315 + LataDBGeometry dom;
8319 + dom.timestep_ = timesteps_.size()-1;
8320 + check(is, "failed reading domain name");
8321 + Journal(verb_level) << "Reading domain " << dom.name_ << endl;
8322 + som.name_ = "SOMMETS";
8323 + som.geometry_ = dom.name_;
8327 + check(is, "failed reading domain filename");
8328 + som.filename_ = n;
8329 + long long nb_elem = -1;
8330 + long long nb_faces = -1;
8331 + entier nproc = -1;
8332 + Nom file_decal_som;
8333 + Nom file_decal_elem;
8334 + Nom file_decal_faces;
8336 + read_keyword(is, nomlu, motlu);
8337 + if (motlu.debute_par("nb_som_tot=")) {
8338 + read_long_param(is, motlu, som.size_, "bad nb_som_tot parameter");
8339 + } else if (motlu.debute_par("nb_elem_tot=")) {
8340 + read_long_param(is, motlu, nb_elem, "bad nb_elem_tot parameter");
8341 + } else if (motlu.debute_par("type_elem=")) {
8342 + read_string_param(is, motlu, dom.elem_type_, "error reading type_elem parameter");
8343 + } else if (motlu.debute_par("nb_faces_tot=")) {
8344 + read_long_param(is, motlu, nb_faces, "bad nb_elem_tot parameter");
8345 + } else if (motlu.debute_par("format=")) {
8347 + read_string_param(is, motlu, fmt, "bad format parameter");
8348 + if (fmt=="BINARY") {
8349 + default_type_int_.msb_ = LataDBDataType::machine_msb_;
8351 + } else if (motlu.debute_par("joints_sommets")) {
8352 + read_keyword(is, nomlu, motlu);
8353 + read_int_param(is, motlu, nproc, "bad nproc parameter");
8354 + read_keyword(is, nomlu, motlu);
8355 + read_string_param(is, nomlu, file_decal_som, "bad decalage file parameter");
8356 + Journal(verb_level+1) << " decal_som " << nproc;
8357 + } else if (motlu.debute_par("joints_elements")) {
8358 + read_keyword(is, nomlu, motlu);
8359 + read_int_param(is, motlu, nproc, "bad nproc parameter");
8360 + read_keyword(is, nomlu, motlu);
8361 + read_string_param(is, nomlu, file_decal_elem, "bad decalage file parameter");
8362 + Journal(verb_level+1) << " decal_elem " << nproc;
8363 + } else if (motlu.debute_par("joints_faces")) {
8364 + read_keyword(is, nomlu, motlu);
8365 + read_int_param(is, motlu, nproc, "bad nproc parameter");
8366 + read_keyword(is, nomlu, motlu);
8367 + read_string_param(is, nomlu, file_decal_faces, "bad decalage file parameter");
8368 + Journal(verb_level+1) << " decal_faces " << nproc;
8371 + Journal(verb_level+1) << " " << motlu << endl;
8373 + som.datatype_ = default_type_float();
8374 + LataDBField elem(som);
8375 + elem.size_ = nb_elem;
8376 + elem.datatype_ = default_type_int_;
8377 + LataDBField faces(elem); // copy filename_
8378 + faces.size_ = nb_faces;
8379 + LataDBField elem_faces(elem);
8380 + elem_faces.size_ = nb_elem;
8381 + elem.name_ = "ELEMENTS";
8382 + faces.name_ = "FACES";
8383 + elem_faces.name_ = "ELEM_FACES";
8384 + elem.geometry_ = dom.name_;
8385 + faces.geometry_ = dom.name_;
8386 + elem_faces.geometry_ = dom.name_;
8388 + if (som.size_ < 0 || elem.size_ < 0) {
8389 + Journal() << "Error reading Geometry: missing or bad nb_som_tot or nb_elem_tot parameter" << endl;
8390 + throw(LataDBError(LataDBError::READ_ERROR));
8392 + if (dom.elem_type_ == "") {
8393 + Journal() << "Error reading Geometry: missing type_elem parameter" << endl;
8394 + throw(LataDBError(LataDBError::READ_ERROR));
8396 + get_element_data(dom.elem_type_, som.nb_comp_, elem.nb_comp_, faces.nb_comp_, elem_faces.nb_comp_);
8398 + // Add domain and som which are complete. We need the "som" to be in the database
8399 + // for the "old lata 2D hack" in read_data2_()
8400 + add(timesteps_.size() - 1, dom);
8401 + add(timesteps_.size() - 1, som);
8402 + // Parse the geometry file to find file_offsets
8404 + Journal(verb_level) << " Parsing geometry file to find file offset of data blocs" << endl;
8405 + LataDataFile f(internal_data_buffer_, path_prefix_, som.filename_,som.datatype_.msb_);
8406 + IntTab * null = 0; // Null pointer => don't actually read the data
8407 + read_data2_(f, som, null);
8408 + elem.datatype_.file_offset_ = f.position();
8409 + Journal(verb_level+1) << " elements at file offset " << elem.datatype_.file_offset_ << endl;
8410 + if (faces.size_ >= 0) {
8411 + read_data2_(f, elem, null);
8412 + faces.datatype_.file_offset_ = f.position();
8413 + Journal(verb_level+1) << " faces at file offset " << faces.datatype_.file_offset_ << endl;
8414 + read_data2_(f, faces, null);
8415 + elem_faces.datatype_.file_offset_ = f.position();
8416 + Journal(verb_level+1) << " elem_faces at file offset " << elem_faces.datatype_.file_offset_ << endl;
8420 + add(timesteps_.size() - 1, elem);
8421 + if (faces.size_ >= 0) {
8422 + Journal(verb_level+1) << " Adding FACES and ELEM_FACES " << faces.size_ << endl;
8423 + add(timesteps_.size() - 1, faces);
8424 + add(timesteps_.size() - 1, elem_faces);
8427 + LataDBField joint(elem);
8428 + joint.datatype_.file_offset_ = 0;
8429 + joint.size_ = nproc;
8430 + joint.nb_comp_ = 2;
8431 + joint.reference_ = "";
8432 + joint.name_ = "JOINTS_SOMMETS";
8433 + joint.filename_ = file_decal_som;
8434 + add(timesteps_.size() - 1, joint);
8435 + joint.reference_ = "";
8436 + joint.name_ = "JOINTS_ELEMENTS";
8437 + joint.filename_ = file_decal_elem;
8438 + add(timesteps_.size() - 1, joint);
8439 + if (file_decal_faces != "??") {
8440 + joint.reference_ = "";
8441 + joint.name_ = "JOINTS_FACES";
8442 + joint.filename_ = file_decal_faces;
8443 + add(timesteps_.size() - 1, joint);
8447 + else if (motlu == "Champ")
8449 + LataDBField field;
8450 + field.datatype_ = default_type_float();
8451 + is >> field.name_;
8452 + check(is, "failed reading field name");
8453 + Journal(verb_level) << "Reading field " << field.name_ << endl;
8456 + check(is, "failed reading field filename");
8457 + field.filename_ = n;
8458 + Journal(verb_level+1) << " filename=" << n << endl;
8460 + if ((field.name_ == "INTERFACES" || field.name_ == "PARTICULES") && old_style_lata_) {
8461 + // This is the old dirty syntax for moving meshes
8463 + Journal(verb_level+1) << " Parsing an oldstyle interface file" << endl;
8464 + // Open the file and read the content
8466 + LataDBDataType::MSB msb = default_type_int_.msb_;
8467 + LataDataFile f(internal_data_buffer_, path_prefix_, field.filename_,msb);
8469 + LataDBDataType::Type int_type = default_type_int_.type_;
8470 + LataDBDataType::Type float_type = default_float_type_;
8471 + LataDBGeometry dom;
8472 + dom.timestep_ = timesteps_.size()-1;
8473 + dom.name_ = field.name_;
8475 + som.name_ = "SOMMETS";
8476 + som.filename_ = field.filename_;
8477 + som.geometry_ = field.name_;
8478 + som.datatype_ = default_type_float();
8479 + som.datatype_.fortran_bloc_markers_ = LataDBDataType::NO_BLOC_MARKER;
8480 + ArrOfInt tmptab(2);
8481 + bloc_read(f, msb, int_type, tmptab);
8482 + som.nb_comp_ = tmptab[0]; // dimension
8483 + som.size_ = tmptab[1]; // nb nodes
8484 + Journal(verb_level+1) << " Nb nodes=" << som.size_ << " dimension=" << som.nb_comp_ << endl;
8485 + som.datatype_.file_offset_ = f.position();
8486 + bloc_read_skip(f, msb, float_type, som.size_ * som.nb_comp_);
8488 + elem.name_ = "ELEMENTS";
8489 + elem.filename_ = field.filename_;
8490 + elem.geometry_ = field.name_;
8491 + elem.datatype_ = default_type_int_;
8492 + elem.datatype_.fortran_bloc_markers_ = LataDBDataType::NO_BLOC_MARKER;
8493 + elem.datatype_.array_index_ = LataDBDataType::C_INDEXING;
8494 + bloc_read(f, msb, int_type, tmptab);
8495 + elem.nb_comp_ = tmptab[0];
8496 + elem.size_ = tmptab[1];
8497 + Journal(verb_level+1) << " Nb elements=" << elem.size_ << " shape=" << elem.nb_comp_ << endl;
8498 + if (field.name_ == "PARTICULES") {
8499 + // Special case for front-tracking markers
8500 + Journal(verb_level+1) << " PARTICULES: element type = point" << endl;
8501 + dom.elem_type_ = "POINT";
8503 + if (elem.nb_comp_ == 2)
8504 + dom.elem_type_ = "SEGMENT";
8505 + else if (elem.nb_comp_ == 3)
8506 + dom.elem_type_ = "TRIANGLE_3D";
8508 + Journal() << "Error reading an interface: invalid element shape " << elem.nb_comp_ << endl;
8509 + throw(LataDBError(LataDBError::READ_ERROR));
8512 + elem.datatype_.file_offset_ = f.position();
8513 + bloc_read_skip(f, msb, int_type, elem.size_ * elem.nb_comp_);
8514 + add(timesteps_.size() - 1, dom);
8515 + add(timesteps_.size() - 1, som);
8516 + add(timesteps_.size() - 1, elem);
8517 + // Read components:
8519 + LataDBField fieldbis;
8520 + f.set_encoding(msb, int_type);
8521 + f.set_exception(0);
8522 + f >> fieldbis.localisation_;
8523 + f.set_exception(1);
8524 + if (fieldbis.localisation_ == "")
8526 + fieldbis.filename_ = som.filename_;
8527 + fieldbis.geometry_ = som.geometry_;
8528 + fieldbis.datatype_ = som.datatype_;
8529 + tmptab.resize_array(1);
8530 + bloc_read(f, msb, int_type, tmptab);
8531 + fieldbis.nb_comp_ = tmptab[0];
8532 + if (fieldbis.nb_comp_ == som.nb_comp_)
8533 + fieldbis.nature_ = LataDBField::VECTOR;
8535 + fieldbis.nature_ = LataDBField::SCALAR;
8536 + f >> fieldbis.name_;
8537 + if (fieldbis.localisation_ == "SOM") {
8538 + fieldbis.size_ = som.size_;
8540 + fieldbis.size_ = elem.size_;
8542 + Journal(verb_level+1) << " Interface field " << fieldbis.localisation_ << " "
8543 + << fieldbis.name_ << endl;
8544 + fieldbis.datatype_.file_offset_ = f.position();
8545 + bloc_read_skip(f, msb, float_type, fieldbis.size_ * fieldbis.nb_comp_);
8546 + add(timesteps_.size() - 1, fieldbis);
8549 + catch (LataDBError err) {
8550 + // If file is missing, issue the "missing file" message and continue
8551 + if (err.err_ != LataDBError::FILE_NOT_FOUND)
8554 + interface_file_not_found++;
8556 + // Read next keyword:
8557 + read_keyword(is, nomlu, motlu);
8559 + if (old_style_lata_) {
8560 + // Old (legacy) syntax for champs: we must guess the properties from the filename!
8562 + field.datatype_ = default_type_float();
8563 + // Extract other data from filename (nb_comp_, localisation_, etc)
8564 + // find geometry name
8565 + Noms dom_names = geometry_names(0 /* timestep */);
8566 + const entier nb_geom = dom_names.size();
8568 + for (i = 0; i < nb_geom; i++) {
8569 + Nom testname(".");
8570 + testname += dom_names[i];
8572 + if (Motcle(n).find(testname)>=0)
8575 + if (i == nb_geom) {
8576 + Journal() << "Error in LataDB_V1::read_master_file: could not find domain for Champ " << n << endl;
8577 + throw(LataDBError(LataDBError::READ_ERROR));
8579 + Journal(verb_level+1) << " geometry=" << dom_names[i] << endl;
8580 + const LataDBGeometry & dom = get_geometry(0, dom_names[i]);
8581 + field.geometry_ = dom_names[i];
8582 + lata_v1_get_localisation(n, field.localisation_);
8583 + Journal(verb_level+1) << " localisation=" << field.localisation_ << endl;
8584 + const LataDBField & sommets = get_field(0 /* timestep */, dom_names[i], "SOMMETS", "*");
8585 + const entier dim = sommets.nb_comp_;
8586 + field.nb_comp_ = lata_v1_get_nb_comp(field.name_, field.localisation_, dom, dim, field.nature_, field.datatype_.data_ordering_);
8587 + Journal(verb_level+1) << " composantes=" << field.nb_comp_ << endl;
8588 + if (field.localisation_.debute_par("SOM"))
8589 + field.size_ = sommets.size_;
8590 + else if (field.localisation_.debute_par("ELEM"))
8591 + field.size_ = get_field(0 /* timestep */, dom_names[i], "ELEMENTS", "*").size_;
8592 + else if (field.localisation_.debute_par("FACE"))
8593 + field.size_ = get_field(0 /* timestep */, dom_names[i], "FACES", "*").size_;
8595 + Journal() << "Error in LataDB_V1::read_master_file: invalid localisation "
8596 + << field.localisation_ << endl;
8597 + throw(LataDBError(LataDBError::READ_ERROR));
8599 + // Read next keyword:
8600 + read_keyword(is, nomlu, motlu);
8602 + // NEW LATAV2 SYNTAX for fields
8603 + // The default data type is "float_"
8604 + field.datatype_ = default_type_float();
8607 + read_keyword(is, nomlu, motlu);
8608 + if (motlu.debute_par("geometrie=")) {
8609 + read_string_param(is, nomlu, field.geometry_, "error reading geometrie parameter");
8610 + // Check that the geometry exists
8611 + get_geometry(timesteps_.size() - 1, field.geometry_, FIRST_AND_CURRENT);
8612 + } else if (motlu.debute_par("composantes=")) {
8613 + read_int_param(is, motlu, field.nb_comp_, "bad composantes parameter");
8614 + } else if (motlu.debute_par("localisation=")) {
8615 + read_string_param(is, motlu, field.localisation_, "error reading localisation parameter");
8616 + } else if (motlu.debute_par("format=")) {
8617 + LataDBDataType::Type tmp_int_type; // Unused
8618 + LataDBDataType::Type tmp_float_type; // unused
8619 + read_format_string(motlu, field.datatype_, tmp_int_type, tmp_float_type);
8620 + } else if (motlu.debute_par("size=")) {
8621 + read_long_param(is, motlu, field.size_, "error reading size parameter");
8622 + } else if (motlu.debute_par("file_offset=")) {
8623 + read_long_param(is, motlu, field.datatype_.file_offset_, "error reading file offset parameter");
8624 + } else if (motlu.debute_par("nature=")) {
8626 + read_string_param(is, motlu, nat, "error reading nature parameter");
8627 + if (nat.find("SCALAR")>=0)
8628 + field.nature_ = LataDBField::SCALAR;
8629 + else if (nat.find("VECTOR")>=0)
8630 + field.nature_ = LataDBField::VECTOR;
8632 + Journal() << "Error in LataDB_V1::read_master_file: invalid nature "
8634 + throw(LataDBError(LataDBError::READ_ERROR));
8636 + } else if (motlu.debute_par("reference=")) {
8638 + read_string_param(is, motlu, ref, "error reading reference parameter");
8639 + field.reference_ = ref;
8640 + } else if (motlu.debute_par("noms_compo=")) {
8642 + read_noms_param(is, motlu, ref, "error reading noms_compo");
8643 + Journal(verb_level+1)<<"noms_compos pas interprete "<<motlu<<endl;
8647 + Journal(verb_level+1) << " " << motlu << endl;
8649 + if (field.size_ < 0) {
8650 + // This is untested. Deactivate for the moment.
8651 + // Journal(verb_level) << " No size parameter given. Take size of the localisation field: ";
8652 + // if (field_exists(timesteps_.size() - 1, field.geometry_, field.localisation_, FIRST_AND_CURRENT)) {
8653 + // field.size_ = get_field(timesteps_.size() - 1, field.geometry_, field.localisation_, FIRST_AND_CURRENT).size_;
8655 + Journal() << " Error, no size parameter for field " << field.name_ << " and localisation " << field.localisation_
8656 + << " does not match any existing field" << endl;
8657 + throw(LataDBError(LataDBError::READ_ERROR));
8661 + add(timesteps_.size() - 1, field);
8664 + else if (motlu == "import_file")
8666 + // Load another lata master file recursively and merge timesteps
8668 + is >> filenamebis; // Read filename (without prefix)
8670 + Nom filename2(prefix);
8671 + filename2 += filenamebis;
8672 + Journal(verb_level) << "Importing another lata database from file: " << filename << endl;
8673 + newdb.read_master_file(prefix, filename2);
8677 + Journal() << "Error: unknown keyword: " << motlu << endl;
8678 + throw(LataDBError(LataDBError::READ_ERROR));
8681 + if (interface_file_not_found)
8682 + throw LataDBError(LataDBError::FILE_NOT_FOUND);
8685 +// Read field data from file f into data array "data".
8686 +// If data is a null pointer, just skip the data bloc and leave the file pointer
8687 +// at the beginning of the next data bloc (used to parse the geometry file if file_offset
8688 +// are not specified in the lata master file)
8689 +template <class C_Tab>
8690 +void LataDB::read_data2_(LataDataFile & f,
8691 + const LataDBField & fld,
8692 + C_Tab * const data, // const pointer to non const data !
8693 + long long debut, entier n, const ArrOfInt *lines_to_read) const
8696 + if (is_med(fld.filename_))
8698 + read_data2_med_(fld,data,debut,n,lines_to_read);
8701 + // Si file_offset_ vaut 0 on y va car on peut avoir lu a un autre endroit avant.
8702 + if (fld.datatype_.file_offset_ >= 0) {
8703 + Journal(verb_level_data_bloc+1) << " Seeking at position " << fld.datatype_.file_offset_ << endl;
8704 + f.seek(fld.datatype_.file_offset_, LataDataFile::ABSOLUTE);
8707 + if (lines_to_read)
8708 + n = lines_to_read->size_array();
8713 + // in old lata format, 2d data is written as 3d:
8714 + // Yeah: dirty specs make dirty code...
8715 + long long size_in_file = fld.size_;
8716 + entier nb_comp_in_file = fld.nb_comp_;
8717 + // entier old_lata_hack = 0;
8718 + if (old_style_lata_ && (Motcle(fld.geometry_) != "INTERFACES") && (Motcle(fld.geometry_) != "PARTICULES")) {
8719 + const LataDBField & som = get_field(0, fld.geometry_, "SOMMETS", "*");
8720 + if (som.nb_comp_ == 2) {
8721 + //old_lata_hack = 1;
8722 + if (fld.name_ == "ELEMENTS") {
8723 + nb_comp_in_file *= 2;
8724 + } else if (fld.name_ == "SOMMETS") {
8725 + nb_comp_in_file = 3; // all coordinates in 3D
8726 + size_in_file *= 2;
8727 + } // else if (fld.localisation_.debute_par("SOM")) {
8728 + // size_in_file *= 2;
8730 + Journal(verb_level_data_bloc+1) << "Old lata hack for 2D" << endl;
8734 + if (fld.nb_comp_ < 0 || fld.size_ < 0) {
8735 + Journal() << "Error in LataDB::read_data_: nb_comp_ or size_ not initialized for component " << fld.name_ << endl;
8739 + if ((!lines_to_read) && (debut < 0 || debut + n > fld.size_)) {
8740 + Journal() << "Error in LataDB::read_data_: [debut,debut+n] invalid range (size=" << fld.size_ << ")" << endl;
8745 + data->resize(n, nb_comp_in_file);
8747 + switch (fld.datatype_.data_ordering_) {
8748 + case LataDBDataType::C_ORDERING:
8749 + // data written like this: tab(0,0) tab(0,1) tab(0,2) ... tab(1,0) tab(1,1) tab(1,2) ...
8750 + if (fld.datatype_.fortran_bloc_markers_ == LataDBDataType::BLOC_MARKERS_MULTIPLE_WRITES) {
8751 + Journal() << "Error in LataDB::read_data_: fortran_bloc_markers_=MULTIPLE_WRITES is incompatible with data_ordering=C" << endl;
8752 + throw LataDBError(LataDBError::DATA_ERROR);
8754 + skip_blocksize(f, fld.datatype_);
8756 + if (!lines_to_read) {
8757 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, (FileOffset)debut * nb_comp_in_file);
8758 + bloc_read(f, fld.datatype_.msb_, fld.datatype_.type_, *data);
8759 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, (FileOffset)(size_in_file - debut - n) * nb_comp_in_file);
8762 + // Read 1024 lines chunks at a time even if only some values are needed inside
8763 + long long chunk_size = 0;
8764 + long long current_chunk_pos = 0;
8765 + long long current_file_pos = 0;
8766 + const entier nl = lines_to_read->size_array();
8767 + for (entier i = 0; i < nl; i++) {
8768 + const long long next_line = (*lines_to_read)[i];
8769 + // Is this line in the current chunk ?
8770 + if (next_line >= current_chunk_pos + chunk_size) {
8771 + // No => read the chunk containing this line
8772 + chunk_size = size_in_file - next_line;
8773 + if (chunk_size > 1024)
8774 + chunk_size = 1024;
8775 + tmp.resize(chunk_size, nb_comp_in_file);
8776 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, (next_line - current_file_pos) * nb_comp_in_file);
8777 + bloc_read(f, fld.datatype_.msb_, fld.datatype_.type_, tmp);
8778 + current_chunk_pos = next_line;
8779 + current_file_pos = next_line + chunk_size;
8781 + // Extract data from tmp array
8782 + const long long tmp_index = next_line - current_chunk_pos;
8783 + for (entier j = 0; j < nb_comp_in_file; j++)
8784 + (*data)(i, j) = tmp(tmp_index, j);
8786 + if (current_file_pos != size_in_file)
8787 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, (size_in_file - current_file_pos) * nb_comp_in_file);
8790 + // just skip the data
8791 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, size_in_file * nb_comp_in_file);
8793 + skip_blocksize(f, fld.datatype_);
8795 + case LataDBDataType::F_ORDERING:
8797 + // data written like this: tab(0,0) tab(1,0) tab(2,0) ... tab(0,1) tab(1,1) tab(2,1) ... tab(0,2) tab(1,2) tab(2,2) ...
8798 + entier multiple_bloc_markers = (fld.datatype_.fortran_bloc_markers_ == LataDBDataType::BLOC_MARKERS_MULTIPLE_WRITES);
8799 + // reverse rows and columns of the array
8801 + if (!multiple_bloc_markers)
8802 + skip_blocksize(f, fld.datatype_);
8803 + for (entier i = 0; i < nb_comp_in_file; i++) {
8804 + if (multiple_bloc_markers)
8805 + skip_blocksize(f, fld.datatype_);
8807 + if (!lines_to_read) {
8809 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, debut);
8810 + bloc_read(f, fld.datatype_.msb_, fld.datatype_.type_, tmp);
8811 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, size_in_file - debut - n);
8812 + for (entier j = 0; j < n; j++)
8813 + (*data)(j, i) = tmp(j, 0);
8816 + // Read 1024 lines chunks at a time even if only some values are needed inside
8817 + long long chunk_size = 0;
8818 + long long current_chunk_pos = 0;
8819 + long long current_file_pos = 0;
8820 + const entier nl = lines_to_read->size_array();
8821 + for (entier j = 0; j < nl; j++) {
8822 + const long long next_line = (*lines_to_read)[j];
8823 + // Is this line in the current chunk ?
8824 + if (next_line >= current_chunk_pos + chunk_size) {
8825 + // No => read the chunk containing this line
8826 + chunk_size = size_in_file - next_line;
8827 + if (chunk_size > 1024)
8828 + chunk_size = 1024;
8829 + tmp.resize(chunk_size, 1);
8830 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, (next_line - current_file_pos));
8831 + bloc_read(f, fld.datatype_.msb_, fld.datatype_.type_, tmp);
8832 + current_chunk_pos = next_line;
8833 + current_file_pos = next_line + chunk_size;
8835 + // Extract data from tmp array
8836 + const entier tmp_index = (entier)(next_line - current_chunk_pos);
8837 + (*data)(j, i) = tmp(tmp_index, 0);
8839 + if (current_file_pos != size_in_file)
8840 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, (size_in_file - current_file_pos));
8843 + bloc_read_skip(f, fld.datatype_.msb_, fld.datatype_.type_, size_in_file);
8845 + if (multiple_bloc_markers)
8846 + skip_blocksize(f, fld.datatype_);
8848 + if (!multiple_bloc_markers)
8849 + skip_blocksize(f, fld.datatype_);
8853 + Journal() << "Error in LataDB::read_data_: data_ordering not implemented" << endl;
8857 + // old lata 2d hack :
8858 + if (data && nb_comp_in_file != fld.nb_comp_) {
8859 + // drop column in data array
8861 + data->resize(n, fld.nb_comp_);
8862 + for (entier i = 0; i < n; i++)
8863 + for (entier j = 0; j < fld.nb_comp_; j++)
8864 + (*data)(i,j) = tmp(i,j);
8869 +// Read n * fld.nb_comp_ values in the file filename_, starting from debut * fld.nb_comp_
8870 +template <class C_Tab>
8871 +void LataDB::read_data_(const LataDBField & fld,
8872 + C_Tab & data, long long debut, entier n) const
8874 + Journal(verb_level_data_bloc) << "LataDB::read_data(" << fld.timestep_ << "," << fld.uname_
8875 + << ") Reading " << path_prefix_ << fld.filename_ << " start at " << debut << " size "
8878 + LataDataFile f(internal_data_buffer_, path_prefix_, fld.filename_,fld.datatype_.msb_);
8879 + read_data2_(f, fld, &data, debut, n);
8884 +// Read n * fld.nb_comp_ values in the file filename_, starting from debut * fld.nb_comp_
8885 +template <class C_Tab>
8886 +void LataDB::read_data_(const LataDBField & fld,
8887 + C_Tab & data, const ArrOfInt & lines_to_read) const
8889 + Journal(verb_level_data_bloc) << "LataDB::read_data(" << fld.timestep_ << "," << fld.uname_
8890 + << ") Reading " << path_prefix_ << fld.filename_ << ", " << lines_to_read.size_array() << " non contiguous lines"
8893 + LataDataFile f(internal_data_buffer_, path_prefix_, fld.filename_,fld.datatype_.msb_);
8894 + read_data2_(f, fld, &data, -1, -1, &lines_to_read);
8897 +// Description: reads n * nb_comp values in the file filename_ starting from debut*nb_comp_
8898 +// If array_index is F_STYLE, substract 1 to all values.
8899 +void LataDB::read_data(const LataDBField & fld, IntTab & data, long long debut, entier n) const
8901 + read_data_(fld, data, debut, n);
8902 + if (fld.datatype_.array_index_ == LataDBDataType::F_INDEXING) {
8903 + ArrOfInt & data2 = data;
8904 + const entier n2 = data2.size_array();
8905 + for (entier i = 0; i < n2; i++)
8910 +// Description: reads n * nb_comp values in the file filename_ starting from debut*nb_comp_
8911 +void LataDB::read_data(const LataDBField & fld, DoubleTab & data, long long debut, entier n) const
8913 + Journal() << "LataDB::read_data not coded for double" << endl;
8917 +void LataDB::read_data(const LataDBField & fld, FloatTab & data, long long debut, entier n) const
8919 + read_data_(fld, data, debut, n);
8922 +// Description: reads lines_to_read.size_array() * nb_comp values.
8923 +// If array_index is F_STYLE, substract 1 to all values.
8924 +void LataDB::read_data(const LataDBField & fld, IntTab & data, const ArrOfInt & lines_to_read) const
8926 + read_data_(fld, data, lines_to_read);
8927 + if (fld.datatype_.array_index_ == LataDBDataType::F_INDEXING) {
8928 + ArrOfInt & data2 = data;
8929 + const entier n = data2.size_array();
8930 + for (entier i = 0; i < n; i++)
8935 +// Description: reads lines_to_read.size_array() * nb_comp values.
8936 +void LataDB::read_data(const LataDBField & fld, DoubleTab & data, const ArrOfInt & lines_to_read) const
8938 + Journal() << "LataDB::read_data not coded for double" << endl;
8942 +// Description: reads lines_to_read.size_array() * nb_comp values.
8943 +void LataDB::read_data(const LataDBField & fld, FloatTab & data, const ArrOfInt & lines_to_read) const
8945 + read_data_(fld, data, lines_to_read);
8949 +// Description: copy the source LataDB object, keeping only timesteps, geometries and fields
8950 +// that are specified (timestep 0 is always included, do not put it in the list).
8951 +// field_nms can contain field.name_ (like VITESSE), or extended name with localisation
8952 +// (like VITESSE_ELEM)
8953 +void LataDB::filter_db(const LataDB & source,
8954 + const Motcles & geometry_nms,
8955 + const Motcles & field_nms,
8956 + const ArrOfInt & timesteps)
8958 + path_prefix_ = source.path_prefix_;
8959 + header_ = source.header_;
8960 + case_ = source.case_;
8961 + software_id_ = source.software_id_;
8962 + old_style_lata_ = source.old_style_lata_;
8963 + default_type_int_ = source.default_type_int_;
8964 + default_float_type_ = source.default_float_type_;
8966 + const entier nb_tsteps = timesteps.size_array();
8967 + for (entier it = 0; it < nb_tsteps + 1; it++) {
8968 + entier src_tstep = 0;
8970 + src_tstep = timesteps[it-1];
8971 + LataDBTimestep & tstep = timesteps_.add(LataDBTimestep());
8972 + tstep.time_ = source.get_time(src_tstep);
8973 + // Copy geometries
8974 + Motcles geoms = noms_to_motcles(source.geometry_names(src_tstep));
8976 + for (ig = 0; ig < geoms.size(); ig++)
8977 + if (geometry_nms.rang(geoms[ig]) >= 0)
8978 + tstep.geoms_.add(source.get_geometry(src_tstep, geoms[ig]));
8980 + geoms = noms_to_motcles(geometry_names(nb_timesteps()-1, FIRST_AND_CURRENT));
8981 + for (ig = 0; ig < geoms.size(); ig++) {
8982 + LataVector<Field_UName> unames = source.field_unames(src_tstep, geoms[ig], "*");
8983 + for (entier i_f = 0; i_f < unames.size(); i_f++) {
8984 + const LataDBField & src = source.get_field(src_tstep, unames[i_f]);
8985 + Nom name_loc = src.name_;
8987 + name_loc += src.localisation_;
8988 + if (field_nms.rang(src.name_) >= 0 || field_nms.rang(name_loc) >= 0)
8989 + tstep.fields_.add(src);
8995 +// Description: set the default value of the path prefix where write_data() will write the data
8996 +// Warning: there is no check that the master lata file is actually written at the same place
8997 +// and that all the files and data blocks mentionned in the database actually exist.
8998 +// For the file_offset_ field, -2 is considered "unknown".
8999 +void LataDB::set_path_prefix(const char * s)
9004 +#define UPDATE_MACRO(x,unknown) if (((old_type.x==unknown)||(type.x==old_type.x))&&(new_type.x!=unknown)) type.x=new_type.x
9006 +// Description: changes the data type of all fields in the database.
9007 +// The property "x" is changed to "new_type.x" if "new_type.x" is not "unknown"
9008 +// and if "old_type.x" is "unknown" or "equal to the previous property"
9009 +// Example: convert all data to ASCII:
9010 +// LataDBDataType old_type; // All defaults to "unknown" => we update all fields
9011 +// LataDBDataType new_type;
9012 +// new_type.msb_ = LataDBDataType::ASCII; // Change msb_ property to ASCII:
9013 +// Example 2: change all REAL32 data to REAL64
9014 +// LataDBDataType old_type;
9015 +// old_type.type_ = LataDBDataType::REAL32;
9016 +// LataDBDataType new_type;
9017 +// new_type.msb_ = LataDBDataType::REAL64;
9018 +void LataDB::change_all_data_types(const LataDBDataType & old_type, const LataDBDataType & new_type)
9020 + const entier nb_tsteps = timesteps_.size();
9021 + for (entier src_tstep = 0; src_tstep < nb_tsteps; src_tstep++) {
9022 + LataVector<LataDBField> & fields = timesteps_[src_tstep].fields_;
9023 + const entier nb_fields = fields.size();
9024 + for (entier i_field = 0; i_field < nb_fields; i_field++) {
9025 + LataDBDataType & type = fields[i_field].datatype_;
9026 + // For each field, if "old_type" is "unknown" or equal to the previous value,
9027 + // and if "new_type" is not "unknown, then update the field
9028 + UPDATE_MACRO(msb_, LataDBDataType::UNKNOWN_MSB);
9029 + UPDATE_MACRO(type_, LataDBDataType::UNKNOWN_TYPE);
9030 + UPDATE_MACRO(array_index_, LataDBDataType::UNKNOWN_ARRAYINDEX);
9031 + UPDATE_MACRO(data_ordering_, LataDBDataType::UNKNOWN_ORDERING);
9032 + UPDATE_MACRO(fortran_bloc_markers_, LataDBDataType::UNKNOWN_MARKERS);
9033 + UPDATE_MACRO(bloc_marker_type_, LataDBDataType::UNKNOWN_TYPE);
9037 +#undef UPDATE_MACRO
9039 +void LataDB::change_all_data_filenames(const Nom & old_prefix, const Nom & new_prefix)
9041 + const entier nb_tsteps = timesteps_.size();
9042 + for (entier i = 0; i < nb_tsteps; i++) {
9043 + LataVector<LataDBField> & fields = timesteps_[i].fields_;
9044 + // Browse all fields:
9045 + const entier nb_fields = fields.size();
9046 + for (entier j = 0; j < nb_fields; j++) {
9047 + Nom & filename = fields[j].filename_;
9048 + Nom old_filename = filename;
9049 + filename = new_prefix;
9050 + if (old_filename.debute_par(old_prefix)) {
9051 + const entier n = old_filename.longueur()-1;
9052 + const char * s = old_filename;
9053 + for (entier ii = old_prefix.longueur()-1; ii < n; ii++)
9054 + filename += Nom(s[ii]);
9055 + } else if (old_filename == LataDBField::memory_buffer_file()) {
9056 + filename += Nom(".data");
9058 + filename += Nom('_');
9059 + filename += old_filename;
9061 + Journal(verb_level+1) << " Changing filename " << old_filename << " -> " << filename << endl;
9066 +// This method takes all filenames mentionned in the database and sets the file_offset_ entry:
9067 +// - set to 0 for the first field where a given filename appears,
9068 +// - then for all subsequent files referring to the same name:
9069 +// If split_files != 0, rename the files by appending a "_number" and set file_offset to 0
9070 +// otherwise set file_offset_ to 1
9071 +void LataDB::check_all_data_fileoffsets(entier split_files)
9073 + Noms existing_filenames;
9074 + ArrOfInt counts; // For each filenames, number of fields referring to it
9075 + counts.set_smart_resize(1);
9077 + const entier nb_tsteps = timesteps_.size();
9078 + for (entier i = 0; i < nb_tsteps; i++) {
9079 + LataVector<LataDBField> & fields = timesteps_[i].fields_;
9080 + // Browse all fields:
9081 + const entier nb_fields = fields.size();
9082 + for (entier j = 0; j < nb_fields; j++) {
9083 + LataDBField & field = fields[j];
9084 + const entier rank = existing_filenames.rang(field.filename_);
9087 + existing_filenames.add(field.filename_);
9088 + counts.append_array(1);
9089 + field.datatype_.file_offset_ = 0;
9090 + Journal(verb_level+1) << " Changing fileoffset to 0 for file " << field.filename_
9091 + << " " << field.name_ << endl;
9093 + // Existing filename
9094 + if (split_files) {
9095 + entier n = counts[rank]++;
9096 + field.filename_ += "_";
9097 + field.filename_ += Nom(n);
9098 + field.datatype_.file_offset_ = 0;
9099 + Journal(verb_level+1) << " Changing fileoffset to 0 and renaming file " << field.filename_
9100 + << " " << field.name_ << endl;
9102 + field.datatype_.file_offset_ = 1;
9103 + Journal(verb_level+1) << " Changing fileoffset to 1 for file " << field.filename_
9104 + << " " << field.name_ << endl;
9111 +// Returns the rank of the created timestep (always at the end)
9112 +entier LataDB::add_timestep(double time)
9114 + const entier n = nb_timesteps();
9115 + // Timestep 0 can have any time: test only versus other timesteps:
9116 + if (n > 1 && time <= get_time(n-1)) {
9117 + Journal() << "Error in LataDB::add_timestep(" << time
9118 + << "): time is below or equal to last timestep " << get_time(n-1) << endl;
9119 + throw(LataDBError(LataDBError::INVALID_OPERATION));
9121 + LataDBTimestep & t = timesteps_.add(LataDBTimestep());
9123 + Journal(verb_level+1) << "LataDB::add_timestep " << n << " " << time << endl;
9127 +static void add_geom_check(const LataDBGeometry & geom, entier test_flag, const char *message)
9130 + Journal() << "Error in LataDB::add_geometry, name_=" << geom.name_ << endl
9131 + << " geometry data is invalid because of: " << message << endl;
9132 + throw(LataDBError(LataDBError::INVALID_OPERATION));
9136 +void LataDB::add_geometry(const LataDBGeometry & geom)
9138 + add_geom_check(geom, geom.timestep_ >= 0 && geom.timestep_ < nb_timesteps(), "timestep");
9139 + Noms geoms= geometry_names(geom.timestep_, CURRENT);
9140 + add_geom_check(geom, geom.name_ != "" && geom.name_ != "??" && geoms.rang(geom.name_) < 0, "empty or already existing name");
9142 + add(geom.timestep_, geom);
9143 + Journal(verb_level+1) << "LataDB::add_geometry " << geom.name_ << endl;
9146 +void LataDB::set_elemtype(entier tstep, const char *geom_name, const char *elem_type)
9148 + LataDBGeometry & geom = (LataDBGeometry&) get_geometry(tstep, geom_name);
9149 + geom.elem_type_ = elem_type;
9153 +static void add_field_check(const LataDBField & field, entier test_flag, const char *message)
9156 + Journal() << "Error in LataDB::add_field, name_=" << field.name_ << " geometry=" << field.geometry_ << endl
9157 + << " field data is invalid because of: " << message << endl;
9158 + throw(LataDBError(LataDBError::INVALID_OPERATION));
9162 +// Adds a new field to the database.
9163 +// The field.datatype_.file_offset_ will be interpreted in a particular way if the data is
9164 +// written with write_data(), see write_data() documentation.
9165 +// Take special care if the same file is referenced more than once in the database:
9166 +// only one file should have file_offset_ <= 0 and this one will have to be written first
9167 +// with write_data() (or you know what you are doing...)
9168 +void LataDB::add_field(const LataDBField & field)
9170 + add_field_check(field, field.timestep_ >= 0 && field.timestep_ < nb_timesteps(), "timestep");
9171 + add_field_check(field, field.filename_ != "" && field.filename_ != "??", "filename");
9172 + add_field_check(field, field.nb_comp_ > 0, "nb_comp");
9173 + Noms geoms = geometry_names(field.timestep_, FIRST_AND_CURRENT);
9174 + add_field_check(field, field.geometry_ == "" || geoms.rang(field.geometry_) >= 0, "unknown geometry name");
9175 + add_field_check(field, field.name_ != "" && field.name_ != "??", "empty name");
9176 + add_field_check(field, field.component_names_.size() == 0 || field.component_names_.size() == field.nb_comp_, "number of component_names");
9177 + add_field_check(field, field.size_ >= 0, "size");
9178 + add_field_check(field, field.datatype_.msb_ != LataDBDataType::UNKNOWN_MSB, "datatype msb unspecified");
9179 + add_field_check(field, field.datatype_.type_ == LataDBDataType::INT32
9180 + || field.datatype_.type_ == LataDBDataType::INT64
9181 + || field.datatype_.type_ == LataDBDataType::REAL32
9182 + || field.datatype_.type_ == LataDBDataType::REAL64, "datatype type unspecified");
9183 + // If integer type, we must say the indexing type:
9184 + add_field_check(field,
9185 + field.datatype_.type_ == LataDBDataType::REAL32
9186 + || field.datatype_.type_ == LataDBDataType::REAL64
9187 + || field.datatype_.array_index_ != LataDBDataType::UNKNOWN_ARRAYINDEX,
9188 + "datatype array indexing unspecified");
9189 + add_field_check(field, field.datatype_.data_ordering_ != LataDBDataType::UNKNOWN_ORDERING, "datatype data ordering unspecified");
9190 + add_field_check(field, field.datatype_.fortran_bloc_markers_ != LataDBDataType::UNKNOWN_MARKERS, "datatype fortran bloc markers unspecified");
9191 + add_field_check(field, field.datatype_.file_offset_ >= 0, "datatype file_offset_");
9193 + add(field.timestep_, field);
9194 + Journal(verb_level+1) << "LataDB::add_field : " << field.name_ << " " << field.geometry_ << " " << field.filename_ << " " << field.uname_ << endl;
9197 +LataDBDataType LataDB::default_type_float() const
9199 + LataDBDataType type = default_type_int_;
9200 + type.type_ = default_float_type_;
9204 +// Description: Writes the lata master file to filename (filename must contain the path
9205 +// if you don't want to write in the current working directory). All data contained
9206 +// in the database is dumped to the file.
9207 +void LataDB::write_master_file(const char *filename) const
9210 + Journal() << "LataDB::write_master_file got a null filename !!!" << endl;
9211 + throw(LataDBError(LataDBError::INVALID_OPERATION));
9213 + std::ofstream os(filename);
9214 + if (!os.good()) { // isnogood ?
9215 + Journal() << "LataDB::write_master_file failed opening file " << filename << endl;
9216 + throw(LataDBError(LataDBError::FILE_NOT_FOUND));
9218 + // Try to write, if error, catch and close the file:
9219 + Journal(verb_level-1) << "Writing lata master file:" << filename << endl;
9220 + os << "LATA_V2.1" << endl;
9221 + os << case_ << endl;
9222 + os << software_id_ << endl;
9224 + // ****************************************************************
9225 + // Writing data format information:
9228 + build_format_string(LataDBDataType(), default_type_int_, fmt);
9229 + build_format_string(default_type_int_, default_type_float(), fmt2);
9230 + os << "Format " << fmt << "," << fmt2 << endl;
9233 + // ***************************************************************
9234 + // Writing timesteps:
9235 + const entier nb_tsteps = nb_timesteps();
9236 + for (entier tstep = 0; tstep < nb_tsteps; tstep++) {
9238 + os << "TEMPS " << get_time(tstep) << endl;
9240 + Noms geoms = geometry_names(tstep);
9241 + const entier nb_geoms = geoms.size();
9242 + for (entier i_geom = 0; i_geom < nb_geoms; i_geom++) {
9243 + const LataDBGeometry & geom = get_geometry(tstep, geoms[i_geom], FIRST_AND_CURRENT);
9244 + // Do not write geometries of the first timestep
9245 + if (geom.timestep_ == tstep)
9246 + os << "GEOM " << geom.name_ << " type_elem=" << geom.elem_type_ << endl;
9248 + Field_UNames unames = field_unames(tstep, "*", "*");
9249 + for (entier i_field = 0; i_field < unames.size(); i_field++) {
9250 + const LataDBField & field = get_field(tstep, unames[i_field]);
9251 + os << "CHAMP " << field.name_
9252 + << " " << field.filename_;
9253 + if (field.geometry_ != "")
9254 + os << " geometrie=" << field.geometry_;
9255 + os << " size=" << field.size_;
9256 + os << " composantes=" << field.nb_comp_;
9257 + if (field.localisation_ != "??" && field.localisation_ != "")
9258 + os << " localisation=" << field.localisation_;
9259 + if (field.component_names_.size() > 0) {
9260 + os << " noms_compo=";
9261 + const entier n = field.component_names_.size();
9262 + for (entier i = 0; i < n; i++) {
9263 + os << field.component_names_[i];
9268 + switch(field.nature_) {
9269 + case LataDBField::UNKNOWN: break;
9270 + case LataDBField::SCALAR: os << " nature=scalar"; break;
9271 + case LataDBField::VECTOR: os << " nature=vector"; break;
9273 + Journal() << "LataDB::write_master_file error: unknown NATURE" << endl;
9274 + throw(LataDBError(LataDBError::INVALID_OPERATION));
9276 + if (field.reference_ != "" && field.reference_ != "??")
9277 + os << " reference=" << field.reference_;
9278 + Motcle format_string;
9279 + build_format_string(default_type_float(), field.datatype_, format_string);
9280 + if (format_string != "")
9281 + os << " format=" << format_string;
9282 + if (field.datatype_.file_offset_ > 0)
9283 + os << " file_offset=" << field.datatype_.file_offset_;
9287 + os << "FIN" << endl;
9288 + write_master_file_to_call_ = 0;
9291 +// Description: internal template to write a data block. We provide explicit methods write_data()
9292 +// to the user instead of a template.
9293 +template <class C_Tab>
9294 +FileOffset LataDB::write_data_(entier tstep, const Field_UName & uname, const C_Tab & data)
9296 + LataDBField & fld = getset_field(tstep, uname);
9298 + LataDataFile f(internal_data_buffer_, path_prefix_, fld.filename_,
9299 + fld.datatype_.msb_,
9300 + (fld.datatype_.file_offset_ <= 0) ? LataDataFile::WRITE : LataDataFile::APPEND);
9301 + fld.datatype_.file_offset_ = f.position();
9302 + Journal(verb_level_data_bloc) << "Writing block data at offset " << fld.datatype_.file_offset_ << endl;
9303 + if (fld.nb_comp_ != data.dimension(1) || fld.size_ != data.dimension(0)) {
9304 + Journal() << "Error in LataDB::write_data_: nb_comp_ or size_ declared in the field doesnt match array dimensions." << fld.name_ << endl;
9308 + const entier n = fld.size_;
9310 + switch (fld.datatype_.data_ordering_) {
9311 + case LataDBDataType::C_ORDERING:
9313 + if (fld.datatype_.fortran_bloc_markers_ == LataDBDataType::BLOC_MARKERS_MULTIPLE_WRITES) {
9314 + Journal() << "Error in LataDB::write_data_: fortran_bloc_markers_=MULTIPLE_WRITES is incompatible with data_ordering=C" << endl;
9315 + throw LataDBError(LataDBError::DATA_ERROR);
9317 + const entier sz = data.size_array();
9318 + write_blocksize(f, fld.datatype_, sz);
9319 + bloc_write(f, fld.datatype_.msb_, fld.datatype_.type_, data, fld.nb_comp_);
9320 + write_blocksize(f, fld.datatype_, sz);
9323 + case LataDBDataType::F_ORDERING:
9325 + entier multiple_bloc_markers = (fld.datatype_.fortran_bloc_markers_ == LataDBDataType::BLOC_MARKERS_MULTIPLE_WRITES);
9326 + // reverse rows and columns of the array
9329 + if (!multiple_bloc_markers)
9330 + write_blocksize(f, fld.datatype_, data.size_array());
9331 + for (entier i = 0; i < fld.nb_comp_; i++) {
9332 + if (multiple_bloc_markers)
9333 + write_blocksize(f, fld.datatype_, n);
9334 + for (entier j = 0; j < n; j++)
9335 + tmp(j, 0) = data(j, i);
9336 + bloc_write(f, fld.datatype_.msb_, fld.datatype_.type_, tmp, 1);
9337 + if (multiple_bloc_markers)
9338 + write_blocksize(f, fld.datatype_, n);
9340 + if (!multiple_bloc_markers)
9341 + write_blocksize(f, fld.datatype_, data.size_array());
9345 + Journal() << "Error in LataDB::write_data_: data_ordering not implemented" << endl;
9348 + write_master_file_to_call_ = 1;
9349 + return f.position();
9352 +// Writes the data to disk according to datatype_ of the field.
9353 +// The filename will be "path_prefix_ + field.filename_".
9354 +// The path_prefix_ can be changed with set_path_prefix()
9355 +// If field.datatype_.file_offset_<=0, any existing file is deleted and the data is written at offset 0
9356 +// otherwise the data is written at the end of the file and file_offset_ for this field is updated.
9357 +// Returns the FileOffset of the file pointer after writing the data (points to the end of the file)
9358 +// The call to write_master_file() must be done after all write_data (otherwise the file_offset_ might be wrong)
9359 +FileOffset LataDB::write_data(entier tstep, const Field_UName & uname, const DoubleTab &tab)
9361 + Journal() << " LataDB::write_data not coded for double" << endl;
9366 +// See write_data(..., const DoubleTab &)
9367 +FileOffset LataDB::write_data(entier tstep, const Field_UName & uname, const FloatTab &tab)
9369 + return write_data_(tstep, uname, tab);
9372 +// See write_data(..., const DoubleTab &)
9373 +FileOffset LataDB::write_data(entier tstep, const Field_UName & uname, const IntTab &tab)
9375 + if (get_field(tstep, uname).datatype_.array_index_ == LataDBDataType::F_INDEXING) {
9377 + tmp.set_smart_resize(1);
9378 + tmp.resize(tab.dimension(0), tab.dimension(1));
9379 + ArrOfInt & array = tmp;
9380 + const ArrOfInt & src = tab;
9381 + for (entier i = 0; i < array.size_array(); i++)
9382 + array[i] = src[i] + 1;
9383 + return write_data_(tstep, uname, tmp);
9386 + return write_data_(tstep, uname, tab);
9392 + if (write_master_file_to_call_) {
9393 + Journal() << "Internal Error !!! write_data() has been called without calling write_master_file() after." << endl;
9394 +// exit(); // In c++ it is forbidden to throw exceptions in a destructor.
9399 +const char *LataDBError::describe() const
9402 + case READ_ERROR: return "READ_ERROR"; break;
9403 + case BAD_HEADER: return "BAD_HEADER"; break;
9404 + case BAD_TIMESTEP: return "BAD_TIMESTEP"; break;
9405 + case NAME_NOT_FOUND: return "NAME_NOT_FOUND"; break;
9406 + case DATA_ERROR: return "DATA_ERROR"; break;
9407 + case FILE_NOT_FOUND: return "FILE_NOT_FOUND"; break;
9408 + case BAD_ELEM_TYPE: return "BAD_ELEM_TYPE"; break;
9409 + case INVALID_OPERATION: return "INVALID_OPERATION"; break;
9410 + case INTEGER_OVERFLOW: return "INTEGER_OVERFLOW"; break;
9413 + return "LataDB_unknown_error";
9416 +#undef verb_level_data_bloc
9417 diff --git a/databases/readers/Lata/LataDB.h b/databases/readers/Lata/LataDB.h
9418 new file mode 100644
9419 index 0000000..8862d3c
9421 +++ b/databases/readers/Lata/LataDB.h
9423 +/*****************************************************************************
9425 +* Copyright (c) 2011 - 2013, CEA
9426 +* All rights reserved.
9427 +* Redistribution and use in source and binary forms, with or without
9428 +* modification, are permitted provided that the following conditions are met:
9430 +* * Redistributions of source code must retain the above copyright
9431 +* notice, this list of conditions and the following disclaimer.
9432 +* * Redistributions in binary form must reproduce the above copyright
9433 +* notice, this list of conditions and the following disclaimer in the
9434 +* documentation and/or other materials provided with the distribution.
9435 +* * Neither the name of CEA, nor the
9436 +* names of its contributors may be used to endorse or promote products
9437 +* derived from this software without specific prior written permission.
9439 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
9440 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9441 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9442 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
9443 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9444 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9445 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9446 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9447 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9448 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9450 +*****************************************************************************/
9452 +#ifndef LataDB_include_
9453 +#define LataDB_include_
9454 +#include <Lata_tools.h>
9457 +// This file describes the LataDB class and all associated data structures.
9458 +// LataDB stores all the meta contained in the .lata master file, and not more.
9459 +// It provides services to add meta-data, read data to a user specified array,
9460 +// and write data to a lata file.
9462 +typedef BigEntier FileOffset;
9464 +// .Description: LataDBError is the type used for thrown exceptions in LataDBxxx classes
9468 + // READ_ERROR: low level io error while reading .lata file
9469 + // BAD_HEADER: the header in the .lata file is not correct
9470 + // BAD_TIMESTEP: request for a non existant timestep
9471 + // NAME_NOT_FOUND: request for a non existant domain or field name
9472 + // DATA_ERROR: low level io error while reading a data bloc file
9473 + // FILE_NOT_FOUND: a file (.lata or data) couldn't be opened on disc.
9474 + // INVALID_OPERATION: trying to read from a modified database, etc...
9475 + // INTEGER_OVERFLOW: trying to convert an integer to a too small data type
9476 + // (if error when reading a data file, you must recompile with typedef long long entier,
9477 + // if error when writing a data file, you must use INT64 type_ for data blocks)
9478 + enum ErrType { READ_ERROR, BAD_HEADER, BAD_TIMESTEP, NAME_NOT_FOUND, DATA_ERROR,
9479 + FILE_NOT_FOUND, BAD_ELEM_TYPE, INVALID_OPERATION, INTEGER_OVERFLOW };
9480 + LataDBError(ErrType err) : err_(err) {};
9482 + const char *describe() const;
9485 +// .Description: This is the data type for a specific part of a data bloc.
9486 +// In order to read a data bloc, we need a LataDBDataType for the "bloc size" id (this is an integer),
9487 +// and a LataDBDataType for the bloc content. LataDBGeometry blocs need two types, one for
9488 +// the node coordinates and one for the elements
9489 +class LataDBDataType
9492 + enum MSB { UNKNOWN_MSB, MSB_BIG_ENDIAN, MSB_LITTLE_ENDIAN, ASCII };
9494 + enum Type { UNKNOWN_TYPE, INT32, INT64, REAL32, REAL64 };
9496 + // Array index is ignored if type_ is REAL.
9497 + // NOT_AN_INDEX: array does not contain indexes.
9498 + // C_INDEXING: If array contains indexes to other items, 0 <= array[i] < nb_items
9499 + // F_INDEXING: 1 <= array[i] <= nb_items (Fortran index)
9500 + // See LataDB::read_data
9501 + enum ArrayIndex { UNKNOWN_ARRAYINDEX, NOT_AN_INDEX, C_INDEXING, F_INDEXING };
9502 + ArrayIndex array_index_;
9503 + // C_ORDERING: If multidimensionnal array is read, data ordering is like in C
9504 + // (all components for first node, then all components for second node, etc)
9505 + // F_ORDERING: like in fortran (first all values for component 0 then all values for compo 1 etc)
9506 + enum DataOrdering { UNKNOWN_ORDERING, C_ORDERING, F_ORDERING };
9507 + DataOrdering data_ordering_;
9509 + // _NO_BLOC: no fortran bloc marker
9510 + // _SINGLE_WRITE: all data written in one fortran write instruction
9511 + // _MULTIPLE_WRITES: one fortran write instruction for each component
9512 + enum FortranBlocMarkers { UNKNOWN_MARKERS, NO_BLOC_MARKER, BLOC_MARKERS_SINGLE_WRITE, BLOC_MARKERS_MULTIPLE_WRITES };
9513 + FortranBlocMarkers fortran_bloc_markers_;
9515 + // The data type for fortran bloc markers
9516 + Type bloc_marker_type_;
9518 + // Data is located at this offset in the file
9519 + FileOffset file_offset_;
9521 + LataDBDataType() : msb_(UNKNOWN_MSB), type_(UNKNOWN_TYPE), array_index_(UNKNOWN_ARRAYINDEX),
9522 + data_ordering_(UNKNOWN_ORDERING), fortran_bloc_markers_(UNKNOWN_MARKERS), bloc_marker_type_(UNKNOWN_TYPE),
9525 + static MSB machine_msb_;
9528 +// .Description: Description of a geometry (= a mesh)
9529 +class LataDBGeometry
9532 + LataDBGeometry() { timestep_ = -1; }
9535 + // Type of elements
9536 + Motcle elem_type_;
9540 +// This is a unique identifier for fields
9541 +// at this time, contains domain name, field name and localisation,
9542 +// might be further extended if needed
9547 + Field_UName(const char *domain_name, const char *field_name, const char *loc);
9548 + Field_UName(const Field_UName &);
9549 + int operator==(const Field_UName &) const;
9550 + Field_UName & operator=(const Field_UName &);
9551 + Nom build_string() const;
9552 + const Motcle & get_localisation() const { return loc_; }
9553 + const Motcle & get_field_name() const { return field_name_; }
9554 + const Motcle & get_geometry() const { return geometry_; }
9555 + void set_field_name(const Nom &);
9558 + Motcle field_name_;
9562 +std::ostream & operator<<(std::ostream &, const Field_UName &);
9564 +typedef LataVector<Field_UName> Field_UNames;
9567 +// .Description: Description of a field
9571 + LataDBField() { timestep_ = -1; nb_comp_ = -1; nature_ = UNKNOWN; size_ = -1; }
9573 + // Unique identifier
9574 + Field_UName uname_;
9575 + // Field name (without localisation spec)
9579 + // Filename containing the data
9580 + // Special names: memory_buffer_file() => data stored in the LataDB memory buffer.
9582 + // Number of components
9586 + // Name of the components
9587 + Noms component_names_;
9589 + // Scalar or vector ?
9590 + enum Nature { UNKNOWN, SCALAR, VECTOR };
9592 + // Type and formatting info of the data
9593 + LataDBDataType datatype_;
9594 + // Localisation (elem, som, faces, ...)
9595 + Motcle localisation_;
9598 + // Size (number of lines)
9601 + static const char * memory_buffer_file();
9604 +// .Description: Description of one timestep (contains a vector of items)
9605 +class LataDBTimestep
9608 + LataDBTimestep() { time_ = -1.; }
9611 + friend class LataDB;
9612 + LataVector<LataDBGeometry> geoms_;
9613 + LataVector<LataDBField> fields_;
9616 +class LataDataFile;
9621 + LataDB() : internal_data_buffer_(std::ios::in | std::ios::out | std::ios::app | std::ios::binary) { old_style_lata_ = 0; path_prefix_ = ""; write_master_file_to_call_ = 0; }
9622 + LataDB(const LataDB & src) :
9623 + header_(src.header_),
9625 + software_id_(src.software_id_),
9626 + default_type_int_(src.default_type_int_),
9627 + default_float_type_(src.default_float_type_),
9628 + timesteps_(src.timesteps_),
9629 + path_prefix_(src.path_prefix_),
9630 + old_style_lata_(src.old_style_lata_),
9631 + write_master_file_to_call_(src.write_master_file_to_call_) {
9632 + // Note B.M. il faudrait copier internal_data_buffer_ pour faire marcher lml->lata mais je ne sais pas faire...
9634 + virtual ~LataDB();
9636 + virtual void read_master_file(const char * path_prefix_, const char * filename);
9637 + void read_master_file_med(const char *prefix, const char *filename);
9638 + static Nom read_master_file_options(const char * filename);
9640 + virtual void filter_db(const LataDB & source,
9641 + const Motcles & geometry_names,
9642 + const Motcles & field_names,
9643 + const ArrOfInt & timesteps);
9645 + entier nb_timesteps() const;
9646 + double get_time(entier tstep) const;
9647 + enum TStepSelector { CURRENT, FIRST_AND_CURRENT };
9648 + Noms geometry_names(entier tstep, TStepSelector which_tstep = CURRENT) const;
9649 + Field_UNames field_unames(entier tstep, const char * geometry, const char * name, TStepSelector which_tstep = CURRENT) const;
9650 + const LataDBGeometry & get_geometry(entier tstep, const char * name, TStepSelector which_tstep = CURRENT) const;
9651 + entier field_exists(entier tstep, const char *geom, const char *name, TStepSelector which_tstep = CURRENT) const;
9652 + const LataDBField & get_field(entier tstep, const Field_UName & uname, TStepSelector which_tstep = CURRENT) const;
9653 + const LataDBField & get_field(entier tstep, const char *geom, const char *name, const char *loc, TStepSelector which_tstep = CURRENT) const;
9654 + const Nom & path_prefix() const { return path_prefix_; };
9655 + void set_path_prefix(const char * s);
9657 + // First line in the .lata file
9659 + // Second line in the .lata file
9661 + // Third line in the .lata file
9664 + LataDBDataType default_type_float() const; // Everything same as int, but type_=default_float_type_
9665 + LataDBDataType default_type_int_;
9666 + LataDBDataType::Type default_float_type_;
9668 + virtual void read_data(const LataDBField &, DoubleTab & data, long long debut = 0, entier n = -1) const;
9669 + virtual void read_data(const LataDBField &, FloatTab & data, long long debut = 0, entier n = -1) const;
9670 + virtual void read_data(const LataDBField &, IntTab & data, long long debut = 0, entier n = -1) const;
9671 + virtual void read_data(const LataDBField &, DoubleTab & data, const ArrOfInt & lines_to_read) const;
9672 + virtual void read_data(const LataDBField &, FloatTab & data, const ArrOfInt & lines_to_read) const;
9673 + virtual void read_data(const LataDBField &, IntTab & data, const ArrOfInt & lines_to_read) const;
9675 + enum Element { line, triangle, quadri, tetra, hexa, triangle_3D, quadri_3D, polyedre,polygone, unspecified };
9676 + static Element element_type_from_string(const Motcle & type_elem);
9678 + // Tools to create/update the database and write lata data to disk
9679 + void change_all_data_types(const LataDBDataType & old_type, const LataDBDataType & new_type);
9680 + void change_all_data_filenames(const Nom & old_prefix, const Nom & new_prefix);
9681 + void check_all_data_fileoffsets(entier split_files);
9682 + entier add_timestep(double time);
9683 + void add_geometry(const LataDBGeometry & geom);
9684 + void set_elemtype(entier tstep, const char *geom_name, const char *elem_type);
9685 + entier check_duplicate_filename(const char *filename) const;
9686 + void add_field(const LataDBField & field);
9687 + void write_master_file(const char *filename) const;
9688 + FileOffset write_data(entier tstep, const Field_UName &, const DoubleTab &);
9689 + FileOffset write_data(entier tstep, const Field_UName &, const FloatTab &);
9690 + FileOffset write_data(entier tstep, const Field_UName &, const IntTab &);
9693 + LataDBField & getset_field(entier tstep, const Field_UName & uname, TStepSelector which_tstep = CURRENT);
9694 + void read_master_file_header(const char *filename, EFichier & is);
9695 + static entier lata_v1_dim_from_elem_type(const Motcle & elem_type);
9696 + static entier lata_v1_get_nb_comp(const Nom & fieldname, const Motcle & localisation, const LataDBGeometry & dom, entier dim, LataDBField::Nature & nature, LataDBDataType::DataOrdering &);
9697 + static void get_element_data(const Motcle & elemtype, entier & dimension, entier & elem_shape, entier & face_shape, entier & nb_elem_faces);
9699 + const LataDBTimestep & get_tstep(entier i) const;
9700 + void add(entier tstep, const LataDBGeometry & item);
9701 + void add(entier tstep, const LataDBField & item);
9702 + template <class C_Tab> void read_data_(const LataDBField &, C_Tab & data, long long debut, entier n) const;
9703 + template <class C_Tab> void read_data_(const LataDBField &, C_Tab & data, const ArrOfInt & lines_to_read) const;
9704 + template <class C_Tab> void read_data2_(LataDataFile & f, const LataDBField & fld, C_Tab * const data, long long debut = 0, entier n = -1, const ArrOfInt *lines_to_read = 0) const;
9705 + template <class C_Tab> void read_data2_med_( const LataDBField & fld, C_Tab * const data, entier debut = 0, entier n = -1, const ArrOfInt *lines_to_read = 0) const;
9706 + template <class C_Tab> FileOffset write_data_(entier tstep, const Field_UName & uname, const C_Tab &);
9708 + // Timestep 0 contains global domains and field definition
9709 + // Timestep 1..size()-1 contain the data for each "TEMPS" entry
9710 + LataVector<LataDBTimestep> timesteps_;
9712 + // Path prefix for all data blocks (used by read_data() and write_data())
9715 + // Is this an old-style lata file ? (with INTERFACES special files and 2D elements expanded to 3D elements)
9716 + entier old_style_lata_;
9718 + // This flag tells if some write_data calls have been made since the last write_master_file
9719 + // If yes, issue a message to say that's wrong !
9720 + mutable entier write_master_file_to_call_;
9722 + // This is a memory buffer where data can be written to create a temporary data base
9723 + mutable std::stringstream internal_data_buffer_;
9726 diff --git a/databases/readers/Lata/LataDBmed.h b/databases/readers/Lata/LataDBmed.h
9727 new file mode 100644
9728 index 0000000..13cfdbe
9730 +++ b/databases/readers/Lata/LataDBmed.h
9732 +/*****************************************************************************
9734 +* Copyright (c) 2011 - 2013, CEA
9735 +* All rights reserved.
9736 +* Redistribution and use in source and binary forms, with or without
9737 +* modification, are permitted provided that the following conditions are met:
9739 +* * Redistributions of source code must retain the above copyright
9740 +* notice, this list of conditions and the following disclaimer.
9741 +* * Redistributions in binary form must reproduce the above copyright
9742 +* notice, this list of conditions and the following disclaimer in the
9743 +* documentation and/or other materials provided with the distribution.
9744 +* * Neither the name of CEA, nor the
9745 +* names of its contributors may be used to endorse or promote products
9746 +* derived from this software without specific prior written permission.
9748 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
9749 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9750 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9751 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
9752 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9753 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9754 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9755 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9756 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9757 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9759 +*****************************************************************************/
9761 +//#define WITH_MEDLOADER
9762 +#ifndef WITH_MEDLOADER
9763 +void LataDB::read_master_file_med(const char *prefix, const char *filename)
9765 + Journal() << "MED PLUGIN not compiled!" << endl;
9768 +template <class C_Tab> void LataDB::read_data2_med_(
9769 + const LataDBField & fld,
9770 + C_Tab * const data, // const pointer to non const data !
9771 + entier debut, entier n, const ArrOfInt *lines_to_read) const
9773 + Journal() << "MED PLUGIN not compiled!" << endl;
9779 +#include <MEDLoader.hxx>
9780 +#include <MEDCouplingMemArray.hxx>
9781 +#include <MEDCouplingUMesh.hxx>
9782 +#include <MEDCouplingFieldDouble.hxx>
9783 +#include <CellModel.hxx>
9784 +#include <MEDFileField.hxx>
9791 +Nom latadb_name_from_type_geo(const med_geometry_type& type_geo)
9797 + type_elem="Rectangle";
9800 + type_elem="Hexaedre";
9803 + type_elem="Triangle";break;
9805 + type_elem="Tetraedre";break;
9807 + type_elem="Prisme";break;
9808 + case MED_POLYHEDRON:
9809 + type_elem="Polyedre"; break;
9811 + type_elem="Polygone"; break;
9813 + type_elem="Segment"; break;
9815 + Cerr<<"type_geo " << (int)type_geo <<" is not a supported element."<<finl;
9823 +// passage de la connectivite trio a MED si sens=1
9824 +// de MED a trio si sens=-1
9825 +ArrOfInt renum_conn(const LataDB::Element& type)
9827 + // cerr<<"type elem "<<type_elem<<endl;
9829 + if (type==LataDB::quadri ) {
9830 + filter.resize_array(4) ;
9840 + if (type== LataDB::hexa ) {
9841 + filter.resize_array(8) ;
9860 +extern med_geometry_type typmai3[MED_N_CELL_FIXED_GEO];
9862 +void latadb_get_info_mesh_med(const char* filename,const char* meshname,med_geometry_type& type_geo,int& ncells,int& nnodes,int& spacedim, int &nbcomp,int& is_structured, std::vector<int>& NIJK)
9867 + std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > res = MEDCoupling::GetUMeshGlobalInfo(filename, meshname, meshDim, spacedim, nnodes);
9870 + // on prend que la dimension la plus grande et on verifie que l'on a qu'un type elt
9873 + cerr<<"error multi dimension in "<<meshname<<endl;
9876 + if (res[0].size()>1)
9878 + cerr<<"error multi elements in "<<meshname<<endl;
9881 + type_geo=typmai3[res[0][0].first];
9883 + if ((type_geo==MED_POLYGON)||(type_geo==MED_POLYHEDRON))
9885 + //on est force de lire le maillage pour avoir le bon nombre de cellules
9886 + MEDCoupling::MEDCouplingUMesh * mesh= MEDCoupling::ReadUMeshFromFile(filename,meshname);
9887 + ncells = mesh->getNumberOfCells();
9888 + const int *idx = mesh->getNodalConnectivityIndex()->getConstPointer();
9889 + for (i = 0, nbcomp = 0; i < ncells; i++) if (nbcomp < idx[i + 1] - idx[i] - 1) nbcomp = idx[i + 1] - idx[i] - 1;
9893 + ncells=res[0][0].second;
9897 + // No UMesh try CMesh
9898 + MEDCoupling::MEDCouplingMesh* mesh= MEDCoupling::ReadMeshFromFile(filename, meshname);
9900 + type_geo,int& ncells,int& nnodes,int& spacedim, int &nbcomp
9902 + MEDCoupling::MEDCouplingCMesh* cmesh = dynamic_cast<MEDCoupling::MEDCouplingCMesh*>(mesh);
9903 + spacedim=cmesh-> getSpaceDimension() ;
9905 + NIJK= cmesh->getNodeGridStructure();
9906 + ncells=mesh->getNumberOfCells();
9907 + nnodes=mesh->getNumberOfNodes();
9910 + // std::cout << ncells<< " "<<sizes[2]<<std::endl;
9914 + type_geo =MED_HEXA8;
9915 + else if (spacedim==2)
9916 + type_geo =MED_QUAD4;
9927 +// Description: Reads the .lata database in the given file indicating than the
9928 +// associated data files will be found in directory "prefix".
9929 +// If not empty, "prefix" must finish with a '/'.
9930 +// For "prefix" and "filename", if they do not begin with '/', are relative to pwd.
9932 +// BAD_HEADER means that the header found in this stream is not LATA_V2
9933 +// READ_ERROR means that an error has been found in the file (premature eof,
9934 +// io error, bad keyword, ...)
9935 +// FILE_NOT_FOUND means that, well, the lata file could not be opened
9936 +void LataDB::read_master_file_med(const char *prefix, const char *filename)
9940 + Journal() << "MED PLUGIN !" << endl;
9942 + // Defaults for lataV1
9943 + default_type_int_.msb_ = LataDBDataType::ASCII;
9944 + default_type_int_.type_ = LataDBDataType::INT32;
9945 + default_type_int_.array_index_ = LataDBDataType::F_INDEXING;
9946 + default_type_int_.data_ordering_ = LataDBDataType::C_ORDERING;
9947 + default_type_int_.fortran_bloc_markers_ = LataDBDataType::BLOC_MARKERS_SINGLE_WRITE;
9948 + default_type_int_.bloc_marker_type_ = LataDBDataType::INT32;
9949 + default_float_type_ = LataDBDataType::REAL32;
9953 + // Create timestep 0 (global domain and fields)
9954 + timesteps_.add(LataDBTimestep());
9957 + // on ajoute les geom
9958 + // on verra apres pour les champs elem et som
9959 + vector<string> geoms= MEDCoupling::GetMeshNames(filename);
9961 + vector<double> times;
9962 + LataDBTimestep table;
9965 + for (int i=0;i<geoms.size();i++)
9967 + LataDBGeometry dom;
9968 + dom.timestep_ = timesteps_.size()-1;
9969 + dom.name_=geoms[i];
9970 + med_geometry_type type_geo;
9971 + int ncells,nnodes,spacedim, nbcomp;
9972 + int is_structured;
9973 + std::vector<int> NIJK;
9974 + latadb_get_info_mesh_med(filename,geoms[i].c_str(),type_geo,ncells,nnodes,spacedim,nbcomp,is_structured,NIJK);
9976 + dom.elem_type_=latadb_name_from_type_geo(type_geo);
9978 + if (is_structured==0)
9981 + som.name_ = "SOMMETS";
9982 + som.geometry_ = dom.name_;
9983 + som.filename_ = filename;
9985 + som.datatype_ = default_type_float(); // ??
9986 + som.nb_comp_=spacedim;
9989 + elem.name_ = "ELEMENTS";
9990 + elem.geometry_ = dom.name_;
9991 + elem.filename_ = filename;
9992 + elem.size_=ncells;
9993 + elem.datatype_ = default_type_float(); // ??
9996 + get_element_data(dom.elem_type_, dim, elem.nb_comp_, ff, ef);
9997 + if (elem.nb_comp_ == -1) elem.nb_comp_ = nbcomp;
9999 + add(timesteps_.size() - 1, dom);
10000 + add(timesteps_.size() - 1, som);
10001 + add(timesteps_.size() - 1, elem);
10005 + add(timesteps_.size() - 1, dom);
10008 + som.name_ = "SOMMETS_IJK_I";
10009 + som.geometry_ = dom.name_;
10010 + som.filename_ = filename;
10011 + som.size_=NIJK[0];
10012 + som.datatype_ = default_type_float(); // ??
10014 + add(timesteps_.size() - 1, som);
10018 + som.name_ = "SOMMETS_IJK_J";
10019 + som.geometry_ = dom.name_;
10020 + som.filename_ = filename;
10021 + som.size_=NIJK[1];
10022 + som.datatype_ = default_type_float(); // ??
10024 + add(timesteps_.size() - 1, som);
10028 + som.name_ = "SOMMETS_IJK_K";
10029 + som.geometry_ = dom.name_;
10030 + som.filename_ = filename;
10031 + som.size_=NIJK[2];
10032 + som.datatype_ = default_type_float(); // ??
10034 + add(timesteps_.size() - 1, som);
10040 + vector<string> fields;
10041 + fields= MEDCoupling::GetAllFieldNamesOnMesh(filename,dom.name_.getString());
10044 + for (int i=0;i<fields.size();i++)
10047 + som.name_ = fields[i];
10049 + som.filename_ = filename;
10051 + som.datatype_ = default_type_float(); // ??
10053 + som.nature_ = LataDBField::SCALAR;
10056 + const Nom& meshname = dom.name_;
10057 + som.geometry_ = meshname;
10058 + Motcle newname(fields[i].c_str());
10059 + Motcle ajout("_");
10061 + // cerr<<"field " <<fields[i]<< " "<< meshname<<" ";
10062 + vector< MEDCoupling::TypeOfField > ltypes=MEDCoupling::GetTypesOfField(filename,meshname.getString(),fields[i].c_str());
10063 + //if (ltypes.size()!=1) throw;
10064 + for (int t=0;t<ltypes.size();t++)
10066 + switch (ltypes[t])
10069 + case MEDCoupling::ON_CELLS :
10070 + //cerr<<"elem"<<endl;
10071 + som.size_=ncells;
10072 + som.localisation_="ELEM";
10074 + case MEDCoupling::ON_NODES :
10075 + //cerr<<"som"<<endl;
10076 + som.size_=nnodes;
10077 + som.localisation_="SOM";
10080 + cerr<<"type inconnu "<<endl;throw;
10084 + // pour recupere nb_comp !!!
10086 + som.nb_comp_=MEDCoupling::GetComponentsNamesOfField(filename,fields[i].c_str()).size();
10089 + if (spacedim==som.nb_comp_)
10090 + som.nature_ = LataDBField::VECTOR;
10091 + ajout+=som.localisation_;
10094 + newname=newname.prefix(ajout);
10096 + som.name_=newname;
10098 + //som.uname_= Field_UName(meshname, newname, som.localisation_);
10100 + table.fields_.add(som);
10104 + if (ltypes.size()>1)
10106 + vector<pair< int, int > > iters= MEDCoupling::GetFieldIterations(ltypes[t],filename,meshname.getString(),fields[i].c_str());
10107 + for (int iter=0;iter<iters.size();iter++)
10109 + double t= MEDCoupling::GetTimeAttachedOnFieldIteration(filename,fields[i].c_str(),iters[iter].first,iters[iter].second);
10112 + times.push_back(t);
10113 + //cerr<<"M ici "<<t <<" "<<iters[iter].first<<" "<<iters[iter].second<<endl;
10117 + if (times[iter]!=t)
10119 + cerr<<"field " <<fields[i]<<" M time "<< t << " diff "<<times[iter] << endl;
10128 + vector<pair<pair<int,int>,double> > vtimes=MEDCoupling::GetAllFieldIterations(filename,/*meshname,*/fields[i].c_str());
10129 + for (int it=0;it<vtimes.size();it++)
10132 + double t=vtimes[it].second;
10135 + times.push_back(t);
10136 + // cerr<<" ici "<<t <<endl;
10140 + if (times[it]!=t)
10142 + cerr<<"field " <<fields[i]<<" time "<< t << " diff "<<times[it] << endl;
10154 + if (times.size()>0)
10155 + for (int i=0;i<times.size();i++)
10158 + //LataDBTimestep & t = timesteps_.add(table);
10159 + LataDBTimestep& t = timesteps_.add(LataDBTimestep());
10160 + t.time_=times[i];
10161 + for (int f=0;f<table.fields_.size();f++)
10162 + add(i+1,table.fields_[f]);
10165 + for (int i=0;i<times.size()*0;i++)
10166 + cerr<<" time "<<times[i]<<endl;
10170 +template <class C_Tab>
10171 +void LataDB::read_data2_med_(
10172 + const LataDBField & fld,
10173 + C_Tab * const data, // const pointer to non const data !
10174 + entier debut, entier n, const ArrOfInt *lines_to_read) const
10176 + assert(debut==0);
10178 + assert(lines_to_read==NULL);
10180 + if (fld.name_=="SOMMETS")
10182 + // cerr<<"load sommets "<<endl;
10183 + MEDCoupling::MEDCouplingUMesh * mesh= MEDCoupling::ReadUMeshFromFile(fld.filename_.getString(),fld.geometry_.getString());
10184 + const MEDCoupling::DataArrayDouble* coords=mesh->getCoords();
10185 + data->resize(fld.size_,fld.nb_comp_);
10186 + for (int i=0;i<fld.size_;i++)
10187 + for (int j=0;j<fld.nb_comp_;j++)
10189 + (*data)(i,j)=coords->getIJ(i,j);
10194 + else if (fld.name_=="ELEMENTS")
10196 + // cerr<<"load elements "<<endl;
10197 + Nom type_elem=get_geometry(fld.timestep_,fld.geometry_).elem_type_;
10198 + LataDB::Element type =LataDB::element_type_from_string(type_elem);
10199 + ArrOfInt filter=renum_conn(type);
10200 + MEDCoupling::MEDCouplingUMesh * mesh= MEDCoupling::ReadUMeshFromFile(fld.filename_.getString(),fld.geometry_.getString());
10201 + const MEDCoupling::DataArrayInt *elems = mesh->getNodalConnectivity(), *idx = mesh->getNodalConnectivityIndex();
10202 + const int *ptr_elems=elems->getConstPointer(), *ptr_idx = idx->getConstPointer();
10203 + data->resize(fld.size_,fld.nb_comp_);
10205 + for (int i=0;i<fld.size_;i++)
10208 + for (int j=0;j<fld.nb_comp_;j++)
10210 + int reel = j + ptr_idx[i] + 1 < ptr_idx[i + 1];
10211 + (*data)(i,filter.size_array()>0 ? filter[j] : j) = reel ? ptr_elems[compt] + 1 : 0;
10217 + else if (fld.name_.debute_par("SOMMETS_IJK_"))
10219 + MEDCoupling::MEDCouplingMesh * mesh= MEDCoupling::ReadMeshFromFile(fld.filename_.getString(),fld.geometry_.getString());
10220 + data->resize(fld.size_,fld.nb_comp_);
10221 + MEDCoupling::MEDCouplingCMesh* cmesh = dynamic_cast<MEDCoupling::MEDCouplingCMesh*>(mesh);
10223 + if (fld.name_=="SOMMETS_IJK_I")
10225 + else if (fld.name_=="SOMMETS_IJK_J")
10227 + else if (fld.name_=="SOMMETS_IJK_K")
10231 + const MEDCoupling::DataArrayDouble* coords=cmesh->getCoordsAt(dir);
10232 + for (int i=0;i<fld.size_;i++)
10233 + for (int j=0;j<fld.nb_comp_;j++)
10235 + (*data)(i,j)=coords->getIJ(i,j);
10243 + data->resize(fld.size_,fld.nb_comp_);
10245 + // if (fld.timestep_==1) iter.first=1;
10247 + Nom fieldname=fld.name_;
10249 + fieldname+=fld.localisation_;
10251 + fieldname+=fld.geometry_;
10255 + vector<string> fields= MEDCoupling::GetAllFieldNamesOnMesh(fld.filename_.getString(),fld.geometry_.getString());
10257 + for (int f=0;f<fields.size();f++)
10259 + if (fieldname==fields[f].c_str())
10267 + fieldname=fld.name_;
10269 + vector<pair<pair<int,int>,double> > vtimes=MEDCoupling::GetAllFieldIterations(fld.filename_.getString(),fieldname.getString());
10271 + int it=fld.timestep_-1;
10272 + pair <int,int> iter(fld.timestep_-1,-1);
10273 + if (fld.timestep_==1) it=0;
10274 + //Cerr<<iter.first <<" 00 "<<vtimes.size()<<finl;
10276 + iter.first=vtimes[it].first.first;
10277 + iter.second=vtimes[it].first.second;
10278 + // Cerr<<"iiii"<<iter.first<<" "<< it<<finl;
10279 + double t=MEDCoupling::GetTimeAttachedOnFieldIteration(fld.filename_.getString(),fieldname.getString(),iter.first,iter.second);
10282 + MEDCoupling::TypeOfField type;
10283 + if (fld.localisation_=="ELEM")
10284 + type=MEDCoupling::ON_CELLS;
10287 + type=MEDCoupling::ON_NODES;
10288 + assert(fld.localisation_=="SOM");
10290 + MEDCoupling::MEDFileField1TS * field ;
10293 + field = MEDCoupling::MEDFileField1TS::New(fld.filename_.getString(),fieldname.getString(),iter.first,iter.second);
10295 + const MEDCoupling::DataArrayDouble * values=field->getUndergroundDataArray();
10297 + if (field->getNumberOfComponents()!=fld.nb_comp_)
10299 + cerr<<field->getNumberOfComponents()<<" test "<< endl;
10300 + Journal()<<fieldname<<" not loaded "<<endl;
10304 + assert(field->getNumberOfComponents()==fld.nb_comp_);
10305 + const double* ptr=values->getConstPointer();
10306 + for (int i=0;i<fld.size_;i++)
10308 + for (int j=0;j<fld.nb_comp_;j++)
10310 + (*data)(i,j)=ptr[i*fld.nb_comp_+j];
10314 + field->decrRef();
10318 diff --git a/databases/readers/Lata/LataFilter.C b/databases/readers/Lata/LataFilter.C
10319 new file mode 100644
10320 index 0000000..5c4a764
10322 +++ b/databases/readers/Lata/LataFilter.C
10324 +/*****************************************************************************
10326 +* Copyright (c) 2011 - 2013, CEA
10327 +* All rights reserved.
10328 +* Redistribution and use in source and binary forms, with or without
10329 +* modification, are permitted provided that the following conditions are met:
10331 +* * Redistributions of source code must retain the above copyright
10332 +* notice, this list of conditions and the following disclaimer.
10333 +* * Redistributions in binary form must reproduce the above copyright
10334 +* notice, this list of conditions and the following disclaimer in the
10335 +* documentation and/or other materials provided with the distribution.
10336 +* * Neither the name of CEA, nor the
10337 +* names of its contributors may be used to endorse or promote products
10338 +* derived from this software without specific prior written permission.
10340 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
10341 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10342 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10343 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
10344 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10345 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10346 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10347 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10348 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10349 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10351 +*****************************************************************************/
10353 +#include <iostream>
10354 +#include <fstream>
10355 +#include <stdlib.h>
10356 +#include <stdio.h>
10357 +#include <stdarg.h>
10359 +#include <assert.h>
10360 +#include <LataFilter.h>
10362 +#include <Static_Int_Lists.h>
10363 +#include <Connectivite_som_elem.h>
10364 +#include <LataDB.h>
10365 +#include <Lata_tools.h>
10366 +#include <Operator.h>
10367 +#include <errno.h>
10368 +#include <UserFields.h>
10369 +#include <string.h>
10370 +static const entier cache_info_level = 5;
10371 +static const entier filter_info_level = 4;
10373 +entier LataOptions::read_int_opt(const Nom & s)
10375 + const char *ptr = strstr(s, "=");
10379 + char *errorptr = 0;
10380 + entier x = strtol(ptr+1, &errorptr, 0 /* base 10 par defaut */);
10381 + if (errno || *errorptr != 0) {
10382 + Journal() << "LataOptions error reading int parameter: " << s << endl;
10388 +double LataOptions::read_float_opt(const Nom & s)
10390 + const char *ptr = strstr(s, "=");
10394 + char *errorptr = 0;
10395 + double x = strtod(ptr+1, &errorptr);
10396 + if (errno || *errorptr != 0) {
10397 + Journal() << "LataOptions error reading float parameter: " << s << endl;
10403 +Nom LataOptions::read_string_opt(const Nom & s)
10405 + const char *ptr = strstr(s, "=");
10409 + return Nom(ptr+1);
10412 +Noms extract_list(const Nom & n)
10417 + const char *ptr = n;
10420 + if (*ptr == ',') {
10424 + tmp += Nom(*ptr);
10431 +void LataOptions::describe()
10433 + cerr << "Data processing options (provided by the LataFilter module)" << endl;
10434 + cerr << " reconnect=tolerance : Find duplicate positions, and redefine connections to use" << endl;
10435 + cerr << " always the same positions. tolerance is the maximum distance between" << endl;
10436 + cerr << " positions that are considered equal." << endl;
10437 + cerr << " Useful for results of parallel runs, where the domain could" << endl;
10438 + cerr << " appear fragmented in as many subdomains as procs used." << endl;
10439 + cerr << " This operator modifies the loaded domain, does not create a new domain." << endl;
10440 + cerr << " regularize=tolerance : Try to transform the irregular domain in a ijk domain." << endl;
10441 + cerr << " tolerance is the maximum dx, dy or dz between positions that are" << endl;
10442 + cerr << " considered to have the same x, y or z." << endl;
10443 + cerr << " !Attention! regularize recalculates positions, connections, and fields" << endl;
10444 + cerr << " Except in particularly simple cases, you cannot use a regularized domain" << endl;
10445 + cerr << " for a field that has not been regularized the same way." << endl;
10446 + cerr << " Create a new domain DOM -> DOM_IJK" << endl;
10447 + cerr << " regularize_polyedre=N : tells how to convert polyedre elements to VTK:" << endl;
10448 + cerr << " N=0 (default): any shape, handled as general VTK_CONVEX_POINT_SET" << endl;
10449 + cerr << " N=1: all elements are extruded in the Z direction (faster and nicer)" << endl;
10450 + cerr << " ijk_mesh_nb_parts=N : When loading an IJK mesh, automatically split the mesh into" << endl;
10451 + cerr << " N blocks (N must be <= number of elements in the K direction, usefull in visit)" << endl;
10452 + cerr << " invalidate : together with regularize, create \"invalid positions\" and \"invalid connections\"" << endl;
10453 + cerr << " components. Otherwise only set the values of the field to zeroes." << endl;
10454 + cerr << " extend_domain=n : When regularizing, add n nodes in each directions to have a layer" << endl;
10455 + cerr << " of invalid positions and connections." << endl;
10456 + cerr << " dualmesh: Build and export the dual mesh" << endl;
10457 + cerr << " (control volume for the velocities in VEF)" << endl;
10458 + cerr << " data at faces become data at elements on the dual mesh." << endl;
10459 + cerr << " Create a new domain DOM -> DOM_dual" << endl;
10460 + cerr << " facesmesh: Build and export the faces mesh" << endl;
10461 + cerr << " (control volume for the velocities in VEF)" << endl;
10462 + cerr << " data at faces become data at elements on the faces mesh." << endl;
10463 + cerr << " Create a new domain DOM -> DOM_faces" << endl;
10465 + //cerr << " ncmesh: Build and export a non-conforming mesh" << endl;
10466 + //cerr << " (each mesh element has its proprietary nodes, elements are not topologically connected)" << endl;
10467 + //cerr << " face dependent data become position dependent data on the new mesh." << endl;
10468 + //cerr << " Create a new domain DOM -> DOM_nc" << endl;
10469 + cerr << " boundarymesh: Build new domains containing the boundaries only" << endl;
10470 + cerr << " Create a new domain DOM -> DOM_Boundary" << endl;
10471 + //cerr << " clipbox=xmin,ymin,zmin,xmax,ymax,zmax : remove from all meshes all nodes," << endl;
10472 + //cerr << " connections and faces outside of this box" << endl;
10473 + cerr << " load_virtual_elements: Read the VIRTUAL_ELEMENTS data in the input database, if available" << endl
10474 + << " and merge nodes, elements and faces to each requested subdomain (using reconnect)" << endl;
10475 + cerr << " Does not create a new domain, but modifies the loaded domain" << endl;
10476 + cerr << " ijk_virt_layer=N: load N layers of virtual elements if domain is ijk in lata file" << endl;
10477 + cerr << " reconnect_tolerance=: specify tolerance for all reconnect operations" << endl;
10478 + cerr << " (reconnection is applied with load_virtual_elements)" << endl;
10479 + cerr << " user_fields: activate the User_Fields module (WARN: this module is often application specific," << endl;
10480 + cerr << " it will fail if some requiered domains/fields are missing in the input database)" << endl;
10481 + cerr << " export_fields_at_faces: tells to export fields located at faces" << endl;
10483 + user_fields_options_.print_help_option();
10486 +entier LataOptions::parse_option(const Nom & s)
10488 + if (s.debute_par("verbosity=")) {
10489 + entier level = read_int_opt(s);
10490 + set_Journal_level(level);
10491 + } else if (s.debute_par("regularize=")) {
10492 + regularize = true;
10493 + regularize_tolerance = read_float_opt(s);
10494 + } else if (s.debute_par("regularize_polyedre=")) {
10495 + regularize_polyedre = read_int_opt(s);
10496 + } else if (s.debute_par("extend_domain=")) {
10497 + extend_domain = read_int_opt(s);
10498 + } else if (s == "invalidate") {
10499 + invalidate = true;
10500 + } else if (s.debute_par("reconnect=")) {
10501 + reconnect = true;
10502 + reconnect_tolerance = read_float_opt(s);
10503 + } else if (s.debute_par("reconnect_tolerance=")) {
10504 + reconnect_tolerance = read_float_opt(s);
10505 + } else if (s == "dualmesh") {
10506 + dual_mesh = true;
10507 + } else if (s == "nodualmesh") {
10508 + dual_mesh = false;
10509 + } else if (s == "ncmesh") {
10511 + } else if (s == "facesmesh") {
10512 + faces_mesh = true;
10513 + } else if (s == "nofacesmesh") {
10514 + faces_mesh = false;
10515 + } else if (s == "boundarymesh") {
10516 + boundary_mesh = true;
10517 + } else if (s.debute_par("clipbox=")) {
10518 + Noms list = extract_list(((const char*)s)+8);
10519 + if (list.size() != 6) {
10520 + Journal() << "Error : clipbox parameters expects 6 values" << endl;
10523 + for (entier i = 0; i < 3; i++) {
10524 + clipbox_min[i] = read_float_opt(list[i]);
10525 + clipbox_max[i] = read_float_opt(list[i+3]);
10527 + } else if (s == "load_virtual_elements") {
10528 + load_virtual_elements = true;
10529 + } else if (s == "user_fields") {
10530 + user_fields_ = true;
10531 + Journal() << "Option: User_fields ON" << endl;
10532 + } else if (s.debute_par("ijk_mesh_nb_parts")) {
10533 + ijk_mesh_nb_parts_ = read_int_opt(s);
10534 + } else if (s == "export_fields_at_faces") {
10535 + export_fields_at_faces_ = 1;
10536 + } else if (s.debute_par("ijk_virt_layer=")) {
10537 + ijk_virt_layer = read_int_opt(s);
10539 + return user_fields_options_.parse_option(s);;
10543 +void LataFilterCache::set_cache_properties(entier clear_on_tstep_change, BigEntier mem_limit)
10545 + clear_cache_on_tstep_change_ = clear_on_tstep_change;
10546 + cache_memory_limit_ = mem_limit;
10549 +// Description: if an entry with "id" tag and timestep exists in the cache,
10550 +// returns the entry, otherwise returns a reference to an empty DERIV that
10551 +// is stored in the cache and stores the associated "id" and timestep.
10552 +// The entry is locked and given a new last_access_time_ to show that it has
10553 +// been used recently.
10554 +// The entry must be released by release_item() when we are finished working
10556 +LataDeriv<LataObject> & LataFilterCache::get_item_(const Nom & id, entier tstep)
10559 + const entier n = data_.size();
10560 + for (i = 0; i < n; i++) {
10561 + const DataCacheItem & item = data_[i];
10562 + if (item.id_ == id && item.tstep_ == tstep)
10566 + // Look for an empty slot:
10567 + for (i = 0; i < n; i++)
10568 + if (data_[i].id_ == "??")
10570 + // No empty slot: create a new slot:
10573 + DataCacheItem & item = data_[i];
10575 + item.tstep_ = tstep;
10577 + Journal(cache_info_level) << "LataFilterCache<C>::get " << id << " (new cache entry " << i << ")." << endl;
10579 + Journal(cache_info_level) << "LataFilterCache<C>::get " << id << " (existing cache entry " << i << ")." << endl;
10581 + // Mark item and lock it:
10582 + DataCacheItem & item = data_[i];
10583 + item.last_access_time_ = cache_data_access_count_++;
10585 + return item.item_;
10589 +// Description: tells that if needed the item can be deleted from cache
10590 +// (there is no reference to it anymore outside of the cache).
10591 +// We update the memory size of this item here.
10592 +void LataFilterCache::release_item(const Nom & id)
10594 + Journal(cache_info_level) << "LataFilterCache::release_item " << id << endl;
10595 + const entier n = data_.size();
10597 + for (i = 0; i < n; i++) {
10598 + const DataCacheItem & item = data_[i];
10599 + if (item.id_ == id)
10603 + Journal() << "LataFilterCache::release_item internal error: unknown item " << id << endl;
10606 + if (data_[i].lock_ <= 0) {
10607 + Journal() << "LataFilterCache::release_item internal error: item is already unlocked" << id << endl;
10610 + data_[i].last_access_time_ = cache_data_access_count_++;
10611 + data_[i].lock_--;
10612 + if (data_[i].item_.non_nul())
10613 + data_[i].memory_size_ = data_[i].item_.valeur().compute_memory_size();
10615 + data_[i].memory_size_ = 0;
10618 +// Description: removes from the cache the oldest items until the total
10619 +// memory used by the cache is below max_mem_size (in bytes), and
10620 +// if tstep_to_keep > 0, also removes all timesteps except 0 and tstep_to_keep
10621 +void LataFilterCache::cleanup_cache(entier tstep_to_keep)
10623 + if (clear_cache_on_tstep_change_ && tstep_to_keep > 0) {
10624 + Journal(cache_info_level) << "LataFilterCache::clear_cache_tsteps except 0 and " << tstep_to_keep << endl;
10625 + const entier n = data_.size();
10626 + for (entier i = 0; i < n; i++) {
10627 + DataCacheItem & item = data_[i];
10628 + if (item.id_ != "??") {
10629 + if (item.tstep_ == 0 || item.tstep_ == tstep_to_keep) {
10630 + Journal(cache_info_level+1) << " item " << item.id_ << " timestep " << item.tstep_ << " kept" << endl;
10631 + } else if (item.lock_) {
10632 + Journal(cache_info_level+1) << " item " << item.id_ << " locked" << endl;
10634 + Journal(cache_info_level) << " deleting item " << item.id_ << " " << item.tstep_ << endl;
10635 + item.item_.reset();
10637 + item.tstep_ = -1;
10642 + if (cache_memory_limit_ >= 0) {
10643 + Journal(cache_info_level) << "LataFilterCache::clear_cache_memory " << cache_memory_limit_ << endl;
10645 + const entier n = data_.size();
10646 + // Scan cached data, looking for the oldest item and summing up memory
10647 + BigEntier total_memsize = 0;
10648 + entier oldest = -1;
10649 + BigEntier oldest_time = cache_data_access_count_;
10650 + for (entier i = 0; i < n; i++) {
10651 + const DataCacheItem & item = data_[i];
10652 + if (item.id_ != "??") {
10653 + total_memsize += item.memory_size_;
10654 + if (!item.lock_ && item.last_access_time_ < oldest_time) {
10655 + oldest_time = item.last_access_time_;
10660 + if (oldest < 0 || total_memsize < cache_memory_limit_)
10663 + DataCacheItem & item = data_[oldest];
10664 + Journal(cache_info_level) << " deleting item " << item.id_ << " " << item.tstep_ << endl;
10665 + item.item_.reset();
10667 + item.tstep_ = -1;
10672 +// Description: Cleanup everything, associate the lata_db and fills metadata information.
10673 +void LataFilter::initialize(const LataOptions & opt, const LataDB & lata_db)
10676 + data_cache_.reset();
10677 + lataDB__ = &lata_db;
10678 + if (opt_.user_fields_) {
10679 + user_fields_.instancie(UserFields);
10680 + user_fields_.valeur().set_options(opt_.user_fields_options_);
10683 + get_all_metadata(geoms_metadata_, fields_metadata_);
10686 +void LataFilter::set_cache_properties(BigEntier max_memory, const entier keep_all_timesteps)
10688 + data_cache_.set_cache_properties(!keep_all_timesteps, max_memory);
10691 +// Description: Return the number of timesteps in the database
10692 +// (=number of physical timesteps + one containing global definitions at timestep 0)
10693 +entier LataFilter::get_nb_timesteps() const
10695 + return lataDB().nb_timesteps();
10698 +// Description: Return the physical time for this timestep.
10699 +// returns -1.0 for timestep 0 (global definitions)
10700 +double LataFilter::get_timestep(entier i) const
10705 + return lataDB().get_time(i);
10708 +static void add_fields_to_metadata_list(const LataDB & lataDB,
10709 + const Nom & lata_geom,
10710 + const Nom & dest_geom,
10711 + const Nom & options,
10713 + LataVector<LataFieldMetaData> & fields_data,
10714 + const Motcle & source,
10715 + const Nom & source_domain)
10717 + if (lataDB.nb_timesteps()<2) return;
10718 + // Query for existing fields in the latadb :
10719 + Field_UNames lata_fields = lataDB.field_unames(1, lata_geom, "*", LataDB::FIRST_AND_CURRENT);
10720 + const entier nb_fields = lata_fields.size();
10721 + for (entier i_field = 0; i_field < nb_fields; i_field++) {
10722 + const LataDBField & lata_field = lataDB.get_field(1, lata_fields[i_field], LataDB::FIRST_AND_CURRENT);
10723 + LataField_base::Elem_som loc = LataField_base::localisation_from_string(lata_field.localisation_);
10725 + // Hidden special fields
10726 + if (Motcle(lata_field.name_) == "INVALID_CONNECTIONS")
10728 + if (Motcle(lata_field.name_) == "ELEMENTS")
10730 + if (Motcle(lata_field.name_) == "FACES")
10732 + if (Motcle(lata_field.name_) == "ELEM_FACES")
10734 + LataFieldMetaData data;
10735 + data.name_ = lata_field.name_;
10736 + data.geometry_name_ = dest_geom;
10737 + data.component_names_ = lata_field.component_names_;
10738 + data.nb_components_ = lata_field.nb_comp_;
10739 + data.source_localisation_ = lata_field.localisation_;
10741 + if (options.find("to_vector")>=0) {
10742 + data.is_vector_ = 1;
10743 + data.nb_components_ = dim;
10745 + data.is_vector_ = (lata_field.nature_ == LataDBField::VECTOR);
10747 + if (options.find("to_elem")>=0)
10748 + data.localisation_ = LataField_base::ELEM;
10749 + else if (options.find("to_som")>=0)
10750 + data.localisation_ = LataField_base::SOM;
10751 + else if (options.find("to_faces")>=0)
10752 + data.localisation_ = LataField_base::FACES;
10754 + data.localisation_ = loc;
10756 + data.source_ = source;
10757 + data.uname_ = Field_UName(data.geometry_name_,
10759 + LataField_base::localisation_to_string(data.localisation_));
10760 + data.source_field_ = Field_UName(source_domain,
10762 + lata_fields[i_field].get_localisation());
10764 + if ((loc == LataField_base::ELEM && options.find("from_elem")>=0)
10765 + || (loc == LataField_base::SOM && options.find("from_som")>=0)
10766 + || (loc == LataField_base::FACES && options.find("from_faces")>=0)) {
10767 + Journal(filter_info_level) << " register field metadata: " << data.uname_ << endl;
10768 + fields_data.add(data);
10773 +// Process the content of the source LataDB structure and builds the metadata for
10774 +// all geometries and fields that the filter can export (depending on options,
10775 +// for example, provide dual mesh geometry and fields only if dualmesh option is on).
10776 +void LataFilter::get_all_metadata(LataVector<LataGeometryMetaData> & geoms_data, LataVector<LataFieldMetaData> & fields_data)
10778 + geoms_data.reset();
10779 + fields_data.reset();
10780 + entier current_tstep = 1;
10781 + // If no real timestep, just check timestep 0
10782 + if (lataDB().nb_timesteps() < 2)
10783 + current_tstep = 0;
10784 + Noms lata_geoms_names = lataDB().geometry_names(current_tstep, LataDB::FIRST_AND_CURRENT);
10785 + const entier nb_geoms = lata_geoms_names.size();
10786 + for (entier i_geom = 0; i_geom < nb_geoms; i_geom++) {
10787 + // Name of the current geometry (from lataDB)
10788 + const Nom & lata_geom_name = lata_geoms_names[i_geom];
10789 + const LataDBGeometry & lata_geom = lataDB().get_geometry(current_tstep, lata_geom_name, LataDB::FIRST_AND_CURRENT);
10790 + // Query properties from LataDB:
10791 + // Is it a dynamic mesh ?
10792 + const entier dynamic = lata_geom.timestep_ > 0;
10793 + // Element type ?
10794 + Domain::Element element_type = Domain::element_type_from_string(lata_geom.elem_type_);
10795 + // Query for dimension
10796 + const entier domain_already_ijk = lataDB().field_exists(current_tstep, lata_geom_name, "SOMMETS_IJK_I", LataDB::FIRST_AND_CURRENT);
10798 + // Do we have faces ?
10799 + const entier have_faces =
10800 + domain_already_ijk ||
10801 + (lataDB().field_exists(current_tstep, lata_geom_name, "FACES", LataDB::FIRST_AND_CURRENT)
10802 + && lataDB().field_exists(current_tstep, lata_geom_name, "ELEM_FACES", LataDB::FIRST_AND_CURRENT));
10805 + // Query for number of blocks in the lata file:
10806 + entier nblocks = 1;
10807 + if (domain_already_ijk) {
10808 + if (lataDB().field_exists(current_tstep, lata_geom_name, "SOMMETS_IJK_K", LataDB::FIRST_AND_CURRENT))
10812 + nblocks = opt_.ijk_mesh_nb_parts_;
10815 + nom_sommets = "SOMMETS_IJK_J";
10817 + nom_sommets = "SOMMETS_IJK_K";
10818 + const LataDBField & coord = lataDB().get_field(current_tstep, lata_geom_name, nom_sommets, "", LataDB::FIRST_AND_CURRENT);
10819 + // Nombre d'elements dans la direction du decoupage parallele:
10820 + const entier nelem = coord.size_ - 1;
10821 + // Si les tranches sont trop petites diminuer le nombre de blocs
10822 + if (nblocks > (nelem + 3) / 4)
10823 + nblocks = (nelem + 3) / 4;
10825 + dim = lataDB().get_field(current_tstep, lata_geom_name, "SOMMETS", "*", LataDB::FIRST_AND_CURRENT).nb_comp_;
10826 + if (lataDB().field_exists(current_tstep, lata_geom_name, "JOINTS_SOMMETS", LataDB::FIRST_AND_CURRENT))
10827 + nblocks = lataDB().get_field(current_tstep, lata_geom_name, "JOINTS_SOMMETS", "*", LataDB::FIRST_AND_CURRENT).size_;
10830 + // Initialize data common to all domains:
10831 + LataGeometryMetaData data;
10832 + data.dynamic_ = dynamic;
10833 + data.dimension_ = dim;
10834 + data.element_type_ = element_type;
10835 + data.is_ijk_=domain_already_ijk;
10837 + // If we reconnect all subdomains, always load all of them:
10838 + if (!opt_.reconnect)
10839 + data.nblocks_ = nblocks;
10841 + data.nblocks_ = 1;
10843 + data.internal_name_ = lata_geom_name;
10844 + data.displayed_name_ = lata_geom_name;
10846 + Nom separ("boundaries_");
10847 + int m=data.displayed_name_.find(separ);
10850 + const Nom& name= data.displayed_name_;
10851 + // on remplace boundaries_ par boundaries/
10852 + const char* jj =name;
10854 + disp.prefix(jj+m-1);
10855 + // GF le nom du domaine existe t il siuoi on a peut etre postraite sur un bord
10856 + if (lata_geoms_names.rang(disp)>-1)
10858 + Nom bord(jj+m+separ.longueur()-1);
10859 + disp+=Nom("_boundaries/");
10861 + data.displayed_name_=disp;
10864 + // cerr<< data.displayed_name_<<endl;
10865 + data.source_ = "latadb";
10866 + Journal(filter_info_level) << " metadata: adding geometry " << lata_geom_name << " displayed name=" << data.displayed_name_ << endl;
10867 + geoms_data.add(data);
10868 + // Add fields at som and elem:
10869 + add_fields_to_metadata_list(lataDB(), lata_geom_name, data.internal_name_,
10870 + "from_elem,from_som,from_faces", dim, fields_data,
10873 + // It is regularizable ?
10874 + entier regularizable = (((element_type == Domain::quadri)&&(data.dimension_==2)) || ((element_type == Domain::hexa)&&(data.dimension_==3)))
10875 + && (lata_geom.elem_type_ != "HEXAEDRE_AXI") && (lata_geom.elem_type_ != "RECTANGLE_AXI");
10876 + Journal(filter_info_level) << " metadata: geometry " << lata_geom_name << " element type says regularizable=" << regularizable << endl;
10877 + if (regularizable && ((opt_.regularize_tolerance < 0) || (!opt_.regularize))) {
10878 + regularizable = 0;
10879 + Journal(filter_info_level) << " regularize option not set: don't build ijk domain" << endl;
10881 + if (regularizable && domain_already_ijk) {
10882 + regularizable = 0;
10883 + Journal(filter_info_level) << " domain is already IJK: do not regularize" << endl;
10886 + // opt_.regularize == 2 means: provide ijk only if faces are present
10887 + if (regularizable && opt_.regularize == 2) {
10888 + if (!have_faces) {
10889 + Journal(filter_info_level) << " regularize option==2 and no faces => do not regularize" << endl;
10890 + regularizable = 0;
10893 + if (regularizable) {
10894 + data.internal_name_ = lata_geom_name;
10895 + data.internal_name_ += "_IJK";
10897 + data.displayed_name_ = lata_geom_name;
10898 + data.source_ = "operator_ijk";
10899 + data.source_domain_ = lata_geom_name;
10900 + geoms_data.add(data);
10901 + Journal(filter_info_level) << " metadata: adding geometry " << data.internal_name_ << " displayed name=" << data.displayed_name_ << endl;
10902 + // Add fields at som and elem:
10903 + add_fields_to_metadata_list(lataDB(), lata_geom_name, data.internal_name_,
10904 + "from_elem,from_som,from_faces", dim, fields_data,
10906 + data.source_domain_);
10909 + // Provide dual mesh
10910 + if (opt_.dual_mesh && have_faces) {
10911 + data.internal_name_ = lata_geom_name;
10913 + // If it's quadri or hexa, we need the regular mesh
10914 + data.source_domain_ = data.internal_name_;
10915 + if (regularizable) {
10916 + data.internal_name_ += "_IJK";
10917 + data.source_domain_ += "_IJK";
10920 + data.internal_name_ += "_dual";
10921 + data.displayed_name_ += "_dual";
10923 + data.source_ = "operator_dual";
10924 + geoms_data.add(data);
10925 + Journal(filter_info_level) << " metadata: adding geometry " << data.internal_name_ << " displayed name=" << data.displayed_name_ << endl;
10926 + // Add fields at faces, localisation will be at elements,
10927 + // forced to vector type if vdf:
10928 + Nom options("from_faces,to_elem");
10929 + if (regularizable)
10930 + options += ",to_vector";
10931 + add_fields_to_metadata_list(lataDB(), lata_geom_name, data.internal_name_,
10932 + options, dim, fields_data,
10934 + data.source_domain_);
10937 + // Provide nc mesh if possible
10938 + if (opt_.nc_mesh && have_faces && !regularizable /* doesn't work for vdf */) {
10939 + data.internal_name_ = lata_geom_name;
10940 + data.internal_name_ += "_nc";
10941 + data.displayed_name_ = data.internal_name_;
10942 + data.source_ = "operator_nc";
10943 + data.source_domain_ = lata_geom_name;
10944 + geoms_data.add(data);
10945 + Journal(filter_info_level) << " metadata: adding geometry " << data.internal_name_ << " displayed name=" << data.displayed_name_ << endl;
10946 + // Add fields at faces, localisation will be at nodes
10947 + Nom options("from_faces,to_som");
10948 + add_fields_to_metadata_list(lataDB(), lata_geom_name, data.internal_name_,
10949 + options, dim, fields_data,
10951 + data.source_domain_);
10953 + // Provide faces mesh if possible
10954 + if (opt_.faces_mesh && have_faces && !regularizable /* doesn't work for vdf */ && !(domain_already_ijk) ) {
10956 + data.internal_name_ = lata_geom_name;
10957 + data.internal_name_ += "_centerfaces";
10958 + data.displayed_name_ = data.internal_name_;
10959 + data.source_ = "operator_faces";
10960 + data.source_domain_ = lata_geom_name;
10961 + if (data.element_type_ == Domain::triangle)
10962 + data.element_type_=Domain::line;
10963 + else if ( data.element_type_ == Domain::tetra)
10964 + data.element_type_=Domain::triangle;
10966 + geoms_data.add(data);
10967 + Journal(filter_info_level) << " metadata: adding geometry " << data.internal_name_ << " displayed name=" << data.displayed_name_ << endl;
10968 + // Add fields at faces, localisation will be at nodes
10969 + Nom options("from_faces,to_elem");
10970 + add_fields_to_metadata_list(lataDB(), lata_geom_name, data.internal_name_,
10971 + options, dim, fields_data,
10972 + "operator_faces",
10973 + data.source_domain_);
10975 + // Provide boundary mesh
10976 + if (opt_.boundary_mesh && (element_type == Domain::hexa || element_type == Domain::tetra)) {
10977 + data.internal_name_ = lata_geom_name;
10978 + data.internal_name_ += "_Boundary";
10979 + data.displayed_name_ = data.internal_name_;
10980 + data.source_ = "operator_boundary";
10981 + data.source_domain_ = lata_geom_name;
10982 + geoms_data.add(data);
10983 + Journal(filter_info_level) << " metadata: adding geometry " << data.internal_name_ << " displayed name=" << data.displayed_name_ << endl;
10984 + Nom options("from_elem,from_som");
10985 + add_fields_to_metadata_list(lataDB(), lata_geom_name, data.internal_name_,
10986 + options, dim, fields_data,
10987 + "operator_boundary",
10988 + data.source_domain_);
10989 + options = "from_faces,to_elem";
10990 + add_fields_to_metadata_list(lataDB(), lata_geom_name, data.internal_name_,
10991 + options, dim, fields_data,
10992 + "operator_boundary",
10993 + data.source_domain_);
10997 + if (user_fields_.non_nul())
10998 + user_fields_.valeur().new_fields_metadata(*this, fields_data);
11001 +// Description: Return a list of domain names available from get_geometry_metadata()
11002 +// and that we want to show to the user.
11003 +// This includes the domains loaded from the lata file plus new constructed domains
11004 +// (nc_mesh, dual_mesh, boundary_mesh, etc) if requested in options and if available
11005 +// (depending if requiered data (eg faces, ...)
11006 +Noms LataFilter::get_exportable_geometry_names() const
11010 + for (i = 0; i < geoms_metadata_.size(); i++)
11011 + names.add(geoms_metadata_[i].internal_name_);
11013 + // If an IJK domain is here, don't show the original domain:
11015 + for (i = 0; i < names.size(); i++) {
11018 + if (names.rang(n) < 0)
11019 + names2.add(names[i]);
11024 +// Description: the same, with field names...
11025 +// If geometry=="*", returns all fields
11026 +// Currently, doesn't show fields located at faces...
11027 +Field_UNames LataFilter::get_exportable_field_unames(const char * geometry) const
11029 + Field_UNames unames;
11030 + Motcle geom(geometry);
11031 + for (entier i = 0; i < fields_metadata_.size(); i++)
11032 + if (geom == fields_metadata_[i].geometry_name_ || geom == "*")
11033 + // Do not show faces located fields to the user...
11034 + if (fields_metadata_[i].localisation_ != LataField_base::FACES || opt_.export_fields_at_faces_)
11035 + unames.add(fields_metadata_[i].uname_);
11040 +// Description: fill "data" for the requested "geometry". "geometry" must be a name
11041 +// returned by get_exportable_geometry_names()
11042 +const LataGeometryMetaData & LataFilter::get_geometry_metadata(const char * geometry) const
11044 + Motcle geom(geometry);
11045 + for (entier i = 0; i < geoms_metadata_.size(); i++)
11046 + if (geom == geoms_metadata_[i].internal_name_)
11047 + return geoms_metadata_[i];
11049 + Journal() << "Error in LataFilter::get_geometry_metadata: unknown geometry " << geometry << endl;
11050 + throw LataError(LataError::INVALID_DOMAIN,"unknown geometry");
11051 + return geoms_metadata_[0];
11054 +// Description: fill "data" for the requested "geometry/field". "geometry" and "field" must be names
11055 +// returned by get_exportable_geometry_names() and get_exportable_field_names()
11056 +const LataFieldMetaData & LataFilter::get_field_metadata(const Field_UName & uname) const
11058 + for (entier i = 0; i < fields_metadata_.size(); i++)
11059 + if (fields_metadata_[i].uname_ == uname)
11060 + return fields_metadata_[i];
11062 + Journal() << "Error in LataFilter::get_field_metadata: unknown field " << uname << endl;
11063 + throw LataError(LataError::INVALID_COMPONENT,"unknown field");
11064 + return fields_metadata_[0];
11068 +// Returns a reference to the requested geometry.
11069 +// If the geometry is not found at the requested timestep, it
11070 +// is seached in the first timestep.
11071 +// If the geometry does not exist in the cache, all needed data is loaded
11072 +// and the geometry is allocated and built in the internal cache.
11073 +// The reference is valid until the user calls release_geometry()
11074 +// The user MUST call release_geometry() to allow the data to be
11075 +// removed from the data cache.
11076 +const Domain & LataFilter::get_geometry(const Domain_Id & id)
11078 + Journal(filter_info_level) << "LataFilter::get_geometry "
11079 + << id.name_ << " time=" << id.timestep_
11080 + << " bloc=" << id.block_ << endl;
11081 + data_cache_.cleanup_cache(id.timestep_);
11083 + Domain_Id requested_id(id);
11084 + // Get the real timestep where this domain is stored:
11085 + const LataGeometryMetaData & geom_metadata = get_geometry_metadata(id.name_);
11086 + if (geom_metadata.dynamic_)
11087 + requested_id.timestep_ = id.timestep_;
11089 + requested_id.timestep_ = 0;
11091 + LataDeriv<Domain> & dom_ptr = get_cached_domain(requested_id);
11092 + if (!dom_ptr.non_nul()) {
11093 + if (geom_metadata.source_ == "latadb") {
11094 + // Request for a native domain : load it from lataDB
11095 + // If reconnect and loading all subdomains, go ! Don't store the operator in cache since it's
11096 + // not required to process fields.
11098 + // Is it a structured or unstructured mesh ?
11099 + if (lataDB().field_exists(requested_id.timestep_, requested_id.name_, "SOMMETS"))
11101 + DomainUnstructured & dom = dom_ptr.instancie(DomainUnstructured);
11103 + if (opt_.reconnect) {
11104 + // Bloc demande, peut etre le bloc 0 ou le bloc -1:
11105 + const entier req_block = requested_id.block_;
11106 + if (requested_id.block_ > 0) {
11107 + Cerr << "Error: requesting block " << requested_id.block_ << " with reconnect option" << endl;
11110 + requested_id.block_ = -1; // load all blocks
11111 + dom.fill_domain_from_lataDB(lataDB(), requested_id, 1 /* faces */, 0);
11112 + Reconnect::reconnect_geometry(dom, opt_.reconnect_tolerance);
11113 + dom.id_.block_ = req_block;
11115 + dom.fill_domain_from_lataDB(lataDB(), requested_id, 1 /* faces */, opt_.load_virtual_elements ? 1 : 0);
11116 + if (opt_.load_virtual_elements && dom.nb_virt_items(LataField_base::ELEM) > 0) {
11117 + Reconnect::reconnect_geometry(dom, opt_.reconnect_tolerance,
11118 + dom.nb_nodes() - dom.nb_virt_items(LataField_base::SOM));
11124 + // Structured ijk:
11125 + DomainIJK & dom = dom_ptr.instancie(DomainIJK);
11126 + if (opt_.reconnect || requested_id.block_ < 0) {
11127 + dom.fill_domain_from_lataDB(lataDB(), requested_id, 1 /* parallel splitting */,
11128 + 0 /* no virtual elements */);
11130 + const entier nparts = opt_.ijk_mesh_nb_parts_;
11131 + const entier virtual_size = opt_.load_virtual_elements ? opt_.ijk_virt_layer : 0;
11132 + dom.fill_domain_from_lataDB(lataDB(), requested_id, nparts /* parallel splitting */,
11133 + virtual_size /* with virtual elements */);
11136 + } else if (geom_metadata.source_.debute_par("OPERATOR")) {
11137 + const Domain & src_domain = get_geometry(Domain_Id(geom_metadata.source_domain_,
11138 + requested_id.timestep_,
11139 + requested_id.block_));
11140 + Operator & op = get_set_operator(requested_id);
11141 + op.build_geometry(src_domain, dom_ptr);
11142 + dom_ptr.valeur().id_ = requested_id;
11143 + release_cached_operator(requested_id);
11144 + release_geometry(src_domain);
11146 + Journal() << "Unknown source in geometry metadata " << geom_metadata.source_ << endl;
11151 + return dom_ptr.valeur();
11154 +Operator & LataFilter::get_set_operator(const Domain_Id & id)
11156 + LataDeriv<Operator> & op_ptr = get_cached_operator(id);
11157 + if (!op_ptr.non_nul()) {
11158 + // Operator not in the cache ? Build it:
11159 + if (id.name_.finit_par("_IJK")) {
11160 + OperatorRegularize & op = op_ptr.instancie(OperatorRegularize);
11161 + op.set_tolerance(opt_.regularize_tolerance);
11162 + op.set_extend_layer(opt_.extend_domain);
11163 + } else if (id.name_.finit_par("_dual")) {
11164 + op_ptr.instancie(OperatorDualMesh);
11165 + } else if (id.name_.finit_par("_Boundary")) {
11166 + op_ptr.instancie(OperatorBoundary);
11167 + } else if (id.name_.finit_par("_centerfaces")) {
11168 + op_ptr.instancie(OperatorFacesMesh);
11170 + Journal() << "Internal error in LataFilter::get_operator: forgot to implement operator choice for " << id.name_ << endl;
11174 + return op_ptr.valeur();
11178 +// Description: returns the requested field, computing it if it is not
11179 +// already in the cache. You MUST call release_field() on the returned field
11180 +// when you don't need it any more...
11181 +// See also class Field_Id
11182 +const LataField_base & LataFilter::get_field(const Field_Id & id)
11184 + Journal(filter_info_level) << "LataFilter::get_field "
11185 + << id.uname_ << " time=" << id.timestep_
11186 + << " bloc=" << id.block_ << endl;
11188 + data_cache_.cleanup_cache(id.timestep_);
11190 + const LataFieldMetaData & field_metadata = get_field_metadata(id.uname_);
11192 + LataDeriv<LataField_base> & field_ptr = get_cached_field(id);
11193 + if (!field_ptr.non_nul()) {
11194 + if (field_metadata.source_ == "latadb") {
11195 + // Request for a native field : load it from lataDB
11196 + const Domain & dom = get_geometry(id);
11197 + dom.fill_field_from_lataDB(lataDB(), id, field_ptr);
11198 + release_geometry(dom);
11199 + } else if (field_metadata.source_.debute_par("OPERATOR")) {
11200 + const Field_Id src_id(field_metadata.source_field_,
11203 + const Domain & src_domain = get_geometry(src_id);
11204 + const LataField_base & src_field = get_field(src_id);
11205 + const Domain & dest_domain = get_geometry(id);
11206 + Operator & op = get_set_operator(dest_domain.id_);
11207 + op.build_field(src_domain, src_field, dest_domain, field_ptr);
11208 + field_ptr.valeur().id_ = Field_Id(field_metadata.uname_, src_field.id_.timestep_, src_field.id_.block_);
11209 + release_field(src_field);
11210 + release_geometry(src_domain);
11211 + release_geometry(dest_domain);
11212 + release_cached_operator(dest_domain.id_);
11213 + } else if (field_metadata.source_ == "user_fields") {
11214 + Field<FloatTab> & f = field_ptr.instancie(Field<FloatTab> );
11215 + f = user_fields_.valeur().get_field(id);
11216 + // Force field id to correct value:
11218 + f.component_names_ = field_metadata.component_names_;
11219 + f.nature_ = field_metadata.is_vector_ ? LataDBField::VECTOR : LataDBField::SCALAR;
11220 + f.localisation_ = field_metadata.localisation_;
11224 + return field_ptr.valeur();
11227 +// Description: returns the requested float field, computing it if it is not
11228 +// already in the cache. You MUST call release_field() on the returned field
11229 +// when you don't need it any more...
11230 +// See also class Field_Id
11231 +const FieldFloat & LataFilter::get_float_field(const Field_Id & id)
11233 + const LataField_base & field = get_field(id);
11234 + const FieldFloat * float_field_ptr = dynamic_cast<const FieldFloat*>(&field);
11235 + if (! float_field_ptr) { /*assert(! float_field_ptr);*/ throw LataError(LataError::INVALID_COMPONENT,"unknown field");}
11236 + const FieldFloat & fld = *float_field_ptr;
11239 +void LataFilter::release_geometry(const Domain & dom)
11241 + Journal(filter_info_level) << "LataFilter::release_geometry "
11242 + << dom.id_.name_ << " time=" << dom.id_.timestep_
11243 + << " bloc=" << dom.id_.block_ << endl;
11244 + release_cached_domain(dom.id_);
11247 +void LataFilter::release_field(const LataField_base & field)
11249 + Journal(filter_info_level) << "LataFilter::release_field "
11250 + << field.id_.uname_ << " time=" << field.id_.timestep_
11251 + << " bloc=" << field.id_.block_ << endl;
11252 + release_cached_field(field.id_);
11255 +void build_mangeld_domain_name(const Domain_Id & id, Nom & name)
11259 + name += Nom(id.timestep_);
11261 + name += Nom(id.block_);
11262 + name.majuscule();
11265 +void build_mangeld_field_name(const Field_Id & id, Nom & name)
11267 + name = id.uname_.build_string();
11269 + name += Nom(id.timestep_);
11271 + name += Nom(id.block_);
11272 + name.majuscule();
11275 +LataDeriv<LataField_base> & LataFilter::get_cached_field(const Field_Id& id)
11278 + build_mangeld_field_name(id, n);
11279 + return data_cache_.get_item<LataDeriv<LataField_base> >(n, id.timestep_);
11281 +LataDeriv<Domain> & LataFilter::get_cached_domain(const Domain_Id& id)
11284 + build_mangeld_domain_name(id, n);
11285 + return data_cache_.get_item<LataDeriv<Domain> >(n, id.timestep_);
11287 +LataDeriv<Operator> & LataFilter::get_cached_operator(const Domain_Id& id)
11290 + build_mangeld_domain_name(id, n);
11292 + return data_cache_.get_item<LataDeriv<Operator> >(n, id.timestep_);
11294 +void LataFilter::release_cached_domain(const Domain_Id& id)
11297 + build_mangeld_domain_name(id, n);
11298 + data_cache_.release_item(n);
11300 +void LataFilter::release_cached_field(const Field_Id& id)
11303 + build_mangeld_field_name(id, n);
11304 + data_cache_.release_item(n);
11306 +void LataFilter::release_cached_operator(const Domain_Id& id)
11309 + build_mangeld_domain_name(id, n);
11311 + data_cache_.release_item(n);
11314 +void LataOptions::extract_path_basename(const char * s, Nom & path_prefix, Nom & basename)
11317 + for (i=(int)strlen(s)-1;i>=0;i--)
11318 + if ((s[i]==PATH_SEPARATOR) ||(s[i]=='\\'))
11320 + path_prefix = "";
11322 + for (j = 0; j <= i; j++)
11323 + path_prefix += Nom(s[j]);
11325 + // Parse basename : if extension given, remove it
11326 + int n = (int)strlen(s);
11327 + if (n > 5 && strcmp(s+n-5,".lata") == 0)
11330 + for (j = i+1; j < n; j++)
11331 + basename += Nom(s[j]);
11332 + // Journal(9)<<" prefix "<<path_prefix<< " "<<i<<endl;
11335 +LataOptions::LataOptions()
11337 + dual_mesh = false;
11338 + faces_mesh=false;
11340 + boundary_mesh = false;
11341 + reconnect = false;
11342 + reconnect_tolerance = 1e-6;
11343 + regularize = false;
11344 + extend_domain = 0;
11345 + regularize_tolerance = 1e-6;
11346 + invalidate = false;
11347 + load_virtual_elements = false;
11348 + user_fields_ = false;
11349 + ijk_mesh_nb_parts_ = 1;
11350 + ijk_virt_layer = 1;
11351 + export_fields_at_faces_ = 0;
11352 + regularize_polyedre=0;
11355 +void build_geometry_(Operator & op, const Domain & src, LataDeriv<Domain> & dest)
11357 + Journal() << "Error in an operator: build_geometry not coded for this Operator/Domain" << endl;
11361 +void build_field_(Operator & op, const Domain & src, const Domain & dest,
11362 + const LataField_base & srcf, LataField_base & destf)
11364 + Journal() << "Error in an operator: build_field not coded for this Operator/Domain/Field" << endl;
11368 +void LataDB_apply_input_filter(const LataDB & lata_db, LataDB & filtered_db,
11369 + const ArrOfInt & input_timesteps_filter,
11370 + const Noms & input_domains_filter,
11371 + const Noms & input_components_filter)
11373 + ArrOfInt timesteps_filter(input_timesteps_filter);
11374 + Noms domains_filter(input_domains_filter);
11375 + Noms components_filter(input_components_filter);
11377 + // Build a list of all available geometries and components
11378 + Noms list_all_domains = lata_db.geometry_names(lata_db.nb_timesteps()-1, LataDB::FIRST_AND_CURRENT);
11379 + Noms list_all_fields;
11381 + Field_UNames fields = lata_db.field_unames(lata_db.nb_timesteps()-1, "*", "*", LataDB::FIRST_AND_CURRENT);
11382 + for (entier i = 0; i < fields.size(); i++) {
11383 + const Nom & n = fields[i].get_field_name();
11384 + if (list_all_fields.rang(n) < 0)
11385 + list_all_fields.add(n);
11389 + if (timesteps_filter.size_array() == 0) {
11390 + // Add all timesteps, timestep 0 is implicitely added.
11391 + entier n = lata_db.nb_timesteps();
11392 + timesteps_filter.resize_array(n-1);
11393 + for (entier i = 1; i < n; i++)
11394 + timesteps_filter[i-1] = i;
11395 + Journal(3) << " Exporting all " << n-1 << " timesteps" << endl;
11396 + } else if (timesteps_filter[0] < 0) {
11397 + timesteps_filter.resize_array(0);
11398 + Journal(3) << " Request timestep -1: Exporting only global time independent data" << endl;
11400 + if (domains_filter.size() == 0) {
11401 + // Add all geometries
11402 + domains_filter = list_all_domains;
11403 + Journal(3) << " Exporting all geometries" << endl;
11405 + if (components_filter.size() == 0) {
11406 + // Add all fields of the selected geometries
11407 + components_filter = list_all_fields;
11408 + Journal(3) << " Exporting all fields:" << endl;
11410 + // Add all known geometry data fields
11411 + components_filter.add("SOMMETS");
11412 + components_filter.add("ELEMENTS");
11413 + components_filter.add("FACES");
11414 + components_filter.add("ELEM_FACES");
11415 + components_filter.add("JOINTS_SOMMETS");
11416 + components_filter.add("JOINTS_ELEMENTS");
11417 + components_filter.add("JOINTS_FACES");
11418 + components_filter.add("VIRTUAL_ELEMENTS");
11419 + // these are for ijk meshs:
11420 + components_filter.add("SOMMETS_IJK_I");
11421 + components_filter.add("SOMMETS_IJK_J");
11422 + components_filter.add("SOMMETS_IJK_K");
11423 + components_filter.add("INVALID_CONNECTIONS");
11425 + filtered_db.filter_db(lata_db,
11426 + noms_to_motcles(domains_filter),
11427 + noms_to_motcles(components_filter),
11428 + timesteps_filter);
11430 diff --git a/databases/readers/Lata/LataFilter.h b/databases/readers/Lata/LataFilter.h
11431 new file mode 100644
11432 index 0000000..77f24d9
11434 +++ b/databases/readers/Lata/LataFilter.h
11436 +/*****************************************************************************
11438 +* Copyright (c) 2011 - 2013, CEA
11439 +* All rights reserved.
11440 +* Redistribution and use in source and binary forms, with or without
11441 +* modification, are permitted provided that the following conditions are met:
11443 +* * Redistributions of source code must retain the above copyright
11444 +* notice, this list of conditions and the following disclaimer.
11445 +* * Redistributions in binary form must reproduce the above copyright
11446 +* notice, this list of conditions and the following disclaimer in the
11447 +* documentation and/or other materials provided with the distribution.
11448 +* * Neither the name of CEA, nor the
11449 +* names of its contributors may be used to endorse or promote products
11450 +* derived from this software without specific prior written permission.
11452 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
11453 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11454 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11455 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
11456 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11457 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11458 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11459 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11460 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11461 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11463 +*****************************************************************************/
11465 +#ifndef LATA_H_INCLUDE
11466 +#define LATA_H_INCLUDE
11468 +#include <LataDB.h>
11469 +#include <LataStructures.h>
11470 +#include <UserFields.h>
11472 +typedef Field<FloatTab> FieldFloat;
11474 +// This file provides the LataFilter class: it is a dynamic mesh
11475 +// and field generator which is able to load data from a lata file,
11476 +// apply operators. Once computed, the data is kept in a data cache
11477 +// to speed up further access to the same data.
11479 +// This class holds the LataFilter configuration (determines which
11480 +// combination of operators should be applied to the data)
11484 + static void extract_path_basename(const char * s, Nom & path_prefix, Nom & basename);
11485 + static entier read_int_opt(const Nom & s);
11486 + static double read_float_opt(const Nom & s);
11487 + static Nom read_string_opt(const Nom & s);
11489 + Nom basename; // Name of the case.
11490 + Nom path_prefix; // Path for the case.
11492 + // Generate de the following meshes and associated data, if the flag is set.
11496 + bool boundary_mesh;
11498 + bool reconnect; // Do we want to reconnect multiblock meshes
11499 + float reconnect_tolerance;
11500 + int regularize_polyedre ; // if 1 Treate polyedre as poyledre extruder
11501 + int regularize; // Do we want to force regularize the domain ie convert the mesh to a structured ijk (not necessary except for dual-mesh vdf)
11502 + // special value 2 means "regularize if faces present and vdf"
11503 + int extend_domain; // Extend the regularized domaine by n layers of cells
11504 + float regularize_tolerance;
11505 + bool invalidate; // invalidate unused positions and connections;
11506 + bool load_virtual_elements; // Do we want to extend the loaded mesh subblocks with a layer of virtual elements
11507 + bool export_fields_at_faces_; // Should we show these fields in exportable fields
11509 + // When loading ijk regular meshes, virtually create this number of blocks in the K direction:
11510 + int ijk_mesh_nb_parts_;
11511 + // When loading ijk regular meshes, merge N layers of virtual elements (default=1)
11512 + int ijk_virt_layer;
11514 + bool user_fields_; //activate user fields ?
11516 + ArrOfDouble clipbox_min;
11517 + ArrOfDouble clipbox_max;
11519 + UserFields_options user_fields_options_;
11522 + virtual entier parse_option(const Nom &);
11523 + virtual void describe();
11524 + virtual ~LataOptions() {};
11527 +class Operator : public LataObject
11530 + virtual void build_field(const Domain & src_domain, const LataField_base & src_field,
11531 + const Domain & dest_domain, LataDeriv<LataField_base> & dest) = 0;
11532 + virtual void build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest) = 0;
11536 +struct LataGeometryMetaData
11538 + Nom internal_name_; // Internal full name (eg DOM_IJK)
11539 + Nom displayed_name_; // Short name showed to the user (DOM for DOM_IJK, ?? if the geometry should not be exported)
11540 + entier dynamic_; // Is the geometry changing at each timestep ?
11541 + entier dimension_; // spatial dimension of coordinates
11542 + Domain::Element element_type_;
11543 + entier nblocks_; // Number of sub_blocks in the geometry (parallel computation)
11544 + Motcle source_; // How to build this domain ("latadb", "operator_ijk", "operator_dual", "operator_boundary", "user_fields")
11545 + Nom source_domain_;
11549 +struct LataFieldMetaData
11551 + Field_UName uname_;
11553 + Nom geometry_name_;
11554 + Noms component_names_;
11555 + entier nb_components_;
11556 + entier is_vector_; // Yes => nb_components is equal to spatial dimension
11557 + LataField_base::Elem_som localisation_;
11558 + Nom source_localisation_; // Localisation of source field (for displayed name in visit)
11559 + Motcle source_; // How to build this field ("latadb", "operator_ijk", "operator_dual", "operator_boundary", "user_fields")
11560 + Field_UName source_field_;
11563 +class DataCacheItem
11566 + DataCacheItem() : tstep_(-1), last_access_time_(0), lock_(0), memory_size_(0) {}
11567 + LataDeriv<LataObject> item_; // The cached item
11568 + Nom id_; // The id for this item
11569 + entier tstep_; // The timestep of the cached data (for cache cleanup)
11570 + BigEntier last_access_time_; // Last time this item has been accessed (for cache cleanup)
11571 + // Is the item locked ? => cannot be deleted by clear_cache()
11572 + // This is a counter: get_item increases, release_item dereases.
11573 + // (this is when we simultaneously need several items, we must lock them to be sure)
11575 + // The memory size is computed when the item is released
11576 + BigEntier memory_size_;
11579 +class LataFilterCache
11582 + LataFilterCache() : cache_data_access_count_(0),
11583 + clear_cache_on_tstep_change_(1), cache_memory_limit_(-1) {};
11584 + void reset() { data_.reset(); cache_data_access_count_ = 0; }
11585 + void set_cache_properties(entier clear_on_tstep_change, BigEntier mem_limit);
11586 + template<class C> C & get_item(const Nom & id, entier tstep)
11588 + LataDeriv<LataObject> & obj = get_item_(id, tstep);
11589 + if (obj.non_nul())
11590 + return obj.refcast(C);
11592 + return obj.instancie(C);
11594 + void release_item(const Nom & id);
11595 + void remove_item(const Nom & id);
11596 + void cleanup_cache(entier tstep_to_keep);
11598 + LataDeriv<LataObject> & get_item_(const Nom & id, entier tstep);
11599 + // Stored data (depends on caching strategy)
11600 + // data_ grows when needed.
11601 + LataVector<DataCacheItem> data_;
11602 + BigEntier cache_data_access_count_;
11603 + // If nonzero, whenever we ask a timestep,
11604 + // remove all cached data from other timesteps
11605 + entier clear_cache_on_tstep_change_;
11606 + // If before getting a new geometry or field, the data cache
11607 + // uses more than the limit, remove old data until we are below.
11608 + // -1 means "no limit"
11609 + BigEntier cache_memory_limit_; // Limit in bytes
11612 +// Description: This is the MAIN class for the lata filter tool:
11613 +// It reads data from a lata database on disk (initialize),
11614 +// and proposes several geometries and fields (get_exportable...) to the user.
11615 +// The user can get them with get_geometry and get_field.
11616 +// He must then call release_geometry and release_field to free the memory.
11617 +// The user can also get metadata information (available without loading all
11618 +// the data from disk) for geometries and fields and also timestep informations.
11619 +// Timestep 0 contains global geometry and field definitions, timestep 1..n
11620 +// are associated with each "TEMPS" entry in the lata file.
11622 +// LataFilter uses a data cache internally: it keeps fields and geometries after
11623 +// the user calls release_xxx(). The cache is controlled by set_cache_properties()
11624 +class LataFilter {
11626 + LataFilter() : lataDB__(0) {};
11627 + void initialize(const LataOptions & opt, const LataDB & db);
11628 + void set_cache_properties(BigEntier max_memory, const entier keep_all_timesteps);
11629 + Noms get_exportable_geometry_names() const;
11630 + const LataGeometryMetaData & get_geometry_metadata(const char * geometry) const;
11631 + LataVector<Field_UName> get_exportable_field_unames(const char * geometry) const;
11632 + const LataFieldMetaData & get_field_metadata(const Field_UName & uname) const;
11633 + entier get_nb_timesteps() const;
11634 + double get_timestep(entier i) const;
11636 + const Domain & get_geometry(const Domain_Id &);
11638 + void release_geometry(const Domain &);
11639 + const LataField_base & get_field(const Field_Id &);
11640 + const FieldFloat & get_float_field(const Field_Id &) ;
11642 + void release_field(const LataField_base &);
11644 + const LataDB & get_lataDB() const { return lataDB(); }
11646 + const LataOptions & get_options() const { return opt_; }
11648 + Operator & get_set_operator(const Domain_Id & id);
11649 + LataDeriv<LataField_base> & get_cached_field(const Field_Id&);
11650 + LataDeriv<Domain> & get_cached_domain(const Domain_Id&);
11651 + LataDeriv<Operator> & get_cached_operator(const Domain_Id&);
11652 + void release_cached_domain(const Domain_Id&);
11653 + void release_cached_field(const Field_Id&);
11654 + void release_cached_operator(const Domain_Id&);
11655 + const Domain & get_geom_field_(const Field_Id & id, LataRef<const LataField_base> & field_result);
11656 + void get_all_metadata(LataVector<LataGeometryMetaData> & geoms_data, LataVector<LataFieldMetaData> & fields_data);
11657 + // LataDB & lataDB() { return lataDB__; }
11658 + const LataDB & lataDB() const { assert(lataDB__); return *lataDB__; }
11660 + // We store in the cache objects of type:
11661 + // LataDeriv<Domain>
11662 + // derived types of Operator
11663 + // LataDeriv<LataField_base>
11664 + LataFilterCache data_cache_;
11666 + // LataV2 masterfile database
11667 + const LataDB *lataDB__;
11668 + LataOptions opt_;
11669 + // Metadata information for all fields and geometries (built in initialize)
11670 + LataVector<LataGeometryMetaData> geoms_metadata_;
11671 + LataVector<LataFieldMetaData> fields_metadata_;
11673 + LataDeriv<UserFields> user_fields_;
11678 + enum ErrorCode { NEED_REGULAR, NO_FACES, WRONG_ELT_TYPE, INVALID_TSTEP, INVALID_COMPONENT,
11679 + INVALID_DOMAIN, OTHER};
11680 + LataError(ErrorCode code, const char * msg) : code_(code), msg_(msg) {};
11682 + const char *msg_;
11685 +struct InternalError
11687 + InternalError(const char *msg) : msg_(msg) {};
11688 + const char *msg_;
11691 +void LataDB_apply_input_filter(const LataDB & lata_db, LataDB & filtered_db,
11692 + const ArrOfInt & input_timesteps_filter,
11693 + const Noms & input_domains_filter,
11694 + const Noms & input_components_filter);
11697 diff --git a/databases/readers/Lata/LataJournal.h b/databases/readers/Lata/LataJournal.h
11698 new file mode 100644
11699 index 0000000..acc68e3
11701 +++ b/databases/readers/Lata/LataJournal.h
11703 +/*****************************************************************************
11705 +* Copyright (c) 2011 - 2013, CEA
11706 +* All rights reserved.
11707 +* Redistribution and use in source and binary forms, with or without
11708 +* modification, are permitted provided that the following conditions are met:
11710 +* * Redistributions of source code must retain the above copyright
11711 +* notice, this list of conditions and the following disclaimer.
11712 +* * Redistributions in binary form must reproduce the above copyright
11713 +* notice, this list of conditions and the following disclaimer in the
11714 +* documentation and/or other materials provided with the distribution.
11715 +* * Neither the name of CEA, nor the
11716 +* names of its contributors may be used to endorse or promote products
11717 +* derived from this software without specific prior written permission.
11719 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
11720 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11721 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11722 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
11723 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11724 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11725 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11726 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11727 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11728 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11730 +*****************************************************************************/
11732 +#ifndef LataJournal_H
11733 +#define LataJournal_H
11734 +#include <iostream>
11736 +std::ostream & Journal(entier level=0);
11737 +void set_Journal_level(entier level);
11739 diff --git a/databases/readers/Lata/LataStructures.C b/databases/readers/Lata/LataStructures.C
11740 new file mode 100644
11741 index 0000000..390d289
11743 +++ b/databases/readers/Lata/LataStructures.C
11745 +/*****************************************************************************
11747 +* Copyright (c) 2011 - 2013, CEA
11748 +* All rights reserved.
11749 +* Redistribution and use in source and binary forms, with or without
11750 +* modification, are permitted provided that the following conditions are met:
11752 +* * Redistributions of source code must retain the above copyright
11753 +* notice, this list of conditions and the following disclaimer.
11754 +* * Redistributions in binary form must reproduce the above copyright
11755 +* notice, this list of conditions and the following disclaimer in the
11756 +* documentation and/or other materials provided with the distribution.
11757 +* * Neither the name of CEA, nor the
11758 +* names of its contributors may be used to endorse or promote products
11759 +* derived from this software without specific prior written permission.
11761 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
11762 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11763 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11764 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
11765 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11766 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11767 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11768 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11769 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11770 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11772 +*****************************************************************************/
11774 +#include <LataStructures.h>
11775 +#include <LataDB.h>
11776 +#include <stdlib.h>
11777 +static const entier info_level = 4;
11779 +// Description: returns the number of items of the given type
11780 +entier Domain::nb_items(const LataField_base::Elem_som loc) const
11784 + case LataField_base::SOM: n = nb_nodes(); break;
11785 + case LataField_base::ELEM: n = nb_elements(); break;
11786 + case LataField_base::FACES: n = nb_faces(); break;
11788 + Journal() << "Invalid localisation " << (int) loc << " in Domain::nb_items" << endl;
11794 +// Description: returns the offset in the lata block on disk of the first
11795 +// item for this Domain.id_.block_ (parallel computation).
11796 +// (this value must be set with set_lata_block_offset)
11797 +entier Domain::lata_block_offset(const LataField_base::Elem_som loc) const
11801 + case LataField_base::SOM: n = decal_nodes_lata_; break;
11802 + case LataField_base::ELEM: n = decal_elements_lata_; break;
11803 + case LataField_base::FACES: n = decal_faces_lata_; break;
11805 + Journal() << "Invalid localisation " << (int) loc << " in Domain::lata_block_offset" << endl;
11809 + Journal() << "Error: lata_block_offset not set for localisation " << (int) loc << endl;
11815 +// Description: set the lata_block_offset (see lata_block_offset)
11816 +void Domain::set_lata_block_offset(const LataField_base::Elem_som loc, entier n)
11819 + case LataField_base::SOM: decal_nodes_lata_ = n; break;
11820 + case LataField_base::ELEM: decal_elements_lata_ = n; break;
11821 + case LataField_base::FACES: decal_faces_lata_ = n; break;
11823 + Journal() << "Invalid localisation " << (int) loc << " in Domain::set_lata_block_offset" << endl;
11828 +template<class TabType>
11829 +void DomainUnstructured::compute_cell_center_coordinates(TabType & coord, entier index_begin) const
11831 + const entier dim = nodes_.dimension(1);
11832 + const entier nb_elem = elements_.dimension(0);
11833 + const entier nb_som_elem = elements_.dimension(1);
11834 + const double facteur = 1. / (double) nb_som_elem;
11836 + for (int i = 0; i < nb_elem; i++) {
11838 + tmp[0] = tmp[1] = tmp[2] = 0.;
11839 + for (j = 0; j < nb_som_elem; j++) {
11840 + int som = elements_(i, j);
11841 + for (k = 0; k < loop_max(dim, 3); k++) {
11842 + tmp[k] += nodes_(som, k);
11843 + break_loop(k, dim);
11846 + for (k = 0; k < loop_max(dim, 3); k++) {
11847 + coord(index_begin + i, k) = tmp[k] * facteur;
11848 + break_loop(k, dim);
11854 +void DomainUnstructured::compute_cell_center_coordinates(FloatTab & coord, entier index_begin) const;
11856 +void DomainUnstructured::compute_cell_center_coordinates(DoubleTab & coord, entier index_begin) const;
11859 +LataField_base::Elem_som LataField_base::localisation_from_string(const Motcle & loc)
11861 + if (loc.debute_par("SOM"))
11863 + else if (loc.debute_par("ELEM"))
11865 + else if (loc.debute_par("FACE"))
11871 +Nom LataField_base::localisation_to_string(const Elem_som loc)
11875 + case SOM: n = "SOM"; break;
11876 + case ELEM: n = "ELEM"; break;
11877 + case FACES: n = "FACES"; break;
11878 + case UNKNOWN: n = "";
11883 +Motcle Domain::lata_element_name(Domain::Element type)
11886 + case point: return "POINT"; break;
11887 + case line: return "SEGMENT"; break;
11888 + case triangle: return "TRIANGLE"; break;
11889 + case quadri: return "QUADRANGLE"; break;
11890 + case tetra: return "TETRAEDRE"; break;
11891 + case hexa: return "HEXAEDRE"; break;
11892 + case prism6: return "PRISM6"; break;
11893 + case polyedre: return "POLYEDRE"; break;
11894 + case polygone: return "POLYGONE"; break;
11895 + default: return "UNSPECIFIED";
11897 + return "UNSPECIFIED";
11900 +Domain::Element Domain::element_type_from_string(const Motcle & type_elem)
11903 + if (type_elem == "HEXAEDRE")
11905 + else if (type_elem == "HEXAEDRE_AXI")
11907 + else if (type_elem == "HEXAEDRE_VEF")
11909 + else if (type_elem == "QUADRANGLE")
11911 + else if (type_elem == "QUADRANGLE_3D")
11913 + else if (type_elem == "RECTANGLE")
11915 + else if (type_elem == "RECTANGLE_2D_AXI")
11917 + else if (type_elem == "RECTANGLE_AXI")
11919 + else if (type_elem == "SEGMENT")
11921 + else if (type_elem == "SEGMENT_2D")
11923 + else if (type_elem == "TETRAEDRE")
11925 + else if (type_elem == "TRIANGLE")
11927 + else if (type_elem == "TRIANGLE_3D")
11929 + else if (type_elem == "POINT")
11931 + else if ((type_elem == "PRISM6")||(type_elem == "PRISME"))
11933 + else if (type_elem.debute_par("POLYEDRE"))
11935 + else if (type_elem.debute_par("POLYGONE"))
11938 + Journal() << "Error in elem_type_from_string: unknown element type " << type_elem << endl;
11944 +Nom Domain::element_type_to_string(Element type)
11948 + case point: n = "POINT"; break;
11949 + case line: n = "SEGMENT"; break;
11950 + case triangle: n = "TRIANGLE"; break;
11951 + case quadri: n = "QUADRANGLE"; break;
11952 + case tetra: n = "TETRAEDRE"; break;
11953 + case hexa: n = "HEXAEDRE"; break;
11954 + case prism6: n = "PRISM6"; break;
11955 + case polyedre: n = "POLYEDRE_0"; break;
11956 + case polygone: n = "POLYGONE"; break;
11957 + case unspecified: n = "UNKNOWN"; break;
11962 +// Description: read the specified geometry from the lataDB_ structure and put it in "dom".
11963 +// load_faces: flag, tells if we should read faces definitions in the lata file
11964 +// merge_virtual_elements: flag, if a "VIRTUAL_ELEMENTS" array is present in the lata file,
11965 +// merges these elements to the requested block.
11966 +void DomainUnstructured::fill_domain_from_lataDB(const LataDB & lataDB,
11967 + const Domain_Id & id,
11968 + entier load_faces,
11969 + entier merge_virtual_elements)
11971 + operator=(DomainUnstructured()); // Reset all data.
11974 + const LataDBGeometry & geom = lataDB.get_geometry(id.timestep_, id.name_);
11976 + // ********************************
11977 + // 1) Look for the sub-block items to read (parallel computation)
11978 + entier decal_nodes = 0;
11979 + entier decal_elements = 0;
11980 + entier decal_faces = 0;
11981 + entier nb_sommets = -1;
11982 + entier nbelements = -1;
11983 + entier nbfaces = -1;
11985 + entier domain_has_faces = load_faces && lataDB.field_exists(id.timestep_, id.name_, "FACES");
11987 + // Tableau de 3 joints (SOM, ELEM et FACES)
11988 + LataVector<IntTab> joints;
11989 + entier nproc = 1;
11990 + for (entier i_item = 0; i_item < 3; i_item++) {
11991 + // LataField_base::Elem_som loc = LataField_base::SOM;
11992 + Nom nom("JOINTS_SOMMETS");
11993 + Nom nom2("SOMMETS");
11994 + if (i_item == 1) {
11995 + //loc = LataField_base::ELEM;
11996 + nom = "JOINTS_ELEMENTS";
11997 + nom2 = "ELEMENTS";
11998 + } else if (i_item == 2) {
11999 + // loc = LataField_base::FACES;
12000 + nom = "JOINTS_FACES";
12004 + IntTab & joint = joints.add();
12005 + if (lataDB.field_exists(id.timestep_, id.name_, nom)) {
12006 + entier nbitems = lataDB.get_field(id.timestep_, id.name_, nom2, "*").size_;
12008 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, nom, "*"), tmp);
12009 + nproc = tmp.dimension(0);
12010 + // Recalcule la deuxieme colonne en fonction de la premiere
12011 + joint.resize(nproc, 2);
12012 + for (entier i = 0; i < nproc; i++) {
12013 + joint(i, 0) = tmp(i, 0);
12015 + joint(i, 1) = tmp(i+1, 0) - tmp(i, 0);
12017 + joint(i, 1) = nbitems - tmp(i, 0);
12022 + if (id_.block_ < 0 || nproc == 1) {
12023 + // read all blocks at once default values are ok
12024 + set_joints(LataField_base::SOM) = joints[0];
12025 + set_joints(LataField_base::ELEM) = joints[1];
12026 + set_joints(LataField_base::FACES) = joints[2];
12028 + if (id_.block_ >= nproc) {
12029 + Journal() << "LataFilter::get_geometry : request non existant block " << id.block_
12030 + << " in geometry " << id.name_ << endl;
12033 + const entier n = id_.block_;
12034 + decal_nodes = joints[0](n, 0);
12035 + nb_sommets = joints[0](n, 1);
12036 + decal_elements = joints[1](n, 0);
12037 + nbelements = joints[1](n, 1);
12038 + if (domain_has_faces) {
12039 + decal_faces = joints[2](n, 0);
12040 + nbfaces = joints[2](n, 1);
12044 + // ******************************
12045 + // 2) Read nodes, elements and faces data
12046 + elt_type_ = Domain::element_type_from_string(geom.elem_type_);
12048 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "SOMMETS", "*"), nodes_, decal_nodes, nb_sommets);
12049 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "ELEMENTS", "*"), elements_, decal_elements, nbelements);
12050 + set_lata_block_offset(LataField_base::SOM, decal_nodes);
12051 + set_lata_block_offset(LataField_base::ELEM, decal_elements);
12052 + if (decal_nodes > 0) {
12053 + // Nodes are stored with global numbering in the lata file: transform to sub_block numbering :
12054 + elements_ -= decal_nodes;
12056 + if (domain_has_faces) {
12057 + set_lata_block_offset(LataField_base::FACES, decal_faces);
12058 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "FACES", "*"), faces_, decal_faces, nbfaces);
12059 + if (decal_nodes > 0)
12060 + faces_ -= decal_nodes;
12061 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "ELEM_FACES", "*"), elem_faces_, decal_elements, nbelements);
12062 + if (decal_faces > 0)
12063 + elem_faces_ -= decal_faces;
12066 + // *************************
12067 + // 3) Merge virtual elements if requested
12068 + if (merge_virtual_elements && lataDB.field_exists(id.timestep_, id.name_, "VIRTUAL_ELEMENTS") && id.block_ >= 0)
12070 + Journal(info_level) << " Merging virtual elements" << endl;
12071 + // joints_virt_elems(sub_block, 0) = index of first virtual element in the VIRTUAL_ELEMENTS array
12072 + IntTab joints_virt_elems;
12073 + // Load the virtual elements (nodes are in global numbering)
12074 + // First: find the index and number of virtual elements for block number id.block_:
12075 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "JOINTS_VIRTUAL_ELEMENTS", "*"), joints_virt_elems);
12076 + entier nb_virt_elems;
12077 + if (id.block_ < nproc-1)
12078 + nb_virt_elems = joints_virt_elems(id.block_+1, 0) - joints_virt_elems(id.block_, 0);
12080 + nb_virt_elems = lataDB.get_field(id.timestep_, id.name_, "VIRTUAL_ELEMENTS", "*").size_ - joints_virt_elems(id.block_, 0);
12081 + Journal(info_level+1) << " Number of virtual elements for block " << id.block_ << "=" << nb_virt_elems << endl;
12082 + // Second: load the indexes of the virtual elements to load:
12083 + IntTab virt_elems;
12084 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "VIRTUAL_ELEMENTS", "*"), virt_elems, joints_virt_elems(id.block_,0), nb_virt_elems);
12085 + set_virt_items(LataField_base::ELEM, virt_elems);
12088 + // Third: load the virtual elements (virt_elems contains the global indexes of the elements to
12089 + // load and virt_elem_som will contain global nodes indexes of the virtual elements)
12090 + IntTab virt_elem_som;
12091 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "ELEMENTS", "*"), virt_elem_som, virt_elems);
12092 + // Find which virtual nodes are required and load them: virtual nodes to load are
12093 + // all nodes of the virtual elements (they have duplicates).
12095 + ArrOfInt & virt_elem_som_array = virt_elem_som; // Array seen as monodimensionnal
12096 + array_sort_indirect(virt_elem_som_array, index);
12097 + // Global nodes indexes of needed virtual nodes
12098 + ArrOfInt nodes_to_read;
12099 + nodes_to_read.set_smart_resize(1);
12101 + const entier n = index.size_array();
12102 + // Global index of the last loaded node:
12103 + entier last_node = -1;
12104 + // Local index of the new loaded node:
12105 + entier new_node_index = nodes_.dimension(0)-1;
12106 + for (entier i = 0; i < n; i++) {
12107 + // Take nodes to load in ascending order of their global numbers:
12108 + const entier idx = index[i];
12109 + const entier node = virt_elem_som_array[idx];
12110 + if (node != last_node) {
12111 + // Node not yet encountered
12112 + nodes_to_read.append_array(node);
12113 + new_node_index++;
12114 + last_node = node;
12116 + virt_elem_som_array[idx] = new_node_index;
12119 + set_virt_items(LataField_base::SOM, nodes_to_read);
12120 + // Copy virtual elements to elements_
12121 + entier debut = elements_.size_array();
12122 + elements_.resize(elements_.dimension(0) + virt_elem_som.dimension(0),
12123 + elements_.dimension(1));
12124 + elements_.inject_array(virt_elem_som, virt_elem_som.size_array(), debut);
12125 + // Load virtual nodes
12126 + FloatTab tmp_nodes;
12127 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "SOMMETS", "*"), tmp_nodes, nodes_to_read);
12128 + // Copy to nodes_
12129 + debut = nodes_.size_array();
12130 + nodes_.resize(nodes_.dimension(0) + tmp_nodes.dimension(0),
12131 + nodes_.dimension(1));
12132 + nodes_.inject_array(tmp_nodes, tmp_nodes.size_array(), debut);
12135 + if (domain_has_faces) {
12136 + // Find which virtual faces are required and load them
12137 + // For each virtual element, index of its faces (like virt_elem_som)
12138 + IntTab virt_elem_faces;
12139 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "ELEM_FACES", "*"), virt_elem_faces, virt_elems);
12140 + // Build the list of missing faces:
12142 + ArrOfInt & virt_elem_faces_array = virt_elem_faces; // Array seen as monodimensionnal
12143 + array_sort_indirect(virt_elem_faces_array, index);
12144 + ArrOfInt faces_to_read;
12145 + faces_to_read.set_smart_resize(1);
12147 + const entier n = index.size_array();
12148 + // Global index of the last loaded face:
12149 + entier last_face = -1;
12150 + // Local index of the new loaded node:
12151 + entier new_face_index = faces_.dimension(0)-1;
12152 + for (entier i = 0; i < n; i++) {
12153 + // Take nodes to load in ascending order of their global numbers:
12154 + const entier idx = index[i];
12155 + const entier face = virt_elem_faces_array[idx];
12156 + if (face != last_face) {
12157 + // Node not yet encountered
12158 + faces_to_read.append_array(face);
12159 + new_face_index++;
12160 + last_face = face;
12162 + virt_elem_faces_array[idx] = new_face_index;
12165 + set_virt_items(LataField_base::FACES, faces_to_read);
12166 + // Copy virtual elem_faces to elem_faces
12167 + entier debut = elem_faces_.size_array();
12168 + elem_faces_.resize(elem_faces_.dimension(0) + virt_elem_faces.dimension(0),
12169 + elem_faces_.dimension(1));
12170 + elem_faces_.inject_array(virt_elem_faces, virt_elem_faces.size_array(), debut);
12172 + // Load virtual faces
12173 + IntTab tmp_faces_nodes;
12174 + lataDB.read_data(lataDB.get_field(id.timestep_, id.name_, "FACES", "*"), tmp_faces_nodes, faces_to_read);
12175 + // Convert global nodes indexes to local loaded nodes indexes in tmp_faces_nodes
12177 + // sort tmp_faces in ascending order so that the search requires linear time
12178 + ArrOfInt & array_tmp_faces_nodes = tmp_faces_nodes;
12180 + array_sort_indirect(array_tmp_faces_nodes, index);
12181 + const entier n = array_tmp_faces_nodes.size_array();
12182 + // Take nodes in tmp_faces_nodes in ascending order and find the corresponding node in nodes_to_read
12183 + // (which is also in sorted)
12184 + entier i1; // index in array_tmp_faces_nodes (the current node to convert)
12185 + entier i2 = 0; // index in nodes_to_read
12186 + const entier index_of_first_virtual_node = nodes_.dimension(0) - nb_virt_items(LataField_base::SOM);
12187 + const ArrOfInt & nodes_to_read = get_virt_items(LataField_base::SOM);
12188 + const entier max_i2 = nodes_to_read.size_array();
12189 + for (i1 = 0; i1 < n; i1++) {
12190 + const entier j = index[i1];
12191 + const entier global_node_index_to_find = array_tmp_faces_nodes[j];
12192 + // find the matching node in nodes_to_read (nodes_to_read is in ascending order)
12193 + while (nodes_to_read[i2] != global_node_index_to_find) {
12195 + if (i2 >= max_i2) {
12196 + cerr << "Internal error in DomainUnstructured::fill_domain_from_lataDB:\n"
12197 + << " node " << global_node_index_to_find << " of a virtual face does not belong to a virtual element" << endl;
12201 + array_tmp_faces_nodes[j] = index_of_first_virtual_node + i2; // index of this node in the local nodes_ array
12204 + // Copy to faces_ array
12205 + debut = faces_.size_array();
12206 + faces_.resize(faces_.dimension(0) + tmp_faces_nodes.dimension(0),
12207 + faces_.dimension(1));
12208 + faces_.inject_array(tmp_faces_nodes, tmp_faces_nodes.size_array(), debut);
12213 +void Domain::fill_field_from_lataDB(const LataDB & lataDB,
12214 + const Field_Id & id,
12215 + LataDeriv<LataField_base> & field) const
12217 + Journal() << "Error : fill_field_from_lataDB not coded for this domain type" << endl;
12221 +// Reads the requested field to "field" structure.
12222 +// id.block_ is not used, the data block read is the same as the domain.
12223 +void DomainUnstructured::fill_field_from_lataDB(const LataDB & lataDB,
12224 + const Field_Id & id,
12225 + LataDeriv<LataField_base> & field) const
12227 + const LataDBField & lata_field = lataDB.get_field(id.timestep_, id.uname_);
12228 + LataField_base::Elem_som loc = LataField_base::localisation_from_string(lata_field.localisation_);
12229 + const entier decal = lata_block_offset(loc);
12231 + const ArrOfInt & virt_items = get_virt_items(loc);
12232 + const entier virt_size = virt_items.size_array();
12233 + const entier size = nb_items(loc) - virt_size;
12235 + const LataDBDataType & type = lata_field.datatype_;
12236 + switch(type.type_) {
12237 + case LataDBDataType::REAL32: {
12238 + FloatTab & data = field.instancie(Field<FloatTab> ).data_;
12239 + lataDB.read_data(lata_field, data, decal, size);
12240 + if (virt_size > 0) {
12242 + lataDB.read_data(lata_field, tmp, virt_items);
12243 + const entier debut = data.size_array();
12244 + data.resize(data.dimension(0)+virt_size, data.dimension(1));
12245 + data.inject_array(tmp, virt_size, debut);
12249 + case LataDBDataType::REAL64: {
12250 + DoubleTab & data = field.instancie(Field<DoubleTab> ).data_;
12251 + lataDB.read_data(lata_field, data, decal, size);
12252 + if (virt_size > 0) {
12254 + lataDB.read_data(lata_field, tmp, virt_items);
12255 + const entier debut = data.size_array();
12256 + data.resize(data.dimension(0)+virt_size, data.dimension(1));
12257 + data.inject_array(tmp, virt_size, debut);
12261 + case LataDBDataType::INT32:
12262 + case LataDBDataType::INT64: {
12263 + IntTab & data = field.instancie(Field<IntTab> ).data_;
12264 + lataDB.read_data(lata_field, data, decal, size);
12265 + if (virt_size > 0) {
12267 + lataDB.read_data(lata_field, tmp, virt_items);
12268 + const entier debut = data.size_array();
12269 + data.resize(data.dimension(0)+virt_size, data.dimension(1));
12270 + data.inject_array(tmp, virt_size, debut);
12275 + Journal() << "LataFilter::get_field_from_lataDB " << id.uname_ << ": data type not implemented" << endl;
12278 + field.valeur().id_ = id;
12279 + field.valeur().component_names_ = lata_field.component_names_;
12280 + field.valeur().localisation_ = loc;
12281 + field.valeur().nature_ = lata_field.nature_;
12284 +DomainIJK::DomainIJK()
12288 + virtual_layer_begin_ = 0;
12289 + virtual_layer_end_ = 0;
12292 +void DomainIJK::fill_domain_from_lataDB(const LataDB & lataDB,
12293 + const Domain_Id & id,
12294 + entier split_in_N_parts,
12295 + const entier virt_layer_size)
12297 + if (virt_layer_size < 0) {
12298 + Journal() << "Error in DomainIJK::fill_domain_from_lataDB: virt_layer_size < 0" << endl;
12303 + Journal(info_level) << "Filling ijk domain " << id.name_ << " tstep " << id.timestep_ << " block " << id.block_ << endl;
12305 + entier dim3 = lataDB.field_exists(id.timestep_, id.name_, "SOMMETS_IJK_K", LataDB::FIRST_AND_CURRENT /* timestep */);
12307 + const LataDBField & coord = lataDB.get_field(id.timestep_,
12308 + Field_UName(id.name_, "SOMMETS_IJK_I", ""),
12309 + LataDB::FIRST_AND_CURRENT /* timestep */);
12311 + lataDB.read_data(coord, tmp);
12316 + const LataDBField & coord = lataDB.get_field(id.timestep_,
12317 + Field_UName(id.name_, "SOMMETS_IJK_J", ""),
12318 + LataDB::FIRST_AND_CURRENT /* timestep */);
12320 + lataDB.read_data(coord, tmp);
12325 + const LataDBField & coord = lataDB.get_field(id.timestep_,
12326 + Field_UName(id.name_, "SOMMETS_IJK_K", ""),
12327 + LataDB::FIRST_AND_CURRENT /* timestep */);
12329 + lataDB.read_data(coord, tmp);
12334 + elt_type_ = dim3 ? hexa : quadri;
12336 + entier block = (id.block_) < 0 ? 0 : id.block_;
12338 + if (id.block_ >= split_in_N_parts) {
12339 + Journal() << "Error in DomainIJK::fill_domain_from_lataDB: invalid block " << id.block_ << endl;
12343 + // Load the N-th part
12344 + // The ijk domain is virtually split in the Z direction (or Y en 2D)
12345 + entier maxdim = coord_.size() - 1;
12346 + // Number of elements in the Z direction:
12347 + const entier nelem = coord_[maxdim].size_array() - 1;
12348 + entier part_size = nelem / split_in_N_parts;
12349 + if (part_size * split_in_N_parts < nelem)
12352 + // Begin and end of the requested part:
12353 + part_begin_ = part_size * block - virt_layer_size;
12354 + if (part_begin_ < 0)
12356 + part_end_ = part_size * block + part_size + virt_layer_size;
12357 + if (part_end_ > nelem)
12358 + part_end_ = nelem;
12359 + if (part_begin_ > part_end_)
12361 + part_begin_ = part_end_ = 0;
12363 + if (block > 0 && part_end_ > part_begin_)
12364 + // There is a virtual layer at the begin
12365 + virtual_layer_begin_ = virt_layer_size;
12366 + if (block < split_in_N_parts-1 && part_end_ > part_begin_)
12367 + virtual_layer_end_ = virt_layer_size;
12369 + // Extract coordinates:
12370 + ArrOfFloat tmp(coord_[maxdim]);
12371 + const entier n = part_end_ - part_begin_ + 1;
12372 + coord_[maxdim].resize_array(n);
12373 + for (entier i = 0; i < n; i++)
12374 + coord_[maxdim][i] = tmp[i + part_begin_];
12376 + Journal(info_level) << "Domain " << id.name_ << " has number of nodes: [ ";
12377 + for (entier dim = 0; dim < coord_.size(); dim++)
12378 + Journal(info_level) << coord_[dim].size_array() << " ";
12379 + Journal(info_level) << "]" << endl;
12381 + if (part_end_ > part_begin_ // part might be empty if too many processors
12382 + && lataDB.field_exists(id.timestep_, id.name_, "INVALID_CONNECTIONS", LataDB::FIRST_AND_CURRENT /* timestep */))
12384 + Journal(info_level) << " loading invalid_connections" << endl;
12386 + entier ij = 0, offset = 0, sz = 0;
12387 + // Product of number of elements in directions I and J
12388 + ij = coord_[0].size_array() - 1;
12389 + if (coord_.size() > 2)
12390 + ij *= coord_[1].size_array() - 1;
12391 + // Select a range of elements in direction K
12392 + offset = ij * part_begin_;
12393 + sz = nb_elements();
12394 + const LataDBField & lata_field = lataDB.get_field(id.timestep_, id.name_, "INVALID_CONNECTIONS", "ELEM",
12395 + LataDB::FIRST_AND_CURRENT);
12397 + lataDB.read_data(lata_field, Itmp, offset, sz);
12399 + invalid_connections_.resize_array(nb_elements());
12400 + invalid_connections_ = 0; // everything valid by default
12402 + for (entier i = 0; i < sz; i++) {
12403 + if (Itmp(i, 0) != 0)
12404 + invalid_connections_.setbit(i);
12409 +void DomainIJK::fill_field_from_lataDB(const LataDB & lataDB,
12410 + const Field_Id & id,
12411 + LataDeriv<LataField_base> & field) const
12413 + const LataDBField & lata_field = lataDB.get_field(id.timestep_, id.uname_);
12414 + LataField_base::Elem_som loc = LataField_base::localisation_from_string(lata_field.localisation_);
12416 + entier ij = 0, offset = 0, sz = 0;
12418 + case LataField_base::ELEM:
12419 + // Product of number of elements in directions I and J
12420 + ij = coord_[0].size_array() - 1;
12421 + if (coord_.size() > 2)
12422 + ij *= coord_[1].size_array() - 1;
12423 + // Select a range of elements in direction K
12424 + offset = ij * part_begin_;
12425 + sz = ij * (part_end_ - part_begin_);
12427 + case LataField_base::SOM:
12428 + case LataField_base::FACES:
12429 + // Product of number of nodes in directions I and J
12430 + ij = coord_[0].size_array();
12431 + if (coord_.size() > 2)
12432 + ij *= coord_[1].size_array();
12433 + offset = ij * part_begin_;
12434 + sz = ij * (part_end_ + 1 - part_begin_);
12437 + Journal() << "Error in DomainIJK::fill_field_from_lataDB: unknown localisation" << endl;
12441 + const LataDBDataType & type = lata_field.datatype_;
12442 + switch(type.type_) {
12443 + case LataDBDataType::REAL32: {
12444 + FloatTab & data = field.instancie(Field<FloatTab> ).data_;
12445 + lataDB.read_data(lata_field, data, offset, sz);
12448 + case LataDBDataType::REAL64: {
12449 + DoubleTab & data = field.instancie(Field<DoubleTab> ).data_;
12450 + lataDB.read_data(lata_field, data, offset, sz);
12453 + case LataDBDataType::INT32:
12454 + case LataDBDataType::INT64: {
12455 + IntTab & data = field.instancie(Field<IntTab> ).data_;
12456 + lataDB.read_data(lata_field, data, offset, sz);
12460 + Journal() << "LataFilter::get_field_from_lataDB " << id.uname_ << ": data type not implemented" << endl;
12463 + field.valeur().id_ = id;
12464 + field.valeur().component_names_ = lata_field.component_names_;
12465 + field.valeur().localisation_ = loc;
12466 + field.valeur().nature_ = lata_field.nature_;
12470 +Domain::DomainType Domain::get_domain_type() const
12472 + const DomainUnstructured* geom_ptr = dynamic_cast<const DomainUnstructured*>(this);
12474 + return UNSTRUCTURED;
12475 + const DomainIJK* ijk_ptr = dynamic_cast<const DomainIJK*>(this);
12478 + throw ("Not implemeneted");
12480 +const DomainUnstructured & Domain::cast_DomainUnstructured() const
12482 + return dynamic_cast<const DomainUnstructured&>(*this);
12484 +const DomainIJK & Domain::cast_DomainIJK() const
12486 + return dynamic_cast<const DomainIJK&>(*this);
12488 diff --git a/databases/readers/Lata/LataStructures.h b/databases/readers/Lata/LataStructures.h
12489 new file mode 100644
12490 index 0000000..74fa765
12492 +++ b/databases/readers/Lata/LataStructures.h
12494 +/*****************************************************************************
12496 +* Copyright (c) 2011 - 2013, CEA
12497 +* All rights reserved.
12498 +* Redistribution and use in source and binary forms, with or without
12499 +* modification, are permitted provided that the following conditions are met:
12501 +* * Redistributions of source code must retain the above copyright
12502 +* notice, this list of conditions and the following disclaimer.
12503 +* * Redistributions in binary form must reproduce the above copyright
12504 +* notice, this list of conditions and the following disclaimer in the
12505 +* documentation and/or other materials provided with the distribution.
12506 +* * Neither the name of CEA, nor the
12507 +* names of its contributors may be used to endorse or promote products
12508 +* derived from this software without specific prior written permission.
12510 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
12511 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12512 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12513 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
12514 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12515 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12516 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12517 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12518 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12519 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12521 +*****************************************************************************/
12523 +#ifndef LataStructures_H
12524 +#define LataStructures_H
12526 +#include <ArrOfBit.h>
12527 +#include <Lata_tools.h>
12528 +#include <LataDB.h>
12530 +// This file contains definitions of data structures containind meshes and fields
12531 +// used by LataFilter.
12533 +// Description: Domain_Id is what you need to identify the content
12534 +// of a Domain object (at this time, the domain name, the timestep and the
12535 +// parallel sub_block number)
12539 + Domain_Id(const char * name = "??", int t = 0, int block = -1) :
12540 + name_(name), timestep_(t), block_(block) {};
12543 + // At which timestep (needed for dynamic domains)
12545 + // Which block of the parallel computation ? -1 => all blocks
12549 +// Description: Field_Id is what you need to identify the content of a
12550 +// LataField_base structure (at this time, the field uname,
12551 +// the timestep and the parallel sub_block number)
12555 + Field_Id() : timestep_(0) {};
12556 + Field_Id(const Field_UName & uname, int timestep, int block) :
12557 + timestep_(timestep), block_(block), uname_(uname) {};
12561 + Field_UName uname_;
12563 + operator Domain_Id() const { return Domain_Id(uname_.get_geometry(), timestep_, block_); }
12566 +// Description: This structure contains a discrete data array for a specific
12567 +// field, at one timestep, for one sub_block of the geometry, with
12568 +// one localisation (but many components)
12569 +class LataField_base : public LataObject
12572 + LataField_base() { localisation_ = UNKNOWN; nature_ = LataDBField::UNKNOWN; }
12574 + Noms component_names_;
12575 + enum Elem_som { ELEM, SOM, FACES, UNKNOWN };
12576 + Elem_som localisation_;
12577 + LataDBField::Nature nature_;
12579 + static Elem_som localisation_from_string(const Motcle &);
12580 + static Nom localisation_to_string(const Elem_som);
12582 +class DomainUnstructured;
12585 +// This class stores the geometry of a domain
12586 +class Domain : public LataObject
12590 + enum Element { point, line, triangle, quadri, tetra, hexa, prism6, polyedre, polygone, unspecified };
12591 + enum DomainType { IJK, UNSTRUCTURED };
12592 + static Element element_type_from_string(const Motcle & type_elem);
12593 + static Nom element_type_to_string(Element type);
12594 + Element elt_type_;
12597 + elt_type_(unspecified),
12598 + decal_nodes_lata_(-1), // -1 indicates: value not set. see lata_block_offset
12599 + decal_elements_lata_(-1),
12600 + decal_faces_lata_(-1) {};
12601 + DomainType get_domain_type() const;
12602 + const DomainUnstructured & cast_DomainUnstructured() const;
12603 + const DomainIJK & cast_DomainIJK() const;
12604 + virtual entier dimension() const = 0;
12605 + virtual entier nb_nodes() const = 0;
12606 + virtual entier nb_elements() const = 0;
12607 + virtual entier nb_faces() const = 0;
12608 + virtual entier nb_items(const LataField_base::Elem_som) const;
12609 + virtual entier lata_block_offset(const LataField_base::Elem_som) const;
12610 + virtual void set_lata_block_offset(const LataField_base::Elem_som, entier n);
12612 + virtual void fill_field_from_lataDB(const LataDB & lataDB,
12613 + const Field_Id & id,
12614 + LataDeriv<LataField_base> & field) const = 0;
12616 + static Motcle lata_element_name(Domain::Element type);
12619 + // If the Domain has been loaded from a lata file and it's not the
12620 + // first block this is the offset in the lata file:
12621 + entier decal_nodes_lata_;
12622 + entier decal_elements_lata_;
12623 + entier decal_faces_lata_;
12626 +class DomainUnstructured : public Domain
12629 + DomainUnstructured() { nb_virt_nodes_ = 0; nb_virt_elements_ = 0; nb_virt_faces_ = 0; }
12632 + // For each element, indexes of the nodes (first node is at index 0)
12633 + // Nodes ordering in an element is the same as in TRUST
12634 + IntTab elements_;
12635 + // For each face, indexes of the nodes (if present in lata file)
12637 + // For each elements, indexes of the faces (first face at index 0, if present in lata file)
12638 + // Faces ordering in an element is the same as in TRUST
12639 + IntTab elem_faces_;
12641 + entier dimension() const { return nodes_.dimension(1); }
12642 + entier nb_nodes() const { return nodes_.dimension(0); }
12643 + entier nb_elements() const { return elements_.dimension(0); }
12644 + entier nb_faces() const { return faces_.dimension(0); }
12645 + // Tests if the geometry contains faces description
12646 + entier faces_ok() const { return elem_faces_.dimension(0) == elements_.dimension(0); }
12647 + template<class TabType>
12648 + void compute_cell_center_coordinates(TabType & coord, entier index_begin) const;
12649 + BigEntier compute_memory_size() const
12651 + memory_size(nodes_)
12652 + + memory_size(elements_)
12653 + + memory_size(faces_)
12654 + + memory_size(elem_faces_);
12656 + const IntTab & get_joints(LataField_base::Elem_som loc) const {
12657 + const IntTab * ptr = 0;
12659 + case LataField_base::SOM: ptr = &joints_sommets_; break;
12660 + case LataField_base::ELEM: ptr = &joints_elements_; break;
12661 + case LataField_base::FACES: ptr = &joints_faces_; break;
12664 + if (ptr->dimension(1) == 0) throw;
12667 + IntTab & set_joints(LataField_base::Elem_som loc) {
12668 + IntTab * ptr = 0;
12670 + case LataField_base::SOM: ptr = &joints_sommets_; break;
12671 + case LataField_base::ELEM: ptr = &joints_elements_; break;
12672 + case LataField_base::FACES: ptr = &joints_faces_; break;
12677 + const ArrOfInt & get_virt_items(LataField_base::Elem_som loc) const {
12679 + case LataField_base::SOM: return virt_nodes_; break;
12680 + case LataField_base::ELEM: return virt_elements_; break;
12681 + case LataField_base::FACES: return virt_faces_; break;
12684 + return virt_nodes_;
12686 + void set_virt_items(LataField_base::Elem_som loc, const ArrOfInt & list) {
12688 + case LataField_base::SOM: virt_nodes_ = list; nb_virt_nodes_ = list.size_array(); break;
12689 + case LataField_base::ELEM: virt_elements_ = list; nb_virt_elements_ = list.size_array(); break;
12690 + case LataField_base::FACES: virt_faces_ = list; nb_virt_faces_ = list.size_array(); break;
12694 + void set_nb_virt_items(LataField_base::Elem_som loc, entier n) {
12696 + case LataField_base::SOM: nb_virt_nodes_ = n; break;
12697 + case LataField_base::ELEM: nb_virt_elements_ = n; break;
12698 + case LataField_base::FACES: nb_virt_faces_ = n; break;
12702 + entier nb_virt_items(LataField_base::Elem_som loc) const {
12704 + case LataField_base::SOM: return nb_virt_nodes_; break;
12705 + case LataField_base::ELEM: return nb_virt_elements_; break;
12706 + case LataField_base::FACES: return nb_virt_faces_; break;
12709 + return nb_virt_nodes_;
12712 + virtual void fill_domain_from_lataDB(const LataDB & lataDB,
12713 + const Domain_Id & id,
12714 + entier load_faces = 1,
12715 + entier merge_virtual_elements = 0);
12716 + virtual void fill_field_from_lataDB(const LataDB & lataDB,
12717 + const Field_Id & id,
12718 + LataDeriv<LataField_base> & field) const;
12721 + // data not always filled:
12722 + IntTab joints_sommets_;
12723 + IntTab joints_elements_;
12724 + IntTab joints_faces_;
12725 + ArrOfInt virt_nodes_; // Global indexes of virtual nodes to load
12726 + ArrOfInt virt_elements_; // Global indexes of virtual elements to load
12727 + ArrOfInt virt_faces_; // Global indexes of virtual faces to load
12728 + entier nb_virt_nodes_;
12729 + entier nb_virt_elements_;
12730 + entier nb_virt_faces_;
12733 +// This is a structured grid, grid axes aligned on X, Y and Z.
12734 +// The grid can have "invalid_positions_" and "invalid_connections_".
12735 +// Nodes are numbered like this:
12736 +// node_index(i,j,k) = (k * nb_nodes_y + j) * nb_nodes_x + i
12737 +// Elements are numbered like this:
12738 +// element_index(i,j,k) = (k * nb_elements_y + j) * nb_elements_x + i
12739 +// Faces are numbered like this: faces of each direction have a numbering starting at zero.
12740 +// The number of a particular face is the smallest number of its nodes.
12741 +// Hence some numbers are not used (le last face of each "row" depending on the
12743 +class DomainIJK : public Domain
12747 + // In each spatial direction, ordered list of coordinates of the IJK grid
12748 + LataVector<ArrOfFloat> coord_;
12750 + // For each node and each element, flag indicates if it is valid or not
12751 + // (eg, has usable field values)
12752 + // If array is empty, all data is valid.
12753 + ArrOfBit invalid_positions_;
12754 + ArrOfBit invalid_connections_;
12756 + entier dimension() const { return coord_.size(); }
12757 + entier nb_nodes() const {
12758 + entier n = 1, d = coord_.size();
12759 + for (entier i=0; i<d; i++)
12760 + n *= coord_[i].size_array();
12763 + entier nb_elements() const {
12764 + entier n = 1, d = coord_.size();
12765 + for (entier i=0; i<d; i++)
12766 + n *= coord_[i].size_array()-1;
12769 + // Dimension(0) des tableaux de valeurs aux faces
12770 + // (voir convention sur la numerotation des faces)
12771 + // les champs associes aux faces des differentes directions sont
12772 + // stockes dans les composantes du champ.
12773 + entier nb_faces() const { return nb_nodes(); }
12774 + BigEntier compute_memory_size() const
12777 + const entier n = coord_.size();
12778 + for (entier i = 0; i < n; i++)
12779 + x += memory_size(coord_[i]);
12780 + return x + memory_size(invalid_positions_) + memory_size(invalid_connections_);
12783 + // renvoie le nombre de sommets dans la direction dir
12784 + // (renvoie 1 si dir >= dimension())
12785 + entier nb_som_dir(entier dir) const {
12786 + if (dir >= dimension())
12789 + return coord_[dir].size_array();
12791 + // renvoie le nombre d'elements dans la direction dir
12792 + // (renvoie 1 si dir >= dimension())
12793 + entier nb_elem_dir(entier dir) const {
12794 + if (dir >= dimension())
12797 + return coord_[dir].size_array() - 1;
12800 + virtual void fill_domain_from_lataDB(const LataDB & lataDB,
12801 + const Domain_Id & id,
12802 + const entier split_in_nparts = 1,
12803 + const entier virt_layer_size = 1);
12804 + virtual void fill_field_from_lataDB(const LataDB & lataDB,
12805 + const Field_Id & id,
12806 + LataDeriv<LataField_base> & field) const;
12808 + // when loading fields, we will load elements (i,j,k) with
12809 + // part_begin_ <= k < part_end_
12810 + // (or j in 2D), part_begin_ and part_end_ include the virtual layer
12811 + entier part_begin_;
12812 + entier part_end_;
12813 + // number of layers of virtual elements at each side:
12814 + entier virtual_layer_begin_;
12815 + entier virtual_layer_end_;
12818 +template <class TabType>
12819 +class Field : public LataField_base
12823 + BigEntier compute_memory_size() const { return memory_size(data_); }
12826 diff --git a/databases/readers/Lata/LataV1_field_definitions.C b/databases/readers/Lata/LataV1_field_definitions.C
12827 new file mode 100644
12828 index 0000000..7bb0e2f
12830 +++ b/databases/readers/Lata/LataV1_field_definitions.C
12832 +/*****************************************************************************
12834 +* Copyright (c) 2011 - 2013, CEA
12835 +* All rights reserved.
12836 +* Redistribution and use in source and binary forms, with or without
12837 +* modification, are permitted provided that the following conditions are met:
12839 +* * Redistributions of source code must retain the above copyright
12840 +* notice, this list of conditions and the following disclaimer.
12841 +* * Redistributions in binary form must reproduce the above copyright
12842 +* notice, this list of conditions and the following disclaimer in the
12843 +* documentation and/or other materials provided with the distribution.
12844 +* * Neither the name of CEA, nor the
12845 +* names of its contributors may be used to endorse or promote products
12846 +* derived from this software without specific prior written permission.
12848 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
12849 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12850 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12851 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
12852 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12853 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12854 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12855 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12856 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12857 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12859 +*****************************************************************************/
12861 +#include <LataV1_field_definitions.h>
12862 +#include <Motcle.h>
12865 + const char * name;
12866 + int shape; // Vector size (-1 => dimension of the problem)
12869 +// COMPOSANTES EN MAJUSCULES !!!!!
12870 +// Components are checked in the same order than this array.
12871 +// We assume that the component has been found if component
12872 +// name begins with the string in this array. For example
12873 +// if the lata file contains INDICATRICE_INTERF, we will
12874 +// find that it is an "INDICATRICE" component.
12875 +// Therefore, long names must be placed before short names:
12876 +// If we have a component "K" and a component "K_EPS", then
12877 +// "K_EPS" must be placed before "K", otherwise "K_EPS" will
12878 +// never be found.
12879 +const StdComponents std_components[] =
12881 + { "VITESSE", -1 },
12882 + { "primal", -1 },
12883 + { "VORTICITE", -2 },
12884 + { "MOYENNE_VITESSE", -1 },
12885 + { "ECART_TYPE_VITESSE", -1 },
12886 + { "MOYENNE_VORTICITE", -2 },
12887 + { "ECART_TYPE_VORTICITE", -2 },
12888 + { "GRADIENT_PRESSION", -1 },
12889 + { "DERIVEE_U_ETOILE", -1 },
12890 + { "TERME_DIFFUSION_VITESSE", -1 },
12891 + { "TERME_CONVECTION_VITESSE", -1 },
12892 + { "TERME_SOURCE_VITESSE", -1 },
12894 + { "NORMALE_INTERFACE", -1 },
12896 + { "ACCELERATION", -1 },
12897 + { "CHAMP_VECTORIEL", -1},
12903 + // Empty label means end of the table
12906 +int latav1_component_shape(const Motcle & compo)
12909 + while (std_components[i].name[0] != 0) {
12910 + if (compo.debute_par(std_components[i].name))
12911 + return std_components[i].shape;
12916 diff --git a/databases/readers/Lata/LataV1_field_definitions.h b/databases/readers/Lata/LataV1_field_definitions.h
12917 new file mode 100644
12918 index 0000000..8aaca6a
12920 +++ b/databases/readers/Lata/LataV1_field_definitions.h
12922 +/*****************************************************************************
12924 +* Copyright (c) 2011 - 2013, CEA
12925 +* All rights reserved.
12926 +* Redistribution and use in source and binary forms, with or without
12927 +* modification, are permitted provided that the following conditions are met:
12929 +* * Redistributions of source code must retain the above copyright
12930 +* notice, this list of conditions and the following disclaimer.
12931 +* * Redistributions in binary form must reproduce the above copyright
12932 +* notice, this list of conditions and the following disclaimer in the
12933 +* documentation and/or other materials provided with the distribution.
12934 +* * Neither the name of CEA, nor the
12935 +* names of its contributors may be used to endorse or promote products
12936 +* derived from this software without specific prior written permission.
12938 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
12939 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12940 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12941 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
12942 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12943 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12944 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12945 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12946 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12947 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12949 +*****************************************************************************/
12951 +// This file is included in LataDB.cpp (and only there)
12952 +// It contains fields definitions for the old LataV1 format
12953 +// (separated from LataDB.cpp so that changes in this file are
12954 +// easily identified)
12956 +int latav1_component_shape(const Motcle & compo);
12957 diff --git a/databases/readers/Lata/LataVector.h b/databases/readers/Lata/LataVector.h
12958 new file mode 100644
12959 index 0000000..18e46f6
12961 +++ b/databases/readers/Lata/LataVector.h
12963 +/*****************************************************************************
12965 +* Copyright (c) 2011 - 2013, CEA
12966 +* All rights reserved.
12967 +* Redistribution and use in source and binary forms, with or without
12968 +* modification, are permitted provided that the following conditions are met:
12970 +* * Redistributions of source code must retain the above copyright
12971 +* notice, this list of conditions and the following disclaimer.
12972 +* * Redistributions in binary form must reproduce the above copyright
12973 +* notice, this list of conditions and the following disclaimer in the
12974 +* documentation and/or other materials provided with the distribution.
12975 +* * Neither the name of CEA, nor the
12976 +* names of its contributors may be used to endorse or promote products
12977 +* derived from this software without specific prior written permission.
12979 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
12980 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12981 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12982 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
12983 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12984 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12985 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12986 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12987 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12988 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12990 +*****************************************************************************/
12992 +#ifndef LataVector_H
12993 +#define LataVector_H
12994 +#include <assert.h>
12996 +// This vector class uses an array of pointers so that objects stored are never
12997 +// moved in memory when the array is resized.
12998 +template <class C>
13002 + LataVector() : n_(0), data_(0) { }
13003 + LataVector(const LataVector<C> & x) : n_(0), data_(0) { operator=(x); }
13004 + LataVector(entier n) : n_(0), data_(0) { for (entier i=0; i<n; i++) add(); }
13005 + ~LataVector() { reset(); }
13006 + void reset() { for (int i=0; i<n_; i++) { delete data_[i]; }; delete[] data_; n_ = 0; data_ = 0; }
13007 + const C & operator[](entier i) const { assert(i>=0 && i<n_); return *(data_[i]); }
13008 + C & operator[](entier i) { assert(i>=0 && i<n_); return *(data_[i]); }
13009 + C & add(const C & item) { return add_item(new C(item)); }
13010 + C & add() { return add_item(new C); }
13011 + entier size() const { return n_; }
13012 + entier rang(const C & c) const { for (entier i = 0; i < n_; i++) if (*(data_[i]) == c) return i; return -1; }
13013 + LataVector<C> & operator=(const LataVector<C> & x) { reset(); for (int i=0; i<x.n_; i++) add(x[i]); return *this; }
13015 + C & add_item(C* added_item) {
13017 + data_ = new C*[n_+1];
13018 + for (int i=0; i<n_; i++) data_[i] = old[i];
13020 + data_[n_++] = added_item;
13021 + return *added_item;
13027 diff --git a/databases/readers/Lata/LataWriter.C b/databases/readers/Lata/LataWriter.C
13028 new file mode 100644
13029 index 0000000..3387570
13031 +++ b/databases/readers/Lata/LataWriter.C
13033 +/*****************************************************************************
13035 +* Copyright (c) 2011 - 2013, CEA
13036 +* All rights reserved.
13037 +* Redistribution and use in source and binary forms, with or without
13038 +* modification, are permitted provided that the following conditions are met:
13040 +* * Redistributions of source code must retain the above copyright
13041 +* notice, this list of conditions and the following disclaimer.
13042 +* * Redistributions in binary form must reproduce the above copyright
13043 +* notice, this list of conditions and the following disclaimer in the
13044 +* documentation and/or other materials provided with the distribution.
13045 +* * Neither the name of CEA, nor the
13046 +* names of its contributors may be used to endorse or promote products
13047 +* derived from this software without specific prior written permission.
13049 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
13050 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13051 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13052 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
13053 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13054 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13055 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13056 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13057 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13058 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13060 +*****************************************************************************/
13062 +#include <LataWriter.h>
13063 +#include <LataStructures.h>
13065 +// Path, if not empty, must include a trailing '/'
13066 +// basename must not include the .lata extension
13067 +void LataWriter::init_file(const Nom & path, const Nom & basename,
13068 + const LataDBDataType & default_int_format,
13069 + LataDBDataType::Type default_float_type)
13072 + db_.set_path_prefix(path);
13073 + basename_ = basename;
13074 + db_.default_type_int_ = default_int_format;
13075 + db_.default_float_type_ = default_float_type;
13076 + db_.header_ = "Lata V2";
13077 + db_.case_ = "lata2dx";
13078 + db_.software_id_ = "Trio_U";
13079 + //split_ = split;
13081 + // Global geometries and fields:
13082 + db_.add_timestep(0.);
13085 +// Add a new timestep to the lata database (new TEMPS entry)
13086 +// Geometries and fields are always written in the last added timestep
13087 +// (the timestep stored within the domain or field is ignored)
13088 +// Those written before the first call to write_time() go into global
13089 +// fields and geometry definitions.
13090 +void LataWriter::write_time(double t)
13092 + db_.add_timestep(t);
13095 +void LataWriter::write_geometry(const Domain & dom)
13097 + // Index of the last timestep:
13098 + const entier tstep = db_.nb_timesteps() - 1;
13100 + // Build a geometry database entry and add it to database
13101 + LataDBGeometry geom;
13102 + geom.name_ = dom.id_.name_;
13103 + geom.elem_type_ = dom.element_type_to_string(dom.elt_type_);
13104 + geom.timestep_ = tstep;
13105 + db_.add_geometry(geom);
13107 + // Write geometry data
13108 + const DomainUnstructured * dom1_ptr = dynamic_cast<const DomainUnstructured*>(&dom);
13109 + const DomainIJK * dom2_ptr = dynamic_cast<const DomainIJK*>(&dom);
13113 + // For unstructured meshes, we write the following fields:
13117 + // [ ELEM_FACES ]
13118 + const DomainUnstructured & domain = *dom1_ptr;
13119 + LataDBField field;
13121 + Nom fieldname = "SOMMETS";
13122 + field.uname_ = Field_UName(geom.name_, fieldname, "" /* localisation */);
13123 + field.name_ = fieldname;
13124 + field.timestep_ = tstep;
13126 + field.filename_ = basename_;
13127 + field.filename_ += ".lata.";
13128 + field.filename_ += fieldname;
13129 + field.filename_ += ".";
13130 + field.filename_ += geom.name_;
13132 + field.filename_ += ".";
13133 + field.filename_ += Nom(tstep);
13135 + field.nb_comp_ = domain.dimension();
13136 + field.geometry_ = geom.name_;
13137 + field.datatype_ = db_.default_type_float();
13138 + field.localisation_ = "";
13139 + field.reference_ = "";
13140 + field.size_ = domain.nb_nodes();
13142 + db_.add_field(field);
13143 + db_.write_data(tstep, field.uname_, domain.nodes_);
13145 + // Write elements
13146 + fieldname = "ELEMENTS";
13147 + field.uname_ = Field_UName(geom.name_, fieldname, "" /* localisation */);
13148 + field.name_ = fieldname;
13149 + field.timestep_ = tstep;
13151 + field.filename_ = basename_;
13152 + field.filename_ += ".lata.";
13153 + field.filename_ += fieldname;
13154 + field.filename_ += ".";
13155 + field.filename_ += geom.name_;
13157 + field.filename_ += ".";
13158 + field.filename_ += Nom(tstep);
13160 + field.nb_comp_ = domain.elements_.dimension(1);
13161 + field.geometry_ = geom.name_;
13162 + field.datatype_ = db_.default_type_int_;
13163 + field.localisation_ = "";
13164 + field.reference_ = "SOMMETS";
13165 + field.size_ = domain.nb_elements();
13167 + db_.add_field(field);
13168 + db_.write_data(tstep, field.uname_, domain.elements_);
13171 + if (domain.faces_ok()) {
13172 + fieldname = "FACES";
13173 + field.uname_ = Field_UName(geom.name_, fieldname, "" /* localisation */);
13174 + field.name_ = fieldname;
13175 + field.timestep_ = tstep;
13177 + field.filename_ = basename_;
13178 + field.filename_ += ".lata.";
13179 + field.filename_ += fieldname;
13180 + field.filename_ += ".";
13181 + field.filename_ += geom.name_;
13183 + field.filename_ += ".";
13184 + field.filename_ += Nom(tstep);
13186 + field.nb_comp_ = domain.faces_.dimension(1);
13187 + field.geometry_ = geom.name_;
13188 + field.datatype_ = db_.default_type_int_;
13189 + field.localisation_ = "";
13190 + field.reference_ = "SOMMETS";
13191 + field.size_ = domain.nb_faces();
13193 + db_.add_field(field);
13194 + db_.write_data(tstep, field.uname_, domain.faces_);
13196 + fieldname = "ELEM_FACES";
13197 + field.uname_ = Field_UName(geom.name_, fieldname, "" /* localisation */);
13198 + field.name_ = fieldname;
13199 + field.timestep_ = tstep;
13201 + field.filename_ = basename_;
13202 + field.filename_ += ".lata.";
13203 + field.filename_ += fieldname;
13204 + field.filename_ += ".";
13205 + field.filename_ += geom.name_;
13207 + field.filename_ += ".";
13208 + field.filename_ += Nom(tstep);
13210 + field.nb_comp_ = domain.elem_faces_.dimension(1);
13211 + field.geometry_ = geom.name_;
13212 + field.datatype_ = db_.default_type_int_;
13213 + field.localisation_ = "";
13214 + field.reference_ = "FACES";
13215 + field.size_ = domain.nb_elements();
13217 + db_.add_field(field);
13218 + db_.write_data(tstep, field.uname_, domain.elem_faces_);
13221 + else if (dom2_ptr)
13223 + // For IJK we write 2 or 3 fields containing 1-dimensionnal arrays with
13224 + // the nodes coordinates in each direction:
13225 + // SOMMETS_IJK_I, SOMMETS_IJK_J, SOMMETS_IJK_K.
13227 + const DomainIJK & domain = *dom2_ptr;
13228 + // Write coordinates
13229 + const entier dim = domain.coord_.size();
13231 + Journal() << "Error in LataWriter::write_geometry: dimension > 3" << endl;
13232 + throw InternalError;
13234 + Noms dir_names(3);
13235 + dir_names[0] = "I";
13236 + dir_names[1] = "J";
13237 + dir_names[2] = "K";
13238 + for (entier i_dim = 0; i_dim < dim; i_dim++) {
13241 + const ArrOfFloat & x = domain.coord_[i_dim];
13242 + const entier n = x.size_array();
13243 + coord.resize(n, 1);
13244 + for (entier i = 0; i < n; i++)
13245 + coord(i, 0) = x[i];
13248 + Nom fieldname = "SOMMETS_IJK_";
13249 + fieldname += dir_names[i_dim];
13250 + LataDBField field;
13251 + field.uname_ = Field_UName(geom.name_, fieldname, "" /* localisation */);
13252 + field.name_ = fieldname;
13253 + field.timestep_ = tstep;
13255 + field.filename_ = basename_;
13256 + field.filename_ += ".lata.";
13257 + field.filename_ += fieldname;
13258 + field.filename_ += ".";
13259 + field.filename_ += geom.name_;
13261 + field.filename_ += ".";
13262 + field.filename_ += Nom(tstep);
13264 + field.nb_comp_ = 1;
13265 + field.geometry_ = geom.name_;
13266 + field.datatype_ = db_.default_type_float();
13267 + field.localisation_ = "";
13268 + field.reference_ = "";
13269 + field.size_ = coord.dimension(0);
13271 + db_.add_field(field);
13272 + db_.write_data(tstep, field.uname_, coord);
13275 + if (domain.invalid_connections_.size_array() > 0) {
13276 + const entier n = domain.invalid_connections_.size_array();
13277 + IntTab tmp(n, 1);
13278 + for (entier i = 0; i < n; i++)
13279 + tmp(i, 0) = domain.invalid_connections_[i];
13281 + Nom fieldname = "INVALID_CONNECTIONS";
13282 + LataDBField field;
13283 + field.uname_ = Field_UName(geom.name_, fieldname, "ELEM" /* localisation */);
13284 + field.name_ = fieldname;
13285 + field.timestep_ = tstep;
13287 + field.filename_ = basename_;
13288 + field.filename_ += ".lata.";
13289 + field.filename_ += fieldname;
13290 + field.filename_ += ".";
13291 + field.filename_ += geom.name_;
13293 + field.filename_ += ".";
13294 + field.filename_ += Nom(tstep);
13296 + field.nb_comp_ = 1;
13297 + field.geometry_ = geom.name_;
13298 + field.datatype_ = db_.default_type_int_;
13299 + field.datatype_.array_index_ = LataDBDataType::NOT_AN_INDEX;
13300 + field.localisation_ = "ELEM";
13301 + field.reference_ = "";
13304 + db_.add_field(field);
13305 + db_.write_data(tstep, field.uname_, tmp);
13310 + Journal() << "Error LataWriter::write_geometry domain type not supported" << endl;
13311 + throw InternalError;
13315 +void LataWriter::write_component(const LataField_base & field)
13317 + // Index of the last timestep:
13318 + const entier tstep = db_.nb_timesteps() - 1;
13320 + LataDBField lata_field;
13322 + lata_field.uname_ = field.id_.uname_;
13323 + lata_field.name_ = field.id_.uname_.get_field_name();
13324 + lata_field.timestep_ = tstep;
13325 + lata_field.filename_ = basename_;
13326 + lata_field.filename_ += ".lata.";
13327 + lata_field.filename_ += lata_field.uname_.build_string();
13329 + lata_field.filename_ += ".";
13330 + lata_field.filename_ += Nom(tstep);
13332 + lata_field.geometry_ = field.id_.uname_.get_geometry();
13333 + lata_field.component_names_ = field.component_names_;
13334 + // Unites a remplir
13335 + // Size = -1 => valeur par defaut cherchee dans la geometrie
13336 + lata_field.localisation_ = LataField_base::localisation_to_string(field.localisation_);
13337 + lata_field.nature_ = field.nature_;
13339 + const Field<FloatTab> * float_f = dynamic_cast<const Field<FloatTab>*>(&field);
13340 + const Field<IntTab>* int_f = dynamic_cast<const Field<IntTab>*>(&field);
13342 + lata_field.nb_comp_ = int_f->data_.dimension(1);
13343 + lata_field.size_ = int_f->data_.dimension(0);
13344 + lata_field.datatype_ = db_.default_type_int_;
13345 + lata_field.datatype_.array_index_ = LataDBDataType::NOT_AN_INDEX;
13346 + db_.add_field(lata_field);
13347 + db_.write_data(tstep, lata_field.uname_, int_f->data_);
13348 + } else if (float_f) {
13349 + lata_field.nb_comp_ = float_f->data_.dimension(1);
13350 + lata_field.size_ = float_f->data_.dimension(0);
13351 + lata_field.datatype_ = db_.default_type_float();
13352 + db_.add_field(lata_field);
13353 + db_.write_data(tstep, lata_field.uname_, float_f->data_);
13357 +void LataWriter::finish()
13359 + Nom n(db_.path_prefix());
13362 + db_.write_master_file(n);
13364 diff --git a/databases/readers/Lata/LataWriter.h b/databases/readers/Lata/LataWriter.h
13365 new file mode 100644
13366 index 0000000..d17c413
13368 +++ b/databases/readers/Lata/LataWriter.h
13370 +/*****************************************************************************
13372 +* Copyright (c) 2011 - 2013, CEA
13373 +* All rights reserved.
13374 +* Redistribution and use in source and binary forms, with or without
13375 +* modification, are permitted provided that the following conditions are met:
13377 +* * Redistributions of source code must retain the above copyright
13378 +* notice, this list of conditions and the following disclaimer.
13379 +* * Redistributions in binary form must reproduce the above copyright
13380 +* notice, this list of conditions and the following disclaimer in the
13381 +* documentation and/or other materials provided with the distribution.
13382 +* * Neither the name of CEA, nor the
13383 +* names of its contributors may be used to endorse or promote products
13384 +* derived from this software without specific prior written permission.
13386 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
13387 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13388 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13389 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
13390 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13391 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13392 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13393 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13394 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13395 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13397 +*****************************************************************************/
13399 +#ifndef LataWriter_H
13400 +#define LataWriter_H
13401 +#include <LataDB.h>
13403 +class LataField_base;
13405 +// This class provides general services to write lata files
13406 +// from the "high level" objects Domain and Field (the LataDB class provides
13407 +// only low level services to write arrays)
13411 + enum FileSplittingOption { MULTIPLE_FILES, SINGLE_FILE };
13412 + void init_file(const Nom & path, const Nom & basename,
13413 + const LataDBDataType & default_int_format,
13414 + LataDBDataType::Type default_float_type);
13416 + void write_time(double t);
13417 + void write_geometry(const Domain & dom);
13418 + void write_component(const LataField_base & field);
13421 + enum ERRORS { InternalError };
13424 + // This is the database where we put all data...
13426 + // Basename for files and lata master file:
13428 + // FileSplittingOption split_;
13431 diff --git a/databases/readers/Lata/Lata_tools.C b/databases/readers/Lata/Lata_tools.C
13432 new file mode 100644
13433 index 0000000..fb97479
13435 +++ b/databases/readers/Lata/Lata_tools.C
13437 +/*****************************************************************************
13439 +* Copyright (c) 2011 - 2013, CEA
13440 +* All rights reserved.
13441 +* Redistribution and use in source and binary forms, with or without
13442 +* modification, are permitted provided that the following conditions are met:
13444 +* * Redistributions of source code must retain the above copyright
13445 +* notice, this list of conditions and the following disclaimer.
13446 +* * Redistributions in binary form must reproduce the above copyright
13447 +* notice, this list of conditions and the following disclaimer in the
13448 +* documentation and/or other materials provided with the distribution.
13449 +* * Neither the name of CEA, nor the
13450 +* names of its contributors may be used to endorse or promote products
13451 +* derived from this software without specific prior written permission.
13453 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
13454 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13455 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13456 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
13457 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13458 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13459 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13460 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13461 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13462 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13464 +*****************************************************************************/
13466 +#include <Lata_tools.h>
13467 +#include <ArrOfInt.h>
13468 +#include <ArrOfDouble.h>
13469 +#include <ArrOfFloat.h>
13470 +#include <ArrOfBit.h>
13471 +#include <sstream>
13472 +#include <string.h>
13473 +#include <stdlib.h>
13475 +static int journal_level = 0;
13477 +void set_Journal_level(entier level)
13479 + if (journal_level==level) return;
13480 + journal_level = level;
13481 + Journal() << "Changed lata journal level: " << journal_level << endl;
13484 +static std::ostringstream junk_journal;
13486 +std::ostream & Journal(entier level)
13488 + if (level <= journal_level) {
13489 + cerr << "[" << level << "] ";
13492 + junk_journal.seekp(0);
13493 + return junk_journal;
13497 +// Description: this method must return the total memory consumption
13498 +// of the object (used to compute the size of the data cache)
13499 +BigEntier LataObject::compute_memory_size() const
13501 + Journal() << "Error in LataObject::compute_memory_size(): function not implemented" << endl;
13505 +BigEntier memory_size(const ArrOfInt & tab)
13507 + // On ne tient pas compte du caractere smart_resize ou ref du tableau
13508 + // c'est pas tres grave pour l'instant pour ce qu'on en fait...
13509 + return ((BigEntier)sizeof(tab)) + ((BigEntier)tab.size_array()) * sizeof(entier);
13512 +BigEntier memory_size(const ArrOfDouble & tab)
13514 + // on ne tient pas compte du caractere smart_resize ou ref du tableau
13515 + // c'est pas tres grave pour l'instant pour ce qu'on en fait...
13516 + return ((BigEntier)sizeof(tab)) + ((BigEntier)tab.size_array()) * sizeof(double);
13519 +BigEntier memory_size(const ArrOfFloat & tab)
13521 + // on ne tient pas compte du caractere smart_resize ou ref du tableau
13522 + // c'est pas tres grave pour l'instant pour ce qu'on en fait...
13523 + return ((BigEntier)sizeof(tab)) + ((BigEntier)tab.size_array()) * sizeof(float);
13526 +BigEntier memory_size(const ArrOfBit & tab)
13528 + return ((BigEntier)sizeof(tab)) + ((BigEntier)tab.size_array()) * sizeof(int) / 32;
13531 +void split_path_filename(const char *s, Nom & path, Nom & filename)
13534 + for (i=(int)strlen(s)-1;i>=0;i--)
13535 + if ((s[i]==PATH_SEPARATOR) || (s[i]=='\\'))
13539 + for (j = 0; j <= i; j++)
13540 + path += Nom(s[j]);
13542 + // Parse basename : if extension given, remove it
13543 + filename = s+i+1;
13546 +static const ArrOfInt * array_to_sort_ptr = 0;
13547 +int compare_indirect(const void *ptr1, const void *ptr2)
13549 + entier i1 = *(const entier*)ptr1;
13550 + entier i2 = *(const entier*)ptr2;
13551 + entier diff = (*array_to_sort_ptr)[i1] - (*array_to_sort_ptr)[i2];
13552 + return (diff>0) ? 1 : ((diff==0) ? 0 : -1);
13555 +void array_sort_indirect(const ArrOfInt & array_to_sort, ArrOfInt & index)
13557 + const entier n = array_to_sort.size_array();
13558 + index.set_smart_resize(1);
13559 + index.resize_array(n);
13560 + for (entier i = 0; i < n; i++)
13562 + array_to_sort_ptr = &array_to_sort;
13563 + qsort(index.addr(), n, sizeof(entier), compare_indirect);
13565 diff --git a/databases/readers/Lata/Lata_tools.h b/databases/readers/Lata/Lata_tools.h
13566 new file mode 100644
13567 index 0000000..940fc54
13569 +++ b/databases/readers/Lata/Lata_tools.h
13571 +/*****************************************************************************
13573 +* Copyright (c) 2011 - 2013, CEA
13574 +* All rights reserved.
13575 +* Redistribution and use in source and binary forms, with or without
13576 +* modification, are permitted provided that the following conditions are met:
13578 +* * Redistributions of source code must retain the above copyright
13579 +* notice, this list of conditions and the following disclaimer.
13580 +* * Redistributions in binary form must reproduce the above copyright
13581 +* notice, this list of conditions and the following disclaimer in the
13582 +* documentation and/or other materials provided with the distribution.
13583 +* * Neither the name of CEA, nor the
13584 +* names of its contributors may be used to endorse or promote products
13585 +* derived from this software without specific prior written permission.
13587 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
13588 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13589 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13590 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
13591 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13592 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13593 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13594 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13595 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13596 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13598 +*****************************************************************************/
13600 +#ifndef Lata_tools_include_
13601 +#define Lata_tools_include_
13602 +#include <assert.h>
13610 +#define __BIG_ENDIAN 111
13611 +#define __LITTLE_ENDIAN 121
13612 +#define __BYTE_ORDER __LITTLE_ENDIAN
13614 +#define strtoll _strtoi64
13615 +// This must be able to contain a total memory size
13616 +// or a very big operation counter.
13617 +typedef __int64 BigEntier;
13621 +// Assume we only have x86, x86_64 based Macs.
13622 +#define __BIG_ENDIAN 111
13623 +#define __LITTLE_ENDIAN 121
13624 +#define __BYTE_ORDER __LITTLE_ENDIAN
13627 +// This must be able to contain a total memory size
13628 +// or a very big operation counter.
13629 +typedef long long BigEntier;
13632 +#ifndef __BYTE_ORDER
13633 +#include <endian.h>
13636 +#include <LataVector.h>
13639 +#define PATH_SEPARATOR '/'
13641 +#ifndef __BYTE_ORDER
13642 +#error "Byte order not defined."
13644 +#if (__BYTE_ORDER == __BIG_ENDIAN)
13645 +const bool mymachine_msb = true;
13646 +#elif (__BYTE_ORDER == __LITTLE_ENDIAN)
13647 +const bool mymachine_msb = false;
13649 +#error "Byte order is neither __BIG_ENDIAN nor __LITTLE_ENDIAN : "
13653 +class ArrOfDouble;
13656 +BigEntier memory_size(const ArrOfInt &);
13657 +BigEntier memory_size(const ArrOfDouble &);
13658 +BigEntier memory_size(const ArrOfFloat &);
13659 +BigEntier memory_size(const ArrOfBit &);
13664 + virtual ~LataObject() {};
13665 + virtual BigEntier compute_memory_size() const;
13668 +// A 'LataDeriv<X> ptr' object can hold an object of class Y which is any derived type of X.
13669 +// The contained object can be accessed via "valeur()" (you get an object of type X)
13670 +// or "refcast()" (get an object of any derived type Z between X and Y)
13671 +// (refcast() throws an exception if you try to cast with a wrong type)
13672 +// It can also be null (hold no object). valeur() will then throw an exception.
13674 +// LataDeriv<X> deriv_x;
13675 +// Y & y = deriv_x.instancie(Y); // Creates an instance of type Y within deriv_x
13676 +// X & x = deriv_x.valeur(); // Get a reference to the contained object
13677 +// Y & y2 = deriv_x.refcast(Y); // Same, but you get a reference of type Y
13678 +// Z & z = deriv_x.refcast(Z); // Throw an exception if Z is not a derived class of X and a base class of Y
13679 +// x.reset(); // Destroys the contained object (also destroyed when deriv_x is destroyed)
13680 +#define instancie(x) instancie_(new x)
13681 +#define refcast(x) refcast_((x*) 0)
13683 +template <class C>
13684 +class LataDeriv : public LataObject
13687 + enum DERIV_ERROR { ERROR_TYPE, ERROR_NULL };
13688 + LataDeriv() : ptr_(0) { };
13689 + ~LataDeriv() { delete ptr_; ptr_ = 0; }
13690 + void reset() { delete ptr_; ptr_ = 0; }
13691 + entier non_nul() const { return ptr_ != 0; }
13692 + // operator C &() { return valeur(); }
13693 + // operator const C &() const { return valeur(); }
13694 + C & valeur() { if (!ptr_) throw ERROR_NULL; return *ptr_; }
13695 + const C & valeur() const { if (!ptr_) throw ERROR_NULL; return *ptr_; }
13696 + template<class DER_C> DER_C & instancie_(DER_C *ptr) {
13699 + if (!dynamic_cast<C*>(ptr_)) {
13701 + throw ERROR_TYPE; // DER_C is not a derived type of C
13703 + return (DER_C &) (*ptr_);
13705 + template<class DER_C> DER_C & refcast_(DER_C *cast_type) {
13707 + throw ERROR_NULL;
13708 + DER_C * x = dynamic_cast<DER_C *>(ptr_);
13710 + throw ERROR_TYPE;
13713 + BigEntier compute_memory_size() const { if (ptr_) return ptr_->compute_memory_size(); else return 0; }
13715 + LataDeriv(const LataDeriv<C> & c) { ptr_ = 0; operator=(c); }
13716 + LataDeriv(const C & c) { ptr_ = 0; operator=(c); }
13717 + LataDeriv<C> & operator=(const LataDeriv<C> &);
13718 + LataDeriv<C> & operator=(const C &);
13722 +// This is a reference to an object of type C, but thr reference can be null
13727 + enum REF_ERROR { ERROR_NULL };
13728 + LataRef() : ptr_(0) { }
13729 + ~LataRef() { ptr_ = 0; }
13730 + LataRef(const LataRef<C> & x) : ptr_(x.ptr_) { }
13731 + LataRef(C & x) : ptr_(&x) { }
13732 + LataRef<C> & operator=(LataRef<C> & x) { ptr_ = x.ptr_; return *this; }
13733 + LataRef<C> & operator=(C & x) { ptr_ = &x; return *this; }
13734 + void reset() { ptr_ = 0; }
13735 + operator C&() { if (!ptr_) throw ERROR_NULL; return *ptr_; }
13736 + C& valeur() { if (!ptr_) throw ERROR_NULL; return *ptr_; }
13737 + entier non_nul() const { return ptr_ != 0; }
13742 +void array_sort_indirect(const ArrOfInt & array_to_sort, ArrOfInt & index);
13745 +void split_path_filename(const char *full_name, Nom & path, Nom & filename);
13747 +// To optimize small loops: replace for(i=0;i<n;i++) with n<=3 by
13748 +// for (i=0; i<loop_max(n,3); i++) {
13749 +// loop_instructions();...
13750 +// break_loop(i,n);
13752 +#define loop_max(nloops,max) max
13753 +#define break_loop(index,nloops) if (index >= nloops-1) break
13755 +#include <LataJournal.h>
13756 +#include <Motcle.h>
13758 +#include <DoubleTab.h>
13759 +#include <IntTab.h>
13760 +#include <FloatTab.h>
13762 +Motcles noms_to_motcles(const Noms & noms);
13765 diff --git a/databases/readers/Lata/LmlReader.C b/databases/readers/Lata/LmlReader.C
13766 new file mode 100644
13767 index 0000000..1b1b7d2
13769 +++ b/databases/readers/Lata/LmlReader.C
13771 +/*****************************************************************************
13773 +* Copyright (c) 2011 - 2013, CEA
13774 +* All rights reserved.
13775 +* Redistribution and use in source and binary forms, with or without
13776 +* modification, are permitted provided that the following conditions are met:
13778 +* * Redistributions of source code must retain the above copyright
13779 +* notice, this list of conditions and the following disclaimer.
13780 +* * Redistributions in binary form must reproduce the above copyright
13781 +* notice, this list of conditions and the following disclaimer in the
13782 +* documentation and/or other materials provided with the distribution.
13783 +* * Neither the name of CEA, nor the
13784 +* names of its contributors may be used to endorse or promote products
13785 +* derived from this software without specific prior written permission.
13787 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
13788 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13789 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13790 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
13791 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13792 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13793 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13794 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13795 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13796 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13798 +*****************************************************************************/
13800 +#define BUFSZ 1000
13801 +#include <iostream>
13802 +#include <EFichier.h>
13803 +#include <LataDB.h>
13804 +#include <LataFilter.h>
13805 +#include <stdlib.h>
13806 +#include <string.h>
13807 +// lml files contain double precision values that can overflow or underflow
13808 +// if converted to float. Check for overflow, ignore underflow
13809 +static inline float double_to_float(double x)
13811 + // Written like this, the code will also stop on NAN values:
13812 + if (!(x < 1.e38 && x > -1.e38)) {
13813 + Journal() << "lml reader: Error converting double value " << x << " to float" << endl;
13814 + throw LataDBError(LataDBError::READ_ERROR);
13816 + return (float) x;
13819 +// Reads the lml file, fills the lata_db and writes the data (coordinates, elements and
13820 +// fields data) to a unique file data_filename.
13821 +// The default format used to write data in the data_filename is lata_db.default_type_*
13822 +// data_filename must not contain the path but only a filename with extension.
13823 +// The path to the data file must be set by lata_db.set_path_prefix() before.
13824 +// If data_filename is a null pointer, data files are not written and file offsets in lata_db will
13825 +// be wrong (useful for just getting metadata)
13826 +void lml_reader(const char * lmlfilename, const char * data_filename, LataDB & lata_db)
13828 + Nom filename_in_master_file;
13829 + if (!data_filename)
13830 + filename_in_master_file = "DATA_NOT_WRITTEN";
13832 + filename_in_master_file = data_filename;
13834 + const entier lmllevel=4;
13836 + Journal(lmllevel) << "lml_reader: " << endl;
13837 + is.ouvrir(lmlfilename);
13838 + if (!is.good()) {
13839 + Journal() << "Error: cannot open lml file " << lmlfilename << endl;
13843 + is.get_istream().getline(s, BUFSZ);
13844 + if (!is.good()) {
13845 + Journal() << "Lml file " << lmlfilename << " is empty" << endl;
13846 + // Just put an empty initial timestep:
13847 + lata_db.add_timestep(-1.);
13850 + lata_db.header_ = s;
13851 + Journal(lmllevel) << "Header: " << s << endl;
13852 + is.get_istream().getline(s, BUFSZ);
13853 + lata_db.case_ = s;
13854 + Journal(lmllevel) << "Case: " << s << endl;
13855 + is.get_istream().getline(s, BUFSZ);
13856 + lata_db.software_id_ = s;
13857 + Journal(lmllevel) << "Software_id: " << s << endl;
13859 + Noms liste_noms_geoms;
13860 + Noms liste_noms_topo;
13861 + // Create first timestep (global definitions)
13862 + lata_db.add_timestep(-1.);
13863 + // file_offset_blurb:
13864 + // the file offset will be computed by LataDB::write_data(),
13865 + // but we must tell write_data() if it must put the data at the beginning
13866 + // (file_offset==0) or append the data at the end of the file (file_offset!=0)
13867 + // file_offset is 0 for the first data block and it is incremented for each block.
13868 + entier file_offset = 0;
13869 + LataDBField sommets;
13872 + const entier tstep = lata_db.nb_timesteps() - 1;
13875 + if (!is.good()) break;
13876 + if (motlu == "GRILLE") {
13877 + LataDBGeometry geom;
13878 + sommets.name_ = "SOMMETS";
13879 + geom.timestep_ = sommets.timestep_ = tstep;
13880 + sommets.filename_ = filename_in_master_file;
13883 + geom.name_ = ((const char*)mottmp)+7; // retire GRILLE_ du nom
13884 + Journal(lmllevel) << "lml_reader: GRILLE " << geom.name_ << endl;
13885 + is >> sommets.nb_comp_;
13889 + sommets.size_ = tmp; // size_ est long long...
13892 + throw LataDBError(LataDBError::READ_ERROR);
13893 + sommets.geometry_ = geom.name_;
13894 + sommets.uname_ = Field_UName(sommets.geometry_, sommets.name_, "");
13895 + sommets.datatype_ = lata_db.default_type_float();
13896 + sommets.datatype_.file_offset_ = file_offset++; // see file_offset_blurb
13897 + nodes.resize(sommets.size_, sommets.nb_comp_);
13898 + for (entier i = 0; i < sommets.size_; i++)
13899 + for (entier j = 0; j < sommets.nb_comp_; j++) {
13903 + throw LataDBError(LataDBError::READ_ERROR);
13904 + nodes(i,j) = double_to_float(x);
13906 + Journal(lmllevel+1) << "Finished reading nodes" << endl;
13908 + lata_db.add_geometry(geom);
13909 + // Write nodes to disk later: in 2D they will be cropped
13910 + } else if (motlu == "TOPOLOGIE") {
13911 + LataDBField elements;
13912 + elements.name_ = "ELEMENTS";
13913 + elements.timestep_ = tstep;
13914 + elements.filename_ = filename_in_master_file;
13915 + elements.datatype_ = lata_db.default_type_int_;
13916 + elements.datatype_.file_offset_ = file_offset++; // see file_offset_blurb
13918 + is >> ident; // Topologie_MAILLAGE_VOLUMIQUE_XXX
13922 + throw LataDBError(LataDBError::READ_ERROR);
13923 + elements.geometry_ = ((const char*)mottmp)+7; // retire GRILLE_ du nom
13924 + elements.uname_ = Field_UName(elements.geometry_, elements.name_, "");
13925 + liste_noms_geoms.add(elements.geometry_);
13926 + liste_noms_topo.add(ident);
13928 + if (motlu != "MAILLE") {
13929 + Journal() << "Error reading TOPOLOGIE: expected MAILLE" << endl;
13934 + is >> tmp; // size_ est long long...
13935 + elements.size_ = tmp;
13938 + int borne_index_min=0;
13939 + if (motlu == "TETRA4") {
13940 + lata_db.set_elemtype(tstep, elements.geometry_, "TETRAEDRE");
13941 + elements.nb_comp_ = 4;
13942 + } else if (motlu == "TRIANGLE_3D") {
13943 + elements.nb_comp_ = 3;
13944 + lata_db.set_elemtype(tstep, elements.geometry_, "TRIANGLE_3D");
13945 + } else if (motlu == "QUADRANGLE_3D") {
13946 + elements.nb_comp_ = 4;
13947 + lata_db.set_elemtype(tstep, elements.geometry_, "QUADRANGLE_3D");
13948 + } else if (motlu == "VOXEL8") {
13949 + elements.nb_comp_ = 8;
13950 + lata_db.set_elemtype(tstep, elements.geometry_, "HEXAEDRE");
13951 + } else if (motlu == "SEGMENT") {
13952 + elements.nb_comp_ = 2;
13953 + lata_db.set_elemtype(tstep, elements.geometry_, "SEGMENT");
13954 + } else if (motlu == "POINT") {
13955 + elements.nb_comp_ = 1;
13956 + lata_db.set_elemtype(tstep, elements.geometry_, "POINT");
13957 + } else if (motlu == "PRISM6") {
13958 + lata_db.set_elemtype(tstep, elements.geometry_, "PRISM6");
13959 + elements.nb_comp_ = 6;
13960 + } else if (motlu.debute_par("POLYEDRE_")) {
13961 + lata_db.set_elemtype(tstep, elements.geometry_, motlu);
13962 + elements.nb_comp_ = atoi(((const char *)motlu) + strlen("polyedre_"));
13963 + borne_index_min=-1;
13964 + } else if (motlu.debute_par("POLYGONE_")) {
13965 + lata_db.set_elemtype(tstep, elements.geometry_, motlu);
13966 + elements.nb_comp_ = atoi(((const char *)motlu) + strlen("polygone_"));
13967 + borne_index_min=-1;
13969 + Journal() << "Error reading TOPOLOGIE: unknown element type" << endl;
13973 + Journal(lmllevel+1) << " " << elements.size_ << " elements " << motlu << endl;
13975 + elems.resize(elements.size_, elements.nb_comp_);
13976 + for (entier i = 0; i < elements.size_; i++) {
13978 + is >> motlu; // element type
13980 + throw LataDBError(LataDBError::READ_ERROR);
13983 + for (j = 0; j < elements.nb_comp_; j++) {
13984 + is >> elems(i,j);
13986 + throw LataDBError(LataDBError::READ_ERROR);
13988 + if (elems(i,j) < borne_index_min || elems(i,j) >= sommets.size_ ) {
13989 + Journal() << "Error reading TOPOLOGIE: bad node number elem(" << i << "," << j << ")=" << elems(i,j) << endl;
13994 + Journal(lmllevel+1) << " finished reading elements" << endl;
13995 + lata_db.add_field(sommets);
13996 + if (data_filename)
13997 + lata_db.write_data(tstep, sommets.uname_, nodes);
13998 + lata_db.add_field(elements);
13999 + if (data_filename)
14000 + lata_db.write_data(tstep, elements.uname_, elems);
14001 + } else if (motlu == "FACE") {
14005 + throw LataDBError(LataDBError::READ_ERROR);
14006 + Journal(lmllevel+1) << " faces " << n << endl;
14007 + } else if (motlu == "TEMPS") {
14011 + throw LataDBError(LataDBError::READ_ERROR);
14012 + lata_db.add_timestep(t);
14013 + Journal(lmllevel+1) << " new time: " << t << endl;
14014 + } else if (motlu == "CHAMPMAILLE" || motlu == "CHAMPPOINT") {
14015 + LataDBField field;
14016 + is >> field.name_;
14018 + throw LataDBError(LataDBError::READ_ERROR);
14019 + Journal(lmllevel+1) << " new field: " << field.name_ << endl;
14020 + field.timestep_ = tstep;
14021 + field.filename_ = filename_in_master_file;
14022 + if (motlu == "CHAMPMAILLE")
14023 + field.localisation_ = "ELEM";
14025 + field.localisation_ ="SOM";
14029 + throw LataDBError(LataDBError::READ_ERROR);
14031 + const entier rang_topo = liste_noms_topo.rang(nom_topo);
14032 + if (rang_topo < 0) {
14033 + Journal() << "Error reading lml file : unknown topology name " << nom_topo << endl;
14036 + field.geometry_ = liste_noms_geoms[rang_topo];
14037 + Motcle mottmp(field.name_);
14038 + Motcle tmp2("_");
14039 + tmp2 += field.localisation_;
14041 + tmp2 += field.geometry_;
14042 + mottmp.prefix(tmp2); // Retire _SOM_dom du nom
14043 + field.name_ = mottmp;
14044 + field.uname_ = Field_UName(field.geometry_, field.name_, field.localisation_);
14046 + is >> t; // Unused time value
14048 + throw LataDBError(LataDBError::READ_ERROR);
14049 + is >> motlu; // Repeat fieldname
14051 + throw LataDBError(LataDBError::READ_ERROR);
14052 + is >> field.nb_comp_;
14054 + throw LataDBError(LataDBError::READ_ERROR);
14058 + throw LataDBError(LataDBError::READ_ERROR);
14059 + field.unites_.add(unit);
14060 + is >> motlu; // type0
14062 + throw LataDBError(LataDBError::READ_ERROR);
14066 + field.size_ = tmp; // long long convert
14069 + throw LataDBError(LataDBError::READ_ERROR);
14070 + // By default, 3 components fields are vectors:
14071 + if (field.nb_comp_ == 3) {
14072 + Journal(lmllevel+1) << " 3 components=> say it's a vector" << endl;
14073 + field.nature_ = LataDBField::VECTOR;
14075 + field.nature_ = LataDBField::SCALAR;
14077 + field.datatype_ = lata_db.default_type_float();
14078 + field.datatype_.file_offset_ = file_offset++; // see file_offset_blurb
14080 + tab.resize(field.size_, field.nb_comp_);
14081 + for (entier i = 0; i < field.size_; i++) {
14085 + throw LataDBError(LataDBError::READ_ERROR);
14086 + for (entier j = 0; j < field.nb_comp_; j++) {
14090 + throw LataDBError(LataDBError::READ_ERROR);
14091 + tab(i,j) = double_to_float(x);
14094 + Journal(lmllevel+1) << " finished reading field " << field.name_ << endl;
14095 + lata_db.add_field(field);
14096 + if (data_filename)
14097 + lata_db.write_data(tstep, field.uname_, tab);
14098 + } else if (motlu == "FIN") {
14101 + Journal() << "Error reading lml file, unknown keyword " << motlu << endl;
14107 +void lml_to_lata(const char *lmlname, const char *latafilename,
14108 + entier ascii, entier fortran_blocs, entier fortran_ordering, entier fortran_indexing)
14110 + const entier lmllevel=4;
14111 + Journal(lmllevel) << "lml_to_lata " << lmlname << " -> " << latafilename << endl;
14113 + Nom dest_prefix, dest_name;
14114 + LataOptions::extract_path_basename(latafilename, dest_prefix, dest_name);
14115 + // Nom du fichier .data a ecrire (sans le chemin)
14116 + Nom datafile(dest_name);
14117 + datafile += ".lata.data";
14118 + lata_db.set_path_prefix(dest_prefix);
14119 + // Nom complet du fichier lml a lire
14120 + LataDBDataType type;
14122 + type.msb_ = LataDBDataType::ASCII;
14124 + type.msb_ = LataDBDataType::machine_msb_;
14125 + type.type_ = LataDBDataType::INT32;
14126 + type.array_index_ = fortran_indexing ? LataDBDataType::F_INDEXING : LataDBDataType::C_INDEXING;
14127 + type.data_ordering_ = fortran_ordering ? LataDBDataType::F_ORDERING : LataDBDataType::C_ORDERING;
14128 + type.fortran_bloc_markers_ = fortran_blocs ? LataDBDataType::BLOC_MARKERS_SINGLE_WRITE : LataDBDataType::NO_BLOC_MARKER;
14129 + type.bloc_marker_type_ = LataDBDataType::INT32;
14130 + type.file_offset_ = 0;
14131 + lata_db.default_type_int_ = type;
14132 + lata_db.default_float_type_ = LataDBDataType::REAL32;
14134 + lml_reader(lmlname, datafile, lata_db);
14135 + Journal(lmllevel) << "lml_to_lata writing lata master file" << endl;
14136 + lata_db.write_master_file(latafilename);
14139 +// Reads lml or lata file into lata_db. lml data is loaded in an internal memory buffer
14140 +// file: full name with path
14141 +// path_prefix: the path (used to access lata data files)
14142 +// If dest_file_if_lml is not null, puts lml data into this file...
14143 +// In this case, you must set lata_db.default_type* to tell which format to use.
14144 +void read_any_format(const char * file, const Nom & path_prefix, LataDB & lata_db)
14146 + // Is it an lml ?
14147 + Motcle motcle_nom_fic(file);
14148 + if (motcle_nom_fic.finit_par(".lml")) {
14149 + Journal(1) << "Detected lml file : " << file << endl;
14150 + // Nom complet du fichier lml a lire
14151 + Journal(1) << "Reading lml file to memory buffer" << endl;
14152 + // data will be put in an internal memory buffer.
14153 + // choose appropriate data format:
14154 + LataDBDataType type;
14155 + type.msb_ = LataDBDataType::machine_msb_;
14156 + type.type_ = LataDBDataType::INT32;
14157 + type.array_index_ = LataDBDataType::C_INDEXING;
14158 + type.data_ordering_ = LataDBDataType::C_ORDERING;
14159 + type.fortran_bloc_markers_ = LataDBDataType::NO_BLOC_MARKER;
14160 + type.bloc_marker_type_ = LataDBDataType::INT32;
14161 + type.file_offset_ = 0;
14162 + lata_db.default_type_int_ = type;
14163 + lata_db.default_float_type_ = LataDBDataType::REAL32;
14164 + lml_reader(file, LataDBField::memory_buffer_file(), lata_db);
14166 + Journal(1) << "Detected lata file : " << file << endl;
14167 + lata_db.read_master_file(path_prefix, file);
14171 +// Description: if the file is a lata file, read the third line and interprets it as options
14172 +// if lml format, do nothing
14173 +// otherwise, error.
14174 +void read_any_format_options(const char * file, LataOptions & opt)
14176 + Motcle nom_fic(file);
14177 + if (nom_fic.finit_par(".lml")) {
14179 + } else if (nom_fic.finit_par(".med")) {
14181 + } else if (nom_fic.finit_par(".lata")) {
14182 + Journal(1) << "Lata file: Interpreting LataFilter options on third line" << endl;
14183 + Nom ligne = LataDB::read_master_file_options(file);
14184 + const char *s = ligne;
14187 + while ((*s) != ' ' && (*s) != 0) {
14191 + if ((toto != "Trio_U")&&(toto != "TRUST" )) {
14192 + if (!opt.parse_option(toto)) {
14193 + Journal(0) << "Interpreting option: " << toto <<" Failed." << endl;
14194 + throw LataDBError::BAD_HEADER;
14196 + Journal(1) << "Interpreting option: " << toto <<" Success." << endl;
14198 + while ((*s) == ' ')
14202 + Journal(0) << "read_any_format_options: file " << nom_fic << " has unsupported extension" << endl;
14203 + throw LataDBError::BAD_HEADER;
14206 diff --git a/databases/readers/Lata/LmlReader.h b/databases/readers/Lata/LmlReader.h
14207 new file mode 100644
14208 index 0000000..9a37ab5
14210 +++ b/databases/readers/Lata/LmlReader.h
14212 +/*****************************************************************************
14214 +* Copyright (c) 2011 - 2013, CEA
14215 +* All rights reserved.
14216 +* Redistribution and use in source and binary forms, with or without
14217 +* modification, are permitted provided that the following conditions are met:
14219 +* * Redistributions of source code must retain the above copyright
14220 +* notice, this list of conditions and the following disclaimer.
14221 +* * Redistributions in binary form must reproduce the above copyright
14222 +* notice, this list of conditions and the following disclaimer in the
14223 +* documentation and/or other materials provided with the distribution.
14224 +* * Neither the name of CEA, nor the
14225 +* names of its contributors may be used to endorse or promote products
14226 +* derived from this software without specific prior written permission.
14228 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
14229 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14230 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14231 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
14232 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14233 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14234 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14235 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14236 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14237 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14239 +*****************************************************************************/
14241 +#ifndef LMLREADER_H
14242 +#define LMLREADER_H
14243 +void lml_reader(const char * lmlfilename, const char * data_filename, LataDB & lata_db);
14244 +void lml_to_lata(const char *lmlfilename, const char *latafilename,
14245 + entier ascii = 0, entier fortran_blocs = 1, entier fortran_ordering = 0, entier fortran_indexing = 1);
14246 +void read_any_format(const char * file, const Nom & path_prefix, LataDB & lata_db);
14247 +void read_any_format_options(const char * file, LataOptions & opt);
14250 diff --git a/databases/readers/Lata/Motcle.C b/databases/readers/Lata/Motcle.C
14251 new file mode 100644
14252 index 0000000..4227be6
14254 +++ b/databases/readers/Lata/Motcle.C
14256 +/*****************************************************************************
14258 +* Copyright (c) 2011 - 2013, CEA
14259 +* All rights reserved.
14260 +* Redistribution and use in source and binary forms, with or without
14261 +* modification, are permitted provided that the following conditions are met:
14263 +* * Redistributions of source code must retain the above copyright
14264 +* notice, this list of conditions and the following disclaimer.
14265 +* * Redistributions in binary form must reproduce the above copyright
14266 +* notice, this list of conditions and the following disclaimer in the
14267 +* documentation and/or other materials provided with the distribution.
14268 +* * Neither the name of CEA, nor the
14269 +* names of its contributors may be used to endorse or promote products
14270 +* derived from this software without specific prior written permission.
14272 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
14273 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14274 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14275 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
14276 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14277 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14278 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14279 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14280 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14281 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14283 +*****************************************************************************/
14285 +#include <Motcle.h>
14286 +#include <string.h>
14287 +#include <istream>
14288 +#include <ostream>
14290 +Nom& Nom::majuscule()
14292 + const int n = longueur()-1;
14293 + for (int i = 0; i < n; i++)
14296 + if (c >= 'a' && c <= 'z')
14297 + s_[i] = c + 'A' - 'a';
14302 +static inline char char_uppercase(char c)
14304 + if (c >= 'a' && c <= 'z')
14310 +// opt=0 => comparaison des chaines completes
14311 +// opt=1 => le debut de n1 doit etre egal a n2
14312 +int Motcle::strcmp_uppercase(const char *n1, const char *n2, int opt)
14315 + unsigned char c1, c2;
14319 + c1 = (unsigned char) char_uppercase(n1[i]);
14320 + c2 = (unsigned char) char_uppercase(n2[i]);
14323 + if (c2 == 0 && opt == 1)
14325 + // Fin de la deuxieme chaine et opt=1 (fonction "debute_par"):
14330 + while ((delta == 0) && (c1 != 0) && (c2 != 0));
14334 +int Nom::debute_par(const char * s) const
14336 + const int l1 = longueur()-1;
14337 + const int l2 = (int)strlen(s);
14338 + return (l1>=l2) ? (strncmp(s_.c_str(), s, l2) == 0) : 0;
14341 +int Nom::finit_par(const char * s) const
14343 + const int l1 = longueur()-1;
14344 + const int l2 = (int)strlen(s);
14345 + return (l1>=l2) ? (strncmp(s_.c_str()+(l1-l2), s, l2) == 0) : 0;
14348 +entier Nom::find(const char * n) const
14350 + std::size_t x = s_.find(n);
14351 + return (x != std::string::npos) ? x : -1;
14354 +Nom& Nom::prefix(const char *s)
14356 + if (finit_par(s))
14358 + entier n = strlen(s_.c_str());
14359 + entier n2 = strlen(s);
14360 + s_.erase(n-n2,n2);
14365 +int Motcle::debute_par(const char * s) const
14367 + return (strcmp_uppercase(s_.c_str(), s, 1) == 0);
14370 +int Motcle::finit_par(const char * s) const
14372 + const int l1 = longueur()-1;
14373 + const int l2 = (int)strlen(s);
14374 + return (l1>=l2) ? (strcmp_uppercase(s_.c_str()+(l1-l2), s) == 0) : 0;
14377 +Motcles noms_to_motcles(const Noms& a)
14380 + entier n = a.size();
14381 + for (entier i = 0; i < n; i++)
14382 + b.add() = a[i]; // ouais, ecriture bizarre mais la plus efficace...
14386 +std::istream& operator>>(std::istream& is, Nom& nom)
14392 +std::ostream& operator<<(std::ostream& os, const Nom& nom)
14398 diff --git a/databases/readers/Lata/Motcle.h b/databases/readers/Lata/Motcle.h
14399 new file mode 100644
14400 index 0000000..e1a992d
14402 +++ b/databases/readers/Lata/Motcle.h
14404 +/*****************************************************************************
14406 +* Copyright (c) 2011 - 2013, CEA
14407 +* All rights reserved.
14408 +* Redistribution and use in source and binary forms, with or without
14409 +* modification, are permitted provided that the following conditions are met:
14411 +* * Redistributions of source code must retain the above copyright
14412 +* notice, this list of conditions and the following disclaimer.
14413 +* * Redistributions in binary form must reproduce the above copyright
14414 +* notice, this list of conditions and the following disclaimer in the
14415 +* documentation and/or other materials provided with the distribution.
14416 +* * Neither the name of CEA, nor the
14417 +* names of its contributors may be used to endorse or promote products
14418 +* derived from this software without specific prior written permission.
14420 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
14421 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14422 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14423 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
14424 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14425 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14426 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14427 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14428 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14429 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14431 +*****************************************************************************/
14433 +#ifndef LataMotcle_H
14434 +#define LataMotcle_H
14436 +#include <iostream>
14437 +#include <LataVector.h>
14440 +#include <stdio.h>
14454 + Nom(std::string str)
14459 + inline const std::string& getString() const { return s_; }
14461 + virtual ~Nom() { };
14462 + Nom(const char * nom) : s_(nom) { };
14470 + sprintf(s, "%d", i);
14473 + operator const char *() const
14475 + return s_.c_str();
14477 + virtual Nom& operator=(const char * nom)
14482 + virtual entier longueur() const
14484 + return static_cast<entier>(s_.length())+1; /*ATTENTION: +1 pour compatibilite avec TRUST*/
14486 + virtual void read(std::istream& is)
14490 + virtual void write(std::ostream& os) const
14494 + virtual int operator==(const char * s) const
14496 + return (s_ == s);
14498 + virtual int operator!=(const char * s) const
14500 + return !operator==(s);
14502 + virtual Nom& operator+=(const char * n)
14507 + virtual entier find(const char * n) const;
14508 + virtual int debute_par(const char * s) const;
14509 + virtual int finit_par(const char * s) const;
14510 + virtual Nom& prefix(const char * s);
14511 + Nom& majuscule();
14513 + friend class Motcle;
14517 +class Motcle : public Nom
14521 + Motcle(const char * s) : Nom(s) {};
14522 + Motcle(const Nom& n) : Nom(n) {};
14524 + int operator==(const char * s) const
14526 + return (strcmp_uppercase(s_.c_str(), s) == 0);
14528 + int operator!=(const char * s) const
14530 + return !operator==(s);
14532 + Motcle& operator+=(const char * n)
14537 + int debute_par(const char * s) const;
14538 + int finit_par(const char * s) const;
14540 + static int strcmp_uppercase(const char * s1, const char * s2, int opt = 0);
14541 + virtual entier find(const char * n) const
14543 + return Nom(*this).majuscule().find(Nom(n).majuscule());
14547 +typedef LataVector<Motcle> Motcles;
14548 +typedef LataVector<Nom> Noms;
14550 +std::istream& operator>>(std::istream& is, Nom& nom);
14551 +std::ostream& operator<<(std::ostream& os, const Nom& nom);
14554 diff --git a/databases/readers/Lata/Noms.h b/databases/readers/Lata/Noms.h
14555 new file mode 100644
14556 index 0000000..d9231d2
14558 +++ b/databases/readers/Lata/Noms.h
14560 +/*****************************************************************************
14562 +* Copyright (c) 2011 - 2013, CEA
14563 +* All rights reserved.
14564 +* Redistribution and use in source and binary forms, with or without
14565 +* modification, are permitted provided that the following conditions are met:
14567 +* * Redistributions of source code must retain the above copyright
14568 +* notice, this list of conditions and the following disclaimer.
14569 +* * Redistributions in binary form must reproduce the above copyright
14570 +* notice, this list of conditions and the following disclaimer in the
14571 +* documentation and/or other materials provided with the distribution.
14572 +* * Neither the name of CEA, nor the
14573 +* names of its contributors may be used to endorse or promote products
14574 +* derived from this software without specific prior written permission.
14576 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
14577 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14578 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14579 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
14580 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14581 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14582 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14583 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14584 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14585 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14587 +*****************************************************************************/
14589 diff --git a/databases/readers/Lata/Objet_U.h b/databases/readers/Lata/Objet_U.h
14590 new file mode 100644
14591 index 0000000..1f63425
14593 +++ b/databases/readers/Lata/Objet_U.h
14595 +/*****************************************************************************
14597 +* Copyright (c) 2011 - 2013, CEA
14598 +* All rights reserved.
14599 +* Redistribution and use in source and binary forms, with or without
14600 +* modification, are permitted provided that the following conditions are met:
14602 +* * Redistributions of source code must retain the above copyright
14603 +* notice, this list of conditions and the following disclaimer.
14604 +* * Redistributions in binary form must reproduce the above copyright
14605 +* notice, this list of conditions and the following disclaimer in the
14606 +* documentation and/or other materials provided with the distribution.
14607 +* * Neither the name of CEA, nor the
14608 +* names of its contributors may be used to endorse or promote products
14609 +* derived from this software without specific prior written permission.
14611 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
14612 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14613 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14614 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
14615 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14616 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14617 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14618 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14619 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14620 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14622 +*****************************************************************************/
14624 +// Class declared for compatibility with TRUST
14625 +#ifndef Objet_U_inclu
14626 +#define Objet_U_inclu
14627 +#include <LataJournal.h>
14628 +#include <Sortie.h>
14629 +#include <Entree.h>
14632 +#define Cerr Journal()
14633 +#define finl std::endl
14636 diff --git a/databases/readers/Lata/Octree_Double.C b/databases/readers/Lata/Octree_Double.C
14637 new file mode 100644
14638 index 0000000..f7cb229
14640 +++ b/databases/readers/Lata/Octree_Double.C
14642 +/*****************************************************************************
14644 +* Copyright (c) 2011 - 2013, CEA
14645 +* All rights reserved.
14646 +* Redistribution and use in source and binary forms, with or without
14647 +* modification, are permitted provided that the following conditions are met:
14649 +* * Redistributions of source code must retain the above copyright
14650 +* notice, this list of conditions and the following disclaimer.
14651 +* * Redistributions in binary form must reproduce the above copyright
14652 +* notice, this list of conditions and the following disclaimer in the
14653 +* documentation and/or other materials provided with the distribution.
14654 +* * Neither the name of CEA, nor the
14655 +* names of its contributors may be used to endorse or promote products
14656 +* derived from this software without specific prior written permission.
14658 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
14659 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14660 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14661 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
14662 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14663 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14664 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14665 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14666 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14667 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14669 +*****************************************************************************/
14671 +#include <Octree_Double.h>
14672 +#include <DoubleTab.h>
14673 +#include <FloatTab.h>
14675 +Octree_Double::Octree_Double()
14680 +void Octree_Double::reset()
14683 + octree_int_.reset();
14688 +// Description: Convertit une coordonnees reele en coordonnee entiere pour l'octree_int
14689 +// Valeur de retour: 1 si ok, 0 si coordonnee hors de l'octree
14690 +inline entier Octree_Double::integer_position(double x, entier direction, entier& ix) const
14692 + const double coord_max = (double) Octree_Int::coord_max_;
14693 + double rnd_x = (x - origin_[direction]) * factor_[direction];
14694 + // 0.49 permet d'accepter une coordonnee x egale a xmin ou xmax de l'octree,
14695 + // sinon pour un octree cree a partir de sommets, il y a un risque
14696 + // de ne pas trouver les coordonnees des points qu'on avait mis au bord de l'octree.
14697 + if (rnd_x >= -0.49 && rnd_x <= coord_max + 0.49)
14699 + ix = (entier) floor(rnd_x + 0.5);
14705 +// Valeur de retour: 1 s'il y a une intersection non vide avec l'octree, 0 sinon
14706 +inline entier Octree_Double::integer_position_clip(double xmin, double xmax,
14707 + entier& x0, entier& x1,
14708 + entier direction) const
14710 + const double coord_max = (double) Octree_Int::coord_max_;
14711 + xmin = (xmin - origin_[direction]) * factor_[direction];
14712 + xmax = (xmax - origin_[direction]) * factor_[direction];
14713 + // pas de marge ici comme on cherche avec une boite, l'epsilon est deja
14714 + // dans la dimension de la boite.
14715 + if (xmin > coord_max || xmax < 0.)
14720 + x0 = (entier) (floor(xmin+0.5));
14721 + if (xmax > coord_max)
14722 + x1 = Octree_Int::coord_max_;
14724 + x1 = (entier) (floor(xmax+0.5));
14728 +// Description: cherche les elements ou les points contenus dans l'octree_floor qui
14729 +// contient le point (x,y,z). Renvoie le nombre n de ces elements.
14730 +// Les indices des elements sont dans floor_elements()[index+i] pour 0 <= i < n
14731 +entier Octree_Double::search_elements(double x, double y, double z, entier& index) const
14734 + return 0; // octree vide
14735 + entier ix = 0, iy = 0, iz = 0;
14736 + entier ok = integer_position(x, 0, ix)
14737 + && integer_position(y, 1, iy)
14738 + && integer_position(z, 2, iz);
14741 + return octree_int_.search_elements(ix, iy, iz, index);
14749 +// Description: methode outil pour build_nodes et build_elements
14750 +// (calcul des facteurs de conversion entre reels et entiers pour Octree_Int
14751 +void Octree_Double::compute_origin_factors(const DoubleTab& coords,
14752 + const double epsilon,
14753 + const entier include_virtual)
14755 + // Recherche des coordonnees min et max du domaine
14756 + const entier nb_som = include_virtual ? coords.dimension_tot(0) : coords.dimension(0);
14758 + return; // octree vide
14760 + const entier dim = coords.dimension(1);
14762 + origin_.resize_array(3);
14763 + factor_.resize_array(3);
14764 + ArrOfDouble xmin(dim, 1.e37);
14765 + ArrOfDouble xmax(dim, -1.e-37);
14766 + assert(dim >= 1 && dim <= 3);
14768 + for (i = 0; i < nb_som; i++)
14770 + for (j = 0; j < dim; j++)
14772 + const double x = coords(i, j);
14779 + const double coord_max = (double) Octree_Int::coord_max_;
14780 + for (j = 0; j < dim; j++)
14782 + xmin[j] -= epsilon;
14783 + xmax[j] += epsilon;
14784 + origin_[j] = xmin[j];
14785 + if (xmax[j] - xmin[j] > 0.)
14787 + factor_[j] = coord_max / (xmax[j] - xmin[j]);
14793 +void Octree_Double::compute_origin_factors(const FloatTab& coords,
14794 + const double epsilon,
14795 + const entier include_virtual)
14797 + // Recherche des coordonnees min et max du domaine
14798 + const entier nb_som = include_virtual ? coords.dimension_tot(0) : coords.dimension(0);
14800 + return; // octree vide
14802 + const entier dim = coords.dimension(1);
14804 + origin_.resize_array(3);
14805 + factor_.resize_array(3);
14806 + ArrOfDouble xmin(dim, 1.e37);
14807 + ArrOfDouble xmax(dim, -1.e-37);
14808 + assert(dim >= 1 && dim <= 3);
14810 + for (i = 0; i < nb_som; i++)
14812 + for (j = 0; j < dim; j++)
14814 + const double x = coords(i, j);
14821 + const double coord_max = (double) Octree_Int::coord_max_;
14822 + for (j = 0; j < dim; j++)
14824 + xmin[j] -= epsilon;
14825 + xmax[j] += epsilon;
14826 + origin_[j] = xmin[j];
14827 + if (xmax[j] - xmin[j] > 0.)
14829 + factor_[j] = coord_max / (xmax[j] - xmin[j]);
14836 +// Description: construit un octree contenant les points de coordonnees coords.
14837 +// Si include_virtual=1, on stocke coords.dimension_tot(0) elements, sinon on en
14838 +// stocke coords.dimension(0)
14839 +void Octree_Double::build_nodes(const DoubleTab& coords, const entier include_virtual)
14841 + octree_int_.reset();
14842 + compute_origin_factors(coords, 0. /* epsilon */, include_virtual);
14843 + const entier nb_som = include_virtual ? coords.dimension_tot(0) : coords.dimension(0);
14845 + return; // octree vide
14846 + const entier dim = coords.dimension(1);
14847 + IntTab elements_boxes(nb_som, dim);
14848 + for (entier i = 0; i < nb_som; i++)
14850 + for (entier j = 0; j < dim; j++)
14853 + const double x = coords(i, j);
14854 + if (!integer_position(x, j, pos1))
14856 + Cerr << "Fatal error in octree : integer position outside octree" << finl;
14859 + elements_boxes(i, j) = pos1;
14862 + octree_int_.build(dim, elements_boxes);
14865 +// Description: Construit un octree a partir d'elements volumiques decrits par des
14866 +// ensembles de sommets. On stocke dans l'octree les parallelipipdes englobant chaque
14867 +// element (contenant tous les sommets de l'element) plus une marge de epsilon.
14868 +// Si include_virtual=1, on stocke elements.dimension_tot(0) elements, sinon on en
14869 +// stocke elements.dimension(0)
14870 +void Octree_Double::build_elements(const DoubleTab& coords, const IntTab& elements,
14871 + const double epsilon, const entier include_virtual)
14873 + octree_int_.reset();
14874 + compute_origin_factors(coords, epsilon, include_virtual);
14876 + const entier nb_elems = include_virtual ? elements.dimension_tot(0) : elements.dimension(0);
14877 + const entier nb_som_elem = elements.dimension(1);
14878 + const entier dim = coords.dimension(1);
14879 + IntTab elements_boxes(nb_elems, dim * 2);
14880 + for (entier i = 0; i < nb_elems; i++)
14882 + for (entier j = 0; j < dim; j++)
14884 + double xmin = 1.e37;
14885 + double xmax = -1.e37;
14886 + for (entier k = 0; k < nb_som_elem; k++)
14888 + const entier som = elements(i, k);
14889 + if (som>=0) { // polyedre som peut valoir -1
14890 + const double x = coords(som, j);
14891 + xmin = (x<xmin) ? x : xmin;
14892 + xmax = (x>xmax) ? x : xmax;
14895 + entier pos1 = 0, pos2 = 0;
14896 + if (!integer_position(xmin, j, pos1) || !integer_position(xmax, j, pos2))
14898 + Cerr << "Fatal error in octree : integer position outside octree" << finl;
14901 + elements_boxes(i, j) = pos1;
14902 + elements_boxes(i, j+dim) = pos2;
14905 + octree_int_.build(dim, elements_boxes);
14908 +void Octree_Double::build_elements(const FloatTab& coords, const IntTab& elements,
14909 + const double epsilon, const entier include_virtual)
14911 + octree_int_.reset();
14912 + compute_origin_factors(coords, epsilon, include_virtual);
14914 + const entier nb_elems = include_virtual ? elements.dimension_tot(0) : elements.dimension(0);
14915 + const entier nb_som_elem = elements.dimension(1);
14916 + const entier dim = coords.dimension(1);
14917 + IntTab elements_boxes(nb_elems, dim * 2);
14918 + for (entier i = 0; i < nb_elems; i++)
14920 + for (entier j = 0; j < dim; j++)
14922 + double xmin = 1.e37;
14923 + double xmax = -1.e37;
14924 + for (entier k = 0; k < nb_som_elem; k++)
14926 + const entier som = elements(i, k);
14927 + if (som>=0) { // polyedre som peut valoir -1
14928 + const double x = coords(som, j);
14929 + xmin = (x<xmin) ? x : xmin;
14930 + xmax = (x>xmax) ? x : xmax;
14933 + entier pos1 = 0, pos2 = 0;
14934 + if (!integer_position(xmin, j, pos1) || !integer_position(xmax, j, pos2))
14936 + Cerr << "Fatal error in octree : integer position outside octree" << finl;
14939 + elements_boxes(i, j) = pos1;
14940 + elements_boxes(i, j+dim) = pos2;
14943 + octree_int_.build(dim, elements_boxes);
14946 +// Description: cherche tous les elements ou points ayant potentiellement une intersection
14947 +// non vide avec la boite donnee.
14948 +entier Octree_Double::search_elements_box(double xmin, double ymin, double zmin,
14949 + double xmax, double ymax, double zmax,
14950 + ArrOfInt& elements) const
14952 + const entier dim = dim_;
14955 + elements.resize_array(0);
14958 + entier x0 = 0, x1 = 0, y0 = 0, y1 = 0, z0 = 0, z1 = 0;
14959 + entier ok = integer_position_clip(xmin, xmax, x0, x1, 0);
14960 + if (ok && dim >= 1)
14962 + ok = integer_position_clip(ymin, ymax, y0, y1, 1);
14963 + if (ok && dim >= 2)
14964 + ok = integer_position_clip(zmin, zmax, z0, z1, 2);
14967 + octree_int_.search_elements_box(x0, y0, z0, x1, y1, z1, elements);
14969 + elements.resize_array(0);
14970 + return elements.size_array();
14973 +// Description: cherche tous les elements ou points ayant potentiellement une intersection
14974 +// non vide avec la boite donnee (centre + ou - radius dans chaque direction)
14975 +entier Octree_Double::search_elements_box(const ArrOfDouble& center, const double radius,
14976 + ArrOfInt& elements) const
14978 + entier dim = center.size_array();
14979 + double x = center[0];
14980 + double y = (dim>=2) ? center[1] : 0.;
14981 + double z = (dim>2) ? center[2] : 0.;
14982 + entier i = search_elements_box(x-radius, y-radius, z-radius,
14983 + x+radius, y+radius, z+radius,
14988 +// Description: Methode hors classe
14989 +// Cherche parmi les sommets de la liste node_list ceux qui sont a une
14990 +// distance inferieure a epsilon du point (x,y,z). node_list contient des indices de
14991 +// sommets dans le tableau coords. La liste des noeuds verifiant le critere est mise
14992 +// dans node_list. On renvoie l'indice dans le tableau coords du sommet le plus proche.
14993 +entier Octree_Double::search_nodes_close_to(double x, double y, double z,
14994 + const DoubleTab& coords, ArrOfInt& node_list,
14997 + const entier n = node_list.size_array();
14998 + double eps2 = epsilon * epsilon;
14999 + entier count = 0;
15000 + const entier dim = coords.dimension(1);
15001 + double dmin = eps2;
15002 + entier nearest = -1;
15003 + for (entier i = 0; i < n; i++)
15005 + const entier som = node_list[i];
15006 + double dx = x - coords(som, 0);
15007 + double dy = (dim >= 2) ? y - coords(som, 1) : 0.;
15008 + double dz = (dim >= 3) ? z - coords(som, 2) : 0.;
15009 + double d2 = dx * dx + dy * dy + dz * dz;
15012 + node_list[count] = som;
15021 + node_list.resize_array(count);
15025 +// Description: Idem que search_nodes_close_to(double x, double y, double z, ...)
15026 +entier Octree_Double::search_nodes_close_to(const ArrOfDouble& point,
15027 + const DoubleTab& coords, ArrOfInt& node_list,
15030 + entier dim = point.size_array();
15031 + double x = point[0];
15032 + double y = (dim>=2) ? point[1] : 0.;
15033 + double z = (dim>2) ? point[2] : 0.;
15034 + entier i = search_nodes_close_to(x, y, z, coords, node_list, epsilon);
15037 diff --git a/databases/readers/Lata/Octree_Double.h b/databases/readers/Lata/Octree_Double.h
15038 new file mode 100644
15039 index 0000000..abf3258
15041 +++ b/databases/readers/Lata/Octree_Double.h
15043 +/*****************************************************************************
15045 +* Copyright (c) 2011 - 2013, CEA
15046 +* All rights reserved.
15047 +* Redistribution and use in source and binary forms, with or without
15048 +* modification, are permitted provided that the following conditions are met:
15050 +* * Redistributions of source code must retain the above copyright
15051 +* notice, this list of conditions and the following disclaimer.
15052 +* * Redistributions in binary form must reproduce the above copyright
15053 +* notice, this list of conditions and the following disclaimer in the
15054 +* documentation and/or other materials provided with the distribution.
15055 +* * Neither the name of CEA, nor the
15056 +* names of its contributors may be used to endorse or promote products
15057 +* derived from this software without specific prior written permission.
15059 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
15060 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15061 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15062 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
15063 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15064 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15065 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15066 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15067 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15068 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15070 +*****************************************************************************/
15073 +#ifndef Octree_Double_inclu
15074 +#define Octree_Double_inclu
15075 +#include <Octree_Int.h>
15076 +#include <ArrOfDouble.h>
15080 +// .DESCRIPTION : Un octree permettant de chercher dans l'espace des elements ou des points
15081 +// decrits par des coordonnees reeles. Cet objet est base sur Octree_Int.
15082 +class Octree_Double
15087 + void build_elements(const FloatTab& coords, const IntTab& elements,
15088 + const double epsilon, const entier include_virtual);
15089 + void build_elements(const DoubleTab& coords, const IntTab& elements,
15090 + const double epsilon, const entier include_virtual);
15091 + void build_nodes(const DoubleTab& coords, const entier include_virtual);
15092 + entier search_elements(double x, double y, double z, entier& index) const;
15093 + entier search_elements_box(double xmin, double ymin, double zmin,
15094 + double xmax, double ymax, double zmax,
15095 + ArrOfInt& elements) const;
15096 + static entier search_nodes_close_to(double x, double y, double z,
15097 + const DoubleTab& coords, ArrOfInt& node_list,
15099 + entier search_elements_box(const ArrOfDouble& center, const double radius,
15100 + ArrOfInt& elements) const;
15101 + static entier search_nodes_close_to(const ArrOfDouble& point,
15102 + const DoubleTab& coords, ArrOfInt& node_list,
15104 + entier dimension() const
15106 + assert(dim_ > 0);
15109 + inline const ArrOfInt& floor_elements() const
15111 + return octree_int_.floor_elements();
15114 + inline entier integer_position(double x, entier direction, entier& ix) const;
15115 + inline entier integer_position_clip(double xmin, double xmax,
15116 + entier& x0, entier& x1,
15117 + entier direction) const;
15118 + void compute_origin_factors(const DoubleTab& coords,
15119 + const double epsilon,
15120 + const entier include_virtual);
15121 + void compute_origin_factors(const FloatTab& coords,
15122 + const double epsilon,
15123 + const entier include_virtual);
15125 + Octree_Int octree_int_;
15126 + // Ces deux tableaux sont toujours de taille 3 par commodite
15127 + ArrOfDouble origin_;
15128 + ArrOfDouble factor_;
15132 diff --git a/databases/readers/Lata/Octree_Int.C b/databases/readers/Lata/Octree_Int.C
15133 new file mode 100644
15134 index 0000000..4f96b7c
15136 +++ b/databases/readers/Lata/Octree_Int.C
15138 +/*****************************************************************************
15140 +* Copyright (c) 2011 - 2013, CEA
15141 +* All rights reserved.
15142 +* Redistribution and use in source and binary forms, with or without
15143 +* modification, are permitted provided that the following conditions are met:
15145 +* * Redistributions of source code must retain the above copyright
15146 +* notice, this list of conditions and the following disclaimer.
15147 +* * Redistributions in binary form must reproduce the above copyright
15148 +* notice, this list of conditions and the following disclaimer in the
15149 +* documentation and/or other materials provided with the distribution.
15150 +* * Neither the name of CEA, nor the
15151 +* names of its contributors may be used to endorse or promote products
15152 +* derived from this software without specific prior written permission.
15154 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
15155 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15156 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15157 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
15158 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15159 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15160 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15161 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15162 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15163 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15165 +*****************************************************************************/
15167 +#include <Octree_Int.h>
15168 +#include <ArrOfBit.h>
15170 +static const entier max_levels_ = 32; // 1 de plus que le nombre de bits=1 dans coords_max
15171 +// La valeur suivante doit etre une puissance de deux
15172 +const entier Octree_Int::root_octree_half_width_ = 1073741824; /* 2^30 = 0100 0000 0000 0000 0000 0000 0000 0000b */
15173 +// La valeur suivante doit etre egale a (root_octree_half_width_ * 2 - 1)
15174 +const entier Octree_Int::coord_max_ = 2147483647; /* 2^31-1 = 0111 1111 1111 1111 1111 1111 1111 1111b */
15176 +// Description: construction d'un octree_id (voir octree_structure_)
15177 +// Si type==EMPTY, on l'octree_id est 0
15178 +// Si type==OCTREE, on suppose que index est un indice dans octree_structure_
15179 +// Si type==FLOOR, on suppose que index est un indice dans floor_elements_
15180 +inline entier Octree_Int::octree_id(entier index, Octree_Type type)
15187 + return index + 1;
15189 + return - index - 1;
15194 +// Description: calcul de l'index de l'octree dans octree_structure ou floor_elements
15195 +// en fonction du type de l'octree et de son octree_id.
15196 +// En general on a deja determine le type avant, on le passe en parametre pour optimiser.
15197 +inline entier Octree_Int::octree_index(entier octree_id, Octree_Type type)
15199 + assert(type==octree_type(octree_id));
15205 + return octree_id - 1;
15207 + return - octree_id - 1;
15212 +// Description: Renvoie le type d'un octree en fonction de son octree_id.
15213 +inline Octree_Int::Octree_Type Octree_Int::octree_type(entier octree_id)
15215 + if (octree_id > 0)
15217 + else if (octree_id == 0)
15223 +// Description: construction de l'octree. On donne la dimension (1, 2 ou 3)
15224 +// et un tableau d'elements a stocker dans l'octree. Deux possibilites:
15225 +// 1) les elements sont ponctuels si elements_boxes.dimension(1) == dimension.
15226 +// Dans ce cas, chaque element se trouve dans un et un seul octree_floor
15227 +// 2) les elements sont des parallelipipedes, si elements_boxes.dimension(1) == dimension*2
15228 +// Les "dimension" premieres colonnes sont les coordonnees inferieures,
15229 +// les "dimension" suivantes sont les coordonnees superieures.
15230 +// Un parallelipipede peut etre affecte a plusieurs octree_floor.
15231 +// Les coordonnees stockees dans elements_boxes peuvent aller de 0 a coord_max_ inclus.
15232 +// Il vaut mieux utiliser toute la plage des entiers en multipliant par un facteur adequat.
15233 +void Octree_Int::build(const entier dimension, const IntTab& elements_boxes)
15235 + assert(dimension >= 1 && dimension <= 3);
15236 + assert(elements_boxes.dimension(1) == dimension
15237 + || elements_boxes.dimension(1) == dimension * 2 );
15239 + const entier nb_elems = elements_boxes.dimension(0);
15240 + nb_elements_ = nb_elems;
15242 + octree_structure_.set_smart_resize(1);
15243 + floor_elements_.set_smart_resize(1);
15244 + floor_elements_.resize_array(0);
15245 + const entier nb_octrees = 1 << dimension;
15246 + octree_structure_.resize(0, nb_octrees);
15248 + assert(elements_boxes.size_array() == 0
15249 + || (min_array(elements_boxes) >= 0 && max_array(elements_boxes) <= coord_max_));
15251 + VECT(ArrOfInt) tmp_elem_flags(max_levels_);
15252 + VECT(ArrOfInt) tmp_elem_list(max_levels_);
15253 + for (i = 0; i < max_levels_; i++)
15255 + tmp_elem_flags[i].set_smart_resize(1);
15256 + tmp_elem_list[i].set_smart_resize(1);
15258 + ArrOfInt& elements_list = tmp_elem_list[0];
15259 + elements_list.resize_array(nb_elems);
15260 + for (entier i = 0; i < nb_elems; i++)
15261 + elements_list[i] = i;
15263 + root_octree_id_ = build_octree_recursively(root_octree_half_width_,root_octree_half_width_,root_octree_half_width_,
15264 + root_octree_half_width_,
15271 +// Description: renvoie la liste des elements contenant potentiellement le point (x,y,z)
15272 +// On renvoie n=nombre d'elements de la liste et les elements sont dans
15273 +// floor_elements()[index+i] pour 0 <= i < n.
15274 +// En realite on renvoie tous les elements qui ont une intersection non vide avec l'octree_floor
15275 +// contenant le point (x,y,z)
15276 +entier Octree_Int::search_elements(entier x, entier y, entier z, entier& index) const
15278 + const entier nb_octrees = octree_structure_.dimension(1);
15279 + if (nb_octrees == 2)
15280 + y = 0; // important pour ne pas tomber sur des cubes inexistants
15281 + if (nb_octrees <= 4)
15283 + assert(x >= 0 && x <= coord_max_);
15284 + assert(y >= 0 && y <= coord_max_);
15285 + assert(z >= 0 && z <= coord_max_);
15287 + const entier octree_id = search_octree_floor(x, y, z);
15289 + if (octree_type(octree_id) == EMPTY)
15293 + const entier idx = octree_index(octree_id, FLOOR);
15294 + const entier n = floor_elements_[idx];
15301 + IntBoxData(entier xmin, entier ymin, entier zmin,
15302 + entier xmax, entier ymax, entier zmax,
15303 + ArrOfInt& elements,
15304 + ArrOfBit *markers) :
15305 + xmin_(xmin), ymin_(ymin), zmin_(zmin),
15306 + xmax_(xmax), ymax_(ymax), zmax_(zmax),
15307 + elements_(elements),
15308 + markers_(markers) { };
15309 + entier xmin_, ymin_, zmin_;
15310 + entier xmax_, ymax_, zmax_;
15311 + ArrOfInt& elements_;
15312 + ArrOfBit *markers_;
15315 +// Description: cherche les elements ayant potentiellement une intersection non vide avec la
15316 +// boite xmin..zmax. Le tableau elements doit etre de type smart_resize(1).
15317 +// Les elements peuvent apparaitre plusieurs fois dans le tableau "elements"
15318 +entier Octree_Int::search_elements_box(entier xmin, entier ymin, entier zmin,
15319 + entier xmax, entier ymax, entier zmax,
15320 + ArrOfInt& elements) const
15322 + const entier nb_octrees = octree_structure_.dimension(1);
15323 + if (nb_octrees == 2)
15324 + ymin = ymax = 0; // important pour ne pas tomber sur des cubes inexistants
15325 + if (nb_octrees <= 4)
15326 + zmin = zmax = 0; // idem
15327 + assert(xmin >= 0 && xmin <= coord_max_);
15328 + assert(ymin >= 0 && ymin <= coord_max_);
15329 + assert(zmin >= 0 && zmin <= coord_max_);
15330 + assert(xmax >= 0 && xmax <= coord_max_);
15331 + assert(ymax >= 0 && ymax <= coord_max_);
15332 + assert(zmax >= 0 && zmax <= coord_max_);
15334 + elements.resize_array(0);
15335 + IntBoxData boxdata(xmin, ymin, zmin, xmax, ymax, zmax, elements, 0);
15336 + switch(octree_type(root_octree_id_))
15339 + search_elements_box_floor(boxdata, root_octree_id_);
15342 + search_elements_box_recursively(boxdata, root_octree_id_,
15343 + root_octree_half_width_,root_octree_half_width_,root_octree_half_width_,
15344 + root_octree_half_width_);
15349 + const entier n = elements.size_array();
15353 +// Description: ajoute des elements de l'octree_floor a boxdata.elements_
15354 +void Octree_Int::search_elements_box_floor(IntBoxData& boxdata,
15355 + entier octree_floor_id) const
15357 + const entier idx = octree_index(octree_floor_id, FLOOR);
15358 + const entier n = floor_elements_[idx];
15359 + if (boxdata.markers_)
15360 + for (entier i = 0; i < n; i++)
15362 + const entier elem = floor_elements_[idx+1+i];
15363 + if (!boxdata.markers_->testsetbit(elem))
15364 + boxdata.elements_.append_array(elem);
15367 + for (entier i = 0; i < n; i++)
15369 + const entier elem = floor_elements_[idx+1+i];
15370 + boxdata.elements_.append_array(elem);
15374 +// Pour chaque direction, drapeaux des cubes de la rangee inferieure
15375 +static entier sub_cube_flags_min[3] = { 1+4+16+64, /* drapeaux des cubes 0,2,4,6 */
15376 + 1+2+16+32, /* drapeaux des cubes 0,1,4,5 */
15377 + 1+2+4+8 /* drapeaux des cubes 0,1,2,3 */
15379 +static entier sub_cube_flags_max[3] = { 2+8+32+128, /* drapeaux des cubes 1,3,5,7 */
15380 + 4+8+64+128, /* drapeaux des cubes 2,3,7,8 */
15381 + 16+32+64+128 /* drapeaux des cubes 4,5,6,7 */
15384 +// Description: cherche recursivement les elements inclus dans la boite
15385 +// boxdata pour l'octree_id donne, de centre cx, cy, cz.
15387 +void Octree_Int::search_elements_box_recursively(IntBoxData& boxdata,
15388 + entier octree_id,
15389 + entier cx, entier cy, entier cz,
15390 + entier half_width) const
15392 + entier flags = 255;
15393 + if (cx > boxdata.xmax_) // les cubes superieurs en x ne sont pas dedans
15394 + flags &= sub_cube_flags_min[0];
15395 + if (cx <= boxdata.xmin_) // les cubes inferieurs ne sont pas dedans
15396 + flags &= sub_cube_flags_max[0];
15397 + if (cy > boxdata.ymax_)
15398 + flags &= sub_cube_flags_min[1];
15399 + if (cy <= boxdata.ymin_)
15400 + flags &= sub_cube_flags_max[1];
15401 + if (cz > boxdata.zmax_)
15402 + flags &= sub_cube_flags_min[2];
15403 + if (cz <= boxdata.zmin_)
15404 + flags &= sub_cube_flags_max[2];
15405 + entier test_flag = 1;
15406 + const entier idx = octree_index(octree_id, OCTREE);
15407 + const entier half_width_2 = half_width >> 1;
15408 + const entier mhalf_width = - half_width_2;
15409 + entier cx2, cy2, cz2;
15410 + for (entier i = 0; i < 8; i++, test_flag <<= 1)
15412 + if ((flags & test_flag) != 0)
15414 + const entier id = octree_structure_(idx, i);
15415 + switch(octree_type(id))
15418 + search_elements_box_floor(boxdata, id);
15421 + cx2 = cx + ((i & 1) ? half_width_2 : mhalf_width);
15422 + cy2 = cy + ((i & 2) ? half_width_2 : mhalf_width);
15423 + cz2 = cz + ((i & 4) ? half_width_2 : mhalf_width);
15424 + search_elements_box_recursively(boxdata, id,
15435 +void Octree_Int::reset()
15437 + root_octree_id_ = octree_id(0, EMPTY);
15438 + nb_elements_ = 0;
15439 + octree_structure_.reset();
15440 + floor_elements_.reset();
15443 +// Description: construit un octree_floor avec la liste d'elements donnee et
15444 +// renvoie l'octree_id de cet octree_floor
15445 +entier Octree_Int::build_octree_floor(const ArrOfInt& elements_list)
15447 + const entier nb_elems = elements_list.size_array();
15448 + const entier index = floor_elements_.size_array();
15449 + floor_elements_.resize_array(index + nb_elems + 1);
15450 + floor_elements_[index] = nb_elems;
15451 + for (entier i = 0; i < nb_elems; i++)
15452 + floor_elements_[index + 1 + i] = elements_list[i];
15453 + return octree_id(index, FLOOR);
15457 +// octree_center_i est le premier entier de la moitie superieure de l'octree dans la direction i.
15458 +// octree_half_width est une puissance de 2 egale a octree_center_i-octree_min_i (octree_min_i
15459 +// est le premier entier inclu dans cet octree dans la direction i)
15460 +// Valeur de retour: octree_id de l'octree construit (void octree_structure_)
15461 +entier Octree_Int::build_octree_recursively(const entier octree_center_x,
15462 + const entier octree_center_y,
15463 + const entier octree_center_z,
15464 + const entier octree_half_width,
15465 + const IntTab& elements_boxes,
15466 + VECT(ArrOfInt) & vect_elements_list,
15467 + const entier level,
15468 + VECT(ArrOfInt) & tmp_elem_flags)
15470 + // Criteres d'arret de la subdivision:
15471 + // Nombre maximal d'elements dans un sous-cube floor
15472 + static const entier octree_floor_max_elems = 8;
15473 + // S'il y a beaucoup d'elements dupliques, mais pas trop, et que le nombre d'elements
15474 + // dans l'octree est superieur a cette valeur, on subdivise quand-meme
15475 + static const entier octree_duplicate_elements_limit = 32;
15476 + const ArrOfInt& elements_list = vect_elements_list[level];
15477 + // Si le nombre d'elements est inferieur a la limite, on cree un floor_element,
15478 + // sinon on subdivise
15479 + const entier nb_elems = elements_list.size_array();
15480 + if (nb_elems == 0)
15481 + return octree_id(0, EMPTY);
15483 + if (nb_elems < octree_floor_max_elems || octree_half_width == 1 /* dernier niveau */)
15485 + const entier octree_id = build_octree_floor(elements_list);
15486 + return octree_id;
15489 + ArrOfInt& elem_flags = tmp_elem_flags[level];
15490 + elem_flags.resize_array(0); // Ne pas conserver les anciennes valeurs
15491 + elem_flags.resize_array(nb_elems);
15493 + const entier nb_octrees = octree_structure_.dimension(1);
15494 + assert(nb_octrees == 2 || nb_octrees == 4 || nb_octrees == 8);
15495 + const entier elem_box_dim = elements_boxes.dimension(1);
15496 + // Soit elements_boxes contient dimension colonnes, soit dimension*2
15497 + const entier box_delta = (elem_box_dim > 3) ? (elem_box_dim >> 1) : 0;
15498 + // Nombre d'elements stockes en double dans l'octree (a cause des elements a cheval
15499 + // sur plusieurs sous-octrees)
15500 + entier nb_duplicate_elements = 0;
15501 + // On range les elements de la liste dans 8 sous-cubes (remplissage de elem_flags)
15502 + for (entier i_elem = 0; i_elem < nb_elems; i_elem++)
15504 + const entier elem = elements_list[i_elem];
15505 + // dir_flag vaut 1 pour la direction x, 2 pour y et 4 pour z
15506 + entier dir_flag = 1;
15507 + // sub_cube_flags contient 2^dim drapeaux binaires (1 par sous-cube),
15508 + // et indique les sous-cubes coupes par l'element
15509 + entier octree_flags = 255;
15510 + // dans combien de sous-octree cet element est-il stocke ?
15511 + entier nb_duplicates = 1;
15513 + for (entier direction = 0; direction < 3; direction++)
15515 + const entier elem_min = elements_boxes(elem, direction);
15516 + const entier elem_max = elements_boxes(elem, box_delta+direction);
15517 + assert(elem_max >= elem_min);
15518 + // coordonnee du centre du cube dans la direction j:
15519 + const entier center = (direction==0) ? octree_center_x : ((direction==1) ? octree_center_y : octree_center_z);
15520 + // L'element coupe-t-il la partie inferieure et la partie superieure du cube dans la "direction" ?
15521 + if (elem_min >= center) // non -> on retire les flags des cubes de la partie inferieure
15522 + octree_flags &= sub_cube_flags_max[direction];
15523 + else if (elem_max < center) // non -> on retire les flags des cubes de la partie superieure
15524 + octree_flags &= sub_cube_flags_min[direction];
15526 + nb_duplicates <<= 1; // l'element coupe les deux parties !
15527 + dir_flag = dir_flag << 1;
15528 + if (dir_flag == nb_octrees)
15531 + elem_flags[i_elem] = octree_flags;
15532 + nb_duplicate_elements += nb_duplicates - 1;
15535 + // Critere un peu complique : s'il y a vraiment beaucoup d'elements
15536 + // dans cet octree, on autorise jusqu'a dupliquer tous les elements,
15537 + // ce qui permet de ranger des elements tres alonges qui sont forcement
15538 + // dupliques dans une direction (>octree_duplicate_elements_limit).
15539 + if ((nb_duplicate_elements * 2 >= nb_elems && nb_elems < octree_duplicate_elements_limit)
15540 + || nb_duplicate_elements > nb_elems)
15542 + const entier octree_id = build_octree_floor(elements_list);
15543 + // On renvoie un index d'octreefloor
15544 + return octree_id;
15547 + // On reserve une case a la fin de octree_structure pour stocker cet octree:
15548 + const entier index_octree = octree_structure_.dimension(0);
15549 + octree_structure_.resize(index_octree + 1, nb_octrees);
15550 + ArrOfInt& new_liste_elems = vect_elements_list[level+1];
15551 + new_liste_elems.resize_array(0);
15552 + const entier width = octree_half_width >> 1;
15553 + const entier m_width = - width;
15554 + // Traitement recursif des sous-cubes de l'octree:
15556 + for (i_cube = 0; i_cube < nb_octrees; i_cube++)
15558 + const entier octree_flag = 1 << i_cube;
15559 + new_liste_elems.resize_array(0); // ne pas conserver les anciennes valeurs
15560 + new_liste_elems.resize_array(nb_elems);
15561 + entier count = 0;
15562 + // Liste des elements inclus dans le sous-cube:
15563 + for (entier i_elem = 0; i_elem < nb_elems; i_elem++)
15564 + if ((elem_flags[i_elem] & octree_flag) != 0)
15565 + new_liste_elems[count++] = elements_list[i_elem];
15566 + new_liste_elems.resize_array(count);
15568 + entier sub_octree_id;
15569 + if (new_liste_elems.size_array() == 0)
15571 + sub_octree_id = octree_id(-1, EMPTY);
15575 + // Coordonnees du nouveau sous-cube
15576 + const entier cx = octree_center_x + ((i_cube&1) ? width : m_width);
15577 + const entier cy = octree_center_y + ((i_cube&2) ? width : m_width);
15578 + const entier cz = octree_center_z + ((i_cube&4) ? width : m_width);
15579 + sub_octree_id = build_octree_recursively(cx, cy, cz, width,
15581 + vect_elements_list,
15585 + octree_structure_(index_octree, i_cube) = sub_octree_id;
15588 + return octree_id(index_octree, OCTREE);
15591 +// Description: renvoie l'octree_id de l'octree_floor contenant le sommet (x,y,z)
15592 +// (peut renvoyer l'octree EMPTY)
15593 +entier Octree_Int::search_octree_floor(entier x, entier y, entier z) const
15595 + if (octree_type(root_octree_id_) != OCTREE)
15596 + return root_octree_id_;
15597 + // Le test pour savoir si on est dans la partie superieure ou
15598 + // inferieure d'un octree au niveau i consiste simplement a tester
15599 + // le i-ieme bit de la position.
15600 + entier flag = root_octree_half_width_;
15602 + entier index = octree_index(root_octree_id_, OCTREE);
15604 + // Descendre dans la hierarchie d'octree subdivises jusqu'au cube
15608 + // Numero du sous-cube dans lequel se trouve le sommet x,y,z
15609 + const entier ix = (x & flag) ? 1 : 0;
15610 + const entier iy = (y & flag) ? 2 : 0;
15611 + const entier iz = (z & flag) ? 4 : 0;
15612 + entier i_sous_cube = ix + iy + iz;
15613 + // On entre dans le sous-cube :
15614 + const entier octree_id = octree_structure_(index, i_sous_cube);
15615 + if (octree_type(octree_id) != OCTREE)
15616 + return octree_id;
15618 + index = octree_index(octree_id, OCTREE);
15621 + return -1; // On n'arrive jamais ici !
15623 diff --git a/databases/readers/Lata/Octree_Int.h b/databases/readers/Lata/Octree_Int.h
15624 new file mode 100644
15625 index 0000000..ace9c2d
15627 +++ b/databases/readers/Lata/Octree_Int.h
15629 +/*****************************************************************************
15631 +* Copyright (c) 2011 - 2013, CEA
15632 +* All rights reserved.
15633 +* Redistribution and use in source and binary forms, with or without
15634 +* modification, are permitted provided that the following conditions are met:
15636 +* * Redistributions of source code must retain the above copyright
15637 +* notice, this list of conditions and the following disclaimer.
15638 +* * Redistributions in binary form must reproduce the above copyright
15639 +* notice, this list of conditions and the following disclaimer in the
15640 +* documentation and/or other materials provided with the distribution.
15641 +* * Neither the name of CEA, nor the
15642 +* names of its contributors may be used to endorse or promote products
15643 +* derived from this software without specific prior written permission.
15645 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
15646 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15647 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15648 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
15649 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15650 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15651 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15652 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15653 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15654 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15656 +*****************************************************************************/
15658 +#ifndef Octree_Int_inclus
15659 +#define Octree_Int_inclus
15660 +#include <IntTab.h>
15661 +#include <VectArrOfInt.h>
15663 +struct IntBoxData;
15666 +// .DESCRIPTION : Un octree permettant de retrouver des objets ponctuels ou
15667 +// parallelipipediques dans un espace 1D, 2D ou 3D et des coordonnees entieres
15671 + void build(const entier dimension, const IntTab& elements_boxes);
15672 + entier search_elements(entier x, entier y, entier z, entier& floor_elements_index) const;
15673 + entier search_elements_box(entier xmin, entier ymin, entier zmin,
15674 + entier xmax, entier ymax, entier zmax,
15675 + ArrOfInt& elements) const;
15678 + inline const ArrOfInt& floor_elements() const
15680 + return floor_elements_;
15683 + // Le plus grand entier autorise pour les coordonnees (du type 2^n - 1)
15684 + static const entier coord_max_;
15685 + // Premier entier de la moitie superieure de l'octree root (si coord_max_=2^n-1, half_width_=2^(n-1))
15686 + static const entier root_octree_half_width_;
15688 + entier build_octree_recursively(const entier octree_center_x, const entier octree_center_y, const entier octree_center_z,
15689 + const entier octree_half_width,
15690 + const IntTab& elements_boxes,
15691 + VECT(ArrOfInt) & vect_elements_list,
15692 + const entier level,
15693 + VECT(ArrOfInt) & tmp_elem_flags);
15694 + entier build_octree_floor(const ArrOfInt& elements_list);
15696 + entier search_octree_floor(entier x_pos, entier y_pos, entier z_pos) const;
15697 + void search_elements_box_floor(IntBoxData& boxdata,
15698 + entier octree_floor_id) const;
15699 + void search_elements_box_recursively(IntBoxData& boxdata,
15700 + entier octree_id,
15701 + entier cx, entier cy, entier cz,
15702 + entier half_width) const;
15704 + // Un octree peut etre soit vide, soit subdivise en nb_octrees autres octrees,
15705 + // soit un octree_floor contenant une liste d'elements.
15706 + enum Octree_Type { EMPTY, OCTREE, FLOOR };
15708 + static inline entier octree_id(entier index, Octree_Type type);
15709 + static inline entier octree_index(entier octree_id, Octree_Type type);
15710 + static inline Octree_Type octree_type(entier octree_id);
15712 + // Octree_id du cube principal : peut etre EMPTY, OCTREE ou FLOOR
15713 + entier root_octree_id_;
15714 + // Nombre d'elements stockes (dimension(0) du tableau elements_boxes)
15715 + entier nb_elements_;
15716 + // Tableau contenant tous les cubes qui sont divises en sous-cubes
15717 + // octree_structure_(i, j) decrit le contenu du sous-cube j du cube d'index i.
15718 + // pour 0 <= j < nombre de sous-cubes par cube.
15719 + // On appelle "octree_id" une valeur X=octree_structure_(i,j) (identifiant octree)
15720 + // L'octree id encode a la fois le type de l'octree et l'index ou
15721 + // il se trouve dans les tableaux (voir octree_id(entier, Octree_Type))
15722 + IntTab octree_structure_;
15724 + // Tableau contenant la liste des elements de chaque sous-cube final non subdivise.
15725 + // Si X < 0, on note i_debut = -X-1.
15726 + // floor_elements_(i_debut) = n = nombre d'elements dans ce sous-cube
15727 + // floor_elements_[i_debut+j] = numero d'un element qui coupe ce sous-cube pour 1 <= j <= n
15728 + ArrOfInt floor_elements_;
15732 diff --git a/databases/readers/Lata/OpenDXWriter.C b/databases/readers/Lata/OpenDXWriter.C
15733 new file mode 100644
15734 index 0000000..7add5ed
15736 +++ b/databases/readers/Lata/OpenDXWriter.C
15738 +/*****************************************************************************
15740 +* Copyright (c) 2011 - 2013, CEA
15741 +* All rights reserved.
15742 +* Redistribution and use in source and binary forms, with or without
15743 +* modification, are permitted provided that the following conditions are met:
15745 +* * Redistributions of source code must retain the above copyright
15746 +* notice, this list of conditions and the following disclaimer.
15747 +* * Redistributions in binary form must reproduce the above copyright
15748 +* notice, this list of conditions and the following disclaimer in the
15749 +* documentation and/or other materials provided with the distribution.
15750 +* * Neither the name of CEA, nor the
15751 +* names of its contributors may be used to endorse or promote products
15752 +* derived from this software without specific prior written permission.
15754 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
15755 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15756 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15757 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
15758 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15759 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15760 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15761 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15762 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15763 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15765 +*****************************************************************************/
15767 +#include <OpenDXWriter.h>
15768 +#include <LataFilter.h>
15769 +#include <iostream>
15770 +#include <fstream>
15778 + DX_stream() : os_to_cout_(0), os_(0) {};
15779 + void init_cout(int is_ascii)
15783 + ascii_ = is_ascii;
15784 + os_ = &std::cout;
15786 + void init_file(const char *fname, int is_ascii)
15790 + ascii_ = is_ascii;
15791 + os_ = new std::ofstream(fname);
15793 + ~DX_stream() { reset(); }
15796 + if (!os_to_cout_)
15801 + DX_stream & operator<<(const float f) { (*os_) << f; return *this; }
15802 + DX_stream & operator<<(const int i) { (*os_) << i; return *this; }
15803 + DX_stream & operator<<(const char * s) { (*os_) << s; return *this; }
15804 + DX_stream & operator<<(DX_stream & f(DX_stream &)) { return f(*this); }
15806 + void write(char * ptr, int sz) { os_->write(ptr, sz); }
15807 + entier ok() { return os_ != 0; }
15808 + entier ascii() { return ascii_; }
15809 + std::ostream & stream() { return *os_; }
15813 + std::ostream *os_;
15816 +DX_stream & endl(DX_stream & os)
15818 + os.stream() << std::endl;
15822 +void DX_write_vect(DX_stream & os, int dxobject, const ArrOfFloat & v)
15824 + const int places = v.size_array();
15825 + os << "object " << dxobject << " class array" << endl;
15826 + os << "type float rank 1 shape 1 items " << places << " ";
15828 + if (!os.ascii()) {
15829 + os << (mymachine_msb ? "msb ieee" : "lsb ieee") << " data follows" << endl;
15830 + os.write((char*)v.addr(), sizeof(float) * places);
15832 + os << "ascii data follows" << endl;
15833 + for (int i=0;i<places;i++) {
15834 + os << v[i] << " ";
15839 +void DX_write_vect(DX_stream & os, int dxobject, const FloatTab & v)
15841 + const int places = v.dimension(0);
15842 + const int shape = v.dimension(1);
15843 + os << "object " << dxobject << " class array" << endl;
15844 + os << "type float rank 1 shape " << shape << " items " << places << " ";
15846 + if (!os.ascii()) {
15847 + os << (mymachine_msb ? "msb ieee" : "lsb ieee") << " data follows" << endl;
15848 + os.write((char*)v.addr(), sizeof(float) * places * shape);
15850 + os << "ascii data follows" << endl;
15851 + for (int i=0;i<places;i++) {
15852 + for (int j=0;j<shape;j++)
15853 + os << v(i, j) << " ";
15859 +void DX_write_vect(DX_stream & os, int dxobject, const IntTab & v)
15861 + if (sizeof(int) != 4) {
15862 + Journal() << "Error DX_write_vect : int size != 32 bits" << endl;
15863 + throw OpenDXWriter::DXInternalError;
15865 + const int places = v.dimension(0);
15866 + const int shape = v.dimension(1);
15867 + os << "object " << dxobject << " class array" << endl;
15868 + os << "type int rank 1 shape " << shape << " items " << places << " ";
15870 + if (!os.ascii()) {
15871 + os << (mymachine_msb ? "msb ieee" : "lsb ieee") << " data follows" << endl;
15872 + os.write((char*)v.addr(), sizeof(int) * places * shape);
15874 + os << "ascii data follows" << endl;
15875 + for (int i=0;i<places;i++) {
15876 + for (int j=0;j<shape;j++)
15877 + os << v(i, j) << " ";
15883 +OpenDXWriter::OpenDXWriter()
15885 + os_ = new DX_stream;
15888 +OpenDXWriter::~OpenDXWriter()
15893 +void OpenDXWriter::reset()
15895 + index_counter_ = 0;
15896 + fields_indexes_.resize_array(0);
15897 + fields_indexes_.set_smart_resize(1);
15898 + fields_names_ = Noms();
15899 + nodes_index_ = -1;
15900 + finish_geometry(); // reset geometry data
15903 +void OpenDXWriter::init_cout(double time, int ascii)
15906 + os_->init_cout(ascii);
15907 + dx_time_index_ = ++index_counter_;
15911 + DX_write_vect(*os_, dx_time_index_, t);
15914 +void OpenDXWriter::init_file(double time, Nom & filename_, int ascii)
15917 + os_->init_file(filename_, ascii);
15918 + dx_time_index_ = ++index_counter_;
15922 + DX_write_vect(*os_, dx_time_index_, t);
15925 +const char * DX_element_name(Domain::Element elem)
15928 + case Domain::line: return "lines";
15929 + case Domain::triangle: return "triangles";
15930 + case Domain::quadri: return "quads";
15931 + case Domain::tetra: return "tetrahedra";
15932 + case Domain::hexa: return "cubes";
15934 + Journal() << "DX_element_name unknown element" << endl;
15935 + throw OpenDXWriter::DXInternalError;
15939 +void OpenDXWriter::write_geometry(const Domain & dom)
15941 + // Write last geometry and begin a new one
15942 + finish_geometry();
15943 + const DomainUnstructured * dom1 = dynamic_cast<const DomainUnstructured*>(&dom);
15944 + const DomainIJK * dom2 = dynamic_cast<const DomainIJK*>(&dom);
15945 + DX_stream & os = *os_;
15947 + nodes_index_ = ++index_counter_;
15948 + DX_write_vect(os, nodes_index_, dom1->nodes_);
15949 + elements_index_ = ++index_counter_;
15950 + DX_write_vect(os, elements_index_, dom1->elements_);
15951 + os << "attribute \"element type\" string \"" << DX_element_name(dom.elt_type_) << "\"" << endl;
15952 + os << "attribute \"ref\" string \"positions\"" << endl;
15953 + } else if (dom2) {
15954 + const entier dim = dom.dimension();
15955 + ArrOfInt dx_coord_index(dim);
15956 + for (entier i = 0; i < dim; i++) {
15957 + dx_coord_index[i] = ++index_counter_;
15958 + const entier n = dom2->coord_[i].size_array();
15960 + tmp.resize(n, 3);
15961 + for (entier j = 0; j < n; j++)
15962 + tmp(j, i) = dom2->coord_[i][j];
15963 + DX_write_vect(os, dx_coord_index[i], tmp);
15965 + nodes_index_ = ++index_counter_;
15966 + os << "object " << nodes_index_ << " class productarray" << endl;
15968 + for (i = dim-1; i >= 0; i--)
15969 + os << " term " << dx_coord_index[i] << endl;
15970 + elements_index_ = ++index_counter_;
15971 + os << "object " << elements_index_ << " class gridconnections counts";
15972 + for (i = dim-1; i >= 0; i--)
15973 + os << " " << dom2->coord_[i].size_array();
15975 + os << "attribute \"element type\" string \"" << ((dim==2)?"quads":"cubes") << "\"" << endl;
15976 + os << "attribute \"ref\" string \"positions\"" << endl;
15977 + const entier n1 = dom2->invalid_positions_.size_array();
15979 + invalid_positions_ = ++index_counter_;
15981 + tmp.resize(n1, 1);
15982 + ArrOfInt & array = tmp;
15983 + for (entier ii = 0; ii < n1; ii++) array[ii] = dom2->invalid_positions_[ii];
15984 + DX_write_vect(os, invalid_positions_, tmp);
15985 + os << "attribute \"ref\" string \"positions\"" << endl;
15990 + tmp.resize(n2, 1);
15991 + ArrOfInt & array = tmp;
15992 + for (entier i = 0; i < n2; i++) array[i] = dom2->invalid_connections_[i];
15993 + DX_write_vect(os, invalid_connections_, tmp);
15994 + os << "attribute \"ref\" string \"connections\"" << endl;
15998 + Journal() << "Error OpenDXWriter::write_geometry domain type not supported" << endl;
15999 + throw DXInternalError;
16001 + fields_names_.add(dom.id_.name_);
16004 +void OpenDXWriter::finish_geometry()
16006 + if (nodes_index_ >= 0) {
16007 + index_counter_++;
16008 + fields_indexes_.append_array(index_counter_);
16009 + DX_stream & os = *os_;
16010 + os << "object " << index_counter_ << " class field" << endl;
16011 + os << " component \"positions\" " << nodes_index_ << endl;
16012 + os << " component \"connections\" " << elements_index_ << endl;
16013 + if (invalid_positions_ >= 0)
16014 + os << " component \"invalid positions\" " << invalid_positions_ << endl;
16015 + if (invalid_connections_ >= 0)
16016 + os << " component \"invalid connections\" " << invalid_connections_ << endl;
16017 + os << " component \"TIME\" " << dx_time_index_ << endl;
16019 + for (entier i=0; i < components_indexes_.size_array(); i++)
16020 + os << " component \"" << components_names_[i] << "\" " << components_indexes_[i] << endl;
16022 + nodes_index_ = -1;
16023 + elements_index_ = -1;
16024 + components_indexes_.resize_array(0);
16025 + components_indexes_.set_smart_resize(1);
16026 + components_names_ = Noms();
16027 + invalid_positions_ = -1;
16028 + invalid_connections_ = -1;
16031 +void OpenDXWriter::write_component(const LataField_base & field)
16033 + index_counter_++;
16034 + const Field<IntTab> * int_field = dynamic_cast<const Field<IntTab>*>(&field);
16035 + const Field<FloatTab> * float_field = dynamic_cast<const Field<FloatTab>*>(&field);
16037 + DX_write_vect(*os_, index_counter_, int_field->data_);
16038 + else if (float_field)
16039 + DX_write_vect(*os_, index_counter_, float_field->data_);
16041 + Journal() << "Error OpenDXWriter::write_component: unknown field type" << endl;
16044 + if (field.localisation_ == LataField_base::ELEM)
16045 + (*os_) << "attribute \"dep\" string \"connections\"" << endl;
16046 + else if (field.localisation_ == LataField_base::SOM)
16047 + (*os_) << "attribute \"dep\" string \"positions\"" << endl;
16050 + ; // no attribute
16052 + components_indexes_.append_array(index_counter_);
16053 + Nom n = field.id_.uname_.get_field_name();
16055 + n += field.id_.uname_.get_localisation();
16056 + components_names_.add(n);
16059 +entier OpenDXWriter::finish(int force_group)
16061 + DX_stream & os = *os_;
16062 + finish_geometry();
16063 + if (force_group || fields_indexes_.size_array() > 1) {
16064 + //DX_stream & os = *os_;
16065 + os << "object " << ++index_counter_ << " class group" << endl;
16066 + for (entier i = 0; i < fields_indexes_.size_array(); i++) {
16067 + os << " member \"" << fields_names_[i] << "\" value " << fields_indexes_[i] << endl;
16070 + os << "END" << endl;
16071 + return index_counter_;
16073 diff --git a/databases/readers/Lata/OpenDXWriter.h b/databases/readers/Lata/OpenDXWriter.h
16074 new file mode 100644
16075 index 0000000..e8f6358
16077 +++ b/databases/readers/Lata/OpenDXWriter.h
16079 +/*****************************************************************************
16081 +* Copyright (c) 2011 - 2013, CEA
16082 +* All rights reserved.
16083 +* Redistribution and use in source and binary forms, with or without
16084 +* modification, are permitted provided that the following conditions are met:
16086 +* * Redistributions of source code must retain the above copyright
16087 +* notice, this list of conditions and the following disclaimer.
16088 +* * Redistributions in binary form must reproduce the above copyright
16089 +* notice, this list of conditions and the following disclaimer in the
16090 +* documentation and/or other materials provided with the distribution.
16091 +* * Neither the name of CEA, nor the
16092 +* names of its contributors may be used to endorse or promote products
16093 +* derived from this software without specific prior written permission.
16095 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
16096 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16097 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16098 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
16099 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16100 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16101 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16102 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16103 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16104 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16106 +*****************************************************************************/
16108 +#ifndef OpenDXWriter_H_
16109 +#define OpenDXWriter_H_
16110 +#include <ArrOfInt.h>
16111 +#include <Lata_tools.h>
16114 +class LataField_base;
16116 +// init_cout(...) or init_file(...)
16117 +// for (i=0; i < nb_geometries; i++) {
16118 +// write_geometry(...);
16119 +// for (j=0; j < nb_fields; j++)
16120 +// write_component(...);
16124 +class OpenDXWriter
16129 + void init_cout(double time, int ascii = 0);
16130 + void init_file(double time, Nom & filename_, int ascii = 0);
16132 + void write_geometry(const Domain & dom);
16133 + void write_component(const LataField_base & field);
16135 + entier finish(int force_group = 0);
16136 + enum DXErrors { DXInternalError };
16139 + void finish_geometry();
16141 + int dx_time_index_;
16142 + int index_counter_;
16143 + // Indexes of all DXfield objects in the file (to build the final group)
16144 + ArrOfInt fields_indexes_;
16145 + // Names of the DXfields:
16146 + Noms fields_names_;
16148 + // Index of the nodes array of the last geometry
16149 + int nodes_index_;
16150 + // Index of the elements array of the last geometry
16151 + int elements_index_;
16152 + // Index of these arrays:
16153 + int invalid_positions_;
16154 + int invalid_connections_;
16155 + // Indexes of the components associated with the last geometry
16156 + ArrOfInt components_indexes_;
16157 + Noms components_names_;
16162 diff --git a/databases/readers/Lata/Operator.h b/databases/readers/Lata/Operator.h
16163 new file mode 100644
16164 index 0000000..2ae94bf
16166 +++ b/databases/readers/Lata/Operator.h
16168 +/*****************************************************************************
16170 +* Copyright (c) 2011 - 2013, CEA
16171 +* All rights reserved.
16172 +* Redistribution and use in source and binary forms, with or without
16173 +* modification, are permitted provided that the following conditions are met:
16175 +* * Redistributions of source code must retain the above copyright
16176 +* notice, this list of conditions and the following disclaimer.
16177 +* * Redistributions in binary form must reproduce the above copyright
16178 +* notice, this list of conditions and the following disclaimer in the
16179 +* documentation and/or other materials provided with the distribution.
16180 +* * Neither the name of CEA, nor the
16181 +* names of its contributors may be used to endorse or promote products
16182 +* derived from this software without specific prior written permission.
16184 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
16185 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16186 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16187 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
16188 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16189 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16190 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16191 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16192 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16193 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16195 +*****************************************************************************/
16197 +#ifndef OPERATORS_H
16198 +#define OPERATORS_H
16199 +#include <LataFilter.h>
16201 +// A tool to "reconnect" several subdomains of a parallel computation:
16202 +// reconnect_geometry() searches for duplicate node coordinates and
16203 +// changes the elements_ and faces_ arrays to use the smallest node
16204 +// index that has the same coordinate. Hence, we recover the connectivity
16205 +// between blocks.
16209 + static void reconnect_geometry(DomainUnstructured & geom, double tolerance, entier nb_nodes_untouched = 0);
16210 + static void apply_renumbering(const ArrOfInt & nodes_renumber, ArrOfInt & data);
16211 + static void search_duplicate_nodes(const FloatTab & src_coord,
16212 + ArrOfInt & nodes_renumber,
16214 + entier nb_nodes_untouched = 0);
16217 +class OperatorClipbox : public Operator
16220 + void build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest);
16221 + void build_field(const Domain & src_domain, const LataField_base & src_field,
16222 + const Domain & dest_domain, LataDeriv<LataField_base> & dest);
16223 + // Renumerotation des sommets, elements et faces par rapport aux donnees brutes lues
16224 + // renum_truc_[new_index] = index in lata file;
16225 + // La renumerotation vient de clip_box et de regularize
16226 + ArrOfInt renum_nodes_;
16227 + ArrOfInt renum_elements_;
16228 + ArrOfInt renum_faces_;
16231 +class OperatorBoundary : public Operator
16234 + OperatorBoundary() { geom_init_ = 0; }
16235 + void build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest);
16236 + void build_field(const Domain & src_domain, const LataField_base & src_field,
16237 + const Domain & dest_domain, LataDeriv<LataField_base> & dest);
16238 + BigEntier compute_memory_size() const {
16240 + memory_size(src_nodes_)
16241 + + memory_size(src_element_)
16242 + + memory_size(src_face_);
16244 + // Renumerotation des sommets, elements et faces par rapport aux donnees brutes lues
16245 + // renum_truc_[new_index] = index in lata file;
16246 + // La renumerotation vient de clip_box et de regularize
16247 + ArrOfInt src_nodes_; // for each boundary node, which node is it in source domain ?
16248 + ArrOfInt src_element_; // same for boundary face vs source domain element
16249 + ArrOfInt src_face_; // local face number on src_element_
16250 + entier geom_init_;
16253 +class OperatorRegularize : public Operator
16256 + OperatorRegularize() { tolerance_ = -1.; geom_init_ = 0; extend_layer_ = 0; }
16257 + void set_tolerance(double epsilon) { tolerance_ = epsilon; }
16258 + void set_extend_layer(entier n) { if (n >= 0) extend_layer_ = n; else extend_layer_ = 0; }
16259 + void build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest);
16260 + void build_field(const Domain & src_domain, const LataField_base & src_field,
16261 + const Domain & dest_domain, LataDeriv<LataField_base> & dest);
16263 + BigEntier compute_memory_size() const {
16265 + memory_size(renum_nodes_)
16266 + + memory_size(renum_elements_)
16267 + + memory_size(renum_faces_);
16269 + // Renumerotation des sommets, elements et faces par rapport aux donnees brutes lues
16270 + // renum_truc_[old_index] = new_index;
16271 + ArrOfInt renum_nodes_;
16272 + ArrOfInt renum_elements_;
16273 + // Pour les faces: les faces de chaque direction du domaine ijk sont numerotees
16274 + // separement: faces de normales X entre 0 et N, faces de normales Y entre 0 et N, etc...
16275 + // Le numero d'une face est egal au plus petit des numeros de ses sommets du le maillage ijk.
16276 + // Renum faces contient le codage suivant:
16277 + // numero de la face = renum_faces_[i] >> 2;
16278 + // direction de la face = (renum_faces_ & 3)
16279 + ArrOfInt renum_faces_;
16280 + double tolerance_;
16281 + entier extend_layer_;
16282 + entier geom_init_;
16285 +class OperatorDualMesh : public Operator
16288 + void build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest);
16289 + void build_field(const Domain & src_domain, const LataField_base & src_field,
16290 + const Domain & dest_domain, LataDeriv<LataField_base> & dest);
16291 + BigEntier compute_memory_size() const { return 0; }
16293 +class OperatorFacesMesh : public Operator
16296 + void build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest);
16297 + void build_field(const Domain & src_domain, const LataField_base & src_field,
16298 + const Domain & dest_domain, LataDeriv<LataField_base> & dest);
16299 + BigEntier compute_memory_size() const { return 0; }
16302 +class OperatorNCMesh : public Operator
16305 + void build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest);
16306 + void build_field(const Domain & src_domain, const LataField_base & src_field,
16307 + const Domain & dest_domain, LataDeriv<LataField_base> & dest);
16308 + BigEntier compute_memory_size() const { return 0; }
16311 +// These generic methods just say that the particular function does not exist:
16312 +void build_geometry_(Operator & op, const Domain & src, LataDeriv<Domain> & dest);
16313 +void build_field_(Operator & op, const Domain & src, const Domain & dest,
16314 + const LataField_base & srcf, LataField_base & destf);
16316 +template<class Op>
16317 +void apply_geometry(Op & op, const Domain & src_domain, LataDeriv<Domain> & dest)
16319 + const DomainUnstructured *src1 = dynamic_cast<const DomainUnstructured*>(&src_domain);
16320 + const DomainIJK *src2 = dynamic_cast<const DomainIJK*>(&src_domain);
16323 + build_geometry_(op, *src1, dest);
16324 + } else if (src2) {
16325 + build_geometry_(op, *src2, dest);
16327 + Journal() << "Error in OperatorDualMesh::build_geometry: unsupported domain type" << endl;
16332 +// See apply_field
16333 +template <class Op, class DomSrc, class DomDest>
16334 +void apply_field3(Op & op, const DomSrc & src_domain, const LataField_base & src_field,
16335 + const DomDest & dest_domain, LataDeriv<LataField_base> & dest)
16337 + const Field<DoubleTab> *src1 = dynamic_cast<const Field<DoubleTab>*> (&src_field);
16338 + const Field<FloatTab> *src2 = dynamic_cast<const Field<FloatTab>*> (&src_field);
16339 + const Field<IntTab> *src3 = dynamic_cast<const Field<IntTab>*> (&src_field);
16342 + build_field_(op, src_domain, dest_domain, *src1, dest.instancie(Field<DoubleTab> ));
16344 + build_field_(op, src_domain, dest_domain, *src2, dest.instancie(Field<FloatTab> ));
16346 + build_field_(op, src_domain, dest_domain, *src3, dest.instancie(Field<IntTab> ));
16348 + Journal() << "Error in apply_field3: unsupported field type" << endl;
16353 +// See apply_field
16354 +template <class Op, class DomSrc>
16355 +void apply_field2(Op & op, const DomSrc & src_domain, const LataField_base & src_field,
16356 + const Domain & dest_domain, LataDeriv<LataField_base> & dest)
16358 + const DomainUnstructured *d1 = dynamic_cast<const DomainUnstructured*>(&dest_domain);
16359 + const DomainIJK *d2 = dynamic_cast<const DomainIJK*>(&dest_domain);
16361 + apply_field3(op, src_domain, src_field, *d1, dest);
16363 + apply_field3(op, src_domain, src_field, *d2, dest);
16365 + Journal() << "Error in apply_field2: unsupported destination domain type" << endl;
16370 +// This template calls the appropriate "build_field_()" method in the given operator.
16371 +// The operator should implement non virtual methods for any usefull combination
16372 +// of source domain type, destination domain type and source field type. This template
16373 +// will call the correct method depending on the effective type of the parameters
16374 +// (determined with dynamic_cast).
16375 +template <class Op>
16376 +void apply_field(Op & op, const Domain & src_domain, const LataField_base & src_field,
16377 + const Domain & dest_domain, LataDeriv<LataField_base> & dest)
16379 + const DomainUnstructured *d1 = dynamic_cast<const DomainUnstructured*>(&src_domain);
16380 + const DomainIJK *d2 = dynamic_cast<const DomainIJK*>(&src_domain);
16382 + apply_field2(op, *d1, src_field, dest_domain, dest);
16384 + apply_field2(op, *d2, src_field, dest_domain, dest);
16386 + Journal() << "Error in apply_field: unsupported source domain type" << endl;
16392 diff --git a/databases/readers/Lata/OperatorBoundary.C b/databases/readers/Lata/OperatorBoundary.C
16393 new file mode 100644
16394 index 0000000..1e10d1a
16396 +++ b/databases/readers/Lata/OperatorBoundary.C
16398 +/*****************************************************************************
16400 +* Copyright (c) 2011 - 2013, CEA
16401 +* All rights reserved.
16402 +* Redistribution and use in source and binary forms, with or without
16403 +* modification, are permitted provided that the following conditions are met:
16405 +* * Redistributions of source code must retain the above copyright
16406 +* notice, this list of conditions and the following disclaimer.
16407 +* * Redistributions in binary form must reproduce the above copyright
16408 +* notice, this list of conditions and the following disclaimer in the
16409 +* documentation and/or other materials provided with the distribution.
16410 +* * Neither the name of CEA, nor the
16411 +* names of its contributors may be used to endorse or promote products
16412 +* derived from this software without specific prior written permission.
16414 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
16415 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16416 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16417 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
16418 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16419 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16420 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16421 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16422 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16423 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16425 +*****************************************************************************/
16427 +#include <LataFilter.h>
16428 +#include <Operator.h>
16429 +#include <Static_Int_Lists.h>
16430 +#include <Connectivite_som_elem.h>
16432 +// Journal level for messages
16433 +#define verb_level 4
16435 +void build_ref_elem_face(const Domain::Element elt_type, IntTab & ref_elem_face)
16437 + static entier faces_sommets_tetra[4][3] =
16442 + static entier faces_sommets_hexa[6][4] =
16443 + { { 0, 2, 4, 6 },
16448 + { 4, 5, 6, 7 } };
16451 + switch(elt_type) {
16452 + case Domain::tetra:
16453 + ref_elem_face.resize(4,3);
16456 + ref_elem_face(i,j) = faces_sommets_tetra[i][j];
16458 + case Domain::hexa:
16459 + ref_elem_face.resize(6,4);
16462 + ref_elem_face(i,j) = faces_sommets_hexa[i][j];
16465 + Journal() << "build_ref_elem_face : non code pour element "
16470 +void build_geometry_(OperatorBoundary & op,
16471 + const DomainUnstructured & src, LataDeriv<Domain> & dest_domain)
16473 + Journal(verb_level) << "OperatorBoundary domain " << src.id_.name_ << endl;
16474 + DomainUnstructured & dest = dest_domain.instancie(DomainUnstructured);
16475 + switch(src.elt_type_) {
16476 + case Domain::tetra: dest.elt_type_ = Domain::triangle; break;
16477 + case Domain::hexa: dest.elt_type_ = Domain::quadri; break;
16479 + Journal() << "Error in OperatorBoundary: element type not supported" << endl;
16483 + Static_Int_Lists som_elem;
16484 + construire_connectivite_som_elem(src.nb_nodes(), src.elements_, som_elem, 0);
16485 + // For each element:
16486 + // for each face of this element
16487 + // how many neighbouring elements ?
16488 + // if only one neighbour, it's a boundary face !
16490 + IntTab element_faces;
16491 + build_ref_elem_face(src.elt_type_, element_faces);
16492 + op.src_element_.set_smart_resize(1);
16493 + op.src_face_.set_smart_resize(1);
16494 + op.src_nodes_.set_smart_resize(1);
16495 + const int nb_nodes_per_face = element_faces.dimension(1);
16496 + const int nb_faces_per_element = element_faces.dimension(0);
16498 + ArrOfInt one_face(nb_nodes_per_face);
16499 + ArrOfInt adjacent_elements;
16501 + // For each node in the source domain, node number on the boundary:
16502 + ArrOfInt nodes_renumber;
16503 + nodes_renumber.resize_array(src.nb_nodes());
16504 + nodes_renumber = -1;
16506 + entier element_index, local_face_index;
16507 + // Browse only real elements (so we don't see boundaries between processors)
16508 + const entier nelem = src.nb_elements() - src.nb_virt_items(LataField_base::ELEM);
16510 + entier count = 0;
16511 + for (element_index = 0; element_index < nelem; element_index++) {
16512 + for (local_face_index = 0; local_face_index < nb_faces_per_element; local_face_index++) {
16513 + for (i = 0; i < nb_nodes_per_face; i++) {
16514 + int local_node = element_faces(local_face_index, i);
16515 + int node = src.elements_(element_index, local_node);
16516 + one_face[i] = node;
16518 + find_adjacent_elements(som_elem, one_face, adjacent_elements);
16519 + if (adjacent_elements.size_array() == 1) {
16520 + op.src_element_.append_array(element_index);
16521 + op.src_face_.append_array(local_face_index);
16522 + for (i = 0; i < nb_nodes_per_face; i++) {
16523 + const entier node = one_face[i];
16524 + entier dest_node = nodes_renumber[node];
16525 + if (dest_node < 0) {
16526 + dest_node = count++;
16527 + op.src_nodes_.append_array(node);
16528 + nodes_renumber[node] = dest_node;
16536 + const entier nb_nodes = op.src_nodes_.size_array();
16537 + const entier dim = src.nodes_.dimension(1);
16538 + dest.nodes_.resize(nb_nodes, dim);
16539 + for (i = 0; i < nb_nodes; i++) {
16540 + const entier n = op.src_nodes_[i];
16541 + for (entier j = 0; j < dim; j++)
16542 + dest.nodes_(i, j) = src.nodes_(n, j);
16545 + // Build elements
16546 + const entier nb_elems = op.src_element_.size_array();
16547 + dest.elements_.resize(nb_elems, nb_nodes_per_face);
16548 + for (i = 0; i < nb_elems; i++) {
16549 + const entier elem = op.src_element_[i];
16550 + const entier face = op.src_face_[i];
16551 + for (entier j = 0; j < nb_nodes_per_face; j++) {
16552 + const entier src_node = src.elements_(elem, element_faces(face, j));
16553 + dest.elements_(i, j) = nodes_renumber[src_node];
16556 + op.geom_init_ = 1;
16559 +template <class TabType>
16560 +void build_field_(OperatorBoundary & op,
16561 + const DomainUnstructured & src_domain,
16562 + const DomainUnstructured & dest_domain,
16563 + const Field<TabType> & src,
16564 + Field<TabType> & dest)
16566 + if (!op.geom_init_) {
16567 + // Must fill the renum_.... arrays first !
16568 + LataDeriv<Domain> destb;
16569 + op.build_geometry(src_domain, destb);
16571 + dest.component_names_ = src.component_names_;
16572 + dest.localisation_ = src.localisation_;
16573 + dest.nature_ = src.nature_;
16574 + if (dest.localisation_ == LataField_base::FACES)
16575 + dest.localisation_ = LataField_base::ELEM;
16577 + const entier nb_compo = src.data_.dimension(1);
16578 + entier i, sz = 0;
16579 + switch(src.localisation_) {
16580 + case LataField_base::ELEM:
16581 + sz = dest_domain.nb_elements();
16582 + dest.data_.resize(sz, nb_compo);
16583 + for (i = 0; i < sz; i++) {
16584 + const entier old_i = op.src_element_[i];
16585 + for (entier j = 0; j < nb_compo; j++)
16586 + dest.data_(i, j) = src.data_(old_i, j);
16589 + case LataField_base::SOM:
16590 + sz = dest_domain.nb_nodes();
16591 + dest.data_.resize(sz, nb_compo);
16592 + for (i = 0; i < sz; i++) {
16593 + const entier old_i = op.src_nodes_[i];
16594 + for (entier j = 0; j < nb_compo; j++)
16595 + dest.data_(i, j) = src.data_(old_i, j);
16598 + case LataField_base::FACES:
16599 + sz = dest_domain.nb_elements();
16600 + dest.data_.resize(sz, nb_compo);
16601 + for (i = 0; i < sz; i++) {
16602 + const entier old_i = src_domain.elem_faces_(op.src_element_[i], op.src_face_[i]);
16603 + for (entier j = 0; j < nb_compo; j++)
16604 + dest.data_(i, j) = src.data_(old_i, j);
16608 + Journal() << "Error in OperatorRegularize::build_field_: unknown localisation" << endl;
16613 +void OperatorBoundary::build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest)
16615 + apply_geometry(*this, src_domain, dest);
16618 +void OperatorBoundary::build_field(const Domain & src_domain, const LataField_base & src_field,
16619 + const Domain & dest_domain, LataDeriv<LataField_base> & dest)
16621 + apply_field(*this, src_domain, src_field, dest_domain, dest);
16625 diff --git a/databases/readers/Lata/OperatorDualMesh.C b/databases/readers/Lata/OperatorDualMesh.C
16626 new file mode 100644
16627 index 0000000..9ecd859
16629 +++ b/databases/readers/Lata/OperatorDualMesh.C
16631 +/*****************************************************************************
16633 +* Copyright (c) 2011 - 2013, CEA
16634 +* All rights reserved.
16635 +* Redistribution and use in source and binary forms, with or without
16636 +* modification, are permitted provided that the following conditions are met:
16638 +* * Redistributions of source code must retain the above copyright
16639 +* notice, this list of conditions and the following disclaimer.
16640 +* * Redistributions in binary form must reproduce the above copyright
16641 +* notice, this list of conditions and the following disclaimer in the
16642 +* documentation and/or other materials provided with the distribution.
16643 +* * Neither the name of CEA, nor the
16644 +* names of its contributors may be used to endorse or promote products
16645 +* derived from this software without specific prior written permission.
16647 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
16648 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16649 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16650 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
16651 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16652 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16653 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16654 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16655 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16656 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16658 +*****************************************************************************/
16660 +#include <LataFilter.h>
16661 +#include <Operator.h>
16664 +#define verb_level 4
16666 +void build_geometry_(OperatorDualMesh & op,
16667 + const DomainUnstructured & src, LataDeriv<Domain> & dest_domain)
16669 + Journal(verb_level) << "OperatorDualMesh geometry(unstructured) " << src.id_.name_ << endl;
16670 + if (!src.faces_ok()) {
16671 + Journal() << "Error in OperatorDualMesh::build_geometry: source domain has no faces data" << endl;
16674 + const int max_nb_som_face = 3; // for tetrahedra
16675 + if (src.elt_type_ != Domain::triangle && src.elt_type_ != Domain::tetra) {
16676 + Journal() << "Error in OperatorDualMesh::build_geometry: cannot operate on unstructured mesh with this element type" << endl;
16679 + const entier nb_som = src.nodes_.dimension(0);
16680 + const entier nb_elem = src.elem_faces_.dimension(0); // Not elements_, in case elem_faces_ has no virtual data.
16681 + const entier dim = src.dimension();
16683 + DomainUnstructured & dest = dest_domain.instancie(DomainUnstructured);
16684 + dest.id_ = src.id_;
16685 + dest.id_.name_ += "_dual";
16686 + dest.elt_type_ = src.elt_type_;
16688 + dest.nodes_ = src.nodes_;
16689 + dest.nodes_.resize(nb_som + nb_elem, dim);
16690 + src.compute_cell_center_coordinates(dest.nodes_, nb_som);
16692 + const entier nb_faces_elem = src.elem_faces_.dimension(1);
16693 + const entier nb_som_face = src.faces_.dimension(1);
16694 + const entier nb_som_elem = src.elements_.dimension(1);
16695 + dest.elements_.resize(nb_elem * nb_faces_elem, nb_som_elem);
16697 + for (int i = 0; i < nb_elem; i++) {
16698 + const int central_node = nb_som + i;
16699 + for (int j = 0; j < nb_faces_elem; j++) {
16700 + const int face = src.elem_faces_(i, j);
16701 + dest.elements_(index, 0) = central_node;
16702 + for (int k = 0; k < loop_max(nb_som_face, max_nb_som_face); k++) {
16703 + dest.elements_(index, k+1) = src.faces_(face, k);
16704 + break_loop(k, nb_som_face);
16709 + const entier nb_elem_virt = src.nb_virt_items(LataField_base::ELEM);
16710 + dest.set_nb_virt_items(LataField_base::ELEM, nb_elem_virt * nb_faces_elem);
16713 +// Builds a field on the dual domain from the field on the source domain.
16714 +// Source field must be located at faces.
16715 +// (destination field is located at the elements. the value for an element
16716 +// is the value associated to the adjacent face of the source domain).
16717 +template <class TabType>
16718 +void build_field_(OperatorDualMesh & op,
16719 + const DomainUnstructured & src_domain,
16720 + const DomainUnstructured & dest_domain,
16721 + const Field<TabType> & src,
16722 + Field<TabType> & dest)
16724 + Journal(verb_level) << "OperatorDualMesh field(unstructured) " << src.id_.uname_ << endl;
16725 + dest.component_names_ = src.component_names_;
16726 + dest.localisation_ = LataField_base::ELEM;
16727 + dest.nature_ = src.nature_;
16728 + const entier nb_elem = src_domain.elements_.dimension(0);
16729 + const entier nb_face_elem = src_domain.elem_faces_.dimension(1);
16730 + const entier nb_comp = src.data_.dimension(1);
16731 + dest.data_.resize(nb_elem * nb_face_elem, nb_comp);
16733 + for (int i = 0; i < nb_elem; i++) {
16734 + for (int j = 0; j < nb_face_elem; j++) {
16735 + const int face = src_domain.elem_faces_(i, j);
16736 + for (int k = 0; k < nb_comp; k++)
16737 + dest.data_(index, k) = src.data_(face, k);
16743 +void build_geometry_(OperatorDualMesh & op,
16744 + const DomainIJK & src, LataDeriv<Domain> & dest_domain)
16746 + Journal(verb_level) << "OperatorDualMesh geometry(ijk) " << src.id_.name_ << endl;
16747 + if (src.elt_type_ != Domain::quadri && src.elt_type_ != Domain::hexa) {
16748 + Journal() << "Error in OperatorDualMesh::build_geometry: cannot operate on unstructured mesh with this element type" << endl;
16752 + DomainIJK & dest = dest_domain.instancie(DomainIJK);
16753 + dest.elt_type_ = src.elt_type_;
16754 + const entier dim = src.dimension();
16755 + for (entier i_dim = 0; i_dim < dim; i_dim++) {
16756 + const ArrOfFloat & c1 = src.coord_[i_dim];
16757 + ArrOfFloat & c2 = dest.coord_.add(ArrOfFloat());
16758 + const int n = c1.size_array() - 1;
16759 + c2.resize_array(n*2+1);
16760 + for (int i = 0; i < n; i++) {
16762 + c2[i*2+1] = (c1[i] + c1[i+1]) * 0.5;
16767 + if (src.invalid_connections_.size_array() > 0) {
16768 + dest.invalid_connections_.resize_array(dest.nb_elements());
16769 + dest.invalid_connections_ = 0;
16772 + const entier ni = dest.coord_[0].size_array()-1;
16773 + const entier nj = dest.coord_[1].size_array()-1;
16774 + const entier nk = (dim==3) ? (dest.coord_[2].size_array()-1) : 1;
16775 + const entier ni_src = src.coord_[0].size_array() - 1;
16776 + const entier nj_src = src.coord_[1].size_array() - 1;
16777 + for (int k = 0; k < nk; k++) {
16778 + const int k_src = k / 2;
16779 + for (int j = 0; j < nj; j++) {
16780 + const int j_src = j / 2;
16781 + const int idx_source = (k_src * nj_src + j_src) * ni_src;
16782 + for (int i = 0; i < ni; i++) {
16783 + const int idx = idx_source + i / 2;
16784 + if (src.invalid_connections_[idx])
16785 + dest.invalid_connections_.setbit(index);
16791 + dest.virtual_layer_begin_ = 2 * src.virtual_layer_begin_;
16792 + dest.virtual_layer_end_ = 2 * src.virtual_layer_end_;
16794 +#define IJK(i,j,k) (k*nj_ni_src + j*ni_src + i)
16796 +template <class TabType>
16797 +void build_field_(OperatorDualMesh & op,
16798 + const DomainIJK & src_domain,
16799 + const DomainIJK & dest_domain,
16800 + const Field<TabType> & src,
16801 + Field<TabType> & dest)
16803 + Journal(verb_level) << "OperatorDualMesh field(ijk) " << src.id_.uname_ << endl;
16804 + dest.component_names_ = src.component_names_;
16805 + dest.localisation_ = LataField_base::ELEM;
16806 + dest.nature_ = LataDBField::VECTOR;
16807 + const entier dim = src_domain.dimension();
16810 + // Loop on destination elements
16811 + const entier ni = dest_domain.coord_[0].size_array()-1;
16812 + const entier nj = dest_domain.coord_[1].size_array()-1;
16813 + const entier nk = (dim==3) ? (dest_domain.coord_[2].size_array()-1) : 1;
16814 + dest.data_.resize(ni*nj*nk, dim);
16815 + const entier ni_src = src_domain.coord_[0].size_array();
16816 + const entier nj_ni_src = src_domain.coord_[1].size_array() * ni_src;
16817 + for (int k = 0; k < nk; k++) {
16818 + const int k2 = k/2;
16819 + const int k3 = (k+1)/2;
16820 + for (int j = 0; j < nj; j++) {
16821 + const int j2 = j/2;
16822 + const int j3 = (j+1)/2;
16823 + for (int i = 0; i < ni; i++) {
16824 + const int i2 = i/2;
16825 + const int i3 = (i+1)/2;
16826 + dest.data_(index, 0) = src.data_(IJK(i3,j2,k2), 0);
16827 + dest.data_(index, 1) = src.data_(IJK(i2,j3,k2), 1);
16829 + dest.data_(index, 2) = src.data_(IJK(i2,j2,k3), 2);
16838 +void OperatorDualMesh::build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest)
16840 + apply_geometry(*this, src_domain, dest);
16843 +void OperatorDualMesh::build_field(const Domain & src_domain, const LataField_base & src_field,
16844 + const Domain & dest_domain, LataDeriv<LataField_base> & dest)
16846 + if (src_field.localisation_ != LataField_base::FACES) {
16847 + Journal() << "Error in OperatorDualMesh::build_field: source field is not located at faces" << endl;
16850 + apply_field(*this, src_domain, src_field, dest_domain, dest);
16853 diff --git a/databases/readers/Lata/OperatorFacesMesh.C b/databases/readers/Lata/OperatorFacesMesh.C
16854 new file mode 100644
16855 index 0000000..6aa85a5
16857 +++ b/databases/readers/Lata/OperatorFacesMesh.C
16859 +/*****************************************************************************
16861 +* Copyright (c) 2011 - 2013, CEA
16862 +* All rights reserved.
16863 +* Redistribution and use in source and binary forms, with or without
16864 +* modification, are permitted provided that the following conditions are met:
16866 +* * Redistributions of source code must retain the above copyright
16867 +* notice, this list of conditions and the following disclaimer.
16868 +* * Redistributions in binary form must reproduce the above copyright
16869 +* notice, this list of conditions and the following disclaimer in the
16870 +* documentation and/or other materials provided with the distribution.
16871 +* * Neither the name of CEA, nor the
16872 +* names of its contributors may be used to endorse or promote products
16873 +* derived from this software without specific prior written permission.
16875 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
16876 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16877 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16878 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
16879 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16880 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16881 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16882 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16883 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16884 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16886 +*****************************************************************************/
16888 +#include <LataFilter.h>
16889 +#include <Operator.h>
16892 +#define verb_level 4
16894 +void build_geometry_(OperatorFacesMesh & op,
16895 + const DomainUnstructured & src, LataDeriv<Domain> & dest_domain)
16897 + Journal(verb_level) << "OperatorFacesMesh geometry(unstructured) " << src.id_.name_ << endl;
16898 + if (!src.faces_ok()) {
16899 + Journal() << "Error in OperatorFacesMesh::build_geometry: source domain has no faces data" << endl;
16902 + // const int max_nb_som_face = 3; // for tetrahedra
16903 + if (src.elt_type_ != Domain::triangle && src.elt_type_ != Domain::polygone && src.elt_type_ != Domain::tetra && src.elt_type_ != Domain::polyedre) {
16904 + Journal() << "Error in OperatorFacesMesh::build_geometry: cannot operate on unstructured mesh with this element type" << endl;
16907 + // const entier nb_som = src.nodes_.dimension(0);
16908 + // const entier nb_elem = src.elem_faces_.dimension(0); // Not elements_, in case elem_faces_ has no virtual data.
16909 + //const entier dim = src.dimension();
16911 + DomainUnstructured & dest = dest_domain.instancie(DomainUnstructured);
16912 + dest.id_ = src.id_;
16913 + dest.id_.name_ += "_centerfaces";
16914 + if (src.elt_type_ == Domain::triangle || src.elt_type_ == Domain::polygone)
16915 + dest.elt_type_=Domain::line;
16916 + else if ( src.elt_type_ == Domain::tetra)
16917 + dest.elt_type_=Domain::triangle;
16918 + else if ( src.elt_type_ == Domain::polyedre)
16919 + dest.elt_type_=Domain::polygone;
16921 + dest.nodes_ = src.nodes_;
16922 + dest.elements_ = src.faces_;
16927 + const entier nb_elem_virt = src.nb_virt_items(LataField_base::FACES);
16928 + dest.set_nb_virt_items(LataField_base::ELEM, nb_elem_virt );
16931 +// Builds a field on the dual domain from the field on the source domain.
16932 +// Source field must be located at faces.
16933 +// (destination field is located at the elements. the value for an element
16934 +// is the value associated to the adjacent face of the source domain).
16935 +template <class TabType>
16936 +void build_field_(OperatorFacesMesh & op,
16937 + const DomainUnstructured & src_domain,
16938 + const DomainUnstructured & dest_domain,
16939 + const Field<TabType> & src,
16940 + Field<TabType> & dest)
16942 + Journal(verb_level) << "OperatorFacesMesh field(unstructured) " << src.id_.uname_ << endl;
16943 + dest.component_names_ = src.component_names_;
16944 + dest.localisation_ = LataField_base::ELEM;
16945 + dest.nature_ = src.nature_;
16947 + dest.data_=src.data_;
16952 +void build_geometry_(OperatorFacesMesh & op,
16953 + const DomainIJK & src, LataDeriv<Domain> & dest_domain)
16955 + Journal(verb_level) << "OperatorFacesMesh geometry(ijk) " << src.id_.name_ << endl;
16956 + Journal() << "Error in OperatorFacesMesh::build_geometry: cannot operate on domainIJK" << endl;
16960 +template <class TabType>
16961 +void build_field_(OperatorFacesMesh & op,
16962 + const DomainIJK & src_domain,
16963 + const DomainIJK & dest_domain,
16964 + const Field<TabType> & src,
16965 + Field<TabType> & dest)
16967 + Journal(verb_level) << "OperatorFacesMesh field(ijk) " << src.id_.uname_ << endl;
16968 + Journal() << "Error in OperatorFacesMesh::build_geometry: cannot operate on domainIJK" << endl;
16974 +void OperatorFacesMesh::build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest)
16976 + apply_geometry(*this, src_domain, dest);
16979 +void OperatorFacesMesh::build_field(const Domain & src_domain, const LataField_base & src_field,
16980 + const Domain & dest_domain, LataDeriv<LataField_base> & dest)
16982 + if (src_field.localisation_ != LataField_base::FACES) {
16983 + Journal() << "Error in OperatorFacesMesh::build_field: source field is not located at faces" << endl;
16986 + apply_field(*this, src_domain, src_field, dest_domain, dest);
16989 diff --git a/databases/readers/Lata/OperatorReconnect.C b/databases/readers/Lata/OperatorReconnect.C
16990 new file mode 100644
16991 index 0000000..4cabccc
16993 +++ b/databases/readers/Lata/OperatorReconnect.C
16995 +/*****************************************************************************
16997 +* Copyright (c) 2011 - 2013, CEA
16998 +* All rights reserved.
16999 +* Redistribution and use in source and binary forms, with or without
17000 +* modification, are permitted provided that the following conditions are met:
17002 +* * Redistributions of source code must retain the above copyright
17003 +* notice, this list of conditions and the following disclaimer.
17004 +* * Redistributions in binary form must reproduce the above copyright
17005 +* notice, this list of conditions and the following disclaimer in the
17006 +* documentation and/or other materials provided with the distribution.
17007 +* * Neither the name of CEA, nor the
17008 +* names of its contributors may be used to endorse or promote products
17009 +* derived from this software without specific prior written permission.
17011 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17012 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17013 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17014 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
17015 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17016 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17017 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17018 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17019 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17020 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17022 +*****************************************************************************/
17024 +#include <Operator.h>
17025 +#include <Octree_Double.h>
17027 +#define verb_level 4
17029 +// Description: Find duplicate coordinates in the "coord" array.
17030 +// nodes_renumber will have dimension src_coord.dimension(0)
17031 +// nodes_renumber[i] = i if the node imust be conserved,
17032 +// nodes_renumber[i] = j if the node i is identical to node j. We always have j<i
17033 +// eps = tolerance in each direction to consider that two nodes are identical
17034 +// nb_nodes_untouched : do not search duplicate nodes in the "nb_nodes_untouched"
17035 +// first nodes. The remaining nodes are still compared to all nodes.
17036 +void Reconnect::search_duplicate_nodes(const FloatTab & src_coord,
17037 + ArrOfInt & nodes_renumber,
17039 + entier nb_nodes_untouched)
17041 + // Create a temporary DoubleTab (coords are normally float)
17042 + const entier nb_nodes = src_coord.dimension(0);
17043 + const entier dim = src_coord.dimension(1);
17045 + // Build an octree with all coordinates
17046 + Journal(verb_level+1) << " Building octree" << endl;
17047 + DoubleTab coords;
17048 + coords.resize(nb_nodes, dim);
17049 + for (i = 0; i < nb_nodes; i++)
17050 + for (entier j = 0; j < dim; j++)
17051 + coords(i,j) = src_coord(i,j);
17052 + Octree_Double octree;
17053 + octree.build_nodes(coords, 0 /* no virtual nodes */);
17055 + Journal(verb_level+1) << " Searching duplicate nodes" << endl;
17056 + nodes_renumber.resize_array(nb_nodes);
17057 + for (i = 0; i < nb_nodes; i++)
17058 + nodes_renumber[i] = i;
17059 + // For each node, are there several nodes within epsilon ?
17060 + ArrOfInt node_list;
17061 + node_list.set_smart_resize(1);
17062 + entier count = 0; // Number of nodes renumbered
17063 + for (i = 0; i < nb_nodes; i++) {
17064 + if (nodes_renumber[i] != i)
17065 + continue; // node already suppressed
17067 + const double x = coords(i, 0);
17068 + const double y = (dim>1) ? coords(i, 1) : 0.;
17069 + const double z = (dim>2) ? coords(i, 2) : 0.;
17070 + octree.search_elements_box(x-eps, y-eps, z-eps,
17071 + x+eps, y+eps, z+eps,
17073 + Octree_Double::search_nodes_close_to(x, y, z,
17074 + coords, node_list,
17076 + const entier n = node_list.size_array();
17078 + for (entier j = 0; j < n; j++) {
17079 + // Change only nodes with rank > i
17080 + const entier node = node_list[j];
17082 + nodes_renumber[node] = i;
17088 + Journal(verb_level+1) << " " << count << " duplicate nodes will be removed" << endl;
17091 +void Reconnect::apply_renumbering(const ArrOfInt & nodes_renumber, ArrOfInt & data)
17093 + entier ntot = data.size_array();
17095 + for (i = 0; i < ntot; i++) {
17096 + const entier node = data[i];
17097 + const entier n = nodes_renumber[node];
17103 +// Description: updates the elements_ and faces_ arrays of the domain so that
17104 +// all nodes having the same coordinates are replaced by one unique node
17105 +// in these arrays. See search_duplicate_nodes for nb_nodes_untouched description.
17106 +void Reconnect::reconnect_geometry(DomainUnstructured & geom, double tolerance, entier nb_nodes_untouched)
17108 + Journal(verb_level) << "Reconnect domain " << geom.id_.name_ << endl;
17110 + ArrOfInt nodes_renumber;
17111 + search_duplicate_nodes(geom.nodes_, nodes_renumber, tolerance, nb_nodes_untouched);
17113 + apply_renumbering(nodes_renumber, geom.elements_);
17115 + if (geom.faces_ok())
17116 + apply_renumbering(nodes_renumber, geom.faces_);
17120 diff --git a/databases/readers/Lata/OperatorRegularize.C b/databases/readers/Lata/OperatorRegularize.C
17121 new file mode 100644
17122 index 0000000..5bbde88
17124 +++ b/databases/readers/Lata/OperatorRegularize.C
17126 +/*****************************************************************************
17128 +* Copyright (c) 2011 - 2013, CEA
17129 +* All rights reserved.
17130 +* Redistribution and use in source and binary forms, with or without
17131 +* modification, are permitted provided that the following conditions are met:
17133 +* * Redistributions of source code must retain the above copyright
17134 +* notice, this list of conditions and the following disclaimer.
17135 +* * Redistributions in binary form must reproduce the above copyright
17136 +* notice, this list of conditions and the following disclaimer in the
17137 +* documentation and/or other materials provided with the distribution.
17138 +* * Neither the name of CEA, nor the
17139 +* names of its contributors may be used to endorse or promote products
17140 +* derived from this software without specific prior written permission.
17142 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17143 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17144 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17145 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
17146 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17147 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17148 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17149 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17150 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17151 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17153 +*****************************************************************************/
17155 +#include <LataFilter.h>
17156 +#include <Operator.h>
17158 +#define verb_level 4
17160 +template<class T, class Tab> int search_in_ordered_vect(T x, const Tab & v, const T epsilon) {
17161 + if (!v.size_array())
17165 + int i2 = (int)v.size_array()-1;
17166 + while (i1 != i2) {
17168 + if (epsilon+ v[i] < x)
17175 + if (((v[i1] - x) * (v[i1] - x))<= (epsilon*epsilon) )
17181 +template<class T, class Tab>
17182 +static void retirer_doublons(Tab & tab, const T epsilon)
17186 + const int n = tab.size_array();
17187 + T last_tab_i = -1e40;
17188 + for (j = 0; j < n; j++) {
17189 + const T x = tab[j];
17190 + assert(x >= last_tab_i); // Array must be sorted
17191 + if (x - last_tab_i > epsilon) {
17197 + tab.resize_array(i);
17200 +void build_geometry_(OperatorRegularize & op,
17201 + const DomainUnstructured & src, LataDeriv<Domain> & dest_domain)
17203 + Journal(verb_level) << "OperatorRegularize domain " << src.id_.name_ << endl;
17204 + if (src.elt_type_ != Domain::quadri && src.elt_type_ != Domain::hexa) {
17205 + Journal() << "Error in OperatorRegularize::build_geometry: cannot operate on unstructured mesh with this element type" << endl;
17209 + DomainIJK & dest = dest_domain.instancie(DomainIJK);
17210 + dest.elt_type_ = src.elt_type_;
17211 + const entier nsom = src.nodes_.dimension(0);
17212 + const entier dim = src.nodes_.dimension(1);
17213 + ArrOfInt nb_som_dir(dim);
17215 + double product_n = 1.;
17216 + for (entier i_dim = 0; i_dim < dim; i_dim++) {
17217 + ArrOfFloat & coord = dest.coord_.add(ArrOfFloat());
17218 + coord.resize_array(nsom);
17220 + for (i = 0; i < nsom; i++)
17221 + coord[i] = src.nodes_(i, i_dim);
17222 + coord.ordonne_array();
17223 + retirer_doublons(coord, op.tolerance_);
17224 + product_n *= coord.size_array();
17225 + // Add extended domain layer:
17226 + if (coord.size_array() > 1) {
17227 + const entier n = coord.size_array();
17228 + const entier l = op.extend_layer_;
17229 + coord.resize_array(n + l * 2);
17230 + double x0 = coord[n-1];
17231 + double delta = coord[n-2] - x0;
17232 + for (i = 1; i <= l; i++)
17233 + coord[n + l + i] = x0 + delta * i;
17234 + for (i = l-1; i >= 0; i--)
17235 + coord[i + l] = coord[i];
17237 + delta = coord[l+1] - x0;
17238 + for (i = 1; i <= l; i++)
17239 + coord[l - i] = x0 - delta * i;
17241 + nb_som_dir[i_dim] = coord.size_array();
17243 + // Verifying that unique has deleted many points...
17244 + // If well organised, nsom=nx*ny*nz
17245 + // If chaos, nsom=(nx+ny+nz)/3
17246 + // We want to verify that we are nearer to organisation than to chaos !
17247 + if (product_n > (double) nsom * (double) nsom - 1.) {
17248 + Journal() << "Positions do not seam regular !" << endl;
17253 + op.renum_nodes_.resize_array(nsom);
17254 + int nb_som_ijk = 1;
17255 + for (i = 0; i < dim; i++)
17256 + nb_som_ijk *= nb_som_dir[i];
17257 + IntTab ijk_indexes;
17258 + ijk_indexes.resize(nsom, dim);
17259 + for (i = 0; i < nsom; i++) {
17260 + entier ijk_index = 0;
17261 + for (int j = dim-1; j >= 0; j--) {
17262 + const double x = src.nodes_(i,j);
17263 + int index = search_in_ordered_vect(x, dest.coord_[j],op.tolerance_);
17265 + Journal() << "Error: coordinate (" << i << "," << j << ") = " << x << " not found in regularize" << endl
17266 + << "Try reducing regularize tolerance value (option regularize=epsilon)" << endl;
17269 + ijk_indexes(i, j) = index;
17270 + ijk_index += index;
17272 + ijk_index *= nb_som_dir[j-1];
17274 + op.renum_nodes_[i] = ijk_index;
17276 + const int max_index = max_array(nb_som_dir);
17277 + int nb_elems_ijk = 1;
17278 + for (i = 0; i < dim; i++)
17279 + nb_elems_ijk *= nb_som_dir[i] - 1;
17280 + dest.invalid_connections_.resize_array(nb_elems_ijk);
17281 + dest.invalid_connections_ = 1; // Everything invalid by default
17282 + const int nelem = src.elements_.dimension(0);
17283 + const int nb_som_elem = src.elements_.dimension(1);
17284 + op.renum_elements_.resize_array(nelem);
17285 + // Pour chaque element, indice dans le maillage ijk du plus sommet le plus proche de l'origine
17286 + // (pour les faces...)
17287 + ArrOfInt idx_elem_som;
17288 + idx_elem_som.resize_array(nelem);
17289 + int min_index[3];
17290 + for (i = 0; i < nelem; i++) {
17291 + min_index[0] = min_index[1] = min_index[2] = max_index;
17292 + for (int j = 0; j < nb_som_elem; j++) {
17293 + int node = src.elements_(i,j);
17294 + for (int k = 0; k < loop_max(dim, 3); k++) {
17295 + int idx = ijk_indexes(node, k);
17296 + min_index[k] = (idx < min_index[k]) ? idx : min_index[k];
17297 + break_loop(k,dim);
17301 + entier idx_som = 0;
17303 + idx = min_index[0];
17305 + } else if (dim == 2) {
17306 + idx = min_index[1] * (nb_som_dir[0]-1) + min_index[0];
17307 + idx_som = min_index[1] * nb_som_dir[0] + min_index[0];
17308 + } else if (dim == 3) {
17309 + idx = (min_index[2] * (nb_som_dir[1]-1) + min_index[1]) * (nb_som_dir[0]-1) + min_index[0];
17310 + idx_som = (min_index[2] * nb_som_dir[1] + min_index[1]) * nb_som_dir[0] + min_index[0];
17313 + op.renum_elements_[i] = idx;
17314 + dest.invalid_connections_.clearbit(idx);
17315 + idx_elem_som[i] = idx_som;
17318 + if (src.faces_ok()) {
17319 + const int nfaces = src.faces_.dimension(0);
17320 + op.renum_faces_.resize_array(nfaces);
17321 + op.renum_faces_ = -1;
17322 + const int nb_elem_face = src.elem_faces_.dimension(1);
17323 + ArrOfInt delta_dir(dim);
17324 + delta_dir[0] = 1;
17325 + for (i = 1; i < dim; i++)
17326 + delta_dir[i] = delta_dir[i-1] * nb_som_dir[i-1];
17327 + for (i = 0; i < nelem; i++) {
17328 + // Les faces haut, gauche et arriere du cube a l'origine portent le numero 0
17329 + // Voir DomaineIJK pour la convention sur la numerotation des faces
17330 + for (entier j = 0; j < nb_elem_face; j++) {
17331 + const entier i_face = src.elem_faces_(i, j);
17332 + entier dir = j % dim;
17333 + entier index = idx_elem_som[i];
17335 + index += delta_dir[dir];
17336 + // Encodage du numero de la face et de la direction
17337 + index = (index << 2) + dir;
17338 + if (op.renum_faces_[i_face] < 0) {
17339 + op.renum_faces_[i_face] = index;
17340 + } else if (op.renum_faces_[i_face] != index) {
17341 + Journal() << "Error in OperatorRegularize: faces renumbering failed" << endl;
17347 + op.geom_init_ = 1;
17350 +template <class TabType>
17351 +void build_field_(OperatorRegularize & op,
17352 + const DomainUnstructured & src_domain,
17353 + const DomainIJK & dest_domain,
17354 + const Field<TabType> & src,
17355 + Field<TabType> & dest)
17357 + Journal(verb_level) << "OperatorRegularize field " << src.id_.uname_ << endl;
17358 + if (!op.geom_init_) {
17359 + // Must fill the renum_.... arrays first !
17360 + LataDeriv<Domain> destr;
17361 + op.build_geometry(src_domain, destr);
17363 + dest.component_names_ = src.component_names_;
17364 + dest.localisation_ = src.localisation_;
17365 + dest.nature_ = src.nature_;
17366 + const entier sz = src.data_.dimension(0);
17367 + const entier nb_compo = src.data_.dimension(1);
17369 + switch(src.localisation_) {
17370 + case LataField_base::ELEM:
17371 + dest.data_.resize(dest_domain.nb_elements(), nb_compo);
17372 + for (i = 0; i < sz; i++) {
17373 + const entier new_i = op.renum_elements_[i];
17374 + for (entier j = 0; j < nb_compo; j++)
17375 + dest.data_(new_i, j) = src.data_(i, j);
17378 + case LataField_base::SOM:
17379 + dest.data_.resize(dest_domain.nb_nodes(), nb_compo);
17380 + for (i = 0; i < sz; i++) {
17381 + const entier new_i = op.renum_nodes_[i];
17382 + for (entier j = 0; j < nb_compo; j++)
17383 + dest.data_(new_i, j) = src.data_(i, j);
17386 + case LataField_base::FACES:
17388 + if (nb_compo != 1) {
17389 + Journal() << "Error in OperatorRegularize: field at faces has nb_compo != 1" << endl;
17392 + dest.nature_ = LataDBField::VECTOR;
17393 + const entier nb_dim = dest_domain.dimension();
17394 + dest.data_.resize(dest_domain.nb_faces(), nb_dim);
17395 + // Field is interpreted as normal component to the face
17396 + for (i = 0; i < sz; i++) {
17397 + const entier code = op.renum_faces_[i];
17398 + // decodage numero et direction de la face:
17399 + const entier new_i = code >> 2;
17400 + const entier direction = (code & 3);
17401 + dest.data_(new_i, direction) = src.data_(i, 0);
17406 + Journal() << "Error in OperatorRegularize::build_field_: unknown localisation" << endl;
17411 +void OperatorRegularize::build_geometry(const Domain & src_domain, LataDeriv<Domain> & dest)
17413 + apply_geometry(*this, src_domain, dest);
17416 +void OperatorRegularize::build_field(const Domain & src_domain, const LataField_base & src_field,
17417 + const Domain & dest_domain, LataDeriv<LataField_base> & dest)
17419 + apply_field(*this, src_domain, src_field, dest_domain, dest);
17422 diff --git a/databases/readers/Lata/Rebuild_virtual_layer.C b/databases/readers/Lata/Rebuild_virtual_layer.C
17423 new file mode 100644
17424 index 0000000..ac29742
17426 +++ b/databases/readers/Lata/Rebuild_virtual_layer.C
17428 +/*****************************************************************************
17430 +* Copyright (c) 2011 - 2013, CEA
17431 +* All rights reserved.
17432 +* Redistribution and use in source and binary forms, with or without
17433 +* modification, are permitted provided that the following conditions are met:
17435 +* * Redistributions of source code must retain the above copyright
17436 +* notice, this list of conditions and the following disclaimer.
17437 +* * Redistributions in binary form must reproduce the above copyright
17438 +* notice, this list of conditions and the following disclaimer in the
17439 +* documentation and/or other materials provided with the distribution.
17440 +* * Neither the name of CEA, nor the
17441 +* names of its contributors may be used to endorse or promote products
17442 +* derived from this software without specific prior written permission.
17444 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17445 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17446 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17447 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
17448 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17449 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17450 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17451 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17452 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17453 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17455 +*****************************************************************************/
17457 +#include <LataFilter.h>
17458 +#include <Connectivite_som_elem.h>
17459 +#include <Operator.h>
17460 +#include <Static_Int_Lists.h>
17461 +#include <Rebuild_virtual_layer.h>
17462 +void find_virtual_layer(DomainUnstructured & domain,
17463 + IntTab & virtual_elements,
17464 + IntTab & joints_virtual_elements,
17465 + double tolerance)
17467 + Journal(4) << "Searching virtual elements for domain " << domain.id_.name_ << endl;
17468 + // Step 1 : find duplicate nodes
17469 + ArrOfInt nodes_renumber;
17470 + Reconnect::search_duplicate_nodes(domain.nodes_,
17475 + // Build reconnected elements
17476 + Reconnect::apply_renumbering(nodes_renumber, domain.elements_);
17478 + Static_Int_Lists som_elem;
17479 + construire_connectivite_som_elem(domain.nb_nodes(),
17480 + domain.elements_,
17482 + 0 /* include virtual */);
17484 + virtual_elements.resize(0, 1);
17485 + virtual_elements.set_smart_resize(1);
17487 + // Step 2 : for each sub_zone, add to virtual_elements list all elements
17488 + // touching the zone and not included in the zone
17489 + const IntTab & joints_sommets = domain.get_joints(LataField_base::SOM);
17490 + const IntTab & joints_elements = domain.get_joints(LataField_base::ELEM);
17491 + const entier nprocs = joints_sommets.dimension(0);
17492 + joints_virtual_elements.resize(nprocs, 2);
17494 + tmp.set_smart_resize(1);
17495 + for (entier i_proc = 0; i_proc < nprocs; i_proc++) {
17496 + entier first_elem_zone = joints_elements(i_proc, 0);
17497 + entier end_elems_zone = first_elem_zone + joints_elements(i_proc, 1);
17498 + entier first_node_zone = joints_sommets(i_proc, 0);
17499 + entier end_nodes_zone = first_node_zone + joints_sommets(i_proc, 1);
17500 + const entier first_virtual_element = virtual_elements.dimension(0);
17501 + tmp.resize_array(0);
17502 + for (entier i_node = first_node_zone; i_node < end_nodes_zone; i_node++) {
17503 + const entier renum_node = nodes_renumber[i_node];
17504 + const entier nb_elems_voisins = som_elem.get_list_size(renum_node);
17505 + for (entier i = 0; i < nb_elems_voisins; i++) {
17506 + const entier elem = som_elem(renum_node, i);
17507 + if (elem < first_elem_zone || elem >= end_elems_zone)
17508 + tmp.append_array(elem);
17511 + // Retirer les doublons
17512 + tmp.ordonne_array();
17513 + const entier n = tmp.size_array();
17514 + entier last = -1;
17515 + for (entier i = 0; i < n; i++) {
17516 + const entier elem = tmp[i];
17517 + if (elem != last) {
17518 + const entier idx = virtual_elements.dimension(0);
17519 + virtual_elements.resize(idx+1, 1);
17520 + virtual_elements(idx, 0) = elem;
17524 + joints_virtual_elements(i_proc, 0) = first_virtual_element;
17525 + joints_virtual_elements(i_proc, 1) = virtual_elements.dimension(0) - first_virtual_element;
17526 + Journal(5) << "Zone " << i_proc << " has " << joints_virtual_elements(i_proc, 1) << " virtual elements" << endl;
17530 +entier rebuild_virtual_layer(LataDB & lataDB, Domain_Id id, double reconnect_tolerance)
17532 + Journal(4) << "rebuilt_virtual_layer domain " << id.name_ << " " << id.timestep_ << endl;
17533 + if (lataDB.field_exists(id.timestep_, id.name_, "VIRTUAL_ELEMENTS")) {
17534 + Journal(4) << " Virtual elements data already exist. Skip" << endl;
17537 + if (!lataDB.field_exists(id.timestep_, id.name_, "JOINTS_ELEMENTS")) {
17538 + Journal(4) << " Domain has no processor splitting information. Skip" << endl;
17541 + // Load all domain, without faces:
17543 + DomainUnstructured dom;
17544 + dom.fill_domain_from_lataDB(lataDB, id, 0 /* no faces */);
17545 + // Compute virtual zones:
17546 + IntTab joints_virtual_elements;
17547 + IntTab virtual_elements;
17548 + find_virtual_layer(dom, virtual_elements, joints_virtual_elements, reconnect_tolerance);
17549 + // Write data to disk
17550 + const LataDBField & joints = lataDB.get_field(id.timestep_, id.name_, "JOINTS_ELEMENTS", "*");
17551 + LataDBField fld(joints);
17552 + // Append virtual_elements data to JOINTS_ELEMENTS, same format, etc
17553 + fld.name_ = "JOINTS_VIRTUAL_ELEMENTS";
17554 + fld.uname_ = Field_UName(fld.geometry_, fld.name_, "");
17555 + fld.nb_comp_ = 2;
17556 + fld.datatype_.file_offset_ = 0;
17557 + fld.filename_ += ".ghostdata";
17558 + lataDB.add_field(fld);
17559 + lataDB.write_data(id.timestep_, fld.uname_, joints_virtual_elements);
17560 + fld.name_ = "VIRTUAL_ELEMENTS";
17561 + fld.uname_ = Field_UName(fld.geometry_, fld.name_, "");
17562 + fld.nb_comp_ = 1;
17563 + fld.datatype_.file_offset_ = 1; // append
17564 + fld.size_ = virtual_elements.dimension(0);
17565 + lataDB.add_field(fld);
17566 + lataDB.write_data(id.timestep_, fld.uname_, virtual_elements);
17569 diff --git a/databases/readers/Lata/Rebuild_virtual_layer.h b/databases/readers/Lata/Rebuild_virtual_layer.h
17570 new file mode 100644
17571 index 0000000..f2666dd
17573 +++ b/databases/readers/Lata/Rebuild_virtual_layer.h
17575 +/*****************************************************************************
17577 +* Copyright (c) 2011 - 2013, CEA
17578 +* All rights reserved.
17579 +* Redistribution and use in source and binary forms, with or without
17580 +* modification, are permitted provided that the following conditions are met:
17582 +* * Redistributions of source code must retain the above copyright
17583 +* notice, this list of conditions and the following disclaimer.
17584 +* * Redistributions in binary form must reproduce the above copyright
17585 +* notice, this list of conditions and the following disclaimer in the
17586 +* documentation and/or other materials provided with the distribution.
17587 +* * Neither the name of CEA, nor the
17588 +* names of its contributors may be used to endorse or promote products
17589 +* derived from this software without specific prior written permission.
17591 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17592 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17593 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17594 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
17595 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17596 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17597 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17598 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17599 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17600 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17602 +*****************************************************************************/
17604 +void find_virtual_layer(DomainUnstructured & domain,
17605 + IntTab & virtual_elements,
17606 + IntTab & joints_virtual_elements,
17607 + double tolerance);
17609 +entier rebuild_virtual_layer(LataDB & lataDB, Domain_Id id, double reconnect_tolerance);
17610 diff --git a/databases/readers/Lata/Sortie.h b/databases/readers/Lata/Sortie.h
17611 new file mode 100644
17612 index 0000000..69c967e
17614 +++ b/databases/readers/Lata/Sortie.h
17616 +/*****************************************************************************
17618 +* Copyright (c) 2011 - 2013, CEA
17619 +* All rights reserved.
17620 +* Redistribution and use in source and binary forms, with or without
17621 +* modification, are permitted provided that the following conditions are met:
17623 +* * Redistributions of source code must retain the above copyright
17624 +* notice, this list of conditions and the following disclaimer.
17625 +* * Redistributions in binary form must reproduce the above copyright
17626 +* notice, this list of conditions and the following disclaimer in the
17627 +* documentation and/or other materials provided with the distribution.
17628 +* * Neither the name of CEA, nor the
17629 +* names of its contributors may be used to endorse or promote products
17630 +* derived from this software without specific prior written permission.
17632 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17633 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17634 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17635 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
17636 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17637 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17638 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17639 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17640 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17641 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17643 +*****************************************************************************/
17645 +#ifndef Sortie_h_inclu
17646 +#define Sortie_h_inclu
17647 +#include <ostream>
17648 +//using namespace std;
17651 +#define Sortie std::ostream
17653 +// for Static_Int_Lists
17654 +inline Sortie& operator<<(Sortie& is, const ArrOfInt& t)
17660 diff --git a/databases/readers/Lata/Static_Int_Lists.C b/databases/readers/Lata/Static_Int_Lists.C
17661 new file mode 100644
17662 index 0000000..4c3f065
17664 +++ b/databases/readers/Lata/Static_Int_Lists.C
17666 +/*****************************************************************************
17668 +* Copyright (c) 2011 - 2013, CEA
17669 +* All rights reserved.
17670 +* Redistribution and use in source and binary forms, with or without
17671 +* modification, are permitted provided that the following conditions are met:
17673 +* * Redistributions of source code must retain the above copyright
17674 +* notice, this list of conditions and the following disclaimer.
17675 +* * Redistributions in binary form must reproduce the above copyright
17676 +* notice, this list of conditions and the following disclaimer in the
17677 +* documentation and/or other materials provided with the distribution.
17678 +* * Neither the name of CEA, nor the
17679 +* names of its contributors may be used to endorse or promote products
17680 +* derived from this software without specific prior written permission.
17682 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17683 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17684 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17685 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
17686 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17687 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17688 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17689 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17690 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17691 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17693 +*****************************************************************************/
17695 +#include <Static_Int_Lists.h>
17696 +// Description: detruit toutes les listes
17697 +void Static_Int_Lists::reset()
17699 + index_.resize_array(0);
17700 + valeurs_.resize_array(0);
17703 +// Description: detruit les listes existantes et en cree de nouvelles.
17704 +// On cree autant de listes que d'elements dans le tableau sizes.
17705 +// La i-ieme liste a une taille sizes[i]
17706 +// Les valeurs sizes doivent etre positives ou nulles.
17707 +void Static_Int_Lists::set_list_sizes(const ArrOfInt& sizes)
17711 + const entier nb_listes = sizes.size_array();
17712 + index_.resize_array(nb_listes + 1);
17713 + // Construction du tableau d'index
17716 + for (i = 0; i < nb_listes; i++)
17718 + assert(sizes[i] >= 0);
17719 + index_[i+1] = index_[i] + sizes[i];
17721 + const entier somme_sizes = index_[nb_listes];
17722 + valeurs_.resize_array(somme_sizes);
17725 +// Description: tri par ordre croissant des valeurs de la i-ieme liste.
17726 +// Si num_liste < 0, on trie toutes les listes.
17727 +void Static_Int_Lists::trier_liste(entier num_liste)
17729 + const entier i_debut = (num_liste < 0) ? 0 : num_liste;
17730 + const entier i_fin = (num_liste < 0) ? index_.size_array() - 1 : num_liste + 1;
17733 + ArrOfInt valeurs_liste;
17734 + for (i = i_debut; i < i_fin; i++)
17736 + const entier index = index_[i];
17737 + const entier size = index_[i+1] - index;
17738 + entier * data = valeurs_.addr() + index;
17739 + valeurs_liste.ref_data(data, size);
17740 + valeurs_liste.ordonne_array();
17744 +// Description: copie la i-ieme liste dans le tableau fourni
17745 +// Le tableau array doit etre resizable.
17746 +void Static_Int_Lists::copy_list_to_array(entier i, ArrOfInt& array) const
17748 + const entier n = get_list_size(i);
17749 + array.resize_array(0); // Ne pas copier les donnees d'origine
17750 + array.resize_array(n);
17751 + entier index = index_[i];
17753 + for (j = 0; j < n; index++, j++)
17754 + array[j] = valeurs_[index];
17757 +Sortie& Static_Int_Lists::printOn(Sortie& os) const
17759 + os << index_ << " ";
17760 + os << valeurs_ << " ";
17764 +Entree& Static_Int_Lists::readOn(Entree& is)
17772 +Sortie& Static_Int_Lists::ecrire(Sortie& os) const
17774 + os << "nb lists : " << get_nb_lists() << finl;
17775 + os << "sizes of lists : ";
17776 + for (entier i=0; i<get_nb_lists(); ++i)
17778 + os << get_list_size(i) << " ";
17782 + for (entier i=0; i<get_nb_lists(); ++i)
17785 + const entier sz = get_list_size(i);
17786 + for (entier j=0; j<sz; ++j)
17788 + os << valeurs_[(index_[i]+j)] << " ";
17790 + os << "}" << finl;
17794 diff --git a/databases/readers/Lata/Static_Int_Lists.h b/databases/readers/Lata/Static_Int_Lists.h
17795 new file mode 100644
17796 index 0000000..3f28783
17798 +++ b/databases/readers/Lata/Static_Int_Lists.h
17800 +/*****************************************************************************
17802 +* Copyright (c) 2011 - 2013, CEA
17803 +* All rights reserved.
17804 +* Redistribution and use in source and binary forms, with or without
17805 +* modification, are permitted provided that the following conditions are met:
17807 +* * Redistributions of source code must retain the above copyright
17808 +* notice, this list of conditions and the following disclaimer.
17809 +* * Redistributions in binary form must reproduce the above copyright
17810 +* notice, this list of conditions and the following disclaimer in the
17811 +* documentation and/or other materials provided with the distribution.
17812 +* * Neither the name of CEA, nor the
17813 +* names of its contributors may be used to endorse or promote products
17814 +* derived from this software without specific prior written permission.
17816 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17817 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17818 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17819 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
17820 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17821 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17822 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17823 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17824 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17825 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17827 +*****************************************************************************/
17829 +#ifndef Static_Int_Lists_def
17830 +#define Static_Int_Lists_def
17832 +#include <ArrOfInt.h>
17835 +// Cette classe permet de stocker des listes d'entiers accessibles
17836 +// en temps constant. La taille des listes ne peut pas changer sans
17837 +// perdre le contenu (ce sont des listes statiques).
17839 +// Static_Int_List l;
17840 +// ArrOfInt tailles(3);
17841 +// tailles[0] = 2; tailles[1] = 3; tailles[2] = 0;
17842 +// // On reserve la memoire pour trois listes de taille 2, 3 et 0:
17843 +// l.set_list_sizes(tailles);
17844 +// // On affecte une valeur au deuxieme element de la premiere liste:
17845 +// l.set_value(0,1,765);
17846 +// // Affiche la valeur
17847 +// cout << l(0,1);
17848 +class Static_Int_Lists
17851 + void set_list_sizes(const ArrOfInt& sizes);
17853 + void copy_list_to_array(entier i_liste, ArrOfInt& array) const;
17855 + inline void set_value(entier i_liste, entier i_element, entier valeur);
17856 + inline entier operator() (entier i_liste, entier i_element) const;
17857 + inline entier get_list_size(entier i_liste) const;
17858 + inline entier get_nb_lists() const;
17860 + void trier_liste(entier i);
17862 + Sortie& printOn(Sortie& os) const;
17863 + Entree& readOn(Entree& is);
17865 + Sortie& ecrire(Sortie& os) const;
17868 + // Les listes d'entiers sont stockees de facon contigue
17869 + // dans le tableau valeurs_.
17870 + // Le premier element de la liste i est valeurs_[index_[i]]
17871 + // et le dernier element est valeurs_[index_[i+1]-1]
17872 + // (c'est comme le stockage morse des matrices).
17874 + ArrOfInt valeurs_;
17877 +// Description: affecte la "valeur" au j-ieme element de la i-ieme liste avec
17878 +// 0 <= i < get_nb_lists() et 0 <= j < get_list_size(i)
17879 +inline void Static_Int_Lists::set_value(entier i, entier j, entier valeur)
17881 + const entier index = index_[i] + j;
17882 + assert(index < index_[i+1]);
17883 + valeurs_[index] = valeur;
17886 +// Description: renvoie le j-ieme element de la i-ieme liste avec
17887 +// 0 <= i < get_nb_lists() et 0 <= j < get_list_size(i)
17888 +inline entier Static_Int_Lists::operator() (entier i, entier j) const
17890 + const entier index = index_[i] + j;
17891 + assert(index < index_[i+1]);
17892 + const entier val = valeurs_[index];
17896 +// Description: renvoie le nombre d'elements de la liste i
17897 +inline entier Static_Int_Lists::get_list_size(entier i) const
17899 + const entier size = index_[i+1] - index_[i];
17903 +// Description: renvoie le nombre de listes stockees
17904 +inline entier Static_Int_Lists::get_nb_lists() const
17906 + return index_.size_array() - 1;
17910 diff --git a/databases/readers/Lata/UserFields.C b/databases/readers/Lata/UserFields.C
17911 new file mode 100644
17912 index 0000000..575c231
17914 +++ b/databases/readers/Lata/UserFields.C
17916 +/*****************************************************************************
17918 +* Copyright (c) 2011 - 2013, CEA
17919 +* All rights reserved.
17920 +* Redistribution and use in source and binary forms, with or without
17921 +* modification, are permitted provided that the following conditions are met:
17923 +* * Redistributions of source code must retain the above copyright
17924 +* notice, this list of conditions and the following disclaimer.
17925 +* * Redistributions in binary form must reproduce the above copyright
17926 +* notice, this list of conditions and the following disclaimer in the
17927 +* documentation and/or other materials provided with the distribution.
17928 +* * Neither the name of CEA, nor the
17929 +* names of its contributors may be used to endorse or promote products
17930 +* derived from this software without specific prior written permission.
17932 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17933 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17934 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17935 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
17936 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17937 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17938 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17939 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17940 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17941 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17943 +*****************************************************************************/
17945 +#include <UserFields.h>
17946 +#include <LataFilter.h>
17947 +#include <stdlib.h>
17948 +// ********************************************************************************
17949 +// METHODES OUTILS DE GESTION
17950 +// (normalement, on n'a pas besoin de les modifier mais on peut en ajouter...)
17951 +// ********************************************************************************
17953 +// Implementation de la classe Geometry_handle
17954 +// (utiliser cette classe pour eviter d'avoir a faire des dynamic_cast
17955 +// compliques et pour ne pas avoir a gerer get_geometry et release_geometry a la main)
17956 +// Exemple d'utilisation: voir interpoler_elem_vers_som()
17957 +Geometry_handle::Geometry_handle()
17960 +void Geometry_handle::set(LataFilter & lata_filter, const Domain_Id & id)
17962 + lata_filter_ = lata_filter;
17963 + geom_ = lata_filter.get_geometry(id);
17965 +Geometry_handle::Geometry_handle(Geometry_handle & handle)
17967 + operator=(handle);
17969 +Geometry_handle & Geometry_handle::operator=(Geometry_handle & handle)
17972 + lata_filter_ = handle.lata_filter_;
17973 + // Get another reference from the lata filter (to increment ref counter in the cache)
17974 + geom_ = lata_filter_.valeur().get_geometry(handle.geom_.valeur().id_);
17977 +Geometry_handle::~Geometry_handle()
17981 +void Geometry_handle::reset()
17983 + if (geom_.non_nul())
17984 + lata_filter_.valeur().release_geometry(geom_.valeur());
17986 + lata_filter_.reset();
17988 +const DomainUnstructured & Geometry_handle::geom()
17990 + if (!geom_.non_nul()) {
17991 + Journal() << "Internal error in Geometry_handle::geom() : nul pointer" << endl;
17994 + const DomainUnstructured* ptr = dynamic_cast<const DomainUnstructured *>(&geom_.valeur());
17996 + Journal() << "Error in Geometry_handle::geom() : domain "
17997 + << geom_.valeur().id_.name_ << " is not unstructured" << endl;
18002 +const DomainIJK & Geometry_handle::geom_ijk()
18004 + if (!geom_.non_nul()) {
18005 + Journal() << "Internal error in Geometry_handle::geom() : nul pointer" << endl;
18008 + const DomainIJK* ptr = dynamic_cast<const DomainIJK *>(&geom_.valeur());
18010 + Journal() << "Error in Geometry_handle::geom() : domain "
18011 + << geom_.valeur().id_.name_ << " is not IJK" << endl;
18016 +entier Geometry_handle::test_ijk()
18018 + if (!geom_.non_nul()) {
18019 + Journal() << "Internal error in Geometry_handle::geom() : nul pointer" << endl;
18022 + const DomainIJK* ptr = dynamic_cast<const DomainIJK *>(&geom_.valeur());
18029 +// Petite fonction outil qui construit l'objet LataFieldMetaData en changeant uniquement
18030 +// le nom du champ (dimension, localisation, geometrie, nombre de composantes sont identiques)
18031 +// Le champ "source" est rempli avec une reference a source, on pourra donc appeler
18032 +// get_champ_source() (voir interpoler_elem_vers_som pour un exemple)
18033 +// Voir new_fields_metadata() pour un exemple d'utilisation.
18034 +static LataFieldMetaData declare_new_name(const LataFieldMetaData & source,
18035 + const char * name)
18037 + LataFieldMetaData dest = source;
18038 + // Lorsqu'on demandera ce champ, on saura que c'est UserFields qui devra le calculer
18039 + dest.source_ = "user_fields";
18040 + // On change le nom du champ:
18041 + dest.name_ = name;
18042 + dest.uname_.set_field_name(name);
18043 + // On remplit le champ source
18044 + dest.source_field_ = source.uname_;
18049 +// Fonction identique a declare_new_name, mais pour declarer un champ avec une localisation
18051 +// Voir new_fields_metadata() pour un exemple d'utilisation.
18052 +static LataFieldMetaData declare_new_name_localisation(const LataFieldMetaData & source,
18053 + const char * name,
18054 + LataField_base::Elem_som loc)
18056 + LataFieldMetaData dest = source;
18057 + // Lorsqu'on demandera ce champ, on saura que c'est UserFields qui devra le calculer
18058 + dest.source_ = "user_fields";
18059 + // On change le nom du champ et la localisation:
18060 + dest.name_ = name;
18061 + dest.uname_ = Field_UName(source.uname_.get_geometry(),
18063 + LataField_base::localisation_to_string(loc));
18064 + // On remplit le champ source
18065 + dest.source_field_ = source.uname_;
18067 + // En plus: je change la localisation:
18068 + dest.localisation_ = loc;
18073 +// Fonction identique a declare_new_name, mais pour declarer un champ avec une localisation
18074 +// differente de type vectoriel.
18075 +// Voir new_fields_metadata() pour un exemple d'utilisation.
18076 +static LataFieldMetaData declare_new_vector_field(const LataFieldMetaData & source,
18077 + const char * name,
18078 + LataField_base::Elem_som loc,
18079 + const entier dim)
18081 + LataFieldMetaData dest = source;
18082 + // Lorsqu'on demandera ce champ, on saura que c'est UserFields qui devra le calculer
18083 + dest.source_ = "user_fields";
18084 + // On change le nom du champ et la localisation:
18085 + dest.name_ = name;
18086 + dest.uname_ = Field_UName(source.uname_.get_geometry(),
18088 + LataField_base::localisation_to_string(loc));
18089 + // On remplit le champ source
18090 + dest.source_field_ = source.uname_;
18092 + // En plus: je change la localisation:
18093 + dest.localisation_ = loc;
18095 + // et le type (vecteur)
18096 + dest.component_names_.reset();
18097 + dest.nb_components_ = dim;
18098 + dest.is_vector_ = 1;
18103 +// Description: demande a la classe LataFilter le champ source du champ "id"
18104 +// qui a ete declare quand on a appele declare_new_name() au debut
18105 +// Voir filtre_boite() pour un exemple d'utilisation.
18106 +FieldType UserFields::get_champ_source(const Field_Id & id)
18108 + // Cherche la structure LataFieldMetaData du champ "id":
18109 + const LataFieldMetaData & data = lata_filter_.valeur().get_field_metadata(id.uname_);
18110 + Field_Id id2(data.source_field_, id.timestep_, id.block_);
18112 + const LataField_base & field = lata_filter_.valeur().get_field(id2);
18113 + const FieldType* ptr = dynamic_cast<const FieldType *>(&field);
18115 + Journal() << "Error in UserFields::get_champ_source : field " << id.uname_
18116 + << " is not a floattab" << endl;
18119 + // Copie le contenu du champ dans un tableau temporaire:
18121 + // Libere le champ d'origine
18122 + lata_filter_.valeur().release_field(field);
18126 +// Description: demande a la classe LataFilter le champ de nom "nom" et dont
18127 +// la geometrie, le pas de temps et la localisation sont celles de "id".
18128 +FieldType UserFields::get_champ(const Nom & nom, const Field_Id & id)
18131 + // Construit un Field_Id identique, seul le nom du champ chamge:
18132 + Field_Id id2(id);
18133 + id2.uname_.set_field_name(nom);
18134 + const LataField_base & field = lata_filter_.valeur().get_field(id2);
18135 + const FieldType* ptr = dynamic_cast<const FieldType *>(&field);
18137 + Journal() << "Error in UserFields::get_champ : field " << id.uname_
18138 + << " is not a floattab" << endl;
18141 + // Copie le contenu du champ dans un tableau temporaire:
18143 + // Libere le champ d'origine
18144 + lata_filter_.valeur().release_field(field);
18149 +// Description: idem, mais cherche un champ avec une localisation differente de id
18150 +FieldType UserFields::get_champ_loc(const Nom & nom, LataField_base::Elem_som loc, const Field_Id & id)
18153 + // Construit un Field_Id identique, seul le nom du champ chamge:
18154 + Field_Id id2(id);
18155 + id2.uname_ = Field_UName(id.uname_.get_geometry(), nom, LataField_base::localisation_to_string(loc));
18157 + const LataField_base & field = lata_filter_.valeur().get_field(id2);
18158 + const FieldType* ptr = dynamic_cast<const FieldType *>(&field);
18160 + Journal() << "Error in UserFields::get_champ : field " << id.uname_
18161 + << " is not a floattab" << endl;
18164 + // Copie le contenu du champ dans un tableau temporaire:
18166 + // Libere le champ d'origine
18167 + lata_filter_.valeur().release_field(field);
18172 +// Description: renvoie un objet Geometry_handle qui pointe sur le domaine
18173 +// support du champ "id".
18174 +// Voir interpoler_elem_vers_som() pour un exemple d'utilisation
18175 +void UserFields::get_geometry(const Domain_Id & id, Geometry_handle & h)
18177 + h.set(lata_filter_.valeur(), id);
18180 +// ********************************************************************************
18181 +// METHODES OUTILS DE CALCUL
18182 +// Ces methodes sont des fonctions qui calculent un champ en fonction d'un autre champ.
18183 +// On peut les modifier comme on veut, en ajouter, etc...
18185 +// ********************************************************************************
18188 +// Fonction d'interpolation qui transforme un champ aux "elements"
18189 +// en un champ aux "sommets".
18190 +// Dans cet exemple, on a deux algorithmes selon que le champ est sur
18191 +// un maillage ijk ou non.
18192 +// La valeur aux sommets est la moyenne des valeurs sur les elements adjacents.
18193 +FieldType UserFields::interpoler_elem_vers_som(const Field_Id & id)
18195 + // Recupere le champ a filtrer (champ aux elements)
18196 + FieldType source = get_champ_source(id);
18199 + // Remplissage des meta-data du champ:
18201 + resu.component_names_ = source.component_names_;
18202 + resu.localisation_ = LataField_base::SOM;
18203 + resu.nature_ = source.nature_;
18205 + // Recupere la geometrie (domaine ijk ou non structure) sur laquelle est definie
18206 + // le champ source:
18207 + Geometry_handle geom;
18208 + get_geometry(id, geom);
18209 + ArrOfFloat poids;
18211 + if (geom.test_ijk()) {
18212 + const DomainIJK & dom = geom.geom_ijk();
18213 + // Le code suivant marche en 1D, 2D et 3D:
18214 + const entier nbsom = dom.nb_nodes();
18215 + const entier nbcompo = source.data_.dimension(1);
18216 + resu.data_.resize(nbsom, nbcompo);
18217 + const entier nsom_x = dom.nb_som_dir(0);
18218 + const entier nsom_y = dom.nb_som_dir(1);
18219 + const entier nelem_x = dom.nb_elem_dir(0);
18220 + const entier nelem_y = dom.nb_elem_dir(1);
18221 + const entier nelem_z = dom.nb_elem_dir(2);
18222 + poids.resize_array(nbsom);
18223 + const entier ni = 2;
18224 + const entier nj = (dom.dimension() > 1) ? 2 : 1;
18225 + const entier nk = (dom.dimension() > 2) ? 2 : 1;
18227 + // Avec les boucles imbriquees comme ceci, on parcourt tous les
18228 + // elements dans l'ordre croissant:
18229 + // (l'indice de l'element (i,j,k) est :
18230 + // elem = (k * nelem_y + j) * nelem_x + i
18232 + for (entier k = 0; k < nelem_z; k++) {
18233 + for (entier j = 0; j < nelem_y; j++) {
18234 + for (entier i = 0; i < nelem_x; i++) {
18235 + if (dom.invalid_connections_.size_array() == 0 || dom.invalid_connections_[elem] == 0) {
18236 + // Element valide:
18237 + // Boucle sur les sommets de l'element
18238 + const entier som0 = (k * nsom_y + j) * nsom_x + i;
18239 + for (entier kk = 0; kk < nk; kk++) {
18240 + for (entier jj = 0; jj < nj; jj++) {
18241 + for (entier ii = 0; ii < ni; ii++) {
18242 + entier som = som0 + (kk * nsom_y + jj) * nsom_x + ii;
18243 + for (entier compo = 0; compo < nbcompo; compo++)
18244 + resu.data_(som, compo) += source.data_(elem, compo);
18245 + poids[som] += 1.;
18255 + const DomainUnstructured & dom = geom.geom();
18257 + const entier nbsom = dom.nb_nodes();
18258 + const entier nbcompo = source.data_.dimension(1);
18259 + resu.data_.resize(nbsom, nbcompo);
18260 + poids.resize_array(nbsom);
18261 + const IntTab & les_elem = dom.elements_;
18262 + const entier n = les_elem.dimension(0);
18263 + const entier m = les_elem.dimension(1);
18265 + for ( i = 0; i < n; i++) {
18266 + for (j = 0; j < m; j++) {
18267 + entier som = les_elem(i,j);
18268 + for (k = 0; k < nbcompo; k++) {
18269 + float x = source.data_(i, k);
18270 + resu.data_(som, k) += x;
18272 + poids[som] += 1.;
18276 + const entier nbsom = poids.size_array();
18277 + const entier nbcompo = resu.data_.dimension(1);
18278 + for (entier i = 0; i < nbsom; i++)
18279 + for (entier k = 0; k < nbcompo; k++)
18280 + resu.data_(i, k) /= poids[i];
18289 +// Attention: le constructeur par defaut n'initialise pas le vecteur !
18294 + Vecteur3(const Vecteur3 & w) {
18295 + v[0] = w.v[0]; v[1] = w.v[1]; v[2] = w.v[2];
18297 + Vecteur3(double x, double y, double z) {
18298 + v[0] = x; v[1] = y; v[2] = z;
18300 + void set(double x, double y, double z) {
18301 + v[0] = x; v[1] = y; v[2] = z;
18303 + double length() const { return sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); };
18304 + Vecteur3(const DoubleTab & tab, entier i) {
18305 + //assert(tab.line_size() == 3);
18306 + assert(i >= 0 && i < tab.dimension_tot(0));
18307 + const double *ptr = tab.addr() + i * 3;
18312 + Vecteur3 & operator=(double x) {
18313 + v[0] = x; v[1] = x; v[2] = x;
18316 + Vecteur3 & operator*=(double x) {
18317 + v[0] *= x; v[1] *= x; v[2] *= x;
18321 + Vecteur3 & operator=(const Vecteur3 & w) {
18322 + v[0] = w.v[0]; v[1] = w.v[1]; v[2] = w.v[2];
18325 + double operator[](entier i) const { assert(i>=0 && i<3); return v[i]; }
18326 + double & operator[](entier i) { assert(i>=0 && i<3); return v[i]; }
18327 + inline double norme_Linfini();
18328 + static inline void produit_vectoriel(const Vecteur3 & x, const Vecteur3 & y, Vecteur3 & resu);
18329 + static inline double produit_scalaire(const Vecteur3 & x, const Vecteur3 & y);
18330 + friend Vecteur3 operator-(const Vecteur3 &, const Vecteur3 &);
18336 +inline void Vecteur3::produit_vectoriel(const Vecteur3 & x, const Vecteur3 & y, Vecteur3 & z)
18338 + z.v[0] = x.v[1] * y.v[2] - x.v[2] * y.v[1];
18339 + z.v[1] = x.v[2] * y.v[0] - x.v[0] * y.v[2];
18340 + z.v[2] = x.v[0] * y.v[1] - x.v[1] * y.v[0];
18343 +inline double Vecteur3::produit_scalaire(const Vecteur3 & x, const Vecteur3 & y)
18345 + double r = x.v[0] * y.v[0] + x.v[1] * y.v[1] + x.v[2] * y.v[2];
18349 +// Description: norme L_infini, c'est le max des abs(v[i])
18350 +inline double Vecteur3::norme_Linfini()
18352 + double x = fabs(v[0]);
18353 + double y = fabs(v[1]);
18354 + double z = fabs(v[2]);
18355 + double resu = ((x > y) ? x : y);
18356 + resu = ((resu > z) ? resu : z);
18360 +inline Vecteur3 operator-(const Vecteur3 & x, const Vecteur3 & y)
18363 + z.v[0] = x.v[0] - y.v[0];
18364 + z.v[1] = x.v[1] - y.v[1];
18365 + z.v[2] = x.v[2] - y.v[2];
18369 +double largest_angle_2(const DoubleTab& coords)
18372 + if (((coords.dimension(0)!=4)&&(coords.dimension(0)!=3))||(coords.dimension(1)!=3))
18374 + Cerr<<" cas nn prevu"<<endl;
18377 + int nb_face=coords.dimension(0);
18378 + Vecteur3 normals[4];
18379 + Vecteur3 edge[2],opp;
18380 + edge[1].set(0,0,1);
18381 + for (int n=0;n<nb_face;n++)
18385 + if (n==0) prem=1;
18387 + for (int s=0;s<nb_face;s++)
18390 + if ((s!=n) && (s!=prem))
18392 + edge[compteur].set(coords(s,0)-coords(prem,0),
18393 + coords(s,1)-coords(prem,1),
18394 + coords(s,2)-coords(prem,2));
18398 + if (compteur!=nb_face-2) throw;
18399 + opp.set(coords(n,0)-coords(prem,0),
18400 + coords(n,1)-coords(prem,1),
18401 + coords(n,2)-coords(prem,2));
18402 + Vecteur3::produit_vectoriel(edge[0],edge[1],normals[n]);
18403 + //normals[n]=edge[0]*edge[1];
18404 + normals[n]*=1./normals[n].length();
18405 + if (Vecteur3::produit_scalaire(normals[n],opp)<0)
18408 + // on a les 4 normals orientes vers l'interieur
18409 + double max_pscal=-100;
18410 + for (int n1=0;n1<nb_face;n1++)
18411 + for (int n2=n1+1;n2<nb_face;n2++)
18413 + double pscal=Vecteur3::produit_scalaire(normals[n1],normals[n2]);
18414 + //min_pscal=pscal;
18415 + if (pscal>max_pscal)
18418 + double tet=acos(max_pscal)/acos(-1.)*180; // PL: acos(-1) ne compile pas sur de multiples plateformes
18426 +FieldType UserFields::calculer_angle(const Field_Id & id)
18428 + // Recupere le champ a filtrer (champ aux elements)
18429 + // FieldType source = get_champ_source(id);
18432 + // Remplissage des meta-data du champ:
18434 + const LataFieldMetaData & data = lata_filter_.valeur().get_field_metadata(id.uname_);
18435 + resu.component_names_ = data.component_names_;
18436 + resu.localisation_ = data.localisation_;
18437 + resu.nature_ = LataDBField::SCALAR;
18439 + // Recupere la geometrie (domaine ijk ou non structure) sur laquelle est definie
18440 + // le champ source:
18441 + Geometry_handle geom;
18442 + get_geometry(id, geom);
18444 + if (geom.test_ijk()) {
18445 + Journal() << "non code" <<endl;
18448 + const DomainUnstructured & dom = geom.geom();
18449 + const entier nbcompo = dom.dimension();
18450 + //poids.resize_array(nbsom);
18451 + const IntTab & les_elem = dom.elements_;
18452 + const entier n = les_elem.dimension(0);
18454 + resu.data_.resize(n, nbcompo);
18456 + const FloatTab& nodes_=dom.nodes_;
18457 + int nb_som_elem=les_elem.dimension(1);
18458 + DoubleTab coords(nb_som_elem,3);
18459 + for ( int i = 0; i < n; i++) {
18460 + for (int s=0;s<nb_som_elem;s++)
18461 + for (int d=0;d<nodes_.dimension(1);d++)
18462 + coords(s,d)=nodes_(les_elem(i,s),d);
18463 + resu.data_(i, 0) = largest_angle_2(coords);
18471 +FieldType UserFields::calculer_normale(const Field_Id & id)
18474 + // Recupere le champ a filtrer (champ aux elements)
18475 + // FieldType source = get_champ_source(id);
18478 + // Remplissage des meta-data du champ:
18480 + const LataFieldMetaData & data = lata_filter_.valeur().get_field_metadata(id.uname_);
18481 + resu.component_names_ = data.component_names_;
18482 + resu.localisation_ = data.localisation_;
18483 + resu.nature_ = LataDBField::VECTOR;
18485 + // Recupere la geometrie (domaine ijk ou non structure) sur laquelle est definie
18486 + // le champ source:
18487 + Geometry_handle geom;
18488 + get_geometry(id, geom);
18490 + if (geom.test_ijk()) {
18491 + Journal() << "non code" <<endl;
18494 + const DomainUnstructured & dom = geom.geom();
18495 + const entier nbcompo = dom.dimension();
18496 + const IntTab & les_elem = dom.elements_;
18497 + const entier n = les_elem.dimension(0);
18499 + resu.data_.resize(n, nbcompo);
18501 + const FloatTab& nodes_=dom.nodes_;
18503 + ArrOfFloat v1( nbcompo),v2(nbcompo);
18504 + ArrOfDouble nor(nbcompo);
18505 + for ( int i = 0; i < n; i++) {
18506 + // calcul de la normale
18507 + entier som0 = les_elem(i,0);
18508 + entier som1 = les_elem(i,1);
18509 + for (int j=0;j<nbcompo;j++)
18510 + v1[j]=nodes_(som1,j)-nodes_(som0,j);
18513 + entier som2 = les_elem(i,2);
18514 + for (int j=0;j<nbcompo;j++)
18515 + v2[j]=nodes_(som2,j)-nodes_(som0,j);
18517 + nor[0]=v1[1]*v2[2]-v1[2]*v2[1];
18518 + nor[1]=v1[2]*v2[0]-v1[0]*v2[2];
18519 + nor[2]=v1[0]*v2[1]-v1[1]*v2[0];
18524 + assert(nbcompo==2);
18529 + for (int k = 0; k < nbcompo; k++) {
18530 + resu.data_(i, k) = nor[k];
18542 +// Fonction d'interpolation qui transforme un champ de vitesse VDF aux "faces"
18543 +// en un champ aux "elements".
18544 +// Ne fonctionne que sur les maillages ijk !
18545 +// On attend un champ scalaire a une composante en entree (champ source)
18546 +// et on fournit en sortie un champ vectoriel a "dimension" composantes.
18547 +FieldType UserFields::interpoler_faces_vdf_vers_elem(const Field_Id & id)
18549 + // Recupere le champ a filtrer (champ aux elements)
18550 + FieldType source = get_champ_source(id);
18552 + if (source.localisation_ != LataField_base::FACES) {
18553 + Journal() << "Error in UserFields::interpoler_faces_vdf_vers_elem: source field " << id.uname_.build_string()
18554 + << " is not at faces !" << endl;
18559 + Geometry_handle geom;
18560 + get_geometry(id, geom);
18561 + if (!geom.test_ijk()) {
18562 + Journal() << "Error in UserFields::interpoler_faces_vdf_vers_elem: geometry of field " << id.uname_.build_string()
18563 + << " is not IJK" << endl;
18566 + const DomainIJK & dom = geom.geom_ijk();
18568 + const entier dim = dom.dimension();
18570 + if (source.data_.dimension(1) != dim) {
18571 + Journal() << "Error in UserFields::interpoler_faces_vdf_vers_elem: source field " << id.uname_.build_string()
18572 + << " must have " << dim << " components !" << endl;
18577 + // Remplissage des meta-data du champ:
18579 + resu.component_names_.reset();
18580 + resu.localisation_ = LataField_base::ELEM;
18581 + resu.nature_ = LataDBField::VECTOR;
18583 + // Le code suivant marche en 1D, 2D et 3D:
18584 + const entier nbelem = dom.nb_elements();
18585 + const entier nbcompo = dim;
18586 + resu.data_.resize(nbelem, nbcompo);
18587 + const entier nelem_x = dom.nb_elem_dir(0);
18588 + const entier nelem_y = dom.nb_elem_dir(1);
18589 + const entier nelem_z = dom.nb_elem_dir(2);
18590 + const entier nfaces_x = dom.nb_som_dir(0);
18591 + const entier nfaces_y = dom.nb_som_dir(1);
18592 + // Avec les boucles imbriquees comme ceci, on parcourt tous les
18593 + // elements dans l'ordre croissant:
18594 + // (l'indice de l'element (i,j,k) est :
18595 + // elem = (k * nelem_y + j) * nelem_x + i
18597 + for (entier k = 0; k < nelem_z; k++) {
18598 + for (entier j = 0; j < nelem_y; j++) {
18599 + for (entier i = 0; i < nelem_x; i++) {
18600 + if (dom.invalid_connections_.size_array() == 0 || dom.invalid_connections_[elem] == 0) {
18601 + // Element valide:
18602 + // Boucle sur les trois directions:
18603 + for (entier dir = 0; dir < dim; dir++) {
18604 + // indices des deux faces opposees de l'element dan la direction dir:
18605 + const entier face1 = (k * nfaces_y + j) * nfaces_x + i;
18608 + face2 = face1 + 1;
18609 + else if (dir == 1)
18610 + face2 = face1 + nfaces_x;
18612 + face2 = face1 + nfaces_y * nfaces_x;
18613 + // On fait la moyenne des vitesses sur les deux faces
18614 + double v_moy = (source.data_(face1, dir) + source.data_(face2, dir)) * 0.5;
18615 + resu.data_(elem, dir) = v_moy;
18625 +// **********************************************************************************
18626 +// METHODES UTILISATEUR: ces methodes sont a mettre a jour en fonction des besoins
18628 +// **********************************************************************************
18630 +// Description: Constructeur de la classe.
18631 +// Attention: penser a initialiser toutes les variables de la classe (options)
18632 +UserFields_options::UserFields_options()
18634 + demie_largeur_filtre_boite_ = 1;
18637 +// Cette methode est appelee avec les options en ligne de commande ou sur la troisieme
18638 +// ligne. Il faut renvoyer 0 si on ne comprend pas l'option, sinon 1.
18639 +entier UserFields_options::parse_option(const Nom & option)
18641 + if (option.debute_par("demie_largeur_filtre_boite=")) {
18642 + demie_largeur_filtre_boite_ = LataOptions::read_int_opt(option);
18649 +// Cette methode est appelee par lata2dx en ligne de commande pour afficher une aide.
18650 +// On peut decrire toutes les options...
18651 +void UserFields_options::print_help_option() const
18653 + cerr << "Options provided by UserFields:" << endl;
18654 + cerr << " demie_largeur_filtre_boite=N (see filtre_boite implementation)" << endl;
18658 +// Cette methode est appelee par lata2dx au debut pour connaitre la liste
18659 +// des champs que UserFields est capable de calculer.
18660 +// fields_data contient en entree tous les champs deja fournis par lata2dx
18661 +// (champs presents dans le fichier .lata, plus les champs resultant des operateurs
18662 +// standards (regularize, dualmesh etc...)
18663 +// On doit ajouter dans fields_data la description des champs supplementaires
18664 +// que UserFields peut calculer.
18665 +void UserFields::new_fields_metadata(LataFilter & filter,
18666 + LataVector<LataFieldMetaData> & fields_data)
18668 + lata_filter_ = filter;
18670 + const Noms geoms = filter.get_exportable_geometry_names();
18672 + const entier nb_geometries = geoms.size();
18674 + for (int i = 0; i < nb_geometries; i++) {
18675 + const LataGeometryMetaData data = filter.get_geometry_metadata(geoms[i]);
18677 + // Si on a des faces, proposer la normale aux faces
18678 + int topo_dim=data.dimension_;
18680 + switch(data.element_type_) {
18681 + case Domain::point: topo_dim = 0; break;
18682 + case Domain::line: topo_dim = 1; break;
18683 + case Domain::triangle:
18684 + case Domain::polygone:
18685 + case Domain::quadri: topo_dim = 2; break;
18686 + case Domain::tetra:
18687 + case Domain::prism6:
18688 + case Domain::polyedre:
18689 + case Domain::hexa: topo_dim = 3; break;
18691 + cerr << "avtlataFileFormat::PopulateDatabaseMetaData error: unknown element type" << endl;
18694 + if ((data.dimension_>1)&&(topo_dim!=data.dimension_)) {
18695 + Journal(1)<<"Ajout de la normale"<<endl;
18696 + LataFieldMetaData dest;
18697 + dest.name_ = "normals/NORMALE";
18698 + dest.geometry_name_ = data.internal_name_;
18699 + dest.component_names_.reset() ;
18701 + dest.nb_components_ = data.dimension_;
18702 + dest.is_vector_ = 1;
18703 + dest.localisation_ = LataField_base::ELEM;
18704 + dest.source_localisation_ = "ELEM";
18705 + dest.source_ = "user_fields";
18706 + // source_field_ inutile.
18708 + dest.uname_ = Field_UName(dest.geometry_name_,
18710 + LataField_base::localisation_to_string(dest.localisation_));
18711 + fields_data.add(dest);
18714 + if (data.element_type_==Domain::triangle||data.element_type_==Domain::tetra)
18717 + Journal(1)<<"Ajout de mesh_quality/LargestAngle"<<endl;
18718 + LataFieldMetaData dest;
18719 + dest.name_ = "mesh_quality/LargestAngle";
18720 + dest.geometry_name_ = data.internal_name_;
18721 + dest.component_names_.reset() ;
18723 + dest.nb_components_ = 1;
18724 + dest.is_vector_ = 0;
18725 + dest.localisation_ = LataField_base::ELEM;
18726 + dest.source_localisation_ = "ELEM";
18727 + dest.source_ = "user_fields";
18728 + // source_field_ inutile.
18730 + dest.uname_ = Field_UName(dest.geometry_name_,
18732 + LataField_base::localisation_to_string(dest.localisation_));
18733 + fields_data.add(dest);
18736 + // on laisse les lignes pour verifier la compilation
18738 + const entier nb_fields_debut = fields_data.size();
18740 + // On fait une boucle sur tous les champs disponibles dans le filtre
18741 + // (nb_fields_debut est le nombre de champs existant avant qu'on
18742 + // commence a en ajouter dans le tableau fields_data)
18744 + for (int i_in = 0; i_in < nb_fields_debut; i_in++)
18746 + // On cherche si le champ de temperature aux elements existe
18747 + // sur une geometrie IJK (Motcle permet d'ignorer majuscule/minuscule)
18748 + const LataFieldMetaData data = fields_data[i_in];
18750 + // Les deux if suivants sont des EXEMPLES
18752 + if (Motcle(data.name_) == "TEMPERATURE"
18753 + && data.localisation_ == LataField_base::ELEM
18754 + && Motcle(data.geometry_name_).finit_par("_IJK"))
18756 + // On declare un champ identique qui s'appelle MOYENNE_TEMPERATURE
18757 + fields_data.add(declare_new_name(data, "MOYENNE_TEMPERATURE"));
18760 + // Si le champ est aux elements, on propose une interpolation aux sommets
18761 + // On reconnaitra le champ parce que son nom finira par elem_vers_som (voir get_field())
18762 + if (data.localisation_ == LataField_base::ELEM)
18764 + Nom nom = data.name_;
18765 + nom += "_elem_vers_som";
18766 + fields_data.add(declare_new_name_localisation(data, nom, LataField_base::SOM));
18769 + // Si le champ est aux faces et le maillage est ijk, on propose
18770 + // une interpolation aux elements
18771 + if (data.localisation_ == LataField_base::FACES
18772 + && Motcle(data.geometry_name_).finit_par("_IJK"))
18774 + Nom nom = data.name_;
18775 + nom += "_faces_vers_elem";
18776 + // Le champ aux faces a deja dimension composantes
18777 + const entier dim = data.nb_components_;
18778 + fields_data.add(declare_new_vector_field(data, nom, LataField_base::ELEM, dim));
18785 +// Cette methode publique est appelee par lata2dx pour obtenir les champs declares dans
18786 +// new_fields_metadata. Il faut tester "id" et calculer le champ demande.
18787 +// On a le droit d'appeler get_champ() pour obtenir d'autres champs.
18788 +FieldType UserFields::get_field(const Field_Id & id)
18790 + // Convertit le nom du champ en majuscules:
18791 + Motcle nom(id.uname_.get_field_name());
18793 + // Ces deux lignes sont des EXEMPLES (a remplacer par les champs qu'on veut
18794 + // effectivement calculer)
18795 + if (nom == "moyenne_temperature") return filtre_boite(id);
18796 + else if (nom.finit_par("_elem_vers_som")) return interpoler_elem_vers_som(id);
18797 + else if (nom.finit_par("_faces_vers_elem")) return interpoler_faces_vdf_vers_elem(id);
18798 + else if (nom.debute_par("normals/NORMALE")) return calculer_normale(id);
18799 + else if (nom.debute_par("mesh_quality/LargestAngle")) return calculer_angle(id);
18800 + // Ceci doit rester:
18802 + Journal() << "Error in UserFields::get_field: unknown field " << nom << endl;
18807 +class FiltreSpatial
18810 + FiltreSpatial(LataFilter & lata, const Domain_Id & id, entier demi_pas) :
18811 + demi_pas_(-1), pbDim_(-1), nx_(-1), ny_(-1), nz_(-1), dx_(-1.), dy_(-1.), dz_(-1.)
18813 + init(lata, id, demi_pas);
18815 + FieldType filtrer(const FieldType & f, const Field_Id & id) const;
18816 + FieldType gradient(const FieldType & f, const Field_Id & id) const;
18817 + float volume() const { return dx_ * dy_ * dz_; }
18819 + void init(LataFilter & lata, const Domain_Id & id, entier demi_pas);
18820 + FloatTab calculer_somme_dir(const FloatTab & src, const int dir) const;
18821 + FloatTab annu_bord(const FloatTab & input, int epaisseur) const;
18822 + int ijk_index(int i, int j, int k) const {
18825 + else if (i >= nx_)
18829 + else if (j >= ny_)
18833 + else if (k >= nz_)
18835 + return k * ny_ * nx_ + j * nx_ + i;
18838 + // Tableau: pour chaque element, 1 s'il est INVALIDE, 0 s'il est OK
18839 + ArrOfBit invalid_connections_;
18841 + entier demi_pas_;
18842 + int pbDim_; // dimension
18851 +void FiltreSpatial::init(LataFilter & lata, const Domain_Id & id, entier demi_pas)
18853 + const Domain & dom = lata.get_geometry(id);
18854 + const DomainIJK * ptr = dynamic_cast<const DomainIJK *>(&dom);
18856 + Journal() << "Error in FiltreSpatial::init : domain " << id.name_ << " is not IJK" << endl;
18859 + demi_pas_ = demi_pas;
18860 + pbDim_ = ptr->coord_.size();
18861 + nx_ = ptr->coord_[0].size_array() - 1;
18862 + ny_ = ptr->coord_[1].size_array() - 1;
18864 + nz_ = ptr->coord_[2].size_array() - 1;
18868 + dx_ = ptr->coord_[0][1] - ptr->coord_[0][0];
18869 + dy_ = ptr->coord_[1][1] - ptr->coord_[1][0];
18871 + dz_ = ptr->coord_[2][1] - ptr->coord_[2][0];
18875 + invalid_connections_ = ptr->invalid_connections_;
18877 + if (invalid_connections_.size_array() == 0) {
18878 + invalid_connections_.resize_array(ptr->nb_elements());
18879 + invalid_connections_ = 0;
18882 + lata.release_geometry(dom);
18885 +FloatTab FiltreSpatial::calculer_somme_dir(const FloatTab & src, const int dir) const
18887 + const int n = src.dimension(0);
18888 + const int nb_compo = src.dimension(1);
18890 + tmp.resize(n, nb_compo);
18892 + int index_resu = 0;
18893 + for (int k = 0; k < nz_; k++) {
18894 + for (int j = 0; j < ny_; j++) {
18895 + for (int i = 0; i < nx_; i++) {
18896 + for (int count = -demi_pas_; count <= demi_pas_; count++) {
18899 + case 0: index = ijk_index(i+count, j, k); break;
18900 + case 1: index = ijk_index(i, j+count, k); break;
18901 + case 2: index = ijk_index(i, j, k+count); break;
18906 + if (invalid_connections_[index] == 1 && dir == 0) {
18907 + // element invalide !
18910 + for (int compo = 0; compo < nb_compo; compo++)
18911 + tmp(index_resu, compo) += src(index, compo);
18921 +FieldType FiltreSpatial::filtrer(const FieldType & source, const Field_Id & id) const
18923 + // On copie tout pour avoir les noms des composantes, localisation etc...
18924 + FieldType resu = source;
18927 + FloatTab somme_x = calculer_somme_dir(source.data_, 0);
18928 + FloatTab somme_y = calculer_somme_dir(somme_x, 1);
18930 + resu.data_ = calculer_somme_dir(somme_y, 2);
18932 + resu.data_ = somme_y;
18934 + entier pas = demi_pas_ * 2 + 1;
18935 + double fact = pas * pas;
18938 + resu.data_ *= (1. / fact);
18943 +FieldType UserFields::filtre_boite(const Field_Id & id)
18945 + FieldType source = get_champ_source(id);
18947 + FiltreSpatial filtre(lata_filter_.valeur(), id, opt_.demie_largeur_filtre_boite_);
18949 + FieldType resu = filtre.filtrer(source, id);
18954 diff --git a/databases/readers/Lata/UserFields.h b/databases/readers/Lata/UserFields.h
18955 new file mode 100644
18956 index 0000000..8e2052c
18958 +++ b/databases/readers/Lata/UserFields.h
18960 +/*****************************************************************************
18962 +* Copyright (c) 2011 - 2013, CEA
18963 +* All rights reserved.
18964 +* Redistribution and use in source and binary forms, with or without
18965 +* modification, are permitted provided that the following conditions are met:
18967 +* * Redistributions of source code must retain the above copyright
18968 +* notice, this list of conditions and the following disclaimer.
18969 +* * Redistributions in binary form must reproduce the above copyright
18970 +* notice, this list of conditions and the following disclaimer in the
18971 +* documentation and/or other materials provided with the distribution.
18972 +* * Neither the name of CEA, nor the
18973 +* names of its contributors may be used to endorse or promote products
18974 +* derived from this software without specific prior written permission.
18976 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
18977 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18978 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18979 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
18980 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18981 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18982 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18983 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18984 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18985 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18987 +*****************************************************************************/
18989 +#ifndef UserFields_H
18990 +#define UserFields_H
18991 +#include <Lata_tools.h>
18992 +#include <LataStructures.h>
18994 +template<class F> class Field;
18996 +typedef Field<FloatTab> FieldType;
18999 +struct LataFieldMetaData;
19000 +class DomainUnstructured;
19003 +// Description: classe outil pour acceder a une geometrie dans LataFilter.
19004 +// La geometrie est chargee en memoire quand cet objet est cree,
19005 +// elle est dechargee quand il est detruit.
19006 +// Exemple d'utilisation dans UserFields::interpoler_elem_vers_som
19007 +class Geometry_handle
19010 + Geometry_handle();
19011 + Geometry_handle(Geometry_handle &);
19012 + Geometry_handle & operator=(Geometry_handle &);
19013 + ~Geometry_handle();
19014 + void set(LataFilter & filter, const Domain_Id &);
19015 + const DomainUnstructured & geom();
19016 + const DomainIJK & geom_ijk();
19017 + entier test_ijk();
19020 + LataRef<LataFilter> lata_filter_;
19021 + LataRef<const Domain> geom_;
19024 +class UserFields_options
19027 + UserFields_options();
19028 + entier parse_option(const Nom &);
19029 + void print_help_option() const;
19031 + // Exemple de parametre en option (commentaires bienvenus !)
19033 + // demie-largeur du filtre_boite en mailles
19034 + entier demie_largeur_filtre_boite_;
19040 + void set_options(const UserFields_options & opt) { opt_ = opt; }
19042 + void new_fields_metadata(LataFilter & filter,
19043 + LataVector<LataFieldMetaData> & fields_data);
19045 + FieldType get_field(const Field_Id & id);
19047 + BigEntier compute_memory_size() { return 0; }
19050 + // Declaration de methodes outils
19051 + FieldType get_champ_source(const Field_Id & id);
19052 + FieldType get_champ(const Nom & nom, const Field_Id & id);
19053 + FieldType get_champ_loc(const Nom & nom, LataField_base::Elem_som loc, const Field_Id & id);
19054 + void get_geometry(const Domain_Id & id, Geometry_handle &);
19056 + FieldType filtre_boite(const Field_Id & id);
19057 + FieldType calculer_normale(const Field_Id & id);
19058 + FieldType calculer_angle(const Field_Id & id);
19059 + FieldType interpoler_elem_vers_som(const Field_Id & id);
19060 + FieldType interpoler_faces_vdf_vers_elem(const Field_Id & id);
19062 + // Reference a la classe LataFilter (pour recuperer les champs sources)
19063 + LataRef<LataFilter> lata_filter_;
19065 + UserFields_options opt_;
19068 diff --git a/databases/readers/Lata/Vect.h b/databases/readers/Lata/Vect.h
19069 new file mode 100644
19070 index 0000000..a650806
19072 +++ b/databases/readers/Lata/Vect.h
19074 +/*****************************************************************************
19076 +* Copyright (c) 2011 - 2013, CEA
19077 +* All rights reserved.
19078 +* Redistribution and use in source and binary forms, with or without
19079 +* modification, are permitted provided that the following conditions are met:
19081 +* * Redistributions of source code must retain the above copyright
19082 +* notice, this list of conditions and the following disclaimer.
19083 +* * Redistributions in binary form must reproduce the above copyright
19084 +* notice, this list of conditions and the following disclaimer in the
19085 +* documentation and/or other materials provided with the distribution.
19086 +* * Neither the name of CEA, nor the
19087 +* names of its contributors may be used to endorse or promote products
19088 +* derived from this software without specific prior written permission.
19090 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
19091 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19092 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19093 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
19094 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19095 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19096 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19097 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19098 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19099 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19101 +*****************************************************************************/
19103 +#ifndef Vect_h_inclu
19104 +#define Vect_h_inclu
19105 +#include <LataVector.h>
19106 +#define VECT(x) LataVector<x >
19108 diff --git a/databases/readers/Lata/VectArrOfInt.h b/databases/readers/Lata/VectArrOfInt.h
19109 new file mode 100644
19110 index 0000000..c666311
19112 +++ b/databases/readers/Lata/VectArrOfInt.h
19114 +/*****************************************************************************
19116 +* Copyright (c) 2011 - 2013, CEA
19117 +* All rights reserved.
19118 +* Redistribution and use in source and binary forms, with or without
19119 +* modification, are permitted provided that the following conditions are met:
19121 +* * Redistributions of source code must retain the above copyright
19122 +* notice, this list of conditions and the following disclaimer.
19123 +* * Redistributions in binary form must reproduce the above copyright
19124 +* notice, this list of conditions and the following disclaimer in the
19125 +* documentation and/or other materials provided with the distribution.
19126 +* * Neither the name of CEA, nor the
19127 +* names of its contributors may be used to endorse or promote products
19128 +* derived from this software without specific prior written permission.
19130 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
19131 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19132 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19133 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
19134 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19135 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19136 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19137 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19138 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19139 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19141 +*****************************************************************************/
19143 +#ifndef VectArrOfInt_h_inclu
19144 +#define VectArrOfInt_h_inclu
19145 +#include <ArrOfInt.h>
19148 diff --git a/databases/readers/Lata/arch.h b/databases/readers/Lata/arch.h
19149 new file mode 100644
19150 index 0000000..68c5800
19152 +++ b/databases/readers/Lata/arch.h
19154 +/*****************************************************************************
19156 +* Copyright (c) 2011 - 2013, CEA
19157 +* All rights reserved.
19158 +* Redistribution and use in source and binary forms, with or without
19159 +* modification, are permitted provided that the following conditions are met:
19161 +* * Redistributions of source code must retain the above copyright
19162 +* notice, this list of conditions and the following disclaimer.
19163 +* * Redistributions in binary form must reproduce the above copyright
19164 +* notice, this list of conditions and the following disclaimer in the
19165 +* documentation and/or other materials provided with the distribution.
19166 +* * Neither the name of CEA, nor the
19167 +* names of its contributors may be used to endorse or promote products
19168 +* derived from this software without specific prior written permission.
19170 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
19171 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19172 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19173 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
19174 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19175 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19176 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19177 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19178 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19179 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19181 +*****************************************************************************/
19183 +#ifndef arch_include_
19184 +#define arch_include_
19185 +typedef int entier;
19188 diff --git a/databases/readers/Lata/avtlataFileFormat.C b/databases/readers/Lata/avtlataFileFormat.C
19189 new file mode 100644
19190 index 0000000..2c4d27c
19192 +++ b/databases/readers/Lata/avtlataFileFormat.C
19194 +/*****************************************************************************
19196 + * Copyright (c) 2000 - 2015, Lawrence Livermore National Security, LLC
19197 + * Produced at the Lawrence Livermore National Laboratory
19198 + * All rights reserved.
19200 + * This file is part of VisIt. For details, see http://www.llnl.gov/visit/. The
19201 + * full copyright notice is contained in the file COPYRIGHT located at the root
19202 + * of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
19204 + * Redistribution and use in source and binary forms, with or without
19205 + * modification, are permitted provided that the following conditions are met:
19207 + * - Redistributions of source code must retain the above copyright notice,
19208 + * this list of conditions and the disclaimer below.
19209 + * - Redistributions in binary form must reproduce the above copyright notice,
19210 + * this list of conditions and the disclaimer (as noted below) in the
19211 + * documentation and/or materials provided with the distribution.
19212 + * - Neither the name of the UC/LLNL nor the names of its contributors may be
19213 + * used to endorse or promote products derived from this software without
19214 + * specific prior written permission.
19216 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19217 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19218 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19219 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF
19220 + * CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR
19221 + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19222 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19223 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19224 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19225 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19226 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
19229 + *****************************************************************************/
19231 +// ************************************************************************* //
19232 +// avtlataFileFormat.C //
19233 +// ************************************************************************* //
19235 +#include <avtlataFileFormat.h>
19237 +#include <LmlReader.h>
19238 +#include <LataJournal.h>
19240 +#include <avtDatabaseMetaData.h>
19241 +#include <avtGhostData.h>
19242 +#include <DebugStream.h>
19243 +#include <Expression.h>
19244 +#include <InvalidVariableException.h>
19246 +#include <vtkCellData.h>
19247 +#include <vtkCellType.h>
19248 +#include <vtkFloatArray.h>
19249 +#include <vtkInformation.h>
19250 +#include <vtkIntArray.h>
19251 +#include <vtkRectilinearGrid.h>
19252 +#include <vtkStreamingDemandDrivenPipeline.h>
19253 +#include <vtkStructuredGrid.h>
19254 +#include <vtkUnsignedCharArray.h>
19255 +#include <vtkUnstructuredGrid.h>
19258 +#include <fstream>
19259 +#include <iostream>
19260 +#include <visitstream.h>
19263 +// ****************************************************************************
19264 +// Method: avtlata constructor
19266 +// Programmer: fauchet -- generated by xml2avt
19268 +// ****************************************************************************
19270 +avtlataFileFormat::avtlataFileFormat(const char *filename)
19271 + : avtMTMDFileFormat(filename)
19273 + debug1 << "avtlataFileFormat constructor " << filename << endl;
19275 + set_Journal_level(0);
19278 + LataOptions::extract_path_basename(filename, opt.path_prefix, opt.basename);
19279 + opt.dual_mesh = true;
19280 + opt.faces_mesh = true;
19281 + opt.regularize = 2;
19282 + opt.regularize_tolerance = 1e-7;
19283 + opt.user_fields_=true;
19284 + read_any_format_options(filename, opt);
19285 + debug1 << "avtlataFileFormat: initializing filter" << endl;
19286 + // Read the source file to the lata database
19287 + read_any_format(filename, opt.path_prefix, lata_db_);
19288 + filter_.initialize(opt, lata_db_);
19290 + catch (LataDBError err) {
19291 + cerr << "Error in LataFilter::initialize " << filename << " " << err.describe() << endl;
19296 +avtlataFileFormat::~avtlataFileFormat()
19300 +// ****************************************************************************
19301 +// Method: avtEMSTDFileFormat::GetNTimesteps
19304 +// Tells the rest of the code how many timesteps there are in this file.
19306 +// Programmer: fauchet -- generated by xml2avt
19308 +// ****************************************************************************
19311 +avtlataFileFormat::GetNTimesteps(void)
19315 + n = filter_.get_nb_timesteps();
19316 + // Timestep 0 contains global definitions.
19317 + // If we have "real" timesteps, do not show timestep 0
19321 + catch (LataDBError err) {
19322 + cerr << "Error in getntimesteps " << filename << " " << err.describe() << endl;
19328 +void avtlataFileFormat::GetTimes(std::vector<double>& times)
19332 + n = filter_.get_nb_timesteps();
19334 + times.push_back(0.);
19336 + for (int i = 1; i < n; i++)
19337 + times.push_back(filter_.get_timestep(i));
19339 + catch (LataDBError err) {
19340 + cerr << "Error in gettimes " << filename << " " << err.describe() << endl;
19346 +// ****************************************************************************
19347 +// Method: avtlataFileFormat::FreeUpResources
19350 +// When VisIt is done focusing on a particular timestep, it asks that
19351 +// timestep to free up any resources (memory, file descriptors) that
19352 +// it has associated with it. This method is the mechanism for doing
19355 +// Programmer: fauchet -- generated by xml2avt
19357 +// ****************************************************************************
19360 +avtlataFileFormat::FreeUpResources(void)
19365 +// ****************************************************************************
19366 +// Method: avtlataFileFormat::PopulateDatabaseMetaData
19369 +// This database meta-data object is like a table of contents for the
19370 +// file. By populating it, you are telling the rest of VisIt what
19371 +// information it can request from you.
19373 +// Programmer: fauchet -- generated by xml2avt
19375 +// ****************************************************************************
19378 +avtlataFileFormat::PopulateDatabaseMetaData(avtDatabaseMetaData *md, int timeState)
19381 + debug1 << "avtlataFileFormat::PopulateDatabaseMetaData : "
19382 + << filename << " " << timeState << endl;
19384 + const char *suffix_vector_names[] = { "_X", "_Y", "_Z" };
19385 + const char *suffix_vector_expr[] = { "[0]", "[1]", "[2]" };
19387 + const Noms geoms = filter_.get_exportable_geometry_names();
19389 + for (int i_geom = 0; i_geom < geoms.size(); i_geom++) {
19390 + debug1 << " Domain : " << geoms[i_geom] << endl;
19391 + const LataGeometryMetaData data = filter_.get_geometry_metadata(geoms[i_geom]);
19393 + avtMeshType mt = AVT_UNSTRUCTURED_MESH;
19395 + if (data.is_ijk_==1)
19397 + mt = AVT_RECTILINEAR_MESH;
19399 + int block_origin = 0;
19401 + switch(data.element_type_) {
19402 + case Domain::point: topo_dim = 0; mt = AVT_POINT_MESH; break;
19403 + case Domain::line: topo_dim = 1; break;
19404 + case Domain::triangle:
19405 + case Domain::polygone:
19406 + case Domain::quadri: topo_dim = 2; break;
19407 + case Domain::tetra:
19408 + case Domain::prism6:
19409 + case Domain::polyedre:
19410 + case Domain::hexa: topo_dim = 3; break;
19412 + cerr << "avtlataFileFormat::PopulateDatabaseMetaData error: unknown element type" << endl;
19413 + topo_dim = 3; ///TODO: this should be an error in default case!
19414 + EXCEPTION1(InvalidVariableException,
19415 + "avtlataFileFormat::PopulateDatabaseMetaData error: unknown element type");
19419 + int mesh_faces=0;
19420 + if (data.internal_name_.finit_par("_centerfaces"))
19422 + //cerr<<"la "<<data.internal_name_<<endl;
19425 + double *extents = NULL;
19426 + const std::string geom_name(data.displayed_name_);
19427 + AddMeshToMetaData(md, geom_name, mt, extents, data.nblocks_, block_origin,
19428 + data.dimension_, topo_dim);
19429 + mesh_username_.add(data.displayed_name_);
19430 + mesh_latafilter_name_.add(data.internal_name_);
19432 + Field_UNames fields = filter_.get_exportable_field_unames(geoms[i_geom]);
19434 + for (int i_field = 0; i_field < fields.size(); i_field++) {
19435 + const LataFieldMetaData data2 = filter_.get_field_metadata(fields[i_field]);
19436 + avtCentering cent;
19437 + switch (data2.localisation_) {
19438 + case LataField_base::ELEM: cent = AVT_ZONECENT; break;
19439 + case LataField_base::SOM: cent = AVT_NODECENT; break;
19441 + // Do not export fields that cannot be shown
19445 + // Take localisation of source field
19446 + Nom loc = data2.source_localisation_;
19447 + std::string varname(data2.name_);
19451 + varname += geom_name;
19452 + if (data2.nb_components_ == 1) {
19454 + // We append the geometry name to the component name:
19455 + register_fieldname(varname.c_str(), fields[i_field], 0);
19456 + if (mesh_faces==0)
19457 + AddScalarVarToMetaData(md, varname, geom_name, cent);
19458 + } else if (data2.is_vector_ && data2.nb_components_ == data.dimension_) {
19460 + register_fieldname(varname.c_str(), fields[i_field], -1);
19461 + AddVectorVarToMetaData(md, varname, geom_name, cent, data2.nb_components_);
19462 + if (mesh_faces==0)
19465 + for (entier i = 0; i < data2.nb_components_; i++) {
19468 + n += suffix_vector_names[i];
19475 + n += suffix_vector_expr[i];
19476 + v.SetDefinition(n);
19477 + v.SetType(Expression::ScalarMeshVar);
19478 + md->AddExpression(&v);
19480 + if (varname.find_first_of("/",0)==std::string::npos)
19482 + // On calcule la norme des vecteurs de premier niveau (pas de / dans le chemin)
19483 + Expression norme_v;
19486 + norme_v.SetName(n);
19487 + n = "magnitude(";
19490 + norme_v.SetDefinition(n);
19491 + norme_v.SetType(Expression::ScalarMeshVar);
19492 + md->AddExpression(&norme_v);
19496 + // Multiscalar field
19497 + // I chose to postfix the varname with the component name, perhaps not the best choice.
19498 + if (mesh_faces==0)
19500 + for (entier i_compo = 0; i_compo < data2.nb_components_; i_compo++) {
19501 + std::string varname2(data2.name_);
19503 + if (data2.component_names_.size() == data2.nb_components_) {
19504 + varname2 += data2.component_names_[i_compo];
19512 + varname2 += geom_name;
19513 + register_fieldname(varname2.c_str(), fields[i_field], i_compo);
19514 + AddScalarVarToMetaData(md, varname2, geom_name, cent);
19520 + debug1 << "End avtlataFileFormat::PopulateDatabaseMetaData" << endl;
19522 + catch (LataDBError err) {
19523 + cerr << "Error in PopulateDatabaseMetaData " << err.describe() << endl;
19529 +avtlataFileFormat::register_fieldname(const char *visit_name, const Field_UName & uname, int component)
19531 + if (field_username_.rang(visit_name) >= 0) {
19532 + cerr << "Error in avtlataFileFormat::register_fieldname: duplicate field name " << visit_name << endl;
19533 + cerr << "Ignoring field" << endl;
19536 + field_username_.add(visit_name);
19537 + field_uname_.add(uname);
19538 + field_component_.add(component);
19542 +avtlataFileFormat::register_meshname(const char *visit_name, const char *latafilter_name)
19544 + if (mesh_username_.rang(visit_name) >= 0) {
19545 + cerr << "Error in avtlataFileFormat::register_meshname: duplicate name " << visit_name << endl;
19546 + cerr << "Ignoring mesh" << endl;
19549 + mesh_username_.add(visit_name);
19550 + mesh_latafilter_name_.add(latafilter_name);
19553 +// ****************************************************************************
19554 +// Method: avtlataFileFormat::GetMesh
19557 +// Gets the mesh associated with this file. The mesh is returned as a
19558 +// derived type of vtkDataSet (ie vtkRectilinearGrid, vtkStructuredGrid,
19559 +// vtkUnstructuredGrid, etc).
19562 +// timestate The index of the timestate. If GetNTimesteps returned
19563 +// 'N' time steps, this is guaranteed to be between 0 and N-1.
19564 +// domain The index of the domain. If there are NDomains, this
19565 +// value is guaranteed to be between 0 and NDomains-1,
19566 +// regardless of block origin.
19567 +// meshname The name of the mesh of interest. This can be ignored if
19568 +// there is only one mesh.
19570 +// Programmer: fauchet -- generated by xml2avt
19572 +// ****************************************************************************
19575 +avtlataFileFormat::GetMesh(int timestate, int block, const char *meshname)
19577 + vtkDataSet *return_value = 0;
19579 + debug1 << " avtlataFileFormat::GetMesh ts=" << timestate
19580 + << " block=" << block
19581 + << " meshname=" << meshname << endl;
19583 + // We have real timesteps in the database, add one to timestep index:
19584 + if (filter_.get_nb_timesteps() > 1)
19587 + const entier index = mesh_username_.rang(meshname);
19589 + cerr << "internal error in avtlataFileFormat::GetMesh: name " << meshname << " not found" << endl;
19592 + Domain_Id id(mesh_latafilter_name_[index], timestate, block);
19593 + const Domain & geometry = filter_.get_geometry(id);
19595 + const DomainUnstructured * geom_ptr = dynamic_cast<const DomainUnstructured*>(&geometry);
19596 + const DomainIJK * ijk_ptr = dynamic_cast<const DomainIJK*>(&geometry);
19599 + const DomainUnstructured & geom = *geom_ptr;
19601 + vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::New();
19602 + vtkPoints *points = vtkPoints::New();
19603 + const FloatTab & pos = geom.nodes_;
19604 + const int nnodes = pos.dimension(0);
19605 + const int dim3 = pos.dimension(1) == 3;
19606 + points->SetNumberOfPoints(nnodes);
19607 + float* pts = (float *) points->GetVoidPointer(0);
19610 + for (i = 0; i < nnodes; i++) {
19611 + pts[jl] = pos(i,0);
19612 + pts[jl+1] = pos(i,1);
19613 + pts[jl+2] = dim3 ? pos(i,2) : 0.;
19616 + ugrid->SetPoints(points);
19617 + points->Delete();
19619 + const IntTab & conn = geom.elements_;
19620 + const IntTab & elem_faces = geom.elem_faces_;
19621 + const IntTab & faces = geom.faces_;
19622 + const int ncells = conn.dimension(0);
19623 + int nverts = conn.dimension(1);
19626 + switch (geom.elt_type_) {
19627 + case Domain::point:
19628 + type_cell=VTK_VERTEX;
19632 + case Domain::line:
19633 + type_cell=VTK_LINE;
19635 + case Domain::triangle:
19636 + type_cell=VTK_TRIANGLE;
19638 + case Domain::quadri:
19639 + type_cell=VTK_QUAD;
19641 + case Domain::tetra:
19642 + type_cell=VTK_TETRA;
19644 + case Domain::prism6:
19645 + type_cell=VTK_WEDGE;
19647 + case Domain::hexa:
19648 + type_cell=VTK_HEXAHEDRON;
19650 + case Domain::polygone:
19651 + type_cell=VTK_POLYGON;
19653 + case Domain::polyedre:
19654 + type_cell= elem_faces.dimension(0) > 0 ? VTK_POLYHEDRON : VTK_CONVEX_POINT_SET;
19658 + cerr<<"avtlataFileFormat::GetMesh unknown elt type "<<endl;
19662 + vtkIdType *verts = new vtkIdType[nverts];
19663 + std::vector<vtkIdType> poly_p, poly_f;
19664 + if (type_cell == VTK_VERTEX && ncells == 0) {
19665 + // Cells are implicit. Create them:
19666 + ugrid->Allocate(nnodes);
19667 + for (i = 0; i < nnodes; i++) {
19669 + ugrid->InsertNextCell(type_cell, nverts, verts);
19672 + ugrid->Allocate(ncells);
19673 + for (i = 0; i < ncells; i++) {
19674 + if (type_cell==VTK_QUAD) {
19675 + // Nodes order is different in visit than in trio_u
19676 + verts[0]=conn(i,0);
19677 + verts[1]=conn(i,1);
19678 + verts[2]=conn(i,3);
19679 + verts[3]=conn(i,2);
19680 + } else if (type_cell==VTK_HEXAHEDRON) {
19681 + // Nodes order is different in visit than in trio_u
19682 + verts[0]=conn(i,0);
19683 + verts[1]=conn(i,1);
19684 + verts[2]=conn(i,3);
19685 + verts[3]=conn(i,2);
19686 + verts[4]=conn(i,4);
19687 + verts[5]=conn(i,5);
19688 + verts[6]=conn(i,7);
19689 + verts[7]=conn(i,6);
19690 + } else if (type_cell==VTK_POLYHEDRON) {
19691 + //polyhedra, face by face
19692 + int j, nfaces = 0, npts = 0, k, i_f, s, f;
19693 + poly_p.resize(0), poly_f.resize(0);
19694 + for (j = 0; j < conn.dimension(1); j++) if ((s = conn(i, j)) >= 0) poly_p.push_back(s), npts++;
19695 + for (j = 0; j < elem_faces.dimension(1); j++) if ((f = elem_faces(i, j)) >= 0)
19696 + for (k = 0, nfaces++, i_f = poly_f.size(), poly_f.push_back(0); k < faces.dimension(1) ; k++) if ((s = faces(f, k)) >= 0)
19697 + poly_f.push_back(s), poly_f[i_f]++;
19698 + ugrid->InsertNextCell(type_cell, npts, &poly_p[0], nfaces, &poly_f[0]);
19699 + } else if ((type_cell==VTK_CONVEX_POINT_SET)||(type_cell==VTK_POLYGON)) {
19700 + int nverts_loc=nverts;
19701 + for (int j = 0; j < nverts; j++)
19703 + verts[j] = conn(i,j);
19705 + if (verts[j]<=-1)
19714 + std::cerr<<i<<" iiiii "<< j<<" "<<verts[j]<<finl;
19719 + int nb_som_max_to_regularize=0;
19720 + if (filter_.get_options().regularize_polyedre!=0)
19722 + nb_som_max_to_regularize=8;
19723 + if (filter_.get_options().regularize_polyedre==-1)
19724 + nb_som_max_to_regularize=32000;
19726 + if ( geom.elt_type_==Domain::polygone)
19727 + nb_som_max_to_regularize=-1;
19728 + if ((nb_som_max_to_regularize>=6) && (nverts_loc==6))
19729 + ugrid->InsertNextCell(VTK_WEDGE, nverts_loc, verts);
19730 + else if ((nb_som_max_to_regularize>=12)&&(nverts_loc==12))
19731 + ugrid->InsertNextCell(VTK_HEXAGONAL_PRISM, nverts_loc, verts);
19732 + else if ((nb_som_max_to_regularize>=8)&&(nverts_loc==8))
19734 + // Nodes order is different in visit than in trio_u
19735 + verts[0]=conn(i,0);
19736 + verts[1]=conn(i,1);
19737 + verts[2]=conn(i,3);
19738 + verts[3]=conn(i,2);
19739 + verts[4]=conn(i,4);
19740 + verts[5]=conn(i,5);
19741 + verts[6]=conn(i,7);
19742 + verts[7]=conn(i,6);
19743 + ugrid->InsertNextCell(VTK_HEXAHEDRON, nverts_loc, verts);
19747 + ugrid->InsertNextCell(type_cell, nverts_loc, verts);
19750 + for (int j = 0; j < nverts; j++)
19751 + verts[j] = conn(i,j);
19753 + if ((type_cell!=VTK_POLYHEDRON) &&(type_cell!=VTK_CONVEX_POINT_SET) && (type_cell!=VTK_POLYGON))
19755 + ugrid->InsertNextCell(type_cell, nverts, verts);
19760 + // Declare ghost elements:
19761 + const int n = geom.nb_virt_items(LataField_base::ELEM);
19763 + unsigned char realVal = 0;
19764 + unsigned char ghost = 0; // Sera modifie par AddGhostZoneType
19765 + avtGhostData::AddGhostZoneType(ghost, DUPLICATED_ZONE_INTERNAL_TO_PROBLEM);
19766 + vtkUnsignedCharArray *ghostcells = vtkUnsignedCharArray::New();
19767 + ghostcells->SetName("avtGhostZones");
19768 + ghostcells->SetNumberOfTuples(ncells);
19769 + unsigned char *dat = (unsigned char *) ghostcells->GetVoidPointer(0);
19770 + for (i = 0; i < ncells - n; i++)
19771 + dat[i] = realVal;
19772 + for (i = ncells - n; i < ncells; i++)
19774 + ugrid->GetCellData()->AddArray(ghostcells);
19775 + ugrid->GetInformation()->Set(
19776 + vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(), 0);
19777 + ghostcells->Delete();
19779 + return_value = ugrid;
19781 + } else if (ijk_ptr) {
19782 + const DomainIJK & geom = *ijk_ptr;
19784 + // Maillage regulier : on transmet la grille ijk
19785 + vtkRectilinearGrid *sgrid = vtkRectilinearGrid::New();
19787 + const int dim = geom.coord_.size();
19788 + ArrOfInt ncoord(3, 1);
19790 + for (i = 0; i < dim; i++)
19791 + ncoord[i] = geom.coord_[i].size_array();
19792 + sgrid->SetDimensions(ncoord[0], ncoord[1], ncoord[2]);
19794 + for (i = 0; i < 3; i++) {
19796 + vtkFloatArray *c;
19797 + c = vtkFloatArray::New();
19798 + const int n = ncoord[i];
19799 + c->SetNumberOfTuples(n);
19800 + data = (float *) c->GetVoidPointer(0);
19802 + const ArrOfFloat & coord = geom.coord_[i];
19803 + for (int j = 0; j < n; j++)
19804 + data[j] = coord[j];
19809 + case 0: sgrid->SetXCoordinates(c); break;
19810 + case 1: sgrid->SetYCoordinates(c); break;
19811 + case 2: sgrid->SetZCoordinates(c); break;
19816 + // Create "invalid cells" data (GettingDataIntoVisit.pdf, page 136)
19817 + // and "ghost cells"
19818 + const int n = geom.invalid_connections_.size_array();
19819 + if (n > 0 || geom.virtual_layer_begin_ || geom.virtual_layer_end_) {
19820 + const int ncells = geom.nb_elements();
19821 + unsigned char realVal = 0;
19822 + unsigned char invalid = 0; // Sera modifie par AddGhostZoneType
19823 + unsigned char ghost = 0;
19824 + avtGhostData::AddGhostZoneType(invalid, ZONE_NOT_APPLICABLE_TO_PROBLEM);
19825 + avtGhostData::AddGhostZoneType(ghost, DUPLICATED_ZONE_INTERNAL_TO_PROBLEM);
19826 + vtkUnsignedCharArray *ghostcells = vtkUnsignedCharArray::New();
19827 + ghostcells->SetName("avtGhostZones");
19828 + ghostcells->SetNumberOfTuples(ncells);
19829 + unsigned char *dat = (unsigned char *) ghostcells->GetVoidPointer(0);
19831 + for (i = 0; i < ncells; i++)
19832 + dat[i] = realVal;
19836 + for (i = 0; i < ncells; i++) {
19837 + if (geom.invalid_connections_[i])
19838 + dat[i] = invalid;
19844 + for (i = 0; i < dim-1; i++)
19845 + ij *= ncoord[i]-1;
19846 + if (geom.virtual_layer_begin_) {
19847 + // first layer of cells is ghost
19848 + for (i = 0; i < ij * geom.virtual_layer_begin_; i++)
19851 + if (geom.virtual_layer_end_) {
19852 + // last layer of cells is ghost
19853 + for (i = ncells - ij * geom.virtual_layer_end_; i < ncells; i++)
19857 + sgrid->GetCellData()->AddArray(ghostcells);
19858 + sgrid->GetInformation()->Set(
19859 + vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(), 0);
19860 + ghostcells->Delete();
19863 + return_value = sgrid;
19865 + cerr << "Error in avtlataFileFormat::GetMesh: unknown geometry type" << endl;
19869 + filter_.release_geometry(geometry);
19871 + catch (LataDBError err) {
19872 + cerr << "Error in getmesh " << timestate << " " << block << " " << meshname << " " << err.describe() << endl;
19876 + return return_value;
19880 +// ****************************************************************************
19881 +// Method: avtlataFileFormat::GetVar
19884 +// Gets a scalar variable associated with this file. Although VTK has
19885 +// support for many different types, the best bet is vtkFloatArray, since
19886 +// that is supported everywhere through VisIt.
19889 +// timestate The index of the timestate. If GetNTimesteps returned
19890 +// 'N' time steps, this is guaranteed to be between 0 and N-1.
19891 +// domain The index of the domain. If there are NDomains, this
19892 +// value is guaranteed to be between 0 and NDomains-1,
19893 +// regardless of block origin.
19894 +// varname The name of the variable requested.
19896 +// Programmer: fauchet -- generated by xml2avt
19898 +// ****************************************************************************
19901 +avtlataFileFormat::GetVar(int timestate, int block, const char *varname)
19903 + vtkDataArray * return_value = 0;
19905 + debug1 << "Getvar time:" << timestate
19906 + << " block:" << block
19907 + << " varname:" << varname << endl;
19909 + if (filter_.get_nb_timesteps() > 1)
19912 + Field_UName field_uname;
19914 + get_field_info_from_visitname(varname, field_uname, component);
19916 + if (component < 0) {
19917 + cerr << "Error: avtlataFileFormat::GetVar called for vector field" << endl;
19921 + Field_Id id(field_uname, timestate, block);
19923 + const LataField_base & field = filter_.get_field(id);
19925 + const Field<FloatTab> * float_field_ptr = dynamic_cast<const Field<FloatTab>*>(&field);
19926 + const Field<IntTab> * int_field_ptr = dynamic_cast<const Field<IntTab>*>(&field);
19928 + if (float_field_ptr) {
19929 + vtkFloatArray *rv = vtkFloatArray::New();
19930 + const Field<FloatTab> & fld = *float_field_ptr;
19931 + const FloatTab & values = fld.data_;
19932 + int ntuples = values.dimension(0);
19933 + rv->SetNumberOfTuples(ntuples);
19934 + float * data = rv->GetPointer(0);
19935 + for (int i = 0; i < ntuples; i++)
19936 + data[i] = values(i, component);
19937 + return_value = rv;
19938 + } else if (int_field_ptr) {
19939 + vtkIntArray *rv = vtkIntArray::New();
19940 + const Field<IntTab> & fld = *int_field_ptr;
19941 + const IntTab & values = fld.data_;
19942 + int ntuples = values.dimension(0);
19943 + rv->SetNumberOfTuples(ntuples);
19944 + int * data = rv->GetPointer(0);
19945 + for (int i = 0; i < ntuples; i++)
19946 + data[i] = values(i, component);
19947 + return_value = rv;
19949 + cerr << "Error in avtlataFileFormat::GetVar: unknown data type" << endl;
19952 + filter_.release_field(field);
19954 + catch (LataDBError err) {
19955 + cerr << "Error in getvar " << timestate << " " << block << " " << varname << " " << err.describe() << endl;
19958 + return return_value;
19962 +// ****************************************************************************
19963 +// Method: avtlataFileFormat::GetVectorVar
19966 +// Gets a vector variable associated with this file. Although VTK has
19967 +// support for many different types, the best bet is vtkFloatArray, since
19968 +// that is supported everywhere through VisIt.
19971 +// timestate The index of the timestate. If GetNTimesteps returned
19972 +// 'N' time steps, this is guaranteed to be between 0 and N-1.
19973 +// domain The index of the domain. If there are NDomains, this
19974 +// value is guaranteed to be between 0 and NDomains-1,
19975 +// regardless of block origin.
19976 +// varname The name of the variable requested.
19978 +// Programmer: fauchet -- generated by xml2avt
19980 +// ****************************************************************************
19983 +avtlataFileFormat::GetVectorVar(int timestate, int block, const char *varname)
19985 + vtkDataArray * return_value = 0;
19987 + debug1 << "Getvectorvar time:" << timestate
19988 + << " block:" << block
19989 + << " varname:" << varname << endl;
19991 + if (filter_.get_nb_timesteps() > 1)
19994 + Field_UName field_uname;
19996 + get_field_info_from_visitname(varname, field_uname, component);
19998 + if (component >= 0) {
19999 + cerr << "Error: avtlataFileFormat::GetVectorVar called for scalar field" << endl;
20003 + Field_Id id(field_uname, timestate, block);
20005 + const LataField_base & field = filter_.get_field(id);
20007 + const Field<FloatTab> * float_field_ptr = dynamic_cast<const Field<FloatTab>*>(&field);
20008 + const Field<IntTab> * int_field_ptr = dynamic_cast<const Field<IntTab>*>(&field);
20010 + if (float_field_ptr) {
20011 + vtkFloatArray *rv = vtkFloatArray::New();
20012 + const Field<FloatTab> & fld = *float_field_ptr;
20013 + const FloatTab & values = fld.data_;
20014 + int ntuples = values.dimension(0);
20015 + int dim = values.dimension(1);
20016 + rv->SetNumberOfComponents(3);
20017 + rv->SetNumberOfTuples(ntuples);
20018 + float* data= rv->WritePointer(0,3*ntuples);
20019 + for (int i = 0; i < ntuples; i++)
20020 + for (int j = 0; j < 3; j++)
20021 + data[i*3+j] = (j<dim) ? values(i, j) : 0.;
20022 + return_value = rv;
20023 + } else if (int_field_ptr) {
20024 + vtkIntArray *rv = vtkIntArray::New();
20025 + const Field<IntTab> & fld = *int_field_ptr;
20026 + const IntTab & values = fld.data_;
20027 + int ntuples = values.dimension(0);
20028 + int dim = values.dimension(1);
20029 + rv->SetNumberOfComponents(3);
20030 + rv->SetNumberOfTuples(ntuples);
20031 + int* data= rv->WritePointer(0,3*ntuples);
20032 + for (int i = 0; i < ntuples; i++)
20033 + for (int j = 0; j < 3; j++)
20034 + data[i*3+j] = (j<dim) ? values(i, j) : 0;
20035 + return_value = rv;
20037 + cerr << "Error in avtlataFileFormat::GetVectorVar: unknown data type" << endl;
20040 + filter_.release_field(field);
20042 + catch (LataDBError err) {
20043 + cerr << "Error in getvectorvar " << timestate << " " << block << " " << varname << " " << err.describe() << endl;
20046 + return return_value;
20049 +void avtlataFileFormat::get_field_info_from_visitname(const char *varname, Field_UName & uname, int & component) const
20051 + const int k = field_username_.rang(varname);
20053 + cerr << "Error in avtlataFileFormat::get_field_info_from_visitname: field " << varname << " not found" << endl;
20056 + uname = field_uname_[k];
20057 + component = field_component_[k];
20059 diff --git a/databases/readers/Lata/avtlataFileFormat.h b/databases/readers/Lata/avtlataFileFormat.h
20060 new file mode 100644
20061 index 0000000..3dd8e43
20063 +++ b/databases/readers/Lata/avtlataFileFormat.h
20065 +/*****************************************************************************
20067 +* Copyright (c) 2000 - 2012, Lawrence Livermore National Security, LLC
20068 +* Produced at the Lawrence Livermore National Laboratory
20069 +* All rights reserved.
20071 +* This file is part of VisIt. For details, see http://www.llnl.gov/visit/. The
20072 +* full copyright notice is contained in the file COPYRIGHT located at the root
20073 +* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
20075 +* Redistribution and use in source and binary forms, with or without
20076 +* modification, are permitted provided that the following conditions are met:
20078 +* - Redistributions of source code must retain the above copyright notice,
20079 +* this list of conditions and the disclaimer below.
20080 +* - Redistributions in binary form must reproduce the above copyright notice,
20081 +* this list of conditions and the disclaimer (as noted below) in the
20082 +* documentation and/or materials provided with the distribution.
20083 +* - Neither the name of the UC/LLNL nor the names of its contributors may be
20084 +* used to endorse or promote products derived from this software without
20085 +* specific prior written permission.
20087 +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20088 +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20089 +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20090 +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF
20091 +* CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR
20092 +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20093 +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20094 +* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20095 +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20096 +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
20097 +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
20100 +*****************************************************************************/
20102 +// ************************************************************************* //
20103 +// avtlataFileFormat.h //
20104 +// ************************************************************************* //
20106 +#ifndef AVT_lata_FILE_FORMAT_H
20107 +#define AVT_lata_FILE_FORMAT_H
20109 +#include <avtMTMDFileFormat.h>
20112 +#include "LataFilter.h"
20114 +// ****************************************************************************
20115 +// Class: avtlataFileFormat
20118 +// Reads in lata files as a plugin to VisIt.
20120 +// Programmer: fauchet -- generated by xml2avt
20122 +// ****************************************************************************
20124 +class avtlataFileFormat : public avtMTMDFileFormat
20127 + avtlataFileFormat(const char *);
20128 + virtual ~avtlataFileFormat();
20131 + // This is used to return unconvention data -- ranging from material
20132 + // information to information about block connectivity.
20134 + // virtual void *GetAuxiliaryData(const char *var, const char *type,
20135 + // int timestep, int domain,void *args,
20136 + // DestructorFunction &);
20140 + // If you know the times and cycle numbers, overload this function.
20141 + // Otherwise, VisIt will make up some reasonable ones for you.
20143 + // virtual void GetCycles(std::vector<int> &);
20144 + // virtual void GetTimes(std::vector<double> &);
20147 + virtual int GetNTimesteps(void);
20149 + virtual const char *GetType(void) { return "lata"; };
20150 + virtual void FreeUpResources(void);
20152 + virtual vtkDataSet *GetMesh(int, int, const char *);
20153 + virtual vtkDataArray *GetVar(int, int, const char *);
20154 + virtual vtkDataArray *GetVectorVar(int, int, const char *);
20155 + virtual void GetTimes(std::vector<double>& times);
20159 + virtual void PopulateDatabaseMetaData(avtDatabaseMetaData *, int);
20161 + void register_fieldname(const char *visit_name, const Field_UName &, int component);
20162 + void register_meshname(const char *visit_name, const char *latafilter_name);
20163 + void get_field_info_from_visitname(const char *varname, Field_UName &, int & component) const;
20165 + LataDB lata_db_; // Source database
20166 + LataFilter filter_; // Data processor and cache
20167 + Noms field_username_;
20168 + Field_UNames field_uname_;
20170 + Noms mesh_username_;
20171 + Noms mesh_latafilter_name_;
20173 + // For each name, which component is it in the source field:
20174 + LataVector<int> field_component_;
20179 diff --git a/databases/readers/Lata/simd_interface.h b/databases/readers/Lata/simd_interface.h
20180 new file mode 100644
20181 index 0000000..e14c409
20183 +++ b/databases/readers/Lata/simd_interface.h
20185 +/*****************************************************************************
20187 +* Copyright (c) 2011 - 2013, CEA
20188 +* All rights reserved.
20189 +* Redistribution and use in source and binary forms, with or without
20190 +* modification, are permitted provided that the following conditions are met:
20192 +* * Redistributions of source code must retain the above copyright
20193 +* notice, this list of conditions and the following disclaimer.
20194 +* * Redistributions in binary form must reproduce the above copyright
20195 +* notice, this list of conditions and the following disclaimer in the
20196 +* documentation and/or other materials provided with the distribution.
20197 +* * Neither the name of CEA, nor the
20198 +* names of its contributors may be used to endorse or promote products
20199 +* derived from this software without specific prior written permission.
20201 +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
20202 +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20203 +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20204 +* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20205 +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20206 +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20207 +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20208 +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20209 +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20210 +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20212 +*****************************************************************************/
20214 +#include "simd_tools.h"
20216 diff --git a/databases/visit_readers.xml b/databases/visit_readers.xml
20217 index 0b1405c..05aa776 100644
20218 --- a/databases/visit_readers.xml
20219 +++ b/databases/visit_readers.xml
20220 @@ -781,6 +781,19 @@
20224 + <SourceProxy name="VisItLataReader" class="vtkVisItLataReader"
20225 + base_proxygroup="internal_readers" base_proxyname="VisItReaderBase">
20227 + long_help="Lata file reader">
20228 + Note this reader is automatically generated from wrapping a third party reader. For more information on the reader see https://wci.llnl.gov/codes/visit
20229 + The default file extensions is .lata
20232 + <ReaderFactory extensions="lata"
20233 + file_description="Lata Files" />
20237 <SourceProxy name="VisItM3DReader" class="vtkVisItM3DReader"
20238 base_proxygroup="internal_readers" base_proxyname="VisItReaderBase">