LifeV
FSIApplyOperatorNonConforming.cpp
Go to the documentation of this file.
1 #include <lifev/fsi_blocks/solver/FSIApplyOperatorNonConforming.hpp>
2 
3 #include <lifev/core/util/Displayer.hpp>
4 #include <lifev/core/util/LifeChrono.hpp>
5 
6 
7 namespace LifeV
8 {
9 namespace Operators
10 {
11 //===========================================================================//
12 // Constructors
13 //===========================================================================//
14 
16  M_label("FSIApplyOperatorNonConforming"),
17  M_useTranspose(false),
18  M_useBDFStructure (false)
19 {
20 
21 }
22 
24 {
25 
26 }
27 
28 // show information about the class
30 {
31 
32 }
33 
34 void
36 {
37  M_monolithicMap = monolithicMap;
38 }
39 
40 void
42  const mapEpetraPtr_Type& fluid_pressure_map,
43  const mapEpetraPtr_Type& structure_displacement_map,
44  const mapEpetraPtr_Type& lagrange_multipliers_map,
45  const mapEpetraPtr_Type& ALE_map)
46 {
47  // Setting maps
48  M_u_map = fluid_velocity_map;
49  M_p_map = fluid_pressure_map;
50  M_ds_map = structure_displacement_map;
51  M_lambda_map = lagrange_multipliers_map;
52  M_ale_map = ALE_map;
53 
54  // Setting offsets
55  M_fluidVelocity = M_u_map->mapSize();
56  M_fluid = M_fluidVelocity + M_p_map->mapSize();
57  M_structure = M_fluid + M_ds_map->mapSize();
58  M_lambda = M_structure + M_lambda_map->mapSize();
59 
60  // Initialize Vectors
61  M_X_velocity.reset( new VectorEpetra_Type (*M_u_map, Unique) );
62  M_X_pressure.reset( new VectorEpetra_Type (*M_p_map, Unique) );
63  M_X_displacement.reset( new VectorEpetra_Type (*M_ds_map, Unique) );
64  M_X_lambda.reset( new VectorEpetra_Type (*M_lambda_map, Unique) );
65  M_X_geometry.reset( new VectorEpetra_Type (*M_ale_map, Unique) );
66 
67  M_Y_velocity.reset( new VectorEpetra_Type (*M_u_map, Unique) );
68  M_Y_pressure.reset( new VectorEpetra_Type (*M_p_map, Unique) );
69  M_Y_displacement.reset( new VectorEpetra_Type (*M_ds_map, Unique) );
70  M_Y_lambda.reset( new VectorEpetra_Type (*M_lambda_map, Unique) );
71  M_Y_geometry.reset( new VectorEpetra_Type (*M_ale_map, Unique) );
72 }
73 
74 void
76  const matrixEpetraPtr_Type & shapePressure)
77 {
78  M_shapeVelocity = shapeVelocity;
79  M_shapePressure = shapePressure;
80 }
81 
82 void
84  const matrixEpetraPtr_Type & block01,
85  const matrixEpetraPtr_Type & block10)
86 {
87  M_F_00 = block00;
88  M_F_01 = block01;
89  M_F_10 = block10;
90  M_useStabilization = false;
91 }
92 
93 void
95  const matrixEpetraPtr_Type & block01,
96  const matrixEpetraPtr_Type & block10,
97  const matrixEpetraPtr_Type & block11)
98 {
99  M_F_00 = block00;
100  M_F_01 = block01;
101  M_F_10 = block10;
102  M_F_11 = block11;
103  M_useStabilization = true;
104 }
105 
106 void
108  interpolationPtr_Type structureToFluid,
109  bool useMasses)
110 {
111  M_FluidToStructureInterpolant = fluidToStructure;
112  M_StructureToFluidInterpolant = structureToFluid;
113  M_useMasses = useMasses;
114 }
115 
116 void
118 {
119  Teuchos::RCP< Teuchos::ParameterList > belosList = Teuchos::rcp ( new Teuchos::ParameterList );
120  belosList = Teuchos::getParametersFromXmlFile ( "SolverParamList_rbf3d.xml" );
121 
122  // Preconditioner
123  prec_Type* precRawPtr;
124  basePrecPtr_Type precPtr;
125  precRawPtr = new prec_Type;
126  precRawPtr->setDataFromGetPot ( M_datafile, "prec" );
127  precPtr.reset ( precRawPtr );
128 
129  // Linear Solver
130  LinearSolver solver;
131  solver.setCommunicator ( M_comm );
132  solver.setParameters ( *belosList );
133  solver.setPreconditioner ( precPtr );
134 
135  // Solution
136  Y->zero();
137 
138  // Solve system
139  solver.setOperator ( M_fluid_interface_mass );
140  solver.setRightHandSide ( X );
141  solver.solve ( Y );
142 }
143 
144 void
145 FSIApplyOperatorNonConforming::setInterfaceMassMatrices ( const matrixEpetraPtr_Type & fluid_interface_mass,
146  const matrixEpetraPtr_Type & structure_interface_mass)
147 {
148  M_fluid_interface_mass = fluid_interface_mass;
149  M_structure_interface_mass = structure_interface_mass;
150 }
151 
152 int
153 FSIApplyOperatorNonConforming::Apply(const vector_Type & X, vector_Type & Y) const
154 {
155  ASSERT_PRE(X.NumVectors() == Y.NumVectors(), "X and Y must have the same number of vectors");
156 
157 // Input vector
158 
159  const VectorEpetra_Type X_vectorEpetra(X, M_monolithicMap, Unique);
160 
161 // X_vectorEpetra.spy("input_apply");
162 
163  //! Extract each component of the input vector
164  M_X_velocity->zero();
165  M_X_velocity->subset(X_vectorEpetra, *M_u_map, 0, 0);
166 
167  M_X_pressure->zero();
168  M_X_pressure->subset(X_vectorEpetra, *M_p_map, M_fluidVelocity, 0 );
169 
170  M_X_displacement->zero();
171  M_X_displacement->subset(X_vectorEpetra, *M_ds_map, M_fluid, 0 );
172 
173  M_X_lambda->zero();
174  M_X_lambda->subset(X_vectorEpetra, *M_lambda_map, M_structure, 0 );
175 
176  M_X_geometry->zero();
177  M_X_geometry->subset(X_vectorEpetra, *M_ale_map, M_lambda , 0 );
178 
179  // M_X_lambda is defined just at the fluid interface, but for coding reasons
180  // I need to have it on the whole fluid domain, i.e., vector of zeros with
181  // nonzero entries only at the interface
182  VectorEpetraPtr_Type lambda_omega_f( new VectorEpetra_Type (*M_u_map) );
183  lambda_omega_f->zero();
184 
185  M_FluidToStructureInterpolant->expandGammaToOmega_Known(M_X_lambda, lambda_omega_f);
186 
187  //----------------------------------------------------------//
188  // Applying the Jacobian to the fluid velocity and pressure //
189  //----------------------------------------------------------//
190 
191  M_Y_velocity->zero();
192  M_Y_pressure->zero();
193 
194  if ( M_useStabilization )
195  {
196  if ( M_useShapeDerivatives )
197  {
198  *M_Y_velocity = (*M_F_00) * (*M_X_velocity ) + (*M_F_01) * (*M_X_pressure) + *lambda_omega_f + (*M_shapeVelocity) * (*M_X_geometry);
199  *M_Y_pressure = (*M_F_10) * (*M_X_velocity ) + (*M_F_11) * (*M_X_pressure) + (*M_shapePressure) * (*M_X_geometry);
200  }
201  else
202  {
203  *M_Y_velocity = (*M_F_00) * (*M_X_velocity ) + (*M_F_01) * (*M_X_pressure) + *lambda_omega_f;
204  *M_Y_pressure = (*M_F_10) * (*M_X_velocity ) + (*M_F_11) * (*M_X_pressure);
205  }
206  }
207  else
208  {
209  if ( M_useShapeDerivatives )
210  {
211  *M_Y_velocity = (*M_F_00) * (*M_X_velocity ) + (*M_F_01) * (*M_X_pressure) + *lambda_omega_f + (*M_shapeVelocity) * (*M_X_geometry);
212  *M_Y_pressure = (*M_F_10) * (*M_X_velocity ) + (*M_shapePressure) * (*M_X_geometry);
213  }
214  else
215  {
216  *M_Y_velocity = (*M_F_00) * (*M_X_velocity ) + (*M_F_01) * (*M_X_pressure) + *lambda_omega_f;
217  *M_Y_pressure = (*M_F_10) * (*M_X_velocity );
218  }
219  }
220 
221  //-----------------------------------------------------//
222  // Applying the Jacobian to the structure displacement //
223  //-----------------------------------------------------//
224 
225  M_Y_displacement->zero();
226  *M_Y_displacement = *M_S * ( *M_X_displacement );
227 
228  // From weak to strong form of the stresses lambda,
229  // need to apply the inverse of the fluid interface
230  // mass
231 
232  if ( M_useMasses )
233  {
234  VectorEpetraPtr_Type X_lambda_strong ( new VectorEpetra_Type ( *M_lambda_map ) );
235  X_lambda_strong->zero();
236  applyInverseInterfaceFluidMass(M_X_lambda, X_lambda_strong);
237 
238  // Interpolate from fluid to structure interface,
239  // need to have vector defined on omega fluid
240  VectorEpetraPtr_Type X_lambda_strong_omega_f ( new VectorEpetra_Type ( *M_u_map ) );
241  X_lambda_strong_omega_f->zero();
242 
243  M_FluidToStructureInterpolant->expandGammaToOmega_Known( X_lambda_strong, X_lambda_strong_omega_f );
244 
245  M_FluidToStructureInterpolant->updateRhs(X_lambda_strong_omega_f);
246 
247  M_FluidToStructureInterpolant->interpolate();
248 
249  VectorEpetraPtr_Type X_lambda_strong_omega_s ( new VectorEpetra_Type ( *M_ds_map ) );
250 
251  X_lambda_strong_omega_s->zero();
252 
253  M_FluidToStructureInterpolant->solution(X_lambda_strong_omega_s);
254 
255  // Restrict X_lambda_strong_omega_s to Gamma S
256  VectorEpetraPtr_Type X_lambda_strong_gamma_s;
257 
258  M_StructureToFluidInterpolant->restrictOmegaToGamma_Known(X_lambda_strong_omega_s, X_lambda_strong_gamma_s);
259 
260  // From strong to weak residual on Gamma S
261  VectorEpetraPtr_Type X_lambda_weak_gamma_s ( new VectorEpetra_Type ( X_lambda_strong_gamma_s->map() ) );
262 
263  X_lambda_weak_gamma_s->zero();
264 
265  *X_lambda_weak_gamma_s = *M_structure_interface_mass * (*X_lambda_strong_gamma_s);
266 
267  // Expand vector to whole omega S
268  VectorEpetraPtr_Type X_lambda_weak_omega_s ( new VectorEpetra_Type ( *M_ds_map ) );
269 
270  X_lambda_weak_omega_s->zero();
271 
272  M_StructureToFluidInterpolant->expandGammaToOmega_Known( X_lambda_weak_gamma_s, X_lambda_weak_omega_s );
273 
274  *M_Y_displacement -= *X_lambda_weak_omega_s;
275  }
276  else
277  {
278  M_FluidToStructureInterpolant->updateRhs(lambda_omega_f);
279 
280  M_FluidToStructureInterpolant->interpolate();
281 
282  VectorEpetraPtr_Type X_lambda_weak_omega_s ( new VectorEpetra_Type ( *M_ds_map ) );
283 
284  M_FluidToStructureInterpolant->solution(X_lambda_weak_omega_s);
285 
286  *M_Y_displacement -= *X_lambda_weak_omega_s;
287  }
288 
289  //---------------------------------------//
290  // Applying the Jacobian to the stresses //
291  //---------------------------------------//
292 
293  M_Y_lambda->zero();
294 
295  VectorEpetraPtr_Type M_Y_lambda_tmp;
296 
297  M_FluidToStructureInterpolant->restrictOmegaToGamma_Known(M_X_velocity, M_Y_lambda_tmp);
298 
299  *M_Y_lambda += *M_Y_lambda_tmp;
300 
301  VectorEpetraPtr_Type structure_vel( new VectorEpetra_Type ( *M_ds_map ) );
302  structure_vel->zero();
303 
304  if ( M_useBDFStructure )
305  {
306  *structure_vel += ( M_coefficientBDF / M_timeStep * (*M_X_displacement) );
307  }
308  else
309  {
310  *structure_vel += ( M_gamma / (M_timeStep*M_beta) * (*M_X_displacement) );
311  }
312 
313  M_StructureToFluidInterpolant->updateRhs(structure_vel);
314  M_StructureToFluidInterpolant->interpolate();
315 
316  VectorEpetraPtr_Type structure_vel_omega_f ( new VectorEpetra_Type ( *M_u_map ) );
317  structure_vel_omega_f->zero();
318  M_StructureToFluidInterpolant->solution(structure_vel_omega_f);
319 
320  VectorEpetraPtr_Type structure_vel_gamma_f ( new VectorEpetra_Type ( *M_lambda_map ) );
321  structure_vel_gamma_f->zero();
322 
323  M_FluidToStructureInterpolant->restrictOmegaToGamma_Known(structure_vel_omega_f, structure_vel_gamma_f);
324 
325  *M_Y_lambda -= *structure_vel_gamma_f;
326 
327  //----------------------------------//
328  // Applying the Jacobian to the ALE //
329  //----------------------------------//
330 
331  M_Y_geometry->zero();
332  *M_Y_geometry = ( *M_G ) * ( *M_X_geometry );
333 
334  M_StructureToFluidInterpolant->updateRhs(M_X_displacement);
335  M_StructureToFluidInterpolant->interpolate();
336 
337  VectorEpetraPtr_Type tmp ( new VectorEpetra_Type ( *M_ale_map ) );
338  tmp->zero();
339  M_StructureToFluidInterpolant->solution(tmp);
340 
341  *M_Y_geometry -= *tmp;
342 
343  // Output vector
344  VectorEpetra_Type Y_vectorEpetra(Y, M_monolithicMap, Unique);
345  Y_vectorEpetra.zero();
346 
347  //! Copy the single contributions into the optput vector
348  Y_vectorEpetra.subset(*M_Y_velocity, M_Y_velocity->map(), 0, 0 );
349  Y_vectorEpetra.subset(*M_Y_pressure, M_Y_pressure->map(), 0, M_fluidVelocity );
350  Y_vectorEpetra.subset(*M_Y_displacement, M_Y_displacement->map(), 0, M_fluid );
351  Y_vectorEpetra.subset(*M_Y_lambda, M_Y_lambda->map(), 0, M_structure );
352  Y_vectorEpetra.subset(*M_Y_geometry, M_Y_geometry->map(), 0, M_lambda );
353 
354 // Y_vectorEpetra.spy("output_apply");
355 
356 // std::cout << "Spy input e output apply completato, digita numero ";
357 // int aaaaaaa;
358 // std::cin >> aaaaaaa;
359 
360  Y = dynamic_cast<Epetra_MultiVector &>( Y_vectorEpetra.epetraVector() );
361 
362  return 0;
363 }
364 
365 } /* end namespace Operators */
366 
367 } /*end namespace */
void applyInverseInterfaceFluidMass(const VectorEpetraPtr_Type &X, VectorEpetraPtr_Type &Y) const
Apply the inverse of the fluid interface mass to a vector.
void setInterpolants(interpolationPtr_Type fluidToStructure, interpolationPtr_Type structureToFluid, bool useMasses)
Copy the pointer of the interpolation objects.
void setFluidBlocks(const matrixEpetraPtr_Type &block00, const matrixEpetraPtr_Type &block01, const matrixEpetraPtr_Type &block10)
Set the blocks of the fluid Jacobian when stabilization is not used.
interpolationPtr_Type M_FluidToStructureInterpolant
Interpolants.
#define ASSERT_PRE(X, A)
Definition: LifeAssert.hpp:96
A class which implements the application of the FSI Jacobian matrix to a given vector when nonconform...
void setMonolithicMap(const mapEpetraPtr_Type &monolithicMap)
Set the monolithic map.
void setFluidBlocks(const matrixEpetraPtr_Type &block00, const matrixEpetraPtr_Type &block01, const matrixEpetraPtr_Type &block10, const matrixEpetraPtr_Type &block11)
Set the blocks of the fluid Jacobian when stabilization is used.
void setShapeDerivativesBlocks(const matrixEpetraPtr_Type &ShapeVelocity, const matrixEpetraPtr_Type &ShapePressure)
Set the shape derivatives.
void setMaps(const mapEpetraPtr_Type &fluid_velocity_map, const mapEpetraPtr_Type &fluid_pressure_map, const mapEpetraPtr_Type &structure_displacement_map, const mapEpetraPtr_Type &lagrange_multipliers_map, const mapEpetraPtr_Type &ALE_map)
Set the map of each component of the residual.
bool M_useStabilization
If using the stabilization for the fluid.