Endocrine.cpp 7.69 KB
Newer Older
Aaron Bray's avatar
Aaron Bray committed
1
2
/* Distributed under the Apache License, Version 2.0.
   See accompanying NOTICE file for details.*/
Aaron Bray's avatar
Aaron Bray committed
3
4

#include "stdafx.h"
5
6
7
#include "physiology/Endocrine.h"
#include "controller/Compartments.h"
#include "controller/Substances.h"
8
// Dependent Systems
Aaron Bray's avatar
Aaron Bray committed
9
#include "system/physiology/SEEnergySystem.h"
10
// Actions
11
12
#include "engine/SEActionManager.h"
#include "engine/SEPatientActionCollection.h"
13
14
15
16
17
#include "patient/actions/SEAcuteStress.h"
// CDM
#include "patient/SEPatient.h"
#include "substance/SESubstance.h"
#include "compartment/fluid/SELiquidCompartment.h"
Aaron Bray's avatar
Aaron Bray committed
18
#include "properties/SEScalarAmountPerTime.h"
19
#include "properties/SEScalarMass.h"
Aaron Bray's avatar
Aaron Bray committed
20
#include "properties/SEScalarMassPerAmount.h"
21
22
#include "properties/SEScalarMassPerVolume.h"
#include "properties/SEScalarTime.h"
Aaron Bray's avatar
Aaron Bray committed
23
#include "properties/SEScalar0To1.h"
24
#include "utils/GeneralMath.h"
Aaron Bray's avatar
Aaron Bray committed
25

26
Endocrine::Endocrine(PulseData& data) : PulseEndocrineSystem(data)
Aaron Bray's avatar
Aaron Bray committed
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
{
  Clear();
}

Endocrine::~Endocrine()
{
  Clear();
}

void Endocrine::Clear()
{
  SEEndocrineSystem::Clear();
  m_aortaGlucose = nullptr;
  m_aortaEpinephrine = nullptr;
  m_splanchnicInsulin = nullptr;  
}

//--------------------------------------------------------------------------------------------------
/// \brief
/// Initializes system properties to valid homeostatic values.
47
48
49
50
///
/// \details
/// For stabilization only!
/// Called AFTER Setup when stabilizing a new patient
Aaron Bray's avatar
Aaron Bray committed
51
52
53
//--------------------------------------------------------------------------------------------------
void Endocrine::Initialize()
{
54
  PulseSystem::Initialize();
Aaron Bray's avatar
Aaron Bray committed
55
56
}

57
58
59
60
61
62
63
64
65
//--------------------------------------------------------------------------------------------------
/// \brief
/// Initializes parameters for Endocrine Class
///
/// \details
/// Called during both State loading and Patient Stabilization
/// Pull and setup up our data (can be from other systems)
/// Initialize will be called after this and can overwrite any of this data (only if stabilizing)
//--------------------------------------------------------------------------------------------------
Aaron Bray's avatar
Aaron Bray committed
66
67
68
void Endocrine::SetUp()
{
  m_dt_s = m_data.GetTimeStep().GetValue(TimeUnit::s);
Aaron Bray's avatar
Aaron Bray committed
69
70
71
  SELiquidCompartment* aorta = m_data.GetCompartments().GetLiquidCompartment(pulse::VascularCompartment::Aorta);
  SELiquidCompartment* rkidney = m_data.GetCompartments().GetLiquidCompartment(pulse::VascularCompartment::RightEfferentArteriole);
  SELiquidCompartment* lkidney = m_data.GetCompartments().GetLiquidCompartment(pulse::VascularCompartment::LeftEfferentArteriole);
Aaron Bray's avatar
Aaron Bray committed
72
73
74
75
76
77
  m_aortaEpinephrine = aorta->GetSubstanceQuantity(m_data.GetSubstances().GetEpi());
  m_rKidneyEpinephrine = rkidney->GetSubstanceQuantity(m_data.GetSubstances().GetEpi());
  m_lKidneyEpinephrine = lkidney->GetSubstanceQuantity(m_data.GetSubstances().GetEpi());
  m_aortaGlucose = aorta->GetSubstanceQuantity(m_data.GetSubstances().GetGlucose());
  SESubstance* insulin = &m_data.GetSubstances().GetInsulin();
  m_insulinMolarMass_g_Per_mol = insulin->GetMolarMass(MassPerAmountUnit::g_Per_mol);
Aaron Bray's avatar
Aaron Bray committed
78
  m_splanchnicInsulin = m_data.GetCompartments().GetLiquidCompartment(pulse::VascularCompartment::Splanchnic)->GetSubstanceQuantity(*insulin);
Aaron Bray's avatar
Aaron Bray committed
79
80
81
82
83
84
85
86
87
88
89
90
}

void Endocrine::AtSteadyState()
{

}

