LifeV
MultiscaleModelFSI1D.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 File containing the Multiscale Model 1D
30  *
31  * @version 1.1
32  * @date 26-02-2010
33  * @author Gilles Fourestey <gilles.fourestey@epfl.ch>
34  *
35  * @version 1.2 and subsequents
36  * @date 23-04-2010
37  * @author Cristiano Malossi <cristiano.malossi@epfl.ch>
38  *
39  * @maintainer Cristiano Malossi <cristiano.malossi@epfl.ch>
40  */
41 
42 #include <lifev/multiscale/models/MultiscaleModelFSI1D.hpp>
43 
44 namespace LifeV
45 {
46 namespace Multiscale
47 {
48 
49 // ===================================================
50 // Constructors & Destructor
51 // ===================================================
55 #ifdef HAVE_HDF5
56  M_exporter ( new IOFile_Type() ),
57  M_importer ( new IOFile_Type() ),
58  M_exporterMesh ( new mesh_Type() ),
60 #endif
62  M_linearBC ( new bc_Type() ),
66  M_bcDelta (),
67  M_bcDeltaType (),
68  M_bcDeltaSide (),
69 #endif
70  M_data ( new data_Type() ),
71  M_bc ( new bcInterface_Type() ),
72  M_physics (),
73  M_flux (),
74  M_source (),
75  M_solver ( new solver_Type() ),
76  M_linearSolver (),
78  M_feSpace (),
79  M_solution_tn ( new solution_Type() ),
80  M_solution ( new solution_Type() )
81 {
82 
83 #ifdef HAVE_LIFEV_DEBUG
84  debugStream ( 8130 ) << "MultiscaleModelFSI1D::MultiscaleModelFSI1D() \n";
85 #endif
86 
87  M_type = FSI1D;
88 
89  //Define the maps of the OneDFSIModel objects
91 
92  //Register the objects
93  physics_Type::factoryPhysics_Type::instance().registerProduct ( OneDFSI::LinearPhysics, &createOneDFSIPhysicsLinear );
94  physics_Type::factoryPhysics_Type::instance().registerProduct ( OneDFSI::NonLinearPhysics, &createOneDFSIPhysicsNonLinear );
95 
96  flux_Type::factoryFlux_Type::instance().registerProduct ( OneDFSI::LinearFlux, &createOneDFSIFluxLinear );
97  flux_Type::factoryFlux_Type::instance().registerProduct ( OneDFSI::NonLinearFlux, &createOneDFSIFluxNonLinear );
98 
99  source_Type::factorySource_Type::instance().registerProduct ( OneDFSI::LinearSource, &createOneDFSISourceLinear );
100  source_Type::factorySource_Type::instance().registerProduct ( OneDFSI::NonLinearSource, &createOneDFSISourceNonLinear );
101 }
102 
103 // ===================================================
104 // MultiscaleModel Methods
105 // ===================================================
106 void
107 MultiscaleModelFSI1D::setupData ( const std::string& fileName )
108 {
109 
110 #ifdef HAVE_LIFEV_DEBUG
111  debugStream ( 8130 ) << "MultiscaleModelFSI1D::setupData( fileName ) \n";
112 #endif
113 
114  multiscaleModel_Type::setupData ( fileName );
115 
116  GetPot dataFile ( fileName );
117 
118  M_data->setup ( dataFile );
119  if ( M_globalData.get() )
120  {
121  setupGlobalData ( fileName );
122  }
123 
124  //1D Model Physics
125  M_physics = physicsPtr_Type ( physics_Type::factoryPhysics_Type::instance().createObject ( M_data->physicsType(), OneDFSI::physicsMap ) );
126  M_physics->setData ( M_data );
127 
128  //1D Model Flux
129  M_flux = fluxPtr_Type ( flux_Type::factoryFlux_Type::instance().createObject ( M_data->fluxType(), OneDFSI::fluxMap ) );
130  M_flux->setPhysics ( M_physics );
131 
132  //1D Model Source
133  M_source = sourcePtr_Type ( source_Type::factorySource_Type::instance().createObject ( M_data->sourceType(), OneDFSI::sourceMap ) );
134  M_source->setPhysics ( M_physics );
135 
136  //Linear Solver
137  M_linearSolver.reset ( new linearSolver_Type ( M_comm ) );
138  //M_linearSolver->setupPreconditioner( dataFile, "1D_Model/prec" );
139  M_linearSolver->setDataFromGetPot ( dataFile, "1D_Model/solver" );
140  M_linearSolver->setParameter ( "Verbose", false );
141  M_linearSolver->setParameters();
142 
143  //Linear Viscoelastic Solver
144  if ( M_data->viscoelasticWall() )
145  {
146  M_linearViscoelasticSolver.reset ( new linearSolver_Type ( M_comm ) );
147  M_linearViscoelasticSolver->setParametersList ( M_linearSolver->parametersList() );
148  M_linearViscoelasticSolver->setParameters();
149  }
150 
151  //1D Model Solver
152  M_solver->setCommunicator ( M_comm );
153  M_solver->setProblem ( M_physics, M_flux, M_source );
154  M_solver->setLinearSolver ( M_linearSolver );
155  M_solver->setLinearViscoelasticSolver ( M_linearViscoelasticSolver );
156 
157  //BC - We need to create the BCHandler before using it
158  M_bc->createHandler();
159  //M_bc->fillHandler( fileName, "1D_Model" );
160 
161  //Exporters
162  M_data->setPostprocessingDirectory ( multiscaleProblemFolder );
163  M_data->setPostprocessingFile ( multiscaleProblemPrefix + "_Model_" + number2string ( M_ID ) + "_" + number2string ( multiscaleProblemStep ) );
164 
165 #ifdef HAVE_HDF5
166  M_exporterMesh->setComm ( M_comm );
167  regularMesh1D ( *M_exporterMesh, 1, M_data->numberOfElements(), false, M_data->length(), 0 );
168 
169  M_exporter->setDataFromGetPot ( dataFile );
170  M_exporter->setPrefix ( multiscaleProblemPrefix + "_Model_" + number2string ( M_ID ) + "_" + number2string ( multiscaleProblemStep ) );
171  M_exporter->setPostDir ( multiscaleProblemFolder );
172 
173  M_importer->setDataFromGetPot ( dataFile );
174  M_importer->setPrefix ( multiscaleProblemPrefix + "_Model_" + number2string ( M_ID ) + "_" + number2string ( multiscaleProblemStep - 1 ) );
175  M_importer->setPostDir ( multiscaleProblemFolder );
176 #endif
177 
178 }
179 
180 void
182 {
183 
184 #ifdef HAVE_LIFEV_DEBUG
185  debugStream ( 8130 ) << "MultiscaleModelFSI1D::setupModel() \n";
186 #endif
187 
188  //FEspace
190 
191  //Setup solution
192  M_solver->setupSolution ( *M_solution );
193  M_solver->setupSolution ( *M_solution_tn );
194 
195  //Set default BC (has to be called after setting other BC)
196  M_bc->handler()->setDefaultBC();
197  M_bc->setPhysicalSolver ( M_solver );
198  M_bc->setSolution ( M_solution );
199  M_bc->setFluxSource ( M_flux, M_source );
200 
201  //Post-processing
202 #ifdef HAVE_HDF5
203  M_exporter->setMeshProcId ( M_exporterMesh, M_comm->MyPID() );
204 
205  DOF tmpDof ( *M_exporterMesh, M_feSpace->refFE() );
206  std::vector<Int> myGlobalElements ( tmpDof.globalElements ( *M_exporterMesh ) );
207  MapEpetra map ( -1, myGlobalElements.size(), &myGlobalElements[0], M_comm );
208  M_solver->setupSolution ( *M_exporterSolution, map, true );
209 
210  M_exporter->addVariable ( IOData_Type::ScalarField, "Area ratio (fluid)", M_feSpace, (*M_exporterSolution) ["AoverA0minus1"], static_cast <UInt> ( 0 ) );
211  M_exporter->addVariable ( IOData_Type::ScalarField, "Flow rate (fluid)", M_feSpace, (*M_exporterSolution) ["Q"], static_cast <UInt> ( 0 ) );
212  //M_exporter->addVariable( IOData_Type::ScalarField, "W1", M_feSpace, (*M_exporterSolution)["W1"], static_cast <UInt> ( 0 ), M_feSpace->dof().numTotalDof() );
213  //M_exporter->addVariable( IOData_Type::ScalarField, "W2", M_feSpace, (*M_exporterSolution)["W2"], static_cast <UInt> ( 0 ), M_feSpace->dof().numTotalDof() );
214  M_exporter->addVariable ( IOData_Type::ScalarField, "Pressure (fluid)", M_feSpace, (*M_exporterSolution) ["P"], static_cast <UInt> ( 0 ) );
215 #endif
216 
218  M_solver->resetOutput ( *M_exporterSolution );
219 #endif
220 
221  //Setup solution
223 
225  if ( M_couplings.size() > 0 )
226  {
228  updateLinearBC ( *M_solution );
230 
231  // Initialize the linear solution
232  copySolution ( *M_solution, *M_linearSolution );
233  }
234 #endif
235 
236 }
237 
238 void
240 {
241 
242 #ifdef HAVE_LIFEV_DEBUG
243  debugStream ( 8130 ) << "MultiscaleModelFSI1D::buildModel() \n";
244 #endif
245 
246  // Display data
247  // if ( M_comm->MyPID() == 0 )
248  // M_data->showMe();
249 
250  M_solver->buildConstantMatrices();
251 
252  // Update previous solution
253  copySolution ( *M_solution, *M_solution_tn );
254 
256  if ( M_couplings.size() > 0 )
257  {
259  }
260 #endif
261 
262 }
263 
264 void
266 {
267 
268 #ifdef HAVE_LIFEV_DEBUG
269  debugStream ( 8130 ) << "MultiscaleModelFSI1D::updateModel() \n";
270 #endif
271 
272  // Update previous solution
273  copySolution ( *M_solution, *M_solution_tn );
274 
276  if ( M_couplings.size() > 0 )
277  {
279  }
280 #endif
281 
282 }
283 
284 void
286 {
287 
288 #ifdef HAVE_LIFEV_DEBUG
289  debugStream ( 8130 ) << "MultiscaleModelFSI1D::solveModel() \n";
290 #endif
291 
292  displayModelStatus ( "Solve" );
293  solve ( *M_bc->handler(), *M_solution );
294 
296  if ( M_couplings.size() > 0 )
297  {
298  updateLinearBC ( *M_solution );
299  }
300 #endif
301 
302 }
303 
304 void
306 {
307 
308 #ifdef HAVE_LIFEV_DEBUG
309  debugStream ( 8130 ) << "MultiscaleModelFSI1D::updateSolution() \n";
310 #endif
311 
312 }
313 
314 void
316 {
317 
318 #ifdef HAVE_LIFEV_DEBUG
319  debugStream ( 8130 ) << "MultiscaleModelFSI1D::saveSolution() \n";
320 #endif
321 
322  // Update exporter solution removing ghost nodes
323  copySolution ( *M_solution, *M_exporterSolution );
324 
325 #ifdef HAVE_HDF5
326  M_exporter->postProcess ( M_data->dataTime()->time() );
327 
328  if ( M_data->dataTime()->isLastTimeStep() )
329  {
330  M_exporter->closeFile();
331  }
332 #endif
333 
335  //Matlab post-processing
336  M_solver->postProcess ( *M_exporterSolution, M_data->dataTime()->time() );
337 #endif
338 
339 }
340 
341 void
343 {
344  if ( M_comm->MyPID() == 0 )
345  {
346  multiscaleModel_Type::showMe();
347 
348  std::cout << "FE order = " << "P1" << std::endl
349  << "DOF = " << M_data->mesh()->numPoints() << std::endl << std::endl;
350 
351  std::cout << "maxH = " << MeshUtility::MeshStatistics::computeSize (*M_data->mesh() ).maxH << std::endl
352  << "meanH = " << MeshUtility::MeshStatistics::computeSize (*M_data->mesh() ).meanH << std::endl << std::endl;
353  }
354 }
355 
356 Real
358 {
359  return (*M_solution) ["AoverA0minus1"]->norm2() + (*M_solution) ["Q"]->norm2() + (*M_solution) ["P"]->norm2();
360 }
361 
362 // ===================================================
363 // MultiscaleInterface Methods
364 // ===================================================
365 void
367 {
368  OneDFSIFunction base;
369  base.setFunction ( std::bind ( function, std::placeholders::_1, std::placeholders::_1, std::placeholders::_1, std::placeholders::_1, std::placeholders::_1 ) );
370 
371  M_bc->handler()->setBC ( flagConverter ( boundaryID ), OneDFSI::first, OneDFSI::Q, base );
372 }
373 
374 void
376 {
377  OneDFSIFunction base;
378  base.setFunction ( std::bind ( function, std::placeholders::_1, std::placeholders::_1, std::placeholders::_1, std::placeholders::_1, std::placeholders::_1 ) );
379 
380  M_bc->handler()->setBC ( flagConverter ( boundaryID ), OneDFSI::first, OneDFSI::S, base );
381 }
382 
384 
385 Real
386 MultiscaleModelFSI1D::boundaryDeltaFlowRate ( const multiscaleID_Type& boundaryID, bool& solveLinearSystem )
387 {
388  bcSide_Type bcSide = flagConverter ( boundaryID );
389 
390  solveLinearModel ( solveLinearSystem );
391 
392  Real Q = M_solver->boundaryValue ( *M_solution, OneDFSI::Q, bcSide );
393  Real Qdelta = M_solver->boundaryValue ( *M_linearSolution, OneDFSI::Q, bcSide );
394 
395 #ifdef HAVE_LIFEV_DEBUG
396  debugStream ( 8130 ) << "MultiscaleModelFSI1D::boundaryDeltaFlowRate( boundaryID, solveLinearSystem ) \n";
397  debugStream ( 8130 ) << "Q: " << Q << "\n";
398  debugStream ( 8130 ) << "Qdelta: " << Qdelta << "\n";
399 #endif
400 
401  return (Qdelta - Q) / M_bcDelta;
402 
403 }
404 
405 Real
406 MultiscaleModelFSI1D::boundaryDeltaMeanNormalStress ( const multiscaleID_Type& boundaryID, bool& solveLinearSystem )
407 {
408  bcSide_Type bcSide = flagConverter ( boundaryID );
409 
410  solveLinearModel ( solveLinearSystem );
411 
412  Real S = M_solver->boundaryValue ( *M_solution, OneDFSI::S, bcSide );
413  Real Sdelta = M_solver->boundaryValue ( *M_linearSolution, OneDFSI::S, bcSide );
414 
415 #ifdef HAVE_LIFEV_DEBUG
416  debugStream ( 8130 ) << "MultiscaleModelFSI1D::boundaryDeltaStress( boundaryID, solveLinearSystem ) \n";
417  debugStream ( 8130 ) << "S: " << S << "\n";
418  debugStream ( 8130 ) << "Sdelta: " << Sdelta << "\n";
419 #endif
420 
421  return (Sdelta - S) / M_bcDelta;
422 }
423 
424 Real
425 MultiscaleModelFSI1D::boundaryDeltaMeanTotalNormalStress ( const multiscaleID_Type& boundaryID, bool& solveLinearSystem )
426 {
427  bcSide_Type bcSide = flagConverter ( boundaryID );
428 
429  solveLinearModel ( solveLinearSystem );
430 
431  Real T = M_solver->boundaryValue ( *M_solution, OneDFSI::T, bcSide );
432  Real Tdelta = M_solver->boundaryValue ( *M_linearSolution, OneDFSI::T, bcSide );
433 
434 #ifdef HAVE_LIFEV_DEBUG
435  debugStream ( 8130 ) << "MultiscaleModelFSI1D::boundaryDeltaTotalStress( boundaryID, solveLinearSystem ) \n";
436  debugStream ( 8130 ) << "T: " << T << "\n";
437  debugStream ( 8130 ) << "Tdelta: " << Tdelta << "\n";
438 #endif
439 
440  return (Tdelta - T) / M_bcDelta;
441 }
442 
443 Real
444 MultiscaleModelFSI1D::boundaryDeltaArea ( const multiscaleID_Type& boundaryID, bool& solveLinearSystem )
445 {
446  bcSide_Type bcSide = flagConverter ( boundaryID );
447 
448  solveLinearModel ( solveLinearSystem );
449 
450  Real A = M_solver->boundaryValue ( *M_solution, OneDFSI::A, bcSide );
451  Real Adelta = M_solver->boundaryValue ( *M_linearSolution, OneDFSI::A, bcSide );
452 
453 #ifdef HAVE_LIFEV_DEBUG
454  debugStream ( 8130 ) << "MultiscaleModelFSI1D::boundaryDeltaArea( boundaryID, solveLinearSystem ) \n";
455  debugStream ( 8130 ) << "A: " << A << "\n";
456  debugStream ( 8130 ) << "Adelta: " << Adelta << "\n";
457 #endif
458 
459  return (Adelta - A) / M_bcDelta;
460 }
461 
462 #else
463 
464 Real
466 {
468 }
469 
470 Real
472 {
474 }
475 
476 Real
478 {
480 }
481 
482 Real
483 MultiscaleModelFSI1D::boundaryDeltaArea ( const multiscaleID_Type& boundaryID, bool& /*solveLinearSystem*/ )
484 {
486 }
487 
488 #endif
489 
490 // ===================================================
491 // Private Methods
492 // ===================================================
493 void
494 MultiscaleModelFSI1D::setupGlobalData ( const std::string& fileName )
495 {
496 
497 #ifdef HAVE_LIFEV_DEBUG
498  debugStream ( 8130 ) << "MultiscaleModelFSI1D::setupGlobalData( fileName ) \n";
499 #endif
500 
501  GetPot dataFile ( fileName );
502 
503  //Global data time
504  M_data->setTimeData ( M_globalData->dataTime() );
505 
506  //Global physical quantities
507  if ( !dataFile.checkVariable ( "1D_Model/PhysicalParameters/density" ) )
508  {
509  M_data->setDensity ( M_globalData->fluidDensity() );
510  }
511  if ( !dataFile.checkVariable ( "1D_Model/PhysicalParameters/viscosity" ) )
512  {
513  M_data->setViscosity ( M_globalData->fluidViscosity() );
514  }
515  if ( !dataFile.checkVariable ( "1D_Model/PhysicalParameters/venousPressure" ) )
516  {
517  M_data->setVenousPressure ( M_globalData->fluidVenousPressure() );
518  }
519  if ( !dataFile.checkVariable ( "1D_Model/PhysicalParameters/externalPressure" ) )
520  {
521  M_data->setExternalPressure ( M_globalData->solidExternalPressure() );
522  }
523  if ( !dataFile.checkVariable ( "1D_Model/PhysicalParameters/densityWall" ) )
524  {
525  M_data->setDensityWall ( M_globalData->solidDensity() );
526  }
527  if ( !dataFile.checkVariable ( "1D_Model/PhysicalParameters/poisson" ) )
528  {
529  M_data->setPoisson ( M_globalData->solidPoissonCoefficient() );
530  }
531  if ( !dataFile.checkVariable ( "1D_Model/PhysicalParameters/young" ) )
532  {
533  M_data->setYoung ( M_globalData->solidYoungModulus() );
534  }
535 
536  //After changing some parameters we need to update the coefficients
537  M_data->updateCoefficients();
538 }
539 
540 void
542 {
543 
544 #ifdef HAVE_LIFEV_DEBUG
545  debugStream ( 8130 ) << "MultiscaleModelFSI1D::initializeSolution() \n";
546 #endif
547 
548  if ( multiscaleProblemStep > 0 )
549  {
550 #ifdef HAVE_HDF5
551  M_importer->setMeshProcId ( M_exporterMesh, M_comm->MyPID() );
552 
553  M_importer->addVariable ( IOData_Type::ScalarField, "Area ratio (fluid)", M_feSpace, (*M_exporterSolution) ["AoverA0minus1"], static_cast <UInt> ( 0 ) );
554  M_importer->addVariable ( IOData_Type::ScalarField, "Flow rate (fluid)", M_feSpace, (*M_exporterSolution) ["Q"], static_cast <UInt> ( 0 ) );
555  // M_importer->addVariable( IOData_Type::ScalarField, "W1", M_feSpace, (*M_exporterSolution)["W1"], static_cast <UInt> ( 0 ), M_feSpace->dof().numTotalDof() );
556  // M_importer->addVariable( IOData_Type::ScalarField, "W2", M_feSpace, (*M_exporterSolution)["W2"], static_cast <UInt> ( 0 ), M_feSpace->dof().numTotalDof() );
557  M_importer->addVariable ( IOData_Type::ScalarField, "Pressure (fluid)", M_feSpace, (*M_exporterSolution) ["P"], static_cast <UInt> ( 0 ) );
558 
559  // Import
560  M_exporter->setTimeIndex ( M_importer->importFromTime ( M_data->dataTime()->initialTime() ) + 1 );
561 
562  M_importer->closeFile();
563 #else
564  std::cout << "!!! ERROR: Importer not implemented for this filter !!!" << std::endl;
565 #endif
566 
567  // Copy the imported solution to the problem solution container
568  copySolution ( *M_exporterSolution, *M_solution );
569 
570  // Compute A from AreaRatio
571  M_solver->computeArea ( *M_solution );
572 
573  // Compute W1 and W2 from A and Q
574  M_solver->computeW1W2 ( *M_solution );
575 
576  // Initialize area in physics for viscoelastic computation
577  M_physics->setArea_tn ( * (*M_solution) ["A"] );
578  }
579  else
580  {
581  M_solver->initialize ( *M_solution );
582  copySolution ( *M_solution, *M_exporterSolution );
583  }
584 }
585 
586 void
588 {
589 
590 #ifdef HAVE_LIFEV_DEBUG
591  debugStream ( 8130 ) << "MultiscaleModelFSI1D::setupFEspace() \n";
592 #endif
593 
594  //Transform mesh
595  std::array< Real, NDIM > NullTransformation;
596  NullTransformation[0] = 0.;
597  NullTransformation[1] = 0.;
598  NullTransformation[2] = 0.;
599 
600  //The real mesh can be only scaled due to OneDFSISolver conventions
601  M_data->mesh()->meshTransformer().transformMesh ( M_geometryScale, NullTransformation, NullTransformation ); // Scale the x dimension
602 
603  for ( UInt i (0); i < M_data->numberOfNodes() ; ++i )
604  {
605  M_data->setArea0 ( M_data->area0 ( i ) * M_geometryScale[1] * M_geometryScale[2], i ); // Scale the area (y-z dimensions)
606  }
607 
608  //After changing some parameters we need to update the coefficients
609  M_data->updateCoefficients();
610 
611 #ifdef HAVE_HDF5
612  //The mesh for the post-processing can be rotated
613  M_exporterMesh->meshTransformer().transformMesh ( M_geometryScale, M_geometryRotate, M_geometryTranslate );
614 #endif
615 
616  //Setup FESpace
617  const ReferenceFE* refFE = &feSegP1;
618  const QuadratureRule* qR = &quadRuleSeg3pt;
619  const QuadratureRule* bdQr = &quadRuleSeg1pt;
620 
621  // const RefFE* refFE = &feSegP2;
622  // const QuadRule* qR = &quadRuleSeg3pt;
623  // const QuadRule* bdQr = &quadRuleSeg1pt;
624 
625  M_feSpace.reset ( new feSpace_Type ( M_data->mesh(), *refFE, *qR, *bdQr, 1, M_comm ) );
626  M_solver->setFESpace ( M_feSpace );
627 }
628 
629 void
630 MultiscaleModelFSI1D::copySolution ( const solution_Type& solution1, solution_Type& solution2 )
631 {
632 
633 #ifdef HAVE_LIFEV_DEBUG
634  debugStream ( 8130 ) << "MultiscaleModelFSI1D::copySolution( solution1, solution2 ) \n";
635 #endif
636 
637  for ( solutionConstIterator_Type i = solution2.begin() ; i != solution2.end() ; ++i )
638  if ( solution1.find ( i->first ) != solution1.end() )
639  {
640  *solution2[i->first] = *solution1.find (i->first)->second;
641  }
642 }
643 
644 void
646 {
647 
648 #ifdef HAVE_LIFEV_DEBUG
649  debugStream ( 8130 ) << "MultiscaleModelFSI1D::updateBCPhysicalSolverVariables() \n";
650 #endif
651 
652  // Update BCInterface solver variables
653  M_bc->updatePhysicalSolverVariables();
654 }
655 
656 void
657 MultiscaleModelFSI1D::solve ( bc_Type& bc, solution_Type& solution, const std::string& solverType )
658 {
659 
660 #ifdef HAVE_LIFEV_DEBUG
661  debugStream ( 8130 ) << "MultiscaleModelFSI1D::solve() \n";
662 #endif
663 
664  // Re-initialize solution
665  copySolution ( *M_solution_tn, solution );
666 
667  // Subiterate to respect CFL
668  UInt subiterationNumber (1);
669  Real timeStep = M_data->dataTime()->timeStep();
670 
671  Real CFL = M_solver->computeCFL ( solution, M_data->dataTime()->timeStep() );
672  if ( CFL > M_data->CFLmax() )
673  {
674  subiterationNumber = std::ceil ( CFL / M_data->CFLmax() );
675  timeStep /= subiterationNumber;
676  }
677 
678  if ( M_comm->MyPID() == 0 )
679  std::cout << solverType << " Number of subiterations " << subiterationNumber
680  << " ( CFL = " << CFL* timeStep / M_data->dataTime()->timeStep() << " )" << std::endl;
681 
682  for ( UInt i (1) ; i <= subiterationNumber ; ++i )
683  {
685  M_physics->setArea_tn ( *solution["A"] );
686  M_solver->updateRHS ( solution, timeStep );
687  M_solver->iterate ( bc, solution, M_data->dataTime()->previousTime() + i * timeStep, timeStep );
688  }
689 }
690 
692 
693 void
695 {
696  // Allocating the correct space
697  M_bcPreviousTimeSteps.reserve ( std::max ( M_couplings[0]->timeInterpolationOrder(), M_couplings[1]->timeInterpolationOrder() ) );
698 
699  // Create bcSide map
700  std::map< bcSide_Type, std::map< bcType_Type, Real > > bcSideMap;
701  M_bcPreviousTimeSteps.push_back ( bcSideMap );
702 
703  // Create bcType map
704  std::map< bcType_Type, Real > bcTypeMap;
705  M_bcPreviousTimeSteps[0][OneDFSI::left] = bcTypeMap;
706  M_bcPreviousTimeSteps[0][OneDFSI::right] = bcTypeMap;
707 }
708 
709 void
710 MultiscaleModelFSI1D::updateLinearBC ( const solution_Type& solution )
711 {
712  M_bcPreviousTimeSteps[0][OneDFSI::left][OneDFSI::A] = M_solver->boundaryValue ( solution, OneDFSI::A, OneDFSI::left );
713  M_bcPreviousTimeSteps[0][OneDFSI::left][OneDFSI::S] = M_solver->boundaryValue ( solution, OneDFSI::S, OneDFSI::left );
714  M_bcPreviousTimeSteps[0][OneDFSI::left][OneDFSI::Q] = M_solver->boundaryValue ( solution, OneDFSI::Q, OneDFSI::left );
715  M_bcPreviousTimeSteps[0][OneDFSI::right][OneDFSI::A] = M_solver->boundaryValue ( solution, OneDFSI::A, OneDFSI::right );
716  M_bcPreviousTimeSteps[0][OneDFSI::right][OneDFSI::S] = M_solver->boundaryValue ( solution, OneDFSI::S, OneDFSI::right );
717  M_bcPreviousTimeSteps[0][OneDFSI::right][OneDFSI::Q] = M_solver->boundaryValue ( solution, OneDFSI::Q, OneDFSI::right );
718 }
719 
720 void
722 {
723 
724 #ifdef HAVE_LIFEV_DEBUG
725  debugStream ( 8130 ) << "MultiscaleModelFSI1D::setupLinearModel( ) \n";
726 #endif
727 
728  // Define bcFunction for linear problem
729  M_bcBaseDelta.setFunction ( std::bind ( &MultiscaleModelFSI1D::bcFunctionDelta, this, std::placeholders::_1 ) );
730 
731  // The linear BCHandler is a copy of the original BCHandler with the LinearSolution instead of the true solution
732  //M_LinearBC.reset( new bc_Type( *M_bc->handler() ) ); // COPY CONSTRUCTOR NOT WORKING
733 
734  //Set left and right BC + default BC
735  M_linearBC->setBC ( OneDFSI::left, OneDFSI::first, M_bc->handler()->bc ( OneDFSI::left )->type ( OneDFSI::first ),
736  M_bc->handler()->bc ( OneDFSI::left )->bcFunction ( OneDFSI::first ) );
737 
738  M_linearBC->setBC ( OneDFSI::right, OneDFSI::first, M_bc->handler()->bc ( OneDFSI::right )->type ( OneDFSI::first ),
739  M_bc->handler()->bc ( OneDFSI::right )->bcFunction ( OneDFSI::first ) );
740 
741  M_linearBC->setDefaultBC();
742 
743  // Solution for the linear problem (this does not change anything in the solver)
744  M_solver->setupSolution ( *M_linearSolution );
745  M_linearBC->setSolution ( M_linearSolution );
746  M_linearBC->setFluxSource ( M_flux, M_source );
747 }
748 
749 void
751 {
752  // The couplings should use the same value for the time interpolation order
753  UInt timeInterpolationOrder ( std::max ( M_couplings[0]->timeInterpolationOrder(), M_couplings[1]->timeInterpolationOrder() ) );
754 
755  UInt containerSize ( M_bcPreviousTimeSteps.size() );
756 
757  // If we have not yet enough samples for interpolation, we add a new one
758  if ( containerSize <= timeInterpolationOrder )
759  {
760  ++containerSize;
761  M_bcPreviousTimeSteps.push_back ( M_bcPreviousTimeSteps[0] );
762  }
763 
764  // Updating database
765  for ( UInt i (1) ; i < containerSize ; ++i )
766  {
767  M_bcPreviousTimeSteps[containerSize - i] = M_bcPreviousTimeSteps[containerSize - i - 1];
768  }
769 }
770 
771 void
772 MultiscaleModelFSI1D::solveLinearModel ( bool& solveLinearSystem )
773 {
774 
775 #ifdef HAVE_LIFEV_DEBUG
776  debugStream ( 8130 ) << "MultiscaleModelFSI1D::solveLinearModel() \n";
777 #endif
778 
779  if ( !solveLinearSystem )
780  {
781  return;
782  }
783 
785 
786  displayModelStatus ( "Solve linear" );
787  solve ( *M_linearBC, *M_linearSolution, "L1D-" );
788 
790 
791  //This flag avoid recomputation of the same system
792  solveLinearSystem = false;
793 }
794 
795 void
797 {
798 
799 #ifdef HAVE_LIFEV_DEBUG
800  debugStream ( 8130 ) << "MultiscaleModelFSI1D::imposePerturbation() \n";
801 #endif
802 
803  for ( multiscaleCouplingsContainerConstIterator_Type i = M_couplings.begin(); i < M_couplings.end(); ++i )
804  if ( ( *i )->isPerturbed() )
805  {
806  // Find the side to perturb and apply the perturbation
807  M_bcDeltaSide = flagConverter ( ( *i )->boundaryID ( ( *i )->modelGlobalToLocalID ( M_ID ) ) );
808  M_linearBC->bc ( M_bcDeltaSide )->setBCFunction ( OneDFSI::first, M_bcBaseDelta );
809 
810  // Compute the range
811  M_bcDeltaType = M_linearBC->bc ( M_bcDeltaSide )->type ( OneDFSI::first );
812 
813  //M_BCDelta = ( *i )->residual()[( *i )->perturbedCoupling()] * 10000;
814  //M_BCDelta = ( M_BCDelta[1] - M_BCDelta[0] ) / 100;
815 
816  //if ( std::abs( M_BCDelta ) < 1e-6 || std::abs( M_BCDelta ) > 1e6 )
817  switch ( M_bcDeltaType )
818  {
819  case OneDFSI::A:
820 
821  M_bcDelta = M_data->jacobianPerturbationArea();
822 
823  break;
824 
825  case OneDFSI::Q:
826 
827  M_bcDelta = M_data->jacobianPerturbationFlowRate();
828 
829  break;
830 
831  case OneDFSI::S:
832 
833  M_bcDelta = M_data->jacobianPerturbationStress();
834 
835  break;
836 
837  case OneDFSI::T:
838 
839  //M_bcDelta = M_data->jacobianPerturbationTotalStress();
840 
841  break;
842 
843  default:
844 
845  std::cout << "Warning: bcType \"" << M_bcDeltaType << "\"not available!" << std::endl;
846 
847  break;
848  }
849 
850  break;
851  }
852 
853 #ifdef HAVE_LIFEV_DEBUG
854  debugStream ( 8130 ) << "BCDelta: " << M_bcDelta << "\n";
855 #endif
856 
857 }
858 
859 void
861 {
862 
863 #ifdef HAVE_LIFEV_DEBUG
864  debugStream ( 8130 ) << "MultiscaleModelFSI1D::resetPerturbation() \n";
865 #endif
866 
867  M_linearBC->bc ( M_bcDeltaSide )->setBCFunction ( OneDFSI::first, M_bc->handler()->bc ( M_bcDeltaSide )->bcFunction ( OneDFSI::first ) );
868 }
869 
870 Real
872 {
873  // Previous bc size
874  UInt bcPreviousSize ( M_bcPreviousTimeSteps.size() );
875 
876  // Time container for interpolation
877  std::vector< Real > timeContainer ( bcPreviousSize, 0 );
878  for ( UInt i (0) ; i < bcPreviousSize ; ++i )
879  {
880  timeContainer[i] = M_globalData->dataTime()->time() - i * M_globalData->dataTime()->timeStep();
881  }
882 
883  // Lagrange interpolation
884  Real bcValue (0);
885  Real base (1);
886 
887  for ( UInt i (0) ; i < M_bcPreviousTimeSteps.size() ; ++i )
888  {
889  base = 1;
890  for ( UInt j (0) ; j < M_bcPreviousTimeSteps.size() ; ++j )
891  if ( j != i )
892  {
893  base *= (t - timeContainer[j]) / (timeContainer[i] - timeContainer[j]);
894  }
895 
896  if ( i == 0 )
897  {
898  bcValue += base * ( M_bcPreviousTimeSteps[i][M_bcDeltaSide][M_bcDeltaType] + M_bcDelta );
899  }
900  else
901  {
902  bcValue += base * M_bcPreviousTimeSteps[i][M_bcDeltaSide][M_bcDeltaType];
903  }
904  }
905 
906  return bcValue;
907 }
908 
909 #else
910 
911 Real
913 {
914 
915 #ifdef HAVE_LIFEV_DEBUG
916  debugStream ( 8130 ) << "MultiscaleModelFSI1D::tangentProblem( bcOutputSide, bcOutputType ) \n";
917 #endif
918 
919  displayModelStatus ( "Solve linear" );
921 
923  if ( ( *i )->isPerturbed() )
924  {
925  // Find the perturbed side
927 
928  // Perturbation has no effect on the other sides (which also means that dQ/dQ and dP/dP are always zero)
929  if ( bcSide != bcOutputSide )
930  {
931  break;
932  }
933 
934  // Compute the RHS
936  rhs = 0.;
937 
938  // Compute the eigenvectors
941 
943 
944  switch ( bcOutputSide )
945  {
946  case OneDFSI::left:
947  switch ( outputType )
948  {
949  case OneDFSI::Q: // dQ_L/dS_L given by -1 * -1 * ( -L21/L22 )
950 
953 
954  break;
955 
956  case OneDFSI::S: // dS_L/dQ_L given by -1 * -1 * ( -L22/L21 )
957 
960 
961  break;
962 
963  default:
964 
965  std::cout << "Warning: bcType \"" << outputType << "\"not available!" << std::endl;
966 
967  break;
968  }
969 
970  break;
971 
972  case OneDFSI::right:
973  switch ( outputType )
974  {
975  case OneDFSI::Q: // dQ_R/dS_R given by -1 * -L11/L12
976 
979 
980  break;
981 
982  case OneDFSI::S: // dS_R/dQ_R given by -1 * -L12/L11
983 
986  break;
987 
988  default:
989 
990  std::cout << "Warning: bcType \"" << outputType << "\"not available!" << std::endl;
991 
992  break;
993  }
994 
995  break;
996 
997  default:
998 
999  std::cout << "Warning: bcSide \"" << bcSide << "\" not available!" << std::endl;
1000 
1001  break;
1002  }
1003 
1004  // Quit the loop
1005  break;
1006  }
1007 
1008  return jacobianCoefficient;
1009 }
1010 
1011 Real
1013 {
1014 #ifdef HAVE_NEUMANN_VISCOELASTIC_BC
1015  if ( M_data->viscoelasticWall() )
1016  {
1017  // Solve elastic tangent problem
1020 
1021  // Solve viscoelastic tangent problem
1024 
1026  flowRateDelta = 0.;
1027 
1028  for ( UInt iNode (0); iNode < M_physics->data()->numberOfNodes() ; ++iNode )
1029  {
1030  flowRateDelta[iNode] = 1.;
1032  flowRateDelta[iNode] = 0.;
1033  }
1034 
1036  }
1037  else
1038 #endif
1039  return rhs[bcNode];
1040 }
1041 
1042 #endif
1043 
1044 } // Namespace multiscale
1045 } // Namespace LifeV
std::function< Real(const Real &, const Real &, const Real &, const Real &, const ID &) > function_Type
void imposeBoundaryFlowRate(const multiscaleID_Type &boundaryID, const function_Type &function)
Impose the flow rate on a specific interface of the model.
const QuadratureRule quadRuleSeg3pt(pt_seg_3pt, QUAD_RULE_SEG_3PT, "Gauss Legendre 3 points on a segment", LINE, 3, 5)
void createLinearBC()
Update linear BC.
OneDFSIFunction()
Empty Constructor.
void setupLinearModel()
Setup the linear model.
#define JACOBIAN_WITH_FINITEDIFFERENCE
MultiscaleModel()
The main constructor.
void setupFESpace()
Setup the FE space for pressure and velocity.
void setupGlobalData(const std::string &fileName)
Setup the global data of the model.
void updateInverseJacobian(const UInt &iQuadPt)
OneDFSIFunction - Base class for 1D BC Functions.
#define NDIM
Definition: LifeV.hpp:265
void setupData(const std::string &fileName)
Setup the data of the model.
void solve(bc_Type &bc, solution_Type &solution, const std::string &solverType=" 1D-")
Solve the 1D hyperbolic problem.
void mapsDefinition()
Define the map of the OneDFSIModel objects.
Real boundaryDeltaArea(const multiscaleID_Type &boundaryID, bool &solveLinearSystem)
Get the variation of the integral of the area (on a specific boundary interface) using the linear mod...
void copySolution(const solution_Type &solution1, solution_Type &solution2)
Copy the solution (solution2 = solution1)
void updateLinearModel()
Update the linear system matrix and vectors.
Real boundaryDeltaFlowRate(const multiscaleID_Type &boundaryID, bool &solveLinearSystem)
Get the variation of the flow rate (on a specific boundary interface) using the linear model...
#define HAVE_MATLAB_POSTPROCESSING
MultiscaleModel multiscaleModel_Type
void initializeSolution()
Initialize the solution.
void buildModel()
Build the initial model.
const QuadratureRule quadRuleSeg1pt(pt_seg_1pt, QUAD_RULE_SEG_1PT, "Gauss Legendre 1 point on a segment", LINE, 1, 1)
void solveLinearModel(bool &solveLinearSystem)
Solve the linear problem.
double Real
Generic real data.
Definition: LifeV.hpp:175
void imposePerturbation()
Impose the coupling perturbation on the correct BC inside the BCHandler.
Real checkSolution() const
Return a specific scalar quantity to be used for a comparison with a reference value.
void updateLinearBC(const solution_Type &solution)
Update linear BC.
The class for a reference Lagrangian finite element.
void showMe()
Display some information about the model.
bcSide_Type flagConverter(const multiscaleID_Type &boundaryID) const
Convert the boundaryID to a bcSide type.
Real boundaryDeltaMeanTotalNormalStress(const multiscaleID_Type &boundaryID, bool &solveLinearSystem)
Get the variation of the integral of the total normal stress (on a specific boundary face) ...
void imposeBoundaryMeanNormalStress(const multiscaleID_Type &boundaryID, const function_Type &function)
Impose the integral of the mean normal stress on a specific boundary interface of the model...
QuadratureRule - The basis class for storing and accessing quadrature rules.
Real boundaryDeltaMeanNormalStress(const multiscaleID_Type &boundaryID, bool &solveLinearSystem)
Get the variation of the integral of the mean normal stress (on a specific boundary interface) using ...
MultiscaleInterface - The multiscale interface for fluid problems.
void resetPerturbation()
Reset all the coupling perturbations imposed on the BCHandler.
void updateBCPhysicalSolverVariables()
Update BCInterface physical solver variables.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191