LifeV
lifev/electrophysiology/testsuite/test_0DTenTusscher06Model/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 0D test with Ten Tusscher et al. 2006 model
30 
31  Note that the model is not solved correctly using Rush-Larsen
32  with forward Euler. In the original code of Ten Tusscher
33  the solution of CaSS and CaSR is computed using a specific
34  algorithm (which I do not know).
35  Therefore I consider all the variables except for the
36  potential as gating variable and use the specific
37  method in their original code to make it work.
38 
39  @date 08 - 2013
40  @author Simone Rossi <simone.rossi@epfl.ch>
41 
42  @contributor
43  @mantainer Simone Rossi <simone.rossi@epfl.ch>
44  */
45 
46 // Tell the compiler to ignore specific kind of warnings:
47 #pragma GCC diagnostic ignored "-Wunused-variable"
48 #pragma GCC diagnostic ignored "-Wunused-parameter"
49 
50 #include <Epetra_ConfigDefs.h>
51 #ifdef EPETRA_MPI
52 #include <mpi.h>
53 #include <Epetra_MpiComm.h>
54 #else
55 #include <Epetra_SerialComm.h>
56 #endif
57 
58 //Tell the compiler to restore the warning previously silented
59 #pragma GCC diagnostic warning "-Wunused-variable"
60 #pragma GCC diagnostic warning "-Wunused-parameter"
61 
62 
63 #include <fstream>
64 
65 
66 #include <lifev/electrophysiology/solver/IonicModels/IonicTenTusscher06.hpp>
67 #include <lifev/core/LifeV.hpp>
68 
69 #include <Teuchos_RCP.hpp>
70 #include <Teuchos_ParameterList.hpp>
71 #include "Teuchos_XMLParameterListHelpers.hpp"
72 
73 using namespace LifeV;
74 
75 #define SolutionTestNorm -2476.4745158656560307
76 
77 Int main ( Int argc, char** argv )
78 {
79  //! Initializing Epetra communicator
80  MPI_Init (&argc, &argv);
81  Epetra_MpiComm Comm (MPI_COMM_WORLD);
82  if ( Comm.MyPID() == 0 )
83  {
84  std::cout << "% using MPI" << std::endl;
85  }
86 
87  //********************************************//
88  // Creates a new model object representing the//
89  // model from TenTusscher et al. 2006. The //
90  // model input are the parameters. Pass the //
91  // parameter list in the constructor //
92  //********************************************//
93  std::cout << "Building Constructor for TenTusscher 2006 Model with default parameters ... ";
94  IonicTenTusscher06 ionicModel;
95  std::cout << " Done!" << std::endl;
96 
97 
98  //********************************************//
99  // Show the parameters of the model as well as//
100  // other informations about the object. //
101  //********************************************//
102  ionicModel.showMe();
103 
104 
105  //********************************************//
106  // Initialize the solution with the default //
107  // values //
108  //********************************************//
109  std::cout << "Initializing solution vector...";
110  std::vector<Real> states (ionicModel.restingConditions() );
111  std::cout << " Done!" << std::endl;
112 
113 
114  //********************************************//
115  // Initialize the rhs to 0. The rhs is the //
116  // vector containing the numerical values of //
117  // the time derivatives of the state //
118  // variables, that is, the right hand side of //
119  // the differential equation. //
120  //********************************************//
121  std::cout << "Initializing rhs..." ;
122  std::vector<Real> rhs (ionicModel.Size(), 0);
123  std::cout << " Done! " << std::endl;
124 
125 
126 
127 
128  //********************************************//
129  // The model needs as external informations //
130  // the contraction velocity and the Calcium //
131  // concentration. //
132  //********************************************//
133  Real Iapp (0.0);
134 
135 
136  //********************************************//
137  // Simulation starts on t=0 and ends on t=TF. //
138  // The timestep is given by dt //
139  //********************************************//
140  Real TF (500.0);
141  Real dt (0.1);
142 
143 
144  //********************************************//
145  // We record the norm of the solution to //
146  // check the failure of the test //
147  //********************************************//
148  Real SolutionNorm = states[0];
149 
150 
151  //********************************************//
152  // Open the file "output.txt" to save the //
153  // solution. //
154  //********************************************//
155  std::string filename = "output.txt";
156  std::ofstream output ("output.txt");
157  output << 0 << "\t";
158 
159  for ( int j (0); j < ionicModel.Size() - 1; j++)
160  {
161  output << states[j] << "\t";
162  }
163  output << states[ ionicModel.Size() - 1 ] << "\n";
164 
165  //********************************************//
166  // Time loop starts. //
167  //********************************************//
168  std::cout << "Time loop starts...\n";
169 
170 
171  int savestep ( 1.0 / dt );
172  int iter (0);
173 
174 
175  std::vector<Real> v (states);
176  for ( Real t = 0; t < TF; )
177  {
178 
179  //********************************************//
180  // Compute the applied current. This is a //
181  // simple switch. //
182  //********************************************//
183  if ( t > 50 && t < 52 )
184  {
185  Iapp = 20.;
186  }
187  else
188  {
189  Iapp = 0;
190  }
191  std::cout << "\r " << t << " ms. " << std::flush;
192 
193 
194  iter++;
195  //********************************************//
196  // Compute the rhs using the model equations //
197  //********************************************//
198  ionicModel.setAppliedCurrent (Iapp);
199  rhs[0] = ionicModel.computeLocalPotentialRhs (states);
200  ionicModel.addAppliedCurrent (rhs);
201 
202  ionicModel.computeGatingVariablesWithRushLarsen ( states, dt);
203  states[0] = states[0] + dt * rhs[0]; //This should be divided by the membrane capacitance ionicModel.membraneCapacitance();
204  //In the code of Ten Tusscher there is no such a division
205  // on the other hand if we don't divide by the membrane capacitance
206  // in the three dimensional simulations
207  // we get a faster wave (as fast as the LuoRudy ~2 the one in the benchmark!)
208 
209 
210  //********************************************//
211  // Update the time. //
212  //********************************************//
213  t = t + dt;
214 
215 
216  //********************************************//
217  // Writes solution on file. //
218  //********************************************//
219  if ( iter % savestep == 0 )
220  {
221  output << t << "\t";
222  for ( int index (0); index < ionicModel.Size() - 1; index++)
223  {
224  output << states[index] << "\t";
225  }
226  output << states[ ionicModel.Size() - 1 ] << "\n";
227 
228  //********************************************//
229  // Update the norm of the solution to check //
230  // test failure //
231  //********************************************//
232  SolutionNorm += states[0];
233  }
234 
235  }
236  std::cout << "\n...Time loop ends.\n";
237  std::cout << "Solution written on file: " << filename << "\n";
238  //********************************************//
239  // Close exported file. //
240  //********************************************//
241  output.close();
242 
243  //! Finalizing Epetra communicator
244  MPI_Finalize();
245 
246  Real returnValue;
247 
248  Real err = std::abs (SolutionTestNorm - SolutionNorm) / std::abs (SolutionTestNorm);
249  std::cout << std::setprecision (20) << "\nError: " << err << "\nSolution norm: " << SolutionNorm << "\n";
250  if ( err > 1e-12 )
251  {
252  std::cout << "\nTest Failed!\n";
253  returnValue = EXIT_FAILURE; // Norm of solution did not match
254  }
255  else
256  {
257  returnValue = EXIT_SUCCESS;
258  }
259  return ( returnValue );
260 }
261 
262 #undef SolutionTestNorm
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
void updateInverseJacobian(const UInt &iQuadPt)
int main(int argc, char **argv)
Definition: dummy.cpp:5
double Real
Generic real data.
Definition: LifeV.hpp:175