Line |
Branch |
Exec |
Source |
1 |
|
|
// ______ ______ _ _ _____ ______ |
2 |
|
|
// | ____| ____| | (_)/ ____| | ____| |
3 |
|
|
// | |__ | |__ | | _| (___ ___| |__ |
4 |
|
|
// | __| | __| | | | |\___ \ / __| __| |
5 |
|
|
// | | | |____| |____| |____) | (__| |____ |
6 |
|
|
// |_| |______|______|_|_____/ \___|______| |
7 |
|
|
// Finite Elements for Life Sciences and Engineering |
8 |
|
|
// |
9 |
|
|
// License: LGL2.1 License |
10 |
|
|
// FELiScE default license: LICENSE in root folder |
11 |
|
|
// |
12 |
|
|
// Main authors: |
13 |
|
|
// |
14 |
|
|
|
15 |
|
|
#ifndef __AUTOREGULATION_HPP__ |
16 |
|
|
#define __AUTOREGULATION_HPP__ |
17 |
|
|
|
18 |
|
|
// System includes |
19 |
|
|
|
20 |
|
|
// External includes |
21 |
|
|
|
22 |
|
|
// Project includes |
23 |
|
|
#include "Core/felisceParam.hpp" |
24 |
|
|
#include "Solver/lumpedModelBC.hpp" |
25 |
|
|
|
26 |
|
|
namespace felisce |
27 |
|
|
{ |
28 |
|
|
/*! |
29 |
|
|
\brief A class to handle boundary conditions data for (retinal) autoregulation |
30 |
|
|
|
31 |
|
|
The class handle several aspects of the data concerning boundary conditions: |
32 |
|
|
- input pressure: \n |
33 |
|
|
shape, mean value over a cardiac cycle, difference with respect to a given pressure story |
34 |
|
|
- autoregulation:\n |
35 |
|
|
both in fibers and in windkessel |
36 |
|
|
- post-process |
37 |
|
|
*/ |
38 |
|
|
class Autoregulation{ |
39 |
|
|
public: |
40 |
|
|
/*! \brief id of the master proc */ |
41 |
|
|
static const int MASTER = 0; |
42 |
|
|
|
43 |
|
|
std::unordered_map<std::string, std::vector<int> > initialize(std::string elemeBoarderType); |
44 |
|
|
/** |
45 |
|
|
@{ \name Downstream autoregulation |
46 |
|
|
*/ |
47 |
|
|
void handleLumpedModel(const double& t, LumpedModelBC* lumpedModel); |
48 |
|
|
/**@}*/ |
49 |
|
|
void computeExtraPressure( const int &nC); |
50 |
|
|
|
51 |
|
|
double control( const double &t ) const; |
52 |
|
|
double inletPressure( const double &t, const int& caseTest ) const; |
53 |
|
|
/** |
54 |
|
|
@{ \name Post-process functions |
55 |
|
|
*/ |
56 |
|
|
void exportSummary( const int& rank) const; |
57 |
|
|
void exportControlFunctions(const int &numCycle); |
58 |
|
|
void print(const int & rank); |
59 |
|
|
void update( const double& time, double Q, double P, std::vector<double> pout, const int& rank ); |
60 |
|
|
/**@}*/ |
61 |
|
|
|
62 |
|
|
/*! \brief PI */ |
63 |
|
|
static constexpr double PI = 3.14159265; |
64 |
|
|
/*! \brief Conversion constant from mm of mercury to Pascal */ |
65 |
|
|
static constexpr double mmHg2DynPerCm2 = 1333.32; |
66 |
|
|
/*! \brief duration of the systole */ |
67 |
|
|
static constexpr double m_systoleDuration = 0.25; |
68 |
|
|
/*! \brief duration of the cardiac cycle */ |
69 |
|
|
static constexpr double m_cycleDuration = 0.8; |
70 |
|
|
|
71 |
|
|
private: |
72 |
|
|
|
73 |
|
|
void meanPressure2PeakAndDiast(double const& meanP, double& peakP, double& diastP ) const; |
74 |
|
|
double computeMeanInflowPress( const int &Case, const double &t0 ) const; |
75 |
|
|
double interpPressure( const double &t ) const; |
76 |
|
|
|
77 |
|
|
/** |
78 |
|
|
@{ \name Sigmoidal function and parameters |
79 |
|
|
all the data members and function, usefull to describe the shape of the sigmoidal function. |
80 |
|
|
*/ |
81 |
|
|
/*!\brief Sigmoidal function used for the autoregulation |
82 |
|
|
|
83 |
|
|
\param[in] extraP \f$\delta p = p-p_{ref}\f$ is the difference between a pressure p and the reference value |
84 |
|
|
\return the value of the sigmoidal function in that point |
85 |
|
|
|
86 |
|
|
The sigmoidal function: |
87 |
|
|
\code |
88 |
|
|
return ( 1 - exp( - m_slope*extraP ) )/ ( 1 + exp( -m_slope*(extraP-m_center ) ) ); |
89 |
|
|
\endcode |
90 |
|
|
Function limits: |
91 |
|
|
- \a extraP goes to infinity it returns 1 |
92 |
|
|
- \a extraP goes to -infinity it returns \code - exp(m_slope * m_center) \endcode |
93 |
|
|
- in zero is equal to zero |
94 |
|
|
|
95 |
|
|
Another possible parametrization (used in the paper) is: |
96 |
|
|
\code |
97 |
|
|
return ( 1 - exp( - m_slope*extraP ) )/ ( 1 + 1/w*exp( -m_slope*(extraP) ) ); |
98 |
|
|
\endcode |
99 |
|
|
In this case \a w represents the minimum value of the sigmoidal function (in absolute value). |
100 |
|
|
And m_slope can be approximated via |
101 |
|
|
\code |
102 |
|
|
m_slope=1/fp.up*std::log((1+q/w)/(1-q)) |
103 |
|
|
\endcode |
104 |
|
|
*/ |
105 |
|
188197 |
inline double sigmoid( const double &extraP) const { |
106 |
|
188197 |
return ( 1 - exp( - m_slope*extraP ) )/ ( 1 + exp( -m_slope*(extraP-m_center ) ) ); |
107 |
|
|
} |
108 |
|
|
/*! \brief slope of the sigmodail function \f$[\mbox{mmHg}^-1]\f$ |
109 |
|
|
|
110 |
|
|
\f$ 2/(\mbox{fp.up-fp.down})\ln(\mbox{fp.q}/(1-\mbox{fp.q}))\f$ |
111 |
|
|
*/ |
112 |
|
|
double m_slope; |
113 |
|
|
/*! \brief relative center of the sigmoidal function \f$[\mbox{mmHg}]\f$ |
114 |
|
|
|
115 |
|
|
\f$ (\mbox{fp.up} + \mbox{fp.down})/2\f$ |
116 |
|
|
*/ |
117 |
|
|
double m_center; |
118 |
|
|
/**@}*/ |
119 |
|
|
|
120 |
|
|
/** |
121 |
|
|
@{ \name Downstream autoregulation |
122 |
|
|
*/ |
123 |
|
|
void setLumpedModel(const double& t); |
124 |
|
|
/*! \brief Distal resistance -- reference value */ |
125 |
|
|
std::vector<double> m_RdistRef; |
126 |
|
|
/*! \brief Distal resistance -- current value */ |
127 |
|
|
std::vector<double> m_Rdist; |
128 |
|
|
/*! \brief Capacitance -- reference value */ |
129 |
|
|
std::vector<double> m_CRef; |
130 |
|
|
/*! \brief Capacitance -- current value */ |
131 |
|
|
std::vector<double> m_C; |
132 |
|
|
/*! \brief Regulation parameter */ |
133 |
|
|
std::vector<double> m_regParam; |
134 |
|
|
/**@}*/ |
135 |
|
|
/*! \brief difference between mean pressure and reference pressure. |
136 |
|
|
|
137 |
|
|
extraPressure is a std::vector that contains for each cycle the difference |
138 |
|
|
of the mean pressure from idcase with respect to the idcontrolFreeCase; |
139 |
|
|
*/ |
140 |
|
|
std::vector<double> m_extraPressure; |
141 |
|
|
|
142 |
|
|
/*! \brief of cardiac cycles */ |
143 |
|
|
int m_nC; |
144 |
|
|
/*! \brief Label(s) of the inlet*/ |
145 |
|
|
std::vector<int> m_labelInlet; |
146 |
|
|
/*! \brief Label(s) of the outlet*/ |
147 |
|
|
std::vector<int> m_labelOutlet; |
148 |
|
|
/*! \brief Label(s) of the structure*/ |
149 |
|
|
std::vector<int> m_labelStructure; |
150 |
|
|
|
151 |
|
|
/*! \brief Flow at the inlet*/ |
152 |
|
|
std::vector<double> m_QInflow; |
153 |
|
|
/*! \brief Mean pressure at the inlet*/ |
154 |
|
|
std::vector<double> m_PInflow; |
155 |
|
|
}; |
156 |
|
|
|
157 |
|
|
|
158 |
|
|
} |
159 |
|
|
#endif |
160 |
|
|
|