LifeV
BCInterfaceFunctionParserFile.hpp
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 BCInterfaceFunctionParserFile class
30  *
31  * @date 09-07-2009
32  * @author Cristiano Malossi <cristiano.malossi@epfl.ch>
33  *
34  * @maintainer Cristiano Malossi <cristiano.malossi@epfl.ch>
35  */
36 #ifndef BCInterfaceFunctionParserFile_H
37 #define BCInterfaceFunctionParserFile_H 1
38 
39 #include <lifev/bc_interface/core/function/BCInterfaceFunctionParser.hpp>
40 
41 namespace LifeV
42 {
43 
44 //! BCInterfaceFunctionParserFile - LifeV boundary condition function file wrapper for \c BCInterface
45 /*!
46  * @author Cristiano Malossi
47  *
48  * This class is an interface between the \c BCInterface and the \c Parser. It allows to construct LifeV
49  * functions type for boundary conditions, using a \c GetPot file containing a function string and a
50  * table of discrete data (for example a discrete flow rate or pressure as a function of the time).
51  *
52  * See \c BCInterfaceFunctionParser class for more details.
53  *
54  * <b>DETAILS</b> <BR>
55  * The constructor of the class takes a string contains the \c GetPot file name.
56  * The \c GetPot file has the following structure:
57  *
58  * <ul>
59  * <li> <b>function:</b> contains the expression of the function (as described in the \c BCInterfaceFunctionParser class).
60  * <li> <b>variables:</b> contains the list of variables and coefficients present in the function.
61  * The first one is the variable and should be sorted in a growing order,
62  * while all the others are coefficients.
63  * <li> <b>data:</b> contains the discrete list of variable and related coefficients. It must
64  * have n columns, where n is the number of variables (and coefficients).
65  * <li> <b>scale:</b> Contains n optional coefficients (default = 1), which multiply each column in the data table.
66  * <li> <b>loop:</b> Useful for periodic simulation: at the end of the list, it restarts using the first value instead of extrapolating the last two.
67  * </ul>
68  *
69  * <b>NOTE</b> <BR>
70  * During the execution, if the value of the variable (usually the time) is not present in the 'data' table,
71  * the class linearly interpolates the value between the two closest values. Moreover, if the value of the variable is higher
72  * than anyone present in the 'data' table, the class linearly extrapolates the value using the last two values in the table.
73  *
74  * <b>EXAMPLE OF DATA FILE</b> <BR>
75  * <CODE>
76  * function = '(0,0,q)' <BR>
77  * loop = false <BR>
78  * variables = 't q' <BR>
79  * scale = '1 1' <BR>
80  * data = '0.000000000 1.00 <BR>
81  * 0.333333333 2.00 <BR>
82  * 0.666666666 3.00 <BR>
83  * 1.000000000 4.00' <BR>
84  * </CODE>
85  */
86 template< typename BcHandlerType, typename PhysicalSolverType >
87 class BCInterfaceFunctionParserFile: public virtual BCInterfaceFunctionParser< BcHandlerType, PhysicalSolverType >
88 {
89 public:
90 
91  //! @name Type definitions
92  //@{
93 
94  typedef BcHandlerType bcHandler_Type;
95  typedef PhysicalSolverType physicalSolver_Type;
96 
99 
100  typedef typename function_Type::data_Type data_Type;
102 
103  //@}
104 
105 
106  //! @name Constructors & Destructor
107  //@{
108 
109  //! Empty Constructor
111 
112  //! Destructor
114 
115  //@}
116 
117 
118  //! @name Set Methods
119  //@{
120 
121  //! Set data for boundary conditions
122  /*!
123  * @param data boundary condition data loaded from \c GetPot file
124  */
125  virtual void setData ( const dataPtr_Type& data );
126 
127  //@}
128 
129 private:
130 
131  //! @name Unimplemented Methods
132  //@{
133 
135 
137 
138  //@}
139 
140 
141  //! @name Private methods
142  //@{
143 
144  //! Linear interpolation (extrapolation) between two values of the data.
145  void dataInterpolation();
146 
147  //@}
148 
150  bool M_loop;
153 };
154 
155 // ===================================================
156 // Factory
157 // ===================================================
158 //! Factory create function
159 template< typename BcHandlerType, typename PhysicalSolverType >
160 inline BCInterfaceFunctionParser< BcHandlerType, PhysicalSolverType >* createBCInterfaceFunctionParserFile()
161 {
162  return new BCInterfaceFunctionParserFile< BcHandlerType, PhysicalSolverType > ();
163 }
164 
165 // ===================================================
166 // Constructors
167 // ===================================================
168 template< typename BcHandlerType, typename PhysicalSolverType >
169 BCInterfaceFunctionParserFile< BcHandlerType, PhysicalSolverType >::BCInterfaceFunctionParserFile() :
170  function_Type (),
172  M_variables (),
173  M_loop (),
174  M_data (),
175  M_dataIterator ()
176 {
177 
178 #ifdef HAVE_LIFEV_DEBUG
179  debugStream ( 5022 ) << "BCInterfaceFunctionFile::BCInterfaceFunctionFile()" << "\n";
180 #endif
181 
182 }
183 
184 
185 
186 // ===================================================
187 // Set Methods
188 // ===================================================
189 template< typename BcHandlerType, typename PhysicalSolverType >
190 inline void
191 BCInterfaceFunctionParserFile< BcHandlerType, PhysicalSolverType >::setData ( const dataPtr_Type& data )
192 {
193 
194 #ifdef HAVE_LIFEV_DEBUG
195  debugStream ( 5022 ) << "BCInterfaceFunctionFile::loadData fileName: " << data->baseString() << "\n";
196 #endif
197 
198  std::vector< std::string > stringsVector;
199  boost::split ( stringsVector, data->baseString(), boost::is_any_of ( "[" ) );
200 
201  //Load data from file
202  GetPot dataFile ( stringsVector[0] );
203 
204  //Set variables
205  UInt variablesNumber = dataFile.vector_variable_size ( "variables" );
206 
207  M_variables.clear();
208  M_variables.reserve ( variablesNumber );
209 
210  std::vector< Real > scale;
211  scale.reserve ( variablesNumber );
212 
213  for ( UInt j ( 0 ); j < variablesNumber; ++j )
214  {
215  M_variables.push_back ( dataFile ( "variables", "unknown", j ) );
216  scale.push_back ( dataFile ( "scale", 1.0, j ) );
217  }
218 
219 #ifdef HAVE_LIFEV_DEBUG
220  std::stringstream output;
221  output << "BCInterfaceFunctionFile::loadData variables: ";
222  for ( UInt j (0); j < variablesNumber; ++j )
223  {
224  output << M_variables[j] << " ";
225  }
226 
227  output << "\n scale: ";
228  for ( UInt j (0); j < variablesNumber; ++j )
229  {
230  output << scale[j] << " ";
231  }
232 
233  debugStream ( 5022 ) << output.str() << "\n";
234 #endif
235 
236  //Load loop flag
237  M_loop = dataFile ( "loop", false );
238 
239  //Load data
240  UInt dataLines = dataFile.vector_variable_size ( "data" ) / variablesNumber;
241 
242  M_data.clear();
243  for ( UInt j ( 0 ); j < variablesNumber; ++j )
244  {
245  M_data[M_variables[j]].reserve ( dataLines );
246  }
247 
248  for ( UInt i ( 0 ); i < dataLines; ++i )
249  for ( UInt j ( 0 ); j < variablesNumber; ++j )
250  {
251  M_data[M_variables[j]].push_back ( scale[j] * dataFile ( "data", 0.0, i * variablesNumber + j ) );
252  }
253 
254 #ifdef HAVE_LIFEV_DEBUG
255  output.str ("");
256  output << " loop: " << M_loop << "\n";
257  output << " data:";
258  for ( UInt i (0); i < dataLines; ++i )
259  {
260  if (i > 0)
261  {
262  output << " ";
263  }
264 
265  for ( UInt j (0); j < variablesNumber; ++j )
266  {
267  output << " " << M_data[ M_variables[j] ][i];
268  }
269  output << "\n";
270  }
271  debugStream ( 5022 ) << output.str();
272 #endif
273 
274  //Initialize iterator
275  M_dataIterator = M_data[M_variables[0]].begin();
276 
277  //Update the data container (IT IS A COPY!) with the correct base string for the BCInterfaceFunctionParser
278  if ( stringsVector.size() < 2 )
279  {
280  data->setBaseString ( dataFile ( "function", "Undefined" ) );
281  }
282  else
283  {
284  std::string search = "]";
285  std::string replace = "";
286 
287  for( size_t pos = 0; ; pos += replace.length() ) {
288  pos = stringsVector[1].find( search, pos );
289  if( pos == std::string::npos ) break;
290  stringsVector[1].erase( pos, search.length() );
291  stringsVector[1].insert( pos, replace );
292  }
293 
294  data->setBaseString ( dataFile ( ( "function" + stringsVector[1] ).c_str(), "Undefined" ) );
295  }
296 
297  // Now data contains the real base string
298  functionParser_Type::setData ( data );
299 
300 #ifdef HAVE_LIFEV_DEBUG
301  debugStream ( 5022 ) << " function: " << data->baseString() << "\n";
302 #endif
303 
304 }
305 
306 // ===================================================
307 // Private Methods
308 // ===================================================
309 template< typename BcHandlerType, typename PhysicalSolverType >
310 inline void
311 BCInterfaceFunctionParserFile< BcHandlerType, PhysicalSolverType >::dataInterpolation()
312 {
313  //Get variable
314  Real X = functionParser_Type::M_parser->variable ( M_variables[0] );
315 
316  //If it is a loop scale the variable: X = X - (ceil( X / Xmax ) -1) * Xmax
317  if ( M_loop )
318  {
319  X -= ( std::ceil ( X / M_data[M_variables[0]].back() ) - 1 ) * M_data[M_variables[0]].back();
320  }
321 
322 #ifdef HAVE_LIFEV_DEBUG
323  debugStream ( 5022 ) << " variable: " << X << "\n";
324 #endif
325 
326  //Move Iterator
327  for ( ;; )
328  {
329 
330 #ifdef HAVE_LIFEV_DEBUG
331  debugStream ( 5022 ) << " iterator position : " << static_cast<Real> ( M_dataIterator - M_data[ M_variables[0] ].begin() ) << "\n";
332  debugStream ( 5022 ) << " variable (position) : " << *M_dataIterator << "\n";
333  debugStream ( 5022 ) << " variable (position+1): " << * (M_dataIterator + 1) << "\n";
334 #endif
335 
336  if ( X >= *M_dataIterator && X <= * ( M_dataIterator + 1 ) )
337  {
338  break;
339  }
340 
341  if ( X > *M_dataIterator )
342  {
343  if ( M_dataIterator + 1 == M_data[M_variables[0]].end() )
344  {
345  break;
346  }
347  else
348  {
349  ++M_dataIterator;
350  }
351  }
352  else
353  {
354  if ( M_dataIterator == M_data[M_variables[0]].begin() )
355  {
356  break;
357  }
358  else
359  {
360  --M_dataIterator;
361  }
362  }
363  }
364 
365  //Linear interpolation (extrapolation if X > xB)
366  Real xA, xB, A, B;
367  for ( UInt j ( 1 ), position = static_cast< UInt > ( M_dataIterator - M_data[M_variables[0]].begin() ) ;
368  j < static_cast< UInt > ( M_variables.size() ); ++j )
369  {
370  xA = M_data[M_variables[0]][position];
371  xB = M_data[M_variables[0]][position + 1];
372  A = M_data[M_variables[j]][position];
373  B = M_data[M_variables[j]][position + 1];
374 
375  functionParser_Type::M_parser->setVariable ( M_variables[j], A + ( B - A ) / ( xB - xA ) * ( X - xA ) );
376 
377 #ifdef HAVE_LIFEV_DEBUG
378  debugStream ( 5022 ) << " " << M_variables[j] << " = " << A + (B - A) / (xB - xA) * (X - xA) << "\n";
379 #endif
380  }
381 }
382 
383 } // Namespace LifeV
384 
385 #endif /* BCInterfaceFunctionParserFile_H */
void dataInterpolation()
Linear interpolation (extrapolation) between two values of the data.
BCInterfaceFunctionParser< bcHandler_Type, physicalSolver_Type > functionParser_Type
void updateInverseJacobian(const UInt &iQuadPt)
BCInterfaceFunctionParserFile & operator=(const BCInterfaceFunctionParserFile &function)
virtual void setData(const dataPtr_Type &data)
Set data for boundary conditions.
BCInterfaceFunctionParserFile(const BCInterfaceFunctionParserFile &function)
BCInterfaceFunctionParser - LifeV boundary condition function wrapper for BCInterface.
BCInterfaceFunctionParserFile - LifeV boundary condition function file wrapper for BCInterface...
BCInterfaceFunctionParser< BcHandlerType, PhysicalSolverType > * createBCInterfaceFunctionParserFile()
Factory create function.
BCInterfaceFunction< bcHandler_Type, physicalSolver_Type > function_Type
double Real
Generic real data.
Definition: LifeV.hpp:175
std::map< std::string, std::vector< Real > > M_data
const std::string operator()(const char *VarName, const char *Default) const
Definition: GetPot.hpp:2045
bool operator()(const char *VarName, bool Default) const
Definition: GetPot.hpp:2008
BCInterfaceFunction - Base class for BCInterface boundary functions.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
unsigned vector_variable_size(const char *VarName) const
Definition: GetPot.hpp:2291