Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/3.2.1_mur.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,17 @@ function calc_umur0(di, de, du) {
}
}

// Si présence d'un doublage
if (type_doublage > 2) {
/**
* Le doublage NE doit PAS être cumulé à une isolation ITE ou ITI.
* Il doit uniquement être pris en compte en l'absence d'isolation ITE/ITI (ex: ITR seule, non isolé, inconnu).
* Types avec ITE ou ITI : 3 (iti), 4 (ite), 6 (iti+ite), 7 (iti+itr), 8 (ite+itr)
* @see https://github.com/Open3CL/engine/issues/146
*/
const type_isolation = parseInt(de.enum_type_isolation_id) || 1;
const hasIteOrIti = [3, 4, 6, 7, 8].includes(type_isolation);

// Si présence d'un doublage et pas d'isolation ITE/ITI
if (type_doublage > 2 && !hasIteOrIti) {
let umur0Doublage;

// 3 - doublage indéterminé ou lame d'air inf 15 mm
Expand Down
98 changes: 98 additions & 0 deletions src/3.2.1_mur.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,102 @@ describe('Recherche de bugs dans le calcul de déperdition des murs', () => {
expect(mur.donnee_intermediaire.umur).toBe(2.5);
expect(mur.donnee_intermediaire.umur0).toBe(2.5);
});

/**
* @see https://github.com/Open3CL/engine/issues/146
* Le doublage NE doit PAS être cumulé à une isolation ITE ou ITI.
*/
describe('[MURS] Doublage non cumulé à une isolation ITE/ITI (#146)', () => {
const baseDE = {
enum_type_adjacence_id: '1', // Paroi sur l'extérieur (b=1)
enum_materiaux_structure_mur_id: '11', // Béton ≤20 cm
epaisseur_structure: 20,
enum_methode_saisie_u0_id: '2',
paroi_ancienne: 0
};

test('doublage avec ITI : le doublage ne doit pas être pris en compte dans Umur0', () => {
const zc = 3; // H2a
const pc_id = 6;
const ej = 0;
// Mur béton 20 cm (umur0 ~ 2.5), avec doublage connu (type 5) ET isolation ITI (type 3)
const mur = {
donnee_entree: {
...baseDE,
description: 'Mur béton avec doublage et ITI',
enum_methode_saisie_u_id: '3', // épaisseur isolation saisie
epaisseur_isolation: 10, // 10 cm
enum_type_doublage_id: '5', // doublage connu (plâtre brique bois)
enum_type_isolation_id: '3' // ITI
},
donnee_intermediaire: {}
};
calc_mur(mur, zc, pc_id, ej);

// Sans doublage cumulé, umur0 = 2.5 (valeur brute du mur béton ≤20cm)
// Avec doublage cumulé à tort : umur0 = 1 / (1/2.5 + 0.21) ≈ 1.724
expect(mur.donnee_intermediaire.umur0).toBeCloseTo(2.5, 2);
});

test('doublage avec ITE : le doublage ne doit pas être pris en compte dans Umur0', () => {
const zc = 3;
const pc_id = 6;
const ej = 0;
const mur = {
donnee_entree: {
...baseDE,
description: 'Mur béton avec doublage et ITE',
enum_methode_saisie_u_id: '3',
epaisseur_isolation: 8,
enum_type_doublage_id: '4', // doublage indéterminé lame d'air sup 15mm
enum_type_isolation_id: '4' // ITE
},
donnee_intermediaire: {}
};
calc_mur(mur, zc, pc_id, ej);

// umur0 = 2.5 (béton ≤20cm, doublage ignoré car ITE présent)
expect(mur.donnee_intermediaire.umur0).toBeCloseTo(2.5, 2);
});

test('doublage avec ITR seule : le doublage DOIT être pris en compte dans Umur0', () => {
const zc = 3;
const pc_id = 6;
const ej = 0;
const mur = {
donnee_entree: {
...baseDE,
description: 'Mur béton avec doublage et ITR',
enum_methode_saisie_u_id: '1', // non isolé
enum_type_doublage_id: '5', // doublage connu
enum_type_isolation_id: '5' // ITR
},
donnee_intermediaire: {}
};
calc_mur(mur, zc, pc_id, ej);

// ITR seule → le doublage est pris en compte : umur0 < 2.5
expect(mur.donnee_intermediaire.umur0).toBeLessThan(2.5);
});

test('doublage sans isolation : le doublage DOIT être pris en compte dans Umur0', () => {
const zc = 3;
const pc_id = 6;
const ej = 0;
const mur = {
donnee_entree: {
...baseDE,
description: 'Mur béton avec doublage sans isolation',
enum_methode_saisie_u_id: '1', // non isolé
enum_type_doublage_id: '5',
enum_type_isolation_id: '2' // non isolé
},
donnee_intermediaire: {}
};
calc_mur(mur, zc, pc_id, ej);

// Non isolé → doublage pris en compte : umur0 < umur0_nu_brut (le doublage réduit bien la valeur)
expect(mur.donnee_intermediaire.umur0).toBeLessThan(2.5);
});
});
});
35 changes: 22 additions & 13 deletions src/features/engine/domain/enveloppe/mur/deperdition-mur.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,29 @@ export class DeperditionMurService extends DeperditionService {
}

/**
* Pour l’ensemble des parois, la présence d’un doublage apporte une résistance thermique supplémentaire
* Pour l’ensemble des parois, la présence d’un doublage apporte une résistance thermique supplémentaire.
* Cependant, lorsqu'une isolation ITE ou ITI est présente, le doublage NE doit PAS être cumulé.
* Le doublage n'est pris en compte que si aucune isolation ITE/ITI n'est appliquée.
* Types d'isolation avec ITE ou ITI : 3 (iti), 4 (ite), 6 (iti+ite), 7 (iti+itr), 8 (ite+itr)
* @see https://github.com/Open3CL/engine/issues/146
*/
switch (murDE.enum_type_doublage_id) {
case '3':
// doublage indéterminé ou lame d'air inf 15 mm
umur0 = 1 / (1 / umur0 + 0.1);
break;
case '4': // doublage indéterminé ou lame d'air sup 15 mm
case '5': // doublage connu (plâtre brique bois)
umur0 = 1 / (1 / umur0 + 0.21);
break;
default:
// absence de doublage ou inconnu
break;
const typeIsolation = parseInt(murDE.enum_type_isolation_id) || 1;
const hasIteOrIti = [3, 4, 6, 7, 8].includes(typeIsolation);

if (!hasIteOrIti) {
switch (murDE.enum_type_doublage_id) {
case '3':
// doublage indéterminé ou lame d'air inf 15 mm
umur0 = 1 / (1 / umur0 + 0.1);
break;
case '4': // doublage indéterminé ou lame d'air sup 15 mm
case '5': // doublage connu (plâtre brique bois)
umur0 = 1 / (1 / umur0 + 0.21);
break;
default:
// absence de doublage ou inconnu
break;
}
}

/**
Expand Down
Loading