1 /****************************************************************************/
2 /* This file is part of FreeFEM. */
3 /* */
4 /* FreeFEM is free software: you can redistribute it and/or modify */
5 /* it under the terms of the GNU Lesser General Public License as */
6 /* published by the Free Software Foundation, either version 3 of */
7 /* the License, or (at your option) any later version. */
8 /* */
9 /* FreeFEM is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU Lesser General Public License for more details. */
13 /* */
14 /* You should have received a copy of the GNU Lesser General Public License */
15 /* along with FreeFEM. If not, see <http://www.gnu.org/licenses/>. */
16 /****************************************************************************/
17 // SUMMARY : Add interface with partionning library scotch
18 // LICENSE : LGPLv3
19 // ORG : LJLL Universite Pierre et Marie Curie, Paris, FRANCE
20 // AUTHORS : Mathieu Cloirec
21 // E-MAIL : cloirec@cines.fr
22
23 /* clang-format off */
24 //ff-c++-LIBRARY-dep: hdf5
25 //ff-c++-cpp-dep:
26 /* clang-format on */
27
28 #include "ff++.hpp"
29 #include "write_xdmf.hpp"
30 #include "write_hdf5.hpp"
31
32 #ifndef H5_NO_NAMESPACE
33 #ifndef H5_NO_STD
34 using std::cout;
35 using std::endl;
36 #endif // H5_NO_STD
37 #endif
38
39 #include "H5Cpp.h"
40
41 #ifndef H5_NO_NAMESPACE
42 using namespace H5;
43 #endif
44 #ifdef DEBUG
45 int debug = 1;
46 #else
47 int debug = 0;
48 #endif
49
50 using namespace std;
51
52 class datasolHDF5Mesh2_Op : public E_F0mps {
53 public:
54 typedef long Result;
55 Expression eTh;
56 Expression filename;
57 struct Expression2 {
58 long what; // 1 scalar, 2 vector, 3 symtensor
59 long nbfloat; // 1 scalar, 2 vector (3D), 3 symtensor(3D)
60 Expression e[3];
61 Expression lename;
Expression2datasolHDF5Mesh2_Op::Expression262 Expression2( ) {
63 e[0] = 0;
64 e[1] = 0;
65 e[2] = 0;
66 what = 0;
67 nbfloat = 0;
68 };
operator []datasolHDF5Mesh2_Op::Expression269 Expression &operator[](int i) { return e[i]; }
70
evaldatasolHDF5Mesh2_Op::Expression271 double eval(int i, Stack stack) const {
72 if (e[i]) {
73 return GetAny< double >((*e[i])(stack));
74 } else {
75 return 0;
76 }
77 }
78 };
79 vector< Expression2 > l;
80 static const int n_name_param = 1;
81 static basicAC_F0::name_and_type name_param[];
82 Expression nargs[n_name_param];
arg(int i,Stack stack,long a) const83 long arg(int i, Stack stack, long a) const {
84 return nargs[i] ? GetAny< long >((*nargs[i])(stack)) : a;
85 }
86
87 public:
datasolHDF5Mesh2_Op(const basicAC_F0 & args)88 datasolHDF5Mesh2_Op(const basicAC_F0 &args) : l((args.size( ) - 2) / 2) {
89 int nbofsol;
90 int ddim = 2;
91 int stsize = 3;
92
93 cout << " " << endl;
94
95 if (debug == 1) {
96 cout << "construction data hdf5 solution avec datasolHDF5Mesh2_Op" << endl;
97 cout << "taille de args " << args.size( ) << endl;
98 }
99
100 args.SetNameParam(n_name_param, name_param, nargs);
101
102 if (BCastTo< string * >(args[0])) {
103 filename = CastTo< string * >(args[0]);
104 }
105
106 if (BCastTo< pmesh >(args[1])) {
107 eTh = CastTo< pmesh >(args[1]);
108 }
109
110 nbofsol = l.size( );
111 if (debug == 1) {
112 cout << "hdf5 solution 2d nb sol: " << nbofsol << endl;
113 }
114
115 size_t kk = 0;
116
117 for (size_t i = 2; i < (unsigned int)args.size( ); i = i + 2) {
118 size_t jj = i - 2 - kk;
119 if (BCastTo< double >(args[i])) {
120 l[jj].what = 1;
121 l[jj].nbfloat = 1;
122 l[jj][0] = to< double >(args[i]);
123 if (debug == 1) {
124 cout << "hdf5 solution 2d N° " << jj << " is scalar type " << endl;
125 }
126 } else if (args[i].left( ) == atype< E_Array >( )) {
127 const E_Array *a0 = dynamic_cast< const E_Array * >(args[i].LeftValue( ));
128 if (a0->size( ) != ddim && a0->size( ) != stsize) {
129 CompileError(
130 "savesol in 2D: vector solution is 2 composant, tensor solution is 3 composant");
131 }
132
133 if (a0->size( ) == ddim) {
134 // vector solution
135 if (debug == 1) {
136 cout << "hdf5 solution 2d N° " << jj << " is vector type" << endl;
137 }
138
139 l[jj].what = 2;
140 l[jj].nbfloat = ddim;
141
142 for (int j = 0; j < ddim; j++) {
143 l[jj][j] = to< double >((*a0)[j]);
144 }
145 } else if (a0->size( ) == stsize) {
146 // symmetric tensor solution
147 if (debug == 1) {
148 cout << "hdf5 solution 2d N° " << jj << " is tensor type" << endl;
149 }
150
151 l[jj].what = 3;
152 l[jj].nbfloat = stsize;
153
154 for (int j = 0; j < stsize; j++) {
155 l[jj][j] = to< double >((*a0)[j]);
156 }
157 }
158 } else {
159 cout << " arg " << i << " " << args[i].left( ) << endl;
160 CompileError("savesol in 2D: Sorry no way to save this kind of data");
161 }
162
163 if (BCastTo< string * >(args[i + 1])) {
164 l[jj].lename = CastTo< string * >(args[i + 1]);
165 }
166
167 kk++;
168 }
169 }
170
typeargs()171 static ArrayOfaType typeargs( ) {
172 return ArrayOfaType(atype< string * >( ), atype< pmesh >( ), true);
173 }
174
f(const basicAC_F0 & args)175 static E_F0 *f(const basicAC_F0 &args) { return new datasolHDF5Mesh2_Op(args); }
176
177 AnyType operator( )(Stack stack) const;
178 };
179
180 basicAC_F0::name_and_type datasolHDF5Mesh2_Op::name_param[] = {{"order", &typeid(long)}};
operator ( )(Stack stack) const181 AnyType datasolHDF5Mesh2_Op::operator( )(Stack stack) const {
182 // Hyp A
183 // -----
184 // A priori, paraview - hdf5 -xdmf impose qu un vecteur possede 3 composantes.
185 // Donc, pour stocker la solution, on transforme le resultat produit par le
186 // code, i.e. vecteur 2D, en vecteur 3D en initialisant le vecteur 3D a zero.
187 //
188
189 // Hyp B
190 // -----
191 // Etant donne que le tenseur est un tenseur 2d symetrique,
192 // on fait le choix, ici, pour paraview, de le representer sous forme
193 // d'un vecteur a 3 composantes Exx,Eyy,Exy=Eyx
194 // un autre choix possible serait de stocker les valeurs sous
195 // un tenseur 3x3 avec Ezz=Exz=Ezx=Eyz=Ezy=0
196
197 // mp & mps set but not used
198 // MeshPoint *mp(MeshPointStack(stack)), mps=*mp;
199
200 const Mesh *pTh = GetAny< const Mesh * >((*eTh)(stack));
201 string *ffname = GetAny< string * >((*filename)(stack));
202
203 ffassert(pTh);
204 const Mesh &Th = *pTh;
205 int nt = Th.nt;
206 int nv = Th.nv;
207 int nbsol;
208 int solnbfloat;
209 int resultorder = arg(0, stack, 1L);
210 string *datafieldname;
211 long longdefault = 0;
212
213 if (verbosity > 2) {
214 cout << "filename data hdf5 solution () : " << ffname << endl;
215 cout << "hdf5 solution () nb vertices: " << nv << endl;
216 cout << "hdf5 solution () nb triangles: " << nt << endl;
217 cout << "hdf5 solution () nb of fields: " << l.size( ) << endl;
218 }
219
220 // write xdmf sol file
221 WriteXdmf *XdmfSolFile2D = new WriteXdmf(ffname->c_str( ), nt, nv);
222 XdmfSolFile2D->WriteXdmfSolFile2DInit( );
223
224 for (size_t i = 0; i < l.size( ); i++) {
225 // Hyp A
226 int trans = -1;
227 if (l[i].nbfloat == 2) {
228 trans = 3;
229 } else {
230 trans = l[i].nbfloat;
231 }
232
233 datafieldname = GetAny< string * >((*(l[i].lename))(stack));
234 XdmfSolFile2D->WriteXdmfSolFile2DAddField(datafieldname, (l[i].what - 1), resultorder, trans);
235 }
236
237 XdmfSolFile2D->WriteXdmfSolFile2DFinalize( );
238 delete XdmfSolFile2D;
239
240 // write hdf5 sol file
241 WriteHdf5 *Hdf5SolFile2D = new WriteHdf5(ffname->c_str( ), nt, nv);
242 Hdf5SolFile2D->WriteHdf5SolFile2DInit( );
243
244 solnbfloat = 0;
245
246 for (size_t ii = 0; ii < l.size( ); ii++) {
247 datafieldname = GetAny< string * >((*(l[ii].lename))(stack));
248
249 if (resultorder == 0) {
250 // ordre 0
251 // a priori la solution est par triangle
252
253 // Hyp A
254 int trans = -1;
255 if (l[ii].nbfloat == 2) {
256 trans = 3;
257 } else {
258 trans = l[ii].nbfloat;
259 }
260
261 // initialisation a 0 du field tab
262 float *tab_vfield;
263 tab_vfield = new float[nt * trans];
264 memset(tab_vfield, 0, sizeof(float) * nt * trans);
265
266 solnbfloat = l[ii].nbfloat;
267 nbsol = nt;
268 KN< double > valsol(solnbfloat * nbsol);
269 MeshPoint *mp3(MeshPointStack(stack));
270 R2 Cdg_hat = R2(1. / 3., 1. / 3.);
271
272 // boucle sur les triangles
273 for (int it = 0; it < nt; it++) {
274 int h = 0;
275 const Mesh::Triangle &K(Th.t(it));
276 mp3->set(Th, K(Cdg_hat), Cdg_hat, K, K.lab);
277
278 // boucle sur chaque champ des triangles
279 for (size_t i = 0; i < l.size( ); i++) {
280 // boucle sur les valeurs de chaque champ des triangles
281 for (size_t j = 0; j < (unsigned int)l[ii].nbfloat; j++) {
282 valsol[it * solnbfloat + h] = l[ii].eval(j, stack);
283 h = h + 1;
284 }
285 }
286
287 assert(solnbfloat == h);
288 }
289
290 // creation du tableau de valeur des champs par element (idem valsol mais pour le cas vecteur
291 // il faut 0 sur la troisieme composante : Hyp A
292 for (int i = 0; i < nt; i++) {
293 for (int h = 0; h < solnbfloat; h++) {
294 tab_vfield[i * trans + h] = valsol[i * solnbfloat + h];
295 }
296 }
297
298 Hdf5SolFile2D->WriteHdf5SolFile2DAddField(datafieldname, resultorder, trans, (l[ii].what - 1),
299 tab_vfield);
300 delete[] tab_vfield;
301 } else {
302 // Hyp A
303 int trans = -1;
304 if (l[ii].nbfloat == 2) {
305 trans = 3;
306 } else {
307 trans = l[ii].nbfloat;
308 }
309
310 // initialisation a 0 du field tab
311 float *tab_vfield;
312 tab_vfield = new float[nv * trans];
313 memset(tab_vfield, 0, sizeof(float) * nv * trans);
314
315 solnbfloat = l[ii].nbfloat;
316 nbsol = nv;
317 KN< double > valsol(solnbfloat * nbsol);
318 valsol = 0.;
319 KN< int > takemesh(nbsol);
320 MeshPoint *mp3(MeshPointStack(stack));
321 takemesh = 0;
322
323 // boucle sur les triangles
324 for (int it = 0; it < nt; it++) {
325 // boucle sur les 3 noeuds du triangle
326 for (int iv = 0; iv < 3; iv++) {
327 // i = numéro du noeud
328 // ex : triangle 0 avec noeuds : 2 3 9
329 int i = Th(it, iv);
330 mp3->setP(&Th, it, iv);
331 int h = 0;
332
333 for (size_t j = 0; j < (unsigned int)l[ii].nbfloat; j++) {
334 // calcul de la somme des valeurs du champ Ux (par exemple) sur un noeud
335 // appartenant à plusieurs triangles
336 // u_noeud_2_appartenant_au_triangle_0 + u_noeud_2_appartenant_au_triangle_23 + ...
337 valsol[i * solnbfloat + h] = valsol[i * solnbfloat + h] + l[ii].eval(j, stack);
338 h = h + 1;
339 }
340
341 assert(solnbfloat == h);
342 takemesh[i] = takemesh[i] + 1;
343 }
344 }
345
346 for (int i = 0; i < nv; i++) {
347 for (int h = 0; h < solnbfloat; h++) {
348 // calcul de la moyenne des valeurs du champ Ux (par exemple) sur un noeud
349 // appartenant à plusieurs triangles
350 valsol[i * solnbfloat + h] = valsol[i * solnbfloat + h] / takemesh[i];
351 }
352 }
353
354 for (int i = 0; i < nv; i++) {
355 for (int h = 0; h < solnbfloat; h++) {
356 tab_vfield[i * trans + h] = valsol[i * solnbfloat + h];
357 }
358 }
359
360 if (verbosity > 10) {
361 for (int m = 0; m < (solnbfloat * nbsol); m++) {
362 cout << "valsol[m] hdf5 solution : " << valsol[m] << " for lii : " << ii << endl;
363 }
364 }
365
366 Hdf5SolFile2D->WriteHdf5SolFile2DAddField(datafieldname, resultorder, trans, (l[ii].what - 1),
367 tab_vfield);
368 delete[] tab_vfield;
369 }
370 }
371
372 Hdf5SolFile2D->WriteHdf5SolFile2DFinalize( );
373 delete Hdf5SolFile2D;
374 return longdefault;
375 };
376
377 // datasolMesh3
378 template< class v_fes >
379 class datasolHDF5Mesh3_Op : public E_F0mps {
380 public:
381 typedef long Result;
382 Expression eTh;
383 Expression filename;
384 struct Expression2 {
385 long what; // 1 scalar, 2 vector, 3 symtensor
386 long nbfloat; // 1 scalar, 3 vector (3D), 6 symtensor(3D)
387 Expression e[6];
388 Expression lename;
Expression2datasolHDF5Mesh3_Op::Expression2389 Expression2( ) {
390 e[0] = 0;
391 e[1] = 0;
392 e[2] = 0;
393 e[3] = 0;
394 e[4] = 0;
395 e[5] = 0;
396 what = 0;
397 nbfloat = 0;
398 };
operator []datasolHDF5Mesh3_Op::Expression2399 Expression &operator[](int i) { return e[i]; }
400
evaldatasolHDF5Mesh3_Op::Expression2401 double eval(int i, Stack stack) const {
402 if (e[i]) {
403 return GetAny< double >((*e[i])(stack));
404 } else {
405 return 0;
406 }
407 }
408 };
409 vector< Expression2 > l;
410 static const int n_name_param = 1;
411 static basicAC_F0::name_and_type name_param[];
412 Expression nargs[n_name_param];
arg(int i,Stack stack,long a) const413 long arg(int i, Stack stack, long a) const {
414 return nargs[i] ? GetAny< long >((*nargs[i])(stack)) : a;
415 }
416
417 public:
datasolHDF5Mesh3_Op(const basicAC_F0 & args)418 datasolHDF5Mesh3_Op(const basicAC_F0 &args) : l((args.size( ) - 2) / 2) {
419 int nbofsol;
420 int ddim = 3;
421 int stsize = 6;
422
423 cout << " " << endl;
424 if (debug == 1) {
425 cout << "construction data hdf5 solution avec datasolHDF5Mesh3_Op" << endl;
426 cout << "taille de args " << args.size( ) << endl;
427 }
428
429 args.SetNameParam(n_name_param, name_param, nargs);
430 if (BCastTo< string * >(args[0])) {
431 filename = CastTo< string * >(args[0]);
432 }
433
434 if (BCastTo< pmesh3 >(args[1])) {
435 eTh = CastTo< pmesh3 >(args[1]);
436 }
437
438 nbofsol = l.size( );
439 if (verbosity > 1) {
440 cout << "hdf5 solution 3d nb sol: " << nbofsol << endl;
441 }
442
443 size_t kk = 0;
444
445 for (size_t i = 2; i < (unsigned int)args.size( ); i = i + 2) {
446 size_t jj = i - 2 - kk;
447 if (BCastTo< double >(args[i])) {
448 l[jj].what = 1;
449 l[jj].nbfloat = 1;
450 l[jj][0] = to< double >(args[i]);
451 if (verbosity > 9) {
452 cout << "hdf5 solution 3d N° " << jj << " is scalar type " << endl;
453 }
454 } else if (args[i].left( ) == atype< E_Array >( )) {
455 const E_Array *a0 = dynamic_cast< const E_Array * >(args[i].LeftValue( ));
456 if (a0->size( ) != ddim && a0->size( ) != stsize) {
457 CompileError(
458 "savesol in 3D: vector solution is 3 composant, tensor solution is 6 composant");
459 }
460
461 if (a0->size( ) == ddim) {
462 // vector solution
463 if (verbosity > 9) {
464 cout << "hdf5 solution 3d N° " << jj << " is vector type" << endl;
465 }
466
467 l[jj].what = 2;
468 l[jj].nbfloat = ddim;
469
470 for (int j = 0; j < ddim; j++) {
471 l[jj][j] = to< double >((*a0)[j]);
472 }
473 } else if (a0->size( ) == stsize) {
474 // symmetric tensor solution
475 if (verbosity > 9) {
476 cout << "hdf5 solution 3d N° " << jj << " is tensor type" << endl;
477 }
478
479 l[jj].what = 3;
480 l[jj].nbfloat = stsize;
481
482 for (int j = 0; j < stsize; j++) {
483 l[jj][j] = to< double >((*a0)[j]);
484 }
485 }
486 } else {
487 CompileError("savesol in 3D: Sorry no way to save this kind of data");
488 }
489
490 if (BCastTo< string * >(args[i + 1])) {
491 l[jj].lename = CastTo< string * >(args[i + 1]);
492 }
493
494 kk++;
495 }
496 }
497
typeargs()498 static ArrayOfaType typeargs( ) {
499 return ArrayOfaType(atype< string * >( ), atype< pmesh3 >( ), true);
500 }
501
f(const basicAC_F0 & args)502 static E_F0 *f(const basicAC_F0 &args) { return new datasolHDF5Mesh3_Op(args); }
503
504 AnyType operator( )(Stack stack) const;
505 };
506
507 template< class v_fes >
508 basicAC_F0::name_and_type datasolHDF5Mesh3_Op< v_fes >::name_param[] = {{"order", &typeid(long)}};
509
510 template< class v_fes >
operator ( )(Stack stack) const511 AnyType datasolHDF5Mesh3_Op< v_fes >::operator( )(Stack stack) const {
512 const Mesh3 *pTh = GetAny< const Mesh3 * >((*eTh)(stack));
513 string *ffname = GetAny< string * >((*filename)(stack));
514
515 ffassert(pTh);
516 const Mesh3 &Th = *pTh;
517 int trans = -1;
518 int nt = Th.nt;
519 int nv = Th.nv;
520 int nbsol;
521 int solnbfloat;
522 int resultorder = arg(0, stack, 1);
523 long longdefault = 0;
524 string *datafieldname;
525
526 if (verbosity > 2) {
527 cout << "filename data hdf5 solution () : " << ffname << endl;
528 cout << "hdf5 solution () nb vertices: " << nv << endl;
529 cout << "hdf5 solution () nb tetrahedrons: " << nt << endl;
530 cout << "hdf5 solution () nb of fields: " << l.size( ) << endl;
531 }
532
533 // write xdmf sol file
534 WriteXdmf *XdmfSolFile3D = new WriteXdmf(ffname->c_str( ), nt, nv);
535 XdmfSolFile3D->WriteXdmfSolFile3DInit( );
536
537 for (size_t i = 0; i < l.size( ); i++) {
538 // Hyp A
539 trans = l[i].nbfloat;
540 datafieldname = GetAny< string * >((*(l[i].lename))(stack));
541 XdmfSolFile3D->WriteXdmfSolFile3DAddField(datafieldname, (l[i].what - 1), resultorder, trans);
542 }
543
544 XdmfSolFile3D->WriteXdmfSolFile3DFinalize( );
545 delete XdmfSolFile3D;
546
547 // write hdf5 sol file
548 WriteHdf5 *Hdf5SolFile3D = new WriteHdf5(ffname->c_str( ), nt, nv);
549 Hdf5SolFile3D->WriteHdf5SolFile3DInit( );
550
551 solnbfloat = 0;
552
553 for (size_t ii = 0; ii < l.size( ); ii++) {
554 datafieldname = GetAny< string * >((*(l[ii].lename))(stack));
555 trans = l[ii].nbfloat;
556
557 if (resultorder == 0) {
558 // Tetrahedra
559 // ordre 0
560 float *tab_vfield;
561 tab_vfield = new float[nt * trans];
562 memset(tab_vfield, 0, sizeof(float) * nt * trans);
563 solnbfloat = l[ii].nbfloat;
564
565 nbsol = nt;
566 KN< double > valsol(solnbfloat * nbsol);
567 MeshPoint *mp3(MeshPointStack(stack));
568 R3 Cdg_hat = R3(1. / 4., 1. / 4., 1. / 4.);
569
570 // boucle sur les tetrahedres
571 for (int it = 0; it < nt; it++) {
572 int h = 0;
573 const Tet &K(Th.elements[it]);
574 mp3->set(Th, K(Cdg_hat), Cdg_hat, K, K.lab);
575
576 // boucle sur chaque champ des tetrahedres
577 for (size_t i = 0; i < l.size( ); i++) {
578 // boucle sur les valeurs de chaque champ des tetrahedres
579 for (size_t j = 0; j < (unsigned int)l[ii].nbfloat; j++) {
580 valsol[it * solnbfloat + h] = l[ii].eval(j, stack);
581 h = h + 1;
582 }
583 }
584
585 assert(solnbfloat == h);
586 }
587
588 // creation du tableau de valeur des champs par element
589 for (int i = 0; i < nt; i++) {
590 for (int h = 0; h < solnbfloat; h++) {
591 tab_vfield[i * trans + h] = valsol[i * solnbfloat + h];
592 }
593 }
594
595 Hdf5SolFile3D->WriteHdf5SolFile3DAddField(datafieldname, resultorder, trans, (l[ii].what - 1),
596 tab_vfield);
597 delete[] tab_vfield;
598 }
599
600 if (resultorder == 1) {
601 // ordre 1
602 float *tab_vfield;
603 tab_vfield = new float[nv * trans];
604 memset(tab_vfield, 0, sizeof(float) * nv * trans);
605 solnbfloat = l[ii].nbfloat;
606 nbsol = nv;
607 KN< double > valsol(solnbfloat * nbsol);
608 KN< int > takemesh(nbsol);
609 MeshPoint *mp3(MeshPointStack(stack));
610 // R3 Cdg_hat = R3(1./4.,1./4.,1./4.);
611 takemesh = 0;
612
613 // boucle sur les tetrahedres
614 for (int it = 0; it < nt; it++) {
615 // boucle sur les 4 noeuds du tetrahedre
616 for (int iv = 0; iv < 4; iv++) {
617 int i = Th(it, iv);
618 if (takemesh[i] == 0) {
619 mp3->setP(&Th, it, iv);
620 int h = 0;
621
622 for (size_t j = 0; j < (unsigned int)l[ii].nbfloat; j++) {
623 valsol[i * solnbfloat + h] = l[ii].eval(j, stack);
624 h = h + 1;
625 }
626
627 assert(solnbfloat == h);
628 takemesh[i] = takemesh[i] + 1;
629 }
630 }
631 }
632
633 for (int i = 0; i < nv; i++) {
634 for (int h = 0; h < solnbfloat; h++) {
635 tab_vfield[i * trans + h] = valsol[i * solnbfloat + h];
636 }
637 }
638
639 if (verbosity > 9) {
640 for (int m = 0; m < (solnbfloat * nbsol); m++) {
641 cout << "valsol[m] hdf5 solution : " << valsol[m] << " for lii : " << ii << endl;
642 }
643 }
644
645 Hdf5SolFile3D->WriteHdf5SolFile3DAddField(datafieldname, resultorder, trans, (l[ii].what - 1),
646 tab_vfield);
647 delete[] tab_vfield;
648 }
649 }
650
651 Hdf5SolFile3D->WriteHdf5SolFile3DFinalize( );
652 delete Hdf5SolFile3D;
653 return longdefault;
654 }
655
Load_Init()656 static void Load_Init( ) {
657 cout << " " << endl;
658 cout << " ---------------------- " << endl;
659
660 typedef const Mesh *pmesh;
661 typedef const Mesh3 *pmesh3;
662
663 if (verbosity > 2) {
664 cout << " load:popen.cpp " << endl;
665 }
666
667 // 2D
668 Global.Add("savehdf5sol", "(", new OneOperatorCode< datasolHDF5Mesh2_Op >);
669
670 // 3D
671 Global.Add("savehdf5sol", "(", new OneOperatorCode< datasolHDF5Mesh3_Op< v_fes3 > >);
672 }
673
674 LOADFUNC(Load_Init)
675