LifeV
FSIOperator.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 /*!
28  @file
29  @brief Pure virtual operator class for FSI solvers
30 
31  @author Simone Deparis <simone.deparis@epfl.ch>
32  @contributor Gilles Fourestey <fourestey@cscs.ch>
33  @contributor Paolo Crosetto <paolo.crosetto@epfl.ch>
34  @maintainer Paolo Crosetto <paolo.crosetto@epfl.ch>
35 
36  @date 10-12-2010
37 
38  This is the base class for the FSI solvers in LifeV. It contains the methods to evaluate the residual and compute the
39  Jacobian matrix, which make it suited for the generalized Newton algorithm implemented in NonlinearRichardson.hpp. The fluid
40  and structure classes are members of this class and different formulations (e.g. Monolithic \cite CrosettoEtAl2009 , segregated
41  Newton \cite FernandezMoubachir2005 , Dirichlet--Neumann \cite DeparisDiscacciati2006 , Robin Neumann \cite BadiaNobileVergara2008 ) are implemented in the derived classes.
42  */
43 
44 #include <lifev/core/LifeV.hpp>
45 #include <lifev/fsi/solver/FSIOperator.hpp>
46 
47 namespace LifeV
48 {
49 
50 // ===================================================
51 // Constructors & Destructors
52 // ===================================================
53 FSIOperator::FSIOperator() :
54  M_uFESpace ( ),
55  M_pFESpace ( ),
56  M_dFESpace ( ),
57  M_dETFESpace ( ),
58  M_mmFESpace ( ),
59  M_fluidMesh ( ),
60  M_solidMesh ( ),
61  M_fluidLocalMesh ( ),
62  M_solidLocalMesh ( ),
63  M_BCh_u ( ),
64  M_BCh_d ( ),
65  M_BCh_mesh ( ),
66  M_BCh_du ( ),
67  M_BCh_du_inv ( ),
68  M_BCh_dz ( ),
69  M_BCh_dz_inv ( ),
70  M_BCh_dp ( ),
71  M_BCh_dp_inv ( ),
72  M_fluid ( ),
73  M_solid ( ),
74  M_meshMotion ( ),
75  // M_fluidLin ( ),
76  // M_solidLin ( ),
77  M_fluidTimeAdvanceMethod ( ),
78  M_solidTimeAdvanceMethod ( ),
79  M_ALETimeAdvanceMethod ( ),
80  M_fluidTimeAdvance ( ),
81  M_fluidMassTimeAdvance ( ),
82  M_solidTimeAdvance ( ),
83  M_ALETimeAdvance ( ),
84  M_dataFile ( ),
85  M_meshDataFluid ( new MeshData() ),
86  M_meshDataSolid ( new MeshData() ),
87  M_data ( ),
88  M_fluidInterfaceMap ( ),
89  M_solidInterfaceMap ( ),
90  M_fluidInterfaceMapOnZero ( ),
91  M_solidInterfaceMapOnZero ( ),
92  M_dofFluidToStructure ( ),
93  M_dofStructureToFluid ( ),
94  M_dofStructureToSolid ( ),
95  M_dofStructureToHarmonicExtension ( ),
96  M_dofHarmonicExtensionToFluid ( ),
97  M_dofFluid ( ),
98  M_dofSolid ( ),
99  M_dofFluidInv ( ),
100  M_dofSolidInv ( ),
101  M_bcvFluidInterfaceDisp ( ),
102  M_bcvFluidLoadToStructure ( ),
103  M_bcvSolidLoadToStructure ( ),
104  M_bcvStructureToFluid ( ),
105  M_bcvStructureDispToFluid ( ),
106  M_bcvStructureDispToSolid ( ),
107  M_bcvStructureDispToHarmonicExtension( ),
108  M_bcvHarmonicExtensionVelToFluid ( ),
109  M_bcvDerHarmonicExtensionVelToFluid ( ),
110  M_bcvDerFluidLoadToStructure ( ),
111  M_bcvDerFluidLoadToFluid ( ),
112  M_bcvDerStructureDispToSolid ( ),
113  M_bcfRobinOuterWall ( ),
114  M_lambdaFluid ( ),
115  M_lambdaFluidRepeated ( ),
116  M_lambda ( ),
117  M_lambdaDot ( ),
118  M_rhs ( ),
119  M_alphaF ( ), //vector_Type, for alphaf robin
120  M_alphaFCoef ( 0 ),
121  M_betaMean ( ),
122  M_epetraComm ( ),
123  M_epetraWorldComm ( ),
124  M_structureNonLinear (false),
125  //begin of private members
126  M_lambdaSolid ( ),
127  M_lambdaSolidRepeated ( ),
128  M_lambdaSolidOld ( ),
129  M_lambdaDotSolid ( ),
130  M_lambdaDotSolidRepeated ( ),
131  M_sigmaFluid ( ),
132  M_sigmaSolid ( ),
133  M_sigmaFluidRepeated ( ),
134  M_sigmaSolidRepeated ( ),
135  M_minusSigmaFluid ( ), //sigmafluid: auxiliary variable for Robin.
136  M_minusSigmaFluidRepeated ( ), //sigmafluid: auxiliary variable for Robin.
137  M_dispFluidMeshOld ( ),
138  M_veloFluidMesh ( ),
139  M_derVeloFluidMesh ( ),
140  M_mpi ( true ),
141  M_isFluid ( false ),
142  M_isSolid ( false ),
143  M_linearFluid ( false ),
144  M_linearSolid ( false ),
145  M_fluidLeader ( ),
146  M_solidLeader ( ),
147  M_aleOrder ( std::string ("P1") )
148 {
149 }
150 
151 FSIOperator::~FSIOperator()
152 {
153 }
154 
155 
156 // ===================================================
157 // Virtual Public Methods
158 // ===================================================
159 void
160 FSIOperator::setDataFile ( const GetPot& dataFile )
161 {
162  M_fluidMesh.reset ( new mesh_Type ( M_epetraComm ) );
163  M_meshDataFluid->setup (dataFile, "fluid/space_discretization");
164  readMesh (*M_fluidMesh, *M_meshDataFluid);
165 
166  M_solidMesh.reset (new mesh_Type ( M_epetraComm ) );
167  M_meshDataSolid->setup (dataFile, "solid/space_discretization");
168  readMesh (*M_solidMesh, *M_meshDataSolid);
169 
170  M_dataFile = dataFile;
171 
172  M_fluidTimeAdvanceMethod = dataFile ( "fluid/time_discretization/method", "BDF");
173  M_aleOrder = dataFile ( "fluid/space_discretization/ale_order", "P1");
174  M_solidTimeAdvanceMethod = dataFile ( "solid/time_discretization/method", "BDF");
175  M_ALETimeAdvanceMethod = dataFile ("mesh_motion/time_discretization/method", "BDF");
176  M_structureNonLinear = M_data->dataSolid()->lawType().compare ("linear");
177  this->setupTimeAdvance ( dataFile );
178 }
179 
180 void
181 FSIOperator::setupFEspace()
182 {
183  Displayer disp (M_epetraComm);
184  disp.leaderPrint ("FSI- Setting ReferenceFE and QuadratureRule ... \n");
185 
186  std::string uOrder = M_data->dataFluid()->uOrder();
187  std::string pOrder = M_data->dataFluid()->pOrder();
188  std::string dOrder = M_data->dataSolid()->order();
189 
190  ASSERT ( ! ( (!uOrder.compare ("P2") && !dOrder.compare ("P1") ) ), "You are using P2 FE for the fluid velocity and P1 FE for the structure: when the coupling is enforced only in the P1 nodes, the energy is not conserved across the interface." );
191  ASSERT ( ! ( (!uOrder.compare ("P1") && !dOrder.compare ("P2") ) ), "You are using P1 FE for the fluid velocity and P2 FE for the structure: when the coupling is enforced only in the P1 nodes, the energy is not conserved across the interface." );
192  ASSERT ( ! ( (!uOrder.compare ("P1Bubble") && !dOrder.compare ("P2") ) ), "You are using P2 FE for the fluid velocity and P1 FE for the structure: when the coupling is enforced only in the P1 nodes, the energy is not conserved across the interface." );
193 
194  if ( M_aleOrder.compare ( M_meshDataFluid->mOrder() ) )
195  {
196  disp.leaderPrint ("FSI- WARNING! The mesh order is different\n");
197  disp.leaderPrint (" => The nodes of the mesh will not entirely follow the computed displacement.\n");
198  }
199 
200  const ReferenceFE* refFE_vel (0);
201  const QuadratureRule* qR_vel (0);
202  const QuadratureRule* bdQr_vel (0);
203 
204  const ReferenceFE* refFE_press (0);
205  const QuadratureRule* qR_press (0);
206  const QuadratureRule* bdQr_press (0);
207 
208  const ReferenceFE* refFE_struct (0);
209  const QuadratureRule* qR_struct (0);
210  const QuadratureRule* bdQr_struct (0);
211 
212  const ReferenceFE* refFE_mesh (0);
213  const QuadratureRule* qR_mesh (0);
214  const QuadratureRule* bdQr_mesh (0);
215 
216  if ( uOrder.compare ("P2") == 0 )
217  {
218  refFE_vel = &feTetraP2;
219  qR_vel = &quadRuleTetra15pt; // DoE 5
220  bdQr_vel = &quadRuleTria3pt; // DoE 2
221  }
222  else if ( uOrder.compare ("P1") == 0 )
223  {
224  refFE_vel = &feTetraP1;
225  qR_vel = &quadRuleTetra4pt; // DoE 2
226  bdQr_vel = &quadRuleTria3pt; // DoE 2
227  }
228  else if ( uOrder.compare ("P1Bubble") == 0 )
229  {
230  refFE_vel = &feTetraP1bubble;
231  qR_vel = &quadRuleTetra64pt; // DoE 2
232  bdQr_vel = &quadRuleTria3pt; // DoE 2
233  }
234  else
235  {
236  ERROR_MSG (uOrder + " velocity FE not implemented yet.");
237  }
238 
239  if ( pOrder.compare ("P2") == 0 )
240  {
241  refFE_press = &feTetraP2;
242  qR_press = qR_vel; // DoE 5
243  bdQr_press = &quadRuleTria3pt; // DoE 2
244  }
245  else if ( pOrder.compare ("P1") == 0 )
246  {
247  refFE_press = &feTetraP1;
248  qR_press = qR_vel; // DoE 2
249  bdQr_press = &quadRuleTria3pt; // DoE 2
250  }
251  else
252  {
253  ERROR_MSG (pOrder + " pressure FE not implemented yet.");
254  }
255 
256  if ( dOrder.compare ("P2") == 0 )
257  {
258  refFE_struct = &feTetraP2;
259  qR_struct = &quadRuleTetra15pt; // DoE 5
260  bdQr_struct = &quadRuleTria3pt; // DoE 2
261  }
262  else if ( dOrder.compare ("P1") == 0 )
263  {
264  refFE_struct = &feTetraP1;
265  qR_struct = &quadRuleTetra4pt; // DoE 2
266  bdQr_struct = &quadRuleTria3pt; // DoE 2
267  }
268  else
269  {
270  ERROR_MSG (dOrder + " structure FE not implemented yet.");
271  }
272 
273  if ( M_aleOrder.compare ("P2") == 0 )
274  {
275  refFE_mesh = &feTetraP2;
276  qR_mesh = &quadRuleTetra15pt; // DoE 5
277  bdQr_mesh = &quadRuleTria3pt; // DoE 2
278  }
279  else if ( M_aleOrder.compare ("P1") == 0 )
280  {
281  refFE_mesh = &feTetraP1;
282  qR_mesh = &quadRuleTetra4pt; // DoE 2
283  bdQr_mesh = &quadRuleTria3pt; // DoE 2
284  }
285  else if ( M_aleOrder.compare ("P1Bubble") == 0 )
286  {
287  refFE_mesh = &feTetraP1bubble;
288  qR_mesh = &quadRuleTetra64pt; // DoE 2
289  bdQr_mesh = &quadRuleTria3pt; // DoE 2
290  }
291  else
292  {
293  ERROR_MSG (M_aleOrder + " mesh FE not implemented yet.");
294  }
295 
296  disp.leaderPrint ("done\n");
297 
298  disp.leaderPrint ("FSI- Building fluid FESpace ... \n");
299  if (this->isFluid() )
300  {
301 
302  M_mmFESpace.reset (new FESpace<mesh_Type, MapEpetra> (M_fluidLocalMesh,
303  //dOrder,
304  *refFE_mesh,
305  *qR_mesh,
306  *bdQr_mesh,
307  3,
308  M_epetraComm) );
309 
310  M_uFESpace.reset ( new FESpace<mesh_Type, MapEpetra> (M_fluidLocalMesh,
311  //uOrder,
312  *refFE_vel,
313  *qR_vel,
314  *bdQr_vel,
315  3,
316  M_epetraComm) );
317 
318  M_pFESpace.reset ( new FESpace<mesh_Type, MapEpetra> (M_fluidLocalMesh,
319  //pOrder,
320  *refFE_press,
321  *qR_press,
322  *bdQr_press,
323  1,
324  M_epetraComm) );
325  }
326  else
327  {
328  M_mmFESpace.reset (new FESpace<mesh_Type, MapEpetra> (M_fluidMesh,
329  //dOrder,
330  *refFE_mesh,
331  *qR_mesh,
332  *bdQr_mesh,
333  3,
334  M_epetraComm) );
335 
336  M_uFESpace.reset ( new FESpace<mesh_Type, MapEpetra> (M_fluidMesh,
337  //uOrder,
338  *refFE_vel,
339  *qR_vel,
340  *bdQr_vel,
341  3,
342  M_epetraComm) );
343 
344  M_pFESpace.reset ( new FESpace<mesh_Type, MapEpetra> (M_fluidMesh,
345  //pOrder,
346  *refFE_press,
347  *qR_press,
348  *bdQr_press,
349  1,
350  M_epetraComm) );
351  }
352  M_epetraWorldComm->Barrier();
353 
354  disp.leaderPrint ("FSI- Building solid FESpace ... \n");
355  if (this->isSolid() )
356  {
357  M_dFESpace.reset ( new FESpace<mesh_Type, MapEpetra> ( M_solidLocalMesh,
358  dOrder,
359  //*refFE_struct,
360  //*qR_struct,
361  //*bdQr_struct,
362  3,
363  M_epetraComm) );
364 
365  M_dETFESpace.reset ( new ETFESpace<mesh_Type, MapEpetra, 3, 3> ( M_solidLocalMesh,
366  & (M_dFESpace->refFE() ),
367  & (M_dFESpace->fe().geoMap() ),
368  M_epetraComm) );
369 
370  }
371  else
372  {
373  M_dFESpace.reset (new FESpace<mesh_Type, MapEpetra> (M_solidMesh,
374  //dOrder,
375  *refFE_struct,
376  *qR_struct,
377  *bdQr_struct,
378  3,
379  M_epetraComm) );
380 
381  M_dETFESpace.reset (new ETFESpace<mesh_Type, MapEpetra, 3, 3> (M_solidMesh,
382  & (M_dFESpace->refFE() ),
383  & (M_dFESpace->fe().geoMap() ),
384  M_epetraComm) );
385 
386  }
387  M_epetraWorldComm->Barrier();
388 }
389 
390 
391 void
392 FSIOperator::partitionMeshes()
393 {
394  if (this->isFluid() )
395  {
396  MeshPartitioner< mesh_Type > fluidPartitioner (M_fluidMesh, M_epetraComm);
397  M_fluidLocalMesh = fluidPartitioner.meshPartition();
398  }
399  if (this->isSolid() )
400  {
401  MeshPartitioner< mesh_Type > solidPartitioner (M_solidMesh, M_epetraComm);
402  M_solidLocalMesh = solidPartitioner.meshPartition();
403  }
404 }
405 
406 #ifdef HAVE_HDF5
407 void
409 {
412 }
413 #endif
414 
415 
416 void
417 FSIOperator::setupDOF ( void )
418 {
419  Displayer disp (M_epetraWorldComm);
420  disp.leaderPrint ("FSI: setting DOF ... " );
421  DOF uDof (*M_fluidMesh, M_uFESpace->refFE() ); // velocity dof related to unpartitioned mesh
422  DOF dDof (*M_solidMesh, M_dFESpace->refFE() ); // velocity dof related to unpartitioned mesh
423 
424  M_dofFluidToStructure .reset ( new DOFInterface3Dto3D );
425  M_dofStructureToFluid .reset ( new DOFInterface3Dto3D );
426  M_dofStructureToSolid .reset ( new DOFInterface3Dto3D );
427  M_dofStructureToHarmonicExtension .reset ( new DOFInterface3Dto3D );
428  M_dofHarmonicExtensionToFluid .reset ( new DOFInterface3Dto3D );
429  M_dofFluid .reset ( new DOFInterface3Dto2D );
430  M_dofSolid .reset ( new DOFInterface3Dto2D );
431  M_dofFluidInv .reset ( new DOFInterface3Dto2D );
432  M_dofSolidInv .reset ( new DOFInterface3Dto2D );
433  M_bcvFluidInterfaceDisp .reset ( new BCVectorInterface );
434  M_bcvFluidLoadToStructure .reset ( new BCVectorInterface );
435  M_bcvSolidLoadToStructure .reset ( new BCVectorInterface );
436  M_bcvStructureToFluid .reset ( new BCVectorInterface );
437  M_bcvStructureDispToFluid .reset ( new BCVectorInterface );
438  M_bcvStructureDispToSolid .reset ( new BCVectorInterface );
439  M_bcvStructureDispToHarmonicExtension.reset ( new BCVectorInterface );
440  M_bcvHarmonicExtensionVelToFluid .reset ( new BCVectorInterface );
441  M_bcvDerHarmonicExtensionVelToFluid .reset ( new BCVectorInterface );
442  M_bcvDerFluidLoadToStructure .reset ( new BCVectorInterface );
443  M_bcvDerFluidLoadToFluid .reset ( new BCVectorInterface );
444  M_bcvDerStructureDispToSolid .reset ( new BCVectorInterface );
445 
446  M_dofFluidToStructure->setup ( M_dFESpace->refFE(), M_dFESpace->dof(),
447  M_uFESpace->refFE(), uDof );
448  M_dofFluidToStructure->update ( *M_dFESpace->mesh(), M_data->structureInterfaceFlag(),
449  *M_fluidMesh, M_data->fluidInterfaceFlag(),
450  M_data->interfaceTolerance(),
451  M_data->structureInterfaceVertexFlag() );
452 
453  //here the solid mesh must be non partitioned in the monolithic case
454  M_dofStructureToHarmonicExtension->setup ( M_uFESpace->refFE(), M_uFESpace->dof(),
455  M_dFESpace->refFE(), dDof );
456  M_dofStructureToHarmonicExtension->update ( *M_uFESpace->mesh(), M_data->fluidInterfaceFlag(),
457  *M_solidMesh, M_data->structureInterfaceFlag(),
458  M_data->interfaceTolerance(),
459  M_data->fluidInterfaceVertexFlag() );
460 
461  M_dofStructureToSolid->setup ( M_dFESpace->refFE(), M_dFESpace->dof(),
462  M_dFESpace->refFE(), M_dFESpace->dof() );
463  M_dofStructureToSolid->update ( *M_dFESpace->mesh(), M_data->structureInterfaceFlag(),
464  *M_dFESpace->mesh(), M_data->structureInterfaceFlag(),
465  M_data->interfaceTolerance(),
466  M_data->structureInterfaceVertexFlag() );
467 
468  M_dofStructureToFluid->setup ( M_uFESpace->refFE(), M_uFESpace->dof(), //modifica matteo FSI
469  M_dFESpace->refFE(), dDof );
470  M_dofStructureToFluid->update ( *M_uFESpace->mesh(), M_data->fluidInterfaceFlag(),
471  *M_solidMesh, M_data->structureInterfaceFlag(),
472  M_data->interfaceTolerance(),
473  M_data->fluidInterfaceVertexFlag() );
474 
475  M_dofHarmonicExtensionToFluid->setup ( M_uFESpace->refFE(), M_uFESpace->dof(),
476  M_uFESpace->refFE(), M_uFESpace->dof() );
477  M_dofHarmonicExtensionToFluid->update ( *M_uFESpace->mesh(), M_data->fluidInterfaceFlag(),
478  *M_uFESpace->mesh(), M_data->fluidInterfaceFlag(),
479  M_data->interfaceTolerance(),
480  M_data->fluidInterfaceVertexFlag() );
481 
482  M_epetraWorldComm->Barrier();
483  disp.leaderPrint ("done\n");
484 
485  createInterfaceMaps ( M_dofStructureToHarmonicExtension->localDofMap() );
486 }
487 
488 void
489 FSIOperator::setupFluidSolid ( void )
490 {
491  setupFluidSolid (imposedFluxes() );
492 }
493 
494 void
495 FSIOperator::setupFluidSolid ( UInt const fluxes )
496 {
497  M_meshMotion.reset ( new meshMotion_Type ( *M_mmFESpace, M_epetraComm ) );
498 
499  if ( this->isFluid() )
500  {
501  M_fluid.reset ( new fluid_Type ( M_data->dataFluid(), *M_uFESpace, *M_pFESpace, M_epetraComm, fluxes ) );
502 
503  //Vector initialization
504  M_rhs.reset ( new vector_Type ( M_fluid->getMap() ) );
505  }
506 
507  M_solid.reset ( new solid_Type( ) );
508  M_solid->setup ( M_data->dataSolid(), M_dFESpace, M_dETFESpace, M_epetraComm );
509 
510  M_epetraWorldComm->Barrier();
511 }
512 
513 
514 
515 void
516 FSIOperator::setupSystem ( void )
517 {
518  if ( this->isFluid() )
519  {
520  //Data
521  M_fluid->setUp ( M_dataFile );
522  M_meshMotion->setUp ( M_dataFile );
523  // if (M_linearFluid)
524  // M_fluidLin->setUp(dataFile);
525  }
526 
527  if ( this->isSolid() )
528  {
529  M_solid->setDataFromGetPot ( M_dataFile );
530  // if (M_linearSolid)
531  // M_solidLin->setUp( dataFile );
532  }
533 
534  M_epetraWorldComm->Barrier();
535 }
536 
537 void
538 FSIOperator::buildSystem()
539 {
540  if ( this->isFluid() )
541  {
542  M_fluid->buildSystem();
543  // if (M_linearFluid)
544  // M_fluidLin->buildSystem();
545  }
546 
547  if (this->isSolid() )
548  {
549  M_data->dataSolid()->showMe();
550  //initialize xi0 for timaAdvance method for solid
551  double xi = M_solidTimeAdvance->coefficientSecondDerivative ( 0 ) / ( M_data->dataSolid()->dataTime()->timeStep() * M_data->dataSolid()->dataTime()->timeStep() );
552  M_solid->buildSystem (xi);
553  M_solid->massMatrix()->globalAssemble();
554  }
555 
556 }
557 
558 void
559 FSIOperator::updateSystem()
560 {
561  if ( this->isFluid() )
562  {
563  M_ALETimeAdvance->updateRHSContribution (M_data->dataFluid()->dataTime()->timeStep() );
564  M_fluidTimeAdvance->updateRHSContribution (M_data->dataFluid()->dataTime()->timeStep() );
565 
566  if (M_data->dataFluid()->conservativeFormulation() )
567  {
568  M_fluidMassTimeAdvance->updateRHSContribution (M_data->dataFluid()->dataTime()->timeStep() );
569  }
570 
571  transferMeshMotionOnFluid (M_meshMotion->disp(), *this->M_dispFluidMeshOld);
572 
573  }
574 
575  if ( this->isSolid() )
576  {
577  M_solid->updateSystem();
578  M_solidTimeAdvance->updateRHSContribution ( M_data->dataSolid()->dataTime()->timeStep() );
579  vector_Type rhsW (M_dFESpace->map(), Repeated);
580  rhsW = (*M_solid->massMatrix() * (M_solidTimeAdvance->rhsContributionSecondDerivative() ) * M_data->dataSolid()->dataTime()->timeStep() * M_data->dataSolid()->dataTime()->timeStep() / M_solidTimeAdvance->coefficientSecondDerivative ( 0 ) );
581  M_solid->setRightHandSide ( rhsW ); //for the solid rhs;
582  }
583 
584  couplingVariableExtrap( );
585 
586 }
587 
588 
589 
590 void FSIOperator::couplingVariableExtrap( )
591 {
592  *M_lambda = lambdaSolid();
593 
594  if (!M_lambdaDot.get() )
595  {
596  M_lambdaDot.reset ( new vector_Type (*M_fluidInterfaceMap, Unique) );
597  *M_lambda += M_data->dataFluid()->dataTime()->timeStep() * lambdaDotSolid();
598  }
599  else
600  {
601  if ( this->isSolid() )
602  {
603  vector_Type solidDisp (M_solid->displacement() );
604  vector_Type solidVel (M_solid->displacement() );
605  M_solidTimeAdvance->extrapolation (solidDisp);
606  M_solidTimeAdvance->extrapolationFirstDerivative (solidVel);
607  transferSolidOnInterface (solidDisp, *M_lambda);
608  transferSolidOnInterface (solidVel, *M_lambdaDot);
609  }
610  }
611  displayer().leaderPrint ("FSI- norm( disp ) init = ", M_lambda->normInf(), "\n" );
612  displayer().leaderPrint ("FSI- norm( velo ) init = ", M_lambdaDot->normInf(), "\n");
613 }
614 
615 void
616 FSIOperator::updateSolution ( const vector_Type& /* solution */ )
617 {
618  if ( this->isFluid() )
619  {
620  M_ALETimeAdvance->shiftRight ( this->M_meshMotion->disp() );
621  M_fluidTimeAdvance->shiftRight ( *M_fluid->solution() );
622  if (M_data->dataFluid()->conservativeFormulation() )
623  {
624  M_fluidTimeAdvance->shiftRight ( M_fluid->matrixMass() * (*M_fluid->solution() ) );
625  }
626  }
627  if ( this->isSolid() )
628  {
629  M_solidTimeAdvance->shiftRight ( M_solid->displacement() );
630  }
631 }
632 
633 UInt
634 FSIOperator::imposedFluxes ( void )
635 {
636  if ( this->isFluid() )
637  {
638  std::vector<bcName_Type> fluxVector = M_BCh_u->findAllBCWithType ( Flux );
639  UInt numLM = static_cast<UInt> ( fluxVector.size() );
640 
641  UInt offset = M_uFESpace->map().map (Unique)->NumGlobalElements()
642  + M_pFESpace->map().map (Unique)->NumGlobalElements();
643 
644  for ( UInt i = 0; i < numLM; ++i )
645  {
646  M_BCh_u->setOffset ( fluxVector[i], offset + i );
647  }
648  return numLM;
649  }
650  else
651  {
652  return 0;
653  }
654 }
655 
656 void
657 FSIOperator::initialize ( fluid_Type::function_Type const& u0,
658  fluid_Type::function_Type const& p0,
659  solid_Type::function const& d0,
660  solid_Type::function const& w0,
661  fluid_Type::function_Type const& /*df0*/ )
662 {
663  debugStream ( 6220 ) << "FSI:: solid init \n";
664  if (this->isSolid() )
665  {
666  solid().initialize (d0 /*, w0, w0*/);
667  }
668  debugStream ( 6220 ) << "FSI:: fluid init \n";
669  if (this->isFluid() )
670  {
671  fluid().initialize (u0, p0);
672  }
673 }
674 
675 void
677 {
678 
679  if (this->isFluid() )
680  {
683  {
685  }
686 
687 
688  if (M_fluidTimeAdvanceMethod == "Newmark")
689  {
692  {
694  }
695  }
696  if (M_fluidTimeAdvanceMethod == "BDF")
697  {
700  {
702  }
703  }
705 
706  if (M_ALETimeAdvanceMethod == "Newmark")
707  {
709  }
710 
711  if (M_ALETimeAdvanceMethod == "BDF")
712  {
714  }
715 
718  {
720  }
721 
723 
724  if (this->isLeader() )
725  {
727  //M_fluidMassTimeAdvance->showMe();
729  }
730  }
731  if ( this->isSolid() )
732  {
734 
735  std::vector<Real> parameters (2);
736  parameters[0] = dataFile ("solid/time_discretization/theta", 0.25);
737  parameters[1] = dataFile ("solid/time_discretization/zeta", 0.5);
738  UInt order = dataFile ("solid/time_discretization/BDF_order", 1);
739  // Real rhoInfty = dataFile("solid/time_discretization/rhoInf", 1.);
740  std::string type = dataFile ("mesh_motion/time_discretization/typeOfGeneralizedAlpha", "HHT");
741 
742 
743  if (M_solidTimeAdvanceMethod == "Newmark")
744  {
746  }
747 
748  if (M_solidTimeAdvanceMethod == "BDF")
749  {
751  }
752 
754  if (this->isLeader() )
755  {
757  }
758  }
759 
760 }
761 // ===================================================
762 // Public Methods
763 // ===================================================
765 {
766  displayer().leaderPrint ("initializeTimeAdvance start");
767 
768  if ( this->isFluid() )
769  {
770  ASSERT ( initialFluidVel.size() == M_fluidTimeAdvance->size(), "The number of vectors for initializing the time scheme for the fluid velocity is not consistent with the discretization chosen" );
771 
773  {
774  ASSERT ( initialFluidVel.size() == M_fluidMassTimeAdvance->size(), "The number of vectors for initializing the time scheme for the fluid velocity is not consistent with the discretization chosen" );
775  }
776 
777  ASSERT (initialFluidDisp.size() == M_ALETimeAdvance->size() , "The number of vectors for initializing the time discretization for the ALE map is not consistent with the discretization chosen");
779 
781  {
783  }
784 
785 
787  }
788  if ( this->isSolid() )
789  {
790  ASSERT (initialSolidDisp.size() == M_solidTimeAdvance->size(), "The number of vectors for initializing the time scheme for the structure displacement is not consistent with the discretization chosen" );
792  }
793  displayer().leaderPrint ("initializeTimeAdvance end");
794 }
795 
796 void
798  const vector_Type& displacement )
799 {
800  this->fluid().initialize ( velAndPressure );
801  this->moveMesh ( displacement);
802 }
803 
804 void
806  vectorPtr_Type /*velocity*/ )
807 {
808  this->solid().initialize ( displacement /*, velocity*/);
809 }
810 
811 void
813 {
814  displayer().leaderPrint ("FSI- Moving the mesh ... ");
816  displayer().leaderPrint ( "done\n" );
817 
818  M_fluid->setRecomputeMatrix ( true );
819 }
820 
822 {
824  disp.leaderPrint ("FSI- Building fluid variables ... ");
825 
826  // now we build the sigma and lambda variables on each proc
827 
828 
830 
831  //is the interface map between HE (first) and solid (second)
832  if ( this->isFluid() )
833  {
834  //std::map<ID, ID> const& locDofMap = M_dofStructureToHarmonicExtension->locDofMap();
836 
837  for (UInt dim = 0; dim < nDimensions; ++dim)
838  for ( iterator_Type i = locDofMap.begin(); i != locDofMap.end(); ++i )
839  {
840  dofInterfaceFluid.push_back (i->second + dim * M_dFESpace->dof().numTotalDof() ); // in solid numerotation
841  }
842  }
843 
844  int* pointerToDofs (0);
845  if (dofInterfaceFluid.size() > 0)
846  {
848  }
849 
851  static_cast<int> (dofInterfaceFluid.size() ),
853  M_epetraWorldComm ) );
854  disp.leaderPrint ("done\n");
856 
857  disp.leaderPrint ("FSI- Building solid variables ... ");
858 
860 
861  if (this->isSolid() )
862  {
863  //std::map<ID, ID> const& locDofMap = M_dofFluidToStructure->locDofMap();
865  //std::cout << "solid" << std::endl;
866  for (UInt dim = 0; dim < nDimensions; ++dim)
867  for ( iterator_Type i = locDofMap.begin(); i != locDofMap.end(); ++i )
868  {
869  dofInterfaceSolid.push_back (i->second/*Simone: first*/ + dim * M_dFESpace->dof().numTotalDof() ); // in solid numerotation
870  }
871  }
872 
873 
874  pointerToDofs = 0;
875  if (dofInterfaceSolid.size() > 0)
876  {
878  }
879 
881  static_cast<int> (dofInterfaceSolid.size() ),
883  M_epetraWorldComm ) );
884 
886  disp.leaderPrint ("done\n");
887 
888  disp.leaderPrint ("FSI- Variables initialization ... \n");
889 
891 
893 }
894 
895 void
897 {
898  // e.g.: vec1=M_fluid->residual(), vec2=M_sigmaFluid
899  // _vec2 = ZeroVector(_vec2.size());
900 
901  if (_vec1.mapType() == Unique)
902  {
905  return;
906  }
907 
908  if (_vec2.mapType() == Repeated)
909  {
912  _vec2 = vec2Unique;
913  return;
914  }
915 
916  _vec2 *= 0;
917 
919 
922 
923  typedef std::map<ID, ID>::const_iterator iterator_Type;
924 
925  for (UInt dim = 0; dim < nDimensions; ++dim)
926  for ( iterator_Type it = locDofMap.begin(); it != locDofMap.end(); ++it )
927  {
928  // std::cout << it->second + dim*numTotalDofFluid << " to "
929  // << it->first + dim*numTotalDofSolid << " : "
930  // << _vec1[it->second + dim*numTotalDofFluid] << std::endl;
933  }
934 }
935 
936 //works in serial but no yet in parallel
937 void
939 {
940  // e.g.: vec2=M_fluid->residual(), vec1=M_sigmaFluid
941  // _vec2 = ZeroVector(_vec2.size());
942 
943  if (_vec1.mapType() == Unique)
944  {
947  return;
948  }
949 
950  if (_vec2.mapType() == Repeated)
951  {
954  _vec2 = vec2Unique;
955  return;
956  }
957 
958  _vec2 *= 0;
959 
961 
962 
965 
966  typedef std::map<ID, ID>::const_iterator iterator_Type;
967 
968  for (UInt dim = 0; dim < nDimensions; ++dim)
969  for ( iterator_Type it = locDofMap.begin(); it != locDofMap.end(); ++it )
970  {
973  }
974 }
975 
976 void
978 {
979  /* e.g.:
980  vec1 (Unique) vec2 (Repeated) (On different MapEpetras) (Changing now to Unique on both)
981  M_solid->disp() M_lambdaSolid
982  M_solid->vel() M_lambdaDotSolid
983  M_solid->residual() M_sigmaSolid
984  */
985 
986  if (_vec1.mapType() == Unique)
987  {
990  return;
991  }
992 
993  if (_vec2.mapType() == Repeated)
994  {
997  _vec2 = vec2Unique;
998  return;
999  }
1000 
1001  _vec2 *= 0;
1002 
1004 
1006 
1007  typedef std::map<ID, ID>::const_iterator iterator_Type;
1008 
1009  for (UInt dim = 0; dim < nDimensions; ++dim)
1010  for ( iterator_Type it = locDofMap.begin(); it != locDofMap.end(); ++it )
1011  {
1013  _vec1[it->first + dim * numTotalDofSolid] );
1014  }
1015 }
1016 
1017 void
1019 {
1020  /* e.g.:
1021  vec2 vec1
1022  M_solid->disp() M_lambdaSolid
1023  M_solid->vel() M_lambdaDotSolid
1024  M_solid->residual() M_sigmaSolid
1025  */
1026 
1027  if (_vec1.mapType() == Unique)
1028  {
1031  return;
1032  }
1033 
1034  if (_vec2.mapType() == Repeated)
1035  {
1038  _vec2 = vec2Unique;
1039  return;
1040  }
1041 
1042  _vec2 *= 0;
1043 
1046 
1047  typedef std::map<ID, ID>::const_iterator iterator_Type;
1048 
1049  for (UInt dim = 0; dim < nDimensions; ++dim)
1050  for ( iterator_Type it = locDofMap.begin(); it != locDofMap.end(); ++it )
1051  {
1054  }
1055 }
1056 
1057 void
1059 {
1061  {
1063  }
1064 
1066 }
1067 
1068 void
1070 {
1072  {
1074  }
1075 
1077 
1078  if ( !bcHandlerSolid->bcUpdateDone() )
1079  {
1081  }
1082 
1084 }
1085 void
1087 {
1088  Real h = 0.1, R = 0.5;
1090  M_alphaFCoef += h * M_data->dataSolid()->young (1) * this->dataFluid()->dataTime()->timeStep() /
1091  (std::pow (R, 2) * (1 - std::pow (M_data->dataSolid()->poisson (1), 2) ) );
1093 }
1094 
1095 void
1097 {
1098  this->setAlphafCoef();
1099  this->setAlphaf();
1100 
1101  if (M_alphaF.get() == 0)
1102  {
1103  this->setAlphafCoef();
1106  }
1107  else
1108  {
1111  }
1112 }
1113 
1114 // ===================================================
1115 // Display Methods
1116 // ===================================================
1117 bool
1119 {
1120  if ( isFluid() )
1121  {
1122  if ( M_fluid.get() == 0 )
1123  {
1124  return ( M_epetraComm->MyPID() == 0 );
1125  }
1126 
1127  return M_fluid->getDisplayer().isLeader();
1128  }
1129 
1130  if ( M_solid.get() == 0 )
1131  {
1132  return ( M_epetraComm->MyPID() == 0 );
1133  }
1134 
1135  return M_solid->displayer().isLeader();
1136 }
1137 
1138 
1139 
1140 Displayer const&
1142 {
1143  if ( isFluid() && M_fluid.get() )
1144  {
1145  return M_fluid->getDisplayer();
1146  }
1147 
1148  if ( !isSolid() || !M_solid.get() )
1149  {
1150  std::cout << "ERROR: displayer not ready" << std::endl;
1151  }
1152 
1153  return M_solid->displayer();
1154 }
1155 
1156 
1157 
1158 
1159 
1160 // ===================================================
1161 // Get Functions
1162 // ===================================================
1163 /*
1164 FSI::vector_Type
1165 FSI::displacementOnInterface()
1166 {
1167 
1168 // vector_Type dispOnInterface();
1169 // //@ dispOnInterface = ZeroVector(dispOnInterface.size());
1170 
1171 // // FOR_EACH_INTERFACE_DOF( dispOnInterface[IDsolid + jDim*totalDofSolid] =
1172 // // M_solid->disp()[IDsolid + jDim*totalDofSolid]);
1173 
1174 // Real norminf;
1175 // Real norm2;
1176 
1177 // dispOnInterface.NormInf(&norminf);
1178 // dispOnInterface.Norm2(&norm2);
1179 
1180 // std::cout << "max norm disp = " << norminf;
1181 // std::cout << std::endl;
1182 // std::cout << "l2 norm disp = " << norm2;
1183 // std::cout << std::endl;
1184 
1185 // return dispOnInterface;
1186  assert(false);
1187 
1188 }
1189 */
1190 
1191 
1192 
1193 
1194 
1195 // ===================================================
1196 // Set Functions
1197 // ===================================================
1198 void
1200  const commPtr_Type& worldComm )
1201 {
1202  M_epetraComm = comm;
1204 }
1205 
1206 
1207 void
1209 {
1210  M_fluid = fluid;
1212  M_isFluid = true;
1213 }
1214 
1215 
1216 
1217 void
1219 {
1220  M_solid = solid;
1221  M_isSolid = true;
1222 }
1223 
1224 
1225 
1226 void
1228 {
1229  if ( isFluid() )
1230  {
1231  M_BCh_u = bc_fluid;
1232  }
1233 }
1234 
1235 
1236 
1237 void
1239 {
1240  if ( isFluid() )
1241  {
1242  M_BCh_mesh = bc_he;
1243  //M_meshMotion->setBC(*M_BCh_mesh);
1244  }
1245 }
1246 
1247 
1248 
1249 void
1251 {
1252  if ( isSolid() )
1253  {
1254  M_BCh_d = bc_solid;
1255  }
1256 }
1257 
1258 
1259 
1260 void
1262 {
1263  if ( lambda.mapType() == Unique )
1264  {
1265  *M_lambdaFluid = lambda;
1266  }
1267  else // to be coded, I am not sure we need this functionality.
1268  {
1269  assert (false); // if you get here, reformulate your problem in order to get a unique map as entry
1270  }
1271 
1273 }
1274 
1275 
1276 
1277 void
1279 {
1280  if ( lambda.mapType() == Unique )
1281  {
1282  *M_lambdaSolid = lambda;
1283  }
1284  else // to be coded, I am not sure we need this functionality.
1285  {
1286  assert (false); // if you get here, reformulate your problem in order to get a unique map as entry
1287  }
1288 
1290 }
1291 
1292 
1293 
1294 void
1296 {
1297  if ( lambda.mapType() == Unique )
1298  {
1300  }
1301  else // to be coded, I am not sure we need this functionality.
1302  {
1303  assert (false); // if you get here, reformulate your problem in order to get a unique map as entry
1304  }
1305 }
1306 
1307 
1308 
1309 void
1311 {
1312  if ( lambda.mapType() == Unique )
1313  {
1315  }
1316  else // to be coded, I am not sure we need this functionality.
1317  {
1318  assert (false); // if you get here, reformulate your problem in order to get a unique map as entry
1319  }
1320 
1322 }
1323 
1324 
1325 
1326 void
1328 {
1329  if ( sigma.mapType() == Unique )
1330  {
1331  *M_sigmaSolid = sigma;
1332  }
1333  else // to be coded, I am not sure we need this functionality.
1334  {
1335  assert (false); // if you get here, reformulate your problem in order to get a unique map as entry
1336  }
1337 
1339 }
1340 
1341 
1342 void
1344 {
1345  if ( sigma.mapType() == Unique )
1346  {
1347  *M_sigmaFluid = sigma;
1348  }
1349  else // to be coded, I am not sure we need this functionality.
1350  {
1351  assert (false); // if you get here, reformulate your problem in order to get a unique map as entry
1352  }
1353 
1355 
1356 }
1357 
1358 
1359 
1360 void
1362 {
1363  if ( sigma.mapType() == Unique )
1364  {
1366  *M_minusSigmaFluid *= -1;
1367  }
1368  else // to be coded, I am not sure we need this functionality.
1369  {
1370  assert (false); // if you get here, reformulate your problem in order to get a unique map as entry
1371  }
1372 
1374 }
1375 
1376 
1377 
1378 
1379 void
1381 {
1384  *M_alphaF = vec ;
1385 }
1386 
1387 
1388 
1389 void
1391 {
1393  M_dFESpace->dof().numTotalDof(),
1395  type );
1396 }
1397 
1398 
1399 
1400 void
1402 {
1404  M_uFESpace->dof().numTotalDof(),
1406  type );
1407 }
1408 
1409 
1410 
1411 void
1413 {
1415  M_uFESpace->dof().numTotalDof(),
1417  type );
1418 }
1419 
1420 
1421 
1422 void
1424 {
1426  M_dFESpace->dof().numTotalDof(),
1428  type );
1429 }
1430 
1431 
1432 
1433 void
1435 {
1437  M_dFESpace->dof().numTotalDof(),
1439  type );
1440 }
1441 
1442 
1443 
1444 void
1446 {
1448  M_dFESpace->dof().numTotalDof(),
1450  type );
1451 }
1452 
1453 
1454 
1455 void
1457 {
1459  M_uFESpace->dof().numTotalDof(),
1461  type );
1462 }
1463 
1464 
1465 
1466 void
1468 {
1470  M_uFESpace->dof().numTotalDof(),
1472  type );
1473 }
1474 
1475 
1476 
1477 
1478 void
1480 {
1482  M_dFESpace->dof().numTotalDof(),
1484  type );
1485 }
1486 
1487 
1488 
1489 void
1491 {
1493  M_dFESpace->dof().numTotalDof(),
1495  type );
1496 }
1497 
1498 
1499 
1500 void
1502 {
1504  M_uFESpace->dof().numTotalDof(),
1506  type );
1507 }
1508 
1510 {
1512  E);
1513 }
1514 
1515 
1516 // ===================================================
1517 // Protected Methods
1518 // ===================================================
1519 
1520 
1521 
1522 void
1523 FSIOperator::variablesInit ( const std::string& /*dOrder*/ )
1524 //FSI::variablesInit(const ReferenceFE* refFE_struct,const LifeV::QuadratureRule* bdQr_struct, const LifeV::QuadratureRule* qR_struct)
1525 {
1530 
1531  if ( this->isFluid() )
1532  {
1536 
1537  if ( M_linearFluid )
1538  {
1540  }
1541  }
1542 
1547 
1552 
1556 }
1557 
1558 
1559 void
1561 {
1562  //transferMeshMotionOnFluid should handle the repetition of the interface nodes.
1563  if (_vec1.mapType() == Unique)
1564  {
1567  return;
1568  }
1569 
1570  if (_vec2.mapType() == Repeated)
1571  {
1574  _vec2 = vec2Unique;
1575  return;
1576  }
1577 
1578  _vec2 *= 0;
1579 
1581  return;
1582 
1583 }
1584 
1585 void
1587 {
1588  assert (_vec1.mapType() == Repeated);
1589  assert (_vec2.mapType() == Unique);
1590 
1591  typedef mesh_Type::elementShape_Type GeoShape; // Element shape
1592 
1593  UInt nDofpV = M_uFESpace->refFE().nbDofPerVertex(); // number of DOF per vertex
1594  UInt nDofpE = M_uFESpace->refFE().nbDofPerEdge(); // number of DOF per edge
1595  UInt nDofpF = M_uFESpace->refFE().nbDofPerFace(); // number of DOF per face
1596  UInt nDofpEl = M_uFESpace->refFE().nbDofPerVolume(); // number of DOF per Volume
1597 
1598  UInt nElemV = GeoShape::S_numVertices; // Number of element's vertices
1599  UInt nElemE = GeoShape::S_numEdges; // Number of element's edges
1600  UInt nElemF = GeoShape::S_numFaces; // Number of element's faces
1601 
1602  // UInt nDofElem = M_uFESpace->refFE().nbDof; // Number of local dof per element of the M_uFESpace->mesh() (_mesh.getRefFE().nbDof)
1604 
1605  UInt nDofElemV = nElemV * nDofpV; // number of vertex's DOF on a Element
1606  UInt nDofElemE = nElemE * nDofpE; // number of edge's DOF on a Element
1607  UInt nDofElemF = nElemF * nDofpF; // number of face's DOF on a Element
1608 
1609  Real x, y, z;
1611  ID lDof;
1612 
1613  // Loop on elements of the mesh
1614  for ( ID iElem = 0; iElem < M_uFESpace->mesh()->numVolumes(); ++iElem )
1615  {
1617  //if (elemId != iElem)
1618  // std::cout << " elemId = " << elemId << " iElem = " << iElem << std::endl;
1619 
1620  // Updating the local mesh velocity in this mesh elment
1621  for ( UInt icmp = 0; icmp < nDimensions; ++icmp )
1622  for ( ID idof = 0; idof < nDofElemMesh; ++idof )
1623  {
1624  wLoc ( icmp * nDofElemMesh + idof ) =
1627  }
1628  // Vertex based Dof
1629  if ( nDofpV )
1630  {
1631 
1632  // loop on element vertices
1633  for ( ID iVe = 0; iVe < nElemV; ++iVe )
1634  {
1635 
1636  // Loop number of DOF per vertex
1637  for ( ID l = 0; l < nDofpV; ++l )
1638  {
1639  lDof = iVe * nDofpV + l; // Local dof in this element
1640 
1641  // Nodal coordinates
1642  x = M_uFESpace->refFE().xi ( lDof );
1643  y = M_uFESpace->refFE().eta ( lDof );
1644  z = M_uFESpace->refFE().zeta ( lDof );
1645 
1646  // Loop on data vector components
1647  for ( UInt icmp = 0; icmp < nDimensions; ++icmp )
1648  {
1649 
1650  // Interpolating data at the nodal point
1651  Real __sum = 0;
1652  for ( ID idof = 0; idof < nDofElemMesh; ++idof ) // Loop on local DOF on the element
1653  {
1654  __sum += wLoc ( icmp * nDofElemMesh + idof ) * M_mmFESpace->refFE().phi ( idof, x, y, z );
1655  }
1656 
1657  // Updating interpolated mesh velocity
1660 
1661  }
1662  }
1663  }
1664  }
1665 
1666  // Edge based Dof
1667  if ( nDofpE )
1668  {
1669 
1670  // loop on element edges
1671  for ( ID iEd = 0; iEd < nElemE; ++iEd )
1672  {
1673 
1674  // Loop number of DOF per edge
1675  for ( ID l = 0; l < nDofpE; ++l )
1676  {
1677  lDof = nDofElemV + iEd * nDofpE + l; // Local dof in the adjacent Element
1678 
1679  // Nodal coordinates
1680  x = M_uFESpace->refFE().xi ( lDof );
1681  y = M_uFESpace->refFE().eta ( lDof );
1682  z = M_uFESpace->refFE().zeta ( lDof );
1683 
1684  // Loop on data vector components
1685  for ( UInt icmp = 0; icmp < nDimensions; ++icmp )
1686  {
1687 
1688  // Interpolating data at the nodal point
1689  Real __sum = 0;
1690  for ( ID idof = 0; idof < nDofElemMesh; ++idof ) // Loop on local DOF on the adjacent element
1691  {
1692  __sum += wLoc ( icmp * nDofElemMesh + idof ) * M_mmFESpace->refFE().phi ( idof, x, y, z ); // Problem here with P2
1693  }
1694 
1695  // Updating interpolating vector
1698 
1699  }
1700  }
1701  }
1702  }
1703 
1704  // Face based Dof
1705  if ( nDofpF )
1706  {
1707 
1708  // loop on element faces
1709  for ( ID iFa = 0; iFa < nElemF; ++iFa )
1710  {
1711 
1712  // Loop on number of DOF per face
1713  for ( ID l = 0; l < nDofpF; ++l )
1714  {
1715 
1716  lDof = nDofElemE + nDofElemV + iFa * nDofpF + l; // Local dof in the adjacent Element
1717 
1718  // Nodal coordinates
1719  x = M_uFESpace->refFE().xi ( lDof );
1720  y = M_uFESpace->refFE().eta ( lDof );
1721  z = M_uFESpace->refFE().zeta ( lDof );
1722 
1723  // Loop on data vector components
1724  for ( UInt icmp = 0; icmp < nDimensions; ++icmp )
1725  {
1726 
1727  // Interpolating data at the nodal point
1728  Real __sum = 0;
1729  for ( ID idof = 0; idof < nDofElemMesh; ++idof ) // Loop on local DOF on the adjacent element
1730  {
1731  __sum += wLoc ( icmp * nDofElemMesh + idof ) * M_mmFESpace->refFE().phi ( idof, x, y, z ); // Problem here with P2
1732  }
1733 
1734  // Updating interpolating vector
1737  }
1738  }
1739  }
1740  }
1741 
1742  // Element based Dof
1743  // Loop on number of DOF per Element
1744  for ( ID l = 0; l < nDofpEl; ++l )
1745  {
1746  lDof = nDofElemF + nDofElemE + nDofElemV + l; // Local dof in the Element
1747 
1748  // Nodal coordinates
1749  x = M_uFESpace->refFE().xi ( lDof );
1750  y = M_uFESpace->refFE().eta ( lDof );
1751  z = M_uFESpace->refFE().zeta ( lDof );
1752 
1753  // Loop on data vector components
1754  for ( UInt icmp = 0; icmp < nDimensions; ++icmp )
1755  {
1756 
1757  // Interpolating data at the nodal point
1758  Real __sum = 0;
1759  for ( ID idof = 0; idof < nDofElemMesh; ++idof ) // Loop on local DOF on the adjacent element
1760  {
1761  __sum += wLoc ( icmp * nDofElemMesh + idof ) * M_mmFESpace->refFE().phi ( idof, x, y, z );
1762  }
1763 
1764  // Updating interpolating vector
1765  // std::cout << M_uFESpace->dof().localToGlobal( elemId, lDof ) << " ";
1766  // std::cout << icmp * M_uFESpace->dof().numTotalDof() + M_uFESpace->dof().localToGlobal( elemId, lDof ) << std::endl;
1767 
1770  }
1771  }
1772  }
1773 
1774 }
1775 
1776 
1777 
1778 
1779 // this will interpolate dofs values from fespace1 to fespace2
1780 void
1782  const vector_Type& _vec1,
1784  vector_Type& _vec2,
1786 {
1787  assert (_vec1.mapType() == Repeated);
1788  assert (_vec2.mapType() == Unique);
1789 
1790  //typedef mesh_Type::elementShape_Type GeoShape; // Element shape
1791 
1792 
1793  UInt nDofPerVert1 = _fespace1.refFE().nbDofPerVertex(); // number of DOF per vertex
1794  UInt nDofPerEdge1 = _fespace1.refFE().nbDofPerEdge(); // number of DOF per edge
1795  //UInt nDofPerFace1 = _fespace1.refFE().nbDofPerFace; // number of DOF per face
1796  //UInt nDofPerElem1 = _fespace1.refFE().nbDofPerVolume; // number of DOF per Volume
1797 
1798  UInt nDofPerVert2 = _fespace2.refFE().nbDofPerVertex(); // number of DOF per vertex
1799  UInt nDofPerEdge2 = _fespace2.refFE().nbDofPerEdge(); // number of DOF per edge
1800  //UInt nDofPerFace2 = _fespace2.refFE().nbDofPerFace; // number of DOF per face
1801  //UInt nDofPerElem2 = _fespace2.refFE().nbDofPerVolume; // number of DOF per Volume
1802 
1803  //UInt nElemV = GeoShape::S_numVertices; // Number of element's vertices
1804  //UInt nElemE = GeoShape::S_numEdges; // Number of element's edges
1805  //UInt nElemF = GeoShape::S_numFaces; // Number of element's faces
1806 
1807  //UInt nBFacesVert = GeoShape::GeoBShape::S_numVertices;
1808  //UInt nBFacesEdge = GeoShape::GeoBShape::S_numEdges;
1809  //UInt nBFacesFace = GeoShape::GeoBShape::S_numFaces;
1810 
1813 
1814  // UInt nDofElem = M_uFESpace->refFE().nbDof; // Number of local dof per element of the M_uFESpace->mesh() (_mesh.getRefFE().nbDof)
1817 
1818  //UInt nDofElemVert1 = nElemV * nDofPerVert1; // number of vertex's DOF on a Element
1819  //UInt nDofElemEdge1 = nElemE * nDofPerEdge1; // number of edge's DOF on a Element
1820  //UInt nDofElemFace1 = nElemF * nDofPerFace1; // number of face's DOF on a Element
1821 
1822  //UInt nDofElemVert2 = nElemV * nDofPerVert2; // number of vertex's DOF on a Element
1823  //UInt nDofElemEdge2 = nElemE * nDofPerEdge2; // number of edge's DOF on a Element
1824  //UInt nDofElemFace2 = nElemF * nDofPerFace2; // number of face's DOF on a Element
1825 
1827  //UInt numTotalEdge1 = _fespace1.mesh()->numGlobalEdges();
1828  //UInt numTotalFace1 = _fespace1.mesh()->numGlobalFaces();
1829  //UInt numTotalVol1 = _fespace1.mesh()->numGlobalVolumes();
1830 
1832  //UInt numTotalEdge2 = _fespace2.mesh()->numGlobalEdges();
1833  //UInt numTotalFace2 = _fespace2.mesh()->numGlobalFaces();
1834  //UInt numTotalVol2 = _fespace2.mesh()->numGlobalVolumes();
1835 
1836 
1837  std::map<ID, ID> const& locDofMap = _dofInterface->localDofMap();
1839 
1840  //Real x, y, z;
1841  Real value;
1842  // Vector wLoc( nDofElemMesh1 * nDimensions );
1843  // Loop on elements of the mesh
1844  if (nDofPerVert1 && nDofPerVert2)
1845  {
1846  // std::cout << " -> both FESpace have unknowns on their nodes" << std::endl;
1847  for ( ID iVert = 0; iVert < _fespace1.mesh()->numVertices(); ++iVert )
1848  {
1849  if ( (int) _fespace1.mesh()->pointList (iVert).markerID() != M_data->fluidInterfaceFlag() )
1850  {
1851  continue;
1852  }
1853 
1855  // Loop number of DOF per vertex
1856  //TODO check this, loop does not depend on l
1857  for ( ID l = 0; l < nDofPerVert1; ++l )
1858  {
1859  // Loop on data vector components
1860  for ( UInt icmp = 0; icmp < nDimensions; ++icmp )
1861  {
1862  // "Interpolating" data at the nodal point
1863  iter = locDofMap.find (nodeID);
1864  Real value = _vec1 ( icmp * numTotalDof1 + nodeID );
1865  // now what to what boundary node ( in the solid numerotation ) should we send this value ?
1866  //std::cout << "" << std::endl;
1867  int iDof = icmp * numTotalDof2 + iter->second;
1868  // std::cout << " transfering " << value << " from P1 " << nodeID << " to P1 " << iDof << " ( " << iter->second << " ) " << std::endl;
1869  // Updating interpolated mesh velocity
1871  }
1872  }
1873  }
1874  }
1875 
1876  // Edge based Dof
1877  if ( nDofPerEdge1 )
1878  {
1879  // loop on boundary edges
1880  for ( ID iEdge = 0; iEdge < nBEdges1; ++iEdge )
1881  {
1882  if ( (int) _fespace1.mesh()->edgeList (iEdge).markerID() != M_data->fluidInterfaceFlag() )
1883  {
1884  continue;
1885  }
1886 
1887  // edge ID
1888  ID edgeID = _fespace1.mesh()->edgeList (iEdge).id();
1889  // dof position of the edge since unknowns are store using [ node | edges | faces | volumes ]
1890  int iDofEdge = numTotalVert1 + edgeID;
1891 
1892  if (nDofPerEdge2) // the second FE space has dofs on its edges
1893  {
1894  for ( ID l = 0; l < nDofPerEdge1; ++l )
1895  {
1896  // Loop on data vector components
1897  for ( UInt icmp = 0; icmp < nDimensions; ++icmp )
1898  {
1899  // ID of the dof in the solid numerotation
1901  int iDof = icmp * numTotalDof2 + iter->second;
1902  // "Interpolating" data at the nodal point
1904  // now what to what boundary node ( in the solid numerotation ) should we send this value ?
1905  // std::cout << " transfering " << value << " from P2 " << edgeID << " to P2 " << iDof << " ( " << iter->second << " ) " << std::endl;
1906  // Updating interpolated mesh velocity
1908  }
1909  }
1910  }
1911  else
1912  {
1913  for ( ID l = 0; l < nDofPerEdge1; ++l )
1914  {
1915  // Loop on data vector components
1916  for ( UInt icmp = 0; icmp < nDimensions; ++icmp )
1917  {
1918  //
1919  // ID of the 1st node of the edge
1920  ID node1 = _fespace1.mesh()->edgeList (iEdge).point (0).id();
1921  iter = locDofMap.find (node1);
1922  // ID of the 1st dof of the edge in the solid numerotation
1923  int iDof1 = icmp * numTotalDof2 + iter->second;
1924  value = 0.5 * _vec1 ( icmp * numTotalDof1 + iDofEdge ) + _vec2[iDof1];
1925  // std::cout << " transfering " << value << " from P2 " << iDofEdge << " to P1 " << iDof1 << " ( " << iter->second << " ) " << std::endl;
1927  //
1928  // ID of the 2nd node of the edge
1929  ID node2 = _fespace1.mesh()->edgeList (iEdge).point (1).id();
1930  iter = locDofMap.find (node2);
1931  // ID of the 2nd dof of the edge in the solid numerotation
1932  int iDof2 = icmp * numTotalDof2 + iter->second;
1933  value = 0.5 * _vec1 ( icmp * numTotalDof1 + iDofEdge ) + _vec2[iDof2];
1934  // std::cout << " transfering " << value << " from P2 " << iDofEdge << " to P1 " << iDof2 << " ( " << iter->second << " ) " << std::endl;
1936  // now what to what boundary node ( in the solid numerotation ) should we send this value ?
1937  //std::cout << "" << std::endl;
1938  // Updating interpolated mesh velocity
1939  // _vec2.setCoefficient( iDof2, value );
1940  // std::cout << std::endl;
1941  }
1942  }
1943  }
1944  }
1945  }
1946  else if (nDofPerEdge2)
1947  {
1948  // The first FESpace has no dofs on the edge
1949  // The second FESpace has dofs on the edge
1950  // We need to interpolate the vertex dofs on the edge dofs
1951 
1952  // First we need to go through the FS interface boundary edges on the second mesh
1953 
1954  // loop on boundary edges
1955  for ( ID iEdge = 0; iEdge < nBEdges2; ++iEdge )
1956  {
1957  if ( (int) _fespace2.mesh()->edgeList (iEdge).markerID() != M_data->fluidInterfaceFlag() )
1958  {
1959  continue;
1960  }
1961  // Now that we have an edge on the FS interface, let's get its ID
1962  ID edgeID = _fespace2.mesh()->edgeList (iEdge).id();
1963  // dof position of the edge since unknowns are store using [ node | edges | faces | volumes ]
1964  int iDofEdge = numTotalVert2 + edgeID;
1965 
1966  for ( ID l = 0; l < nDofPerEdge1; ++l )
1967  {
1968  // Loop on data vector components
1969  for ( UInt icmp = 0; icmp < nDimensions; ++icmp )
1970  {
1971  // interpolation of the nodal values in the middle of the segement
1972  ID node1 = _fespace2.mesh()->edgeList (iEdge).point (0).id();
1973  ID node2 = _fespace2.mesh()->edgeList (iEdge).point (1).id();
1974  value = 0.5 * (_vec2 (icmp * numTotalDof2 + node1) + _vec2 (icmp * numTotalDof2 + node2) );
1976  }
1977  }
1978  }
1979  }
1980 
1981 
1982 }
1983 
1984 
1985 } // Namespace LifeV
const QuadratureRule quadRuleTetra64pt(pt_tetra_64pt, 6, "Quadrature rule 64 points on a tetraedra", TETRA, 64, 7)
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
const QuadratureRule quadRuleTetra15pt(pt_tetra_15pt, 5, "Quadrature rule 15 points on a tetraedra", TETRA, 15, 5)
#define debugStream
Definition: LifeDebug.hpp:182
const QuadratureRule quadRuleTetra4pt(pt_tetra_4pt, 2, "Quadrature rule 4 points on a tetraedra", TETRA, 4, 2)
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
std::shared_ptr< std::vector< Int > > M_isOnProc
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.
QuadratureRule - The basis class for storing and accessing quadrature rules.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191