LifeV
mesh/MeshPartitionerOfflineFSI.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 Offline mesh partitioning for FSI
30 
31  @date 24-08-2010
32  @author Radu Popescu <radu.popescu@epfl.ch>
33 
34  @maintainer Radu Popescu <radu.popescu@epfl.ch>
35 */
36 
37 #ifndef MESH_PARTITIONER_OFFLINE_FSI_H
38 #define MESH_PARTITIONER_OFFLINE_FSI_H 1
39 
40 
41 #include <boost/scoped_ptr.hpp>
42 #include <boost/shared_ptr.hpp>
43 
44 
45 #include <lifev/core/fem/FESpace.hpp>
46 #include <lifev/core/fem/DOFInterface3Dto3D.hpp>
47 #include <lifev/core/mesh/Marker.hpp>
48 
49 namespace LifeV
50 {
51 
52 //! MeshPartitionerOfflineFSI - Offline mesh partitioning for FSI
53 /*!
54  @author Radu Popescu
55 
56  This class handles the offline partitioning for FSI simulations.
57  It cuts the two unpartitioned meshes for the fluid and the solid
58  into a set number of partitions for each. It also generates the
59  map of the degrees of freedom at the interface between the two
60  materials.
61 
62  Usage: create object
63  call setup(...) method
64  call execute() method
65 */
66 template<typename MeshType>
68 {
69 public:
70 
71  //! @name Public Types
72  //@{
73  typedef MeshType mesh_Type;
74  typedef MeshType uncutMesh_Type;
78 
81 
84 
89 
90  typedef DOFInterface3Dto3D interface_Type;
93  // The vector contains pointers to each fluid partition's interface with
94  // the solid. The vector must be wrapped in a pointer so it can be stored
95  // inside HDF5Filter3DMesh when doing output.
97 
98  typedef MeshPartitioner<uncutMesh_Type> meshCutter_Type;
100 
101  //@}
102 
103  //! @name Constructor & Destructor
104  //@{
105 
106  //! Empty Constructor
108 
109  //! Destructor
111  //@}
112 
113  //! @name Methods
114  //@{
115 
116  //! Setup the data members of the class after construction
117  /*!
118  This methods is called to configure the MeshPartitionerOfflineFSI object
119  after it is constructed.
120  @param uncutFluidMesh const std::shared_ptr to the unpartitioned
121  fluid mesh
122  @param uncutSolidMesh const std::shared_ptr to the unpartitioned
123  solid mesh
124  @param fluidPartitionNumber Int
125  @param solidPartitionNumber Int
126  @param velocityOrder std::string
127  @param displacementOrder std::string
128  @param fluidInterfaceFlag LifeV::MarkerIDStandardPolicy::markerID_Type (Int)
129  @param solidInterfaceFlag LifeV::MarkerIDStandardPolicy::markerID_Type (Int)
130  @param interfaceTolerance Real
131  @param fluidInterfaceVertexFlag Int
132  @param comm std::shared_ptr to a Epetra_Comm object
133  */
134  void setup (const uncutMeshPtr_Type& uncutFluidMesh,
135  const uncutMeshPtr_Type& uncutSolidMesh,
136  const Int& fluidPartitionNumber,
137  const Int& solidPartitionNumber,
138  const std::string& velocityOrder,
139  const std::string& displacementOrder,
140  const markerID_Type& fluidInterfaceFlag,
141  const markerID_Type& solidInterfaceFlag,
142  const Real& interfaceTolerance,
143  const Int& fluidInterfaceVertexFlag,
144  const Int& solidInterfaceVertexFlag,
145  const commPtr_Type& comm);
146 
147  //! Execute the partitioning and create the interface map
148  /*!
149  This is a wrapper method that calls the following private methods:
150  runTheCutters(), createSpaces(), mapTheInterface()
151  */
152  void execute();
153 
154  //! Display general information about the content of the class
155  /*!
156  Displays the current value of the data members.
157  @param output std::ostream - stream used for output
158  */
159  void showMe (std::ostream& output = std::cout) const;
160 
161  //@}
162 
163  //! @name Get Methods
164  //@{
166  {
167  return M_fluidInterfaceFlag;
168  }
170  {
171  return M_solidInterfaceFlag;
172  }
173  const graphPtr_Type& fluidGraph() const
174  {
175  return M_fluidMeshCutter->elementDomains();
176  }
177  const graphPtr_Type& solidGraph() const
178  {
179  return M_solidMeshCutter->elementDomains();
180  }
182  {
183  return M_fluidMeshCutter->meshPartitions();
184  }
185 
187  {
188  return M_solidMeshCutter->meshPartitions();
189  }
190  /*
191  const interfaceVectorPtr_Type& dofFluidToStructure()
192  {
193  return M_dofFluidToStructure;
194  }
195  */
197  {
199  }
200  /*
201  const interfaceVectorPtr_Type& dofStructureToSolid()
202  {
203  return M_dofStructureToSolid;
204  }
205 
206  const interfaceVectorPtr_Type& dofStructureToFluid()
207  {
208  return M_dofStructureToFluid;
209  }
210 
211  const interfaceVectorPtr_Type& dofHarmonicExtensionToFluid()
212  {
213  return M_dofHarmonicExtensionToFluid;
214  }
215  */
216  //@}
217 
218 private:
219  // !!! ATTENTION !!!
220  // Copy constructor and assignment operator are disabled
221  // because there is no need for such operations in this case.
222  // As a safety measure, there are no definitions for these
223  // functions, so any attempts to use them result in link errors.
226 
227  //! @name Private Methods
228  //@{
229 
230  //! Create the MeshPartitioner objects for fluid and solid
231  /*!
232  Allocate the MeshPartitioner objects for the fluid and solid and
233  execute the partitioning of the two materials
234  */
235  void runTheCutters();
236 
237  //! Create the finite element spaces
238  /*!
239  This method creates the finite element spaces necessary for
240  the offline partitioning: one FE space for the uncut solid
241  mesh and one FE space for each of the fluid mesh partitions.
242  */
243  void createSpaces();
244 
245  //! Create the interface map between fluid and solid
246  /*!
247  This method creates the interface map between the two
248  regions. One interface map is created between each of the
249  fluid partitions and the solid uncut mesh
250  */
251  void mapTheInterface();
252 
253  //@}
254 
256 
259 
261 
264 
267 
268  std::string M_velocityOrder;
269  std::string M_displacementOrder;
270 
273 
276 
279 
285 };
286 
287 ///////////////////////////
288 // IMPLEMENTATION //
289 ///////////////////////////
290 
291 // ===============================
292 // Pubic methods
293 // ===============================
294 
295 template<typename MeshType>
296 void MeshPartitionerOfflineFSI<MeshType>::setup (const uncutMeshPtr_Type& uncutFluidMesh,
297  const uncutMeshPtr_Type& uncutSolidMesh,
298  const Int& fluidPartitionNumber,
299  const Int& solidPartitionNumber,
300  const std::string& velocityOrder,
301  const std::string& displacementOrder,
302  const markerID_Type& fluidInterfaceFlag,
303  const markerID_Type& solidInterfaceFlag,
304  const Real& interfaceTolerance,
305  const Int& fluidInterfaceVertexFlag,
306  const Int& solidInterfaceVertexFlag,
307  const commPtr_Type& comm)
308 {
309  M_comm = comm;
310 
311  // Make sure we are running in serial
312  if (M_comm->NumProc() == 1)
313  {
314  M_fluidPartitionNumber = fluidPartitionNumber;
315  M_solidPartitionNumber = solidPartitionNumber;
316 
317  M_velocityOrder = velocityOrder;
318  M_displacementOrder = displacementOrder;
319 
320  M_fluidInterfaceFlag = fluidInterfaceFlag;
321  M_solidInterfaceFlag = solidInterfaceFlag;
322  M_interfaceTolerance = interfaceTolerance;
323 
324  if (fluidInterfaceVertexFlag > 0)
325  {
326  M_fluidInterfaceVertexFlag.reset (new const Int (fluidInterfaceVertexFlag) );
327  }
328  if (solidInterfaceVertexFlag > 0)
329  {
330  M_solidInterfaceVertexFlag.reset (new const Int (solidInterfaceVertexFlag) );
331  }
332 
333  M_uncutFluidMesh = uncutFluidMesh;
334  M_uncutSolidMesh = uncutSolidMesh;
335 
336  // Allocate and configure the mesh cutters
337  M_fluidMeshCutter.reset (new meshCutter_Type);
338  M_fluidMeshCutter->setup (M_fluidPartitionNumber, M_comm);
339  M_fluidMeshCutter->attachUnpartitionedMesh (M_uncutFluidMesh);
340 
341  M_solidMeshCutter.reset (new meshCutter_Type);
342  M_solidMeshCutter->setup (M_solidPartitionNumber, M_comm);
343  M_solidMeshCutter->attachUnpartitionedMesh (M_uncutSolidMesh);
344  }
345  else
346  {
347  ERROR_MSG ("Offline FSI partitioning is designed to run"
348  " with a single process.");
349  }
350 }
351 
352 template<typename MeshType>
354 {
355  // Cut the meshes ...
357 
358  // ... create the appropriate FE spaces ...
360 
361  // ... then create the F-S interface
363 }
364 
365 template<typename MeshType>
366 void MeshPartitionerOfflineFSI<MeshType>::showMe (std::ostream& output) const
367 {
368  output << std::endl;
369  output << "=======================================" << std::endl;
370  output << "Internal state of MeshPartitionerOfflineFSI" << std::endl;
371  output << std::endl;
372 
373  output << "Number of fluid partitions: " << M_fluidPartitionNumber
374  << std::endl;
375  output << "Number of solid partitions: " << M_solidPartitionNumber
376  << std::endl;
377  output << "Velocity order: " << M_velocityOrder
378  << std::endl;
379  output << "Displacement order: " << M_displacementOrder
380  << std::endl;
381  output << "Fluid interface flag: " << M_fluidInterfaceFlag
382  << std::endl;
383  output << "Solid interface flag: " << M_solidInterfaceFlag
384  << std::endl;
385  output << "Interface tolerance: " << M_interfaceTolerance
386  << std::endl;
387  if (M_fluidInterfaceVertexFlag.get() )
388  {
389  output << "Fluid interface vertex flag: " << *M_fluidInterfaceVertexFlag
390  << std::endl;
391  }
392  if (M_solidInterfaceVertexFlag.get() )
393  {
394  output << "Solid interface vertex flag: " << *M_solidInterfaceVertexFlag
395  << std::endl;
396  }
397  output << "Fluid mesh is stored at: " << M_uncutFluidMesh.get()
398  << std::endl;
399  output << "Solid mesh is stored at: " << M_uncutSolidMesh.get()
400  << std::endl;
401  output << "=======================================" << std::endl;
402  output << std::endl;
403 }
404 
405 // ===============================
406 // Private methods
407 // ===============================
408 
409 template<typename MeshType>
411 {
412  std::cout << "\nPartitioning fluid mesh...\n" << std::endl;
413  M_fluidMeshCutter->doPartitionGraph();
414  M_fluidMeshCutter->doPartitionMesh();
415  M_fluidMeshCutter->releaseUnpartitionedMesh();
416  std::cout << "\nPartitioning solid mesh...\n" << std::endl;
417  M_solidMeshCutter->doPartitionGraph();
418  M_solidMeshCutter->doPartitionMesh();
419  M_solidMeshCutter->releaseUnpartitionedMesh();
420  std::cout << std::endl;
421 }
422 
423 template<typename MeshType>
425 {
426  // Set the appropriate reference elements and quad rules
427  const ReferenceFE* refFE_vel (0);
428  const QuadratureRule* qR_vel (0);
429  const QuadratureRule* bdQr_vel (0);
430 
431  const ReferenceFE* refFE_disp (0);
432  const QuadratureRule* qR_disp (0);
433  const QuadratureRule* bdQr_disp (0);
434 
435  if ( M_velocityOrder.compare ("P2") == 0 )
436  {
437  refFE_vel = &feTetraP2;
438  qR_vel = &quadRuleTetra15pt;
439  bdQr_vel = &quadRuleTria3pt;
440  }
441  else
442  {
443  if ( M_velocityOrder.compare ("P1") == 0 )
444  {
445  refFE_vel = &feTetraP1;
446  qR_vel = &quadRuleTetra4pt;
447  bdQr_vel = &quadRuleTria3pt;
448  }
449  else
450  {
451  if ( M_velocityOrder.compare ("P1Bubble") == 0 )
452  {
453  refFE_vel = &feTetraP1bubble;
454  qR_vel = &quadRuleTetra64pt;
455  bdQr_vel = &quadRuleTria3pt;
456  }
457  else
458  {
459  ERROR_MSG (M_velocityOrder + " velocity FE not implemented yet.");
460  }
461  }
462  }
463 
464  if ( M_displacementOrder.compare ("P2") == 0 )
465  {
466  refFE_disp = &feTetraP2;
467  qR_disp = &quadRuleTetra15pt;
468  bdQr_disp = &quadRuleTria3pt;
469  }
470  else
471  {
472  if ( M_displacementOrder.compare ("P1") == 0 )
473  {
474  refFE_disp = &feTetraP1;
475  qR_disp = &quadRuleTetra4pt;
476  bdQr_disp = &quadRuleTria3pt;
477  }
478  else
479  {
480  ERROR_MSG (M_displacementOrder + " structure FE not implemented yet.");
481  }
482  }
483 
484  // Create finite element spaces for velocity and displacement
485  std::cout << "Creating velocity finite element space... ";
486  M_velocityFESpaces.reset (new feSpaceVector_Type);
487  M_velocityFESpaces->resize (M_fluidPartitionNumber);
488  for (Int i = 0; i < M_fluidPartitionNumber; ++i)
489  {
490  (*M_velocityFESpaces) [i].reset (new feSpace_Type (M_fluidMeshCutter->getPartition (i),
491  *refFE_vel,
492  *qR_vel,
493  *bdQr_vel,
494  3,
495  M_comm) );
496  }
497  std::cout << "done." << std::endl;
498  std::cout << "Creating displacement finite element space... ";
499  M_displacementFESpace.reset (new feSpace_Type (M_uncutSolidMesh,
500  *refFE_disp,
501  *qR_disp,
502  *bdQr_disp,
503  3,
504  M_comm) );
505  std::cout << "done." << std::endl;
506 }
507 
508 template<typename MeshType>
510 {
511  // Create the DOFInterface3Dto3D objects for each fluid partition
512  std::cout << std::endl;
513  std::cout << "Creating the DOF interfaces..." << std::endl;
514  std::cout << std::endl;
515  std::cout << "Fluid interface flag is: " << M_fluidInterfaceFlag << std::endl;
516  std::cout << "Solid interface flag is: " << M_solidInterfaceFlag << std::endl;
517  std::cout << std::endl;
518 
519  M_dofStructureToHarmonicExtension.reset (new interfaceVector_Type);
520  M_dofStructureToHarmonicExtension->resize (M_fluidPartitionNumber);
521 
522  for (Int i = 0; i < M_fluidPartitionNumber; ++i)
523  {
524  interfacePtr_Type& ifPtr = (*M_dofStructureToHarmonicExtension) [i];
525  feSpacePtr_Type& velSpacePtr = (*M_velocityFESpaces) [i];
526  ifPtr.reset (new interface_Type);
527  ifPtr->setup (velSpacePtr->refFE(),
528  velSpacePtr->dof(),
529  M_displacementFESpace->refFE(),
530  M_displacementFESpace->dof() );
531  ifPtr->update (* (velSpacePtr->mesh() ), M_fluidInterfaceFlag,
532  * (M_displacementFESpace->mesh() ), M_solidInterfaceFlag,
533  M_interfaceTolerance, M_fluidInterfaceVertexFlag.get() );
534  }
535  std::cout << "dofStructureToHarmonicExtension done." << std::endl;
536 
537  std::cout << "All done." << std::endl << std::endl;
538 }
539 
540 } // Namespace LifeV
541 
542 #endif // MESH_PARTITIONER_OFFLINE_FSI_H
const uncutMeshVectorPtr_Type & solidPartitions() const
const QuadratureRule quadRuleTetra64pt(pt_tetra_64pt, 6, "Quadrature rule 64 points on a tetraedra", TETRA, 64, 7)
std::shared_ptr< meshCutter_Type > meshCutterPtr_Type
void showMe(std::ostream &output=std::cout) const
Display general information about the content of the class.
const QuadratureRule quadRuleTetra15pt(pt_tetra_15pt, 5, "Quadrature rule 15 points on a tetraedra", TETRA, 15, 5)
const QuadratureRule quadRuleTetra4pt(pt_tetra_4pt, 2, "Quadrature rule 4 points on a tetraedra", TETRA, 4, 2)
void execute()
Execute the partitioning and create the interface map.
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
MeshPartitionerOfflineFSI & operator=(const MeshPartitionerOfflineFSI &)
ID markerID_Type
markerID_Type is the type used to store the geometric entity marker IDs
Definition: Marker.hpp:81
void updateInverseJacobian(const UInt &iQuadPt)
std::shared_ptr< interfaceVector_Type > interfaceVectorPtr_Type
const uncutMeshVectorPtr_Type & fluidPartitions() const
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
void runTheCutters()
Create the MeshPartitioner objects for fluid and solid.
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
std::shared_ptr< feSpaceVector_Type > feSpaceVectorPtr_Type
void mapTheInterface()
Create the interface map between fluid and solid.
FESpace< uncutMesh_Type, MapEpetra > feSpace_Type
double Real
Generic real data.
Definition: LifeV.hpp:175
MeshPartitionerOfflineFSI - Offline mesh partitioning for FSI.
const QuadratureRule quadRuleTria3pt(pt_tria_3pt, 2, "Quadrature rule 3 points on a triangle", TRIANGLE, 3, 2)
The class for a reference Lagrangian finite element.
const interfaceVectorPtr_Type & dofStructureToHarmonicExtension() const
void setup(const uncutMeshPtr_Type &uncutFluidMesh, const uncutMeshPtr_Type &uncutSolidMesh, const Int &fluidPartitionNumber, const Int &solidPartitionNumber, const std::string &velocityOrder, const std::string &displacementOrder, const markerID_Type &fluidInterfaceFlag, const markerID_Type &solidInterfaceFlag, const Real &interfaceTolerance, const Int &fluidInterfaceVertexFlag, const Int &solidInterfaceVertexFlag, const commPtr_Type &comm)
Setup the data members of the class after construction.
std::shared_ptr< uncutMeshVector_Type > uncutMeshVectorPtr_Type
void createSpaces()
Create the finite element spaces.
QuadratureRule - The basis class for storing and accessing quadrature rules.
MeshPartitionerOfflineFSI(const MeshPartitionerOfflineFSI &)