LifeV
blocks/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 #include <lifev/core/mesh/MeshPartitioner.hpp>
49 
50 namespace LifeV
51 {
52 
53 //! MeshPartitionerOfflineFSI - Offline mesh partitioning for FSI
54 /*!
55  @author Radu Popescu
56 
57  This class handles the offline partitioning for FSI simulations.
58  It cuts the two unpartitioned meshes for the fluid and the solid
59  into a set number of partitions for each. It also generates the
60  map of the degrees of freedom at the interface between the two
61  materials.
62 
63  Usage: create object
64  call setup(...) method
65  call execute() method
66 */
67 template<typename MeshType>
69 {
70 public:
71 
72  //! @name Public Types
73  //@{
74  typedef MeshType mesh_Type;
75  typedef MeshType uncutMesh_Type;
79 
82 
85 
90 
91  typedef DOFInterface3Dto3D interface_Type;
94  // The vector contains pointers to each fluid partition's interface with
95  // the solid. The vector must be wrapped in a pointer so it can be stored
96  // inside HDF5Filter3DMesh when doing output.
98 
99  typedef MeshPartitioner<uncutMesh_Type> meshCutter_Type;
101 
102  //@}
103 
104  //! @name Constructor & Destructor
105  //@{
106 
107  //! Constructor
108  /*!
109  Constructor which configures the MeshPartitionerOfflineFSI object
110  @param uncutFluidMesh const std::shared_ptr to the unpartitioned
111  fluid mesh
112  @param uncutSolidMesh const std::shared_ptr to the unpartitioned
113  solid mesh
114  @param fluidPartitionNumber Int
115  @param solidPartitionNumber Int
116  @param velocityOrder std::string
117  @param displacementOrder std::string
118  @param fluidInterfaceFlag LifeV::MarkerIDStandardPolicy::markerID_Type (Int)
119  @param solidInterfaceFlag LifeV::MarkerIDStandardPolicy::markerID_Type (Int)
120  @param interfaceTolerance Real
121  @param fluidInterfaceVertexFlag Int
122  @param comm std::shared_ptr to a Epetra_Comm object
123  */
124  MeshPartitionerOfflineFSI (const uncutMeshPtr_Type& uncutFluidMesh,
125  const uncutMeshPtr_Type& uncutSolidMesh,
126  const Int fluidPartitionNumber,
127  const Int solidPartitionNumber,
128  const std::string velocityOrder,
129  const std::string displacementOrder,
130  const markerID_Type fluidInterfaceFlag,
131  const markerID_Type solidInterfaceFlag,
132  const Real interfaceTolerance,
133  const Int fluidInterfaceVertexFlag,
134  const Int solidInterfaceVertexFlag,
135  const commPtr_Type& comm);
136 
137  //! Destructor
139  //@}
140 
141  //! @name Methods
142  //@{
143  //! Display general information about the content of the class
144  /*!
145  Displays the current value of the data members.
146  @param output std::ostream - stream used for output
147  */
148  void showMe (std::ostream& output = std::cout) const;
149  //@}
150 
151  //! @name Get Methods
152  //@{
154  {
155  return M_fluidInterfaceFlag;
156  }
158  {
159  return M_solidInterfaceFlag;
160  }
161  const graphPtr_Type& fluidGraph() const
162  {
163  return M_fluidMeshCutter->elementDomains();
164  }
165  const graphPtr_Type& solidGraph() const
166  {
167  return M_solidMeshCutter->elementDomains();
168  }
170  {
171  return M_fluidMeshCutter->meshPartitions();
172  }
173 
175  {
176  return M_solidMeshCutter->meshPartitions();
177  }
178  /*
179  const interfaceVectorPtr_Type& dofFluidToStructure()
180  {
181  return M_dofFluidToStructure;
182  }
183  */
185  {
187  }
188  /*
189  const interfaceVectorPtr_Type& dofStructureToSolid()
190  {
191  return M_dofStructureToSolid;
192  }
193 
194  const interfaceVectorPtr_Type& dofStructureToFluid()
195  {
196  return M_dofStructureToFluid;
197  }
198 
199  const interfaceVectorPtr_Type& dofHarmonicExtensionToFluid()
200  {
201  return M_dofHarmonicExtensionToFluid;
202  }
203  */
204  //@}
205 
206 private:
207  // Copy constructor and assignment operator are disabled
208  // because there is no need for such operations in this case.
209  // As a safety measure, there are no definitions for these
210  // functions, so any attempts to use them result in link errors.
213 
214  //! @name Private Methods
215  //@{
216  //! Create the MeshPartitioner objects for fluid and solid
217  /*!
218  Allocate the MeshPartitioner objects for the fluid and solid and
219  execute the partitioning of the two materials
220  */
221  void runTheCutters();
222 
223  //! Create the finite element spaces
224  /*!
225  This method creates the finite element spaces necessary for
226  the offline partitioning: one FE space for the uncut solid
227  mesh and one FE space for each of the fluid mesh partitions.
228  */
229  void createSpaces();
230 
231  //! Create the interface map between fluid and solid
232  /*!
233  This method creates the interface map between the two
234  regions. One interface map is created between each of the
235  fluid partitions and the solid uncut mesh
236  */
237  void mapTheInterface();
238  //@}
239 
241 
244 
246 
249 
252 
253  std::string M_velocityOrder;
254  std::string M_displacementOrder;
255 
258 
261 
264 
270 };
271 
272 ///////////////////////////
273 // IMPLEMENTATION //
274 ///////////////////////////
275 
276 // ===============================
277 // Pubic methods
278 // ===============================
279 
280 template<typename MeshType>
282  const uncutMeshPtr_Type& uncutFluidMesh,
283  const uncutMeshPtr_Type& uncutSolidMesh,
284  const Int fluidPartitionNumber,
285  const Int solidPartitionNumber,
286  const std::string velocityOrder,
287  const std::string displacementOrder,
288  const markerID_Type fluidInterfaceFlag,
289  const markerID_Type solidInterfaceFlag,
290  const Real interfaceTolerance,
291  const Int fluidInterfaceVertexFlag,
292  const Int solidInterfaceVertexFlag,
293  const commPtr_Type& comm)
294  : M_comm (comm),
295  M_fluidPartitionNumber (fluidPartitionNumber),
296  M_solidPartitionNumber (solidPartitionNumber),
297  M_interfaceTolerance (interfaceTolerance),
298  M_fluidInterfaceFlag (fluidInterfaceFlag),
299  M_solidInterfaceFlag (solidInterfaceFlag),
300  M_fluidInterfaceVertexFlag (fluidInterfaceVertexFlag),
301  M_solidInterfaceVertexFlag (solidInterfaceVertexFlag),
302  M_velocityOrder (velocityOrder),
303  M_displacementOrder (displacementOrder),
304  M_uncutFluidMesh (uncutFluidMesh),
305  M_uncutSolidMesh (uncutSolidMesh)
306 {
307  // Make sure we are running in serial
308  if (M_comm->NumProc() == 1)
309  {
310  // Allocate and configure the mesh cutters
311  M_fluidMeshCutter.reset (new meshCutter_Type);
312  M_fluidMeshCutter->setup (M_fluidPartitionNumber, M_comm);
313  M_fluidMeshCutter->attachUnpartitionedMesh (M_uncutFluidMesh);
314 
315  M_solidMeshCutter.reset (new meshCutter_Type);
316  M_solidMeshCutter->setup (M_solidPartitionNumber, M_comm);
317  M_solidMeshCutter->attachUnpartitionedMesh (M_uncutSolidMesh);
318 
319  // Cut the meshes ...
321 
322  // ... create the appropriate FE spaces ...
324 
325  // ... then create the F-S interface
327  }
328  else
329  {
330  ERROR_MSG ("Offline FSI partitioning is designed to run"
331  " with a single process.");
332  }
333 }
334 
335 template<typename MeshType>
336 void MeshPartitionerOfflineFSI<MeshType>::showMe (std::ostream& output) const
337 {
338  output << std::endl;
339  output << "=======================================" << std::endl;
340  output << "Internal state of MeshPartitionerOfflineFSI" << std::endl;
341  output << std::endl;
342 
343  output << "Number of fluid partitions: " << M_fluidPartitionNumber
344  << std::endl;
345  output << "Number of solid partitions: " << M_solidPartitionNumber
346  << std::endl;
347  output << "Velocity order: " << M_velocityOrder
348  << std::endl;
349  output << "Displacement order: " << M_displacementOrder
350  << std::endl;
351  output << "Fluid interface flag: " << M_fluidInterfaceFlag
352  << std::endl;
353  output << "Solid interface flag: " << M_solidInterfaceFlag
354  << std::endl;
355  output << "Interface tolerance: " << M_interfaceTolerance
356  << std::endl;
358  {
359  output << "Fluid interface vertex flag: " << M_fluidInterfaceVertexFlag
360  << std::endl;
361  }
363  {
364  output << "Solid interface vertex flag: " << M_solidInterfaceVertexFlag
365  << std::endl;
366  }
367  output << "Fluid mesh is stored at: " << M_uncutFluidMesh.get()
368  << std::endl;
369  output << "Solid mesh is stored at: " << M_uncutSolidMesh.get()
370  << std::endl;
371  output << "=======================================" << std::endl;
372  output << std::endl;
373 }
374 
375 // ===============================
376 // Private methods
377 // ===============================
378 
379 template<typename MeshType>
381 {
382  std::cout << "\nPartitioning fluid mesh...\n" << std::endl;
383  M_fluidMeshCutter->doPartitionGraph();
384  M_fluidMeshCutter->fillEntityPID();
385  M_fluidMeshCutter->doPartitionMesh();
386  M_fluidMeshCutter->releaseUnpartitionedMesh();
387  std::cout << "\nPartitioning solid mesh...\n" << std::endl;
388  M_solidMeshCutter->doPartitionGraph();
389  M_solidMeshCutter->fillEntityPID();
390  M_solidMeshCutter->doPartitionMesh();
391  M_solidMeshCutter->releaseUnpartitionedMesh();
392  std::cout << std::endl;
393 }
394 
395 template<typename MeshType>
396 void MeshPartitionerOfflineFSI<MeshType>::createSpaces()
397 {
398  // Set the appropriate reference elements and quad rules
399  const ReferenceFE* refFE_vel (0);
400  const QuadratureRule* qR_vel (0);
401  const QuadratureRule* bdQr_vel (0);
402 
403  const ReferenceFE* refFE_disp (0);
404  const QuadratureRule* qR_disp (0);
405  const QuadratureRule* bdQr_disp (0);
406 
407  if ( M_velocityOrder.compare ("P2") == 0 )
408  {
409  refFE_vel = &feTetraP2;
410  qR_vel = &quadRuleTetra15pt;
411  bdQr_vel = &quadRuleTria3pt;
412  }
413  else
414  {
415  if ( M_velocityOrder.compare ("P1") == 0 )
416  {
417  refFE_vel = &feTetraP1;
418  qR_vel = &quadRuleTetra4pt;
419  bdQr_vel = &quadRuleTria3pt;
420  }
421  else
422  {
423  if ( M_velocityOrder.compare ("P1Bubble") == 0 )
424  {
425  refFE_vel = &feTetraP1bubble;
426  qR_vel = &quadRuleTetra64pt;
427  bdQr_vel = &quadRuleTria3pt;
428  }
429  else
430  {
431  ERROR_MSG (M_velocityOrder + " velocity FE not implemented yet.");
432  }
433  }
434  }
435 
436  if ( M_displacementOrder.compare ("P2") == 0 )
437  {
438  refFE_disp = &feTetraP2;
439  qR_disp = &quadRuleTetra15pt;
440  bdQr_disp = &quadRuleTria3pt;
441  }
442  else
443  {
444  if ( M_displacementOrder.compare ("P1") == 0 )
445  {
446  refFE_disp = &feTetraP1;
447  qR_disp = &quadRuleTetra4pt;
448  bdQr_disp = &quadRuleTria3pt;
449  }
450  else
451  {
452  ERROR_MSG (M_displacementOrder + " structure FE not implemented yet.");
453  }
454  }
455 
456  // Create finite element spaces for velocity and displacement
457  std::cout << "Creating velocity finite element space... ";
458  M_velocityFESpaces.reset (new feSpaceVector_Type);
459  M_velocityFESpaces->resize (M_fluidPartitionNumber);
460  for (Int i = 0; i < M_fluidPartitionNumber; ++i)
461  {
462  (*M_velocityFESpaces) [i].reset (new feSpace_Type (M_fluidMeshCutter->getPartition (i),
463  *refFE_vel,
464  *qR_vel,
465  *bdQr_vel,
466  3,
467  M_comm) );
468  }
469  std::cout << "done." << std::endl;
470  std::cout << "Creating displacement finite element space... ";
471  M_displacementFESpace.reset (new feSpace_Type (M_uncutSolidMesh,
472  *refFE_disp,
473  *qR_disp,
474  *bdQr_disp,
475  3,
476  M_comm) );
477  std::cout << "done." << std::endl;
478 
479  // Printing out number of dofs for the fluid and the velocity
480  feSpace_Type velocity(M_uncutFluidMesh, *refFE_vel, *qR_vel, *bdQr_vel, 3, M_comm);
481  std::cout << "Number of dofs for the fluid velocity: " << velocity.dof().numTotalDof()*3 << std::endl;
482  std::cout << "Number of dofs for the structure displacement: " << M_displacementFESpace->dof().numTotalDof()*3 << std::endl;
483 }
484 
485 template<typename MeshType>
487 {
488  // Create the DOFInterface3Dto3D objects for each fluid partition
489  std::cout << std::endl;
490  std::cout << "Creating the DOF interfaces..." << std::endl;
491  std::cout << std::endl;
492  std::cout << "Fluid interface flag is: " << M_fluidInterfaceFlag << std::endl;
493  std::cout << "Solid interface flag is: " << M_solidInterfaceFlag << std::endl;
494  std::cout << std::endl;
495 
496  M_dofStructureToHarmonicExtension.reset (new interfaceVector_Type);
497  M_dofStructureToHarmonicExtension->resize (M_fluidPartitionNumber);
498 
499  for (Int i = 0; i < M_fluidPartitionNumber; ++i)
500  {
501  interfacePtr_Type& ifPtr = (*M_dofStructureToHarmonicExtension) [i];
502  feSpacePtr_Type& velSpacePtr = (*M_velocityFESpaces) [i];
503  ifPtr.reset (new interface_Type);
504  ifPtr->setup (velSpacePtr->refFE(),
505  velSpacePtr->dof(),
506  M_displacementFESpace->refFE(),
507  M_displacementFESpace->dof() );
508  ifPtr->update (* (velSpacePtr->mesh() ), M_fluidInterfaceFlag,
509  * (M_displacementFESpace->mesh() ), M_solidInterfaceFlag,
510  M_interfaceTolerance, &M_fluidInterfaceVertexFlag );
511  }
512  std::cout << "dofStructureToHarmonicExtension done." << std::endl;
513 
514  std::cout << "All done." << std::endl << std::endl;
515 }
516 
517 } // Namespace LifeV
518 
519 #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)
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
MeshPartitionerOfflineFSI(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)
Constructor.
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 &)