@open3cl/engine
Version:
Open Source 3CL-DPE engine
440 lines (395 loc) • 14.7 kB
JavaScript
import { inject } from 'dioma';
import { DeperditionService } from '../deperdition.service.js';
import { logger } from '../../../../../core/util/logger/log-service.js';
import { compareReferences } from '../../../../../utils.js';
import { DeperditionMurService } from '../mur/deperdition-mur.service.js';
import { PontThermiqueTvStore } from '../../../../dpe/infrastructure/enveloppe/pontThermiqueTv.store.js';
import enums from '../../../../../enums.js';
import { DeperditionPlancherHautService } from '../plancher_haut/deperdition-plancher-haut.service.js';
import { DeperditionPlancherBasService } from '../plancher_bas/deperdition-plancher-bas.service.js';
/**
* Calcul des déperditions des ponts thermiques
* Chapitre 3.4 Calcul des déperditions par les ponts thermiques
*
* Méthode de calcul 3CL-DPE 2021
* Octobre 2021
* @see consolide_anne…arrete_du_31_03_2021_relatif_aux_methodes_et_procedures_applicables.pdf
*
* Si le coefficient U des portes est connu et justifié, le saisir directement. Sinon, prendre les valeurs tabulées
*/
export class DeperditionPontThermiqueService extends DeperditionService {
/**
* @type {DeperditionMurService}
*/
#deperditionMurService;
/**
* @type {DeperditionPlancherHautService}
*/
#deperditionPlancherHautService;
/**
* @type {DeperditionPlancherBasService}
*/
#deperditionPlancherBasService;
/**
* @param tvStore {PontThermiqueTvStore}
* @param deperditionMurService {DeperditionMurService}
* @param deperditionPlancherHautService {DeperditionPlancherHautService}
* @param deperditionPlancherBasService {DeperditionPlancherBasService}
*/
constructor(
tvStore = inject(PontThermiqueTvStore),
deperditionMurService = inject(DeperditionMurService),
deperditionPlancherHautService = inject(DeperditionPlancherHautService),
deperditionPlancherBasService = inject(DeperditionPlancherBasService)
) {
super(tvStore);
this.#deperditionMurService = deperditionMurService;
this.#deperditionPlancherHautService = deperditionPlancherHautService;
this.#deperditionPlancherBasService = deperditionPlancherBasService;
}
/**
* @param ctx {Contexte}
* @param enveloppe {Enveloppe}
* @param pontThermiqueDE {PontThermiqueDE}
* @return {PontThermiqueDI}
*/
execute(ctx, enveloppe, pontThermiqueDE) {
/** @type {PontThermiqueDI} */
const di = {
k: undefined
};
if ([2, 3].includes(parseInt(pontThermiqueDE.enum_methode_saisie_pont_thermique_id))) {
// valeur justifiée saisie à partir des documents justificatifs autorisés
// saisie direct k depuis rset/rsee( etude rt2012/re2020)
di.k = pontThermiqueDE.k_saisi;
if (!di.k) {
logger.error(`
Aucune valeur de k_saisi pour le pont thermique '${pontThermiqueDE.reference}' alors que la donnée est saisie
`);
}
} else {
// valeur forfaitaire
di.k = this.k(ctx, pontThermiqueDE, enveloppe);
}
if (di.k === undefined) {
logger.error(`
Aucune valeur k n'a été trouvée pour le pont thermique '${pontThermiqueDE.description}'.
`);
di.k = this.defaultValue(pontThermiqueDE);
}
return di;
}
/**
* Coefficient de transmission thermique du vitrage (W/(m².K))
*
* @param ctx {Contexte}
* @param pontThermiqueDE {PontThermiqueDE}
* @param enveloppe {Enveloppe}
* @return {number|undefined}
*/
k(ctx, pontThermiqueDE, enveloppe) {
if (!pontThermiqueDE.reference_1) {
logger.error(`
Impossible de trouver un mur ayant pour référence '${pontThermiqueDE.reference_1}' ou '${pontThermiqueDE.reference_2}'.
`);
return this.defaultValue(pontThermiqueDE);
}
const typeLiaison = parseInt(pontThermiqueDE.enum_type_liaison_id);
/**
* @type {MurDE|undefined}
*/
const mur = this.mur(pontThermiqueDE, enveloppe);
if (mur && !this.murHasPontThermique(mur, typeLiaison)) {
return 0;
}
const isolationMur = this.isolationMur(ctx, mur);
switch (typeLiaison) {
// 'plancher bas / mur'
case 1: {
return this.pontThermiquePlancherBasMur(ctx, pontThermiqueDE, enveloppe, isolationMur);
}
// 'plancher haut lourd / mur'
case 3: {
return this.pontThermiquePlancherHautMur(ctx, pontThermiqueDE, enveloppe, isolationMur);
}
// 'menuiserie / mur'
case 5: {
return this.pontThermiqueMenuiserieMur(pontThermiqueDE, enveloppe, isolationMur);
}
//'plancher intermédiaire lourd / mur'
// 'refend / mur'
case 2:
case 4: {
return this.tvStore.getKForMur(typeLiaison, enums.type_isolation[isolationMur]);
}
}
}
/**
* Calcul de l'isolation du mur
*
* @param ctx {Contexte}
* @param murDE {MurDE}
* @return {number}
*/
isolationMur(ctx, murDE) {
if (murDE) {
return this.#deperditionMurService.typeIsolation(ctx, murDE);
} else {
// Isolation ITI si le mur n'est pas défini
return 3;
}
}
/**
* Calcul du pont thermique 'plancher bas / mur'
*
* @param ctx {Contexte}
* @param pontThermiqueDE {PontThermiqueDE}
* @param enveloppe {Enveloppe}
* @param isolationMur {number}
* @return {number|undefined}
*/
pontThermiquePlancherBasMur(ctx, pontThermiqueDE, enveloppe, isolationMur) {
const plancherBasDE = this.plancherBas(pontThermiqueDE, enveloppe);
if (!plancherBasDE) {
logger.error(`
Impossible de trouver un plancher bas ayant pour référence '${pontThermiqueDE.reference_1}' ou '${pontThermiqueDE.reference_2}'.
`);
return this.defaultValue(pontThermiqueDE);
}
if (!this.plancherBasHasPontThermique(plancherBasDE)) {
return 0;
}
const isolationPlancher = this.#deperditionPlancherBasService.typeIsolation(ctx, plancherBasDE);
return this.tvStore.getKForPlancher(
1,
enums.type_isolation[isolationMur],
enums.type_isolation[isolationPlancher]
);
}
/**
Calcul du pont thermique 'plancher haut lourd / mur'
*
* @param ctx {Contexte}
* @param pontThermiqueDE {PontThermiqueDE}
* @param enveloppe {Enveloppe}
* @param isolationMur {number}
* @return {number|undefined}
*/
pontThermiquePlancherHautMur(ctx, pontThermiqueDE, enveloppe, isolationMur) {
const plancherHautDE = this.plancherHaut(pontThermiqueDE, enveloppe);
if (!plancherHautDE) {
logger.error(`
Impossible de trouver un plancher haut ayant pour référence '${pontThermiqueDE.reference_1}' ou '${pontThermiqueDE.reference_2}'.
`);
return this.defaultValue(pontThermiqueDE);
}
if (!this.plancherHautHasPontThermique(plancherHautDE)) {
return 0;
}
const isolationPlancher = this.#deperditionPlancherHautService.typeIsolation(
ctx,
plancherHautDE
);
return this.tvStore.getKForPlancher(
3,
enums.type_isolation[isolationMur],
enums.type_isolation[isolationPlancher]
);
}
/**
Calcul du pont thermique 'menuiserie / mur'
*
* @param pontThermiqueDE {PontThermiqueDE}
* @param enveloppe {Enveloppe}
* @param isolationMur {number}
* @return {number|undefined}
*/
pontThermiqueMenuiserieMur(pontThermiqueDE, enveloppe, isolationMur) {
const menuiserieDE = this.menuiserie(pontThermiqueDE, enveloppe);
if (!menuiserieDE) {
logger.error(`
Impossible de trouver une menuiserie ayant pour référence '${pontThermiqueDE.reference_1}' ou '${pontThermiqueDE.reference_2}'.
`);
return this.defaultValue(pontThermiqueDE);
}
if (parseInt(menuiserieDE.enum_type_vitrage_id) === 5) {
return 0;
}
let typePose = parseInt(menuiserieDE.enum_type_pose_id || 3);
// Pour les types sans objet
if (typePose === 4) {
typePose = 3;
}
const largeurDormant = menuiserieDE.largeur_dormant;
const presenceRetourIsolation = menuiserieDE.presence_retour_isolation;
return this.tvStore.getKForMenuiserie(
5,
enums.type_isolation[isolationMur],
typePose,
presenceRetourIsolation,
largeurDormant
);
}
/**
* Récupération du mur sur lequel se réfère ce pont thermique à partir des références
*
* @param pontThermiqueDE {PontThermiqueDE}
* @param enveloppe {Enveloppe}
* @return {MurDE|undefined}
*/
mur(pontThermiqueDE, enveloppe) {
return (enveloppe.mur_collection?.mur || []).find(
(mur) =>
compareReferences(mur.donnee_entree.reference, pontThermiqueDE.reference_1) ||
compareReferences(mur.donnee_entree.reference, pontThermiqueDE.reference_2)
)?.donnee_entree;
}
/**
* Récupération du plancher bas sur lequel se réfère ce pont thermique à partir des références
*
* @param pontThermiqueDE {PontThermiqueDE}
* @param enveloppe {Enveloppe}
* @return {PlancherBasDE|undefined}
*/
plancherBas(pontThermiqueDE, enveloppe) {
return (enveloppe.plancher_bas_collection?.plancher_bas || []).find(
(plancher) =>
compareReferences(plancher.donnee_entree.reference, pontThermiqueDE.reference_1) ||
compareReferences(plancher.donnee_entree.reference, pontThermiqueDE.reference_2)
)?.donnee_entree;
}
/**
* Récupération du plancher haut sur lequel se réfère ce pont thermique à partir des références
*
* @param pontThermiqueDE {PontThermiqueDE}
* @param enveloppe {Enveloppe}
* @return {PlancherHautDE|undefined}
*/
plancherHaut(pontThermiqueDE, enveloppe) {
return (enveloppe.plancher_haut_collection?.plancher_haut || []).find(
(plancher) =>
compareReferences(plancher.donnee_entree.reference, pontThermiqueDE.reference_1) ||
compareReferences(plancher.donnee_entree.reference, pontThermiqueDE.reference_2)
)?.donnee_entree;
}
/**
* Récupération de la menuiserie (baie vitrée ou porte) sur laquelle se réfère ce pont thermique
*
* @param pontThermiqueDE {PontThermiqueDE}
* @param enveloppe {Enveloppe}
* @return {BaieVitreeDE|PorteDE|undefined}
*/
menuiserie(pontThermiqueDE, enveloppe) {
return (enveloppe.baie_vitree_collection?.baie_vitree || [])
.concat(enveloppe.porte_collection?.porte || [])
.find(
(menuiserie) =>
compareReferences(menuiserie.donnee_entree.reference, pontThermiqueDE.reference_1) ||
compareReferences(menuiserie.donnee_entree.reference, pontThermiqueDE.reference_2)
)?.donnee_entree;
}
/**
* Retourne true si le mur est concerné par un pont thermique
* @param murDE {MurDE}
* @param typeLiaison {number}
*/
murHasPontThermique(murDE, typeLiaison) {
/**
* 3.4 Calcul des déperditions par les ponts thermiques
* Les ponts thermiques des parois au niveau des circulations communes ne sont pas pris en compte.
* 14 - Circulation sans ouverture directe sur l'extérieur
* 15 - Circulation avec ouverture directe sur l'extérieur
* 16 - Circulation avec bouche ou gaine de désenfumage ouverte en permanence
* 17 - Hall d'entrée avec dispositif de fermeture automatique
* 18 - Hall d'entrée sans dispositif de fermeture automatique
* 22 - Local non déperditif ( local à usage d'habitation chauffé)
*/
// @todo vérifier la liste
if ([14, 15, 16, 17, 18, 22].includes(parseInt(murDE.enum_type_adjacence_id))) {
return false;
}
/**
* 3.4.1 Mur Plancher bas / mur
* 3.4.3 Plancher haut / mur
*
* Seuls les murs et planchers bas constitués d’un matériau lourd (béton, brique, …) sont considérés ici. Pour les autres
* cas ce pont thermique est pris nul.
*
* 5 - Murs en pan de bois sans remplissage tout venant
* 6 - Murs en pan de bois avec remplissage tout venant
* 7 - Murs bois (rondin)
* 16 - Béton cellulaire avant 2013
* 18 - Murs en ossature bois avec isolant en remplissage ≥ 2006
* 24 - Murs en ossature bois avec isolant en remplissage 2001-2005
* 25 - Murs en ossature bois sans remplissage
* 26 - Murs en ossature bois avec isolant en remplissage <2001
* 27 - Murs en ossature bois avec remplissage tout venant
*/
if (typeLiaison === 1 || typeLiaison === 3) {
return ![5, 6, 7, 16, 18, 24, 25, 26, 27].includes(
parseInt(murDE.enum_materiaux_structure_mur_id)
);
}
/**
* 3.4.5 Menuiserie / mur
* Les ponts thermiques avec les parois en structure bois (ossature bois, rondin de bois, pans de bois) sont négligés.
* enum_materiaux_structure_mur_id
*
* 5 - Murs en pan de bois sans remplissage tout venant
* 6 - Murs en pan de bois avec remplissage tout venant
* 7 - Murs bois (rondin)
* 18 - Murs en ossature bois avec isolant en remplissage ≥ 2006
* 24 - Murs en ossature bois avec isolant en remplissage 2001-2005
* 25 - Murs en ossature bois sans remplissage
* 26 - Murs en ossature bois avec isolant en remplissage <2001
* 27 - Murs en ossature bois avec remplissage tout venant
*/
if (typeLiaison === 4) {
return ![5, 6, 7, 18, 24, 25, 26, 27].includes(
parseInt(murDE.enum_materiaux_structure_mur_id)
);
}
return true;
}
/**
* Retourne true si le plancher haut est concerné par un pont thermique
* @param plancherHautDE {PlancherHautDE}
* @return {boolean}
*/
plancherHautHasPontThermique(plancherHautDE) {
/**
* 3.4.3 Plancher haut / mur
*
* Les ponts thermiques des planchers haut en structure légère sont négligés.
* type_plancher_haut
* 9 - Plafond bois sur solives bois
* 10 - Plafond bois sous solives bois
*/
// @todo d'autres type de plancher haut ?
return ![9, 10].includes(parseInt(plancherHautDE.enum_type_plancher_haut_id));
}
/**
* Retourne true si le plancher bas est concerné par un pont thermique
*
* @param plancherBasDE {PlancherBasDE}
*/
plancherBasHasPontThermique(plancherBasDE) {
/**
* 3.4.3 Plancher haut / mur
*
* Seuls les planchers bas constitués d’un matériau lourd (béton, brique, …) sont considérés ici. Pour les autres
* cas ce pont thermique est pris nul.
* 4 - Plancher entre solives bois avec ou sans remplissage
* 10 - Plancher bois sur solives bois
*/
// @todo d'autres type de plancher bas ?
return ![4, 10].includes(parseInt(plancherBasDE.enum_type_plancher_bas_id));
}
/**
*
* @param ptDE {PontThermiqueDE}
*/
defaultValue(ptDE) {
return this.tvStore.getKForMurById(ptDE.tv_pont_thermique_id);
}
}