Endocrine.cpp 7.65 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
void Endocrine::SetUp()
{
Aaron Bray's avatar
Aaron Bray committed
68
69
70
  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
71
72
73
74
75
76
  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
77
  m_splanchnicInsulin = m_data.GetCompartments().GetLiquidCompartment(pulse::VascularCompartment::Splanchnic)->GetSubstanceQuantity(*insulin);
Aaron Bray's avatar
Aaron Bray committed
78
79
80
81
82
83
84
85
86
87
88
89
}

void Endocrine::AtSteadyState()
{

}

//--------------------------------------------------------------------------------------------------
/// \brief
/// Endocrine process function
///
/// \details
90
/// Currently, only two hormones exists in the Pulse system: epinephrine and insulin. If the metabolic rate 
Aaron Bray's avatar
Aaron Bray committed
91
92
93
94
/// 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.
//--------------------------------------------------------------------------------------------------
95
void Endocrine::Process(bool solve_and_transport)
Aaron Bray's avatar
Aaron Bray committed
96
97
98
{
  ReleaseEpinephrine();
  SynthesizeInsulin();
99
100
101
102
103
  ComputeExposedModelParameters();
}
void Endocrine::ComputeExposedModelParameters()
{

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

//--------------------------------------------------------------------------------------------------
/// \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()
115
116
117
118
119
{
  double insulinMassDelta_g = 0;
  double bloodGlucoseConcentration_mg_Per_dL = m_data.GetSubstances().GetGlucose().GetBloodConcentration(MassPerVolumeUnit::mg_Per_dL);
  if (bloodGlucoseConcentration_mg_Per_dL >= 80)
  {
120
    // Linear function for blood glucose between 80-150 mg/dL and insulin synthesis of 100-475 pmol/min [polonsky1987insulin]
121
122
    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
123

124
    insulinMassDelta_g = Convert(insulinSynthesisRate_pmol_Per_min, AmountPerTimeUnit::pmol_Per_min, AmountPerTimeUnit::mol_Per_s);
125
    insulinMassDelta_g *= m_insulinMolarMass_g_Per_mol * m_data.GetTimeStep_s();
126
  }
Aaron Bray's avatar
Aaron Bray committed
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  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()
{
141
  SEPatient& Patient = m_data.GetCurrentPatient();
Aaron Bray's avatar
Aaron Bray committed
142
143
  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
144
  double epinephrineRelease_ug = (epinephrineBasalReleaseRate_ug_Per_min / 60) * m_data.GetTimeStep_s();  //amount released per timestep
Aaron Bray's avatar
Aaron Bray committed
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

  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())
  {
165
    double severity = m_data.GetActions().GetPatientActions().GetAcuteStress().GetSeverity().GetValue();
Aaron Bray's avatar
Aaron Bray committed
166
167
168
169
170
171
172
173
174
175

    //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);
}