simclimat-lib
Version:
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0.
737 lines (724 loc) • 172 kB
JavaScript
import { CLogger } from './simclimat-lib.logger';
import { CModelVars } from './simclimat-lib.model-vars';
import { CPhysicsConstants } from './simclimat-lib.physics-constants';
/**
* 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
*/
export 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 = { ...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_moy2save, zphig_moy2save;
let zTeq;
let zsomme_flux;
let niter;
let nmid;
let dt;
/** variables intermédiaires */
let G;
let alteration_max;
let zC_alteration;
let zC_stockage;
let forcage_serre_eau = 0;
let forcage_serre_CO2 = 0;
let forcage_serre = 0;
let zB_ocean;
let zalbedo = 0;
let Fin0, insol65N;
let emission_coo_ppm = 0;
let zrapport_H2O;
let delta_angle;
let Fin, Fout;
let zpuit_oce = 0, zpuit_bio = 0;
let phieq;
let tau_niveau_calottes;
let zCO2eq, tau_CO2_eq;
let zCO2eq_oce;
let B_ocean = 0;
let Fdegaz;
let zsomme_flux_const, zsomme_C;
// ** End of declarations
// prend en compte la nouvelle echeance et calcul indiciation des tableaux
niter = Math.max(4, Math.trunc(3 * Math.exp(0.3 * Math.log(this.experienceValues.temps_elem()))));
nmid = Math.trunc(niter / 2. + 0.5);
CLogger.log('Method modelExecute: temps_elem = ' + this.experienceValues.temps_elem());
CLogger.log('Method modelExecute: Math.log( this.experienceValues.temps_elem() ) = ' + Math.log(this.experienceValues.temps_elem()));
CLogger.log('Method modelExecute: Math.exp( 0.3 * Math.log( this.experienceValues.temps_elem() ) ) = ' + Math.exp(0.3 * Math.log(this.experienceValues.temps_elem())));
CLogger.log('Method modelExecute: Math.trunc( 3 * Math.exp( 0.3 * Math.log( this.experienceValues.temps_elem() ) ) ) = ' + Math.trunc(3 * Math.exp(0.3 * Math.log(this.experienceValues.temps_elem()))));
CLogger.log('Method modelExecute: niter = ' + niter);
dt = this.experienceValues.temps_elem() / (niter);
CLogger.log('Method modelExecute: dt = ' + dt);
// remplit les tableaux des emissions de GES ou leurs concentration à partir des params de l'interface
// if (current_values.simulation_type==FIXED_CONCENTRATIONS){
CLogger.log('Method modelExecute: fixed_concentration = ' + this.simulationValues.fixed_concentration);
if (this.simulationValues.fixed_concentration) {
CLogger.log('Method modelExecute: Entering fixed_concentration');
// on remplit les tableaux de concentrations de GES entre 1 et indice_max
for (let t = 0; t <= this.experienceValues.indice_max(); t++) {
this.simulationValues.concentrations_coo_data.set(t, this.simulationValues.coo_concentr_value); // en ppm
zCO2 = this.simulationValues.coo_concentr_value;
forcage_serre_CO2 = this.calcul_forcage_serre_CO2(zCO2);
this.simulationValues.emissions_coo_data.set(t, 0.);
} // eo for
CLogger.log('Method modelExecute: zCO2 = ' + zCO2);
CLogger.log('Method modelExecute: concentrations_coo_data[1] = ' + this.simulationValues.concentrations_coo_data.get(1));
} // endif if (current_values.simulation_type==FIXED_CONCENTRATIONS){
else {
//endif if (current_values.simulation_type==FIXED_CONCENTRATIONS){
if (this.simulationValues.debranche_biologie) {
zpuit_bio = 0;
}
else {
zpuit_bio = this.simulationValues.puit_bio_value / 100.0;
}
if (this.simulationValues.debranche_ocean) {
zpuit_oce = 0;
B_ocean = 0;
}
else {
zpuit_oce = this.simulationValues.puit_oce_value / 100.0;
if (this.simulationValues.fixed_ocean) {
B_ocean = 0;
}
else {
B_ocean = CPhysicsConstants.b_ocean;
}
}
CLogger.log('Method modelExecute: zpuit_oce = ' + zpuit_oce);
CLogger.log('Method modelExecute: zpuit_bio = ' + zpuit_bio);
} // endif if (current_values.simulation_type==FIXED_CONCENTRATIONS){
// attribution de variables dans le cas où elles sont en mode fixé:
// les variables précédées de z sont celles qui sont calculées aussi bien dans les cas
// avec et sans rétroaction
CLogger.log('Method modelExecute: fixed_eau = ' + this.simulationValues.fixed_eau);
if (this.simulationValues.fixed_eau) {
forcage_serre_eau = this.calcul_forcage_serre_H2O(this.simulationValues.rapport_H2O_value / 100.0);
}
if (this.simulationValues.fixed_albedo) {
zalbedo = this.simulationValues.albedo_value / 100.; // conversion albedo en % en albedo en unité
for (let t = 0; t <= this.experienceValues.indice_max(); t++) {
this.simulationValues.albedo_data.set(t, this.simulationValues.albedo_value);
}
}
else {
this.simulationValues.albedo_data.set(0, this.calcul_albedo(this.simulationValues.niveau_calottes_data.get(0)) * 100.);
}
CLogger.log('Method modelExecute: puissance_recue_zero = ' + CPhysicsConstants.puissance_recue_zero);
CLogger.log('Method modelExecute: puissance_soleil_value = ' + this.simulationValues.puissance_soleil_value);
CLogger.log('Method modelExecute: distance_ts_value = ' + this.simulationValues.distance_ts_value);
CLogger.log('Method modelExecute: distance_ts_value = ' + this.simulationValues.distance_ts_value);
Fin0 = CPhysicsConstants.puissance_recue_zero * (this.simulationValues.puissance_soleil_value / 100.) / (this.simulationValues.distance_ts_value / 100) / (this.simulationValues.distance_ts_value / 100);
delta_angle = Math.abs(CPhysicsConstants.lat_Mil - this.simulationValues.obliquite_value) / 360 * 2 * CPhysicsConstants.pi;
insol65N = Fin0 * Math.cos(delta_angle) * Math.exp(2 * Math.log((1 - CPhysicsConstants.excentricite_actuel * 0.5 * Math.sin(-CPhysicsConstants.precession_actuel / 180 * Math.PI)) / (1 - (0.3 * this.simulationValues.excentricite_value + 0.7 * CPhysicsConstants.excentricite_actuel) * 0.5 * Math.sin(-this.simulationValues.precession_value / 180 * Math.PI))));
// on fait une bidouille pour réduire l'effet de l'excentricité.
CLogger.log('Method modelExecute: Fin0 = ' + Fin0);
CLogger.log('Method modelExecute: Fin0*cos(delta_angle) = ' + Fin0 * Math.cos(delta_angle));
CLogger.log('Method modelExecute: delta_angle_actuel = ' + this.modelPhysicsConstants.delta_angle_actuel);
CLogger.log('Method modelExecute: delta_angle = ' + delta_angle);
CLogger.log('Method modelExecute: puissance_recue_zero = ' + CPhysicsConstants.puissance_recue_zero);
CLogger.log('Method modelExecute: insol65N = ' + insol65N);
CLogger.log('Method modelExecute: insol_actuel = ' + this.modelPhysicsConstants.insol_actuel);
CLogger.log('Method modelExecute: G0 = ' + this.modelPhysicsConstants.G0);
CLogger.log('Method modelExecute: albedo_actuel = ' + this.modelPhysicsConstants.albedo_actuel);
CLogger.log('Method modelExecute: niveau_calottes_actuel = ' + this.modelPhysicsConstants.niveau_calottes_actuel);
CLogger.log('Method modelExecute: debugCR: excentricite_actuel=' + CPhysicsConstants.excentricite_actuel);
CLogger.log('Method modelExecute: debugCR: excentricite_value=' + this.simulationValues.excentricite_value);
CLogger.log('Method modelExecute: debugCR: precession_actuel=' + CPhysicsConstants.precession_actuel);
CLogger.log('Method modelExecute: debugCR: precession_value=' + this.simulationValues.precession_value);
CLogger.log('Method modelExecute: debugCR: numerateur=' + (1 - CPhysicsConstants.excentricite_actuel * 0.5 * Math.sin(-CPhysicsConstants.precession_actuel / 180 * Math.PI)));
CLogger.log('Method modelExecute: debugCR: denominateur=' + (1 - (0.3 * this.simulationValues.excentricite_value + 0.7 * CPhysicsConstants.excentricite_actuel) * 0.5 * Math.sin(-this.simulationValues.precession_value / 180 * Math.PI)));
CLogger.log('Method modelExecute: debugCR: num/denom=' + (1 - CPhysicsConstants.excentricite_actuel * 0.5 * Math.sin(-CPhysicsConstants.precession_actuel / 180 * Math.PI)) / (1 - (0.3 * this.simulationValues.excentricite_value + 0.7 * CPhysicsConstants.excentricite_actuel) * 0.5 * Math.sin(-this.simulationValues.precession_value / 180 * Math.PI)));
CLogger.log('Method modelExecute: debugCR: facteur=' + Math.exp(2 * Math.log((1 - CPhysicsConstants.excentricite_actuel * 0.5 * Math.sin(-CPhysicsConstants.precession_actuel / 180 * Math.PI)) / (1 - (0.3 * this.simulationValues.excentricite_value + 0.7 * CPhysicsConstants.excentricite_actuel) * 0.5 * Math.sin(-this.simulationValues.precession_value / 180 * Math.PI)))));
// mettons toutes les températures de indice_min à 0 en K:
for (let t = 1; t <= this.experienceValues.indice_max(); t++) {
this.simulationValues.temperature_data.set_past(t, this.simulationValues.temperature_data.get_past(t) + CPhysicsConstants.Tkelvin);
}
this.simulationValues.temperature_data.set(0, this.simulationValues.temperature_data.get(0) + CPhysicsConstants.Tkelvin);
// mettons les albédo entre 0 et 1
// variables nécessaires pour intégration temporelle:
zT_ancien = this.simulationValues.temperature_data.get(0);
zT_ancien_prec = zT_ancien;
zCO2_ancien = this.simulationValues.concentrations_coo_data.get(0);
zCO2_ancien_prec = zCO2_ancien;
zphig_ancien = this.simulationValues.niveau_calottes_data.get(0);
// ajout CR 19 decembre 2019
// on vérifie les températures passées:
for (let t = 1; t <= this.experienceValues.indice_max(); t++) {
CLogger.log('verif past temperatures: t=' + t + '; T' + this.simulationValues.temperature_data.get_past(t));
}
// intégration temporelle
for (let t = 1; t <= this.experienceValues.indice_max(); t++) {
CLogger.log('Method modelExecute: **** boucle d\'integration, t = ' + t);
oscillation = 0;
CLogger.log('Method modelExecute: s.temperature_data[t-1] = ' + this.simulationValues.temperature_data.get(t - 1));
CLogger.log('Method modelExecute: zT_ancien = ' + zT_ancien);
zT_moy1 = 0.;
zCO2_moy1 = 0.;
zphig_moy1 = 0.;
zT_moy2 = 0.;
zCO2_moy2 = 0.;
zphig_moy2 = 0.;
for (let iter = 1; iter <= niter; iter++) {
CLogger.log('Method modelExecute: **boucle d\'integration, iter = ' + iter);
if (!this.simulationValues.fixed_concentration) {
// calculs des flux de CO2
CLogger.log('Method modelExecute: zphig_ancien = ' + zphig_ancien);
alteration_max = this.modelPhysicsConstants.C_alteration_naturel * (this.simulationValues.alteration_value / 100.);
zC_alteration = this.calcul_zC_alteration(alteration_max, zphig_ancien);
CLogger.log('Method modelExecute: zC_alteration = ' + zC_alteration);
this.assert(zC_alteration <= 0);
zC_stockage = this.calcul_zC_alteration(-this.simulationValues.stockage_biologique_value * 1e-3, zphig_ancien);
CLogger.log('Method modelExecute: zC_stockage = ' + zC_stockage);
this.assert(zC_stockage <= 0);
Fdegaz = 0.;
zB_ocean = this.calcul_zC_alteration(B_ocean, zphig_ancien);
if ((!this.simulationValues.debranche_ocean) && (!this.simulationValues.fixed_ocean)) {
zpuit_oce = this.calcul_zpuit_oce(zT_ancien);
this.assert(zpuit_oce >= 0.);
this.assert(zpuit_oce <= CPhysicsConstants.puit_oce_max);
Fdegaz = this.calcul_Fdegaz(zT_ancien);
}
CLogger.log('Method modelExecute: zB_ocean = ' + zB_ocean);
CLogger.log('Method modelExecute: zpuit_oce = ' + zpuit_oce);
CLogger.log('Method modelExecute: zpuit_bio = ' + zpuit_bio);
CLogger.log('Method modelExecute: Fdegaz = ' + Fdegaz);
CLogger.log('Method modelExecute: zCO2_ancien = ' + zCO2_ancien);
// ** calculs des emissions en Gt/an
CLogger.log('Method modelExecute: s.emit_anthro_coo_value = ' + this.simulationValues.emit_anthro_coo_value);
CLogger.log('Method modelExecute: s.volcan_value = ' + this.simulationValues.volcan_value);
CLogger.log('Method modelExecute: zC_alteration * zCO2_ancien = ' + zC_alteration * zCO2_ancien);
CLogger.log('Method modelExecute: zC_stockage * zCO2_ancien = ' + zC_stockage * zCO2_ancien);
CLogger.log('Method modelExecute: zpuit_oce = ' + zpuit_oce);
zCO2eq_oce = this.calcul_zCO2eq(zT_ancien);
CLogger.log('Method modelExecute: zCO2eq_oce = ' + zCO2eq_oce);
// attention, on met des min et max pour éviter les pbs.
zsomme_flux_const = Math.max(Math.min(1.0 - zpuit_oce - zpuit_bio, 1.0), 0.0) * (this.simulationValues.emit_anthro_coo_value + this.simulationValues.volcan_value) + Math.max(Math.min(1 - zpuit_bio, 1.0), 0.0) * zB_ocean * zCO2eq_oce + Fdegaz;
zsomme_C = Math.max(Math.min(1 - zpuit_oce - zpuit_bio, 1.0), 0.0) * (zC_alteration + zC_stockage) - Math.max(Math.min(1 - zpuit_bio, 1.0), 0.0) * zB_ocean;
CLogger.log('Method modelExecute: zsomme_flux_const = ' + zsomme_flux_const);
CLogger.log('Method modelExecute: zsomme_C = ' + zsomme_C);
this.assert(zsomme_flux_const >= 0);
this.assert(zsomme_C <= 0);
zsomme_flux = zsomme_flux_const + zCO2_ancien * zsomme_C;
CLogger.log('Method modelExecute: zsomme_flux = ' + zsomme_flux);
if (CPhysicsConstants.calcul_carbone == 1) {
// ** calcul concentration en CO2
CLogger.log('Method modelExecute: méthode Euler');
emission_coo_ppm = zsomme_flux * (CPhysicsConstants.concentration_coo_2007 / CPhysicsConstants.coo_Gt_2007); //en ppm/an // modif mars 2022 dans le facteur de conversion
CLogger.log('Method modelExecute: zCO2_ancien = ' + zCO2_ancien);
CLogger.log('Method modelExecute: emission_coo_ppm = ' + emission_coo_ppm);
CLogger.log('Method modelExecute: dt = ' + dt);
zCO2 = zCO2_ancien + emission_coo_ppm * dt;
zCO2 = Math.max(0.0, zCO2);
CLogger.log('Method modelExecute: zCO2 = ' + zCO2);
}
else if (CPhysicsConstants.calcul_carbone == 2) {
//** calcul par zCO2eq: méthode directe:
if (zsomme_C > 0) {
CLogger.log('Method modelExecute: méthode equilibre: cas general');
zCO2eq = -zsomme_flux_const / zsomme_C;
tau_CO2_eq = -1. / zsomme_C;
CLogger.log('Method modelExecute: zCO2eq = ' + zCO2eq);
CLogger.log('Method modelExecute: tau_CO2_eq = ' + tau_CO2_eq);
zCO2 = this.calculT(zCO2eq, zCO2_ancien, tau_CO2_eq, dt);
this.assert(zCO2 >= 0.);
CLogger.log('Method modelExecute: zCO2 = ' + zCO2);
}
else {
CLogger.log('Method modelExecute: méthode equilibre: cas zsomme_C>O');
CLogger.log('Method modelExecute: emission_coo_ppm = ' + emission_coo_ppm);
emission_coo_ppm = zsomme_flux_const * (CPhysicsConstants.concentration_coo_2007 / CPhysicsConstants.coo_Gt_2007); // modif mars 2022 dans le facteur de conversion
zCO2 = zCO2_ancien + emission_coo_ppm * dt;
this.assert(zCO2 >= 0.);
CLogger.log('Method modelExecute: zCO2 = ' + zCO2);
}
}
// **calcul de l'effet de serre en t
CLogger.log('Method modelExecute: calcul de l\'effet de serre');
forcage_serre_CO2 = this.calcul_forcage_serre_CO2(zCO2);
} //if (current_values.simulation_type==FIXED_EMISSIONS) {
if (!this.simulationValues.fixed_eau) {
zrapport_H2O = this.calcul_rapport_H2O(zT_ancien);
forcage_serre_eau = this.calcul_forcage_serre_H2O(zrapport_H2O);
}
forcage_serre = forcage_serre_CO2 + forcage_serre_eau;
G = this.modelPhysicsConstants.G0 - forcage_serre;
if (G < CPhysicsConstants.G_min) {
G = CPhysicsConstants.G_min;
}
if (G > 1) {
G = 1;
}
CLogger.log('Method modelExecute: forcage_serre = ' + forcage_serre);
CLogger.log('Method modelExecute: G = ' + G);
//** calcul de la latitude de glace
phieq = this.calcul_phieq(zT_ancien, insol65N);
CLogger.log('Method modelExecute: calcul_phig: zphig_ancien = ' + zphig_ancien);
tau_niveau_calottes = this.calcul_tau_niveau_calottes(phieq, zphig_ancien);
CLogger.log('Method modelExecute: calcul_phig: dt = ' + dt);
// Calcul de zphig
zphig = this.calculT(phieq, zphig_ancien, tau_niveau_calottes, dt);
zphig = Math.min(Math.max(CPhysicsConstants.niveau_calottes_min, zphig), CPhysicsConstants.niveau_calottes_max);
CLogger.log('Method modelExecute: calcul_phig: zphig = ' + zphig);
CLogger.log('Method modelExecute: zphig = ' + zphig);
//** calcul de l'albédo
CLogger.log('Method modelExecute: fixed_albedo = ' + this.simulationValues.fixed_albedo);
if (!this.simulationValues.fixed_albedo) {
CLogger.log('Method modelExecute: calcul_albedo: albedo_ter = ' + CPhysicsConstants.albedo_ter);
zalbedo = this.calcul_albedo(zphig);
}
CLogger.log('Method modelExecute: zalbedo = ' + zalbedo);
//** déduction de la température
//Teq=exp(0.25*log(Fin0*(1-zalbedo)/G/sigma));
//zT=Teq;
//zT=calculT(Teq,temperature_data[t-1],tau_temperature,temps_elem);
Fin = Fin0 * (1 - zalbedo);
Fout = G * CPhysicsConstants.sigma * Math.exp(4 * Math.log(zT_ancien));
CLogger.log('Method modelExecute: zT_ancien = ' + zT_ancien.toFixed(8));
CLogger.log('Method modelExecute: Fin = ' + Fin.toFixed(8));
CLogger.log('Method modelExecute: Fout = ' + Fout.toFixed(8));
//zT=zT_ancien+min(max(capacite_calorifique*(Fin-Fout)*dt,-100.),100.);
zTeq = Math.exp(0.25 * Math.log(Fin / (G * CPhysicsConstants.sigma)));
CLogger.log('Method modelExecute: zTeq = ' + zTeq.toFixed(8));
zT = this.calculT(zTeq, zT_ancien, CPhysicsConstants.tau_temperature, dt);
zT = Math.max(0.0, Math.min(1e6, zT));
CLogger.log('Method modelExecute: dT = ' + (CPhysicsConstants.capacite_calorifique * (Fin - Fout) * dt).toFixed(8));
CLogger.log('Method modelExecute: zT = ' + zT.toFixed(8));
CLogger.log('Method modelExecute: zT_ancien = ' + zT_ancien.toFixed(8));
CLogger.log('Method modelExecute: zT_ancien_prec = ' + zT_ancien_prec.toFixed(8));
// fin des calculs
if ((iter >= 3) && (oscillation == 0)) {
// if ( zT_ancien < zT_ancien_prec -1e-5 )
// modif CR 19 dec 2019 pour éviter de détecter des oscillations à cause d'erreurs numériques
// on rajoute marge de 1e-5
if (zT_ancien < zT_ancien_prec - 1e-5) {
if (zT > zT_ancien + 1e-5) {
oscillation = 1;
}
}
else if (zT_ancien > zT_ancien_prec + 1e-5) {
if (zT < zT_ancien - 1e-5) {
oscillation = 1;
}
}
}
if (!this.simulationValues.fixed_concentration) {
CLogger.log('Method modelExecute: test oscillation: zCO2 = ' + zCO2);
CLogger.log('Method modelExecute: test oscillation: zCO2_ancien = ' + zCO2_ancien);
CLogger.log('Method modelExecute: test oscillation: zCO2_ancien_prec = ' + zCO2_ancien_prec);
if ((iter >= 3) && (oscillation == 0)) {
// modif CR 19 dec 2019 pour éviter de détecter des oscillations à cause d'erreurs numériques
// on rajoute marge de 1e-5
if (zCO2_ancien < zCO2_ancien_prec - 1e-5) {
if (zCO2 > zCO2_ancien + 1e-5) {
CLogger.log('Method modelExecute: cas 1 d\'oscillation en CO2');
oscillation = 1;
}
}
else if (zCO2_ancien > zCO2_ancien_prec + 1e-5) {
if (zCO2 < zCO2_ancien - 1e-5) {
CLogger.log('Method modelExecute: cas 2 d\'oscillation en CO2');
oscillation = 1;
}
}
}
} // if (current_values.simulation_type==FIXED_EMISSIONS) {
CLogger.log('Method modelExecute: oscillation = ' + oscillation);
if (oscillation == 1) {
zT = (zT + zT_ancien + 0.5 * zT_ancien_prec) / 2.5;
// if (current_values.simulation_type==FIXED_EMISSIONS) {
if (!this.simulationValues.fixed_concentration) {
zCO2 = (zCO2 + zCO2_ancien + 0.5 * zCO2_ancien_prec) / 2.5;
}
zphig = (zphig + zphig_ancien + 0.5 * zphig_ancien_prec) / 2.5;
}
zCO2_ancien_prec = zCO2_ancien;
zT_ancien_prec = zT_ancien;
zphig_ancien_prec = zphig_ancien;
zT_ancien = zT;
zCO2_ancien = zCO2;
zphig_ancien = zphig;
} // for (int iter=1;iter<=niter;iter++) {
this.simulationValues.temperature_data.set(t, zT);
CLogger.log('Method modelExecute: s.temperature_data[t] = ' + this.simulationValues.temperature_data.get(t));
CLogger.log('Method modelExecute: fin de la sous boucle, zT = ' + zT);
if (!this.simulationValues.fixed_concentration) {
CLogger.log('Method modelExecute: zCO2 = ' + zCO2);
this.simulationValues.concentrations_coo_data.set(t, zCO2);
// this.simulationValues.emissions_coo_data.set( t - 1, ( this.simulationValues.concentrations_coo_data.get( t ) - this.simulationValues.concentrations_coo_data.get( t - 1 ) ) / this.experienceValues.temps_elem() ); //en ppm/an /(concentration_coo_actuel/coo_Gt_act); // conversion en Gt/an
this.simulationValues.emissions_coo_data.set(t - 1, (this.simulationValues.concentrations_coo_data.get(t) - this.simulationValues.concentrations_coo_data.get(t - 1)) / this.experienceValues.temps_elem() / (CPhysicsConstants.concentration_coo_2007 / CPhysicsConstants.coo_Gt_2007)); //en Gt/an; modif mars 2022: conversion en Gt/an
CLogger.log('Method modelExecute: emissions_coo_data[t - 1] = ' + this.simulationValues.emissions_coo_data.get(t - 1));
CLogger.log('Method modelExecute: concentrations_coo_data[t] = ' + this.simulationValues.concentrations_coo_data.get(t));
}
CLogger.log('Method modelExecute: zphig = ' + zphig);
this.simulationValues.niveau_calottes_data.set(t, 90 - zphig);
CLogger.log('Method modelExecute: Niveau calottes = ' + (90 - zphig) + ' / ' + zphig);
zphig_moy = 0.0; // init ajoutée le 30 nov 2012 remise le 11jan2014
CLogger.log('Method modelExecute: zphig_moy = ' + zphig_moy);
if (!this.simulationValues.fixed_albedo) {
this.simulationValues.albedo_data.set(t, zalbedo * 100.);
CLogger.log('Method modelExecute: zalbedo = ' + zalbedo);
}
//** calcul niveau de la mer
this.simulationValues.niveau_mer_data.set(t, this.calcul_niveau_mer(90 - this.simulationValues.niveau_calottes_data.get(t), this.simulationValues.temperature_data.get(t), t));
CLogger.log('Method modelExecute: s.niveau_mer_data[t] = ' + this.simulationValues.niveau_mer_data.get(t));
} //for (int t=1;t<=indice_max;t++){
this.simulationValues.emissions_coo_data.set(this.experienceValues.indice_max(), this.simulationValues.emissions_coo_data.get(this.experienceValues.indice_max() - 1));
// met la température en °C
for (let t = 0; t <= this.experienceValues.indice_max(); t++) {
this.simulationValues.temperature_data.set(t, this.simulationValues.temperature_data.get(t) - CPhysicsConstants.Tkelvin);
// ajout affichage par CR 19 dec 2019
CLogger.log('verif temperatures: t=' + t + '; T' + this.simulationValues.temperature_data.get(t));
}
// met la température en °C
for (let t = 1; t <= this.experienceValues.indice_max(); t++) {
this.simulationValues.temperature_data.set_past(t, this.simulationValues.temperature_data.get_past(t) - CPhysicsConstants.Tkelvin);