LifeV
lifev/multiscale/testsuite/onedmodel/main.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 One Dimensional Test
30  *
31  * @date 01-09-2004
32  * @author Vincent Martin
33  *
34  * @version 2.0
35  * @date 01-01-2010
36  * @author Gilles Fourestey <gilles.fourestey@epfl.ch>
37  *
38  * @maintainer Cristiano Malossi <cristiano.malossi@epfl.ch>
39  *
40  * This is a test to verify that the One Dimensional Model works correctly.
41  */
42 
43 
44 #include <Epetra_ConfigDefs.h>
45 #ifdef EPETRA_MPI
46 #include <mpi.h>
47 #include <Epetra_MpiComm.h>
48 #else
49 #include <Epetra_SerialComm.h>
50 #endif
51 
52 
53 // LifeV includes
54 #include <lifev/core/LifeV.hpp>
55 #include <lifev/core/util/LifeChrono.hpp>
56 #include <lifev/core/filter/GetPot.hpp>
57 #include <lifev/core/array/MapEpetra.hpp>
58 
59 // Mathcard includes
60 #include <lifev/one_d_fsi/fem/OneDFSIBCHandler.hpp>
61 #include <lifev/one_d_fsi/solver/OneDFSISolver.hpp>
62 #include <lifev/multiscale/models/MultiscaleModelFSI1D.hpp>
63 
64 #include "ud_functions.hpp"
65 
66 using namespace LifeV;
67 using namespace Multiscale;
68 
69 bool checkValue (const Real val, const Real test, const Real tol = 1.e-5, const bool verbose = true)
70 {
71  Real norm = abs (val - test);
72 
73  if ( verbose )
74  {
75  std::cout << "value = " << val << " computed value = " << test << " diff = " << norm << std::endl;
76  }
77 
78  return (norm < tol);
79 }
80 
81 Int main (Int argc, char** argv)
82 {
83  //Setup main communicator
84  std::shared_ptr<Epetra_Comm> comm;
85 
86 #ifdef HAVE_MPI
87  std::cout << "MPI Initialization" << std::endl;
88  MPI_Init ( &argc, &argv );
89 #endif
90 
91  //MPI Preprocessing
92 #ifdef EPETRA_MPI
93  Int nprocs;
94  Int rank;
95 
96  MPI_Comm_size ( MPI_COMM_WORLD, &nprocs );
97  MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
98 
99  if ( rank == 0 )
100  {
101  std::cout << "MPI Processes: " << nprocs << std::endl;
102  std::cout << "MPI Epetra Initialization ... " << std::endl;
103  }
104  comm.reset ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
105 
106  comm->Barrier();
107 #else
108  std::cout << "MPI SERIAL Epetra Initialization ... " << std::endl;
109  comm.reset ( new Epetra_SerialComm() );
110 #endif
111 
112  // *********************************
113  // Useful typedefs
114  // *********************************
115 
116  typedef MultiscaleModelFSI1D::bc_Type bc_Type;
117  typedef bc_Type::bcFunction_Type bcFunction_Type;
118 
119  // *********************************
120  // Reading from data file
121  // *********************************
122  GetPot command_line (argc, argv);
123 
124  // checking if we are checking for the nightly build
125  const bool check = command_line.search (2, "-c", "--check");
126 
127  std::string fileName = command_line.follow ("data", 2, "-f", "--file");
128  GetPot dataFile ( fileName );
129 
130  // *********************************
131  // Build the 1D model
132  // *********************************
133  MultiscaleModelFSI1D oneDModel;
134  oneDModel.setCommunicator ( comm );
135 
136  // Scale, Rotate, Translate 1D (if necessary)
137  std::array< Real, NDIM > geometryScale;
138  std::array< Real, NDIM > geometryRotate;
139  std::array< Real, NDIM > geometryTranslate;
140 
141  geometryScale[0] = dataFile ( "1D_Model/space_discretization/transform", 1., 0);
142  geometryScale[1] = dataFile ( "1D_Model/space_discretization/transform", 1., 1);
143  geometryScale[2] = dataFile ( "1D_Model/space_discretization/transform", 1., 2);
144 
145  geometryRotate[0] = dataFile ( "1D_Model/space_discretization/transform", 0., 3) * M_PI / 180;
146  geometryRotate[1] = dataFile ( "1D_Model/space_discretization/transform", 0., 4) * M_PI / 180;
147  geometryRotate[2] = dataFile ( "1D_Model/space_discretization/transform", 0., 5) * M_PI / 180;
148 
149  geometryTranslate[0] = dataFile ( "1D_Model/space_discretization/transform", 0., 6);
150  geometryTranslate[1] = dataFile ( "1D_Model/space_discretization/transform", 0., 7);
151  geometryTranslate[2] = dataFile ( "1D_Model/space_discretization/transform", 0., 8);
152 
153  oneDModel.setGeometry ( geometryScale, geometryRotate, geometryTranslate );
154 
155  oneDModel.setupData ( fileName );
156 
157  // *********************************
158  // BC for the 1D model
159  // *********************************
160 
161  // Set BC using BCInterface
162  //oneDModel.GetBCInterface().FillHandler( fileName, "1D_Model" );
163 
164  // Set BC using standard approach
165  Sin sinus ( 0, 10, .01, 0.);
166  bcFunction_Type sinusoidalFunction ( std::bind ( &Sin::operator(), &sinus, std::placeholders::_1 ) );
167 
168  // Absorbing
169  bc_Type::bcFunctionSolverDefinedPtr_Type absorbing ( new OneDFSIFunctionSolverDefinedAbsorbing ( OneDFSI::right, OneDFSI::W2 ) );
170  bcFunction_Type absorbingFunction ( std::bind ( &OneDFSIFunctionSolverDefinedAbsorbing::operator(),
171  dynamic_cast<OneDFSIFunctionSolverDefinedAbsorbing*> ( & ( *absorbing ) ), std::placeholders::_1, std::placeholders::_2 ) );
172 
173  // BC to test A_from_P conversion
174  //Constant constantArea( 1.00 );
175  //bcFunction_Type constantAreaFunction( std::bind( &Constant::operator(), &constantArea, std::placeholders::_1 ) );
176 
177  //Constant constantPressure( 24695.0765959599 );
178  //bcFunction_Type constantPressureFunction( std::bind( &Constant::operator(), &constantPressure, std::placeholders::_1 ) );
179 
180  oneDModel.bc().setBC ( OneDFSI::left, OneDFSI::first, OneDFSI::Q, sinusoidalFunction );
181  oneDModel.bc().setBC ( OneDFSI::right, OneDFSI::first, OneDFSI::W2, absorbingFunction );
182 
183  //oneDModel.bc().setBC( OneDFSI::right, OneDFSI::first, OneDFSI::A, constantAreaFunction );
184  //oneDModel.bc().setBC( OneDFSI::right, OneDFSI::first, OneDFSI::P, constantPressureFunction );
185 
186  oneDModel.setupModel();
187 
188  absorbing->setSolution ( oneDModel.solution() );
189  absorbing->setFluxSource ( oneDModel.flux(), oneDModel.source() );
190 
191  // *********************************
192  // Tempolar loop
193  // *********************************
194  std::cout << "\nTemporal loop:" << std::endl;
195 
196  LifeChrono chronoTotal;
197  LifeChrono chronoSystem;
198  LifeChrono chronoIteration;
199 
200  Int count = 0;
201  chronoTotal.start();
202  for ( ; oneDModel.data().dataTime()->canAdvance() ; oneDModel.data().dataTime()->updateTime(), ++count )
203  {
204  std::cout << std::endl << "--------- Iteration " << count << " time = " << oneDModel.data().dataTime()->time() << std::endl;
205 
206  chronoIteration.start();
207 
208  if ( oneDModel.data().dataTime()->isFirstTimeStep() )
209  {
210  oneDModel.buildModel();
211  }
212  else
213  {
214  oneDModel.updateModel();
215  }
216 
217  chronoSystem.start();
218 
219  oneDModel.solveModel();
220 
221  chronoSystem.stop();
222 
223  oneDModel.updateSolution();
224 
225  //Save solution
226  if ( count % 50 == 0 || oneDModel.data().dataTime()->isLastTimeStep() )
227  {
228  oneDModel.saveSolution();
229  }
230 
231  chronoIteration.stop();
232 
233  std::cout << " System solved in " << chronoSystem.diff() << " s, (total time " << chronoIteration.diff() << " s)." << std::endl;
234  }
235 
236  chronoTotal.stop();
237  std::cout << std::endl << " Simulation ended successfully in " << chronoTotal.diff() << " s" << std::endl;
238 
239 #ifdef HAVE_MPI
240  std::cout << "MPI Finalization" << std::endl;
241  MPI_Finalize();
242 #endif
243 
244  if ( check )
245  {
246  bool ok = true;
247  Int rightNodeID = oneDModel.solver()->boundaryDOF ( OneDFSI::right );
248 
249  ok = ok && checkValue ( 0.999998 , (*oneDModel.solution ("A") ) [rightNodeID]);
250  ok = ok && checkValue (-0.00138076, (*oneDModel.solution ("Q") ) [rightNodeID]);
251  ok = ok && checkValue (-0.00276153, (*oneDModel.solution ("W1") ) [rightNodeID]);
252  ok = ok && checkValue ( 0.00000000, (*oneDModel.solution ("W2") ) [rightNodeID]);
253 
254  ok = ok && checkValue ( 0.999999 , (*oneDModel.solution ("A") ) [rightNodeID - 1]);
255  ok = ok && checkValue (-0.00040393, (*oneDModel.solution ("Q") ) [rightNodeID - 1]);
256  ok = ok && checkValue (-0.00080833, (*oneDModel.solution ("W1") ) [rightNodeID - 1]);
257  ok = ok && checkValue ( 0.00000045, (*oneDModel.solution ("W2") ) [rightNodeID - 1]);
258 
259  if (ok)
260  {
261  std::cout << "Test successful" << std::endl;
262  return 0;
263  }
264  else
265  {
266  std::cout << "Test unsuccessful" << std::endl;
267  return -1;
268  }
269  }
270  else
271  {
272  return 0;
273  }
274 }
bc_Type & bc() const
Get the BC handler container of the boundary conditions of the model.
void start()
Start the timer.
Definition: LifeChrono.hpp:93
void setBC(const bcSide_Type &bcSide, const bcLine_Type &bcLine, const bcType_Type &bcType, const bcFunction_Type &bcFunction)
Set a boundary condition.
GetPot(const int argc_, char **argv_, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:507
Sin(const Real mean=0, const Real scale=10, const Real period=.01, const Real phase=0.)
The constructor.
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
#define M_PI
Definition: winmath.h:20
void updateInverseJacobian(const UInt &iQuadPt)
#define NDIM
Definition: LifeV.hpp:265
int main(int argc, char **argv)
Definition: dummy.cpp:5
double Real
Generic real data.
Definition: LifeV.hpp:175
bool checkValue(const Real val, const Real test, const Real tol=1.e-5, const bool verbose=true)
bool search(unsigned No, const char *P,...)
Definition: GetPot.hpp:1217
void stop()
Stop the timer.
Definition: LifeChrono.hpp:100
GetPot(const STRING_VECTOR &FileNameList)
Definition: GetPot.hpp:645
const std::string follow(const char *Default, unsigned No, const char *Option,...)
Definition: GetPot.hpp:1510