Skip to content

Commit 300674f

Browse files
ntatum94StevenAWhite
authored andcommitted
Discretizing burn affect on discretized skin nodes
1 parent 5dc0a9a commit 300674f

File tree

3 files changed

+63
-30
lines changed

3 files changed

+63
-30
lines changed

projects/biogears/libBiogears/src/engine/Systems/Energy.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -697,10 +697,25 @@ void Energy::UpdateHeatResistance()
697697
double bloodSpecificHeat_J_Per_K_kg = m_data.GetBloodChemistry().GetBloodSpecificHeat().GetValue(HeatCapacitancePerMassUnit::J_Per_K_kg);
698698

699699
double alphaScale = 0.5; // Scaling factor for convective heat transfer from core to skin (35 seems to be near the upper limit before non-stabilization)
700-
// Rough implementation to correlate burn location to skin location
701-
// ?????????????????????????? Wait until we can merge the burn updates to get better segmentation
700+
bool isBurnWound = false;
702701
if (m_data.GetBloodChemistry().GetInflammatoryResponse().HasInflammationSource(CDM::enumInflammationSource::Burn)) {
703-
const double burnSurfaceAreaFraction = m_data.GetActions().GetPatientActions().GetBurnWound()->GetTotalBodySurfaceArea().GetValue();
702+
SEBurnWound* burnAction = m_data.GetActions().GetPatientActions().GetBurnWound();
703+
std::vector<std::string> burnComptVector = burnAction->GetCompartments();
704+
// Check if burn is on specific compartment. Skip head since burns cannot currently be initialized on the head
705+
if (index == 0 && burnAction->HasCompartment("Trunk")) {
706+
isBurnWound = true;
707+
} else if (index == 2 && burnAction->HasCompartment("LeftArm")) {
708+
isBurnWound = true;
709+
} else if (index == 3 && burnAction->HasCompartment("RightArm")) {
710+
isBurnWound = true;
711+
} else if (index == 4 && burnAction->HasCompartment("LeftLeg")) {
712+
isBurnWound = true;
713+
} else if (index == 5 && burnAction->HasCompartment("RightLeg")) {
714+
isBurnWound = true;
715+
}
716+
}
717+
if (isBurnWound) {
718+
const double burnSurfaceAreaFraction = m_data.GetActions().GetPatientActions().GetBurnWound()->GetBurnIntensity();
704719
const double resInput = std::min(2.0 * burnSurfaceAreaFraction, 1.0); // Make >50% burn the worse case scenario
705720
const double targetAlpha = GeneralMath::LinearInterpolator(0.0, resInput, alphaScale, 20.0, resInput);
706721
const double lastAlpha = 1.0 / (coreToSkinPath->GetResistance(HeatResistanceUnit::K_Per_W) * bloodDensity_kg_Per_m3 * bloodSpecificHeat_J_Per_K_kg * segmentedSkinBloodFlows[index]);

projects/biogears/libBiogears/src/engine/Systems/Environment.cpp

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ void Environment::ProcessActions()
374374
const double lastConvectiveResistance = m_ClothingToEnvironmentPath->GetResistance(HeatResistanceUnit::K_Per_W);
375375

376376
//Target resistance are based on burn surface area (using "next" values since they were just set to basal values earlier in PreProcess)
377-
const double targetRadiativeResistance = nextRadiativeResistance * std::pow(1.0 - burnSurfaceAreaFraction, 4.0);
378-
const double targetConvectiveResistance = nextConvectiveResistance * std::pow(1.0 - burnSurfaceAreaFraction, 4.0);
377+
const double targetRadiativeResistance = nextRadiativeResistance * std::pow(1.0 - burnSurfaceAreaIntensityFraction, 4.0);
378+
const double targetConvectiveResistance = nextConvectiveResistance * std::pow(1.0 - burnSurfaceAreaIntensityFraction, 4.0);
379379

380380
const double rampGain = 1.0e-5; //Smooth the response so that we reach targets over several minutes
381381

@@ -389,7 +389,7 @@ void Environment::ProcessActions()
389389
for (SEThermalCircuitPath* skinToClothing : m_SkinToClothingPaths) {
390390
double nextSkinToClothingResistance = skinToClothing->GetNextResistance(HeatResistanceUnit::K_Per_W);
391391
const double lastSkinToClothingResistance = skinToClothing->GetResistance(HeatResistanceUnit::K_Per_W);
392-
const double targetSkinToClothingResistance = nextSkinToClothingResistance * std::pow(1.0 - burnSurfaceAreaFraction, 4.0);
392+
const double targetSkinToClothingResistance = nextSkinToClothingResistance * std::pow(1.0 - burnSurfaceAreaIntensityFraction, 4.0);
393393
nextSkinToClothingResistance = lastSkinToClothingResistance + rampGain * (targetSkinToClothingResistance - lastSkinToClothingResistance);
394394
skinToClothing->GetNextResistance().SetValue(nextSkinToClothingResistance, HeatResistanceUnit::K_Per_W);
395395
}
@@ -735,38 +735,57 @@ void Environment::CalculateEvaporation()
735735
auto burn_inflamation = std::find(inflamationSources.begin(), inflamationSources.end(), CDM::enumInflammationSource::Burn);
736736
if (burn_inflamation != inflamationSources.end()) {
737737
if (m_data.GetActions().GetPatientActions().HasBurnWound()) {
738-
skinWettednessDiffusion = m_data.GetActions().GetPatientActions().GetBurnWound()->GetTotalBodySurfaceArea().GetValue();
739-
dClothingResistance_m2_kPa_Per_W = 0.0;
740-
fCl = 1.0;
738+
bool isBurnWoundLocal = false;
739+
if (m_data.GetBloodChemistry().GetInflammatoryResponse().HasInflammationSource(CDM::enumInflammationSource::Burn)) {
740+
SEBurnWound* burnAction = m_data.GetActions().GetPatientActions().GetBurnWound();
741+
std::vector<std::string> burnComptVector = burnAction->GetCompartments();
742+
// Check if burn is on specific compartment. Skip head since burns cannot currently be initialized on the head
743+
if (index == 0 && burnAction->HasCompartment("Trunk")) {
744+
isBurnWoundLocal = true;
745+
} else if (index == 2 && burnAction->HasCompartment("LeftArm")) {
746+
isBurnWoundLocal = true;
747+
} else if (index == 3 && burnAction->HasCompartment("RightArm")) {
748+
isBurnWoundLocal = true;
749+
} else if (index == 4 && burnAction->HasCompartment("LeftLeg")) {
750+
isBurnWoundLocal = true;
751+
} else if (index == 5 && burnAction->HasCompartment("RightLeg")) {
752+
isBurnWoundLocal = true;
753+
}
754+
}
755+
if (isBurnWoundLocal) {
756+
skinWettednessDiffusion = m_data.GetActions().GetPatientActions().GetBurnWound()->GetBurnIntensity();
757+
dClothingResistance_m2_kPa_Per_W = 0.0;
758+
fCl = 1.0;
759+
}
741760
} else {
742761
// Ok, so we likely want to evaluate the vector of inflamations
743762
// This really slows down optimization of adding/removing and accessing InflamationSources
744763
// If we can not have duplicate InflamationSources of a type then why store it as a vector.
745764
inflamationSources.erase(burn_inflamation);
746765
}
747-
}
748766

749-
///\ToDo: The units of this constant are incorrect on the CDM--they should be W_Per_m2_Pa (no support for this unit currently)
750-
GetEvaporativeHeatTranferCoefficient().SetValue(dEvaporativeHeatTransferCoefficient_W_Per_m2_kPa, HeatConductancePerAreaUnit::W_Per_m2_K);
767+
///\ToDo: The units of this constant are incorrect on the CDM--they should be W_Per_m2_Pa (no support for this unit currently)
768+
GetEvaporativeHeatTranferCoefficient().SetValue(dEvaporativeHeatTransferCoefficient_W_Per_m2_kPa, HeatConductancePerAreaUnit::W_Per_m2_K);
751769

752-
double dMaxEvaporativePotential = (1.0 / 1000.0) * (m_dWaterVaporPressureAtSkin_Pa - m_dWaterVaporPressureInAmbientAir_Pa) / (dClothingResistance_m2_kPa_Per_W + 1.0 / (fCl * dEvaporativeHeatTransferCoefficient_W_Per_m2_kPa));
753-
double dSurfaceArea_m2 = m_Patient->GetSkinSurfaceArea(AreaUnit::m2) * segmentedSkinSurfaceAreaPercents[index];
770+
double dMaxEvaporativePotential = (1.0 / 1000.0) * (m_dWaterVaporPressureAtSkin_Pa - m_dWaterVaporPressureInAmbientAir_Pa) / (dClothingResistance_m2_kPa_Per_W + 1.0 / (fCl * dEvaporativeHeatTransferCoefficient_W_Per_m2_kPa));
771+
double dSurfaceArea_m2 = m_Patient->GetSkinSurfaceArea(AreaUnit::m2) * segmentedSkinSurfaceAreaPercents[index];
754772

755-
double dSweatRate_kgPers = 0.0;
756-
if (m_data.GetEnergy().HasSweatRate()) {
757-
dSweatRate_kgPers = m_data.GetEnergy().GetSweatRate(MassPerTimeUnit::kg_Per_s) / dSurfaceArea_m2;
758-
}
759-
double dSweatingControlMechanisms = dSweatRate_kgPers * m_dHeatOfVaporizationOfWater_J_Per_kg;
760-
double dWettedPortion = 0.0;
761-
if (dMaxEvaporativePotential != 0) {
762-
dWettedPortion = dSweatingControlMechanisms / dMaxEvaporativePotential;
763-
}
764-
double dDiffusionOfWater = (1.0 - dWettedPortion) * skinWettednessDiffusion * dMaxEvaporativePotential;
765-
double EvaporativeHeatLossFromSkin_W = dSweatingControlMechanisms + dDiffusionOfWater;
773+
double dSweatRate_kgPers = 0.0;
774+
if (m_data.GetEnergy().HasSweatRate()) {
775+
dSweatRate_kgPers = m_data.GetEnergy().GetSweatRate(MassPerTimeUnit::kg_Per_s) / dSurfaceArea_m2;
776+
}
777+
double dSweatingControlMechanisms = dSweatRate_kgPers * m_dHeatOfVaporizationOfWater_J_Per_kg;
778+
double dWettedPortion = 0.0;
779+
if (dMaxEvaporativePotential != 0) {
780+
dWettedPortion = dSweatingControlMechanisms / dMaxEvaporativePotential;
781+
}
782+
double dDiffusionOfWater = (1.0 - dWettedPortion) * skinWettednessDiffusion * dMaxEvaporativePotential;
783+
double EvaporativeHeatLossFromSkin_W = dSweatingControlMechanisms + dDiffusionOfWater;
766784

767-
// Set the source
768-
envSkinToGround->GetNextHeatSource().SetValue(dSurfaceArea_m2 * EvaporativeHeatLossFromSkin_W, PowerUnit::W);
769-
index += 1;
785+
// Set the source
786+
envSkinToGround->GetNextHeatSource().SetValue(dSurfaceArea_m2 * EvaporativeHeatLossFromSkin_W, PowerUnit::W);
787+
index += 1;
788+
}
770789
}
771790
}
772791
}

share/data/config/VerificationScenarios.config

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,5 +300,4 @@ ScenarioTest( BurnWoundTreatment, Scenario=Burncare/BurnWoundTreatment.xml )
300300
ScenarioTest( BurnWound10, Scenario=Burncare/BurnWound10.xml )
301301
ScenarioTest( BurnWound20, Scenario=Burncare/BurnWound20.xml )
302302
ScenarioTest( BurnWound25, Scenario=Burncare/BurnWound25.xml )
303-
ScenarioTest( BurnWound40, Scenario=Burncare/BurnWound40.xml )
304-
303+
ScenarioTest( BurnWound40, Scenario=Burncare/BurnWound40.xml )

0 commit comments

Comments
 (0)