projects/biogears/src/engine/Systems/Nervous.cpp
void Nervous::BaroreceptorFeedback()
{
  if (!m_FeedbackActive)
    return;
  //First calculate the sympathetic and parasympathetic firing rates:
  double nu = m_data.GetConfiguration().GetResponseSlope();
  double meanArterialPressure_mmHg = m_data.GetCardiovascular().GetMeanArterialPressure(PressureUnit::mmHg);
  //Adjusting the mean arterial pressure set-point to account for cardiovascular drug effects
  double meanArterialPressureSetPoint_mmHg = m_data.GetPatient().GetMeanArterialPressureBaseline(PressureUnit::mmHg) //m_MeanArterialPressureNoFeedbackBaseline_mmHg
    + m_data.GetEnergy().GetExerciseMeanArterialPressureDelta(PressureUnit::mmHg);

  //Adjust the MAP set-point for baroreceptors for anesthetics, opioids, and sedatives.  Other drugs should leave set-point as is.
  for (SESubstance* sub : m_data.GetCompartments().GetLiquidCompartmentSubstances()) {
    if (!sub->HasPD())
      continue;
    if ((sub->GetClassification() == CDM::enumSubstanceClass::Anesthetic) || (sub->GetClassification() == CDM::enumSubstanceClass::Sedative) || (sub->GetClassification() == CDM::enumSubstanceClass::Opioid)) {
      meanArterialPressureSetPoint_mmHg += m_data.GetDrugs().GetMeanBloodPressureChange(PressureUnit::mmHg);
      break;
      //Only want to apply the blood pressure change ONCE (In case there are multiple sedative/opioids/etc)
      ///\TODO:  Look into a better way to implement drug classification search
    }
  }

  double sympatheticFraction = 1.0 / (1.0 + pow(meanArterialPressure_mmHg / meanArterialPressureSetPoint_mmHg, nu));
  double parasympatheticFraction = 1.0 / (1.0 + pow(meanArterialPressure_mmHg / meanArterialPressureSetPoint_mmHg, -nu));

  //Calculate the normalized change in heart rate
  double normalizedHeartRate = GetBaroreceptorHeartRateScale().GetValue();
  double tauHeartRate_s = m_data.GetConfiguration().GetHeartRateDistributedTimeDelay(TimeUnit::s);
  double deltaNormalizedHeartRate = (1.0 / tauHeartRate_s) * (-normalizedHeartRate + m_normalizedAlphaHeartRate * sympatheticFraction - m_normalizedBetaHeartRate * parasympatheticFraction + m_normalizedGammaHeartRate) * m_dt_s;
  normalizedHeartRate += deltaNormalizedHeartRate;
  GetBaroreceptorHeartRateScale().SetValue(normalizedHeartRate);

  //Calculate the normalized change in heart elastance
  double normalizedHeartElastance = GetBaroreceptorHeartElastanceScale().GetValue();
  double tauElastance_s = m_data.GetConfiguration().GetHeartElastanceDistributedTimeDelay(TimeUnit::s);
  double deltaNormalizedHeartElastance = (1.0 / tauElastance_s) * (-normalizedHeartElastance + m_normalizedAlphaElastance * sympatheticFraction + m_normalizedGammaElastance) * m_dt_s;
  normalizedHeartElastance += deltaNormalizedHeartElastance;
  GetBaroreceptorHeartElastanceScale().SetValue(normalizedHeartElastance);

  //Calculate the normalized change in flow resistance for any cardiovascular resistor
  double normalizedResistance = GetBaroreceptorResistanceScale().GetValue();
  double tauResistance_s = m_data.GetConfiguration().GetSystemicResistanceDistributedTimeDelay(TimeUnit::s);
  double deltaNormalizedResistance = (1.0 / tauResistance_s) * (-normalizedResistance + m_normalizedAlphaResistance * sympatheticFraction + m_normalizedGammaResistance) * m_dt_s;
  normalizedResistance += deltaNormalizedResistance;
  GetBaroreceptorResistanceScale().SetValue(normalizedResistance);

  //Calculate the normalized change in flow compliance for any cardiovascular compliance
  double normalizedCompliance = GetBaroreceptorComplianceScale().GetValue();
  double tauCompliance_s = m_data.GetConfiguration().GetVenousComplianceDistributedTimeDelay(TimeUnit::s);
  double deltaNormalizedCompliance = (1.0 / tauCompliance_s) * (-normalizedCompliance + m_normalizedAlphaCompliance * parasympatheticFraction + m_normalizedGammaCompliance) * m_dt_s;
  normalizedCompliance += deltaNormalizedCompliance;
  GetBaroreceptorComplianceScale().SetValue(normalizedCompliance);
#ifdef VERBOSE
  m_data.GetDataTrack().Probe("normalizedHeartRate", normalizedHeartRate);
  m_data.GetDataTrack().Probe("normalizedHeartElastance", normalizedHeartElastance);
  m_data.GetDataTrack().Probe("normalizedResistance", normalizedResistance);
  m_data.GetDataTrack().Probe("normalizedCompliance", normalizedCompliance);
  m_data.GetDataTrack().Probe("meanArterialPressureSetPoint_mmHg", meanArterialPressureSetPoint_mmHg);
#endif
}
//--------------------------------------------------------------------------------------------------
/// \brief
/// Calculates the baroreceptor feedback and sets the scaling parameters in the CDM
///
/// \details
/// The baroreceptor feedback function uses the current mean arterial pressure relative to the mean arterial
/// pressure set-point in order to calculate the sympathetic and parasympathetic response fractions.
/// These fractions are used to update the scaling parameters of heart rate, heart elastance, resistance and compliance
/// for each time step.
//--------------------------------------------------------------------------------------------------
/// \todo Add decompensation. Perhaps a reduction in the effect that is a function of blood volume below a threshold... and maybe time.
\brief
Calculates the baroreceptor feedback and sets the scaling parameters in the CDM

