LifeV
FSIMonolithicGE.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 /*!
29  @file
30  @brief A short description of the file content
31 
32  @author Paolo Crosetto <crosetto@iacspc70.epfl.ch>
33  @date 26 Jul 2010
34 
35  A more detailed description of the file (if necessary)
36  */
37 
38 #include <lifev/core/LifeV.hpp>
39 
40 #include <lifev/fsi/solver/FSIMonolithicGE.hpp>
41 
42 namespace LifeV
43 {
44 
45 // ===================================================
46 // Constructors & Destructor
47 // ===================================================
48 
49 
50 void FSIMonolithicGE::setupFluidSolid ( UInt const fluxes )
51 {
52  super_Type::setupFluidSolid ( fluxes );
53 
54  M_meshMotion.reset (new FSIOperator::meshMotion_Type (*M_mmFESpace,
55  M_epetraComm) );
56 
57  M_fluid.reset (new FSIOperator::fluid_Type (M_data->dataFluid(),
58  *M_uFESpace,
59  *M_pFESpace,
60  M_epetraComm,
61  *M_monolithicMap,
62  fluxes) );
63 
64  M_rhs.reset (new vector_Type (*this->M_monolithicMap) );
65  M_rhsFull.reset (new vector_Type (*this->M_monolithicMap) );
66  M_beta.reset (new vector_Type (M_uFESpace->map() ) );
67 
68  M_solid.reset (new solid_Type() );
69 
70  M_solid->setup (M_data->dataSolid(),
71  M_dFESpace,
72  M_dETFESpace,
73  M_epetraComm,
74  M_dFESpace->mapPtr(),
75  UInt (0)
76  );
77 }
78 
79 
80 
81 
82 void FSIMonolithicGE::setupDOF()
83 {
84  M_bcvStructureDispToHarmonicExtension.reset ( new BCVectorInterface );
85  super_Type::setupDOF();
86 }
87 
88 void
89 FSIMonolithicGE::setupSystem( )
90 {
91  super_Type::setupSystem();
92  M_meshMotion->setUp ( M_dataFile );
93 }
94 
95 void
96 FSIMonolithicGE::updateSystem()
97 {
98  super_Type::updateSystem();
99 }
100 
101 
102 void
103 FSIMonolithicGE::evalResidual ( vector_Type& res,
104  const vector_Type& disp,
105  const UInt iter )
106 {
107  // disp here is the current solution guess (u,p,ds)
108  // disp is already "extrapolated", the main is doing it.
109 
110  if (iter == 0)
111  {
112 
113  // Solve HE
114  this->iterateMesh (disp);
115 
116  // Update displacement
117 
118  M_ALETimeAdvance->updateRHSFirstDerivative (M_data->dataFluid()->dataTime()->timeStep() );
119 
120  vector_Type meshDispRepeated ( M_meshMotion->disp(), Repeated );
121  this->moveMesh (meshDispRepeated);
122 
123  //here should use extrapolationFirstDerivative instead of velocity
124  vector_Type meshVelocityRepeated ( this->M_ALETimeAdvance->firstDerivative ( M_meshMotion->disp() ), Repeated );
125  vector_Type interpolatedMeshVelocity (this->M_uFESpace->map() );
126 
127  interpolateVelocity ( meshVelocityRepeated, interpolatedMeshVelocity );
128  // maybe we should use disp here too...
129  M_fluidTimeAdvance->extrapolation (*M_beta);
130  *M_beta -= interpolatedMeshVelocity; // convective term, u^* - w^*
131 
132  // in MonolithicGI here it used M_uk, which comes from disp
133  assembleSolidBlock (iter, disp);
134  assembleFluidBlock (iter, disp);
135  *M_rhsFull = *M_rhs;
136 
137  applyBoundaryConditions();
138  }
139  super_Type::evalResidual ( disp, M_rhsFull, res, M_diagonalScale);
140 }
141 
142 void
143 FSIMonolithicGE::iterateMesh (const vector_Type& disp)
144 {
145  vector_Type lambdaFluid (*M_interfaceMap, Unique);
146 
147  monolithicToInterface (lambdaFluid, disp);
148 
149  lambdaFluid *= (M_solid->rescaleFactor() );
150 
151  this->setLambdaFluid (lambdaFluid); // it must be _disp restricted to the interface
152 
153  M_meshMotion->iterate (*M_BCh_mesh);
154 
155 }
156 
157 void FSIMonolithicGE::applyBoundaryConditions( )
158 {
159 
160  if ( !M_BCh_u->bcUpdateDone() )
161  {
162  M_BCh_u->bcUpdate ( *M_uFESpace->mesh(), M_uFESpace->feBd(), M_uFESpace->dof() );
163  }
164  M_BCh_d->setOffset (M_offset);
165  if ( !M_BCh_d->bcUpdateDone() )
166  {
167  M_BCh_d->bcUpdate ( *M_dFESpace->mesh(), M_dFESpace->feBd(), M_dFESpace->dof() );
168  }
169 
170  M_monolithicMatrix->setRobin ( M_robinCoupling, M_rhsFull );
171  M_precPtr->setRobin (M_robinCoupling, M_rhsFull);
172 
173  if (!this->M_monolithicMatrix->set() )
174  {
175  M_BChs.push_back (M_BCh_d);
176  M_BChs.push_back (M_BCh_u);
177  M_FESpaces.push_back (M_dFESpace);
178  M_FESpaces.push_back (M_uFESpace);
179 
180  M_monolithicMatrix->push_back_matrix (M_solidBlockPrec, false);
181  M_monolithicMatrix->push_back_matrix (M_fluidBlock, true);
182  M_monolithicMatrix->setConditions (M_BChs);
183  M_monolithicMatrix->setSpaces (M_FESpaces);
184  M_monolithicMatrix->setOffsets (2, M_offset, 0);
185  M_monolithicMatrix->coupler (M_monolithicMap, M_dofStructureToFluid->localDofMap(), M_numerationInterface, M_data->dataFluid()->dataTime()->timeStep(), M_solidTimeAdvance->coefficientFirstDerivative ( 0 ), M_solid->rescaleFactor() );
186  }
187  else
188  {
189  M_monolithicMatrix->replace_matrix (M_fluidBlock, 1);
190  M_monolithicMatrix->replace_matrix (M_solidBlockPrec, 0);
191  }
192 
193  super_Type::checkIfChangedFluxBC ( M_monolithicMatrix );
194 
195  M_monolithicMatrix->blockAssembling();
196  M_monolithicMatrix->applyBoundaryConditions (dataFluid()->dataTime()->time(), M_rhsFull);
197 
198  M_monolithicMatrix->GlobalAssemble();
199  //M_monolithicMatrix->matrix()->spy("M");
200 }
201 
202 void FSIMonolithicGE::setALEVectorInStencil (const vectorPtr_Type& fluidDisp, const UInt /*iter*/, const bool /*lastVector*/)
203 {
204 
205  //ALE problem
206  //The shared_pointer for the vectors has to be transformed into a pointer to VectorEpetra
207  //That is the type of pointers that are used in TimeAdvance
208  vector_Type* normalPointerToALEVector ( new vector_Type (*fluidDisp) );
209  (M_ALETimeAdvance->stencil() ).push_back ( normalPointerToALEVector );
210 
211 }
212 
213 void FSIMonolithicGE::updateSolution ( const vector_Type& solution )
214 {
215  super_Type::updateSolution ( solution );
216 
217  //This updateRHSFirstDerivative has to be done before the shiftRight
218  //In fact it updates the right hand side of the velocity using the
219  //previous times. The method velocity() uses it and then, the computation
220  //of the velocity is done using the current time and the previous times.
221  //M_ALETimeAdvance->updateRHSFirstDerivative ( M_data->dataFluid()->dataTime()->timeStep() );
222  M_ALETimeAdvance->shiftRight ( this->M_meshMotion->disp() );
223 }
224 
225 
226 // ===================================================
227 //! Products registration
228 // ===================================================
229 
230 bool FSIMonolithicGE::S_register = FSIFactory_Type::instance().registerProduct ( "monolithicGE", &FSIMonolithicGE::instantiate ) &&
231  BlockPrecFactory::instance().registerProduct ("ComposedDNND" , &MonolithicBlockComposedDNND::createComposedDNND) &&
232  BlockPrecFactory::instance().registerProduct ("AdditiveSchwarz" , &MonolithicBlockMatrix::createAdditiveSchwarz) &&
233  MonolithicBlockMatrix::Factory_Type::instance().registerProduct ("AdditiveSchwarz" , &MonolithicBlockMatrix::createAdditiveSchwarz ) &&
234  BlockPrecFactory::instance().registerProduct ("AdditiveSchwarzRN" , &MonolithicBlockMatrixRN::createAdditiveSchwarzRN ) &&
235  MonolithicBlockMatrix::Factory_Type::instance().registerProduct ("AdditiveSchwarzRN" , &MonolithicBlockMatrixRN::createAdditiveSchwarzRN ) &&
236  BlockPrecFactory::instance().registerProduct ("ComposedDN" , &MonolithicBlockComposedDN::createComposedDN ) &&
237  BlockPrecFactory::instance().registerProduct ("ComposedDN2" , &MonolithicBlockComposedDN::createComposedDN2 );
238 
239 } // Namespace LifeV