//--------------------------------------------------------------------------------------------------
/// \brief
/// Endocrine process function
///
/// \details
91
/// Currently, only two hormones exists in the Pulse system: epinephrine and insulin. If the metabolic rate 
Aaron Bray's avatar
Aaron Bray committed
92
93
94
95
/// rises above the basal rate, epinephrine is released. This is meant to simulate a sympathetic 
/// nervous system response. The masses of the hormones are increased in the kidneys' efferent arterioles. 
/// The hormones will then circulate using the transport and substances methodology.
//--------------------------------------------------------------------------------------------------
96
void Endocrine::Process(bool solve_and_transport)
Aaron Bray's avatar
Aaron Bray committed
97
98
99
{
  ReleaseEpinephrine();
  SynthesizeInsulin();
100
101
102
103
104
  ComputeExposedModelParameters();
}
void Endocrine::ComputeExposedModelParameters()
{

Aaron Bray's avatar
Aaron Bray committed
105
106
107
108
109
110
111
112
113
114
115
}

//--------------------------------------------------------------------------------------------------
/// \brief
/// Calculate the rate of insulin production 
///
/// \details
/// The insulin production rate is calculated based on the relevant range of glucose and instantaneous concentration of glucose in the aorta
/// (representative of the body). The equation for insulin production is from \cite tolic2000insulin
//--------------------------------------------------------------------------------------------------
void Endocrine::SynthesizeInsulin()
116
117
118
119
120
{
  double insulinMassDelta_g = 0;
  double bloodGlucoseConcentration_mg_Per_dL = m_data.GetSubstances().GetGlucose().GetBloodConcentration(MassPerVolumeUnit::mg_Per_dL);
  if (bloodGlucoseConcentration_mg_Per_dL >= 80)
  {
121
    // Linear function for blood glucose between 80-150 mg/dL and insulin synthesis of 100-475 pmol/min [polonsky1987insulin]
122
123
    double insulinSynthesisRate_pmol_Per_min = (5.357 * bloodGlucoseConcentration_mg_Per_dL) - 328.56;
    GetInsulinSynthesisRate().SetValue(insulinSynthesisRate_pmol_Per_min, AmountPerTimeUnit::pmol_Per_min);
Aaron Bray's avatar
Aaron Bray committed
124

125
126
127
    insulinMassDelta_g = Convert(insulinSynthesisRate_pmol_Per_min, AmountPerTimeUnit::pmol_Per_min, AmountPerTimeUnit::mol_Per_s);
    insulinMassDelta_g *= m_insulinMolarMass_g_Per_mol * m_dt_s;
  }
Aaron Bray's avatar
Aaron Bray committed
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  m_splanchnicInsulin->GetMass().IncrementValue(insulinMassDelta_g, MassUnit::g);
  m_splanchnicInsulin->Balance(BalanceLiquidBy::Mass);
}

//--------------------------------------------------------------------------------------------------
/// \brief
/// Release epinephrine into the bloodstream and handle sympathetic responses
///
/// \details
/// Epinephrine is released at a basal rate of .18 ug/min \cite best1982release from the kidneys. During
/// certain events, the release rate of epinephrine increases. This is sympathetic response.
//--------------------------------------------------------------------------------------------------
void Endocrine::ReleaseEpinephrine()
{
142
  SEPatient& Patient = m_data.GetCurrentPatient();
Aaron Bray's avatar
Aaron Bray committed
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  double patientWeight_kg = Patient.GetWeight(MassUnit::kg);
  double epinephrineBasalReleaseRate_ug_Per_min = .00229393 * patientWeight_kg; //We want it to be ~.18 ug/min for our StandardMale
  double epinephrineRelease_ug = (epinephrineBasalReleaseRate_ug_Per_min / 60) * m_dt_s;  //amount released per timestep

  double currentMetabolicRate_W = m_data.GetEnergy().GetTotalMetabolicRate(PowerUnit::W);
  double basalMetabolicRate_W = Patient.GetBasalMetabolicRate(PowerUnit::W);
  double releaseMultiplier = 1.0;

  // If we have exercise, release more epi. Release multiplier is a sigmoid based on the total metabolic rate
  // with the maximum multiplier adapted from concentration data presented in @cite tidgren1991renal and @cite stratton1985hemodynamic
  // and the shape adjusted to match data in @cite tidgren1991renal.
  if (currentMetabolicRate_W > basalMetabolicRate_W)
  {
    double exercise_W = (currentMetabolicRate_W - basalMetabolicRate_W);
    double e50_W = 190;
    double eta = 0.035;
    double maxMultiplier = 18.75; 
    releaseMultiplier = 1.0 + GeneralMath::LogisticFunction(maxMultiplier, e50_W, eta, exercise_W);
  }

  // If we have a stress/anxiety response, release more epi
  if (m_data.GetActions().GetPatientActions().HasAcuteStress())
  {
    SEAcuteStress* s = m_data.GetActions().GetPatientActions().GetAcuteStress();
    double severity = s->GetSeverity().GetValue();

    //The highest stress multiplier we currently support is 30
    releaseMultiplier += GeneralMath::LinearInterpolator(0, 1, 0, 30, severity);
  }

  epinephrineRelease_ug *= releaseMultiplier;

  m_rKidneyEpinephrine->GetMass().IncrementValue(0.5*epinephrineRelease_ug, MassUnit::ug);
  m_lKidneyEpinephrine->GetMass().IncrementValue(0.5*epinephrineRelease_ug, MassUnit::ug);
}