\details
The baroreceptor feedback function uses the current mean arterial pressure relative to the mean arterial
pressure set-point in order to calculate the sympathetic and parasympathetic response fractions.
These fractions are used to update the scaling parameters of heart rate, heart elastance, resistance and compliance
for each time step.

\todo Add decompensation. Perhaps a reduction in the effect that is a function of blood volume below a threshold... and maybe time.
\ brief Calculates the baroreceptor feedback and sets the scaling parameters in the CDM \ details The baroreceptor feedback function uses the current mean arterial pressure relative to the mean arterial pressure set - point in order to calculate the sympathetic and parasympathetic response fractions . These fractions are used to update the scaling parameters of heart rate heart elastance resistance and compliance for each time step . \ todo Add decompensation . Perhaps a reduction in the effect that is a function of blood volume below a threshold ... and maybe time .
void Nervous::BaroreceptorFeedback()
{
  if (!m_FeedbackActive)
    return;
  double nu = m_data.GetConfiguration().GetResponseSlope();
  double meanArterialPressure_mmHg = m_data.GetCardiovascular().GetMeanArterialPressure(PressureUnit::mmHg);
  double meanArterialPressureSetPoint_mmHg = m_data.GetPatient().GetMeanArterialPressureBaseline(PressureUnit::mmHg) 
    + m_data.GetEnergy().GetExerciseMeanArterialPressureDelta(PressureUnit::mmHg);
  for (SESubstance* sub : m_data.GetCompartments().GetLiquidCompartmentSubstances()) {
    if (!sub->HasPD())
      continue;
    if ((sub->GetClassification() == CDM::enumSubstanceClass::Anesthetic) || (sub->GetClassification() == CDM::enumSubstanceClass::Sedative) || (sub->GetClassification() == CDM::enumSubstanceClass::Opioid)) {
      meanArterialPressureSetPoint_mmHg += m_data.GetDrugs().GetMeanBloodPressureChange(PressureUnit::mmHg);
      break;
    }
  }
  double sympatheticFraction = 1.0 / (1.0 + pow(meanArterialPressure_mmHg / meanArterialPressureSetPoint_mmHg, nu));
  double parasympatheticFraction = 1.0 / (1.0 + pow(meanArterialPressure_mmHg / meanArterialPressureSetPoint_mmHg, -nu));
  double normalizedHeartRate = GetBaroreceptorHeartRateScale().GetValue();
  double tauHeartRate_s = m_data.GetConfiguration().GetHeartRateDistributedTimeDelay(TimeUnit::s);
  double deltaNormalizedHeartRate = (1.0 / tauHeartRate_s) * (-normalizedHeartRate + m_normalizedAlphaHeartRate * sympatheticFraction - m_normalizedBetaHeartRate * parasympatheticFraction + m_normalizedGammaHeartRate) * m_dt_s;
  normalizedHeartRate += deltaNormalizedHeartRate;
  GetBaroreceptorHeartRateScale().SetValue(normalizedHeartRate);
  double normalizedHeartElastance = GetBaroreceptorHeartElastanceScale().GetValue();
  double tauElastance_s = m_data.GetConfiguration().GetHeartElastanceDistributedTimeDelay(TimeUnit::s);
  double deltaNormalizedHeartElastance = (1.0 / tauElastance_s) * (-normalizedHeartElastance + m_normalizedAlphaElastance * sympatheticFraction + m_normalizedGammaElastance) * m_dt_s;
  normalizedHeartElastance += deltaNormalizedHeartElastance;
  GetBaroreceptorHeartElastanceScale().SetValue(normalizedHeartElastance);
  double normalizedResistance = GetBaroreceptorResistanceScale().GetValue();
  double tauResistance_s = m_data.GetConfiguration().GetSystemicResistanceDistributedTimeDelay(TimeUnit::s);
  double deltaNormalizedResistance = (1.0 / tauResistance_s) * (-normalizedResistance + m_normalizedAlphaResistance * sympatheticFraction + m_normalizedGammaResistance) * m_dt_s;
  normalizedResistance += deltaNormalizedResistance;
  GetBaroreceptorResistanceScale().SetValue(normalizedResistance);
  double normalizedCompliance = GetBaroreceptorComplianceScale().GetValue();
  double tauCompliance_s = m_data.GetConfiguration().GetVenousComplianceDistributedTimeDelay(TimeUnit::s);
  double deltaNormalizedCompliance = (1.0 / tauCompliance_s) * (-normalizedCompliance + m_normalizedAlphaCompliance * parasympatheticFraction + m_normalizedGammaCompliance) * m_dt_s;
  normalizedCompliance += deltaNormalizedCompliance;
  GetBaroreceptorComplianceScale().SetValue(normalizedCompliance);
#ifdef VERBOSE
  m_data.GetDataTrack().Probe("normalizedHeartRate", normalizedHeartRate);
  m_data.GetDataTrack().Probe("normalizedHeartElastance", normalizedHeartElastance);
  m_data.GetDataTrack().Probe("normalizedResistance", normalizedResistance);
  m_data.GetDataTrack().Probe("normalizedCompliance", normalizedCompliance);
  m_data.GetDataTrack().Probe("meanArterialPressureSetPoint_mmHg", meanArterialPressureSetPoint_mmHg);
#endif
}
void Nervous :: BaroreceptorFeedback ( ) { if ( ! m_FeedbackActive ) return ; double nu = m_data . GetConfiguration ( ) . GetResponseSlope ( ) ; double meanArterialPressure_mmHg = m_data . GetCardiovascular ( ) . GetMeanArterialPressure ( PressureUnit :: mmHg ) ; double meanArterialPressureSetPoint_mmHg = m_data . GetPatient ( ) . GetMeanArterialPressureBaseline ( PressureUnit :: mmHg ) + m_data . GetEnergy ( ) . GetExerciseMeanArterialPressureDelta ( PressureUnit :: mmHg ) ; for ( SESubstance * sub : m_data . GetCompartments ( ) . GetLiquidCompartmentSubstances ( ) ) { if ( ! sub -> HasPD ( ) ) continue ; if ( ( sub -> GetClassification ( ) == CDM :: enumSubstanceClass :: Anesthetic ) || ( sub -> GetClassification ( ) == CDM :: enumSubstanceClass :: Sedative ) || ( sub -> GetClassification ( ) == CDM :: enumSubstanceClass :: Opioid ) ) { meanArterialPressureSetPoint_mmHg += m_data . GetDrugs ( ) . GetMeanBloodPressureChange ( PressureUnit :: mmHg ) ; break ; } } double sympatheticFraction = 1.0 / ( 1.0 + pow ( meanArterialPressure_mmHg / meanArterialPressureSetPoint_mmHg , nu ) ) ; double parasympatheticFraction = 1.0 / ( 1.0 + pow ( meanArterialPressure_mmHg / meanArterialPressureSetPoint_mmHg , - nu ) ) ; double normalizedHeartRate = GetBaroreceptorHeartRateScale ( ) . GetValue ( ) ; double tauHeartRate_s = m_data . GetConfiguration ( ) . GetHeartRateDistributedTimeDelay ( TimeUnit :: s ) ; double deltaNormalizedHeartRate = ( 1.0 / tauHeartRate_s ) * ( - normalizedHeartRate + m_normalizedAlphaHeartRate * sympatheticFraction - m_normalizedBetaHeartRate * parasympatheticFraction + m_normalizedGammaHeartRate ) * m_dt_s ; normalizedHeartRate += deltaNormalizedHeartRate ; GetBaroreceptorHeartRateScale ( ) . SetValue ( normalizedHeartRate ) ; double normalizedHeartElastance = GetBaroreceptorHeartElastanceScale ( ) . GetValue ( ) ; double tauElastance_s = m_data . GetConfiguration ( ) . GetHeartElastanceDistributedTimeDelay ( TimeUnit :: s ) ; double deltaNormalizedHeartElastance = ( 1.0 / tauElastance_s ) * ( - normalizedHeartElastance + m_normalizedAlphaElastance * sympatheticFraction + m_normalizedGammaElastance ) * m_dt_s ; normalizedHeartElastance += deltaNormalizedHeartElastance ; GetBaroreceptorHeartElastanceScale ( ) . SetValue ( normalizedHeartElastance ) ; double normalizedResistance = GetBaroreceptorResistanceScale ( ) . GetValue ( ) ; double tauResistance_s = m_data . GetConfiguration ( ) . GetSystemicResistanceDistributedTimeDelay ( TimeUnit :: s ) ; double deltaNormalizedResistance = ( 1.0 / tauResistance_s ) * ( - normalizedResistance + m_normalizedAlphaResistance * sympatheticFraction + m_normalizedGammaResistance ) * m_dt_s ; normalizedResistance += deltaNormalizedResistance ; GetBaroreceptorResistanceScale ( ) . SetValue ( normalizedResistance ) ; double normalizedCompliance = GetBaroreceptorComplianceScale ( ) . GetValue ( ) ; double tauCompliance_s = m_data . GetConfiguration ( ) . GetVenousComplianceDistributedTimeDelay ( TimeUnit :: s ) ; double deltaNormalizedCompliance = ( 1.0 / tauCompliance_s ) * ( - normalizedCompliance + m_normalizedAlphaCompliance * parasympatheticFraction + m_normalizedGammaCompliance ) * m_dt_s ; normalizedCompliance += deltaNormalizedCompliance ; GetBaroreceptorComplianceScale ( ) . SetValue ( normalizedCompliance ) ; #ifdef VERBOSE m_data . GetDataTrack ( ) . Probe ( " " , normalizedHeartRate ) ; m_data . GetDataTrack ( ) . Probe ( " " , normalizedHeartElastance ) ; m_data . GetDataTrack ( ) . Probe ( " " , normalizedResistance ) ; m_data . GetDataTrack ( ) . Probe ( " " , normalizedCompliance ) ; m_data . GetDataTrack ( ) . Probe ( " " , meanArterialPressureSetPoint_mmHg ) ; #endif }
\brief
Calculates the baroreceptor feedback and sets the scaling parameters in the CDM
\ brief Calculates the baroreceptor feedback and sets the scaling parameters in the CDM
//First calculate the sympathetic and parasympathetic firing rates: //Adjusting the mean arterial pressure set-point to account for cardiovascular drug effects //m_MeanArterialPressureNoFeedbackBaseline_mmHg //Adjust the MAP set-point for baroreceptors for anesthetics, opioids, and sedatives.  Other drugs should leave set-point as is. //Only want to apply the blood pressure change ONCE (In case there are multiple sedative/opioids/etc) ///\TODO:  Look into a better way to implement drug classification search //Calculate the normalized change in heart rate //Calculate the normalized change in heart elastance //Calculate the normalized change in flow resistance for any cardiovascular resistor //Calculate the normalized change in flow compliance for any cardiovascular compliance