LifeV
FSIFixedPoint.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 #include <lifev/fsi/solver/FSIFixedPoint.hpp>
28 
29 namespace LifeV
30 {
31 
32 // ===================================================
33 // Constructors & Destructor
34 // ===================================================
35 
37  super(),
39  M_rhsNew(),
40  M_beta()
41 {
42 }
43 
44 
46 {}
47 
48 
49 // ===================================================
50 // Methods
51 // ===================================================
52 
53 void FSIFixedPoint::solveJac (vector_Type& muk,
54  const vector_Type& res,
55  const Real /*_linearRelTol*/)
56 {
57  // M_nonLinearAitken.restart();
58 
59  if (M_data->algorithm() == "RobinNeumann")
60  {
61  muk = res;
62  }
63  else
64  {
65  muk = M_nonLinearAitken.computeDeltaLambdaScalar (this->lambdaSolidOld(), res);
66  }
67 }
68 
69 void FSIFixedPoint::evalResidual (vector_Type& res, const vector_Type& disp, UInt iter)
70 {
71 
72  if (this->isSolid() )
73  {
74  std::cout << "*** Residual computation g(x_" << iter << " )";
75  if (iter == 0)
76  {
77  std::cout << " [NEW TIME STEP] ";
78  }
79  std::cout << std::endl;
80  }
81 
82  this->setLambdaSolidOld (disp);
83 
84  eval (disp, iter);
85 
86  res = disp;
87  res -= this->lambdaSolid();
88 }
89 
90 
91 void
93 {
94  super::setLinearFluid (false);
95  super::setLinearSolid (false);
96 
97  super::setupFEspace();
98 }
99 
100 
101 
102 void
104 {
105  // call FSI setup()
106 
107  debugStream ( 6205 ) << "Setting up the FSI problem \n";
108 
109  super::setLinearFluid (false);
110  super::setLinearSolid (false);
111 
112  super::setupFluidSolid();
113 
114  if ( this->isFluid() )
115  {
116  M_rhsNew.reset (new vector_Type (this->M_fluid->getMap() ) );
117  M_beta.reset (new vector_Type (this->M_fluid->getMap() ) );
118  }
119 
120 }
121 
122 void
123 FSIFixedPoint::setDataFile ( GetPot const& dataFile )
124 {
125  super::setDataFile ( dataFile );
126 
127  M_nonLinearAitken.setDefaultOmega (M_data->defaultOmega(), 0.001);
128  M_nonLinearAitken.setOmegaRange ( M_data->OmegaRange() );
129 
130  if ( M_data->algorithm() == "RobinNeumann" )
131  {
132  M_nonLinearAitken.setDefaultOmega (-1, 1);
133  }
134 
135 }
136 
137 // ===================================================
138 // Private Methods
139 // ===================================================
140 
141 void FSIFixedPoint::eval ( const vector_Type& _disp,
142  UInt iter)
143 {
144  // If M_data->updateEvery() == 1, normal fixedPoint algorithm
145  // If M_data->updateEvery() > 1, recompute computational domain every updateEvery iterations (transpiration)
146  // If M_data->updateEvery() <= 0, recompute computational domain and matrices only at first subiteration (semi-implicit)
147  bool recomputeMatrices ( iter == 0 || ( M_data->updateEvery() > 0 && iter % M_data->updateEvery() == 0 ) );
148 
149  std::cout << "recomputeMatrices = " << recomputeMatrices << " == " << true
150  << "; iter = " << iter
151  << "; updateEvery = " << M_data->updateEvery() << std::endl;
152 
153  if (iter == 0 && this->isFluid() )
154  {
155  M_nonLinearAitken.restart();
156  this->M_fluid->resetPreconditioner();
157  //this->M_solid->resetPrec();
158  }
159 
160  M_epetraWorldComm->Barrier();
161 
162  // possibly unsafe when using more cpus,
163  this->setLambdaFluid (_disp);
164 
165  //Change in sign in the residual for RN:
166  // if(this->algorithm()=="RobinNeumann") this->setMinusSigmaFluid( sigmaSolidUnique );
167  if (M_data->algorithm() == "RobinNeumann")
168  {
169  this->setMinusSigmaFluid ( this->sigmaSolid() );
170  }
171 
172 
173  vector_Type sigmaFluidUnique (this->sigmaFluid().map(), Unique);
174 
175  if (this->isFluid() )
176  {
177  this->M_meshMotion->iterate (*M_BCh_mesh);
178 
179  // this->transferMeshMotionOnFluid(M_meshMotion->disp(),
180  // this->veloFluidMesh());
181  //this->veloFluidMesh() -= this->dispFluidMeshOld();
182  // this->veloFluidMesh() *= 1./(M_data->dataFluid()->dataTime()->timeStep());
183 
184  // copying displacement to a repeated indeces displacement, otherwise the mesh wont know
185  // the value of the displacement for some points
186 
187  // vector_Type const meshDisplacement( M_meshMotion->disp(), Repeated );
188  // this->moveMesh(meshDisplacement);
189  /*
190  vector_Type const meshDisplacement( M_meshMotion->dispDiff(), Repeated );
191  this->moveMesh(meshDispDiff);
192  */
193 
194  *M_beta = 0;
195 
196  vector_Type meshDisp ( M_meshMotion->disp(), Repeated );
197  this->moveMesh (meshDisp);
198 
199  if (iter == 0)
200  {
201  M_fluidTimeAdvance->extrapolation ( *M_beta); //explicit treatment of u
202  }
203  else
204  {
205  *M_beta += *this->M_fluid->solution();
206  }
207 
208  vector_Type meshVelocity ( M_meshMotion->disp(), Repeated );
209  meshVelocity = M_ALETimeAdvance->firstDerivative (meshDisp); //implicit treatment of w (because I already did the shiftRight)
210  this->transferMeshMotionOnFluid (meshVelocity,
211  this->veloFluidMesh() );
212 
213  *M_beta -= this->veloFluidMesh();
214 
215  double alpha = M_fluidTimeAdvance->coefficientFirstDerivative ( 0 ) / M_data->dataFluid()->dataTime()->timeStep();
216 
217  //*M_rhsNew = *this->M_rhs;
218  //*M_rhsNew *= alpha;
219 
220 
221  //the conservative formulation as it is now is of order 1. To have higher order (TODO) we need to store the mass matrices computed at the previous time steps.
222  if (M_data->dataFluid()->conservativeFormulation() )
223  {
224  *M_rhs = M_fluidMassTimeAdvance->rhsContributionFirstDerivative();
225  }
226  if (recomputeMatrices)
227  {
228 
229  this->M_fluid->updateSystem ( alpha, *M_beta, *M_rhs );
230  }
231  else
232  {
233  this->M_fluid->updateRightHandSide ( *M_rhs );
234  }
235  if (!M_data->dataFluid()->conservativeFormulation() )
236  {
237  *M_rhs = M_fluid->matrixMass() * M_fluidTimeAdvance->rhsContributionFirstDerivative();
238  this->M_fluid->updateRightHandSide ( *M_rhs );
239  }
240 
241  // if(this->algorithm()=="RobinNeumann") this->updatealphaf(this->veloFluidMesh());// this->setAlphaf();
242 
243  this->M_fluid->iterate ( *M_BCh_u );
244 
245  std::cout << "Finished iterate, transfering to interface \n" << std::flush;
246 
247  this->transferFluidOnInterface (this->M_fluid->residual(), sigmaFluidUnique);
248  }
249 
250  M_epetraWorldComm->Barrier();
251 
252  if ( true && this->isFluid() )
253  {
254  vector_Type vel (this->fluid().velocityFESpace().map() );
255  vector_Type press (this->fluid().pressureFESpace().map() );
256 
257  vel.subset (*this->M_fluid->solution() );
258  press.subset (*this->M_fluid->solution(), this->fluid().velocityFESpace().dim() *this->fluid().pressureFESpace().fieldDim() );
259 
260  std::cout << "norm_inf( vel ) " << vel.normInf() << std::endl;
261  std::cout << "norm_inf( press ) " << press.normInf() << std::endl;
262 
263  }
264 
265  this->setSigmaFluid ( sigmaFluidUnique );
266  this->setSigmaSolid ( sigmaFluidUnique );
267 
268  M_epetraWorldComm->Barrier();
269 
270 
271  vector_Type lambdaSolidUnique (this->lambdaSolid().map(), Unique);
272  vector_Type lambdaDotSolidUnique (this->lambdaDotSolid().map(), Unique);
273  vector_Type sigmaSolidUnique (this->sigmaSolid().map(), Unique);
274  if (this->isSolid() )
275  {
276  this->M_solid->iterate ( M_BCh_d );
277  this->transferSolidOnInterface (this->M_solid->displacement(), lambdaSolidUnique);
278  this->transferSolidOnInterface ( M_solidTimeAdvance->firstDerivative ( this->solid().displacement() ), lambdaDotSolidUnique );
279  this->transferSolidOnInterface (this->M_solid->residual(), sigmaSolidUnique);
280  }
281 
282  this->setLambdaSolid ( lambdaSolidUnique );
283  this->setLambdaDotSolid ( lambdaDotSolidUnique );
284  this->setSigmaSolid ( sigmaSolidUnique );
285 
286  M_epetraWorldComm->Barrier();
287 
288 
289  // Some displays:
290  Real norm;
291 
292  norm = _disp.normInf();
293  if (this->isSolid() && this->isLeader() )
294  {
295  std::cout << " ::: norm(disp ) = " << norm << std::endl;
296  }
297 
298  norm = this->lambdaSolid().normInf();
299  if (this->isSolid() && this->isLeader() )
300  {
301  std::cout << " ::: norm(dispNew ) = " << norm << std::endl;
302  }
303 
304  norm = this->lambdaDotSolid().normInf();
305  if (this->isSolid() && this->isLeader() )
306  {
307  std::cout << " ::: norm(velo ) = " << norm << std::endl;
308  }
309 
310  norm = this->sigmaFluid().normInf();
311  if (this->isSolid() && this->isLeader() )
312  {
313  std::cout << " ::: max Residual Fluid = " << norm << std::endl;
314  }
315 
316  norm = this->sigmaSolid().normInf();
317  if (this->isSolid() && this->isLeader() )
318  {
319  std::cout << " ::: max Residual Solid = " << norm << std::endl;
320  }
321 
322  if (this->isFluid() )
323  {
324  norm = M_fluid->residual().normInf();
325  if (this->isLeader() )
326  {
327  std::cout << "Max ResidualF = " << norm << std::endl;
328  }
329  }
330  if (this->isSolid() )
331  {
332  norm = M_solid->displacement().norm2();
333  if (this->isLeader() )
334  {
335  std::cout << "NL2 DiplacementS = " << norm << std::endl;
336  }
337 
338  norm = M_solid->residual().normInf();
339 
340  if (this->isLeader() )
341  {
342  std::cout << "Max ResidualS = " << norm << std::endl;
343  }
344  }
345 
346 }
347 
348 
349 
350 
352 {
353  FSIFactory_Type::instance().registerProduct ( "fixedPoint", &createFP );
354 
355  solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "linearVenantKirchhoff", &createVenantKirchhoffLinear );
356  solid_Type::material_Type::isotropicLaw_Type::StructureIsotropicMaterialFactory::instance().registerProduct ( "nonLinearVenantKirchhoff", &createVenantKirchhoffNonLinear );
357 
358 }
359 
360 } // Namespace LifeV
void registerMyProducts()
register the product for the factory
FSIFixedPoint()
Empty Constructor.
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
#define debugStream
Definition: LifeDebug.hpp:182
void setupFEspace()
sets the space discretization parameters
vectorPtr_Type M_rhsNew
double Real
Generic real data.
Definition: LifeV.hpp:175
NdebugStream noDebugStream(int=0, NdebugStream::stprintf=&printf)
Definition: LifeDebug.hpp:183
FSIFixedPont - Implementation of an FSI with fixed point iterations.
void setupFluidSolid()
setup of the fluid and solid solver classes
void solveJac(vector_Type &_muk, const vector_Type &_res, const Real _linearRelTol)
solves the Jacobian system
vectorPtr_Type M_beta
void setDataFile(GetPot const &data)
initializes the GetPot data file
~FSIFixedPoint()
Destructor.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
void eval(const vector_Type &disp, UInt status)