simclimat-lib
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0.
832 lines (816 loc) • 92.6 kB
JavaScript
function add(num1, num2) {
return num1 + num2;
}
class CLogger {
static log(message, logLevel = 'info') {
if (!this.debug) {
return;
}
switch (logLevel) {
case 'debug': {
console.info(message);
break;
}
case 'info': {
console.log(message);
break;
}
case 'warning': {
console.log('WARNING : ' + message);
break;
}
case 'error': {
console.error('ERROR : ' + message);
break;
}
default: {
console.log(message);
break;
}
}
} // eo log method
static setDebug(debug) {
this.debug = debug;
}
}
CLogger.debug = false;
/**
* This class define physics constants and calculated physics constants.
*
* Instanciation example :
*
* ```typescript
* const instance = new CPhysicsConstants();
* ```
*
* @remarks
* This method is part of the {@link core-library#Statistics | Statistics subsystem}.
*
* @author Alain Deseine
*
* @copyright CEI Alain Deseine 1992-2019
*
* @beta
*/
class CPhysicsConstants {
// si 1: calcul Euler explicite
// si 2: calcul par decroissance vers équilibre
/**
* Constructor.
*
* The constructor of this class calculate calculated physics constants.
*
* @remarks
* This method is part of the {@link core-library#Statistics | Statistics subsystem}.
*
* @beta
*/
constructor() {
// Set calculated physics constants
CLogger.log('physics-constants: appel constructor');
this.t_res_coo_actuel = 280 / 0.083 / (CPhysicsConstants.concentration_coo_2007 / CPhysicsConstants.coo_Gt_2007); // Modification mars 2022
this.t_res_coo_90 = this.t_res_coo_actuel * 0.9;
this.t_res_coo_critique = this.t_res_coo_90 + (90 - CPhysicsConstants.niveau_calotte_critique_coo) * -(this.t_res_coo_90 - this.t_res_coo_actuel) / (90 - CPhysicsConstants.niveau_calottes_1750);
this.deltaT_last_century = CPhysicsConstants.temperature_actuelle - CPhysicsConstants.temperature_1750;
//this.temperature_1900 = CPhysicsConstants.temperature_actuelle - CPhysicsConstants.deltaT_last_century; // en °C ; necessaire dans modele_reset
this.G0 = CPhysicsConstants.puissance_recue_zero * (1 - CPhysicsConstants.albedo_1750) / CPhysicsConstants.sigma / Math.exp(4 * Math.log(CPhysicsConstants.Tkelvin + CPhysicsConstants.temperature_1750)); //0.584;
// commenté le 19 avril 2024 par Camille car inutile
/*
this.T_ressentie_actuelle = ( 1. / ( CPhysicsConstants.p0 + CPhysicsConstants.p1 + CPhysicsConstants.p2 + CPhysicsConstants.p3 ) ) * ( CPhysicsConstants.p0 * CPhysicsConstants.temperature_actuelle
+ CPhysicsConstants.p1 * CPhysicsConstants.temperature_actuelle - CPhysicsConstants.deltaT_last_century / 100 * CPhysicsConstants.deltat1
+ CPhysicsConstants.p2 * CPhysicsConstants.temperature_actuelle - CPhysicsConstants.deltaT_last_century / 100 * CPhysicsConstants.deltat2
+ CPhysicsConstants.p3 * CPhysicsConstants.temperature_actuelle - CPhysicsConstants.deltaT_last_century / 100 * CPhysicsConstants.deltat3 );
*/
this.a_calottes = (CPhysicsConstants.niveau_calottes_1750 - CPhysicsConstants.niveau_calottes_LGM_noinsol) / (CPhysicsConstants.temperature_1750 - CPhysicsConstants.temperature_LGM) * 0.8; // on suppose qu'une partie de la variation du niveau de calotte est lié à l'effet de la température (ici 40%), et l'autre est liée à l'effet de la variation d'insolation.
this.b_calottes = CPhysicsConstants.niveau_calottes_1750 - this.a_calottes * CPhysicsConstants.temperature_1750;
this.niveau_calottes_actuel = CPhysicsConstants.niveau_calottes_1750 + (this.a_calottes * CPhysicsConstants.temperature_actuelle + this.b_calottes - CPhysicsConstants.niveau_calottes_1750) * (1. - Math.exp(-100. / CPhysicsConstants.tau_niveau_calottes_deglacement));
CLogger.log('physics-constants: niveau_calottes_actuel= ' + this.niveau_calottes_actuel);
//CLogger.log( 'niveau_calottes_1750,temperature_actuelle,niveau_calottes_1750=' + CPhysicsConstants.niveau_calottes_1750 + CPhysicsConstants.temperature_actuelle + CPhysicsConstants.niveau_calottes_1750);
//CLogger.log ('a_calottes,b_calottes,tau_niveau_calottes_deglacement=' + this.a_calottes + this.b_calottes + CPhysicsConstants.tau_niveau_calottes_deglacement);
// modif CR: 31 oct 2019: Tressentie_act doit correspondre au calcul dans calcul_niveau_mer
// this.Tressentie_act = CPhysicsConstants.temperature_actuelle - 0.7; // orig -0.75
this.pond_memoire_mer = Math.exp(-CPhysicsConstants.tmemoire_niveau_mer / CPhysicsConstants.tau_niveau_mer);
CLogger.log('physics-constants: pond_memoire_mer= ' + this.pond_memoire_mer);
CLogger.log('pond_memoire_mer=' + this.pond_memoire_mer);
CLogger.log('temperature_actuelle=' + CPhysicsConstants.temperature_actuelle);
CLogger.log('deltaT_last_century=' + this.deltaT_last_century);
this.Tressentie_act = CPhysicsConstants.temperature_actuelle - this.pond_memoire_mer * this.deltaT_last_century; // -0.64
this.dilatation_1750 = CPhysicsConstants.dilat * CPhysicsConstants.coef_dilat * (CPhysicsConstants.temperature_1750 - this.Tressentie_act);
CLogger.log('dilatation_1750=' + this.dilatation_1750);
CLogger.log('dilat=' + CPhysicsConstants.dilat);
CLogger.log('coef_dilat=' + CPhysicsConstants.coef_dilat);
CLogger.log('temperature_1750=' + CPhysicsConstants.temperature_1750);
CLogger.log('Tressentie_act=' + this.Tressentie_act);
// Commenté par Camille le 19 avril 2024 car c'est devenu inutile
/*
this.optim1 = ( 1 + this.dilatation_1750 ) * ( 1
- CPhysicsConstants.fphig2 * Math.pow( CPhysicsConstants.niveau_calottes_1750 - CPhysicsConstants.niveau_calottes_max, 2 )
- CPhysicsConstants.fphig3 * Math.pow( CPhysicsConstants.niveau_calottes_1750 - CPhysicsConstants.niveau_calottes_max, 3 ) )
- ( 1 - CPhysicsConstants.fphig2 * Math.pow( this.niveau_calottes_actuel - CPhysicsConstants.niveau_calottes_max, 2 )
- CPhysicsConstants.fphig3 * Math.pow( this.niveau_calottes_actuel - CPhysicsConstants.niveau_calottes_max, 3 ) );
this.optim2 = ( this.niveau_calottes_actuel - CPhysicsConstants.niveau_calottes_max ) - ( 1 + this.dilatation_1750 ) * ( CPhysicsConstants.niveau_calottes_1750 - CPhysicsConstants.niveau_calottes_max );
this.fphig1 = (CPhysicsConstants.niveau_mer_1750_target / CPhysicsConstants.Hmer_tot - this.optim1 ) / this.optim2;
*/
// CR avril 2024: Hmer_tot est maintenant ajusté avec le LGM
CPhysicsConstants.Hmer_tot = (CPhysicsConstants.niveau_mer_LGM + 10.0) / ((1. - Math.cos((CPhysicsConstants.niveau_calottes_max - this.niveau_calottes_actuel) * CPhysicsConstants.pi / 180)) * Math.pow((1. - this.niveau_calottes_actuel / CPhysicsConstants.niveau_calottes_max), CPhysicsConstants.expmer) - (1. - Math.cos((CPhysicsConstants.niveau_calottes_max - CPhysicsConstants.niveau_calottes_LGM) * CPhysicsConstants.pi / 180)) * Math.pow((1. - CPhysicsConstants.niveau_calottes_LGM / CPhysicsConstants.niveau_calottes_max), CPhysicsConstants.expmer));
CLogger.log('physics-constants: Hmer_tot = ' + CPhysicsConstants.Hmer_tot);
CLogger.log('physics-constants: niveau_calottes_actuel=' + this.niveau_calottes_actuel);
// CR avril 2024: Hmeract calculé avec la nouvelle formule du niveau mer
this.Hmeract = CPhysicsConstants.Hmer_tot * (1. - (1. - Math.cos((CPhysicsConstants.niveau_calottes_max - this.niveau_calottes_actuel) * CPhysicsConstants.pi / 180)) * Math.pow((1. - this.niveau_calottes_actuel / CPhysicsConstants.niveau_calottes_max), CPhysicsConstants.expmer));
CLogger.log('physics-constants: Hmeract = ' + this.Hmeract);
/*
this.Hmeract = CPhysicsConstants.Hmer_tot * ( 1
- this.fphig1 * ( this.niveau_calottes_actuel - CPhysicsConstants.niveau_calottes_max)
- CPhysicsConstants.fphig2 * Math.pow( this.niveau_calottes_actuel - CPhysicsConstants.niveau_calottes_max, 2 )
- CPhysicsConstants.fphig3 * Math.pow( this.niveau_calottes_actuel - CPhysicsConstants.niveau_calottes_max, 3 ) );
*/
// modif CR 4 nov 2019: calcul exact de niveau_mer_1750
// this.niveau_mer_1750 = CPhysicsConstants.Hmer_tot * ( 1 + CPhysicsConstants.dilat * 0.5 * ( CPhysicsConstants.temperature_1750 - this.Tressentie_act ) ) * ( 1
// - this.fphig1 * ( CPhysicsConstants.niveau_calottes_1750 - CPhysicsConstants.niveau_calottes_max)
// - CPhysicsConstants.fphig2 * Math.pow( CPhysicsConstants.niveau_calottes_1750 - CPhysicsConstants.niveau_calottes_max, 2 )
// - CPhysicsConstants.fphig3 * Math.pow( CPhysicsConstants.niveau_calottes_1750 - CPhysicsConstants.niveau_calottes_max, 3 ) ) - this.Hmeract;
// modif CR avril 2024 car on modifie le calcul de niveau mer.
this.Hmer_1750 = CPhysicsConstants.Hmer_tot * (1 + this.dilatation_1750) * (1. - (1. - Math.cos((CPhysicsConstants.niveau_calottes_max - CPhysicsConstants.niveau_calottes_1750) * CPhysicsConstants.pi / 180)) * Math.pow((1. - CPhysicsConstants.niveau_calottes_1750 / CPhysicsConstants.niveau_calottes_max), CPhysicsConstants.expmer));
CLogger.log('physics-constants: Hmer_1750 = ' + this.Hmer_1750);
CLogger.log('physics-constants: dilatation_1750= ' + this.dilatation_1750);
CLogger.log('physics-constants: Hmer_tot= ' + CPhysicsConstants.Hmer_tot);
CLogger.log('physics-constants: CPhysicsConstants.niveau_calottes_1750 = ' + CPhysicsConstants.niveau_calottes_1750);
this.niveau_mer_1750 = this.Hmer_1750 - this.Hmeract;
CLogger.log('physics-constants: niveau_mer_1750 = ' + this.niveau_mer_1750);
this.C_alteration_naturel = -CPhysicsConstants.volcanisme_actuel / CPhysicsConstants.concentration_coo_1750;
this.deltaT_poce = 0.5 / CPhysicsConstants.A_oce;
this.a_H2O = -CPhysicsConstants.q_H2O * (1 - this.G0);
this.Tlim_bio_froid = CPhysicsConstants.temperature_froid;
this.delta_angle_actuel = (CPhysicsConstants.lat_Mil - CPhysicsConstants.obliquite_actuel) / 360 * 2 * CPhysicsConstants.pi;
this.insol_actuel = CPhysicsConstants.puissance_recue_zero * Math.cos(this.delta_angle_actuel);
this.albedo_crit = (CPhysicsConstants.albedo_1750 - CPhysicsConstants.albedo_ter * (CPhysicsConstants.niveau_calottes_1750 - CPhysicsConstants.phig_crit) /
(CPhysicsConstants.niveau_calottes_max - CPhysicsConstants.phig_crit)) /
(1 - (CPhysicsConstants.niveau_calottes_1750 - CPhysicsConstants.phig_crit) /
(CPhysicsConstants.niveau_calottes_max - CPhysicsConstants.phig_crit)); // 0.41
this.albedo_actuel = this.albedo_crit + (this.niveau_calottes_actuel - CPhysicsConstants.phig_crit) / (CPhysicsConstants.niveau_calottes_max - CPhysicsConstants.phig_crit) * (CPhysicsConstants.albedo_ter - this.albedo_crit);
this.stockage_max = CPhysicsConstants.flux_co2_stockage_max / CPhysicsConstants.concentration_coo_1750;
this.concentration_coo_carbonifere = CPhysicsConstants.concentration_coo_1750 * 2; // modif 7 avril 2009
this.stockage_carbonifere = CPhysicsConstants.flux_co2_stockage_carbonifere / this.concentration_coo_carbonifere;
}
/**
* logModelConstants method.
*
* this method simply log to the console class properties and methods.
*
* @remarks
* This method is part of the {@link core-library#Statistics | Statistics subsystem}.
*
* @beta
*/
logModelConstants() {
console.log(this);
}
/**
* toJSON method.
*
* this method return the public and protected object properties.
*
* @remarks
* This method is part of the {@link core-library#Statistics | Statistics subsystem}.
*
* @beta
*/
toJSON() {
let properties = Object.getOwnPropertyNames(this);
return properties;
}
}
// Constantes mathématiques
/** Pi math constant */
CPhysicsConstants.pi = Math.PI;
// constantes radiatives
CPhysicsConstants.puissance_recue_zero = 1370 / 4.;
CPhysicsConstants.distance_ts_actuelle = 1.5e11;
CPhysicsConstants.sigma = 5.67e-8;
// constantes du calcul de l'albédo
CPhysicsConstants.albedo_froid = 0.65;
CPhysicsConstants.albedo_chaud = 0.325;
CPhysicsConstants.temperature_froid = 262;
CPhysicsConstants.temperature_chaud = 286;
// constantes des GES (Gaz à effet de serre)
// conversions de Gt à ppm:
/** 5.13e6 en Gt */
CPhysicsConstants.masse_atmosphere_Gt = 1.4e6;
/** Exprimée eng/mol */
CPhysicsConstants.masse_molaire_coo = 44;
CPhysicsConstants.masse_molaire_chhhh = 16;
CPhysicsConstants.masse_molaire_air = 29;
// concentrations actuelles et naturelles
CPhysicsConstants.concentration_coo_actuel = 405; // ppm
CPhysicsConstants.concentration_coo_2007 = 370; // ppm: ajout mars 2022
CPhysicsConstants.concentration_coo_1750 = 280;
CPhysicsConstants.concentration_coo_naturel = 280;
CPhysicsConstants.concentration_coo_min = 1e-1; // pour ne pas avoir de nan en prenant le log
CPhysicsConstants.coo_Gt_act = 750; // masse de CO2 en Gt
CPhysicsConstants.coo_Gt_2007 = 750; // masse de CO2 en Gt: ajout mars 2022
CPhysicsConstants.coo_Gt_1750 = 280 * 750 / 370; // masse de CO2 en Gt
CPhysicsConstants.concentration_coo_glaciaire = 180; // ppm
// constantes radiatives
CPhysicsConstants.a_coo = 22e-3; // 5.35; On peut changer cette valeur sans changer l'equilibre pre-industriel.
CPhysicsConstants.concentration_coo_limite = 10000; // en ppm, la limite entre relation linéaire et log pour forcage serre
// pour extrapolations lin pour hautes concentrations
CPhysicsConstants.concentration_coo_limite_bas = 100; // en ppm,idem pour extrapolation pour basses concnetrations
CPhysicsConstants.G_min = 1e-4; // forcage_serre min, pour eviter des nan
CPhysicsConstants.t_res_coo_0 = 1.5e6;
CPhysicsConstants.niveau_calotte_critique_coo = 20;
CPhysicsConstants.niveau_calottes_1750 = 60;
// const double facteur_alteration_0=1e-3;
// const double facteur_alteration_90=1;
// températures
CPhysicsConstants.tau_temperature = 30; // en années
CPhysicsConstants.temperature_actuelle = 15.5; // en °C ; necessaire dans modele_reset
// calculée à la main pour C02=370 et albédo=albédo_actuel
// public readonly temperature_1900: number;
CPhysicsConstants.temperature_1750 = 14.4;
CPhysicsConstants.temperature_LGM = 10;
CPhysicsConstants.C_terre = 5e9; // capacité calorifique de la Terre en J/K/m2
CPhysicsConstants.Tkelvin = 273.0;
// données radiatives sur l'actuel
CPhysicsConstants.albedo_1750 = 0.33;
// données et constantes de bidouille sur le niveau de la mer
/** Facteur de pondération de la température il y a [[deltat0]] ans */
// constantes commentées par Camille le 19 avril 2024 car sont inutiles
// public static readonly p0: number = 1.;
// public static readonly p1: number = 5.;
// public static readonly p2: number = 3.;
// public static readonly p3: number = 1.;
/** Retard en temps en année */
CPhysicsConstants.deltat0 = 0.;
CPhysicsConstants.deltat1 = 5.;
CPhysicsConstants.deltat2 = 20.;
CPhysicsConstants.deltat3 = 50.;
CPhysicsConstants.C_niveau = 100.; // orig=96
CPhysicsConstants.a_mer = 140;
CPhysicsConstants.tmemoire_niveau_mer = 100.; // le 30 janvier 2011: en fait, tau_niveau_mer ne peut dépasser 100 ans car c'est la mémoire maximale d'une simul pour la simul précédente. # c est le pas de temps utilise pour calculer l effet memoire.
CPhysicsConstants.tau_niveau_mer = 1000.; // c est l echelle de temps caracteristique de l evolution de la temperature de l ocean
// public readonly T_ressentie_actuelle: number; // commenté le 19 avril 2024 par Camille car c'est inutile
// niveau mer exprimé en m /t actuel
CPhysicsConstants.niveau_mer_LGM = -130;
// niveau des calottes
CPhysicsConstants.niveau_calottes_LGM = 45;
CPhysicsConstants.niveau_calottes_LGM_noinsol = 52;
CPhysicsConstants.tau_niveau_calottes_englacement = 5000.;
CPhysicsConstants.tau_niveau_calottes_deglacement = 5000.;
CPhysicsConstants.niveau_calottes_min = 0;
CPhysicsConstants.niveau_calottes_max = 90;
CPhysicsConstants.dilat = 2.4e-4; // en °C
CPhysicsConstants.coef_dilat = 2.0; // c'est un param ajustable pour ajuster la dilatation. Avant on n'en avait pas besoin parce que Hmer_tot réaliste, mais là, on l'ajuste su le changement de niveau mer du LGM
// public readonly optim1: number;
// public readonly optim2: number;
CPhysicsConstants.expmer = 1.5; // constante ajoutée le 19 avril 2024 par Camille. C'est un exposant qui sert de maramètre ajustable pour que niveau_mer_1750 soit à peu près égale à -0.2 m.
// public static readonly niveau_mer_1750_target: number = -0.2; // commenté le 19 avril 2024 par Camille
// flux de carbone
// const double CO2_biologique_eq=concentration_coo_naturel;
// calcul CO2_ocean_eq en fonction temp�rature
CPhysicsConstants.a_CO2_eq = 20; // ppm/°C
CPhysicsConstants.emit_anthro_coo_act = 12; // Gt: mise à jour mars 2022
CPhysicsConstants.volcanisme_actuel = 0.083; // en Gt/an
CPhysicsConstants.puit_ocean_act = 20.0; // en pourcent des emissions anthro absorbées
CPhysicsConstants.Tlim_oce = 10; // en °K
// const double rel_CO2_temperature=emit_anthro_coo_act/Tlim_oce;
CPhysicsConstants.b_ocean = 1 / 5000.0;
CPhysicsConstants.Tlim_oce_froid = 275;
CPhysicsConstants.A_oce = 3e-2;
CPhysicsConstants.Tcrit_oce = 35;
CPhysicsConstants.puit_oce_max = 40; // en pourcent
CPhysicsConstants.dFdegaz = 0.05;
CPhysicsConstants.q_CO2 = 0.26; // CO2=26% de l'effet de serre
// retroactions vapeur d'eau
CPhysicsConstants.q_H2O = 0.6; // eau=60% de l'effet de serre
// public static readonly tau_T: number = 200; // en °K
CPhysicsConstants.rapport_H2O_actconst = 1.05719; // rapport pour la température actuelle
CPhysicsConstants.a_rankine = 13.7;
CPhysicsConstants.b_rankine = 5120.;
CPhysicsConstants.pow_H2O = 0.23; // normallement: 0.18
// paramétrisation de A_biologique en fonction de la température
CPhysicsConstants.puit_bio_act = 30; // en pourcent
CPhysicsConstants.Tlim_bio_chaud = 340; // en K
//const double A_biologique_act=-puit_bio_act*emit_anthro_coo_act/(concentration_coo_actuel-concentration_coo_1750); // en an-1
// parametres orbitaux
CPhysicsConstants.lat_Mil = 65;
CPhysicsConstants.c_calottes = 0.2;
//const double precession_actuel=-90;
CPhysicsConstants.precession_actuel = 102.7; // modif 31 janv 2009: on prend la même precession que LMDZ
// la formule de insol65N n'a pas été modifiée car 2 bugs se compensaient
CPhysicsConstants.obliquite_actuel = 23.5;
CPhysicsConstants.excentricite_actuel = 0.0167;
// albédo
CPhysicsConstants.albedo_phi_min = 0.60;
CPhysicsConstants.albedo_phi_max = 0.2;
CPhysicsConstants.albedo_glace_const = 0.90;
CPhysicsConstants.phig_crit = 30.0; // 30
CPhysicsConstants.albedo_ter = 0.25;
// calcule de la température
CPhysicsConstants.capacite_calorifique = 0.1;
// stockage biologique
CPhysicsConstants.flux_co2_stockage_max = -10; // GT/an-1
CPhysicsConstants.flux_co2_stockage_carbonifere = -0.396; // en Gt par an d'apres R.A. Berner et D.E. Canfield (1989)
// logicals
CPhysicsConstants.echantillonage = 1;
// if 1: échantillonage direct au pas de temps
// if 2: échantillonage en moyennant sur les pas de temps autour du point d'échantillonage
CPhysicsConstants.calcul_carbone = 1;
const modelVarsConstants = {
enable_gl_animations: 0,
echeance_min: 100,
echeance_max: 10e6,
echeance_reset_value: 500,
time_slider_reset_value: 0,
/** affichage des results */
graphe_one_init: 0 /* graphTypes.TEMPERATURE */,
graphe_two_init: 3 /* graphTypes.CONCENTRATION_CO2 */,
graphe_three_init: 1 /* graphTypes.WATERLEVEL */,
graphe_four_init: 2 /* graphTypes.CALOTTESLEVEL */,
/** simulation_type */
fixed_concentration_reset_value: 1,
/** concentrations en CO2 en ppm */
coo_concentr_terre_initiale: 0.3e6,
coo_concentr_cretace: 1500,
coo_concentr_1750: CPhysicsConstants.concentration_coo_1750,
coo_concentr_today: CPhysicsConstants.concentration_coo_actuel,
coo_concentr_min: 0,
coo_concentr_max: 1e6,
coo_concentr_reset_value: 0,
/** emissions de CO2, en Gt/an. */
/** emissions antropiques */
emit_anthro_coo_actuel: CPhysicsConstants.emit_anthro_coo_act,
emit_anthro_coo_2xactuel: CPhysicsConstants.emit_anthro_coo_act * 2,
emit_anthro_coo_nul: 0.,
emit_anthro_coo_min: -2,
emit_anthro_coo_max: 50,
emit_anthro_coo_reset_value: 0,
/** volcanisme */
volcan_actuel: CPhysicsConstants.volcanisme_actuel,
volcan_terre_init: 0,
/** d'après les flux de chaleurs en fonction du temps depuis formation de la terre données sur www.geo.mtu.edu/svl/GE3320/LECTURE%206.ppt */
/** volcan_terre_600ma=volcan_actuel*2; // d'après la même source */
volcan_min: 0,
volcan_max: 0,
volcan_reset_value: 0,
/** alteration, en % de variation par rapport à la ref=C_alteration_naturel */
alteration_actuel: 100.,
alteration_min: 0.0,
alteration_max: 1000.0,
alteration_reset_value: 0,
/** stockage biologique */
stockage_biologique_actuel: 0.,
stockage_biologique_carbonifere: 0,
stockage_biologique_min: 0.,
stockage_biologique_max: 0,
stockage_biologique_reset_value: 0.,
/** albédo */
fixed_albedo_reset_value: 0,
albedo_act: 0,
albedo_reset_value: 0,
albedo_glace: CPhysicsConstants.albedo_glace_const * 100,
albedo_terre: CPhysicsConstants.albedo_ter * 100,
albedo_min: 0.,
albedo_max: 100.,
/** puit biologique */
debranche_biologie_reset_value: 0,
puit_bio_actuel: CPhysicsConstants.puit_bio_act,
puit_bio_min: -50,
puit_bio_max: 100.,
puit_bio_reset_value: 0,
/** puit océanique */
fixed_ocean_reset_value: 1,
debranche_ocean_reset_value: 0,
puit_ocean_actuel: CPhysicsConstants.puit_ocean_act,
puit_ocean_min: -50,
puit_ocean_max: 100.,
puit_ocean_reset_value: 0,
/** vapeur d'eau */
fixed_eau_reset_value: 0,
rapport_H2O_reset_value: 100.,
rapport_H2O_actuel: 100. * CPhysicsConstants.rapport_H2O_actconst,
rapport_H2O_min: 0.,
rapport_H2O_max: 1000.,
/** parametres orbitaux */
/** en fraction d'augmentation par rapport à l'actuel, en % */
puissance_soleil_terre_init: 70,
puissance_soleil_actuel: 100,
puissance_soleil_min: 0,
puissance_soleil_max: 1000,
puissance_soleil_reset_value: 0,
distance_ts_actuel: 100,
distance_ts_min: 0,
distance_ts_max: 1000,
distance_ts_reset_value: 0,
/** paramètres orbitaux */
excentricite_act: CPhysicsConstants.excentricite_actuel,
excentricite_reset_value: 0,
excentricite_valeur_min: 0.,
excentricite_valeur_max: 0.06,
excentricite_autre_min: 0.,
excentricite_autre_max: 0.2,
obliquite_act: CPhysicsConstants.obliquite_actuel,
obliquite_reset_value: 0,
obliquite_valeur_min: 21.8,
obliquite_valeur_max: 24.4,
obliquite_autre_min: 0.,
obliquite_autre_max: 90.,
precession_act: CPhysicsConstants.precession_actuel,
precession_reset_value: 0,
/** 31 janv 2009: on met les min et max à -90 et 90 respectivement, au lieu de -180 et 180, car c'est avec -90 et 90 qu'on a les écarts de température les plus fort. */
precession_valeur_min: 90,
precession_valeur_max: 270,
precession_autre_min: 0,
precession_autre_max: 360
};
class CModelVars {
constructor(modelConstants) {
/** Merge default constants values with constructor passed values into private modelConstants property. */
if (modelConstants == undefined) {
this.modelConstants = Object.assign({}, modelVarsConstants);
}
else {
this.modelConstants = Object.assign(Object.assign({}, modelVarsConstants), modelConstants);
}
/** Instantiate a CPhysicsConstants object */
let physicConstants = new CPhysicsConstants();
// Set reset vars + some others
this.modelConstants.precession_reset_value = this.modelConstants.precession_act;
this.modelConstants.obliquite_reset_value = this.modelConstants.obliquite_act;
this.modelConstants.excentricite_reset_value = this.modelConstants.excentricite_act;
this.modelConstants.distance_ts_reset_value = this.modelConstants.distance_ts_actuel;
this.modelConstants.puissance_soleil_reset_value = this.modelConstants.puissance_soleil_actuel;
this.modelConstants.puit_ocean_reset_value = this.modelConstants.puit_ocean_actuel;
this.modelConstants.puit_bio_reset_value = this.modelConstants.puit_bio_actuel;
this.modelConstants.albedo_reset_value = physicConstants.albedo_actuel * 100;
this.modelConstants.albedo_act = physicConstants.albedo_actuel * 100;
this.modelConstants.stockage_biologique_max = -physicConstants.stockage_max * 1e3;
this.modelConstants.stockage_biologique_carbonifere = -physicConstants.stockage_carbonifere * 1e3;
this.modelConstants.alteration_reset_value = this.modelConstants.alteration_actuel;
this.modelConstants.volcan_reset_value = this.modelConstants.volcan_actuel;
this.modelConstants.volcan_terre_init = this.modelConstants.volcan_actuel * 5;
this.modelConstants.volcan_max = this.modelConstants.volcan_terre_init * 6;
this.modelConstants.emit_anthro_coo_reset_value = this.modelConstants.emit_anthro_coo_nul;
this.modelConstants.coo_concentr_reset_value = this.modelConstants.coo_concentr_1750;
}
logModelConstants() {
console.log(this.modelConstants);
}
}
/**
* This class calculate climat simulation model.
*
* Instanciation example :
*
* ```typescript
* const instance = new CModel();
* ```
*
* @remarks
* This method is part of the {@link core-library#Statistics | Statistics subsystem}.
*
* @author Alain Deseine
*
* @copyright CEI Alain Deseine 1992-2019
*
* @beta
*/
class CModel {
/**
* Constructor.
*
* The constructor of this class initialise Physics constants and model vars.
*
* @remarks
* This method is part of the {@link core-library#Statistics | Statistics subsystem}.
*
* @beta
*/
constructor(modelConstants) {
// Instanciate a CModelVars object
let modelVars;
if (modelConstants == undefined) {
modelVars = new CModelVars();
}
else {
modelVars = new CModelVars(modelConstants);
}
// Merge default constants values with constructor passed values into private modelConstants property.
this.modelConstants = Object.assign({}, modelVars.modelConstants);
// Instanciate a CPhysicsConstants object
this.modelPhysicsConstants = new CPhysicsConstants();
} // eo constructor
logModelConstants() {
console.log(this.modelPhysicsConstants);
console.log(this.modelConstants);
} // eo logModelConstants method
/**
* Utils methods
*/
calculT(Teq, Tprec, tau, dt) {
let T;
T = Tprec + (Teq - Tprec) * (1 - Math.exp(-dt / tau));
return T;
} // eo calculT method
calcul_forcage_serre_H2O(zrapport_H2O) {
let forcage_serre_H2O;
CLogger.log('Method calcul_forcage_serre_H2O: zrapport_H2O = ' + zrapport_H2O);
if (zrapport_H2O > 1e-5) {
// forcage_serre_H2O=a_H2O*(1-exp(pow_H2O*log(zrapport_H2O)));
// modif le 7 avril pour éviter rétroactions trop positives
// on sature le forcage serre aux hautes concentrations en eau
// forcage_serre_H2O = this.modelPhysicsConstants.a_H2O * ( 1 - Math.exp( CPhysicsConstants.pow_H2O * Math.log( zrapport_H2O ) ) );
forcage_serre_H2O = this.modelPhysicsConstants.a_H2O * (1 - Math.exp(CPhysicsConstants.pow_H2O * Math.log(zrapport_H2O))) * (0.3 * Math.exp(-Math.sqrt(Math.abs(zrapport_H2O - 1)) / 10.0) + 0.7);
}
else {
forcage_serre_H2O = this.modelPhysicsConstants.a_H2O;
}
CLogger.log('Method calcul_forcage_serre_H2O: forcage_serre_H2O = ' + forcage_serre_H2O);
return forcage_serre_H2O;
} // eo calcul_forcage_serre_H2O method
calcul_forcage_serre_CO2(zCO2) {
let forcage_serre_CO2;
if (zCO2 < CPhysicsConstants.concentration_coo_limite_bas) {
CLogger.log('Method calcul_forcage_serre_CO2: relation linéaire, extrapolation basse');
// forcage_serre_CO2 = - 0.2 * this.modelPhysicsConstants.G0 + zCO2 / CPhysicsConstants.concentration_coo_limite_bas * ( 0.2 * this.modelPhysicsConstants.G0 + CPhysicsConstants.a_coo * Math.log( CPhysicsConstants.concentration_coo_limite_bas / CPhysicsConstants.concentration_coo_1750 ) );
forcage_serre_CO2 = -CPhysicsConstants.q_CO2 * this.modelPhysicsConstants.G0 + zCO2 / CPhysicsConstants.concentration_coo_limite_bas * (CPhysicsConstants.q_CO2 * this.modelPhysicsConstants.G0 + CPhysicsConstants.a_coo * Math.log(CPhysicsConstants.concentration_coo_limite_bas / CPhysicsConstants.concentration_coo_1750));
}
else if (zCO2 > CPhysicsConstants.concentration_coo_limite) {
CLogger.log('Method calcul_forcage_serre_CO2: relation linéaire, extrapolation haute');
// forcage_serre_CO2 = CPhysicsConstants.a_coo * ( Math.log( CPhysicsConstants.concentration_coo_limite / CPhysicsConstants.concentration_coo_1750 ) + zCO2 / CPhysicsConstants.concentration_coo_limite - 1 );
forcage_serre_CO2 = CPhysicsConstants.a_coo * (Math.log(CPhysicsConstants.concentration_coo_limite / CPhysicsConstants.concentration_coo_1750) + 1.0 * (zCO2 / CPhysicsConstants.concentration_coo_limite - 1));
}
else {
// relation log
CLogger.log('Method calcul_forcage_serre_CO2: relation log');
forcage_serre_CO2 = CPhysicsConstants.a_coo * Math.log(zCO2 / CPhysicsConstants.concentration_coo_1750);
}
CLogger.log('Method calcul_forcage_serre_CO2: forcage_serre_CO2 = ' + forcage_serre_CO2);
return forcage_serre_CO2;
} // eo calcul_forcage_serre_CO2 method
calcul_phieq(zT, insol65N) {
let zphieq;
// T en degre K
CLogger.log('Method calcul_phieq: calcul_phig = ' + zT);
CLogger.log('Method calcul_phieq: calcul_phig: a_calottes = ' + this.modelPhysicsConstants.a_calottes);
CLogger.log('Method calcul_phieq: calcul_phig: b_calottes = ' + this.modelPhysicsConstants.b_calottes);
// zphieq = this.modelPhysicsConstants.a_calottes * ( zT - 273.0 ) + this.modelPhysicsConstants.b_calottes + CPhysicsConstants.c_calottes * ( insol65N - this.modelPhysicsConstants.insol_actuel );
zphieq = this.modelPhysicsConstants.a_calottes * (zT - CPhysicsConstants.Tkelvin) + this.modelPhysicsConstants.b_calottes + CPhysicsConstants.c_calottes * (insol65N - this.modelPhysicsConstants.insol_actuel);
if (zphieq > CPhysicsConstants.niveau_calottes_max) {
zphieq = CPhysicsConstants.niveau_calottes_max;
}
if (zphieq < CPhysicsConstants.niveau_calottes_min) {
zphieq = CPhysicsConstants.niveau_calottes_min;
}
CLogger.log('Method calcul_phieq: calcul_phig: a_calottes * ( zT - CPhysicsConstants.Tkelvin ) = ' + this.modelPhysicsConstants.a_calottes * (zT - CPhysicsConstants.Tkelvin));
CLogger.log('Method calcul_phieq: calcul_phig: c_calottes * ( insol65N - insol_actuel ) = ' + CPhysicsConstants.c_calottes * (insol65N - this.modelPhysicsConstants.insol_actuel));
CLogger.log('Method calcul_phieq: calcul_phig: zphieq = ' + zphieq);
return zphieq;
} // eo calcul_phieq method
calcul_tau_niveau_calottes(phieq, zphig_ancien) {
let tau_niveau_calottes;
if (zphig_ancien < phieq) {
CLogger.log('Method calcul_tau_niveau_calottes: désenglacement');
tau_niveau_calottes = CPhysicsConstants.tau_niveau_calottes_deglacement;
}
else {
CLogger.log('Method calcul_tau_niveau_calottes: englacement');
tau_niveau_calottes = CPhysicsConstants.tau_niveau_calottes_englacement;
}
CLogger.log('Method calcul_tau_niveau_calottes: calcul_phig: tau_niveau_calottes = ' + tau_niveau_calottes);
return tau_niveau_calottes;
} // eo calcul_tau_niveau_calottes method
/*
public calcul_niveau_mer_old( zphig: number, zT: number, t: number ): number {
// let sv: any = this.experienceValues.back(); // TODO Alain : Revenir la dessus
let niveau_mer: number;
let Tressentie: number;
// modif le 30 jan 2011: tau_niveau_mer est en année, il faut diviser par temps_elem pour l'avoir en nombre de pas
// let index: number = Math.max( this.experienceValues.indice_min(), t - Math.trunc( CPhysicsConstants.tau_niveau_mer ) );
// let index: number = Math.max( this.experienceValues.indice_min(), t - Math.trunc( CPhysicsConstants.tau_niveau_mer / this.experienceValues.temps_elem() ) );
// modif CR: 31 oct 2019: index doit pouvoir être soit positif, soit négatif. On met juste des bornes entre -100 et +100
let index: number = t - Math.trunc( CPhysicsConstants.tau_niveau_mer / this.experienceValues.temps_elem() );
index = Math.min( this.experienceValues.indice_max() , index );
index = Math.max( - this.experienceValues.indice_max() , index );
CLogger.log( 'Method calcul_niveau_mer: index = ' + index + ' - indice_min() = ' + this.experienceValues.indice_min() + ' - t = ' + t + ' - tau_niveau_mer = ' + CPhysicsConstants.tau_niveau_mer + ' - temps_elem() = ' + this.experienceValues.temps_elem() );
if ( index < 0 )
{
Tressentie = zT * 0.2 + this.simulationValues.temperature_data.get_past( - index ) * 0.8;
CLogger.log( 'Method calcul_niveau_mer: index neg: Tpast' + this.simulationValues.temperature_data.get_past( - index ) );
}
else
{
Tressentie = zT * 0.2 + this.simulationValues.temperature_data.get( index ) * 0.8;
}
CLogger.log( 'Method calcul_niveau_mer: zT = ' + zT + ' - Tressentie = ' + Tressentie );
// le 30 jan 2011: on rajoute facteur 0.5 pour tenir compte de la sous-estimation de la constante de temps de l'océan.
// let dilatation: number = CPhysicsConstants.dilat * ( Tressentie - 273 - this.modelPhysicsConstants.Tressentie_act );
let dilatation: number = CPhysicsConstants.dilat * CPhysicsConstants.coef_dilat * ( Tressentie - CPhysicsConstants.Tkelvin - this.modelPhysicsConstants.Tressentie_act );
CLogger.log( 'Method calcul_niveau_mer: Tressentie_act = ' + this.modelPhysicsConstants.Tressentie_act );
CLogger.log( 'Method calcul_niveau_mer: Hmer_tot = ' + CPhysicsConstants.Hmer_tot );
CLogger.log( 'Method calcul_niveau_mer: dilatation = ' + dilatation );
CLogger.log( 'Method calcul_niveau_mer: zphig = ' + zphig );
// CLogger.log( 'Method calcul_niveau_mer: fmax*F(phig_act) = ' + ( -3.8827e-7 * Math.pow( this.modelPhysicsConstants.niveau_calottes_actuel, 3 ) + 1.2689e-4 * Math.pow( this.modelPhysicsConstants.niveau_calottes_actuel, 2 ) -0.0134 * this.modelPhysicsConstants.niveau_calottes_actuel + 0.4615 ) );
// CLogger.log( 'Method calcul_niveau_mer: fmax*F(phig) = ' + ( -3.8827e-7 * Math.pow( zphig, 3 ) + 1.2689e-4 * Math.pow( zphig, 2 ) - 0.0134 * zphig + 0.4615 ) );
CLogger.log( 'Method calcul_niveau_mer: f(phig_act) = ' + this.modelPhysicsConstants.fphig1 * ( zphig - CPhysicsConstants.niveau_calottes_max) + CPhysicsConstants.fphig2 * Math.pow( zphig - CPhysicsConstants.niveau_calottes_max, 2 ) + CPhysicsConstants.fphig3 * Math.pow( zphig - CPhysicsConstants.niveau_calottes_max, 3 ) );
// let Hmer: number = CPhysicsConstants.Hmer_tot * ( 1 + dilatation ) * ( 1 - ( -3.8827e-7 * Math.pow( zphig, 3 ) + 1.2689e-4 * Math.pow( zphig, 2 ) - 0.0134 * zphig + 0.4615 ) );
// let Hmeract: number = CPhysicsConstants.Hmer_tot * ( 1 - ( -3.8827e-7 * Math.pow( this.modelPhysicsConstants.niveau_calottes_actuel, 3 ) + 1.2689e-4 * Math.pow( this.modelPhysicsConstants.niveau_calottes_actuel, 2 ) - 0.0134 * this.modelPhysicsConstants.niveau_calottes_actuel + 0.4615 ) );
let Hmer: number = CPhysicsConstants.Hmer_tot * ( 1 + dilatation ) * ( 1 - this.modelPhysicsConstants.fphig1 * ( zphig - CPhysicsConstants.niveau_calottes_max ) - CPhysicsConstants.fphig2 * Math.pow( zphig - CPhysicsConstants.niveau_calottes_max, 2 ) - CPhysicsConstants.fphig3 * Math.pow( zphig - CPhysicsConstants.niveau_calottes_max, 3 ) );
CLogger.log( 'Method calcul_niveau_mer: Hmer = ' + Hmer );
CLogger.log( 'Method calcul_niveau_mer: Hmeract = ' + this.modelPhysicsConstants.Hmeract );
niveau_mer = Hmer - this.modelPhysicsConstants.Hmeract;
CLogger.log( 'Method calcul_niveau_mer: niveau_mer = ' + niveau_mer );
return niveau_mer;
} // eo calcul_niveau_mer_old method
*/
calcul_niveau_mer(zphig, zT, t) {
// let sv: any = this.experienceValues.back(); // TODO Alain : Revenir la dessus
let niveau_mer;
let Tressentie;
// modif le 30 jan 2011: tau_niveau_mer est en année, il faut diviser par temps_elem pour l'avoir en nombre de pas
// let index: number = Math.max( this.experienceValues.indice_min(), t - Math.trunc( CPhysicsConstants.tau_niveau_mer ) );
// let index: number = Math.max( this.experienceValues.indice_min(), t - Math.trunc( CPhysicsConstants.tau_niveau_mer / this.experienceValues.temps_elem() ) );
// modif CR: 31 oct 2019: index doit pouvoir être soit positif, soit négatif. On met juste des bornes entre -100 et +100
let index = t - Math.trunc(CPhysicsConstants.tmemoire_niveau_mer / this.experienceValues.temps_elem());
index = Math.min(this.experienceValues.indice_max(), index);
index = Math.max(-this.experienceValues.indice_max(), index);
CLogger.log('Method calcul_niveau_mer: index = ' + index + ' - indice_min() = ' + this.experienceValues.indice_min() + ' - t = ' + t + ' - tau_niveau_mer = ' + CPhysicsConstants.tmemoire_niveau_mer + ' - temps_elem() = ' + this.experienceValues.temps_elem());
if (index < 0) {
Tressentie = zT * (1. - this.modelPhysicsConstants.pond_memoire_mer) + this.simulationValues.temperature_data.get_past(-index) * this.modelPhysicsConstants.pond_memoire_mer;
CLogger.log('Method calcul_niveau_mer: index neg: Tpast' + this.simulationValues.temperature_data.get_past(-index));
}
else {
Tressentie = zT * (1. - this.modelPhysicsConstants.pond_memoire_mer) + this.simulationValues.temperature_data.get(index) * this.modelPhysicsConstants.pond_memoire_mer;
}
CLogger.log('Method calcul_niveau_mer: zT = ' + zT + ' - Tressentie = ' + Tressentie);
// le 30 jan 2011: on rajoute facteur 0.5 pour tenir compte de la sous-estimation de la constante de temps de l'océan.
// let dilatation: number = CPhysicsConstants.dilat * ( Tressentie - 273 - this.modelPhysicsConstants.Tressentie_act );
let dilatation = CPhysicsConstants.dilat * CPhysicsConstants.coef_dilat * (Tressentie - CPhysicsConstants.Tkelvin - this.modelPhysicsConstants.Tressentie_act);
CLogger.log('Method calcul_niveau_mer: Tressentie_act = ' + this.modelPhysicsConstants.Tressentie_act);
CLogger.log('Method calcul_niveau_mer: Hmer_tot = ' + CPhysicsConstants.Hmer_tot);
CLogger.log('Method calcul_niveau_mer: dilatation = ' + dilatation);
CLogger.log('Method calcul_niveau_mer: zphig = ' + zphig);
let Hmer = CPhysicsConstants.Hmer_tot * (1 + dilatation) * (1. - (1. - Math.cos((CPhysicsConstants.niveau_calottes_max - zphig) * CPhysicsConstants.pi / 180)) * Math.pow((1. - zphig / CPhysicsConstants.niveau_calottes_max), CPhysicsConstants.expmer));
CLogger.log('Method calcul_niveau_mer: Hmer = ' + Hmer);
CLogger.log('Method calcul_niveau_mer: Hmeract = ' + this.modelPhysicsConstants.Hmeract);
CLogger.log('Method calcul_niveau_mer: Hmer_tot = ' + CPhysicsConstants.Hmer_tot);
niveau_mer = Hmer - this.modelPhysicsConstants.Hmeract;
CLogger.log('Method calcul_niveau_mer: niveau_mer = ' + niveau_mer);
return niveau_mer;
} // eo calcul_niveau_mer method
calcul_zA_biologique(zT, A) {
let zA;
if (zT < this.modelPhysicsConstants.Tlim_bio_froid) {
zA = 0;
}
else if (zT > CPhysicsConstants.Tlim_bio_chaud) {
zA = 0;
}
else {
zA = A;
}
return zA;
} // eo calcul_zA_biologique method
calcul_zCO2eq(zT) {
let zCO2eq;
CLogger.log('Method calcul_zCO2eq: calcul zCO2eq_oce: entrée: zT = ' + zT);
let Tc = 13.7;
let c = 5.0;
let b = (CPhysicsConstants.concentration_coo_glaciaire - CPhysicsConstants.concentration_coo_1750 - c * (CPhysicsConstants.temperature_LGM - CPhysicsConstants.temperature_1750)) / (Math.atan(CPhysicsConstants.temperature_LGM - Tc) - Math.atan(CPhysicsConstants.temperature_1750 - Tc));
let a = CPhysicsConstants.concentration_coo_glaciaire - b * Math.atan(CPhysicsConstants.temperature_LGM - Tc) - c * (CPhysicsConstants.temperature_LGM - Tc);
zCO2eq = a + b * Math.atan(zT - CPhysicsConstants.Tkelvin - Tc) + c * (zT - CPhysicsConstants.Tkelvin - Tc);
CLogger.log('Method calcul_zCO2eq: calcul_zCO2eq: zT = ' + zT + ' - zCO2eq = ' + zCO2eq);
return zCO2eq;
} // eo calcul_zCO2eq method
calcul_zCO2_ocean_eq(zT) {
let zCO2_ocean_eq;
CLogger.log('Method calcul_zCO2_ocean_eq: zT = ' + zT);
zCO2_ocean_eq = CPhysicsConstants.concentration_coo_naturel + CPhysicsConstants.a_CO2_eq * (zT - (CPhysicsConstants.temperature_1750 + CPhysicsConstants.Tkelvin));
CLogger.log('Method calcul_zCO2_ocean_eq: calcul_zCO2eq: zCO2_ocean_eq = ' + zCO2_ocean_eq);
return zCO2_ocean_eq;
} // eo calcul_zCO2_ocean_eq method
calcul_zC_alteration(Cmax, zphig) {
let zC_alteration;
CLogger.log('Method calcul_zC_alteration: Cmax = ' + Cmax);
CLogger.log('Method calcul_zC_alteration: zphig = ' + zphig);
if (zphig > CPhysicsConstants.niveau_calotte_critique_coo) {
zC_alteration = Cmax;
}
else if (zphig > 1e-2) {
zC_alteration = Cmax * zphig / CPhysicsConstants.niveau_calotte_critique_coo;
}
else {
zC_alteration = 0.;
}
return zC_alteration;
} // eo calcul_zC_alteration method
calcul_rapport_H2O(zT) {
let zrapport_H2O;
CLogger.log('Method calcul_rapport_H2O: zT = ' + zT);
CLogger.log('Method calcul_rapport_H2O: temperature_1750 + CPhysicsConstants.Tkelvin = ' + CPhysicsConstants.temperature_1750 + CPhysicsConstants.Tkelvin);
// CLogger.log( 'Method calcul_rapport_H2O: tau_T = ' + CPhysicsConstants.tau_T );
// utilisation de la formule de Rankine donnant Psat :
zrapport_H2O = (Math.exp(CPhysicsConstants.a_rankine - CPhysicsConstants.b_rankine / zT)) / (Math.exp(CPhysicsConstants.a_rankine - CPhysicsConstants.b_rankine / (CPhysicsConstants.temperature_1750 + CPhysicsConstants.Tkelvin)));
CLogger.log('Method calcul_rapport_H2O: zrapport_H2O = ' + zrapport_H2O);
return zrapport_H2O;
} // eo calcul_rapport_H2O method
calcul_albedo(zphig) {
let zalbedo;
if (zphig > CPhysicsConstants.phig_crit) {
zalbedo = this.modelPhysicsConstants.albedo_crit + (zphig - CPhysicsConstants.phig_crit) / (CPhysicsConstants.niveau_calottes_max - CPhysicsConstants.phig_crit) * (CPhysicsConstants.albedo_ter - this.modelPhysicsConstants.albedo_crit);
CLogger.log('Method calcul_albedo: albedo_crit = ' + this.modelPhysicsConstants.albedo_crit);
CLogger.log('Method calcul_albedo: albedo_actuel = ' + this.modelPhysicsConstants.albedo_actuel);
CLogger.log('Method calcul_albedo: zphig > phig_crit');
CLogger.log('Method calcul_albedo: B = ' + (this.modelPhysicsConstants.niveau_calottes_actuel - CPhysicsConstants.phig_crit) / (CPhysicsConstants.niveau_calottes_max - CPhysicsConstants.phig_crit));
CLogger.log('Method calcul_albedo: 1 - B = ' + (1 - (this.modelPhysicsConstants.niveau_calottes_actuel - CPhysicsConstants.phig_crit) / (CPhysicsConstants.niveau_calottes_max - CPhysicsConstants.phig_crit)));
CLogger.log('Method calcul_albedo: Aact - B.Ater = ' + (this.modelPhysicsConstants.albedo_actuel - CPhysicsConstants.albedo_ter * (this.modelPhysicsConstants.niveau_calottes_actuel - CPhysicsConstants.phig_crit) / (CPhysicsConstants.niveau_calottes_max - CPhysicsConstants.phig_crit)));
}
else {
zalbedo = CPhysicsConstants.albedo_glace_const + (zphig - CPhysicsConstants.niveau_calottes_min) / (CPhysicsConstants.phig_crit - CPhysicsConstants.niveau_calottes_min) * (this.modelPhysicsConstants.albedo_crit - CPhysicsConstants.albedo_glace_const);
}
CLogger.log('Method calcul_albedo: zphig = ' + zphig);
CLogger.log('Method calcul_albedo: zalbedo = ' + zalbedo);
// ASSERT(zalbedo>0);
// ASSERT(zalbedo<1);
return zalbedo;
} // eo calcul_albedo method
calcul_poce(zT) {
let zpoce;
let poce_act = 1 - CPhysicsConstants.puit_ocean_act;
if (zT > CPhysicsConstants.temperature_actuelle - CPhysicsConstants.Tkelvin) {
zpoce = poce_act + (1 - poce_act) * (1 - Math.exp(-(zT - CPhysicsConstants.temperature_actuelle - CPhysicsConstants.Tkelvin) / this.modelPhysicsConstants.deltaT_poce));
}
else {
zpoce = poce_act * Math.exp((zT - CPhysicsConstants.temperature_actuelle - CPhysicsConstants.Tkelvin) / this.modelPhysicsConstants.deltaT_poce);
}
return zpoce;
} // eo calcul_poce method
calcul_zpuit_oce(zT) {
let zpuit_oce;
zpuit_oce = (zT - CPhysicsConstants.Tcrit_oce - CPhysicsConstants.Tkelvin) / (CPhysicsConstants.temperature_actuelle - CPhysicsConstants.Tcrit_oce) * CPhysicsConstants.puit_ocean_act / 100.0;
CLogger.log('Method calcul_zpuit_oce: zpuit_oce = ' + zpuit_oce);
zpuit_oce = Math.max(0., zpuit_oce);
// zpuit_oce = Math.min( CPhysicsConstants.puit_oce_max, zpuit_oce );
zpuit_oce = Math.min(CPhysicsConstants.puit_oce_max / 100.0, zpuit_oce);
CLogger.log('Method calcul_zpuit_oce: zpuit_oce = ' + zpuit_oce);
// TODO Alain : Eclaircir le besoin de ces deux assertions pour éventuellement faire autrement
this.assert(zpuit_oce >= 0.);
this.assert(zpuit_oce <= CPhysicsConstants.puit_oce_max / 100.0);
return zpuit_oce;
} // eo calcul_zpuit_oce method
calcul_Fdegaz(zT) {
let Fdegaz;
if (zT - CPhysicsConstants.Tkelvin > CPhysicsConstants.Tcrit_oce) {
Fdegaz = (zT - CPhysicsConstants.Tcrit_oce - CPhysicsConstants.Tkelvin) * CPhysicsConstants.dFdegaz;
}
else {
Fdegaz = 0;
}
// TODO Alain : Eclaircir le besoin de cette assertion pour éventuellement faire autrement
this.assert(Fdegaz >= 0.);
return Fdegaz;
} // eo calcul_Fdegaz method
abs(x) {
let y;
if (x < 0) {
y = -x;
}
else {
y = x;
}
return y;
} // eo abs method
assert(condition, message = '') {
if (!condition) {
message = message || "Assertion failed";
if (typeof Error !== "undefined") {
throw new Error(message);
}
throw message; // Fallback
}
} // eo assert method
/** End of Utils methods */
/**
* Model execution method
*/
modelExecute(simulationValue, experienceValue) {
CLogger.log('Method modelExecute: Initialisation du modèle ... ');
CLogger.log(simulationValue);
CLogger.log(experienceValue);
simulationValue.set_annee_fin(experienceValue.echeance());
simulationValue.set_resolution(experienceValue.temps_elem());
/**
* On mappe l'objet CSimulationValues
*/
this.simulationValues = simulationValue;
this.experienceValues = experienceValue;
/**
* declarations pour l'integration temporelle
*/
let oscillation;
let zT = 0, zT_ancien, zT_ancien_prec; // température
let zCO2 = 0, zCO2_ancien, zCO2_ancien_prec; // CO2
let zphig = 0, zphig_ancien, zphig_ancien_prec = 0; // niveau calotte
let zT_moy, zCO2_moy, zphig_moy;
let zT_moy1, zCO2_moy1, zphig_moy1;
let zT_moy2, zCO2_moy2, zphig_moy2;
let zT_moy2save, zCO2_moy2sav