Created
September 16, 2020 00:58
-
-
Save dennisjbell/3c7c99e441ea81087d56211cb558dde7 to your computer and use it in GitHub Desktop.
Breathe - calculate death in minutes for a given room dimension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use List::Util qw/sum reduce/; | |
use Data::Dumper; | |
use Pry; | |
print STDERR "ERROR: Specify 3 dimensions of the room\n" | |
if (@ARGV != 3) || grep {$_ !~ /\d+(\.\d+)?/} @ARGV; | |
my @room_in_ft = @ARGV; | |
# @room_in_ft = (6,2.5,2.1); # Coffin less a 66l person | |
my $litre_per_cubic_foot = 28.31685; | |
my @components = qw/Nitrogen Oxygen Argon CarbonDioxide CarbonMonoxide Other/; | |
my %initial_concentrations = ( | |
Nitrogen => 78.08400, | |
Oxygen => 20.94760, | |
Argon => 0.9340, | |
CarbonDioxide => 0.0314 | |
); # https://www.thoughtco.com/chemical-composition-of-air-604288 | |
# 12 - 20 per minute normal for average adult | |
#https://www.medicalnewstoday.com/articles/324409#adults | |
my $breath_rate = 16; # repetitions per minute | |
# https://www.reference.com/science/much-oxygen-inhale-exhale-b763252ad5727e56 | |
my $breath_capacity = 8; # litres per minute | |
my $breath_convertion = 5; # percent of oxygen converted to CO2 and CO | |
# https://www.sciencedirect.com/science/article/pii/S0954611104000034 | |
my $eCO_ppm = 5; | |
# Initialize | |
my $time = 0; | |
my %current_concentrations = (%initial_concentrations); | |
$current_concentrations{CarbonMonoxide} = 0; | |
$current_concentrations{Other} = 100 - sum(values(%current_concentrations)); | |
my $volume = $litre_per_cubic_foot * reduce {$a * $b} @room_in_ft; | |
my $max_co2 = 4.0; # percent, or 40,000 ppm - https://www.cdc.gov/niosh/idlh/124389.html | |
my $max_co = 0.12; # percent, or 1200 ppm - https://www.cdc.gov/niosh/idlh/630080.html | |
# https://www.reference.com/science/much-oxygen-inhale-exhale-b763252ad5727e56 | |
my $min_o2 = 6.0; | |
my $feel_o2 = 19.5; | |
sub breathe { | |
$air_in_lungs = inhale(); | |
respire($air_in_lungs); | |
exhale($air_in_lungs); | |
} | |
sub inhale { | |
my $contents = {}; | |
$contents->{$_} = ($breath_capacity/$breath_rate) * $current_concentrations{$_} / 100 for keys(%current_concentrations); | |
$volume = $volume - sum(values %$contents); | |
return $contents; | |
} | |
sub respire { # convert inhaled air to air that will be exhaled | |
my $contents = shift; | |
my $new_co = sum(values(%$contents)) * $eCO_ppm / 1000000; | |
my $used_o2 = sum(values(%$contents)) * $breath_convertion / 100 ; | |
$contents->{Oxygen} -= $used_o2; | |
$contents->{CarbonDioxide} += $used_o2 - $new_co; | |
$contents->{CarbonMonoxide} += $new_co; | |
} | |
sub exhale { | |
my $contents = shift; | |
my $air = {}; | |
$air->{$_} = ($volume) * $current_concentrations{$_} / 100 + $contents->{$_} for keys(%current_concentrations); | |
$volume = sum(values(%$air)); | |
$current_concentrations{$_} = ($air->{$_}/$volume*100) for keys(%current_concentrations); | |
printf "%s,%s,%s,%s,%s,%s,%s\n", $time, map {$current_concentrations{$_}} @components; | |
} | |
my %effects = (); | |
printf "Time,%s,%s,%s,%s,%s,%s\n", @components; | |
while ($time < 7*24*60 && keys(%effects) < 4) { | |
breathe(); | |
$time += 1/$breath_rate; | |
if ($current_concentrations{Oxygen} < $feel_o2 && ! $effects{feeling_o2_depletion}) { | |
$effects{feeling_o2_depletion} = $time; | |
} | |
if ($current_concentrations{Oxygen} < $min_o2 && ! $effects{death_from_lack_o2}) { | |
$effects{death_from_lack_o2} = $time; | |
} | |
if ($current_concentrations{CarbonDioxide} > $max_co2 && ! $effects{death_from_co2}) { | |
$effects{death_from_co2} = $time; | |
} | |
if ($current_concentrations{CarbonMonoxide} > $max_co && ! $effects{death_from_co}) { | |
$effects{death_from_co} = $time; | |
} | |
} | |
print STDERR Dumper(\%effects); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment