LifeV
test_ghosthandler.cpp
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  \file test_ghosthandler.cpp
28  \author A. Cervone <ant.cervone@gmail.com>
29  \date 2011-11-03
30  */
31 
32 /*!
33 todo
34 */
35 
36 // ===================================================
37 //! Includes
38 // ===================================================
39 
40 #include <lifev/core/LifeV.hpp>
41 #include <lifev/core/util/LifeChrono.hpp>
42 #include <lifev/core/array/GhostHandler.hpp>
43 #include <lifev/core/array/VectorEpetra.hpp>
44 #include <lifev/core/mesh/MeshData.hpp>
45 #include <lifev/core/mesh/MeshPartitioner.hpp>
46 #include <lifev/core/mesh/NeighborMarker.hpp>
47 #include <lifev/core/filter/GetPot.hpp>
48 #include <lifev/core/fem/FESpace.hpp>
49 
50 #include <lifev/core/filter/Exporter.hpp>
51 #ifdef HAVE_HDF5
52 #include <lifev/core/filter/ExporterHDF5.hpp>
53 #endif
54 #include <lifev/core/filter/ExporterEmpty.hpp>
55 #include <lifev/core/filter/ExporterEnsight.hpp>
56 
57 // ===================================================
58 //! Namespaces & define
59 // ===================================================
60 
61 using namespace LifeV;
62 
63 int main ( int argc, char* argv[] )
64 {
65 
66 #ifdef HAVE_MPI
67  MPI_Init (&argc, &argv);
68  std::cout << "MPI Initialization" << std::endl;
69 #endif
70 
71  // this brace is important to destroy the Epetra_Comm object before calling MPI_Finalize
72  {
73 
75  typedef FESpace< mesh_Type, MapEpetra > feSpace_Type;
76  typedef std::shared_ptr< feSpace_Type > feSpacePtr_Type;
77 
78  LifeChrono chronoTotal;
79  LifeChrono chronoMesh;
80  LifeChrono chronoGhost;
81 
82  // Start chronoTotal for measure the total time for the computation
83  chronoTotal.start();
84 
85  GetPot command_line (argc, argv);
86  const std::string data_file_name = command_line.follow ("data_ghosthandler", 2, "-f", "--file");
87  GetPot dataFile ( data_file_name );
88 
89 #ifdef EPETRA_MPI
90  std::cout << "Epetra Initialization" << std::endl;
91  std::shared_ptr<Epetra_Comm> comm ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
92 #else
93  std::shared_ptr<Epetra_Comm> comm ( new Epetra_SerialComm() );
94 #endif
95 
96  // Create the leader process, i.e. the process with MyPID equal to zero
97  bool isLeader = ( comm->MyPID() == 0 );
98 
99 #ifdef HAVE_LIFEV_DEBUG
100  // Create a stream that is different for each process
101  std::ofstream fileOut ( ( "gh." + std::to_string ( comm->MyPID() ) + ".out" ).c_str() );
102 #else
103  // discard file output in opt mode
104  std::ofstream fileOut ( "/dev/null" );
105 #endif
106 
107  if ( isLeader )
108  {
109  std::cout << "GhostHendler test" << std::endl;
110  }
111 
112  // Start chronoMesh for measure the total time for the creation of the local meshes
113  chronoMesh.start();
114 
115  // Create the mesh file handler
116  MeshData meshData;
117 
118  // Set up the mesh file
119  meshData.setup ( dataFile, "space_discretization" );
120 
121  // Create the mesh
122  std::shared_ptr<mesh_Type> fullMeshPtr ( new mesh_Type ( comm ) );
123 
124  // Set up the mesh
125  readMesh ( *fullMeshPtr, meshData );
126 
127  // Partition the mesh using ParMetis
128  std::shared_ptr<mesh_Type> meshPtr ( new mesh_Type ( comm ) );
129  {
130  MeshPartitioner< mesh_Type > meshPart ( fullMeshPtr, comm );
131  meshPtr = meshPart.meshPartition();
132  }
133 
134  // Stop chronoReadAndPartitionMesh
135  chronoMesh.stop();
136 
137  // The leader process print chronoReadAndPartitionMesh
138  if ( isLeader )
139  {
140  std::cout << " C- Time for mesh " << chronoMesh.diff() << std::endl;
141  }
142 
143  // Start chronoGhost for measure the total time for GhostHandler routines
144  chronoGhost.start();
145 
146  feSpacePtr_Type feSpaceP1 ( new feSpace_Type ( meshPtr,
147  feTriaP1,
148  quadRuleTria4pt,
149  quadRuleSeg2pt,
150  1,
151  comm ) );
152 
153  fileOut << "=================== P1" << std::endl;
154  fileOut << "9---8---7---6---5" << std::endl;
155  fileOut << "| /| /| /| /|" << std::endl;
156  fileOut << "| / | / | / | / |" << std::endl;
157  fileOut << "|/ |/ |/ |/ |" << std::endl;
158  fileOut << "0---1---2---3---4" << std::endl;
159 
160  GhostHandler<mesh_Type> ghostP1 ( fullMeshPtr, meshPtr, feSpaceP1->mapPtr(), comm );
161 
162  ghostP1.setUpNeighbors();
163 
164  MapEpetra mapP1 ( feSpaceP1->map() );
165  MapEpetra mapP1Overlap ( ghostP1.ghostMapOnPoints ( dataFile ( "ghost/overlap", 2 ) ) );
166 
167  fileOut << "=================== mapP1 Unique" << std::endl;
168  fileOut << "9---8---7---+---+ +---+---+---6---5" << std::endl;
169  fileOut << "| /| /| /| /| | /| /| /| /|" << std::endl;
170  fileOut << "| / | / | / | / | | / | / | / | / |" << std::endl;
171  fileOut << "|/ |/ |/ |/ | |/ |/ |/ |/ |" << std::endl;
172  fileOut << "0---1---2---+---+ +---+---+---3---4" << std::endl;
173  fileOut << *mapP1.map ( Unique );
174 
175  fileOut << "=================== mapP1 Repeated" << std::endl;
176  fileOut << "9---8---7---+---+ +---+---7---6---5" << std::endl;
177  fileOut << "| /| /| /| /| | /| /| /| /|" << std::endl;
178  fileOut << "| / | / | / | / | | / | / | / | / |" << std::endl;
179  fileOut << "|/ |/ |/ |/ | |/ |/ |/ |/ |" << std::endl;
180  fileOut << "0---1---2---+---+ +---+---2---3---4" << std::endl;
181  fileOut << *mapP1.map ( Repeated );
182 
183  fileOut << "=================== mapP1 Repeated overlap 2" << std::endl;
184  fileOut << "9---8---7---6---5 9---8---7---6---5" << std::endl;
185  fileOut << "| /| /| /| /| | /| /| /| /|" << std::endl;
186  fileOut << "| / | / | / | / | | / | / | / | / |" << std::endl;
187  fileOut << "|/ |/ |/ |/ | |/ |/ |/ |/ |" << std::endl;
188  fileOut << "0---1---2---3---4 0---1---2---3---4" << std::endl;
189  fileOut << *mapP1Overlap.map ( Repeated );
190 
191 #ifdef HAVE_HDF5
192 
193  ghostP1.exportToHDF5();
194 
195  ghostP1.importFromHDF5();
196 
197 #endif // HAVE_HDF5
198 
199  ghostP1.clean();
200 
201  std::shared_ptr<VectorEpetra> vP1 ( new VectorEpetra ( mapP1Overlap, Unique ) );
202 
203  // get all elements from the repeated map
204  Int* pointer ( mapP1Overlap.map ( Repeated )->MyGlobalElements() );
205  for ( Int ii = 0; ii < mapP1Overlap.map ( Repeated )->NumMyElements(); ++ii, ++pointer )
206  {
207  vP1->sumIntoGlobalValues ( *pointer, 1 );
208  }
209 
210  vP1->globalAssemble();
211 
212  // check that the overlapping map has all the points in the mesh
213  if ( mapP1Overlap.map ( Repeated )->NumMyElements() != 10 )
214  {
215  return 1;
216  }
217 
218  feSpacePtr_Type feSpaceP0 ( new feSpace_Type ( meshPtr,
219  feTriaP0,
220  quadRuleTria1pt,
221  quadRuleSeg1pt,
222  1,
223  comm ) );
224 
225  fileOut << "=================== P0" << std::endl;
226  fileOut << "+---+---+---+---+" << std::endl;
227  fileOut << "|1 /|3 /|5 /|7 /|" << std::endl;
228  fileOut << "| / | / | / | / |" << std::endl;
229  fileOut << "|/ 0|/ 2|/ 4|/ 6|" << std::endl;
230  fileOut << "+---+---+---+---+" << std::endl;
231 
232  GhostHandler<mesh_Type> ghostP0 ( fullMeshPtr, meshPtr, feSpaceP0->mapPtr(), comm );
233 
234  ghostP0.setUpNeighbors();
235 
236  MapEpetra mapP0 ( feSpaceP0->map() );
237  MapEpetra mapP0P0 ( ghostP0.ghostMapOnElementsFV() );
238  MapEpetra mapP0P1 ( ghostP0.ghostMapOnElementsFE ( dataFile ( "ghost/overlap", 2 ) ) );
239 
240  fileOut << "=================== mapP0 Unique" << std::endl;
241  fileOut << "+---+---+---+---+ +---+---+---+---+" << std::endl;
242  fileOut << "|1 /|3 /| /| /| | /| /|5 /|7 /|" << std::endl;
243  fileOut << "| / | / | / | / | | / | / | / | / |" << std::endl;
244  fileOut << "|/ 0|/ 2|/ |/ | |/ |/ |/ 4|/ 6|" << std::endl;
245  fileOut << "+---+---+---+---+ +---+---+---+---+" << std::endl;
246  fileOut << *mapP0.map ( Unique );
247 
248  fileOut << "=================== mapP0 Repeated" << std::endl;
249  fileOut << "+---+---+---+---+ +---+---+---+---+" << std::endl;
250  fileOut << "|1 /|3 /| /| /| | /| /|5 /|7 /|" << std::endl;
251  fileOut << "| / | / | / | / | | / | / | / | / |" << std::endl;
252  fileOut << "|/ 0|/ 2|/ |/ | |/ |/ |/ 4|/ 6|" << std::endl;
253  fileOut << "+---+---+---+---+ +---+---+---+---+" << std::endl;
254  fileOut << *mapP0.map ( Repeated );
255 
256  fileOut << "=================== mapP0 Repeated face neighbors" << std::endl;
257  fileOut << "+---+---+---+---+ +---+---+---+---+" << std::endl;
258  fileOut << "|1 /|3 /|5 /| /| | /| /|5 /|7 /|" << std::endl;
259  fileOut << "| / | / | / | / | | / | / | / | / |" << std::endl;
260  fileOut << "|/ 0|/ 2|/ |/ | |/ |/ 2|/ 4|/ 6|" << std::endl;
261  fileOut << "+---+---+---+---+ +---+---+---+---+" << std::endl;
262  fileOut << *mapP0P0.map ( Repeated );
263 
264  fileOut << "=================== mapP0 Repeated point neighbors overlap 2" << std::endl;
265  fileOut << "+---+---+---+---+ +---+---+---+---+" << std::endl;
266  fileOut << "|1 /|3 /|5 /|7 /| |1 /|3 /|5 /|7 /|" << std::endl;
267  fileOut << "| / | / | / | / | | / | / | / | / |" << std::endl;
268  fileOut << "|/ 0|/ 2|/ 4|/ 6| |/ 0|/ 2|/ 4|/ 6|" << std::endl;
269  fileOut << "+---+---+---+---+ +---+---+---+---+" << std::endl;
270  fileOut << *mapP0P1.map ( Repeated );
271 
272  ghostP0.showMe ( true, fileOut );
273 
274  ghostP0.clean();
275 
276  std::shared_ptr<VectorEpetra> vP0 ( new VectorEpetra ( mapP0P0, Unique ) );
277 
278  // get all elements from the repeated map
279  pointer = mapP0P1.map ( Repeated )->MyGlobalElements();
280  if ( isLeader )
281  for ( Int ii = 0; ii < mapP0P1.map ( Repeated )->NumMyElements(); ++ii, ++pointer )
282  {
283  vP0->sumIntoGlobalValues ( *pointer, 1 );
284  }
285 
286  vP0->globalAssemble();
287 
288  fileOut << "=================== vector" << std::endl;
289  fileOut << vP0->epetraVector();
290 
291  // check that the overlapping map has all the elements in the mesh
292  if ( mapP0P1.map ( Repeated )->NumMyElements() != 8 )
293  {
294  return 1;
295  }
296 
297  // Stop chronoGhost
298  chronoGhost.stop();
299 
300  // The leader process print chronoGhost
301  if ( isLeader )
302  {
303  std::cout << " C- Time for ghost " << chronoGhost.diff() << std::endl;
304  }
305 
306  std::shared_ptr< Exporter< mesh_Type > > exporter;
307 
308  // Type of the exporter
309  std::string const exporterType = dataFile ( "exporter/type", "ensight" );
310 
311  // Choose the exporter
312 #ifdef HAVE_HDF5
313  if ( exporterType.compare ( "hdf5" ) == 0 )
314  {
315  exporter.reset ( new ExporterHDF5< mesh_Type > ( dataFile, dataFile ( "exporter/file_name", "GH" ) ) );
316  }
317  else
318 #endif
319  {
320  if ( exporterType.compare ("none") == 0 )
321  {
322  exporter.reset ( new ExporterEmpty< mesh_Type > ( dataFile, dataFile ( "exporter/file_name", "GH" ) ) );
323  }
324  else
325  {
326  exporter.reset ( new ExporterEnsight< mesh_Type > ( dataFile, dataFile ( "exporter/file_name", "GH" ) ) );
327  }
328  }
329 
330  // Set directory where to save the solution
331  exporter->setPostDir ( dataFile ( "exporter/folder", "./" ) );
332  exporter->setMeshProcId ( meshPtr, comm->MyPID() );
333 
334  // Export the partitioning
335  exporter->exportPID ( meshPtr, comm );
336 
337  // Add the solution to the exporter
338  exporter->addVariable ( ExporterData<mesh_Type>::ScalarField,
339  "MapP1", feSpaceP1,
340  vP1,
341  static_cast<UInt> ( 0 ),
342  ExporterData<mesh_Type>::SteadyRegime,
343  ExporterData<mesh_Type>::Node );
344 
345  // Add the solution to the exporter
346  exporter->addVariable ( ExporterData<mesh_Type>::ScalarField,
347  "MapP0", feSpaceP0,
348  vP0,
349  static_cast<UInt> ( 0 ),
350  ExporterData<mesh_Type>::SteadyRegime,
351  ExporterData<mesh_Type>::Cell );
352 
353  // Save the initial solution into the exporter
354  exporter->postProcess ( 0 );
355 
356  // Stop chronoTotal
357  chronoTotal.stop();
358 
359  // The leader process print chronoTotal
360  if ( isLeader )
361  {
362  std::cout << " C- Time total " << chronoTotal.diff() << std::endl;
363  }
364 
365  }
366 
367 #ifdef HAVE_MPI
368  MPI_Finalize();
369  std::cout << "MPI Finalization" << std::endl;
370 #endif
371 
372  return 0;
373 
374 }
void start()
Start the timer.
Definition: LifeChrono.hpp:93
FESpace - Short description here please!
Definition: FESpace.hpp:78
A Geometric Shape.
GetPot(const int argc_, char **argv_, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:507
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
NeighborMarkerCommon< MarkerIDStandardPolicy > neighborMarkerCommon_Type
The NeighborMarkerCommon: uses all defaults except for Points.
Class for 3D, 2D and 1D Mesh.
Definition: RegionMesh.hpp:87
std::shared_ptr< std::vector< Int > > M_isOnProc
MeshData - class for handling spatial discretization.
Definition: MeshData.hpp:72
const std::string operator()(const char *VarName, const char *Default) const
Definition: GetPot.hpp:2045
void stop()
Stop the timer.
Definition: LifeChrono.hpp:100
GetPot(const STRING_VECTOR &FileNameList)
Definition: GetPot.hpp:645
const std::string follow(const char *Default, unsigned No, const char *Option,...)
Definition: GetPot.hpp:1510
int main(int argc, char **argv)
void importFromHDF5(std::string const &fileName="ghostmap")
Import neighbor lists to an hdf5 file.