Code

1// Copyright 2015 Bo Johansson. All rights reserved
2// Mail: bo(stop)johansson(at)lsn(stop)se
3
4"use strict;";
5
6var boj = boj || {};
7
8boj.PHS = ( function () {
9 var pdo = boj.par_data_object;
10
11 var air = {};
12 var body = {};
13 var cloth = {};
14 var core = {};
15 var heatex = {};
16 var limit = {};
17 var move = {};
18 var skin = {};
19 var sweat = {};
20
21 var sim_mod;
22 var sim_time;
23
24 function var_reset(){
25
26 air.v_air = NaN;
27 air.Tair = NaN;
28 air.Trad = NaN;
29 air.Pw_air = NaN;
30
31 body.accl = NaN;
32 body.Adu = NaN;
33 body.fAdu_rad_aux = NaN;
34 body.fAdu_rad = NaN;
35 body.drink = NaN;
36 body.height = NaN;
37 body.Met = NaN;
38 body.posture = NaN;
39 body.spHeat = NaN;
40 body.Tbm = NaN;
41 body.Tbm_0 = NaN;
42 body.weight = NaN;
43 body.work = NaN;
44
45 cloth.fAcl = NaN;
46 cloth.Ia_st = NaN;
47 cloth.CORcl = NaN;
48 cloth.CORia = NaN;
49 cloth.CORe = NaN;
50 cloth.CORtot = NaN;
51 cloth.Icl_dyn = NaN;
52 cloth.im_dyn = NaN;
53 cloth.Rtdyn = NaN;
54 cloth.fAcl_rad = NaN;
55 cloth.Fr = NaN;
56 cloth.fAref = NaN;
57 cloth.Icl_st = NaN;
58 cloth.im_st = NaN;
59 cloth.Tcl = NaN;
60 cloth.Icl = NaN;
61 cloth.Itot_dyn = NaN;
62 cloth.Itot_st = NaN;
63
64 core.dStoreq = NaN;
65 core.sk_cr_rel = NaN;
66 core.sk_cr_rel_0 = NaN;
67 core.Tcr = NaN;
68 core.Tcr_0 = NaN;
69 core.Tcr_1 = NaN;
70 core.Tcreq_rm_ss = NaN;
71 core.Tcreq_mr_0 = NaN;
72 core.Tcreq_mr = NaN;
73 core.Tcreq_mr_ConstTeq = NaN;
74 core.Trec_0 = NaN;
75 core.Trec = NaN;
76
77 heatex.Hcdyn = NaN;
78 heatex.Hr = NaN;
79 heatex.Conv = NaN;
80 heatex.Rad = NaN;
81 heatex.Eresp = NaN;
82 heatex.Cresp = NaN;
83 heatex.Tresp = NaN;
84 heatex.Z = NaN;
85
86 limit.rec_temp = NaN;
87 limit.sweat_max50 = NaN;
88 limit.sweat_max95 = NaN;
89 limit.water_loss_max50 = NaN;
90 limit.water_loss_max95 = NaN;
91
92 move.v_walk_in = NaN;
93 move.v_air_rel = NaN;
94 move.walk_dir = NaN;
95 move.walk_dir_in = NaN;
96 move.v_walk = NaN;
97
98 sim_mod = NaN;
99 sim_time = NaN;
100
101 skin.Pw_sk = NaN;
102 skin.w_max = NaN;
103 skin.w_req = NaN;
104 skin.w_pre = NaN;
105 skin.Tsk_0 = NaN;
106 skin.Tsk = NaN;
107 skin.ConstTsk = NaN;
108
109 sweat.Emax = NaN;
110 sweat.Epre = NaN;
111 sweat.Ereq = NaN;
112 sweat.SWmax = NaN;
113 sweat.SWpre = NaN;
114 sweat.SWreq = NaN;
115 sweat.SW = NaN;
116 sweat.SWg = NaN;
117 sweat.SWtot = NaN;
118 sweat.SWtotg = NaN;
119 sweat.Eeff_req = NaN;
120 sweat.ConstSW = NaN;
121 sweat.fSWmax_accl = NaN;
122 }
123
124 var par_sim_mod = false;
125
126 var par_spec_sim = [
127 [ 'accl', 'int', function(){ return body.accl; },
128 function(val){ body.accl = val === 0 ? 0 : 100;
129 par_sim_mod = true; },
130 { def_val : 100, min : 0, max : 100, unit : '%', symbol : 'accl',
131 descr : 'Acclimatised subject 0 or 100'}
132 ],
133 [ 'drink', 'int', function(){ return body.drink; },
134 function(val){ body.drink = val === 0 ? 0 : 1;
135 par_sim_mod = true; },
136 { def_val : 1, min : 0, max : 1, unit : '', symbol : 'drink',
137 descr : 'May drink freely, 0 or 1'}
138 ],
139 [ 'height', 'float', function(){ return body.height; },
140 function(val){ body.height = val; par_sim_mod = true; },
141 { def_val : 1.8, min : 1.5, max : 2.4, dec_nof : 1, unit : 'm', symbol : 'height',
142 descr : 'Body height'}
143 ],
144 [ 'mass', 'float', function(){ return body.weight; },
145 function(val){ body.weight = val; par_sim_mod = true; },
146 { def_val : 75, min : 0, max : 120, dec_nof : 1, unit : 'kg', symbol : 'mass',
147 descr : 'Body mass'}
148 ],
149 // sim_mod = 0 default,
150 // = 1 iso7933 ver. 1,
151 // = 2 iso7933 ver. 2,
152 // = 3 as 1 and modified core_temp_pred,
153 // = 4 as 2 and modified core_temp_pred
154 [ 'sim_mod', 'int', function(){ return sim_mod; },
155 function(val){ sim_mod = val; par_sim_mod = true; },
156 { def_val : 0, min : 0, max : 4, unit : '', symbol : 'sim_mod',
157 descr : 'Simulation model variant'}
158 ]
159 ];
160
161 var par_swarm_sim = pdo.new_par_swarm( 'phs_sim' ).
162 create_parameter( par_spec_sim );
163
164 var par_step_mod = false;
165
166 var par_spec_step = [
167 [ 'post', 'int', function(){ return body.posture; },
168 function(val){ body.posture = val; par_step_mod = true; },
169 { def_val : 2, min : 1, max : 3, unit : '', symbol : 'post',
170 descr : '1= sitting, 2= standing, 3= crouching'}
171 ],
172 [ 'Tair', 'float', function(){ return air.Tair; },
173 function(val){ air.Tair = val; par_step_mod = true; },
174 { def_val : 40, min : 15, max : 50, dec_nof : 1, unit : 'C', symbol : 'Tair',
175 descr : 'Air temperature'}
176 ],
177 [ 'Pw_air', 'float', function(){ return air.Pw_air; },
178 function(val){ air.Pw_air = val; par_step_mod = true; },
179 { def_val : 2.5, min : 0, max : 4.5, dec_nof : 1, unit : 'kPa', symbol : 'Pw_air',
180 descr : 'Partial water vapour pressure'}
181 ],
182 [ 'Trad', 'float', function(){ return air.Trad; },
183 function(val){ air.Trad = val; par_step_mod = true; },
184 { def_val : 40, min : 15, max : 110, dec_nof : 1, unit : 'C', symbol : 'Trad',
185 descr : 'Radiant temperature'}
186 ],
187 [ 'v_air', 'float', function(){ return air.v_air; },
188 function(val){air.v_air = val; par_step_mod = true; },
189 { def_val : 0.3, min : 0, max : 3.0, dec_nof : 1, unit : 'm/s', symbol : 'v_air',
190 descr : 'Air velocity'}
191 ],
192 [ 'Met', 'int', function(){ return body.Met; },
193 function(val){ body.Met = val; par_step_mod = true; },
194 { def_val : 150, min : 100, max : 400, unit : 'W/m2', symbol : 'Met',
195 descr : 'Metabolic energy production'}
196 ],
197 [ 'Icl', 'float', function(){ return cloth.Icl; },
198 function(val){ cloth.Icl = val; par_step_mod = true; },
199 { def_val : 0.5, min : 0.1 , max : 1.2 , dec_nof : 1, unit : 'clo', symbol : 'Icl',
200 descr : 'Cloth static thermal insulation'}
201 ],
202 [ 'im_st', 'float', function(){ return cloth.im_st; },
203 function(val){ cloth.im_st = val; par_step_mod = true; },
204 { def_val : 0.38, min : 0, max : 1.0, dec_nof : 2, unit : '', symbol : 'im_st',
205 descr : 'Static moisture permeability index'}
206 ],
207 [ 'fAref', 'float', function(){ return cloth.fAref; },
208 function(val){ cloth.fAref = val; par_step_mod = true; },
209 { def_val : 0.54, min : 0, max : 1.0, dec_nof : 2, unit : '', symbol : 'Ap',
210 descr : 'Fraction covered by reflective clothing'}
211 ],
212 [ 'Fr', 'float', function(){ return cloth.Fr; },
213 function(val){ cloth.Fr = val; par_step_mod = true; },
214 { def_val : 0.97, min : 0, max : 1.0, dec_nof : 2, unit : '', symbol : 'Fr',
215 descr : 'Emissivity reflective clothing'}
216 ],
217 [ 'walk_dir', 'int', function(){ return move.walk_dir_in; },
218 function(val){ move.walk_dir_in = val; par_step_mod = true; },
219 { def_val : NaN, min : 0, max : 360, unit : 'degree', symbol : 'theta_ww',
220 descr : 'Angel betwen wind and walking direction', may_be_null : true}
221 ],
222 [ 'v_walk', 'float', function(){ return move.v_walk_in; },
223 function(val){ move.v_walk_in = val; par_step_mod = true; },
224 { def_val : NaN, min : 0, max : 1.2, dec_nof : 1, unit : 'm/s', symbol : 'v_walk',
225 descr : 'Walking speed', may_be_null : true}
226 ],
227 [ 'work', 'int', function(){ return body.work; },
228 function(val){ body.work = val; par_step_mod = true; },
229 { def_val : 0, min : 0, max : 200, unit : 'W/m2', symbol : 'body_work',
230 descr : 'Mechanical power'}
231 ]
232 ];
233
234 var par_swarm_step = pdo.new_par_swarm( 'phs_step' ).
235 create_parameter( par_spec_step );
236
237 var branch_reg = {};
238 var flag = 0;
239
240 function branch( id ){
241 if ( branch_reg[ id ]){ branch_reg[ id ] ++; }
242 else { branch_reg[ id ] = 1; }
243 }
244
245 function branch_reset(){
246 var res = JSON.stringify( branch_reg );
247 branch_reg = {};
248 return res;
249 }
250
251 function calc_sim_const(){
252 if ( sim_mod === 0 ) { sim_mod = 1; }
253 body.Adu = 0.202 * Math.pow( body.weight, 0.425 ) *
254 Math.pow( body.height, 0.725);
255 body.spHeat = 57.83 * body.weight / body.Adu;
256 if ( body.drink === 1 ){
257 limit.sweat_max50 = 0.075 * body.weight * 1000;
258 limit.sweat_max95 = 0.05 * body.weight * 1000;
259 }
260 else {
261 limit.sweat_max50 = 0.03 * body.weight * 1000;
262 limit.sweat_max95 = 0.03 * body.weight * 1000;
263 }
264 if ( body.accl < 50 ) { skin.w_max = 0.85; }
265 else { skin.w_max = 1; }
266 core.Tcreq_mr_ConstTeq = Math.exp( -1 / 10 );
267
268 skin.ConstTsk = Math.exp( -1 / 3 );
269 sweat.ConstSW = Math.exp( -1 / 10 );
270 par_sim_mod = false;
271 calc_step_const();
272 }
273
274 function calc_step_const(){
275 var posture = body.posture;
276 if ( posture == 1 ) {body.fAdu_rad = 0.7; }
277 else if ( posture == 2 ) {body.fAdu_rad = 0.77; }
278 else if ( posture == 3 ) {body.fAdu_rad = 0.67; }
279 else {body.fAdu_rad = 0.7; }
280 body.fAdu_rad_aux = 5.67E-08 * body.fAdu_rad;
281 if ( sim_mod === 1 || sim_mod === 3 ) { // iso7933 ver. 1
282 sweat.SWmax = (body.Met - 32) * body.Adu;
283 if ( sweat.SWmax > 400 ) { sweat.SWmax = 400; }
284 if ( sweat.SWmax < 250 ) { sweat.SWmax = 250; }
285 }
286 else if ( sim_mod === 2 || sim_mod === 4 ) { // iso7933 modified
287 sweat.SWmax = 400;
288 }
289 else { alert( 'ERROR in calc_step_const ' + sim_mod ); }
290 if ( body.accl >= 50 ) { sweat.SWmax = sweat.SWmax * 1.25; }
291 core.Tcreq_rm_ss = 0.0036 * body.Met + 36.6;
292 cloth.Icl_st = cloth.Icl * 0.155;
293 cloth.fAcl = 1 + 0.3 * cloth.Icl;
294 cloth.Ia_st = 0.111;
295 cloth.Itot_st = cloth.Icl_st + cloth.Ia_st / cloth.fAcl;
296 if ( ! isNaN( move.v_walk_in ) ) {
297 move.v_walk = move.v_walk_in;
298 if ( ! isNaN( move.walk_dir_in ) ){
299 move.v_air_rel = Math.abs( air.v_air - move.v_walk *
300 Math.cos(3.14159 * move.walk_dir_in / 180));
301 }
302 else {
303 if ( air.v_air < move.v_walk ) {
304 move.v_air_rel = move.v_walk; }
305 else { move.v_air_rel = air.v_air; }
306 }
307 }
308 else {
309 move.v_walk = 0.0052 * (body.Met - 58);
310 if ( move.v_walk > 0.7) { move.v_walk = 0.7; }
311 move.v_air_rel = air.v_air;
312 }
313 heatex.Tresp =
314 28.56 + 0.115 * air.Tair + 0.641 * air.Pw_air;
315 heatex.Cresp =
316 0.001516 * body.Met * (heatex.Tresp - air.Tair);
317 heatex.Eresp = 0.00127 * body.Met *
318 (59.34 + 0.53 * air.Tair - 11.63 * air.Pw_air);
319 if ( move.v_air_rel > 1 ) {
320 heatex.Z = 8.7 * Math.pow( move.v_air_rel, 0.6 ); }
321 else {heatex.Z = 3.5 + 5.2 * move.v_air_rel; }
322 par_step_mod = false;
323 }
324
325 function reset(){
326 var_reset();
327 }
328
329 function sim_init(){
330 limit.rec_temp = NaN;
331 limit.water_loss_max50 = NaN;
332 limit.water_loss_max95 = NaN;
333 sweat.SWpre = 0;
334 sweat.SWtot = 0;
335 sweat.SWtotg = 0;
336 core.Trec = 36.8;
337 core.Tcr = 36.8;
338 skin.Tsk = 34.1;
339 //body.Tbm = 36.394922930774554;
340 //body.Tbm = 36.4;
341 body.Tbm = 36.39488;
342 core.Tcreq_mr = 36.8;
343 core.sk_cr_rel = 0.3;
344 cloth.Tcl = NaN;
345 sweat.Epre = NaN;
346 sweat.SW = NaN;
347 sweat.SWg = NaN;
348 sweat.SWmax = NaN;
349 sweat.SWreq = NaN;
350 sim_time = 0;
351
352 branch_reset();
353 calc_sim_const();
354 calc_step_const();
355 }
356
357 function step_core_temp_equi_mr(){
358 var Tcreqm = core.Tcreq_rm_ss;
359 var ConstTeq = core.Tcreq_mr_ConstTeq;
360 var val_0 = core.Tcreq_mr_0;
361 core.Tcreq_mr = val_0 * ConstTeq + Tcreqm * ( 1 - ConstTeq);
362 core.dStoreq = body.spHeat * (core.Tcreq_mr - val_0) * (1 - core.sk_cr_rel_0);
363 }
364
365 function skin_temp_equilibrium(){
366 var Tskeq_cl = 12.165 + 0.02017 * air.Tair + 0.04361 * air.Trad + 0.19354 * air.Pw_air -
367 0.25315 * air.v_air + 0.005346 * body.Met + 0.51274 * core.Trec;
368 var Tskeq_nu = 7.191 + 0.064 * air.Tair + 0.061 * air.Trad + 0.198 * air.Pw_air -
369 0.348 * air.v_air + 0.616 * core.Trec;
370 var I_cl = cloth.Icl;
371 if ( I_cl <= 0.2 ) { return Tskeq_nu; }
372 if ( I_cl >= 0.6 ) { return Tskeq_cl; }
373 var Tskeq = Tskeq_nu + 2.5 * ( Tskeq_cl - Tskeq_nu ) * (I_cl - 0.2);
374 return Tskeq;
375 }
376
377 function step_skin_temp(){
378 var Tskeq = skin_temp_equilibrium();
379 var ConstTsk = skin.ConstTsk;
380 skin.Tsk = skin.Tsk_0 * ConstTsk + Tskeq * ( 1 - ConstTsk);
381 skin.Pw_sk = 0.6105 * Math.exp( 17.27 * skin.Tsk / (skin.Tsk + 237.3));
382 }
383
384 function calc_dynamic_insulation(){
385 var Vaux = move.v_air_rel;
386 if ( move.v_air_rel > 3) { Vaux = 3; }
387 var Waux = move.v_walk;
388 if ( move.v_walk > 1.5 ) { Waux = 1.5; }
389 cloth.CORcl =
390 1.044 * Math.exp(( 0.066 * Vaux - 0.398 ) * Vaux + ( 0.094 * Waux - 0.378 ) * Waux);
391 if ( cloth.CORcl > 1 ) { cloth.CORcl = 1; }
392 cloth.CORia =
393 Math.exp(( 0.047 * move.v_air_rel - 0.472) * move.v_air_rel +
394 ( 0.117 * Waux - 0.342) * Waux);
395 if ( cloth.CORia > 1 ) { cloth.CORia = 1; }
396 cloth.CORtot = cloth.CORcl;
397 if ( cloth.Icl <= 0.6 ) {
398 cloth.CORtot = (( 0.6 - cloth.Icl) * cloth.CORia +
399 cloth.Icl * cloth.CORcl) / 0.6;
400 }
401 cloth.Itot_dyn =
402 cloth.Itot_st * cloth.CORtot;
403 var IAdyn = cloth.CORia * cloth.Ia_st;
404 cloth.Icl_dyn = cloth.Itot_dyn - IAdyn / cloth.fAcl;
405
406 cloth.CORe =
407 (2.6 * cloth.CORtot - 6.5) * cloth.CORtot + 4.9;
408 cloth.im_dyn =
409 cloth.im_st * cloth.CORe;
410 if ( cloth.im_dyn > 0.9 ) { cloth.im_dyn = 0.9; }
411 cloth.Rtdyn =
412 cloth.Itot_dyn / cloth.im_dyn / 16.7;
413 }
414
415 function dynamic_convection_coefficient(){
416 heatex.Hcdyn =
417 2.38 * Math.pow( Math.abs( skin.Tsk - air.Tair ), 0.25);
418 if ( heatex.Z > heatex.Hcdyn ) { heatex.Hcdyn = heatex.Z; }
419 cloth.fAcl_rad = (1 - cloth.fAref) * 0.97 +
420 cloth.fAref * cloth.Fr;
421 }
422
423 function clothing_temp(){
424 var Hcdyn = heatex.Hcdyn;
425 var Trad_K_pow4 = air.Trad + 273;
426 Trad_K_pow4 = Trad_K_pow4 * Trad_K_pow4;
427 Trad_K_pow4 = Trad_K_pow4 * Trad_K_pow4;
428 var Tcl1;
429 var loop = 20;
430
431 cloth.Tcl = air.Trad + 0.1;
432 while ( loop > 0 ) {
433 loop--;
434 var Tcl_K_pow4 = cloth.Tcl + 273;
435 Tcl_K_pow4 = Tcl_K_pow4 * Tcl_K_pow4;
436 Tcl_K_pow4 = Tcl_K_pow4 * Tcl_K_pow4;
437 heatex.Hr = cloth.fAcl_rad * body.fAdu_rad_aux *
438 ( Tcl_K_pow4 - Trad_K_pow4 ) / (cloth.Tcl - air.Trad);
439 Tcl1 =
440 ((cloth.fAcl * (Hcdyn * air.Tair + heatex.Hr * air.Trad) +
441 skin.Tsk / cloth.Icl_dyn)) /
442 (cloth.fAcl *(Hcdyn + heatex.Hr) + 1 / cloth.Icl_dyn);
443 if ( Math.abs(cloth.Tcl - Tcl1) > 0.001 ) {
444 cloth.Tcl = (cloth.Tcl + Tcl1) / 2;
445 }
446 else { return; }
447 }
448 alert( 'clothing_temp overun');
449 }
450
451 function calc_heat_exchange(){
452 heatex.Conv = cloth.fAcl * heatex.Hcdyn * (cloth.Tcl - air.Tair);
453 heatex.Rad = cloth.fAcl * heatex.Hr * (cloth.Tcl - air.Trad);
454 sweat.Ereq = body.Met - core.dStoreq - body.work - heatex.Cresp -
455 heatex.Eresp - heatex.Conv - heatex.Rad;
456 }
457
458 function sweat_rate(){
459 sweat.Emax = (skin.Pw_sk - air.Pw_air) / cloth.Rtdyn;
460 if ( sweat.Ereq <= 0 ) {
461 sweat.Ereq = 0;
462 sweat.SWreq = 0;
463 //trace branch( 'sr1');
464 }
465 else if ( sweat.Emax <= 0 ) {
466 sweat.Emax = 0;
467 sweat.SWreq = sweat.SWmax;
468 //trace branch( 'sr2');
469 }
470 else{
471 skin.w_req = sweat.Ereq / sweat.Emax;
472 if ( skin.w_req >= 1.7 ) {
473 skin.w_req = 1.7;
474 sweat.SWreq = sweat.SWmax;
475 //trace branch( 'sr3.1');
476 }
477 else
478 {
479 if ( skin.w_req > 1 ) {
480 sweat.Eeff_req = ( 2 - skin.w_req ) * ( 2 - skin.w_req ) / 2;
481 //trace branch( 'sr3.2.1');
482 }
483 else
484 {
485 sweat.Eeff_req = 1 - ( skin.w_req * skin.w_req / 2 );
486 //trace branch( 'sr3.2.2');
487 }
488 sweat.SWreq = sweat.Ereq / sweat.Eeff_req;
489 if ( sweat.SWreq > sweat.SWmax ) {
490 sweat.SWreq = sweat.SWmax;
491 //trace branch( 'sr3.2.3');
492 }
493 }
494 }
495 sweat.SWpre = sweat.SWpre * sweat.ConstSW + sweat.SWreq * (1 - sweat.ConstSW);
496 if ( sweat.SWpre <= 0 ) {
497 sweat.Epre = 0;
498 sweat.SWpre = 0;
499 //trace branch( 'sp1');
500 }
501 else {
502 var k = sweat.Emax / sweat.SWpre;
503 skin.w_pre = 1;
504 if ( k >= 0.5 ) {
505 skin.w_pre= -k + Math.sqrt( k * k + 2 );
506 //trace branch( 'sp2.1');
507 }
508 if ( skin.w_pre > skin.w_max ) {
509 skin.w_pre = skin.w_max;
510 //trace branch( 'sp2.2')
511 }
512 sweat.Epre = skin.w_pre * sweat.Emax;
513 }
514 //trace if ( sim_time <=5 || (sim_time % 40) === 0 ){
515 //trace console.log( JSON.stringify(
516 //trace {time: sim_time, Ereq: sweat.Ereq, Eeff_req: sweat.Eeff_req,
517 //trace SWreq: sweat.SWreq, SWpre: sweat.SWpre, Epre: sweat.Epre }
518 //trace ) + branch_reset() )
519 //trace }
520 }
521
522 function core_temp_pred_std(){
523 var dStorage = sweat.Ereq - sweat.Epre + core.dStoreq;
524 core.Tcr_1 = core.Tcr_0;
525
526 var loop = 25;
527 while ( loop > 0 ) {
528 loop--;
529 core.sk_cr_rel = 0.3 - 0.09 * (core.Tcr_1 - 36.8);
530 if ( core.sk_cr_rel > 0.3 ) { core.sk_cr_rel = 0.3; }
531 if ( core.sk_cr_rel < 0.1 ) { core.sk_cr_rel = 0.1; }
532 core.Tcr = dStorage / body.spHeat + skin.Tsk_0 * core.sk_cr_rel_0 / 2 -
533 skin.Tsk * core.sk_cr_rel / 2;
534 core.Tcr = (core.Tcr + core.Tcr_0 * (1 - core.sk_cr_rel_0 / 2)) /
535 (1 - core.sk_cr_rel / 2);
536 if ( Math.abs(core.Tcr - core.Tcr_1 ) > 0.001 ) {
537 core.Tcr_1 = (core.Tcr_1 + core.Tcr) / 2;
538 }
539 else{
540 return;
541 }
542 }
543 alert( 'core_temp_pred_std overun');
544 }
545
546 // part of body having Tcr as mean temperature
547 function core_temp_pred_sk_cr_rel( Tcr ){
548 if ( Tcr < 36.8 ) { return 0.3; }
549 else if (Tcr > 39.0) { return 0.1; }
550 else { return 0.3 - 0.091 * (Tcr - 36.8); }
551 }
552
553 function core_temp_pred_Tcr ( Tbm, Tcr_0, Tsk ){
554 var Tcr = Tbm;
555 var loop = 25;
556 while ( loop > 0 ) {
557 loop--;
558 var sk_cr_rel_0_5 = core_temp_pred_sk_cr_rel( Tcr ) * 0.5;
559 //Tbm_1 = Tcr * ( 1 - sk_cr_rel ) + (Tsk + Tcr)* 0.5 * sk_cr_rel;
560 //Tbm_1 = Tcr - Tcr * sk_cr_rel + Tsk * sk_cr_rel * 0.5 + Tcr * sk_cr_rel * 0.5;
561 //Tbm_1 = Tcr( 1 - sk_cr_rel + sk_cr_rel * 0.5 ) + Tsk * sk_cr_rel * 0.5;
562 //Tbm_1 = Tcr( 1 - sk_cr_rel * 0.5 ) + Tsk * sk_cr_rel * 0.5;
563 Tbm_1 = Tcr * ( 1 - sk_cr_rel_0_5 ) + Tsk * sk_cr_rel_0_5;
564 var diff = Tbm_1 - Tbm;
565 if ( Math.abs( diff ) > 0.001 ) {
566 Tcr = Tcr - diff * 0.5;
567 }
568 else {
569 return Tcr;
570 }
571 }
572 console.error( 'core_temp_pred overun' + sim_time + Tcr );
573 return Tcr;
574 }
575
576 function core_temp_pred(){
577 var dStorage = sweat.Ereq - sweat.Epre + core.dStoreq;
578 var dTempStorage = dStorage / body.spHeat;
579 body.Tbm = body.Tbm_0 + dTempStorage;
580 var rv = core_temp_pred_Tcr ( body.Tbm, core.Tcr_0, skin.Tsk );
581 core.Tcr = rv;
582 }
583
584 function rect_temp_pred(){
585 var Tre0 = core.Trec_0;
586 core.Trec = Tre0 + (2 * core.Tcr - 1.962 * Tre0 - 1.31) / 9;
587 if ( ! limit.rec_temp && core.Trec >= 38 ) {
588 limit.rec_temp = sim_time; }
589 }
590
591 function water_loss(){
592 sweat.SW = sweat.SWpre + heatex.Eresp;
593 sweat.SWtot = sweat.SWtot + sweat.SW;
594 var k_to_g = 2.67 * body.Adu / 1.8 / 60;
595 sweat.SWg = sweat.SW * k_to_g;
596 sweat.SWtotg = sweat.SWtot * k_to_g;
597 if (! limit.water_loss_max50 && sweat.SWtotg >= limit.sweat_max50 ) {
598 limit.water_loss_max50 = sim_time;
599 }
600 if ( ! limit.water_loss_max95 && sweat.SWtotg >= limit.sweat_max95 ) {
601 limit.water_loss_max95 = sim_time;
602 }
603 }
604
605 function state(){
606 return {
607 time : sim_time,
608 Tcreq : core.Tcreq_mr,
609 Tsk : skin.Tsk,
610 SWg : sweat.SWg,
611 SWtotg : sweat.SWtotg,
612 Tcr : core.Tcr,
613 Tre : core.Trec,
614 Tcl : cloth.Tcl,
615 SW : sweat.SW,
616 Epre : sweat.Epre,
617 SWreq : sweat.SWreq,
618 SWmax : sweat.SWmax
619 };
620 }
621
622 function time_step(){
623 if ( par_sim_mod ) {
624 alert( 'Simulation parameter changed between steps' );
625 }
626 if ( par_step_mod ){
627 calc_step_const();
628 }
629 sim_time++;
630 body.Tbm_0 = body.Tbm;
631 core.Trec_0 = core.Trec;
632 core.Tcr_0 = core.Tcr;
633 core.Tcreq_mr_0 = core.Tcreq_mr;
634 core.sk_cr_rel_0 = core.sk_cr_rel;
635 skin.Tsk_0 = skin.Tsk;
636
637 step_core_temp_equi_mr();
638 step_skin_temp();
639 calc_dynamic_insulation();
640 dynamic_convection_coefficient();
641 clothing_temp();
642 calc_heat_exchange();
643 sweat_rate();
644 if ( sim_mod === 1 || sim_mod === 2 ){ // std core_temp_pred
645 core_temp_pred_std();
646 }
647 else { // modified core_temp_pred
648 core_temp_pred();
649 }
650 rect_temp_pred();
651 water_loss();
652
653 return state();
654 }
655
656 function current_result(){
657 return {
658 time : sim_time,
659 Tre : core.Trec,
660 SWtotg : sweat.SWtotg,
661 D_Tre : limit.rec_temp,
662 Dwl50 : limit.water_loss_max50,
663 Dwl95 : limit.water_loss_max95
664 };
665 }
666
667 function sample_get(){
668 var phs_data = {
669 air : air,
670 body : body,
671 cloth : cloth,
672 core : core,
673 heatex : heatex,
674 limit : limit,
675 move : move,
676 skin : skin,
677 sweat : sweat
678 };
679 var vid = [
680 'core:Tcreq_rm_ss', 'core:Tcreq_mr', 'core:dStoreq',
681 'skin:Tsk', 'skin:Pw_sk', 'move:v_air_rel',
682 'cloth:CORcl', 'cloth:CORia', 'cloth:CORtot', 'cloth:Itot_dyn',
683 'cloth:Icl_dyn', 'cloth:CORe', 'cloth:Rtdyn',
684 'heatex:Hcdyn', 'cloth:fAcl_rad', 'cloth:Tcl', 'heatex:Hr',
685 'heatex:Conv', 'heatex:Rad', 'sweat:Ereq', 'sweat:Emax',
686 'skin:w_req', 'sweat:SWpre', 'skin:w_pre', 'sweat:Epre',
687 'core:sk_cr_rel', 'core:Tcr', 'core:Trec',
688 'sweat:SWtot', 'sweat:SWtotg'
689 ];
690
691 var res = {
692 sim_time : sim_time,
693 sim_mod : sim_mod
694 };
695 var idp;
696 var tag;
697 var val;
698
699 vid.map( function(ai) {
700 idp = ai.split( ':' );
701 tag = idp.join( '_' );
702 var val = phs_data;
703 idp.map( function(id){val = val [ id ]; });
704 res[ tag ] = val;
705 } );
706
707 return res;
708 }
709
710 // Reveal public pointers to
711 // private functions and properties
712 return{
713 par_spec_sim : par_spec_sim,
714 par_spec_step : par_spec_step,
715 par_swarm_sim : par_swarm_sim,
716 par_swarm_step : par_swarm_step,
717 reset : reset,
718 sim_init : sim_init,
719 state : state,
720 time_step : time_step,
721 current_result : current_result,
722 sample_get : sample_get
723 };

Index

.161, 234
ConstTeq359, 361, 361
(ConstTeq) time constant, core temperature as a function of the metabolic rate
ConstTsk379, 380, 380
(ConstTsk) skin temperature; time constant; 3 minutes
Hcdyn424, 440, 442
(<lv> )
IAdyn403, 404
(<lv> )
I_cl370, 371, 372, 373
(I_cl) <lv>
JSON.stringify246
Math.abs299, 417, 443, 536, 565
(<func>ABS )
Math.cos300
(<func>COS )
Math.exp266, 268, 269, 381, 390, 393
(<func>EXP )
Math.pow253, 254, 320, 417
(<func>^ )
Math.sqrt505
(<func>SQR )
Tbm553, 554, 564
Tbm_1563, 564
Tcl1428, 439, 443, 444
(<lv> )
Tcl_K_pow4434, 435, 435, 435, 436, 436, 436, 438
Tcr547, 548, 549, 550, 554, 558, 563, 566, 566, 569, 572, 573
Tcr_0553
Tcreqm358, 361
(<lv> )
Trad_K_pow4425, 426, 426, 426, 427, 427, 427, 438
Tre0585, 586, 586
(<lv> )
Tsk553, 563
Tskeq373, 374, 378, 380
(<lv> )
Tskeq_cl366, 372, 373
(<lv> )
Tskeq_nu368, 371, 373, 373
(<lv> )
Vaux385, 386, 390, 390
(<lv> )
Waux387, 388, 390, 390, 394, 394
(<lv> )
ai699
(<lv> )
ai.split700
(() )
air11, 669
({} )
air.Pw_air29, 177, 178, 314, 318, 366, 368, 459
air.Tair27, 172, 173, 314, 316, 318, 366, 368, 417, 440, 452
(Ta) air temperature [C] 15-50
air.Trad28, 182, 183, 366, 368, 425, 431, 438, 440, 453
(Tr) mean radiant temperature [C] 15-110
air.v_air26, 187, 188, 299, 303, 305, 311, 367, 369
(Va) air velocity [m/s] 0-3
alert289, 448, 543, 624
(() )
body12, 670
({} )
body.Adu32, 253, 255, 282, 594
(Adu) DuBois body surface area [m2]
body.Met37, 192, 193, 282, 291, 309, 316, 317, 367, 454
(Met) metabolic rate [W\m2]
body.Tbm40, 341, 579, 580, 630
body.Tbm_041, 579, 630
body.accl31, 127, 128, 264, 290
(accl) acclimatised subject []
body.drink35, 133, 134, 256
(DRINK) ==1 can drink freely
body.fAdu_rad34, 276, 277, 278, 279, 280
(fAdu_rad) effective radiating area of the body []
body.fAdu_rad_aux33, 280, 437
(auxR) = 5.67E-08 * Ardu
body.height36, 139, 140, 254
(height) body height [m]
body.posture38, 167, 168, 275
(posture) == 1 sitting, == 2 standing, == 3 crouching
body.spHeat39, 255, 362, 532, 578
(spHeat)
body.weight42, 144, 145, 253, 255, 257, 258, 261, 262
(weight) body weight [kg]
body.work43, 227, 228, 454
(Work) mechanical power [W\m2]
boj6, 6
({} )
boj.PHS8
({} )
boj.par_data_object9
branch240
branch_reg237, 241, 241, 242, 246, 247
branch_reset245, 352
calc_dynamic_insulation384, 639
(() )
calc_heat_exchange451, 642
(() )
calc_sim_const251, 353
(() )
calc_step_const271, 274, 354, 627
(() )
cloth13, 671
({} )
cloth.CORcl47, 389, 391, 391, 396, 399
(CORcl) correction Icl []
cloth.CORe49, 406, 409
(CORe) correction dynamic permeability index []
cloth.CORia48, 392, 395, 395, 398, 403
(CORia) correction Ia_st []
cloth.CORtot50, 396, 398, 402, 407, 407
(CORtot) correction dynamic clothing insulation []
cloth.Fr55, 212, 213, 420
(FclR) reduction factor radiation heat exchange clothing
cloth.Ia_st46, 294, 295, 403
(Ia_st) static boundary layer thermal insulation in quiet air [?]
cloth.Icl60, 197, 198, 292, 293, 370, 397, 398, 399
(Icl) static clothing insulation [?]
cloth.Icl_dyn51, 404, 441, 442
(Icl_dyn) dynamic clothing insulation [?]
cloth.Icl_st57, 292, 295
(Icl_st) static clothing insulation
cloth.Itot_dyn61, 401, 404, 412
(Itotdyn) total dynamic insulation [m2K/W]
cloth.Itot_st62, 295, 402
(Itotst) total static insulation [m2K/W]
cloth.Rtdyn53, 411, 459
(Rtdyn) dynamic evaporative resistance [?]
cloth.Tcl59, 344, 431, 434, 438, 443, 444, 444, 452, 453, 614
(Tcl) mean temperature of the clothing [C]
cloth.fAcl45, 293, 295, 404, 440, 442, 452, 453
(fAcl) clothing area factor []
cloth.fAcl_rad54, 419, 437
(fAcl_rad) reflective clothing area factor []
cloth.fAref56, 207, 208, 419, 420
(Ap) fraction covered by reflective clothing []
cloth.im_dyn52, 408, 410, 410, 412
(im_dyn) dynamic moisture permeability index []
cloth.im_st58, 202, 203, 409
(im_st) static moisture permeability index []
clothing_temp423, 641
(() )
console.error572
(() )
core14, 672
({} )
core.Tcr67, 337, 532, 534, 534, 536, 537, 581, 586, 612, 632
(Tcr) body core temperature [C]
core.Tcr_068, 524, 534, 580, 632
(Tcr0) body core temperature SoI [C]
core.Tcr_169, 524, 529, 536, 537, 537
(<lv>Tcr1) body core temperature [C]
core.Tcreq_mr72, 342, 361, 362, 608, 633
(Tcreq) core equilibrium temperature at this minute [C]
core.Tcreq_mr_071, 360, 633
(core.Tcreq0) core equilibrium temperature previous minute [C]
core.Tcreq_mr_ConstTeq73, 266, 359
(ConstTeq) time constant Tcreq [/minute]
core.Tcreq_rm_ss70, 291, 358
(Tcreqm) equilibrium core temperature associated to the metabolic rate [C]
core.Trec75, 336, 367, 369, 586, 587, 613, 631, 659
(Trec) rectal temperature this minute [C]
core.Trec_074, 585, 631
(Trec0) rectal temperature previous minute [C]
core.dStoreq64, 362, 454, 523, 577
(dStoreq) heat storage, core temperature increase during this minute [?]
core.sk_cr_rel65, 343, 529, 530, 530, 531, 531, 533, 535, 634
(TskTcrwg) skin - core weighting this minute []
core.sk_cr_rel_066, 362, 532, 534, 634
(TskTcrwg) skin - core weighting previous minute []
core_temp_pred576, 648
(() )
core_temp_pred_Tcr553, 580
core_temp_pred_sk_cr_rel547, 558
core_temp_pred_std522, 645
(() )
create_parameter162, 235
current_result656, 721
dStorage523, 532, 577, 578
(<lv> )
dTempStorage578, 579
(<lv> )
diff564, 565, 566
dynamic_convection_coefficient415, 640
(() )
flag238
heatex15, 673
({} )
heatex.Conv79, 452, 455
(heatex.Conv )
heatex.Cresp82, 315, 454
(heatex.Cresp )
heatex.Eresp81, 317, 455, 592
(heatex.Eresp )
heatex.Hcdyn77, 416, 418, 418, 424, 452
(heatex.Hcdyn )
heatex.Hr78, 437, 440, 442, 453
(heatex.Hr )
heatex.Rad80, 453, 455
(heatex.Rad )
heatex.Tresp83, 313, 316
(heatex.Tresp )
heatex.Z84, 320, 321, 418, 418
(heatex.Z )
id240, 241, 241, 242, 703, 703
(<lv> )
idp695, 700
(<lv> )
idp.join701
(() )
idp.map703
(() )
k502, 504, 505, 505, 505
(<lv> )
k_to_g594, 595, 596
(<lv> )
limit16, 674
({} )
limit.rec_temp86, 330, 587, 588, 661
(limit.rec_temp )
limit.sweat_max5087, 257, 261, 597
(limit.sweat_max50 )
limit.sweat_max9588, 258, 262, 600
(limit.sweat_max95 )
limit.water_loss_max5089, 331, 597, 598, 662
(limit.water_loss_max50 )
limit.water_loss_max9590, 332, 600, 601, 663
(limit.water_loss_max95 )
loop429, 432, 433, 526, 527, 528, 555, 556, 557
(<lv> )
move17, 675
({} )
move.v_air_rel93, 299, 304, 305, 311, 319, 320, 321, 385, 386, 393, 393
(move.v_air_rel )
move.v_walk96, 297, 299, 303, 304, 309, 310, 310, 387, 388
(move.v_walk )
move.v_walk_in92, 222, 223, 296, 297
(move.v_walk_in )
move.walk_dir94
(move.walk_dir )
move.walk_dir_in95, 217, 218, 298, 300
(move.walk_dir_in )
par_sim_mod124, 129, 135, 140, 145, 155, 270, 623
par_spec_sim126, 162, 713
(<lv> )
par_spec_step166, 235, 714
(<lv> )
par_step_mod164, 168, 173, 178, 183, 188, 193, 198, 203, 208, 213, 218, 223, 228, 322, 626
par_swarm_sim161, 715
par_swarm_step234, 716
pdo9
pdo.new_par_swarm161, 234
phs_data668, 702
({} )
posture275, 276, 277, 278
(<lv> )
rect_temp_pred584, 650
(() )
res246, 248, 691, 704, 707
(<lv> )
reset325, 717
(() )
rv580, 581
sample_get667, 722
(() )
sim_init329, 718
(() )
sim_mod21, 98, 154, 155, 252, 252, 281, 281, 286, 286, 289, 644, 644, 693
sim_time22, 99, 350, 572, 588, 598, 601, 607, 629, 658, 692
(() )
sk_cr_rel_0_5558, 563, 563
skin18, 676
({} )
skin.ConstTsk107, 268, 379
(skin.ConstTsk )
skin.Pw_sk101, 381, 459
skin.Tsk106, 338, 380, 381, 381, 417, 441, 533, 580, 609, 635
(skin.Tsk )
skin.Tsk_0105, 380, 532, 635
(skin.Tsk_0 )
skin.w_max102, 264, 265, 508, 509
(skin.w_max )
skin.w_pre104, 503, 505, 508, 509, 512
(skin.w_pre )
skin.w_req103, 471, 472, 473, 479, 480, 480, 485, 485
(skin.w_req )
skin_temp_equilibrium365, 378
(() )
state605, 653, 719
step_core_temp_equi_mr357, 637
(() )
step_skin_temp377, 638
(() )
sweat19, 677
({} )
sweat.ConstSW120, 269, 495, 495
(ConstSW) time constant sweat rate []
sweat.Eeff_req119, 480, 485, 488
(Eeff_req) required evaporation efficiency []
sweat.Emax109, 459, 465, 466, 471, 502, 512
(Emax) maximal evaporation rate [W/m2]
sweat.Epre110, 345, 497, 512, 523, 577, 616
(Epre) predicted evaporation rate [W/m2]
sweat.Ereq111, 454, 460, 461, 471, 488, 523, 577
(Ereq) required evaporation rate [W/m2]
sweat.SW115, 346, 592, 593, 595, 615
(SW) sweat rate [g]
sweat.SWg116, 347, 595, 610
(SWg) sweat rate [W/m2]
sweat.SWmax112, 282, 283, 283, 284, 284, 287, 290, 290, 348, 467, 474, 489, 490, 618
(SWmax) maximum sweat rate as result of the metabolic rate [W/m2]
sweat.SWpre113, 333, 495, 495, 496, 498, 502, 592
(SWpre) predicted sweat rate [W/m2]
sweat.SWreq114, 349, 462, 467, 474, 488, 489, 490, 495, 617
(SWreq) required sweat rate [W/m2]
sweat.SWtot117, 334, 593, 593, 596
(SWtot) total water loss rate during the minutes [W/m2]
sweat.SWtotg118, 335, 596, 597, 600, 611, 660
(SWtotg) total water loss [g]
sweat.fSWmax_accl121
(fSWmax_accl) correction factor to SWmax depending on accl []
sweat_rate458, 643
tag696, 701, 704
(<lv> )
time_step622, 720
(() )
val128, 128, 134, 134, 140, 140, 145, 145, 155, 155, 168, 168, 173, 173, 178, 178, 183, 183, 188, 188, 193, 193, 198, 198, 203, 203, 208, 208, 213, 213, 218, 218, 223, 223, 228, 228, 697, 702, 703, 703, 704
(<lv> )
val_0360, 361, 362
(<lv> )
var_reset24, 326
vid679
(<lv> )
vid.map699
(() )
water_loss591, 651
(() )