comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 509:103051b4d9c1

NEW NDL analytic model (Erik Baker's formula)
author JeanDo
date Sun, 20 Nov 2011 23:14:18 +0100
parents 560764da0629
children 2a6293641d51
comparison
equal deleted inserted replaced
508:b595569e4bcc 509:103051b4d9c1
101 // ** V A R I A B L E S D E F I N I T I O N S ** 101 // ** V A R I A B L E S D E F I N I T I O N S **
102 // *********************************************** 102 // ***********************************************
103 103
104 #include "p2_definitions.h" 104 #include "p2_definitions.h"
105 #define TEST_MAIN 105 #define TEST_MAIN
106 #include "shared_definitions.h" 106 #include "../OSTC_code_asm_part1/shared_definitions.h"
107 107
108 // Water vapour partial pressure in the lumb. 108 // Water vapour partial pressure in the lumb.
109 #define ppWater 0.0627 109 #define ppWater 0.0627
110 #define METER_TO_BAR 0.09985 110 #define METER_TO_BAR 0.09985
111 #define BAR_TO_METER 10.0150 // (1.0/METER_TO_BAR) 111 #define BAR_TO_METER 10.0150 // (1.0/METER_TO_BAR)
127 static void calc_ascenttime(void); 127 static void calc_ascenttime(void);
128 static void update_startvalues(void); 128 static void update_startvalues(void);
129 static void clear_deco_table(void); 129 static void clear_deco_table(void);
130 static unsigned char update_deco_table(void); 130 static unsigned char update_deco_table(void);
131 131
132 static void backup_sim_pres_tissue(void);
133 static void restore_sim_pres_tissue(void);
134 static void sim_tissue(PARAMETER unsigned char period); 132 static void sim_tissue(PARAMETER unsigned char period);
135 static void sim_limit(PARAMETER float GF_current); 133 static void sim_limit(PARAMETER float GF_current);
136 static void sim_extra_time(void); 134 static void sim_extra_time(void);
137 static void calc_dive_interval(void); 135 static void calc_dive_interval(void);
138 136
191 static float var_N2_b; // Bühlmann b, for current N2 tissue. 189 static float var_N2_b; // Bühlmann b, for current N2 tissue.
192 static float var_He_a; // Bühlmann a, for current He tissue. 190 static float var_He_a; // Bühlmann a, for current He tissue.
193 static float var_He_b; // Bühlmann b, for current He tissue. 191 static float var_He_b; // Bühlmann b, for current He tissue.
194 static float var_N2_e; // Exposition, for current N2 tissue. 192 static float var_N2_e; // Exposition, for current N2 tissue.
195 static float var_He_e; // Exposition, for current He tissue. 193 static float var_He_e; // Exposition, for current He tissue.
194 static float var_N2_ht; // Half-time for current N2 tissue.
195 static float var_He_ht; // Half-time for current N2 tissue.
196 196
197 static float pres_diluent; // new in v.101 197 static float pres_diluent; // new in v.101
198 static float const_ppO2; // new in v.101 198 static float const_ppO2; // new in v.101
199 199
200 static unsigned char sim_gas_last_depth; // Depth of last used gas, to detected a gas switch. 200 static unsigned char sim_gas_last_depth; // Depth of last used gas, to detected a gas switch.
214 //---- Bank 6 parameters ----------------------------------------------------- 214 //---- Bank 6 parameters -----------------------------------------------------
215 #pragma udata bank6=0x600 215 #pragma udata bank6=0x600
216 216
217 float pres_tissue_N2[NUM_COMP]; 217 float pres_tissue_N2[NUM_COMP];
218 float pres_tissue_He[NUM_COMP]; 218 float pres_tissue_He[NUM_COMP];
219 float sim_pres_tissue_N2[NUM_COMP]; // 16 floats = 64 bytes.
220 float sim_pres_tissue_He[NUM_COMP]; // 16 floats = 64 bytes.
219 221
220 //---- Bank 7 parameters ----------------------------------------------------- 222 //---- Bank 7 parameters -----------------------------------------------------
221 #pragma udata bank7=0x700 223 #pragma udata bank7=0x700
222 224 // EMPTY ...
223 float sim_pres_tissue_N2[NUM_COMP]; // 32 floats = 128 bytes.
224 float sim_pres_tissue_He[NUM_COMP]; // 32 floats = 128 bytes.
225 static float sim_pres_tissue_backup_N2[NUM_COMP];
226 static float sim_pres_tissue_backup_He[NUM_COMP];
227 225
228 //---- Bank 8 parameters ----------------------------------------------------- 226 //---- Bank 8 parameters -----------------------------------------------------
229 #pragma udata bank8=0x800 227 #pragma udata bank8=0x800
230 228
231 static char md_pi_subst[256]; 229 static char md_pi_subst[256];
678 assert(0); // Never go there... 676 assert(0); // Never go there...
679 } 677 }
680 } 678 }
681 679
682 ////////////////////////////////////////////////////////////////////////////// 680 //////////////////////////////////////////////////////////////////////////////
681 // read buhlmann tables for compatriment ci
682 //
683 static void read_buhlmann_ht(void)
684 {
685
686 #ifndef CROSS_COMPILE
687 // Note: we don't use far rom pointer, because the
688 // 24 bits is to complex, hence we have to set
689 // the UPPER page ourself...
690 // --> Set zero if tables are moved to lower pages !
691 _asm
692 movlw 1
693 movwf TBLPTRU,0
694 _endasm
695 #endif
696
697 assert( 0 <= ci && ci < NUM_COMP );
698 {
699 overlay rom const float* ptr = &buhlmann_ht[2*ci];
700 var_N2_ht = *ptr++;
701 var_He_ht = *ptr++;
702 }
703
704 assert( 4.0 <= var_N2_ht && var_N2_ht <= 635.0 );
705 assert( 1.5099 <= var_He_ht && var_He_ht <= 240.03 );
706 }
707
708 //////////////////////////////////////////////////////////////////////////////
683 // calc_nextdecodepth 709 // calc_nextdecodepth
684 // 710 //
685 // new in v.102 711 // new in v.102
686 // 712 //
687 // INPUT, changing during dive: 713 // INPUT, changing during dive:
714 // temp_deco
688 // low_depth 715 // low_depth
689 // 716 //
690 // INPUT, fixed during dive: 717 // INPUT, fixed during dive:
691 // pres_surface 718 // pres_surface
692 // GF_delta 719 // GF_delta
715 overlay unsigned char need_stop = 0; 742 overlay unsigned char need_stop = 0;
716 743
717 assert( depth >= -0.2 ); // Allow for 200mbar of weather change. 744 assert( depth >= -0.2 ); // Allow for 200mbar of weather change.
718 745
719 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ 746 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------
720 if (char_I_deco_model == 1) 747 if( char_I_deco_model != 0 )
721 { 748 {
722 if( depth >= low_depth ) 749 if( depth >= low_depth )
723 sim_limit( GF_low ); 750 sim_limit( GF_low );
724 else 751 else
725 sim_limit( GF_high - depth * locked_GF_step ); 752 sim_limit( GF_high - depth * locked_GF_step );
1111 } 1138 }
1112 1139
1113 ////////////////////////////////////////////////////////////////////////////// 1140 //////////////////////////////////////////////////////////////////////////////
1114 // 1141 //
1115 // Input: calc_N2_ratio, calc_He_ratio : simulated gas mix. 1142 // Input: calc_N2_ratio, calc_He_ratio : simulated gas mix.
1116 // temp_deco : simulated respiration pressure + security offset (deco_distance) 1143 // temp_deco : simulated respiration pressure
1117 // float_deco_distance : security factor. 1144 // float_deco_distance : security factor.
1118 // Water-vapor pressure inside limbs (ppWater). 1145 // Water-vapor pressure inside limbs (ppWater).
1119 // 1146 //
1120 // Output: ppN2, ppHe. 1147 // Output: ppN2, ppHe.
1121 // 1148 //
1263 sim_dive_mins = 0; 1290 sim_dive_mins = 0;
1264 break; 1291 break;
1265 1292
1266 case 0: //---- bottom time ----------------------------------------------- 1293 case 0: //---- bottom time -----------------------------------------------
1267 default: 1294 default:
1295 gas_switch_find_current(); // Lookup for current gas & time.
1296 gas_switch_set(); // setup calc_ratio's
1297
1268 calc_nullzeit(); 1298 calc_nullzeit();
1269 check_ndl(); 1299 check_ndl();
1270 char_O_deco_status = 2; // calc ascent next time. 1300 char_O_deco_status = 2; // calc ascent next time.
1271 break; 1301 break;
1272 1302
1273 case 2: //---- Simulate ascent to first stop ----------------------------- 1303 case 2: //---- Simulate ascent to first stop -----------------------------
1274 case 6: // @+5min variation 1304 case 6: // @+5min variation
1275 // Check proposed gas at begin of ascent simulation 1305 // Check proposed gas at begin of ascent simulation
1276 sim_dive_mins = int_I_divemins; // Init current time. 1306 sim_dive_mins = int_I_divemins; // Init current time.
1277
1278 gas_switch_find_current(); // Lookup for current gas & time.
1279 gas_switch_set(); // setup calc_ratio's
1280 1307
1281 backup_gas_used = sim_gas_last_used; // And save for later simu steps. 1308 backup_gas_used = sim_gas_last_used; // And save for later simu steps.
1282 backup_gas_depth = sim_gas_last_depth; // And save for later simu steps. 1309 backup_gas_depth = sim_gas_last_depth; // And save for later simu steps.
1283 backup_gas_delay = sim_gas_delay; 1310 backup_gas_delay = sim_gas_delay;
1284 1311
1665 // Note: Also depends of the GF. So the calcul is different for 1692 // Note: Also depends of the GF. So the calcul is different for
1666 // GF_low, current GF, or GF_high... 1693 // GF_low, current GF, or GF_high...
1667 // *BUT* calc_tissue() is used to compute bottom time, 1694 // *BUT* calc_tissue() is used to compute bottom time,
1668 // hence what would happend at surface, 1695 // hence what would happend at surface,
1669 // hence at GF_high. 1696 // hence at GF_high.
1670 if( char_I_deco_model == 1 ) 1697 if( char_I_deco_model != 0 )
1671 p = ( p - var_N2_a * GF_high) * var_N2_b 1698 p = ( p - var_N2_a * GF_high) * var_N2_b
1672 / (GF_high + var_N2_b * (1.0 - GF_high)); 1699 / (GF_high + var_N2_b * (1.0 - GF_high));
1673 else 1700 else
1674 p = (p - var_N2_a) * var_N2_b; 1701 p = (p - var_N2_a) * var_N2_b;
1675 if( p < 0.0 ) p = 0.0; 1702 if( p < 0.0 ) p = 0.0;
1688 ////////////////////////////////////////////////////////////////////////////// 1715 //////////////////////////////////////////////////////////////////////////////
1689 // calc_nullzeit 1716 // calc_nullzeit
1690 // 1717 //
1691 // calculates the remaining bottom time 1718 // calculates the remaining bottom time
1692 // 1719 //
1693 // unchanged in v.101 1720 // 2011-11-20 jDG: Changed (beta 2.06) to use Eric Baker's direct NDL formula.
1721 //
1722 // Input: pres_respiration
1723 // Output: char_O_nullzeit
1694 // 1724 //
1695 static void calc_nullzeit(void) 1725 static void calc_nullzeit(void)
1696 { 1726 {
1697 overlay unsigned char loop; 1727 overlay float Pin;
1698 update_startvalues(); 1728
1699 1729 temp_deco = pres_respiration;
1700 char_O_nullzeit = 0; 1730 sim_alveolar_presures();
1701 for(loop = 1; loop <= 17; loop++) 1731 Pin = ppN2 + ppHe;
1702 { 1732
1703 backup_sim_pres_tissue(); 1733 char_O_nullzeit = 240;
1704 sim_tissue(2); // 10 min. 1734 for(ci=0; ci<NUM_COMP; ci++)
1705 sim_limit(GF_high); 1735 {
1706 1736 //---- Compute composite A/B values and half times for the mix -------
1707 if( sim_lead_tissue_limit > pres_surface ) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately 1737 overlay float N2 = pres_tissue_N2[ci];
1708 { 1738 overlay float He = pres_tissue_He[ci];
1709 restore_sim_pres_tissue(); 1739 overlay float p = N2 + He;
1710 break; 1740
1711 } 1741 read_buhlmann_ht();
1712 // Validate once we know its good. 1742 var_N2_ht = (var_N2_ht * N2 + var_He_ht * He) / p;
1713 char_O_nullzeit += 10; 1743
1714 } 1744 read_buhlmann_coefficients();
1715 1745 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p;
1716 if (char_O_nullzeit < 60) 1746 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p;
1717 { 1747
1718 for(loop=1; loop <= 10; loop++) 1748 //---- Calc time for that tissue -------------------------------------
1719 { 1749 // Erik Baker's formula:
1720 sim_tissue(1); // 1 min 1750 // M0 (M-value at surface) = var_N2_a + pres_surface/var_N2_b
1721 sim_limit(GF_high); 1751 // Pin = respirated pressure ppN2 + ppHe
1722 1752 // p = pressure inside tissue
1723 if( sim_lead_tissue_limit > pres_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately 1753 // 0.6931 = log(2)
1724 break; 1754 // NDL(ci) = log((Pin - p)/(Pin - M0))/log(2) * ht
1725 char_O_nullzeit++; 1755 //
1726 } 1756 if( Pin > p ) // Only when on-gasing
1727 } 1757 {
1728 } 1758 overlay float M0 = (var_N2_a + pres_surface/var_N2_b);
1729 1759
1730 ////////////////////////////////////////////////////////////////////////////// 1760 // Apply security margin when using the GF model
1731 // backup_sim_pres_tissue 1761 if( char_I_deco_model != 0 )
1732 // 1762 M0 = GF_high * (M0 - pres_surface) + pres_surface;
1733 void backup_sim_pres_tissue(void) 1763
1734 { 1764 if( Pin > M0 )
1735 overlay unsigned char x; 1765 {
1736 1766 overlay unsigned char indl;
1737 for(x=0; x<NUM_COMP; x++) 1767
1738 { 1768 overlay float ndl = log((Pin - p)/(Pin - M0)) * var_N2_ht/0.6931;
1739 sim_pres_tissue_backup_N2[x] = sim_pres_tissue_N2[x]; 1769
1740 sim_pres_tissue_backup_He[x] = sim_pres_tissue_He[x]; 1770 // Apply non-GF model security margins:
1741 } 1771 // Saturation factor will be applied to gas loading, accelerating
1742 } 1772 // loading, hence we should decrease NDL accordingly.
1743 1773 if( char_I_deco_model == 0)
1744 ////////////////////////////////////////////////////////////////////////////// 1774 ndl /= float_saturation_multiplier;
1745 // restore_sim_pres_tissue 1775
1746 // 1776 if( ndl < 0.0f ) ndl = 0.0f;
1747 void restore_sim_pres_tissue(void) 1777 if( ndl > 254.5f ) ndl = 255.0f;
1748 { 1778 indl = (unsigned char)(ndl + 0.5f);
1749 overlay unsigned char x; 1779 if( indl < char_O_nullzeit )
1750 1780 char_O_nullzeit = indl;
1751 for(x=0; x<NUM_COMP; x++) 1781 }
1752 { 1782 }
1753 sim_pres_tissue_N2[x] = sim_pres_tissue_backup_N2[x];
1754 sim_pres_tissue_He[x] = sim_pres_tissue_backup_He[x];
1755 } 1783 }
1756 } 1784 }
1757 1785
1758 ////////////////////////////////////////////////////////////////////////////// 1786 //////////////////////////////////////////////////////////////////////////////
1759 // calc_ascenttime 1787 // calc_ascenttime
1860 // Apply the Eric Baker's varying gradient factor correction. 1888 // Apply the Eric Baker's varying gradient factor correction.
1861 // Note: the correction factor depends both on GF and b, 1889 // Note: the correction factor depends both on GF and b,
1862 // Actual values are in the 1.5 .. 1.0 range (for a GF=30%), 1890 // Actual values are in the 1.5 .. 1.0 range (for a GF=30%),
1863 // so that can change who is the leading gas... 1891 // so that can change who is the leading gas...
1864 // Note: Also depends of the GF_current... 1892 // Note: Also depends of the GF_current...
1865 if( char_I_deco_model == 1 ) 1893 if( char_I_deco_model != 0 )
1866 p = ( p - var_N2_a * GF_current) 1894 p = ( p - var_N2_a * GF_current)
1867 / (GF_current / var_N2_b + 1.0 - GF_current); 1895 / (GF_current / var_N2_b + 1.0 - GF_current);
1868 else 1896 else
1869 p = (p - var_N2_a) * var_N2_b; 1897 p = (p - var_N2_a) * var_N2_b;
1870 if( p < 0.0 ) p = 0.0; 1898 if( p < 0.0 ) p = 0.0;
1972 overlay float limit = calc_lead_tissue_limit; 2000 overlay float limit = calc_lead_tissue_limit;
1973 // NOTE: in GF model, calc_lead_tissue_limit include already the 2001 // NOTE: in GF model, calc_lead_tissue_limit include already the
1974 // correction due to gradient factor. To compute the actual 2002 // correction due to gradient factor. To compute the actual
1975 // current GF, we need to (re-)compute the raw ambiant-pressure 2003 // current GF, we need to (re-)compute the raw ambiant-pressure
1976 // limit from the Bühlmann model. 2004 // limit from the Bühlmann model.
1977 if( char_I_deco_model == 1 ) 2005 if( char_I_deco_model != 0 )
1978 { 2006 {
1979 ci = char_O_gtissue_no; 2007 ci = char_O_gtissue_no;
1980 read_buhlmann_coefficients(); 2008 read_buhlmann_coefficients();
1981 var_N2_a = (var_N2_a * N2 + var_He_a * He) / temp_tissue; 2009 var_N2_a = (var_N2_a * N2 + var_He_a * He) / temp_tissue;
1982 var_N2_b = (var_N2_b * N2 + var_He_b * He) / temp_tissue; 2010 var_N2_b = (var_N2_b * N2 + var_He_b * He) / temp_tissue;
1989 if( gf > 254.5 ) gf = 255.0; 2017 if( gf > 254.5 ) gf = 255.0;
1990 if( gf < 0.0 ) gf = 0.0; 2018 if( gf < 0.0 ) gf = 0.0;
1991 } 2019 }
1992 char_O_gradient_factor = (unsigned char)(gf+0.5f); 2020 char_O_gradient_factor = (unsigned char)(gf+0.5f);
1993 2021
1994 if (char_I_deco_model == 1) // calculate relative gradient factor 2022 if( char_I_deco_model != 0 ) // calculate relative gradient factor
1995 { 2023 {
1996 overlay float rgf; 2024 overlay float rgf;
1997 2025
1998 if( low_depth < 1.5 ) 2026 if( low_depth < 1.5 )
1999 rgf = GF_high; 2027 rgf = GF_high;
2029 // Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier 2057 // Inputs: int_I_pres_surface, ppWater, char_I_desaturation_multiplier
2030 // Outputs: int_O_desaturation_time, char_O_tissue_saturation[0..31] 2058 // Outputs: int_O_desaturation_time, char_O_tissue_saturation[0..31]
2031 // 2059 //
2032 void deco_calc_desaturation_time(void) 2060 void deco_calc_desaturation_time(void)
2033 { 2061 {
2034 overlay rom const float *ptr;
2035
2036 RESET_C_STACK 2062 RESET_C_STACK
2037 2063
2038 assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 ); 2064 assert( 800 < int_I_pres_surface && int_I_pres_surface < 1100 );
2039 assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 ); 2065 assert( 0 < char_I_desaturation_multiplier && char_I_desaturation_multiplier <= 100 );
2040
2041 #ifndef CROSS_COMPILE
2042 // Note: we don't use far rom pointer, because the
2043 // 24 bits is to complex, hence we have to set
2044 // the UPPER page ourself...
2045 // --> Set zero if tables are moved to lower pages !
2046 _asm
2047 movlw 1
2048 movwf TBLPTRU,0
2049 _endasm
2050 #endif
2051 2066
2052 N2_ratio = 0.7902; // FIXED sum as stated in bühlmann 2067 N2_ratio = 0.7902; // FIXED sum as stated in bühlmann
2053 pres_surface = int_I_pres_surface * 0.001; 2068 pres_surface = int_I_pres_surface * 0.001;
2054 ppN2 = N2_ratio * (pres_surface - ppWater); 2069 ppN2 = N2_ratio * (pres_surface - ppWater);
2055 int_O_desaturation_time = 0; 2070 int_O_desaturation_time = 0;
2056 float_desaturation_multiplier = char_I_desaturation_multiplier * (0.01 * SURFACE_DESAT_FACTOR); 2071 float_desaturation_multiplier = char_I_desaturation_multiplier * (0.01 * SURFACE_DESAT_FACTOR);
2057 2072
2058 ptr = &buhlmann_ht[0];
2059 for(ci=0; ci<NUM_COMP; ci++) 2073 for(ci=0; ci<NUM_COMP; ci++)
2060 { 2074 {
2061 overlay float var_N2_halftime = *ptr++;
2062 overlay float var_He_halftime = *ptr++;
2063 overlay unsigned short desat_time; // For a particular compartiment, in min. 2075 overlay unsigned short desat_time; // For a particular compartiment, in min.
2064 overlay float temp1; 2076 overlay float temp1;
2065 overlay float temp2; 2077 overlay float temp2;
2066 overlay float temp3; 2078 overlay float temp3;
2067 overlay float temp4; 2079 overlay float temp4;
2068 2080
2069 assert( 4.0 <= var_N2_halftime && var_N2_halftime <= 635.0 ); 2081 read_buhlmann_ht();
2070 assert( 1.5099 <= var_He_halftime && var_He_halftime <= 240.03 );
2071 2082
2072 // saturation_time (for flight) and N2_saturation in multiples of halftime 2083 // saturation_time (for flight) and N2_saturation in multiples of halftime
2073 // version v.100: 1.1 = 10 percent distance to totally clean (totally clean is not possible, would take infinite time ) 2084 // version v.100: 1.1 = 10 percent distance to totally clean (totally clean is not possible, would take infinite time )
2074 // new in version v.101: 1.07 = 7 percent distance to totally clean (totally clean is not possible, would take infinite time ) 2085 // new in version v.101: 1.07 = 7 percent distance to totally clean (totally clean is not possible, would take infinite time )
2075 // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and NoFly calculations 2086 // changes in v.101: 1.05 = 5 percent dist to totally clean is new desaturation point for display and NoFly calculations
2086 if( 0.0 < temp1 && temp1 < 1.0 ) 2097 if( 0.0 < temp1 && temp1 < 1.0 )
2087 { 2098 {
2088 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. 2099 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
2089 // minus because log is negative. 2100 // minus because log is negative.
2090 temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary. 2101 temp1 = log(1.0 - temp1) / -0.6931; // temp1 is the multiples of half times necessary.
2091 temp2 = var_N2_halftime * temp1 / float_desaturation_multiplier; // time necessary (in minutes ) for complete desaturation (see comment about 5 percent) , new in v.101: float_desaturation_multiplier 2102 temp2 = var_N2_ht * temp1 / float_desaturation_multiplier; // time necessary (in minutes ) for complete desaturation (see comment about 5 percent) , new in v.101: float_desaturation_multiplier
2092 2103
2093 } 2104 }
2094 else 2105 else
2095 { 2106 {
2096 temp1 = 0.0; 2107 temp1 = 0.0;
2109 if( 0.0 < temp3 && temp3 < 1.0 ) 2120 if( 0.0 < temp3 && temp3 < 1.0 )
2110 { 2121 {
2111 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary. 2122 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary.
2112 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. 2123 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
2113 // minus because log is negative 2124 // minus because log is negative
2114 temp4 = var_He_halftime * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier 2125 temp4 = var_He_ht * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier
2115 } 2126 }
2116 else 2127 else
2117 { 2128 {
2118 temp3 = 0.0; 2129 temp3 = 0.0;
2119 temp4 = 0.0; 2130 temp4 = 0.0;