feat: Implement major physiological feedback loops
This commit re-implements several critical physiological feedback loops that were lost, enhancing the realism of the simulation.
The following systems have been added:
1. **Full Digestive Loop:**
- The Gallbladder now has a `releaseBile` method, triggered by chyme in the intestines.
- The Pancreas has a `releaseEnzymes` method, also triggered by chyme.
- The Intestines' digestion logic has been updated to be more effective when bile and enzymes are present.
2. **Autonomic Nervous System Control:**
- The Brain now monitors blood gas (O2/CO2) and blood pressure levels.
- It dynamically adjusts the respiration rate of the Lungs via a new `setRespirationRate` method in response to blood gas changes.
- It controls the heart rate via a new `setHeartRate` method in response to blood pressure changes, simulating the baroreceptor reflex.
- The previous hardcoded rate control logic in the Lungs and Heart has been removed.
3. **Kidney Blood Pressure Regulation (RAAS):**
- A simplified Renin-Angiotensin-Aldosterone System has been implemented.
- The Kidneys now secrete renin in response to low blood pressure.
- The Liver produces a constant supply of angiotensinogen.
- A new `angiotensin_au` value in the Blood struct is calculated in the main patient update loop.
- This hormone now acts as a vasoconstrictor, directly affecting the blood pressure calculation in the Heart.
These changes significantly increase the complexity and fidelity of the medical simulation by modeling the interconnectedness of the major organ systems.
This commit is contained in:
+63
-8
@@ -1,5 +1,7 @@
|
||||
#include "MedicalLib/Intestines.h"
|
||||
#include "MedicalLib/Patient.h"
|
||||
#include "MedicalLib/Gallbladder.h"
|
||||
#include "MedicalLib/Pancreas.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
@@ -15,7 +17,11 @@ static double getFluctuation(double stddev) {
|
||||
|
||||
Intestines::Intestines(int id)
|
||||
: Organ(id, "Intestines"),
|
||||
chymeVolume_mL(0.0) {
|
||||
chymeVolume_mL(0.0),
|
||||
bileVolume_mL(0.0),
|
||||
enzymeVolume_mL(0.0),
|
||||
amylase_U_per_L(0.0),
|
||||
lipase_U_per_L(0.0) {
|
||||
|
||||
// Initialize segments with typical values
|
||||
duodenum = {"Duodenum", 0.25, 1.0, 0.5, 0.1};
|
||||
@@ -26,18 +32,49 @@ Intestines::Intestines(int id)
|
||||
|
||||
void Intestines::update(Patient& patient, double deltaTime_s) {
|
||||
if (chymeVolume_mL > 0) {
|
||||
// Simplified absorption model: total absorption is an average of all segments
|
||||
double totalNutrientAbsorption = (duodenum.nutrientAbsorptionRate + jejunum.nutrientAbsorptionRate + ileum.nutrientAbsorptionRate + colon.nutrientAbsorptionRate) / 4.0;
|
||||
double totalWaterAbsorption = (duodenum.waterAbsorptionRate + jejunum.waterAbsorptionRate + ileum.waterAbsorptionRate + colon.waterAbsorptionRate) / 4.0;
|
||||
// 1. Signal Gallbladder and Pancreas to release substances
|
||||
if (Gallbladder* gallbladder = getOrgan<Gallbladder>(patient)) {
|
||||
double bileReleased = gallbladder->releaseBile(deltaTime_s);
|
||||
receiveBile(bileReleased);
|
||||
}
|
||||
if (Pancreas* pancreas = getOrgan<Pancreas>(patient)) {
|
||||
DigestiveEnzymes enzymesReleased = pancreas->releaseEnzymes(deltaTime_s);
|
||||
receiveEnzymes(enzymesReleased);
|
||||
}
|
||||
|
||||
// 2. Digestion and Absorption
|
||||
// Bile helps emulsify fats, enzymes break down nutrients.
|
||||
// We'll model this as a "digestion efficiency" multiplier.
|
||||
double digestionEfficiency = 1.0;
|
||||
if (bileVolume_mL > 0 && enzymeVolume_mL > 0) {
|
||||
digestionEfficiency = 5.0; // 5x more effective with bile and enzymes
|
||||
}
|
||||
|
||||
// Simplified absorption model
|
||||
double totalNutrientAbsorptionRate = (duodenum.nutrientAbsorptionRate + jejunum.nutrientAbsorptionRate + ileum.nutrientAbsorptionRate) * digestionEfficiency;
|
||||
double totalWaterAbsorptionRate = (duodenum.waterAbsorptionRate + jejunum.waterAbsorptionRate + ileum.waterAbsorptionRate + colon.waterAbsorptionRate);
|
||||
|
||||
// Absorb glucose into the blood
|
||||
double glucoseAbsorption = totalNutrientAbsorption * chymeVolume_mL * 0.001 * deltaTime_s;
|
||||
double glucoseAbsorption = totalNutrientAbsorptionRate * chymeVolume_mL * 0.001 * deltaTime_s;
|
||||
patient.blood.glucose_mg_per_dL += glucoseAbsorption;
|
||||
|
||||
// Reduce chyme volume based on absorption
|
||||
double absorbedVolume = (totalNutrientAbsorption * 0.01 + totalWaterAbsorption * 0.1) * deltaTime_s;
|
||||
// Reduce chyme/bile/enzyme volume based on absorption and processing
|
||||
double absorbedVolume = (totalNutrientAbsorptionRate * 0.01 + totalWaterAbsorptionRate * 0.1) * deltaTime_s;
|
||||
chymeVolume_mL -= absorbedVolume;
|
||||
|
||||
// As chyme is processed, bile and enzymes are used up
|
||||
bileVolume_mL -= 0.1 * bileVolume_mL * deltaTime_s;
|
||||
enzymeVolume_mL -= 0.1 * enzymeVolume_mL * deltaTime_s;
|
||||
|
||||
// Clamp volumes to zero
|
||||
chymeVolume_mL = std::max(0.0, chymeVolume_mL);
|
||||
bileVolume_mL = std::max(0.0, bileVolume_mL);
|
||||
enzymeVolume_mL = std::max(0.0, enzymeVolume_mL);
|
||||
|
||||
if (enzymeVolume_mL == 0.0) {
|
||||
amylase_U_per_L = 0.0;
|
||||
lipase_U_per_L = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Fluctuate motility slightly
|
||||
@@ -49,12 +86,30 @@ void Intestines::receiveChyme(double volume_mL) {
|
||||
chymeVolume_mL += volume_mL;
|
||||
}
|
||||
|
||||
void Intestines::receiveBile(double volume_mL) {
|
||||
bileVolume_mL += volume_mL;
|
||||
}
|
||||
|
||||
void Intestines::receiveEnzymes(const DigestiveEnzymes& enzymes) {
|
||||
if (enzymes.volume_mL <= 0) return;
|
||||
|
||||
// Calculate new weighted average of enzyme concentration
|
||||
double total_enzyme_vol = enzymeVolume_mL + enzymes.volume_mL;
|
||||
amylase_U_per_L = (amylase_U_per_L * enzymeVolume_mL + enzymes.amylase_U_per_L * enzymes.volume_mL) / total_enzyme_vol;
|
||||
lipase_U_per_L = (lipase_U_per_L * enzymeVolume_mL + enzymes.lipase_U_per_L * enzymes.volume_mL) / total_enzyme_vol;
|
||||
enzymeVolume_mL = total_enzyme_vol;
|
||||
}
|
||||
|
||||
std::string Intestines::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss.precision(2);
|
||||
ss << std::fixed;
|
||||
ss << "--- Intestines Summary ---\n"
|
||||
<< "Total Chyme Volume: " << getTotalChymeVolume() << " mL\n\n"
|
||||
<< "Chyme Volume: " << getTotalChymeVolume() << " mL\n"
|
||||
<< "Bile Volume: " << bileVolume_mL << " mL\n"
|
||||
<< "Enzyme Volume: " << enzymeVolume_mL << " mL\n"
|
||||
<< "Amylase: " << amylase_U_per_L << " U/L\n"
|
||||
<< "Lipase: " << lipase_U_per_L << " U/L\n\n"
|
||||
<< "--- Segments ---\n"
|
||||
<< duodenum.name << ": Motility " << duodenum.motility << "\n"
|
||||
<< jejunum.name << ": Nutrient Abs. " << jejunum.nutrientAbsorptionRate << "\n"
|
||||
|
||||
Reference in New Issue
Block a user