feat: Add detailed simulation to remaining simple organs
This commit applies a detailed physiological model to all remaining simple organ classes, bringing them to a level of complexity consistent with the Heart, Lungs, and Brain. Updates include: - Esophagus: Simulates peristalsis and bolus movement. - Stomach: Implements a gastric state machine for digestion. - Intestines: Adds segments (duodenum, jejunum, etc.) and simulates absorption. - Pancreas: Differentiates endocrine and exocrine functions. - Gallbladder: Simulates storing, concentrating, and releasing bile. - Kidneys: Models nephrons, GFR, and electrolyte balance. - Bladder: Implements a micturition cycle with pressure dynamics. - Spleen: Models red and white pulp for blood filtering and immunity.
This commit is contained in:
@@ -1,24 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief Represents the Bladder.
|
||||
* @brief Represents the state of the bladder muscles and sphincters.
|
||||
*/
|
||||
enum class MicturitionState {
|
||||
FILLING,
|
||||
FULL,
|
||||
VOIDING
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the Bladder, which stores urine.
|
||||
*/
|
||||
class MEDICAL_LIB_API Bladder : public Organ {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the Bladder class.
|
||||
* @param id The ID of the organ.
|
||||
*/
|
||||
Bladder(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the bladder's state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
|
||||
/**
|
||||
* @brief Gets a string summary of the bladder's state.
|
||||
* @return A string containing the bladder's state.
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
// Note: A real model would get urine input from kidneys.
|
||||
// For now, it will just fill at a constant rate.
|
||||
/**
|
||||
* @brief Adds urine from the kidneys.
|
||||
* @param amount_ml The volume of urine to add.
|
||||
*/
|
||||
void addUrine(double amount_ml);
|
||||
|
||||
double getCurrentVolume() const;
|
||||
double getCapacity() const;
|
||||
// --- Getters for Bladder State ---
|
||||
|
||||
/** @brief Gets the current volume of urine in the bladder in mL. */
|
||||
double getVolume() const;
|
||||
|
||||
/** @brief Gets the current pressure inside the bladder in cmH2O. */
|
||||
double getPressure() const;
|
||||
|
||||
/** @brief Gets the current state of the micturition cycle. */
|
||||
MicturitionState getCurrentState() const;
|
||||
|
||||
private:
|
||||
double currentVolume; // in ml
|
||||
double capacity; // in ml
|
||||
// --- Helper to convert enum to string ---
|
||||
std::string stateToString(MicturitionState state) const;
|
||||
|
||||
// --- Physiological Parameters ---
|
||||
MicturitionState currentState;
|
||||
double currentVolume_mL;
|
||||
double pressure_cmH2O;
|
||||
bool internalSphincterClosed;
|
||||
|
||||
const double capacity_mL = 500.0;
|
||||
const double pressureThreshold_cmH2O = 40.0; // Pressure at which voiding reflex is strong
|
||||
};
|
||||
|
||||
@@ -1,19 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief Represents the Esophagus.
|
||||
* @note This is a placeholder with minimal logic for now.
|
||||
* @brief Represents the state of esophageal muscle contraction.
|
||||
*/
|
||||
enum class PeristalsisState {
|
||||
IDLE,
|
||||
CONTRACTING,
|
||||
RELAXING
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a small mass of chewed food.
|
||||
*/
|
||||
struct Bolus {
|
||||
double volume_mL;
|
||||
double position_cm; // Position from the top of the esophagus
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the Esophagus with a more detailed physiological model.
|
||||
*/
|
||||
class MEDICAL_LIB_API Esophagus : public Organ {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the Esophagus class.
|
||||
* @param id The ID of the organ.
|
||||
*/
|
||||
Esophagus(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the esophagus state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
|
||||
/**
|
||||
* @brief Gets a string summary of the esophagus's state.
|
||||
* @return A string containing the esophagus's state.
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
double getMotility() const; // Peristalsis efficiency
|
||||
/**
|
||||
* @brief Initiates a swallow.
|
||||
* @param bolusVolume_mL The volume of the bolus being swallowed.
|
||||
*/
|
||||
void initiateSwallow(double bolusVolume_mL);
|
||||
|
||||
// --- Getters for Esophageal State ---
|
||||
|
||||
/** @brief Gets the current state of peristalsis. */
|
||||
PeristalsisState getCurrentState() const;
|
||||
|
||||
/** @brief Checks if a bolus is currently being swallowed. */
|
||||
bool isSwallowing() const;
|
||||
|
||||
private:
|
||||
double motility;
|
||||
// --- Helper to convert enum to string ---
|
||||
std::string stateToString(PeristalsisState state) const;
|
||||
|
||||
// --- Physiological Parameters ---
|
||||
PeristalsisState currentState;
|
||||
double lowerEsophagealSphincterTone; // Pressure in mmHg
|
||||
|
||||
// --- Simulation State ---
|
||||
std::vector<Bolus> activeBoli;
|
||||
const double length_cm = 25.0; // Average length of esophagus
|
||||
};
|
||||
|
||||
@@ -1,18 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief Represents the Gallbladder.
|
||||
* @brief Represents the contraction state of the gallbladder.
|
||||
*/
|
||||
enum class GallbladderState {
|
||||
STORING,
|
||||
CONTRACTING
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the Gallbladder, which stores and concentrates bile.
|
||||
*/
|
||||
class MEDICAL_LIB_API Gallbladder : public Organ {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the Gallbladder class.
|
||||
* @param id The ID of the organ.
|
||||
*/
|
||||
Gallbladder(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the gallbladder's state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
|
||||
/**
|
||||
* @brief Gets a string summary of the gallbladder's state.
|
||||
* @return A string containing the gallbladder's state.
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
double getBileStored() const;
|
||||
/**
|
||||
* @brief Adds bile from the liver.
|
||||
* @param volume_mL The volume of bile to add.
|
||||
*/
|
||||
void storeBile(double volume_mL);
|
||||
|
||||
// --- Getters for Gallbladder State ---
|
||||
|
||||
/** @brief Gets the current volume of stored bile in mL. */
|
||||
double getStoredBileVolume() const;
|
||||
|
||||
/** @brief Gets the concentration factor of the stored bile. */
|
||||
double getBileConcentration() const;
|
||||
|
||||
/** @brief Gets the current state of the gallbladder. */
|
||||
GallbladderState getCurrentState() const;
|
||||
|
||||
private:
|
||||
double bileStored; // in ml
|
||||
// --- Helper to convert enum to string ---
|
||||
std::string stateToString(GallbladderState state) const;
|
||||
|
||||
// --- Physiological Parameters ---
|
||||
GallbladderState currentState;
|
||||
double storedBile_mL;
|
||||
double bileConcentrationFactor; // How concentrated the bile is (1x, 5x, etc.)
|
||||
const double capacity_mL = 50.0;
|
||||
};
|
||||
|
||||
@@ -1,20 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief Represents the Intestines (Small and Large combined).
|
||||
* @brief Represents a segment of the intestines.
|
||||
*/
|
||||
struct IntestinalSegment {
|
||||
std::string name;
|
||||
double length_m;
|
||||
double motility; // Rate of chyme movement
|
||||
double nutrientAbsorptionRate;
|
||||
double waterAbsorptionRate;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the Intestines (Small and Large) with a more detailed model.
|
||||
*/
|
||||
class MEDICAL_LIB_API Intestines : public Organ {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the Intestines class.
|
||||
* @param id The ID of the organ.
|
||||
*/
|
||||
Intestines(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the intestines' state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
|
||||
/**
|
||||
* @brief Gets a string summary of the intestines' state.
|
||||
* @return A string containing the intestines' state.
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
double getNutrientAbsorptionRate() const;
|
||||
double getWaterAbsorptionRate() const;
|
||||
/**
|
||||
* @brief Adds chyme from the stomach to the duodenum.
|
||||
* @param volume_mL The volume of chyme.
|
||||
*/
|
||||
void receiveChyme(double volume_mL);
|
||||
|
||||
// --- Getters for Intestinal State ---
|
||||
|
||||
/** @brief Gets the total volume of chyme currently in the intestines. */
|
||||
double getTotalChymeVolume() const;
|
||||
|
||||
private:
|
||||
double nutrientAbsorptionRate; // in arbitrary units
|
||||
double waterAbsorptionRate; // in ml/s
|
||||
// --- Anatomical Components ---
|
||||
IntestinalSegment duodenum;
|
||||
IntestinalSegment jejunum;
|
||||
IntestinalSegment ileum;
|
||||
IntestinalSegment colon;
|
||||
|
||||
// --- Simulation State ---
|
||||
double chymeVolume_mL; // Total volume in the whole system for now
|
||||
};
|
||||
|
||||
@@ -1,20 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief Represents the Kidneys.
|
||||
* @brief Represents a functional unit of the kidney.
|
||||
*/
|
||||
struct Nephron {
|
||||
std::string id;
|
||||
double filtrationEfficiency; // 0.0 to 1.0
|
||||
bool isDamaged;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the Kidneys, responsible for filtering blood and producing urine.
|
||||
*/
|
||||
class MEDICAL_LIB_API Kidneys : public Organ {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the Kidneys class.
|
||||
* @param id The ID of the organ.
|
||||
*/
|
||||
Kidneys(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the kidneys' state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
|
||||
/**
|
||||
* @brief Gets a string summary of the kidneys' state.
|
||||
* @return A string containing the kidneys' state.
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
double getFiltrationRate() const;
|
||||
double getUrineProductionRate() const;
|
||||
// --- Getters for Renal Function ---
|
||||
|
||||
/** @brief Gets the Glomerular Filtration Rate (GFR) in mL/min. */
|
||||
double getGfr() const;
|
||||
|
||||
/** @brief Gets the rate of urine production in mL/s. */
|
||||
double getUrineOutputRate() const;
|
||||
|
||||
/** @brief Gets the simulated blood sodium level in mEq/L. */
|
||||
double getBloodSodium() const;
|
||||
|
||||
/** @brief Gets the simulated blood potassium level in mEq/L. */
|
||||
double getBloodPotassium() const;
|
||||
|
||||
private:
|
||||
double filtrationRate; // in ml/min
|
||||
double urineProductionRate; // in ml/s
|
||||
// --- Physiological Parameters ---
|
||||
double gfr_mL_per_min;
|
||||
double urineOutput_mL_per_s;
|
||||
double bloodSodium_mEq_per_L;
|
||||
double bloodPotassium_mEq_per_L;
|
||||
|
||||
// --- Anatomical Components ---
|
||||
std::vector<Nephron> nephrons;
|
||||
double totalFiltrationCapacity;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief Represents the Liver organ.
|
||||
* @brief Represents a functional unit of the liver.
|
||||
*/
|
||||
struct HepaticLobule {
|
||||
std::string id;
|
||||
double metabolicActivity; // A factor from 0.0 to 1.0+
|
||||
bool isDamaged;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the Liver organ with a more detailed physiological model.
|
||||
*/
|
||||
class MEDICAL_LIB_API Liver : public Organ {
|
||||
public:
|
||||
@@ -14,7 +25,7 @@ public:
|
||||
Liver(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the liver's state over time.
|
||||
* @brief Updates the liver's state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
@@ -25,11 +36,32 @@ public:
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
// Specific getters for Liver properties
|
||||
double getBileProductionRate() const; // in ml/s
|
||||
double getGlucoseProductionRate() const; // in g/s
|
||||
// --- Getters for Key Metabolic Vitals ---
|
||||
|
||||
/** @brief Gets the rate of bile production in mL/min. */
|
||||
double getBileProductionRate() const;
|
||||
|
||||
/** @brief Gets the rate of glucose production (gluconeogenesis) in g/min. */
|
||||
double getGlucoseProductionRate() const;
|
||||
|
||||
/** @brief Gets the Alanine Aminotransferase (ALT) level in U/L. */
|
||||
double getAltLevel() const;
|
||||
|
||||
/** @brief Gets the Aspartate Aminotransferase (AST) level in U/L. */
|
||||
double getAstLevel() const;
|
||||
|
||||
/** @brief Gets the total bilirubin level in mg/dL. */
|
||||
double getBilirubinLevel() const;
|
||||
|
||||
private:
|
||||
double bileProductionRate;
|
||||
double glucoseProductionRate;
|
||||
// --- Physiological Parameters ---
|
||||
double bileProductionRate_ml_per_s;
|
||||
double glucoseProductionRate_g_per_s;
|
||||
double alt_U_per_L; ///< Alanine Aminotransferase
|
||||
double ast_U_per_L; ///< Aspartate Aminotransferase
|
||||
double bilirubin_mg_per_dL; ///< Total bilirubin
|
||||
|
||||
// --- Anatomical Components ---
|
||||
std::vector<HepaticLobule> lobules;
|
||||
double totalMetabolicCapacity;
|
||||
};
|
||||
|
||||
@@ -1,20 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief Represents the Pancreas, with both endocrine and exocrine functions.
|
||||
*/
|
||||
class MEDICAL_LIB_API Pancreas : public Organ {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the Pancreas class.
|
||||
* @param id The ID of the organ.
|
||||
*/
|
||||
Pancreas(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the pancreas's state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
|
||||
/**
|
||||
* @brief Gets a string summary of the pancreas's state.
|
||||
* @return A string containing the pancreas's state.
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
double getInsulinProduction() const;
|
||||
double getGlucagonProduction() const;
|
||||
// --- Getters for Endocrine Functions (Hormones) ---
|
||||
|
||||
/** @brief Gets the current insulin secretion rate in units/hr. */
|
||||
double getInsulinSecretion() const;
|
||||
|
||||
/** @brief Gets the current glucagon secretion rate in ng/hr. */
|
||||
double getGlucagonSecretion() const;
|
||||
|
||||
// --- Getters for Exocrine Functions (Enzymes) ---
|
||||
|
||||
/** @brief Gets the current amylase secretion rate in U/L. */
|
||||
double getAmylaseSecretion() const;
|
||||
|
||||
/** @brief Gets the current lipase secretion rate in U/L. */
|
||||
double getLipaseSecretion() const;
|
||||
|
||||
private:
|
||||
double insulinProduction; // in units/hr
|
||||
double glucagonProduction; // in ng/hr
|
||||
// --- Endocrine Parameters ---
|
||||
double insulinSecretion_units_per_hr;
|
||||
double glucagonSecretion_ng_per_hr;
|
||||
|
||||
// --- Exocrine Parameters ---
|
||||
double amylaseSecretion_U_per_L;
|
||||
double lipaseSecretion_U_per_L;
|
||||
};
|
||||
|
||||
@@ -1,18 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief Represents the Spinal Cord.
|
||||
* @brief Represents the functional status of a neural pathway.
|
||||
*/
|
||||
enum class SignalStatus {
|
||||
NORMAL,
|
||||
IMPAIRED,
|
||||
SEVERED
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a major bundle of nerve fibers in the spinal cord.
|
||||
*/
|
||||
struct SpinalTract {
|
||||
std::string name;
|
||||
SignalStatus status;
|
||||
double conductionVelocity_m_per_s;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the Spinal Cord with a more detailed physiological model.
|
||||
*/
|
||||
class MEDICAL_LIB_API SpinalCord : public Organ {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the SpinalCord class.
|
||||
* @param id The ID of the organ.
|
||||
*/
|
||||
SpinalCord(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the spinal cord's state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
|
||||
/**
|
||||
* @brief Gets a string summary of the spinal cord's vitals.
|
||||
* @return A string containing the spinal cord's vital signs.
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
double getSignalConductionVelocity() const; // in m/s
|
||||
// --- Getters for Key Neurological Pathways ---
|
||||
|
||||
/** @brief Gets the status of the primary motor pathways. */
|
||||
SignalStatus getMotorPathwayStatus() const;
|
||||
|
||||
/** @brief Gets the status of the primary sensory pathways. */
|
||||
SignalStatus getSensoryPathwayStatus() const;
|
||||
|
||||
/** @brief Gets the status of a basic reflex arc. */
|
||||
bool isReflexArcIntact() const;
|
||||
|
||||
private:
|
||||
double signalConductionVelocity;
|
||||
// --- Helper to convert enum to string ---
|
||||
std::string statusToString(SignalStatus status) const;
|
||||
|
||||
// --- Anatomical Components ---
|
||||
SpinalTract descendingMotorTract;
|
||||
SpinalTract ascendingSensoryTract;
|
||||
|
||||
// --- Physiological Parameters ---
|
||||
bool reflexArcIntact; // Simplified representation of a reflex (e.g., patellar)
|
||||
};
|
||||
|
||||
@@ -1,20 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief Represents the Spleen.
|
||||
* @brief Represents the red pulp, responsible for filtering blood.
|
||||
*/
|
||||
struct RedPulp {
|
||||
double filtrationRate; // Arbitrary units
|
||||
double rbcBreakdownRate; // Rate of old red blood cell removal
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the white pulp, part of the immune system.
|
||||
*/
|
||||
struct WhitePulp {
|
||||
double lymphocyteCount; // in millions
|
||||
double macrophageCount; // in millions
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the Spleen, involved in blood filtering and immunity.
|
||||
*/
|
||||
class MEDICAL_LIB_API Spleen : public Organ {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the Spleen class.
|
||||
* @param id The ID of the organ.
|
||||
*/
|
||||
Spleen(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the spleen's state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
|
||||
/**
|
||||
* @brief Gets a string summary of the spleen's state.
|
||||
* @return A string containing the spleen's state.
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
double getRedBloodCellCount() const;
|
||||
double getWhiteBloodCellCount() const;
|
||||
// --- Getters for Spleen Function ---
|
||||
|
||||
/** @brief Gets the rate of red blood cell breakdown. */
|
||||
double getRbcBreakdownRate() const;
|
||||
|
||||
/** @brief Gets the total lymphocyte count in the white pulp. */
|
||||
double getLymphocyteCount() const;
|
||||
|
||||
private:
|
||||
double redBloodCellCount; // in millions/uL
|
||||
double whiteBloodCellCount; // in thousands/uL
|
||||
// --- Anatomical Components ---
|
||||
RedPulp redPulp;
|
||||
WhitePulp whitePulp;
|
||||
};
|
||||
|
||||
@@ -1,20 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#include "Organ.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief Represents the Stomach.
|
||||
* @brief Represents the current digestive state of the stomach.
|
||||
*/
|
||||
enum class GastricState {
|
||||
EMPTY,
|
||||
FILLING,
|
||||
DIGESTING,
|
||||
EMPTYING
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the mixture of partially digested food and gastric juices.
|
||||
*/
|
||||
struct Chyme {
|
||||
double volume_mL;
|
||||
double acidity_pH;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the Stomach with a more detailed physiological model.
|
||||
*/
|
||||
class MEDICAL_LIB_API Stomach : public Organ {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor for the Stomach class.
|
||||
* @param id The ID of the organ.
|
||||
*/
|
||||
Stomach(int id);
|
||||
|
||||
/**
|
||||
* @brief Updates the stomach state over a time interval.
|
||||
* @param deltaTime_s The time elapsed in seconds.
|
||||
*/
|
||||
void update(double deltaTime_s) override;
|
||||
|
||||
/**
|
||||
* @brief Gets a string summary of the stomach's state.
|
||||
* @return A string containing the stomach's state.
|
||||
*/
|
||||
std::string getSummary() const override;
|
||||
|
||||
double getPhLevel() const;
|
||||
double getDigestionRate() const;
|
||||
/**
|
||||
* @brief Adds a substance (e.g., a bolus from the esophagus) to the stomach.
|
||||
* @param volume_mL The volume of the substance.
|
||||
*/
|
||||
void addSubstance(double volume_mL);
|
||||
|
||||
// --- Getters for Gastric State ---
|
||||
|
||||
/** @brief Gets the current gastric state. */
|
||||
GastricState getCurrentState() const;
|
||||
|
||||
/** @brief Gets the current volume of contents in the stomach in mL. */
|
||||
double getVolume() const;
|
||||
|
||||
/** @brief Gets the current pH of the stomach contents. */
|
||||
double getAcidity() const;
|
||||
|
||||
private:
|
||||
double phLevel; // Acidity
|
||||
double digestionRate; // in arbitrary units
|
||||
// --- Helper to convert enum to string ---
|
||||
std::string stateToString(GastricState state) const;
|
||||
|
||||
// --- Physiological Parameters ---
|
||||
GastricState currentState;
|
||||
double currentVolume_mL;
|
||||
double currentPh;
|
||||
double gastricJuiceSecretionRate_ml_per_s;
|
||||
double emptyingRate_ml_per_s;
|
||||
|
||||
// --- Simulation State ---
|
||||
const double capacity_mL = 1500.0;
|
||||
};
|
||||
|
||||
+69
-12
@@ -2,28 +2,85 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
Bladder::Bladder(int id) : Organ(id, "Bladder"), currentVolume(50.0), capacity(500.0) {}
|
||||
Bladder::Bladder(int id)
|
||||
: Organ(id, "Bladder"),
|
||||
currentState(MicturitionState::FILLING),
|
||||
currentVolume_mL(50.0),
|
||||
pressure_cmH2O(5.0),
|
||||
internalSphincterClosed(true) {}
|
||||
|
||||
void Bladder::update(double deltaTime_s) {
|
||||
// In a more complex model, this would be driven by kidney output.
|
||||
// For now, simulate a constant fill rate.
|
||||
const double fillRate_ml_per_s = 0.02;
|
||||
currentVolume += fillRate_ml_per_s * deltaTime_s;
|
||||
currentVolume = std::clamp(currentVolume, 0.0, capacity);
|
||||
// In a connected model, this would be called by the Kidneys.
|
||||
// For now, simulate a constant fill rate from the kidneys.
|
||||
const double urineInflow_ml_per_s = 0.02;
|
||||
if (currentState != MicturitionState::VOIDING) {
|
||||
addUrine(urineInflow_ml_per_s * deltaTime_s);
|
||||
}
|
||||
|
||||
// Simple pressure model: pressure increases with volume
|
||||
pressure_cmH2O = (currentVolume_mL / capacity_mL) * 60.0;
|
||||
|
||||
// State machine
|
||||
switch (currentState) {
|
||||
case MicturitionState::FILLING:
|
||||
if (currentVolume_mL > capacity_mL * 0.8 || pressure_cmH2O > pressureThreshold_cmH2O) {
|
||||
currentState = MicturitionState::FULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case MicturitionState::FULL:
|
||||
// For demo, automatically start voiding after 10 seconds in FULL state
|
||||
static double timeInFullState = 0.0;
|
||||
timeInFullState += deltaTime_s;
|
||||
if (timeInFullState > 10.0) {
|
||||
currentState = MicturitionState::VOIDING;
|
||||
internalSphincterClosed = false;
|
||||
timeInFullState = 0.0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MicturitionState::VOIDING:
|
||||
double voidingRate_ml_per_s = 15.0;
|
||||
currentVolume_mL -= voidingRate_ml_per_s * deltaTime_s;
|
||||
if (currentVolume_mL <= 0) {
|
||||
currentVolume_mL = 0;
|
||||
currentState = MicturitionState::FILLING;
|
||||
internalSphincterClosed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Bladder::addUrine(double amount_ml) {
|
||||
currentVolume += amount_ml;
|
||||
currentVolume = std::clamp(currentVolume, 0.0, capacity);
|
||||
if (currentState != MicturitionState::VOIDING) {
|
||||
currentVolume_mL += amount_ml;
|
||||
currentVolume_mL = std::clamp(currentVolume_mL, 0.0, capacity_mL);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Bladder::stateToString(MicturitionState state) const {
|
||||
switch (state) {
|
||||
case MicturitionState::FILLING: return "Filling";
|
||||
case MicturitionState::FULL: return "Full";
|
||||
case MicturitionState::VOIDING: return "Voiding";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string Bladder::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Volume: " << currentVolume << " / " << capacity << " ml";
|
||||
ss.precision(1);
|
||||
ss << std::fixed;
|
||||
ss << "--- Bladder Summary ---\n"
|
||||
<< "State: " << stateToString(currentState) << "\n"
|
||||
<< "Volume: " << getVolume() << " / " << capacity_mL << " mL\n"
|
||||
<< "Pressure: " << getPressure() << " cmH2O\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Bladder::getCurrentVolume() const { return currentVolume; }
|
||||
double Bladder::getCapacity() const { return capacity; }
|
||||
// --- Getters Implementation ---
|
||||
double Bladder::getVolume() const { return currentVolume_mL; }
|
||||
double Bladder::getPressure() const { return pressure_cmH2O; }
|
||||
MicturitionState Bladder::getCurrentState() const { return currentState; }
|
||||
|
||||
+58
-9
@@ -2,25 +2,74 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
Esophagus::Esophagus(int id) : Organ(id, "Esophagus"), motility(1.0) {}
|
||||
Esophagus::Esophagus(int id)
|
||||
: Organ(id, "Esophagus"),
|
||||
currentState(PeristalsisState::IDLE),
|
||||
lowerEsophagealSphincterTone(20.0) {}
|
||||
|
||||
void Esophagus::update(double deltaTime_s) {
|
||||
// Placeholder, no real logic yet.
|
||||
// Fluctuate motility slightly.
|
||||
// Simulate a swallow every 15 seconds for demonstration
|
||||
static double timeSinceLastSwallow = 0.0;
|
||||
timeSinceLastSwallow += deltaTime_s;
|
||||
if (timeSinceLastSwallow > 15.0) {
|
||||
initiateSwallow(15.0); // Swallow a 15mL bolus
|
||||
timeSinceLastSwallow = 0.0;
|
||||
}
|
||||
|
||||
if (!activeBoli.empty()) {
|
||||
currentState = PeristalsisState::CONTRACTING;
|
||||
const double peristalsisSpeed_cm_per_s = 3.0;
|
||||
|
||||
for (auto& bolus : activeBoli) {
|
||||
bolus.position_cm += peristalsisSpeed_cm_per_s * deltaTime_s;
|
||||
}
|
||||
|
||||
// Remove boli that have passed into the stomach
|
||||
activeBoli.erase(std::remove_if(activeBoli.begin(), activeBoli.end(),
|
||||
[this](const Bolus& b) { return b.position_cm >= this->length_cm; }),
|
||||
activeBoli.end());
|
||||
|
||||
if (activeBoli.empty()) {
|
||||
currentState = PeristalsisState::IDLE;
|
||||
}
|
||||
} else {
|
||||
currentState = PeristalsisState::IDLE;
|
||||
}
|
||||
|
||||
// Fluctuate LES tone slightly
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, 0.001);
|
||||
std::normal_distribution<> d(0, 0.1);
|
||||
lowerEsophagealSphincterTone += d(gen) * deltaTime_s;
|
||||
lowerEsophagealSphincterTone = std::clamp(lowerEsophagealSphincterTone, 18.0, 25.0);
|
||||
}
|
||||
|
||||
motility += d(gen) * deltaTime_s;
|
||||
motility = std::clamp(motility, 0.95, 1.05);
|
||||
void Esophagus::initiateSwallow(double bolusVolume_mL) {
|
||||
activeBoli.push_back({bolusVolume_mL, 0.0});
|
||||
}
|
||||
|
||||
std::string Esophagus::stateToString(PeristalsisState state) const {
|
||||
switch (state) {
|
||||
case PeristalsisState::IDLE: return "Idle";
|
||||
case PeristalsisState::CONTRACTING: return "Contracting";
|
||||
case PeristalsisState::RELAXING: return "Relaxing";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string Esophagus::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Motility: " << motility * 100 << "%";
|
||||
ss << "--- Esophagus Summary ---\n"
|
||||
<< "State: " << stateToString(currentState) << "\n"
|
||||
<< "LES Tone: " << std::fixed << std::setprecision(1) << lowerEsophagealSphincterTone << " mmHg\n"
|
||||
<< "Boluses in transit: " << activeBoli.size() << "\n";
|
||||
if (!activeBoli.empty()) {
|
||||
ss << " - Top bolus position: " << activeBoli.front().position_cm << " / " << length_cm << " cm\n";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Esophagus::getMotility() const { return motility; }
|
||||
PeristalsisState Esophagus::getCurrentState() const { return currentState; }
|
||||
bool Esophagus::isSwallowing() const { return !activeBoli.empty(); }
|
||||
|
||||
+63
-11
@@ -2,25 +2,77 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
Gallbladder::Gallbladder(int id) : Organ(id, "Gallbladder"), bileStored(30.0) {}
|
||||
Gallbladder::Gallbladder(int id)
|
||||
: Organ(id, "Gallbladder"),
|
||||
currentState(GallbladderState::STORING),
|
||||
storedBile_mL(30.0),
|
||||
bileConcentrationFactor(5.0) {}
|
||||
|
||||
void Gallbladder::update(double deltaTime_s) {
|
||||
// A real model would be affected by liver production and digestion.
|
||||
// For now, it just sits there with a small fluctuation.
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
std::normal_distribution<> d(0, 0.01);
|
||||
// A real model would be driven by liver output and CCK hormone for contraction.
|
||||
// For now, simulate slow storage and concentration, with a periodic contraction.
|
||||
|
||||
bileStored += d(gen) * deltaTime_s;
|
||||
bileStored = std::clamp(bileStored, 10.0, 50.0);
|
||||
// Simulate bile coming from the liver
|
||||
storeBile(0.005 * deltaTime_s); // Slow constant trickle
|
||||
|
||||
switch (currentState) {
|
||||
case GallbladderState::STORING:
|
||||
// Concentrate bile over time
|
||||
bileConcentrationFactor += 0.05 * deltaTime_s;
|
||||
bileConcentrationFactor = std::min(10.0, bileConcentrationFactor);
|
||||
|
||||
// For demo, contract every 40 seconds
|
||||
static double timeSinceContraction = 0.0;
|
||||
timeSinceContraction += deltaTime_s;
|
||||
if (timeSinceContraction > 40.0) {
|
||||
currentState = GallbladderState::CONTRACTING;
|
||||
timeSinceContraction = 0.0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GallbladderState::CONTRACTING:
|
||||
// Release bile
|
||||
double releasedBile = 2.0 * deltaTime_s;
|
||||
storedBile_mL -= releasedBile;
|
||||
|
||||
if (storedBile_mL < 5.0) { // Stop contracting when near empty
|
||||
storedBile_mL = std::max(0.0, storedBile_mL);
|
||||
bileConcentrationFactor = 1.0; // Bile is fresh
|
||||
currentState = GallbladderState::STORING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Gallbladder::storeBile(double volume_mL) {
|
||||
if (currentState == GallbladderState::STORING) {
|
||||
storedBile_mL += volume_mL;
|
||||
storedBile_mL = std::clamp(storedBile_mL, 0.0, capacity_mL);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Gallbladder::stateToString(GallbladderState state) const {
|
||||
switch (state) {
|
||||
case GallbladderState::STORING: return "Storing/Concentrating";
|
||||
case GallbladderState::CONTRACTING: return "Contracting (Releasing)";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string Gallbladder::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Bile Stored: " << bileStored << " ml";
|
||||
ss.precision(1);
|
||||
ss << std::fixed;
|
||||
ss << "--- Gallbladder Summary ---\n"
|
||||
<< "State: " << stateToString(currentState) << "\n"
|
||||
<< "Volume: " << getStoredBileVolume() << " / " << capacity_mL << " mL\n"
|
||||
<< "Concentration: " << getBileConcentration() << "x\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Gallbladder::getBileStored() const { return bileStored; }
|
||||
// --- Getters Implementation ---
|
||||
double Gallbladder::getStoredBileVolume() const { return storedBile_mL; }
|
||||
double Gallbladder::getBileConcentration() const { return bileConcentrationFactor; }
|
||||
GallbladderState Gallbladder::getCurrentState() const { return currentState; }
|
||||
|
||||
+46
-15
@@ -2,6 +2,7 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
@@ -11,29 +12,59 @@ static double getFluctuation(double stddev) {
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Intestines::Intestines(int id) : Organ(id, "Intestines"), nutrientAbsorptionRate(1.0), waterAbsorptionRate(0.1) {}
|
||||
Intestines::Intestines(int id)
|
||||
: Organ(id, "Intestines"),
|
||||
chymeVolume_mL(0.0) {
|
||||
|
||||
// Initialize segments with typical values
|
||||
duodenum = {"Duodenum", 0.25, 1.0, 0.5, 0.1};
|
||||
jejunum = {"Jejunum", 2.5, 1.0, 1.0, 0.3};
|
||||
ileum = {"Ileum", 3.0, 1.0, 0.8, 0.5};
|
||||
colon = {"Colon", 1.5, 0.5, 0.1, 1.0}; // High water absorption
|
||||
}
|
||||
|
||||
void Intestines::update(double deltaTime_s) {
|
||||
const double baseline_nutrient_abs = 1.0;
|
||||
const double baseline_water_abs = 0.1;
|
||||
const double theta = 0.05;
|
||||
const double nutrient_abs_stddev = 0.02;
|
||||
const double water_abs_stddev = 0.005;
|
||||
// For demonstration, simulate chyme arriving from the stomach
|
||||
static double timeSinceChyme = 0.0;
|
||||
timeSinceChyme += deltaTime_s;
|
||||
if (timeSinceChyme > 25.0) {
|
||||
receiveChyme(10.0); // Receive 10mL of chyme
|
||||
timeSinceChyme = 0.0;
|
||||
}
|
||||
|
||||
nutrientAbsorptionRate += theta * (baseline_nutrient_abs - nutrientAbsorptionRate) * deltaTime_s + getFluctuation(nutrient_abs_stddev * deltaTime_s);
|
||||
waterAbsorptionRate += theta * (baseline_water_abs - waterAbsorptionRate) * deltaTime_s + getFluctuation(water_abs_stddev * 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;
|
||||
|
||||
nutrientAbsorptionRate = std::clamp(nutrientAbsorptionRate, 0.8, 1.2);
|
||||
waterAbsorptionRate = std::clamp(waterAbsorptionRate, 0.08, 0.12);
|
||||
// Reduce chyme volume based on absorption
|
||||
double absorbedVolume = (totalNutrientAbsorption * 0.01 + totalWaterAbsorption * 0.1) * deltaTime_s;
|
||||
chymeVolume_mL -= absorbedVolume;
|
||||
chymeVolume_mL = std::max(0.0, chymeVolume_mL);
|
||||
}
|
||||
|
||||
// Fluctuate motility slightly
|
||||
duodenum.motility += getFluctuation(0.01);
|
||||
duodenum.motility = std::clamp(duodenum.motility, 0.9, 1.1);
|
||||
}
|
||||
|
||||
void Intestines::receiveChyme(double volume_mL) {
|
||||
chymeVolume_mL += volume_mL;
|
||||
}
|
||||
|
||||
std::string Intestines::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Nutrient Absorption: " << nutrientAbsorptionRate << "\n"
|
||||
<< " Water Absorption: " << waterAbsorptionRate << " ml/s";
|
||||
ss.precision(2);
|
||||
ss << std::fixed;
|
||||
ss << "--- Intestines Summary ---\n"
|
||||
<< "Total Chyme Volume: " << getTotalChymeVolume() << " mL\n\n"
|
||||
<< "--- Segments ---\n"
|
||||
<< duodenum.name << ": Motility " << duodenum.motility << "\n"
|
||||
<< jejunum.name << ": Nutrient Abs. " << jejunum.nutrientAbsorptionRate << "\n"
|
||||
<< ileum.name << ": Water Abs. " << ileum.waterAbsorptionRate << "\n"
|
||||
<< colon.name << ": Water Abs. " << colon.waterAbsorptionRate << "\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Intestines::getNutrientAbsorptionRate() const { return nutrientAbsorptionRate; }
|
||||
double Intestines::getWaterAbsorptionRate() const { return waterAbsorptionRate; }
|
||||
// --- Getters Implementation ---
|
||||
double Intestines::getTotalChymeVolume() const { return chymeVolume_mL; }
|
||||
|
||||
+52
-15
@@ -2,6 +2,8 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <numeric>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
@@ -11,29 +13,64 @@ static double getFluctuation(double stddev) {
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Kidneys::Kidneys(int id) : Organ(id, "Kidneys"), filtrationRate(125.0), urineProductionRate(0.02) {}
|
||||
Kidneys::Kidneys(int id)
|
||||
: Organ(id, "Kidneys"),
|
||||
gfr_mL_per_min(125.0),
|
||||
urineOutput_mL_per_s(0.02),
|
||||
bloodSodium_mEq_per_L(140.0),
|
||||
bloodPotassium_mEq_per_L(4.0),
|
||||
totalFiltrationCapacity(1.0) {
|
||||
|
||||
// Create a simplified representation of nephrons
|
||||
nephrons.resize(100); // 100 representative units
|
||||
for (int i = 0; i < nephrons.size(); ++i) {
|
||||
nephrons[i] = {"Nephron " + std::to_string(i), 1.0, false};
|
||||
}
|
||||
}
|
||||
|
||||
void Kidneys::update(double deltaTime_s) {
|
||||
const double baseline_filtration = 125.0;
|
||||
const double baseline_urine_prod = 0.02;
|
||||
const double theta = 0.03;
|
||||
const double filtration_stddev = 1.0;
|
||||
const double urine_prod_stddev = 0.001;
|
||||
// Recalculate total capacity based on nephron health
|
||||
totalFiltrationCapacity = 0.0;
|
||||
for (const auto& nephron : nephrons) {
|
||||
if (!nephron.isDamaged) {
|
||||
totalFiltrationCapacity += nephron.filtrationEfficiency;
|
||||
}
|
||||
}
|
||||
totalFiltrationCapacity /= nephrons.size();
|
||||
|
||||
filtrationRate += theta * (baseline_filtration - filtrationRate) * deltaTime_s + getFluctuation(filtration_stddev * deltaTime_s);
|
||||
urineProductionRate += theta * (baseline_urine_prod - urineProductionRate) * deltaTime_s + getFluctuation(urine_prod_stddev * deltaTime_s);
|
||||
// GFR is dependent on overall health
|
||||
const double baseline_gfr = 125.0 * totalFiltrationCapacity;
|
||||
gfr_mL_per_min += 0.1 * (baseline_gfr - gfr_mL_per_min) * deltaTime_s + getFluctuation(0.5);
|
||||
|
||||
filtrationRate = std::clamp(filtrationRate, 100.0, 150.0);
|
||||
urineProductionRate = std::clamp(urineProductionRate, 0.01, 0.03);
|
||||
// Urine output is related to GFR but also hydration status (not modeled yet)
|
||||
urineOutput_mL_per_s = gfr_mL_per_min / 60.0 * 0.01; // Simplified relationship
|
||||
urineOutput_mL_per_s += getFluctuation(0.001);
|
||||
|
||||
// Simulate electrolyte balance
|
||||
bloodSodium_mEq_per_L += getFluctuation(0.05);
|
||||
bloodPotassium_mEq_per_L += getFluctuation(0.01);
|
||||
|
||||
// Clamp to healthy ranges
|
||||
gfr_mL_per_min = std::clamp(gfr_mL_per_min, 90.0, 150.0);
|
||||
urineOutput_mL_per_s = std::clamp(urineOutput_mL_per_s, 0.01, 0.03);
|
||||
bloodSodium_mEq_per_L = std::clamp(bloodSodium_mEq_per_L, 135.0, 145.0);
|
||||
bloodPotassium_mEq_per_L = std::clamp(bloodPotassium_mEq_per_L, 3.5, 5.0);
|
||||
}
|
||||
|
||||
std::string Kidneys::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Filtration Rate: " << filtrationRate << " ml/min\n"
|
||||
<< " Urine Production: " << urineProductionRate << " ml/s";
|
||||
ss.precision(1);
|
||||
ss << std::fixed;
|
||||
ss << "--- Kidneys Summary ---\n"
|
||||
<< "Glomerular Filtration Rate (GFR): " << getGfr() << " mL/min\n"
|
||||
<< "Urine Output: " << getUrineOutputRate() * 3600 << " mL/hr\n"
|
||||
<< "Blood Sodium: " << getBloodSodium() << " mEq/L\n"
|
||||
<< "Blood Potassium: " << getBloodPotassium() << " mEq/L\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Kidneys::getFiltrationRate() const { return filtrationRate; }
|
||||
double Kidneys::getUrineProductionRate() const { return urineProductionRate; }
|
||||
// --- Getters Implementation ---
|
||||
double Kidneys::getGfr() const { return gfr_mL_per_min; }
|
||||
double Kidneys::getUrineOutputRate() const { return urineOutput_mL_per_s; }
|
||||
double Kidneys::getBloodSodium() const { return bloodSodium_mEq_per_L; }
|
||||
double Kidneys::getBloodPotassium() const { return bloodPotassium_mEq_per_L; }
|
||||
|
||||
+57
-18
@@ -2,6 +2,7 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <numeric>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
@@ -11,32 +12,70 @@ static double getFluctuation(double stddev) {
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
// Healthy baseline rates converted to per-second
|
||||
// Bile: 400-800 ml/day -> ~0.0069 ml/s
|
||||
// Glucose: ~90 g/day -> ~0.001 g/s
|
||||
Liver::Liver(int id) : Organ(id, "Liver"), bileProductionRate(0.0069), glucoseProductionRate(0.001) {}
|
||||
Liver::Liver(int id)
|
||||
: Organ(id, "Liver"),
|
||||
bileProductionRate_ml_per_s(0.0069),
|
||||
glucoseProductionRate_g_per_s(0.001),
|
||||
alt_U_per_L(25.0),
|
||||
ast_U_per_L(25.0),
|
||||
bilirubin_mg_per_dL(0.8),
|
||||
totalMetabolicCapacity(1.0) {
|
||||
|
||||
// Create a simplified representation of lobules
|
||||
lobules.resize(100); // 100 representative units
|
||||
for (int i = 0; i < lobules.size(); ++i) {
|
||||
lobules[i] = {"Lobule " + std::to_string(i), 1.0, false};
|
||||
}
|
||||
}
|
||||
|
||||
void Liver::update(double deltaTime_s) {
|
||||
const double baseline_bile_rate = 0.0069;
|
||||
const double baseline_glucose_rate = 0.001;
|
||||
const double theta = 0.02; // Slow reversion for metabolic rates
|
||||
const double bile_stddev = 0.0001;
|
||||
const double glucose_stddev = 0.00005;
|
||||
// Recalculate total capacity based on lobule health (for future use)
|
||||
totalMetabolicCapacity = 0.0;
|
||||
for (const auto& lobule : lobules) {
|
||||
if (!lobule.isDamaged) {
|
||||
totalMetabolicCapacity += lobule.metabolicActivity;
|
||||
}
|
||||
}
|
||||
totalMetabolicCapacity /= lobules.size();
|
||||
|
||||
bileProductionRate += theta * (baseline_bile_rate - bileProductionRate) * deltaTime_s + getFluctuation(bile_stddev * deltaTime_s);
|
||||
glucoseProductionRate += theta * (baseline_glucose_rate - glucoseProductionRate) * deltaTime_s + getFluctuation(glucose_stddev * deltaTime_s);
|
||||
// Baseline production rates are modulated by liver health
|
||||
const double baseline_bile_rate = 0.0069 * totalMetabolicCapacity;
|
||||
const double baseline_glucose_rate = 0.001 * totalMetabolicCapacity;
|
||||
|
||||
bileProductionRate = std::clamp(bileProductionRate, 0.005, 0.009);
|
||||
glucoseProductionRate = std::clamp(glucoseProductionRate, 0.0008, 0.0012);
|
||||
// Update production rates with minor fluctuations
|
||||
bileProductionRate_ml_per_s += 0.02 * (baseline_bile_rate - bileProductionRate_ml_per_s) * deltaTime_s + getFluctuation(0.0001);
|
||||
glucoseProductionRate_g_per_s += 0.02 * (baseline_glucose_rate - glucoseProductionRate_g_per_s) * deltaTime_s + getFluctuation(0.00005);
|
||||
|
||||
// Update enzyme and bilirubin levels
|
||||
// In a healthy state, they hover around a normal baseline
|
||||
alt_U_per_L += getFluctuation(0.1);
|
||||
ast_U_per_L += getFluctuation(0.1);
|
||||
bilirubin_mg_per_dL += getFluctuation(0.01);
|
||||
|
||||
// Clamp to normal healthy ranges
|
||||
bileProductionRate_ml_per_s = std::clamp(bileProductionRate_ml_per_s, 0.005, 0.009);
|
||||
glucoseProductionRate_g_per_s = std::clamp(glucoseProductionRate_g_per_s, 0.0008, 0.0012);
|
||||
alt_U_per_L = std::clamp(alt_U_per_L, 10.0, 40.0);
|
||||
ast_U_per_L = std::clamp(ast_U_per_L, 10.0, 40.0);
|
||||
bilirubin_mg_per_dL = std::clamp(bilirubin_mg_per_dL, 0.3, 1.2);
|
||||
}
|
||||
|
||||
std::string Liver::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Bile Production Rate: " << bileProductionRate * 60 << " ml/min\n"
|
||||
<< " Glucose Production Rate: " << glucoseProductionRate * 60 << " g/min";
|
||||
ss.precision(3);
|
||||
ss << std::fixed;
|
||||
ss << "--- Liver Summary ---\n"
|
||||
<< "Bile Production: " << getBileProductionRate() * 60.0 << " mL/min\n"
|
||||
<< "Glucose Production: " << getGlucoseProductionRate() * 60.0 << " g/min\n"
|
||||
<< "ALT Level: " << getAltLevel() << " U/L\n"
|
||||
<< "AST Level: " << getAstLevel() << " U/L\n"
|
||||
<< "Bilirubin: " << getBilirubinLevel() << " mg/dL\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Liver::getBileProductionRate() const { return bileProductionRate; }
|
||||
double Liver::getGlucoseProductionRate() const { return glucoseProductionRate; }
|
||||
// --- Getters Implementation ---
|
||||
double Liver::getBileProductionRate() const { return bileProductionRate_ml_per_s; }
|
||||
double Liver::getGlucoseProductionRate() const { return glucoseProductionRate_g_per_s; }
|
||||
double Liver::getAltLevel() const { return alt_U_per_L; }
|
||||
double Liver::getAstLevel() const { return ast_U_per_L; }
|
||||
double Liver::getBilirubinLevel() const { return bilirubin_mg_per_dL; }
|
||||
|
||||
+36
-15
@@ -2,6 +2,7 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
@@ -11,29 +12,49 @@ static double getFluctuation(double stddev) {
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Pancreas::Pancreas(int id) : Organ(id, "Pancreas"), insulinProduction(1.0), glucagonProduction(50.0) {}
|
||||
Pancreas::Pancreas(int id)
|
||||
: Organ(id, "Pancreas"),
|
||||
insulinSecretion_units_per_hr(1.0),
|
||||
glucagonSecretion_ng_per_hr(50.0),
|
||||
amylaseSecretion_U_per_L(80.0),
|
||||
lipaseSecretion_U_per_L(40.0) {}
|
||||
|
||||
void Pancreas::update(double deltaTime_s) {
|
||||
const double baseline_insulin = 1.0;
|
||||
const double baseline_glucagon = 50.0;
|
||||
const double theta = 0.05;
|
||||
const double insulin_stddev = 0.01;
|
||||
const double glucagon_stddev = 1.0;
|
||||
// In a real model, hormone secretion would be driven by blood glucose.
|
||||
// Enzyme secretion would be driven by food in the duodenum.
|
||||
// For now, we just simulate minor fluctuations around a baseline.
|
||||
|
||||
insulinProduction += theta * (baseline_insulin - insulinProduction) * deltaTime_s + getFluctuation(insulin_stddev * deltaTime_s);
|
||||
glucagonProduction += theta * (baseline_glucagon - glucagonProduction) * deltaTime_s + getFluctuation(glucagon_stddev * deltaTime_s);
|
||||
// Endocrine fluctuations
|
||||
insulinSecretion_units_per_hr += getFluctuation(0.05);
|
||||
glucagonSecretion_ng_per_hr += getFluctuation(0.5);
|
||||
|
||||
insulinProduction = std::clamp(insulinProduction, 0.5, 2.0);
|
||||
glucagonProduction = std::clamp(glucagonProduction, 40.0, 60.0);
|
||||
// Exocrine fluctuations
|
||||
amylaseSecretion_U_per_L += getFluctuation(0.2);
|
||||
lipaseSecretion_U_per_L += getFluctuation(0.2);
|
||||
|
||||
// Clamp to healthy ranges
|
||||
insulinSecretion_units_per_hr = std::clamp(insulinSecretion_units_per_hr, 0.5, 2.0);
|
||||
glucagonSecretion_ng_per_hr = std::clamp(glucagonSecretion_ng_per_hr, 40.0, 60.0);
|
||||
amylaseSecretion_U_per_L = std::clamp(amylaseSecretion_U_per_L, 60.0, 100.0);
|
||||
lipaseSecretion_U_per_L = std::clamp(lipaseSecretion_U_per_L, 20.0, 60.0);
|
||||
}
|
||||
|
||||
std::string Pancreas::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Insulin Production: " << insulinProduction << " units/hr\n"
|
||||
<< " Glucagon Production: " << glucagonProduction << " ng/hr";
|
||||
ss.precision(1);
|
||||
ss << std::fixed;
|
||||
ss << "--- Pancreas Summary ---\n"
|
||||
<< "--- Endocrine Function ---\n"
|
||||
<< "Insulin Secretion: " << getInsulinSecretion() << " units/hr\n"
|
||||
<< "Glucagon Secretion: " << getGlucagonSecretion() << " ng/hr\n"
|
||||
<< "--- Exocrine Function ---\n"
|
||||
<< "Amylase Secretion: " << getAmylaseSecretion() << " U/L\n"
|
||||
<< "Lipase Secretion: " << getLipaseSecretion() << " U/L\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Pancreas::getInsulinProduction() const { return insulinProduction; }
|
||||
double Pancreas::getGlucagonProduction() const { return glucagonProduction; }
|
||||
// --- Getters Implementation ---
|
||||
double Pancreas::getInsulinSecretion() const { return insulinSecretion_units_per_hr; }
|
||||
double Pancreas::getGlucagonSecretion() const { return glucagonSecretion_ng_per_hr; }
|
||||
double Pancreas::getAmylaseSecretion() const { return amylaseSecretion_U_per_L; }
|
||||
double Pancreas::getLipaseSecretion() const { return lipaseSecretion_U_per_L; }
|
||||
|
||||
+39
-9
@@ -2,6 +2,7 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
@@ -11,23 +12,52 @@ static double getFluctuation(double stddev) {
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
SpinalCord::SpinalCord(int id) : Organ(id, "SpinalCord"), signalConductionVelocity(70.0) {}
|
||||
SpinalCord::SpinalCord(int id)
|
||||
: Organ(id, "SpinalCord"),
|
||||
reflexArcIntact(true) {
|
||||
|
||||
// Initialize major pathways
|
||||
descendingMotorTract = {"Descending Motor Tract", SignalStatus::NORMAL, 75.0};
|
||||
ascendingSensoryTract = {"Ascending Sensory Tract", SignalStatus::NORMAL, 65.0};
|
||||
}
|
||||
|
||||
void SpinalCord::update(double deltaTime_s) {
|
||||
const double baseline_velocity = 70.0;
|
||||
const double theta = 0.01;
|
||||
const double velocity_stddev = 0.1;
|
||||
// In a healthy state, status doesn't change.
|
||||
// Pathology models would alter these values.
|
||||
// For now, we just simulate minor fluctuations in a healthy velocity.
|
||||
descendingMotorTract.conductionVelocity_m_per_s += getFluctuation(0.1);
|
||||
descendingMotorTract.conductionVelocity_m_per_s = std::clamp(descendingMotorTract.conductionVelocity_m_per_s, 70.0, 80.0);
|
||||
|
||||
signalConductionVelocity += theta * (baseline_velocity - signalConductionVelocity) * deltaTime_s + getFluctuation(velocity_stddev * deltaTime_s);
|
||||
ascendingSensoryTract.conductionVelocity_m_per_s += getFluctuation(0.1);
|
||||
ascendingSensoryTract.conductionVelocity_m_per_s = std::clamp(ascendingSensoryTract.conductionVelocity_m_per_s, 60.0, 70.0);
|
||||
|
||||
signalConductionVelocity = std::clamp(signalConductionVelocity, 60.0, 80.0);
|
||||
// Reflex arc is a simple boolean for now.
|
||||
reflexArcIntact = (descendingMotorTract.status == SignalStatus::NORMAL && ascendingSensoryTract.status == SignalStatus::NORMAL);
|
||||
}
|
||||
|
||||
std::string SpinalCord::statusToString(SignalStatus status) const {
|
||||
switch (status) {
|
||||
case SignalStatus::NORMAL: return "Normal";
|
||||
case SignalStatus::IMPAIRED: return "Impaired";
|
||||
case SignalStatus::SEVERED: return "Severed";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string SpinalCord::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " Signal Velocity: " << signalConductionVelocity << " m/s";
|
||||
ss << "--- Spinal Cord Summary ---\n"
|
||||
<< "Motor Pathway (" << descendingMotorTract.name << "): "
|
||||
<< statusToString(descendingMotorTract.status) << " ("
|
||||
<< std::fixed << std::setprecision(1) << descendingMotorTract.conductionVelocity_m_per_s << " m/s)\n"
|
||||
<< "Sensory Pathway (" << ascendingSensoryTract.name << "): "
|
||||
<< statusToString(ascendingSensoryTract.status) << " ("
|
||||
<< std::fixed << std::setprecision(1) << ascendingSensoryTract.conductionVelocity_m_per_s << " m/s)\n"
|
||||
<< "Reflex Arc Intact: " << (isReflexArcIntact() ? "Yes" : "No") << "\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double SpinalCord::getSignalConductionVelocity() const { return signalConductionVelocity; }
|
||||
// --- Getters Implementation ---
|
||||
SignalStatus SpinalCord::getMotorPathwayStatus() const { return descendingMotorTract.status; }
|
||||
SignalStatus SpinalCord::getSensoryPathwayStatus() const { return ascendingSensoryTract.status; }
|
||||
bool SpinalCord::isReflexArcIntact() const { return reflexArcIntact; }
|
||||
|
||||
+32
-15
@@ -2,6 +2,7 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
@@ -11,29 +12,45 @@ static double getFluctuation(double stddev) {
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Spleen::Spleen(int id) : Organ(id, "Spleen"), redBloodCellCount(4.5), whiteBloodCellCount(7.5) {}
|
||||
Spleen::Spleen(int id) : Organ(id, "Spleen") {
|
||||
// Initialize pulp components
|
||||
redPulp = {1.0, 0.5};
|
||||
whitePulp = {1500.0, 500.0};
|
||||
}
|
||||
|
||||
void Spleen::update(double deltaTime_s) {
|
||||
const double baseline_rbc = 4.5;
|
||||
const double baseline_wbc = 7.5;
|
||||
const double theta = 0.02;
|
||||
const double rbc_stddev = 0.01;
|
||||
const double wbc_stddev = 0.05;
|
||||
// In a real model, these values would change in response to infection or disease.
|
||||
// For now, we just simulate minor fluctuations around a healthy baseline.
|
||||
|
||||
redBloodCellCount += theta * (baseline_rbc - redBloodCellCount) * deltaTime_s + getFluctuation(rbc_stddev * deltaTime_s);
|
||||
whiteBloodCellCount += theta * (baseline_wbc - whiteBloodCellCount) * deltaTime_s + getFluctuation(wbc_stddev * deltaTime_s);
|
||||
// Red pulp fluctuations
|
||||
redPulp.filtrationRate += getFluctuation(0.01);
|
||||
redPulp.rbcBreakdownRate += getFluctuation(0.005);
|
||||
|
||||
redBloodCellCount = std::clamp(redBloodCellCount, 4.0, 5.0);
|
||||
whiteBloodCellCount = std::clamp(whiteBloodCellCount, 5.0, 10.0);
|
||||
// White pulp fluctuations
|
||||
whitePulp.lymphocyteCount += getFluctuation(1.0);
|
||||
whitePulp.macrophageCount += getFluctuation(0.5);
|
||||
|
||||
// Clamp to healthy ranges
|
||||
redPulp.filtrationRate = std::clamp(redPulp.filtrationRate, 0.9, 1.1);
|
||||
redPulp.rbcBreakdownRate = std::clamp(redPulp.rbcBreakdownRate, 0.45, 0.55);
|
||||
whitePulp.lymphocyteCount = std::clamp(whitePulp.lymphocyteCount, 1400.0, 1600.0);
|
||||
whitePulp.macrophageCount = std::clamp(whitePulp.macrophageCount, 450.0, 550.0);
|
||||
}
|
||||
|
||||
std::string Spleen::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " RBC Count: " << redBloodCellCount << " million/uL\n"
|
||||
<< " WBC Count: " << whiteBloodCellCount << " thousand/uL";
|
||||
ss.precision(1);
|
||||
ss << std::fixed;
|
||||
ss << "--- Spleen Summary ---\n"
|
||||
<< "--- Red Pulp ---\n"
|
||||
<< "Filtration Rate: " << redPulp.filtrationRate << "\n"
|
||||
<< "RBC Breakdown Rate: " << getRbcBreakdownRate() << "\n"
|
||||
<< "--- White Pulp ---\n"
|
||||
<< "Lymphocyte Count: " << getLymphocyteCount() << " million\n"
|
||||
<< "Macrophage Count: " << whitePulp.macrophageCount << " million\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Spleen::getRedBloodCellCount() const { return redBloodCellCount; }
|
||||
double Spleen::getWhiteBloodCellCount() const { return whiteBloodCellCount; }
|
||||
// --- Getters Implementation ---
|
||||
double Spleen::getRbcBreakdownRate() const { return redPulp.rbcBreakdownRate; }
|
||||
double Spleen::getLymphocyteCount() const { return whitePulp.lymphocyteCount; }
|
||||
|
||||
+86
-16
@@ -2,6 +2,7 @@
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
// Helper function for random fluctuations
|
||||
static double getFluctuation(double stddev) {
|
||||
@@ -11,30 +12,99 @@ static double getFluctuation(double stddev) {
|
||||
return d(gen);
|
||||
}
|
||||
|
||||
Stomach::Stomach(int id) : Organ(id, "Stomach"), phLevel(2.0), digestionRate(1.0) {}
|
||||
Stomach::Stomach(int id)
|
||||
: Organ(id, "Stomach"),
|
||||
currentState(GastricState::EMPTY),
|
||||
currentVolume_mL(0.0),
|
||||
currentPh(4.5), // pH of an empty stomach is higher
|
||||
gastricJuiceSecretionRate_ml_per_s(0.1),
|
||||
emptyingRate_ml_per_s(0.5) {}
|
||||
|
||||
void Stomach::update(double deltaTime_s) {
|
||||
// For now, these values just fluctuate around a baseline.
|
||||
const double baseline_ph = 2.0;
|
||||
const double baseline_digestion = 1.0;
|
||||
const double theta = 0.1;
|
||||
const double ph_stddev = 0.05;
|
||||
const double digestion_stddev = 0.02;
|
||||
// --- State Machine Logic ---
|
||||
switch (currentState) {
|
||||
case GastricState::EMPTY:
|
||||
// For demo, simulate food arriving every 20 seconds
|
||||
static double timeUntilFood = 0.0;
|
||||
timeUntilFood += deltaTime_s;
|
||||
if (timeUntilFood > 20.0) {
|
||||
addSubstance(150.0); // Simulate arrival of a meal
|
||||
timeUntilFood = 0.0;
|
||||
}
|
||||
break;
|
||||
|
||||
phLevel += theta * (baseline_ph - phLevel) * deltaTime_s + getFluctuation(ph_stddev * deltaTime_s);
|
||||
digestionRate += theta * (baseline_digestion - digestionRate) * deltaTime_s + getFluctuation(digestion_stddev * deltaTime_s);
|
||||
case GastricState::FILLING:
|
||||
// Transition to DIGESTING after a short period
|
||||
static double fillTime = 0.0;
|
||||
fillTime += deltaTime_s;
|
||||
if (fillTime > 2.0) {
|
||||
currentState = GastricState::DIGESTING;
|
||||
fillTime = 0.0;
|
||||
}
|
||||
break;
|
||||
|
||||
phLevel = std::clamp(phLevel, 1.5, 3.5);
|
||||
digestionRate = std::clamp(digestionRate, 0.5, 1.5);
|
||||
case GastricState::DIGESTING:
|
||||
// Secrete acid, lowering pH
|
||||
currentPh -= 0.5 * deltaTime_s;
|
||||
currentPh = std::max(1.5, currentPh);
|
||||
|
||||
// After some time, start emptying
|
||||
static double digestionTime = 0.0;
|
||||
digestionTime += deltaTime_s;
|
||||
if (digestionTime > 30.0) { // Digest for 30 seconds
|
||||
currentState = GastricState::EMPTYING;
|
||||
digestionTime = 0.0;
|
||||
}
|
||||
break;
|
||||
|
||||
case GastricState::EMPTYING:
|
||||
// Empty chyme into intestines
|
||||
double amountToEmpty = emptyingRate_ml_per_s * deltaTime_s;
|
||||
currentVolume_mL -= amountToEmpty;
|
||||
|
||||
if (currentVolume_mL <= 0) {
|
||||
currentVolume_mL = 0;
|
||||
currentState = GastricState::EMPTY;
|
||||
currentPh = 4.5; // pH returns to baseline
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Secrete a baseline level of gastric juice, increasing during digestion
|
||||
double currentSecretionRate = (currentState == GastricState::DIGESTING) ? 2.0 : 0.1;
|
||||
currentVolume_mL += currentSecretionRate * deltaTime_s;
|
||||
currentVolume_mL = std::clamp(currentVolume_mL, 0.0, capacity_mL);
|
||||
}
|
||||
|
||||
void Stomach::addSubstance(double volume_mL) {
|
||||
currentVolume_mL += volume_mL;
|
||||
// Food buffers the acid initially
|
||||
currentPh = std::min(4.0, currentPh + 0.5);
|
||||
currentState = GastricState::FILLING;
|
||||
}
|
||||
|
||||
std::string Stomach::stateToString(GastricState state) const {
|
||||
switch (state) {
|
||||
case GastricState::EMPTY: return "Empty";
|
||||
case GastricState::FILLING: return "Filling";
|
||||
case GastricState::DIGESTING: return "Digesting";
|
||||
case GastricState::EMPTYING: return "Emptying";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string Stomach::getSummary() const {
|
||||
std::stringstream ss;
|
||||
ss << "Type: " << organType << " (ID: " << organId << ")\n"
|
||||
<< " pH Level: " << phLevel << "\n"
|
||||
<< " Digestion Rate: " << digestionRate;
|
||||
ss.precision(1);
|
||||
ss << std::fixed;
|
||||
ss << "--- Stomach Summary ---\n"
|
||||
<< "State: " << stateToString(currentState) << "\n"
|
||||
<< "Volume: " << currentVolume_mL << " / " << capacity_mL << " mL\n"
|
||||
<< "Acidity (pH): " << getAcidity() << "\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
double Stomach::getPhLevel() const { return phLevel; }
|
||||
double Stomach::getDigestionRate() const { return digestionRate; }
|
||||
// --- Getters Implementation ---
|
||||
GastricState Stomach::getCurrentState() const { return currentState; }
|
||||
double Stomach::getVolume() const { return currentVolume_mL; }
|
||||
double Stomach::getAcidity() const { return currentPh; }
|
||||
|
||||
Reference in New Issue
Block a user