LifeV
TestImportExport.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3  *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23  *******************************************************************************
24  */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief TestImportExport
30 
31  @author Tiziano Passerini <tiziano@mathcs.emory.edu>
32  @contributor
33  @maintainer
34 
35  @date 05-2011
36 
37  */
38 
39 #ifndef TESTIMPORTEXPORT_HPP_
40 #define TESTIMPORTEXPORT_HPP_ 1
41 
42 // LifeV definition files
43 #include <lifev/core/LifeV.hpp>
44 #include <lifev/core/util/Displayer.hpp>
45 #include <lifev/core/util/LifeChrono.hpp>
46 #include <lifev/core/fem/TimeData.hpp>
47 #include <lifev/core/filter/Exporter.hpp>
48 #include <lifev/core/mesh/MeshData.hpp>
49 #include <lifev/core/mesh/MeshPartitioner.hpp>
50 #include <lifev/navier_stokes/function/Womersley.hpp>
51 #include <lifev/navier_stokes/function/RossEthierSteinmanDec.hpp>
52 
53 
54 // Trilinos-MPI communication definitions
55 #include <Epetra_ConfigDefs.h>
56 #ifdef HAVE_MPI
57 #include "Epetra_MpiComm.h"
58 #else
59 #include "Epetra_SerialComm.h"
60 #endif
61 
62 
64 {
65 public:
66 
67  // Object type definitions
69  typedef LifeV::RossEthierSteinmanUnsteadyDec problem_Type;
74  typedef std::function < LifeV::Real ( LifeV::Real const&,
75  LifeV::Real const&,
76  LifeV::Real const&,
77  LifeV::Real const&,
78  LifeV::UInt const& ) > function_Type;
79 
80  TestImportExport ( const commPtr_Type& commPtr );
81 
82  template<typename ImporterType, typename ExporterType>
83  bool run ( GetPot& commandLine, const std::string& testString = "import" );
84 
85  template<typename ImporterType>
86  bool importLoop ( const std::shared_ptr< ImporterType >& importerPtr );
87 
88  template<typename ExporterType>
89  bool exportLoop ( const std::shared_ptr< ExporterType >& exporterPtr );
90 
91 private:
92  void loadData ( GetPot& commandLine );
93  void buildMesh();
94  void buildFESpaces();
95  template<typename ExporterType>
96  void buildExporter ( std::shared_ptr< ExporterType >& exporterPtr,
97  const std::string& prefix ) const;
98 
104 
107 
110 
113 
116 };
117 
118 
120  M_commPtr ( commPtr ),
121  M_displayer ( commPtr )
122 {}
123 
124 
125 void
127 {
128  using namespace LifeV;
129  // Chronometer
130  LifeChrono chrono;
131 
132  // +-----------------------------------------------+
133  // | Loading the data |
134  // +-----------------------------------------------+
135  M_displayer.leaderPrint ( "[Loading the data]\n" );
136  chrono.start();
137 
138  const std::string problemName = commandLine.follow ("", 2, "-p", "--problem");
139  const std::string defaultDataFileName ("data" + problemName);
140  const std::string dataFileName = commandLine.follow (defaultDataFileName.c_str(), 2, "-f", "--file");
141  M_dataFile = GetPot (dataFileName);
142 
143  UInt numVectors = M_dataFile ("importer/numVectors", 0);
144  UInt numScalars = M_dataFile ("importer/numScalars", 0);
145 
146  M_vectorInterpolantPtr.resize (numVectors);
147  M_scalarInterpolantPtr.resize (numScalars);
148 
149  M_vectorImportedPtr.resize (numVectors);
150  M_scalarImportedPtr.resize (numScalars);
151 
152  M_vectorName.resize (numVectors);
153  M_scalarName.resize (numScalars);;
154 
155  for ( UInt iVec = 0; iVec < numVectors; ++iVec )
156  {
157  std::stringstream ss;
158  ss.str ("");
159  ss << "importer/vector" << iVec << "Name";
160  M_vectorName[iVec] = M_dataFile (ss.str().c_str(), "");
161  }
162  for ( UInt iScal = 0; iScal < numScalars; ++iScal )
163  {
164  std::stringstream ss;
165  ss.str ("");
166  ss << "importer/scalar" << iScal << "Name";
167  M_scalarName[iScal] = M_dataFile (ss.str().c_str(), "");
168  }
169 
170  problem_Type::setParamsFromGetPot (M_dataFile);
171 
172  chrono.stop();
173  M_displayer.leaderPrint ( "[...done in ", chrono.diff(), "s]\n" );
174 }
175 
176 
177 void
179 {
180  using namespace LifeV;
181  // Chronometer
182  LifeChrono chrono;
183 
184  // +-----------------------------------------------+
185  // | Building the mesh |
186  // +-----------------------------------------------+
187  M_displayer.leaderPrint ( "[Building the mesh]\n" );
188  chrono.start();
189  std::shared_ptr< mesh_Type > fullMeshPtr ( new mesh_Type ( M_commPtr ) );
190 
191  if ( M_dataFile ("space_discretization/mesh_from_file", false) )
192  {
193  // The following is when reading from file
194  MeshData meshData;
195  meshData.setup (M_dataFile, "space_discretization");
196  //if (verbose) std::cout << "Mesh file: " << meshData.meshDir() << meshData.meshFile() << std::endl;
197  readMesh (*fullMeshPtr, meshData);
198  }
199  else
200  {
201  UInt nEl (M_dataFile ("space_discretization/dimension", 1) );
202  regularMesh3D (*fullMeshPtr, 0, nEl, nEl, nEl);
203  }
204  // Split the mesh between processors
205  MeshPartitioner<mesh_Type> meshPart ( fullMeshPtr, M_commPtr );
206  // Get the mesh for the current partition
207  M_meshPtr = meshPart.meshPartition();
208  // Release the original mesh from the MeshPartitioner object and delete the RegionMesh3D object
209  meshPart.releaseUnpartitionedMesh();
210  fullMeshPtr.reset();
211 
212  chrono.stop();
213  M_displayer.leaderPrint ( "[...done in ", chrono.diff(), "s]\n" );
214 }
215 
216 
217 void
219 {
220  using namespace LifeV;
221  // Chronometer
222  LifeChrono chrono;
223 
224  // +-----------------------------------------------+
225  // | Creating the FE spaces |
226  // +-----------------------------------------------+
227  M_displayer.leaderPrint ( "[Creating the FE spaces...]\n" );
228  chrono.start();
229 
230  const std::string vectorFE = M_dataFile ( "space_discretization/vector_fespace", "P2");
231  M_displayer.leaderPrint ( "\t-o FE for the vector: ", vectorFE, "\n" );
232 
233  M_displayer.leaderPrint ( "\t-o Building the vector FE space...\n" );
234 
235  M_vectorFESpacePtr.reset ( new feSpace_Type ( M_meshPtr, vectorFE, nDimensions, M_commPtr ) );
236 
237  M_displayer.leaderPrint ( "\t\t...ok.\n" );
238 
239  const std::string scalarFE = M_dataFile ( "space_discretization/scalar_fespace", "P1");
240  M_displayer.leaderPrint ( "\t-o FE for the scalar: ", scalarFE, "\n" );
241 
242  M_displayer.leaderPrint ( "\t-o Building the scalar FE space...\n" );
243 
244  M_scalarFESpacePtr.reset ( new feSpace_Type ( M_meshPtr, scalarFE, 1, M_commPtr ) );
245 
246  M_displayer.leaderPrint ( "\t\t...ok.\n" );
247 
248  // Total degrees of freedom (elements of matrix)
249  UInt vectorTotalDof = M_vectorFESpacePtr->map().map (Unique)->NumGlobalElements();
250  UInt scalarTotalDof = M_scalarFESpacePtr->map().map (Unique)->NumGlobalElements();
251 
252  M_displayer.leaderPrint ( "\t-o Total Dof for the vector: ", vectorTotalDof, "\n" );
253  M_displayer.leaderPrint ( "\t-o Total Dof for the scalar: ", scalarTotalDof, "\n" );
254 
255  chrono.stop();
256  M_displayer.leaderPrint ( "[...done in ", chrono.diff(), "s]\n" );
257 
258 }
259 
260 
261 template<typename ExporterType>
262 void
263 TestImportExport::buildExporter ( std::shared_ptr< ExporterType >& exporterPtr,
264  const std::string& prefix ) const
265 {
266  using namespace LifeV;
267  // Chronometer
268  LifeChrono chrono;
269 
270  // +-----------------------------------------------+
271  // | Creating the exporter |
272  // +-----------------------------------------------+
273  M_displayer.leaderPrint ( "[Creating the exporter...]\n" );
274  chrono.start();
275 
276  exporterPtr.reset ( new ExporterType ( M_dataFile, prefix ) );
277 
278  //exporterPtr->setPostDir( "./" );
279  exporterPtr->setMeshProcId ( M_meshPtr, M_commPtr->MyPID() );
280  chrono.stop();
281  M_displayer.leaderPrint ( "[...done in ", chrono.diff(), "s]\n" );
282 
283 }
284 
285 
286 template<typename ImporterType, typename ExporterType>
287 bool
288 TestImportExport::run ( GetPot& commandLine, const std::string& testString )
289 {
290  using namespace LifeV;
291 
292  bool passed ( true );
293 
294  loadData ( commandLine );
295  buildMesh();
297 
298  std::shared_ptr< ExporterType > exporterPtr;
299  std::shared_ptr< ImporterType > importerPtr;
300 
301  buildExporter ( importerPtr, M_dataFile ("importer/prefix", "testImporter" ) );
302  buildExporter ( exporterPtr, M_dataFile ("exporter/prefix", "testExporter" ) );
303 
304  importerPtr->setDataFromGetPot (M_dataFile, "importer");
305  exporterPtr->setDataFromGetPot (M_dataFile, "exporter");
306 
307  // Chronometer
308  LifeChrono globalChrono;
309 
310  // +-----------------------------------------------+
311  // | Solving the problem |
312  // +-----------------------------------------------+
313  M_displayer.leaderPrint ( "[Entering the time loop]\n" );
314  globalChrono.start();
315 
316  M_timeData.setup ( M_dataFile, "time_discretization" );
317 
318  M_timeData.updateTime();
319  M_displayer.leaderPrint ( "\t[t = ", M_timeData.time(), " s.]\n" );
320 
321 
322  // Exporting
323  if ( testString.compare ( "export" ) == 0 )
324  {
325  passed = passed && exportLoop (exporterPtr);
326  }
327 
328  MPI_Barrier (MPI_COMM_WORLD);
329  M_displayer.leaderPrint ( "Exporting finished. Now importing\n" );
330 
331  // Exporting and checking
332  passed = passed && importLoop (importerPtr);
333 
334  globalChrono.stop();
335  M_displayer.leaderPrint ( "[Time loop, elapsed time: ", globalChrono.diff(), " s.]\n" );
336 
337  return passed;
338 }
339 
340 
341 template<typename ExporterType>
342 bool
343 TestImportExport::exportLoop ( const std::shared_ptr< ExporterType >& exporterPtr )
344 {
345  using namespace LifeV;
346 
347  bool passed (true);
348 
349  ASSERT ( M_vectorInterpolantPtr.size() + M_scalarInterpolantPtr.size(), "There's no data on which to work!" )
350 
351  const UInt vectorInterpolantPtrSize = M_vectorInterpolantPtr.size();
352  const UInt scalarInterpolantPtrSize = M_scalarInterpolantPtr.size();
353 
354  // Set up the EXPORTER
355  for ( UInt iVec (0); iVec < vectorInterpolantPtrSize; ++iVec )
356  {
357  M_vectorInterpolantPtr[iVec].reset (
358  new Exporter<mesh_Type >::vector_Type ( M_vectorFESpacePtr->map(), ExporterType::MapType ) );
359  exporterPtr->addVariable ( ExporterData<mesh_Type>::VectorField, M_vectorName[iVec],
360  M_vectorFESpacePtr, M_vectorInterpolantPtr[iVec], UInt (0) );
361  }
362  for ( UInt iScal (0); iScal < scalarInterpolantPtrSize; ++iScal )
363  {
364  M_scalarInterpolantPtr[iScal].reset (
365  new Exporter<mesh_Type >::vector_Type ( M_scalarFESpacePtr->map(), ExporterType::MapType ) );
366  exporterPtr->addVariable ( ExporterData<mesh_Type>::ScalarField, M_scalarName[iScal],
367  M_scalarFESpacePtr, M_scalarInterpolantPtr[iScal], UInt (0) );
368  }
369 
370  //exporterPtr->postProcess( 0 );
371 
372  for ( ; M_timeData.canAdvance(); M_timeData.updateTime() )
373  {
374 
375  M_displayer.leaderPrint ( "[t = ", M_timeData.time(), " s.]\n" );
376 
377  // Computation of the interpolation
378  if ( vectorInterpolantPtrSize )
379  {
380  M_vectorFESpacePtr->interpolate ( static_cast<function_Type> ( problem_Type::uexact ), *M_vectorInterpolantPtr[0], M_timeData.time() );
381  }
382  if ( scalarInterpolantPtrSize )
383  {
384  M_scalarFESpacePtr->interpolate ( static_cast<function_Type> ( problem_Type::pexact ), *M_scalarInterpolantPtr[0], M_timeData.time() );
385  }
386 
387  // Exporting the solution
388  exporterPtr->postProcess ( M_timeData.time() );
389 
390  }
391 
392  exporterPtr->closeFile();
393 
394  return passed;
395 
396 }
397 
398 
399 template<typename ImporterType>
400 bool
401 TestImportExport::importLoop ( const std::shared_ptr< ImporterType >& importerPtr )
402 {
403  using namespace LifeV;
404 
405  bool passed (true);
406 
407  ASSERT ( M_vectorImportedPtr.size() + M_scalarImportedPtr.size(), "There's no data on which to work!" )
408 
409  // Set up the IMPORTER
410  ExporterData<mesh_Type>::WhereEnum whereVector =
411  ( M_vectorFESpacePtr->fe().refFE().type() == FE_P0_3D )
412  ?
413  ExporterData<mesh_Type>::Cell : ExporterData<mesh_Type>::Node;
414 
415  ExporterData<mesh_Type>::WhereEnum whereScalar =
416  ( M_scalarFESpacePtr->fe().refFE().type() == FE_P0_3D )
417  ?
418  ExporterData<mesh_Type>::Cell : ExporterData<mesh_Type>::Node;
419 
420  for ( UInt iVec (0); iVec < M_vectorImportedPtr.size(); ++iVec )
421  {
422  M_vectorImportedPtr[iVec].reset (
423  new Exporter<mesh_Type >::vector_Type ( M_vectorFESpacePtr->map(), ImporterType::MapType ) );
424 
425  importerPtr->addVariable ( ExporterData<mesh_Type>::VectorField, M_vectorName[iVec],
426  M_vectorFESpacePtr, M_vectorImportedPtr[iVec], UInt (0),
427  ExporterData<mesh_Type>::UnsteadyRegime,
428  whereVector );
429  }
430  for ( UInt iScal (0); iScal < M_scalarImportedPtr.size(); ++iScal )
431  {
432  M_scalarImportedPtr[iScal].reset (
433  new Exporter<mesh_Type >::vector_Type ( M_scalarFESpacePtr->map(), ImporterType::MapType ) );
434  importerPtr->addVariable ( ExporterData<mesh_Type>::ScalarField, M_scalarName[iScal],
435  M_scalarFESpacePtr, M_scalarImportedPtr[iScal], UInt (0),
436  ExporterData<mesh_Type>::UnsteadyRegime,
437  whereScalar );
438  }
439 
440  const UInt vectorImportedPtrSize = M_vectorImportedPtr.size();
441  const UInt scalarImportedPtrSize = M_scalarImportedPtr.size();
442 
443  Exporter<mesh_Type >::vector_Type vectorDiff ( M_vectorFESpacePtr->map(), ImporterType::MapType );
444  Exporter<mesh_Type >::vector_Type scalarDiff ( M_scalarFESpacePtr->map(), ImporterType::MapType );
445 
446  // Set up the INTERPOLANT
447  for ( UInt iVec (0); iVec < vectorImportedPtrSize; ++iVec )
448  {
449  M_vectorInterpolantPtr[iVec].reset (
450  new Exporter<mesh_Type >::vector_Type ( M_vectorFESpacePtr->map(), ImporterType::MapType ) );
451  }
452  for ( UInt iScal (0); iScal < scalarImportedPtrSize; ++iScal )
453  {
454  M_scalarInterpolantPtr[iScal].reset (
455  new Exporter<mesh_Type >::vector_Type ( M_scalarFESpacePtr->map(), ImporterType::MapType ) );
456  }
457 
458  M_timeData.setup ( M_dataFile, "time_discretization" );
459  M_timeData.updateTime();
460 
461  for ( ; M_timeData.canAdvance(); M_timeData.updateTime() )
462  {
463  // Computation of the interpolation
464  if ( vectorImportedPtrSize )
465  {
466  M_vectorFESpacePtr->interpolate ( static_cast<function_Type> ( problem_Type::uexact ), *M_vectorInterpolantPtr[0], M_timeData.time() );
467  }
468  if ( scalarImportedPtrSize )
469  {
470  M_scalarFESpacePtr->interpolate ( static_cast<function_Type> ( problem_Type::pexact ), *M_scalarInterpolantPtr[0], M_timeData.time() );
471  }
472 
473  // Importing the solution
474  importerPtr->import ( M_timeData.time() );
475 
476  Real maxDiff (1.e6);
477  if ( vectorImportedPtrSize )
478  {
479  vectorDiff = *M_vectorInterpolantPtr[0];
480  vectorDiff += (-*M_vectorImportedPtr[0]);
481  maxDiff = vectorDiff.normInf();
482 
483  //M_vectorInterpolantPtr[0]->spy ("interpolantVector");
484  //M_vectorImportedPtr[0]->spy ("importedVector");
485 
486  M_displayer.leaderPrint ( "[vectorDiff.normInf() = ", vectorDiff.normInf(), "]\n" );
487  }
488  if ( scalarImportedPtrSize )
489  {
490  scalarDiff = *M_scalarInterpolantPtr[0];
491  scalarDiff += (-*M_scalarImportedPtr[0]);
492  maxDiff = std::max (scalarDiff.normInf(), maxDiff);
493 
494  //M_scalarInterpolantPtr[0]->spy ("interpolant");
495  //M_scalarImportedPtr[0]->spy ("imported");
496 
497  M_displayer.leaderPrint ( "[scalarDiff.normInf() = ", scalarDiff.normInf(), "]\n" );
498  }
499  passed = passed && (maxDiff < 1.e-4);
500 
501  }
502 
503  return passed;
504 }
505 
506 #endif /* TESTIMPORTEXPORT_HPP_ */
LifeV::FESpace< mesh_Type, LifeV::MapEpetra > feSpace_Type
void start()
Start the timer.
Definition: LifeChrono.hpp:93
std::vector< vectorPtr_Type > M_scalarInterpolantPtr
LifeV::RegionMesh< LifeV::LinearTetra > mesh_Type
void loadData(GetPot &commandLine)
std::shared_ptr< Epetra_Comm > commPtr_Type
std::vector< vectorPtr_Type > M_vectorImportedPtr
std::vector< vectorPtr_Type > M_scalarImportedPtr
std::shared_ptr< mesh_Type > M_meshPtr
bool run(GetPot &commandLine, const std::string &testString="import")
LifeV::Exporter< mesh_Type >::vectorPtr_Type vectorPtr_Type
bool importLoop(const std::shared_ptr< ImporterType > &importerPtr)
feSpacePtr_Type M_vectorFESpacePtr
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
MeshData - class for handling spatial discretization.
Definition: MeshData.hpp:72
commPtr_Type M_commPtr
LifeV::Displayer M_displayer
void buildExporter(std::shared_ptr< ExporterType > &exporterPtr, const std::string &prefix) const
std::vector< vectorPtr_Type > M_vectorInterpolantPtr
std::shared_ptr< feSpace_Type > feSpacePtr_Type
std::vector< std::string > M_scalarName
LifeV::RossEthierSteinmanUnsteadyDec problem_Type
void stop()
Stop the timer.
Definition: LifeChrono.hpp:100
TestImportExport(const commPtr_Type &commPtr)
const std::string follow(const char *Default, unsigned No, const char *Option,...)
Definition: GetPot.hpp:1510
std::vector< std::string > M_vectorName
bool exportLoop(const std::shared_ptr< ExporterType > &exporterPtr)
std::function< LifeV::Real(LifeV::Real const &, LifeV::Real const &, LifeV::Real const &, LifeV::Real const &, LifeV::UInt const &) > function_Type
feSpacePtr_Type M_scalarFESpacePtr
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
LifeV::TimeData M_timeData