comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 171:7f3e1bf588bc

More p2_deco.c cleanups + char_I_table_deco_done[] was never initialised. + temp_deco (deco presure) in meter (instead of bars), p2_deco.c line 661 ! Gas switches: + Added check_gas_switch() and calc_gas_switch state.
author JeanDo
date Tue, 01 Feb 2011 00:24:46 +0100
parents e26f49674956
children 016c45a0caaf
comparison
equal deleted inserted replaced
170:0f7ca37b1412 171:7f3e1bf588bc
56 // 03/13/25 v101: CNS_fraction calculation 56 // 03/13/25 v101: CNS_fraction calculation
57 // 03/13/26 v101: optimization of tissue calc routines 57 // 03/13/26 v101: optimization of tissue calc routines
58 // 07/xx/08 v102a: debug of bottom time routine 58 // 07/xx/08 v102a: debug of bottom time routine
59 // 09/xx/08 v102d: Gradient Factor Model implemenation 59 // 09/xx/08 v102d: Gradient Factor Model implemenation
60 // 10/10/08 v104: renamed to build v103 for v118 stable 60 // 10/10/08 v104: renamed to build v103 for v118 stable
61 // 10/14/08 v104: integration of temp_depth_last_deco for Gradient Model 61 // 10/14/08 v104: integration of char_I_depth_last_deco for Gradient Model
62 // 03/31/09 v107: integration of FONT Incon24 62 // 03/31/09 v107: integration of FONT Incon24
63 // 05/23/10 v109: 5 gas changes & 1 min timer 63 // 05/23/10 v109: 5 gas changes & 1 min timer
64 // 07/13/10 v110: cns vault added 64 // 07/13/10 v110: cns vault added
65 // 12/25/10 v110: split in three files (deco.c, main.c, definitions.h) 65 // 12/25/10 v110: split in three files (deco.c, main.c, definitions.h)
66 // 2011/01/20: [jDG] Create a common file included in ASM and C code. 66 // 2011/01/20: [jDG] Create a common file included in ASM and C code.
113 static void calc_hauptroutine_data_input(void); 113 static void calc_hauptroutine_data_input(void);
114 static void calc_hauptroutine_update_tissues(void); 114 static void calc_hauptroutine_update_tissues(void);
115 static void calc_hauptroutine_calc_deco(void); 115 static void calc_hauptroutine_calc_deco(void);
116 static void sim_ascent_to_first_stop(void); 116 static void sim_ascent_to_first_stop(void);
117 117
118 static void calc_nextdecodepth_GF(void); 118 static void calc_nextdecodepth(void);
119 119
120 // *********************************************** 120 // ***********************************************
121 // ** V A R I A B L E S D E F I N I T I O N S ** 121 // ** V A R I A B L E S D E F I N I T I O N S **
122 // *********************************************** 122 // ***********************************************
123 123
130 static unsigned char lock_GF_depth_list; 130 static unsigned char lock_GF_depth_list;
131 static float temp_limit; 131 static float temp_limit;
132 static float GF_low; 132 static float GF_low;
133 static float GF_high; 133 static float GF_high;
134 static float GF_delta; 134 static float GF_delta;
135 static float GF_temp; 135 static float locked_GF_step;
136 static float GF_step; 136
137 static float GF_step2; 137 static float sim_pres_gtissue;
138 static float temp_pres_gtissue; 138 static float sim_pres_gtissue_diff;
139 static float temp_pres_gtissue_diff; 139 static float sim_pres_gtissue_limit_GF_low;
140 static float temp_pres_gtissue_limit_GF_low; 140 static float sim_pres_gtissue_limit_GF_low_below_surface;
141 static float temp_pres_gtissue_limit_GF_low_below_surface; 141 static unsigned char temp_depth_limit;
142 static unsigned int temp_depth_limit; 142 static float sim_pres_gtissue_limit;
143 static unsigned char temp_gtissue_no; 143 static unsigned char sim_gtissue_no;
144 static unsigned int temp_depth_last_deco; // new in v.101
145 144
146 static unsigned char temp_depth_GF_low_meter; 145 static unsigned char temp_depth_GF_low_meter;
147 static unsigned char internal_deco_pointer; 146 static unsigned char internal_deco_pointer;
148 147
149 static unsigned char internal_deco_time[32]; 148 static unsigned char internal_deco_time[32];
176 static float var_N2_e; 175 static float var_N2_e;
177 static float var_He_e; 176 static float var_He_e;
178 static float var_N2_halftime; 177 static float var_N2_halftime;
179 static float var_He_halftime; 178 static float var_He_halftime;
180 static float pres_gtissue_limit; 179 static float pres_gtissue_limit;
181 static float temp_pres_gtissue_limit;
182 180
183 static float pres_diluent; // new in v.101 181 static float pres_diluent; // new in v.101
184 static float deco_diluent; // new in v.101 182 static float deco_diluent; // new in v.101
185 static float const_ppO2; // new in v.101 183 static float const_ppO2; // new in v.101
186 static float deco_ppO2_change; // new in v.101 184 static float deco_ppO2_change; // new in v.101
187 static float deco_ppO2; // new in v.101 185 static float deco_ppO2; // new in v.101
188 186
187 static unsigned char calc_gas_switch; // Detected a gas switch.
189 static float calc_N2_ratio; // new in v.101 188 static float calc_N2_ratio; // new in v.101
190 static float calc_He_ratio; // new in v.101 189 static float calc_He_ratio; // new in v.101
191 static float CNS_fraction; // new in v.101 190 static float CNS_fraction; // new in v.101
192 static float float_saturation_multiplier; // new in v.101 191 static float float_saturation_multiplier; // new in v.101
193 static float float_desaturation_multiplier; // new in v.101 192 static float float_desaturation_multiplier; // new in v.101
585 // calc_next_decodepth_GF 584 // calc_next_decodepth_GF
586 // 585 //
587 // new in v.102 586 // new in v.102
588 // 587 //
589 // INPUT, changing during dive: 588 // INPUT, changing during dive:
590 // temp_pres_gtissue_limit_GF_low 589 // sim_pres_gtissue_limit_GF_low
591 // temp_pres_gtissue_limit_GF_low_below_surface 590 // sim_pres_gtissue_limit_GF_low_below_surface
592 // temp_pres_gtissue 591 // sim_pres_gtissue
593 // temp_pres_gtissue_diff 592 // sim_pres_gtissue_diff
594 // lock_GF_depth_list 593 // lock_GF_depth_list
595 // 594 //
596 // INPUT, fixed during dive: 595 // INPUT, fixed during dive:
597 // pres_surface 596 // pres_surface
598 // GF_delta 597 // GF_delta
599 // GF_high 598 // GF_high
600 // GF_low 599 // GF_low
601 // temp_depth_last_deco 600 // char_I_depth_last_deco
602 // float_deco_distance 601 // float_deco_distance
603 // 602 //
604 // OUTPUT 603 // OUTPUT
605 // GF_step 604 // locked_GF_step
606 // temp_deco 605 // temp_deco
607 // temp_depth_limt 606 // temp_depth_limt
608 // lock_GF_depth_list 607 // lock_GF_depth_list
609 // 608 //
610 static void calc_nextdecodepth_GF(void) 609 static void calc_nextdecodepth(void)
611 { 610 {
612
613 char_I_table_deco_done[0] = 0; // safety if changed somewhere else. Needed for exit
614
615 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ 611 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------
616 if (char_I_deco_model == 1) 612 if (char_I_deco_model == 1)
617 { 613 {
618 overlay float next_stop; // Next stop to test, in Bar. 614 overlay float next_stop; // Next stop to test, in Bar.
619 overlay float press_tol; // Upper limit (lower pressure) tolerated.
620 overlay int int_temp;
621 overlay unsigned char temp_depth_GF_low_number;
622 overlay float temp_pres_deco_GF_low;
623 615
624 if (lock_GF_depth_list == 0) 616 if (lock_GF_depth_list == 0)
625 { 617 {
626 next_stop = temp_pres_gtissue_limit_GF_low_below_surface / 0.29985; // = ... / 99.95 / 0.003; 618 overlay unsigned char temp_depth_GF_low_number;
627 int_temp = (int) (next_stop + 0.99); 619
628 if (int_temp > 31) 620 next_stop = sim_pres_gtissue_limit_GF_low_below_surface / 0.29985;
629 int_temp = 31; // deepest deco at 93 meter (31 deco stops) 621 temp_depth_GF_low_number = (int) (next_stop + 0.99); // Deepest stop index.
630 if (int_temp < 0) 622 if (temp_depth_GF_low_number > 31)
631 int_temp = 0; 623 temp_depth_GF_low_number = 31; // deepest deco at 93 meter (31 deco stops)
632 temp_depth_GF_low_number = int_temp; 624 if (temp_depth_GF_low_number < 0)
625 temp_depth_GF_low_number = 0;
633 temp_depth_GF_low_meter = 3 * temp_depth_GF_low_number; 626 temp_depth_GF_low_meter = 3 * temp_depth_GF_low_number;
634 next_stop = (float)temp_depth_GF_low_meter * 0.09995; 627 next_stop = (float)temp_depth_GF_low_meter * 0.09995;
635 temp_pres_deco_GF_low = next_stop + float_deco_distance + pres_surface;
636 if (temp_depth_GF_low_number == 0) 628 if (temp_depth_GF_low_number == 0)
637 GF_step = 0; 629 locked_GF_step = 0;
638 else 630 else
639 GF_step = GF_delta / (float)temp_depth_GF_low_number; 631 locked_GF_step = GF_delta / (float)temp_depth_GF_low_number;
640 if (GF_step < 0)
641 GF_step = 0;
642 if (GF_step > GF_delta)
643 GF_step = GF_delta;
644 int_O_GF_step = (int)(GF_step * 10000);
645 int_O_limit_GF_low = (int)(temp_pres_deco_GF_low * 1000);
646 int_O_gtissue_press_at_GF_low = (int)(temp_pres_gtissue * 1000);
647 char_O_GF_low_pointer = temp_depth_GF_low_number;
648 lock_GF_depth_list = 1; 632 lock_GF_depth_list = 1;
649 internal_deco_pointer = 0; 633
634 // new run
635 internal_deco_pointer = temp_depth_GF_low_number;
650 } 636 }
651 if (internal_deco_pointer == 0) // new run 637
652 { 638 // Check all stops until one is higher that tolerated presure
653 internal_deco_pointer = temp_depth_GF_low_number; 639 while(internal_deco_pointer > 0)
654 GF_temp = GF_high - ((float)internal_deco_pointer * GF_step); 640 {
655 int_temp = char_I_table_deco_done[internal_deco_pointer]; 641 overlay unsigned char index; // Next index (0..30)
642 overlay unsigned char next_depth_limit; // Next depth (0m..90m)
643 overlay float press_tol; // Upper limit (lower pressure) tolerated.
644 overlay float GF_temp; // Changing Gradient-Factor value at next depth.
645
646 index = internal_deco_pointer - 1; // Index of next (upper) stop.
647 if (index == 1) // new in v104
648 next_depth_limit = char_I_depth_last_deco; // Use last 3m..6m instead.
649 else
650 next_depth_limit = 3 * index; // Convert index to meter.
651
652 next_stop = next_depth_limit * 0.09995 // Meters to bar
653 + pres_surface;
654 // current GF is GF_high - alpha (GF_high - GF_low)
655 // With alpha = currentStop / (totalStops-1), hence in [0..1]
656 GF_temp = GF_high - (next_depth_limit/3) * locked_GF_step;
657
658 // upper limit (lowest pressure tolerated):
659 press_tol = GF_temp * sim_pres_gtissue_diff + sim_pres_gtissue;
660
661 if( press_tol > next_stop ) // check if ascent to next deco stop is ok
662 break;
663
664 // Else, validate that stop and loop...
665 internal_deco_pointer = index;
656 } 666 }
657 else 667
658 { 668 // Redo the results once we do have the validated index
659 int_temp = 1; 669 if( internal_deco_pointer==1 )
660 } 670 temp_depth_limit = char_I_depth_last_deco; // Use last 3m..6m instead.
661 while (int_temp == 1) 671 else
662 { 672 temp_depth_limit = 3 * internal_deco_pointer; // Normal depth, from 0m to 96m
663 int_temp = internal_deco_pointer - 1; 673 temp_deco = temp_depth_limit * 0.09995 // Convert to bars.
664 if (int_temp == 1) // new in v104 674 + pres_surface;
665 { 675 if (internal_deco_pointer != 0)
666 next_stop = (float)(temp_depth_last_deco * int_temp) * 0.09995; 676 temp_deco += float_deco_distance; // Add security distance (bars too)
667 GF_step2 = GF_step/3.0 * ((float)(6 - temp_depth_last_deco));
668 }
669 else
670 if (int_temp == 0)
671 {
672 next_stop = 0.0;
673 GF_step2 = GF_high - GF_temp;
674 }
675 else
676 {
677 next_stop = (float)(3 *int_temp) * 0.09995;
678 GF_step2 = GF_step;
679 }
680 next_stop = next_stop + pres_surface; // next deco stop to be tested
681 press_tol = ((GF_temp + GF_step2)* temp_pres_gtissue_diff) + temp_pres_gtissue; // upper limit (lowest pressure allowed) // changes GF_step2 in v104
682 if (press_tol > next_stop) // check if ascent to next deco stop is ok
683 {
684 int_temp = 0; // no
685 }
686 else
687 {
688 internal_deco_pointer = int_temp;
689 GF_temp = GF_temp + GF_step2; // changed in v104
690 int_temp = char_I_table_deco_done[internal_deco_pointer]; // yes and check for ascent to even next stop if deco_done is set
691 }
692 } // while
693
694 if (internal_deco_pointer > 0)
695 {
696 next_stop = 0.29985 * internal_deco_pointer;
697 temp_deco = next_stop + float_deco_distance + pres_surface;
698 if (internal_deco_pointer == 1) // new in v104
699 temp_depth_limit = temp_depth_last_deco;
700 else
701 temp_depth_limit = 3 * internal_deco_pointer;
702 }
703 else // if (char_I_deco_model == 1)
704 {
705 temp_deco = pres_surface;
706 temp_depth_limit = 0;
707 }
708 } 677 }
709 else //---- ZH-L16 model ------------------------------------------------- 678 else //---- ZH-L16 model -------------------------------------------------
710 { 679 {
711 // calc_nextdecodepth - original 680 // calc_nextdecodepth - original model
712 // optimized in v.101 681 // optimized in v.101
713 // depth_last_deco included in v.101 682 // char_I_depth_last_deco included in v.101
714 683
715 overlay float pres_gradient = temp_pres_gtissue_limit - pres_surface; 684 overlay float pres_gradient = sim_pres_gtissue_limit - pres_surface;
716 if (pres_gradient >= 0) 685 if (pres_gradient >= 0)
717 { 686 {
718 pres_gradient = pres_gradient / 0.29985; // = pres_gradient / 99.95 / 0.003; 687 pres_gradient = pres_gradient / 0.29985; // == pres_gradient / 99.95 / 3m;
719 temp_depth_limit = (int) (pres_gradient + 0.99); 688 temp_depth_limit = 3 * (int) (pres_gradient + 0.99); // depth for deco [m]
720 temp_depth_limit = 3 * temp_depth_limit; // depth for deco [m] 689 if (temp_depth_limit == 0) // At surface ?
721 if (temp_depth_limit == 0)
722 temp_deco = pres_surface; 690 temp_deco = pres_surface;
723 else 691 else
724 { 692 {
725 if (temp_depth_limit < temp_depth_last_deco) 693 if (temp_depth_limit < char_I_depth_last_deco) // Implement last stop at 4m/5m/6m...
726 temp_depth_limit = temp_depth_last_deco; 694 temp_depth_limit = char_I_depth_last_deco;
727 pres_gradient = (float)temp_depth_limit * 0.09995; 695 temp_deco = (temp_depth_limit * 0.09995) // depth for deco [bar] = depth
728 temp_deco = pres_gradient + float_deco_distance + pres_surface; // depth for deco [bar] 696 + float_deco_distance // + security margin
729 } // if (temp_depth_limit == 0) 697 + pres_surface; // + surface ambient presure
730 } // if (pres_gradient >= 0) 698 }
699 }
731 else 700 else
732 { 701 {
733 temp_deco = pres_surface; 702 temp_deco = pres_surface; // surface ambient presure
734 temp_depth_limit = 0; 703 temp_depth_limit = 0; // stop number = 0
735 } // if (pres_gradient >= 0) 704 }
736 } // calc_nextdecodepth original 705 }
737 } 706 }
738 707
739 ////////////////////////////////////////////////////////////////////////////// 708 //////////////////////////////////////////////////////////////////////////////
740 // copy_deco_table 709 // copy_deco_table
741 // 710 //
967 // 936 //
968 // this is the major code in dive mode calculates: 937 // this is the major code in dive mode calculates:
969 // the tissues, 938 // the tissues,
970 // the bottom time, 939 // the bottom time,
971 // and simulates the ascend with all deco stops. 940 // and simulates the ascend with all deco stops.
972 941 //
942 // The deco_state sequence is :
943 // 3 (at surface)
944 // +---> 0 : calc nullzeit
945 // | 2 : simulate ascent to first stop (at 10m/min, less that 16x 1min simu)
946 // | +-> 1 : simulate up to 16min of stops.
947 // | +------< not finished
948 // +--------< finish
949 //
973 static void calc_hauptroutine(void) 950 static void calc_hauptroutine(void)
974 { 951 {
975 calc_hauptroutine_data_input(); 952 calc_hauptroutine_data_input();
976 953
977 if(!flag_in_divemode) 954 if(!flag_in_divemode)
997 char_O_deco_status = 2; // calc ascent next time. 974 char_O_deco_status = 2; // calc ascent next time.
998 break; 975 break;
999 976
1000 case 1: //---- Simulate stops -------------------------------------------- 977 case 1: //---- Simulate stops --------------------------------------------
1001 calc_hauptroutine_calc_deco(); 978 calc_hauptroutine_calc_deco();
979 // Sets char_O_deco_status to 0 (buffered results, and restart nullzeit),
980 // or 1 (more stops to simulate).
1002 break; 981 break;
1003 982
1004 case 3: //---- At surface: start a new dive ------------------------------ 983 case 3: //---- At surface: start a new dive ------------------------------
1005 clear_deco_table(); 984 clear_deco_table();
1006 copy_deco_table(); 985 copy_deco_table();
1007 internal_deco_pointer = 0; 986 internal_deco_pointer = 0;
1008 lock_GF_depth_list = 0; 987 lock_GF_depth_list = 0;
1009 update_startvalues(); 988 update_startvalues();
1010 calc_nextdecodepth_GF(); 989 calc_nextdecodepth();
1011 char_O_deco_status = 0; // Calc nullzeit next time. 990 char_O_deco_status = 0; // Calc nullzeit next time.
1012 break; 991 break;
1013 992
1014 case 2: //---- Simulate ascent to first stop ----------------------------- 993 case 2: //---- Simulate ascent to first stop -----------------------------
1015 sim_ascent_to_first_stop(); 994 sim_ascent_to_first_stop();
1112 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0; 1091 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0;
1113 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; 1092 float_saturation_multiplier = char_I_saturation_multiplier / 100.0;
1114 GF_low = (float)char_I_GF_Low_percentage / 100.0; 1093 GF_low = (float)char_I_GF_Low_percentage / 100.0;
1115 GF_high = (float)char_I_GF_High_percentage / 100.0; 1094 GF_high = (float)char_I_GF_High_percentage / 100.0;
1116 GF_delta = GF_high - GF_low; 1095 GF_delta = GF_high - GF_low;
1117 1096 }
1118 temp2 = (pres_respiration - pres_surface) / 0.29985; 1097
1119 int_temp = (int)(temp2); 1098 //////////////////////////////////////////////////////////////////////////////
1120 if (int_temp < 0) 1099 //
1121 int_temp = 0; 1100 //
1122 if (int_temp > 255)
1123 int_temp = 255;
1124 char_O_actual_pointer = int_temp;
1125
1126 temp_depth_last_deco = (int)char_I_depth_last_deco;
1127 }
1128
1129 //////////////////////////////////////////////////////////////////////////////
1130
1131 void calc_hauptroutine_update_tissues(void) 1101 void calc_hauptroutine_update_tissues(void)
1132 { 1102 {
1133 int_O_calc_tissue_call_counter = int_O_calc_tissue_call_counter + 1;
1134 if (char_I_const_ppO2 == 0) // new in v.101 1103 if (char_I_const_ppO2 == 0) // new in v.101
1135 pres_diluent = pres_respiration; // new in v.101 1104 pres_diluent = pres_respiration; // new in v.101
1136 else // new in v.101 1105 else // new in v.101
1137 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 1106 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101
1138 if (pres_diluent > pres_respiration) // new in v.101 1107 if (pres_diluent > pres_respiration) // new in v.101
1169 if (pres_gtissue_limit > temp1 && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately 1138 if (pres_gtissue_limit > temp1 && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately
1170 { 1139 {
1171 char_O_nullzeit = 0; // deco necessary 1140 char_O_nullzeit = 0; // deco necessary
1172 char_O_deco_status = 2; // calculate ascent on next iteration. 1141 char_O_deco_status = 2; // calculate ascent on next iteration.
1173 } 1142 }
1174 } // calc_hauptroutine_update_tissues 1143 }
1144
1145 //////////////////////////////////////////////////////////////////////////////
1146 // Calculate gas switches
1147 //
1148 //
1149 void check_gas_switch(void)
1150 {
1151 calc_N2_ratio = N2_ratio;
1152 calc_He_ratio = He_ratio;
1153
1154 if (char_I_const_ppO2 == 0)
1155 {
1156 deco_diluent = temp_deco;
1157 calc_gas_switch = 0;
1158
1159 if(deco_gas_change1 && (temp_deco < deco_gas_change1))
1160 {
1161 calc_N2_ratio = deco_N2_ratio1;
1162 calc_He_ratio = deco_He_ratio1;
1163 calc_gas_switch = 1;
1164 }
1165 if(deco_gas_change2 && (temp_deco < deco_gas_change2))
1166 {
1167 calc_N2_ratio = deco_N2_ratio2;
1168 calc_He_ratio = deco_He_ratio2;
1169 calc_gas_switch = 2;
1170 }
1171 if(deco_gas_change3 && (temp_deco < deco_gas_change3))
1172 {
1173 calc_N2_ratio = deco_N2_ratio3;
1174 calc_He_ratio = deco_He_ratio3;
1175 calc_gas_switch = 3;
1176 }
1177 if(deco_gas_change4 && (temp_deco < deco_gas_change4))
1178 {
1179 calc_N2_ratio = deco_N2_ratio4;
1180 calc_He_ratio = deco_He_ratio4;
1181 calc_gas_switch = 4;
1182 }
1183 if(deco_gas_change5 && (temp_deco < deco_gas_change5))
1184 {
1185 calc_N2_ratio = deco_N2_ratio5;
1186 calc_He_ratio = deco_He_ratio5;
1187 calc_gas_switch = 4;
1188 }
1189 }
1190 else
1191 {
1192 if (temp_deco > deco_ppO2_change)
1193 {
1194 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio));
1195 }
1196 else
1197 {
1198 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio));
1199 }
1200 }
1201
1202 if (deco_diluent > temp_deco)
1203 deco_diluent = temp_deco;
1204
1205 if (deco_diluent > 0.0627)
1206 {
1207 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627);
1208 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627);
1209 }
1210 else
1211 {
1212 temp_atem = 0.0;
1213 temp2_atem = 0.0;
1214 }
1215 }
1175 1216
1176 ////////////////////////////////////////////////////////////////////////////// 1217 //////////////////////////////////////////////////////////////////////////////
1177 // Compute stops. 1218 // Compute stops.
1178 // 1219 //
1179 // Note: because this can be very long, break on 16 iterations, and set state 1220 // Note: because this can be very long, break on 16 iterations, and set state
1183 { 1224 {
1184 overlay unsigned char loop; 1225 overlay unsigned char loop;
1185 1226
1186 for(loop = 0; loop < 16; ++loop) 1227 for(loop = 0; loop < 16; ++loop)
1187 { 1228 {
1188 calc_nextdecodepth_GF(); 1229 calc_nextdecodepth();
1189 1230
1190 //---- Finish computations once surface is reached ------------------- 1231 //---- Finish computations once surface is reached -------------------
1191 if( temp_depth_limit <= 0 ) 1232 if( temp_depth_limit <= 0 )
1192 { 1233 {
1193 copy_deco_table(); 1234 copy_deco_table();
1195 char_O_deco_status = 0; // calc nullzeit next time. 1236 char_O_deco_status = 0; // calc nullzeit next time.
1196 return; 1237 return;
1197 } 1238 }
1198 1239
1199 //---- Else, continue simulating the stops --------------------------- 1240 //---- Else, continue simulating the stops ---------------------------
1200 calc_N2_ratio = N2_ratio; 1241 check_gas_switch();
1201 calc_He_ratio = He_ratio;
1202
1203 if (char_I_const_ppO2 == 0)
1204 {
1205 deco_diluent = temp_deco;
1206
1207 if(deco_gas_change1 && (temp_deco < deco_gas_change1))
1208 {
1209 calc_N2_ratio = deco_N2_ratio1;
1210 calc_He_ratio = deco_He_ratio1;
1211 }
1212 if(deco_gas_change2 && (temp_deco < deco_gas_change2))
1213 {
1214 calc_N2_ratio = deco_N2_ratio2;
1215 calc_He_ratio = deco_He_ratio2;
1216 }
1217 if(deco_gas_change3 && (temp_deco < deco_gas_change3))
1218 {
1219 calc_N2_ratio = deco_N2_ratio3;
1220 calc_He_ratio = deco_He_ratio3;
1221 }
1222 if(deco_gas_change4 && (temp_deco < deco_gas_change4))
1223 {
1224 calc_N2_ratio = deco_N2_ratio4;
1225 calc_He_ratio = deco_He_ratio4;
1226 }
1227 if(deco_gas_change5 && (temp_deco < deco_gas_change5))
1228 {
1229 calc_N2_ratio = deco_N2_ratio5;
1230 calc_He_ratio = deco_He_ratio5;
1231 }
1232 }
1233 else
1234 {
1235 if (temp_deco > deco_ppO2_change)
1236 {
1237 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio));
1238 }
1239 else
1240 {
1241 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio));
1242 }
1243 }
1244
1245 if (deco_diluent > temp_deco) // new in v.101
1246 deco_diluent = temp_deco; // new in v.101
1247
1248 if (deco_diluent > 0.0627) // new in v.101
1249 {
1250 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); // changed in v.101
1251 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); // changed in v.101
1252 }
1253 else // new in v.101
1254 {
1255 temp_atem = 0.0; // new in v.101
1256 temp2_atem = 0.0; // new in v.101
1257 }
1258 1242
1259 sim_tissue_1min(); // Simulate compartiments for 1 minute. 1243 sim_tissue_1min(); // Simulate compartiments for 1 minute.
1260 update_deco_table(); // Add one minute stops. 1244 update_deco_table(); // Add one minute stops.
1261 } 1245 }
1262 1246
1271 // there is no need to break on more that 16 iterations 1255 // there is no need to break on more that 16 iterations
1272 // (or we are already in deep shit). 1256 // (or we are already in deep shit).
1273 // 1257 //
1274 void sim_ascent_to_first_stop(void) 1258 void sim_ascent_to_first_stop(void)
1275 { 1259 {
1276 update_startvalues(); 1260 update_startvalues();
1277 clear_deco_table(); 1261 clear_deco_table();
1278 1262
1279 temp_deco = pres_respiration; 1263 temp_deco = pres_respiration;
1280 lock_GF_depth_list = 1;
1281 1264
1282 // Loop until first top or surface is reached. 1265 // Loop until first top or surface is reached.
1283 for(;;) 1266 for(;;)
1284 { 1267 {
1285 temp_deco = temp_deco - 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. 1268 temp_deco = temp_deco - 1.0; // Ascent 1 min, at 10m/min. == 1bar/min.
1286 1269
1287 if ( char_I_deco_model == 1) 1270 if ( char_I_deco_model == 1)
1288 temp_limit = temp_pres_gtissue_limit_GF_low; 1271 temp_limit = sim_pres_gtissue_limit_GF_low;
1289 else 1272 else
1290 temp_limit = temp_pres_gtissue_limit; 1273 temp_limit = sim_pres_gtissue_limit;
1291 1274
1292 // Did we hit the first stop ? 1275 // Can we ascent directly to surface ?
1293 if( temp_deco <= temp_limit ) 1276 if( temp_deco <= temp_limit )
1294 break; 1277 break; //Yes: finished !
1295 1278
1296 // Or the surface ? 1279 // Next stop is surface ?
1297 if( temp_deco <= pres_surface ) 1280 if( temp_deco <= pres_surface )
1298 break; 1281 break; // Yes: finished too.
1299 1282
1283 // The ascent is not done (already), so re-defined locked_GF_step:
1300 lock_GF_depth_list = 0; 1284 lock_GF_depth_list = 0;
1285
1286 //---- Simulat gas switches, at half the ascent
1301 temp_deco += 0.5; // Check gas change 5 meter below new depth. 1287 temp_deco += 0.5; // Check gas change 5 meter below new depth.
1302 1288 check_gas_switch();
1303 //---- Simulat gas switches, at half the ascent 1289 temp_deco -= 0.5; // Back to new depth.
1304 calc_N2_ratio = N2_ratio;
1305 calc_He_ratio = He_ratio;
1306
1307 if (char_I_const_ppO2 == 0)
1308 {
1309 deco_diluent = temp_deco;
1310
1311 if(deco_gas_change1 && (temp_deco < deco_gas_change1))
1312 {
1313 calc_N2_ratio = deco_N2_ratio1;
1314 calc_He_ratio = deco_He_ratio1;
1315 }
1316 if(deco_gas_change2 && (temp_deco < deco_gas_change2))
1317 {
1318 calc_N2_ratio = deco_N2_ratio2;
1319 calc_He_ratio = deco_He_ratio2;
1320 }
1321 if(deco_gas_change3 && (temp_deco < deco_gas_change3))
1322 {
1323 calc_N2_ratio = deco_N2_ratio3;
1324 calc_He_ratio = deco_He_ratio3;
1325 }
1326 if(deco_gas_change4 && (temp_deco < deco_gas_change4))
1327 {
1328 calc_N2_ratio = deco_N2_ratio4;
1329 calc_He_ratio = deco_He_ratio4;
1330 }
1331 if(deco_gas_change5 && (temp_deco < deco_gas_change5))
1332 {
1333 calc_N2_ratio = deco_N2_ratio5;
1334 calc_He_ratio = deco_He_ratio5;
1335 }
1336 }
1337 else
1338 {
1339 if( temp_deco > deco_ppO2_change )
1340 deco_diluent = (temp_deco - const_ppO2)/(N2_ratio + He_ratio); // calculate at half of the ascent
1341 else
1342 deco_diluent = (temp_deco - deco_ppO2)/(N2_ratio + He_ratio); // calculate at half of the ascent
1343 if( deco_diluent > temp_deco )
1344 deco_diluent = temp_deco;
1345 }
1346
1347 temp_deco -= 0.5; // Back to new depth.
1348
1349 if (deco_diluent > 0.0627)
1350 {
1351 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627);
1352 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627);
1353 }
1354 else
1355 {
1356 temp_atem = 0.0;
1357 temp2_atem = 0.0;
1358 }
1359 1290
1360 // Then simulate with the new gas pressures...s 1291 // Then simulate with the new gas pressures...s
1361 sim_tissue_1min(); 1292 sim_tissue_1min();
1362 } 1293 }
1363 } 1294 }
1438 backup_sim_pres_tissue(); 1369 backup_sim_pres_tissue();
1439 sim_tissue_10min(); 1370 sim_tissue_10min();
1440 char_O_nullzeit += 10; 1371 char_O_nullzeit += 10;
1441 1372
1442 if (char_I_deco_model == 1) 1373 if (char_I_deco_model == 1)
1443 temp1 = GF_high * temp_pres_gtissue_diff + temp_pres_gtissue; 1374 temp1 = GF_high * sim_pres_gtissue_diff + sim_pres_gtissue;
1444 else 1375 else
1445 temp1 = temp_pres_gtissue_limit; 1376 temp1 = sim_pres_gtissue_limit;
1446 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately 1377 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately
1447 loop = 255; 1378 loop = 255;
1448 } 1379 }
1449 1380
1450 if (loop == 255) 1381 if (loop == 255)
1458 for(loop=1; loop <= 10; loop++) 1389 for(loop=1; loop <= 10; loop++)
1459 { 1390 {
1460 sim_tissue_1min(); 1391 sim_tissue_1min();
1461 char_O_nullzeit = char_O_nullzeit + 1; 1392 char_O_nullzeit = char_O_nullzeit + 1;
1462 if (char_I_deco_model == 1) 1393 if (char_I_deco_model == 1)
1463 temp1 = GF_high * temp_pres_gtissue_diff + temp_pres_gtissue; 1394 temp1 = GF_high * sim_pres_gtissue_diff + sim_pres_gtissue;
1464 else 1395 else
1465 temp1 = temp_pres_gtissue_limit; 1396 temp1 = sim_pres_gtissue_limit;
1466 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately 1397 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately
1467 loop = 255; 1398 loop = 255;
1468 } 1399 }
1469 if (loop == 255) 1400 if (loop == 255)
1470 char_O_nullzeit = char_O_nullzeit - 1; 1401 char_O_nullzeit = char_O_nullzeit - 1;
1521 // updated in v.102 1452 // updated in v.102
1522 // 1453 //
1523 void update_startvalues(void) 1454 void update_startvalues(void)
1524 { 1455 {
1525 overlay unsigned char x; 1456 overlay unsigned char x;
1526 1457
1527 temp_pres_gtissue_limit = pres_gtissue_limit; 1458 // Initialize data used to compute GF_low depth from current dive/simu
1528 temp_pres_gtissue = pres_tissue[char_O_gtissue_no] + pres_tissue[char_O_gtissue_no+16]; 1459 sim_gtissue_no = char_O_gtissue_no;
1529 temp_pres_gtissue_diff = temp_pres_gtissue_limit - temp_pres_gtissue; // negative number 1460 sim_pres_gtissue_limit = pres_gtissue_limit;
1530 temp_pres_gtissue_limit_GF_low = GF_low * temp_pres_gtissue_diff + temp_pres_gtissue; 1461 sim_pres_gtissue = pres_tissue[char_O_gtissue_no] + pres_tissue[char_O_gtissue_no+16];
1531 temp_pres_gtissue_limit_GF_low_below_surface = temp_pres_gtissue_limit_GF_low - pres_surface; 1462 sim_pres_gtissue_diff = sim_pres_gtissue_limit - sim_pres_gtissue; // negative number
1532 if (temp_pres_gtissue_limit_GF_low_below_surface < 0) 1463 sim_pres_gtissue_limit_GF_low = GF_low * sim_pres_gtissue_diff + sim_pres_gtissue;
1533 temp_pres_gtissue_limit_GF_low_below_surface = 0; 1464 sim_pres_gtissue_limit_GF_low_below_surface = sim_pres_gtissue_limit_GF_low - pres_surface;
1534 1465 if (sim_pres_gtissue_limit_GF_low_below_surface < 0)
1535 temp_gtissue_no = char_O_gtissue_no; 1466 sim_pres_gtissue_limit_GF_low_below_surface = 0;
1467
1536 for (x = 0;x<16;x++) 1468 for (x = 0;x<16;x++)
1537 { 1469 {
1538 sim_pres_tissue[x] = pres_tissue[x]; 1470 sim_pres_tissue[x] = pres_tissue[x];
1539 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; 1471 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x];
1540 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; 1472 sim_pres_tissue_limit[x] = pres_tissue_limit[x];
1551 // + Do it on sim_pres_tissue, instead of pres_tissue. 1483 // + Do it on sim_pres_tissue, instead of pres_tissue.
1552 // + Update GF_low state for GF decompression model. 1484 // + Update GF_low state for GF decompression model.
1553 // 1485 //
1554 static void sim_tissue(static unsigned char period) 1486 static void sim_tissue(static unsigned char period)
1555 { 1487 {
1556 temp_pres_gtissue_limit = 0.0; 1488 sim_pres_gtissue_limit = 0.0;
1557 temp_gtissue_no = 255; 1489 sim_gtissue_no = 255;
1558 1490
1559 for (ci=0;ci<16;ci++) 1491 for (ci=0;ci<16;ci++)
1560 { 1492 {
1561 read_buhlmann_coeffifients(period); // 1 or 10 minute(s) interval 1493 read_buhlmann_coeffifients(period); // 1 or 10 minute(s) interval
1562 1494
1576 var_N2_b = (var_N2_b * sim_pres_tissue[ci] + var_He_b * (sim_pres_tissue+16)[ci]) / temp_tissue; 1508 var_N2_b = (var_N2_b * sim_pres_tissue[ci] + var_He_b * (sim_pres_tissue+16)[ci]) / temp_tissue;
1577 sim_pres_tissue_limit[ci] = (temp_tissue - var_N2_a) * var_N2_b; 1509 sim_pres_tissue_limit[ci] = (temp_tissue - var_N2_a) * var_N2_b;
1578 1510
1579 if (sim_pres_tissue_limit[ci] < 0) 1511 if (sim_pres_tissue_limit[ci] < 0)
1580 sim_pres_tissue_limit[ci] = 0; 1512 sim_pres_tissue_limit[ci] = 0;
1581 if (sim_pres_tissue_limit[ci] > temp_pres_gtissue_limit) 1513 if (sim_pres_tissue_limit[ci] > sim_pres_gtissue_limit)
1582 { 1514 {
1583 temp_pres_gtissue = temp_tissue; 1515 sim_pres_gtissue = temp_tissue;
1584 temp_pres_gtissue_limit = sim_pres_tissue_limit[ci]; 1516 sim_pres_gtissue_limit = sim_pres_tissue_limit[ci];
1585 temp_gtissue_no = ci; 1517 sim_gtissue_no = ci;
1586 } 1518 }
1587 } // for 1519 } // for
1588 1520
1589 temp_pres_gtissue_diff = temp_pres_gtissue_limit - temp_pres_gtissue; 1521 // Update data used to compute GF_low depth:
1590 temp_pres_gtissue_limit_GF_low = GF_low * temp_pres_gtissue_diff + temp_pres_gtissue; 1522 sim_pres_gtissue_diff = sim_pres_gtissue_limit - sim_pres_gtissue;
1591 temp_pres_gtissue_limit_GF_low_below_surface = temp_pres_gtissue_limit_GF_low - pres_surface; 1523 sim_pres_gtissue_limit_GF_low = GF_low * sim_pres_gtissue_diff + sim_pres_gtissue;
1592 if (temp_pres_gtissue_limit_GF_low_below_surface < 0) 1524 sim_pres_gtissue_limit_GF_low_below_surface = sim_pres_gtissue_limit_GF_low - pres_surface;
1593 temp_pres_gtissue_limit_GF_low_below_surface = 0; 1525 if (sim_pres_gtissue_limit_GF_low_below_surface < 0)
1526 sim_pres_gtissue_limit_GF_low_below_surface = 0;
1594 } 1527 }
1595 1528
1596 ////////////////////////////////////////////////////////////////////////////// 1529 //////////////////////////////////////////////////////////////////////////////
1597 // sim_tissue_1min 1530 // sim_tissue_1min
1598 // 1531 //