diff --git a/src/structure/rectangular_structure_params.ts b/src/structure/rectangular_structure_params.ts
index 61b11480dc80038362d1b2055d3b528921f53a81..549a83ba42175fa44dd9b5865cbac7bcbac69a5e 100644
--- a/src/structure/rectangular_structure_params.ts
+++ b/src/structure/rectangular_structure_params.ts
@@ -1,4 +1,4 @@
-import { ParamCalculability, ParamDefinition, ParamDomainValue, ParamsEquation } from "../param";
+import { ParamDefinition, ParamDomainValue } from "../param";
 import { Structure } from "./structure";
 import { StructureParams } from "./structure_params";
 
diff --git a/src/structure/structure_kivi.ts b/src/structure/structure_kivi.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2d2be5ecbba10a7bb8dba52eacd1bc391441452a
--- /dev/null
+++ b/src/structure/structure_kivi.ts
@@ -0,0 +1,76 @@
+import { ParamCalculability } from "../param";
+import { Message, MessageCode } from "../util/message";
+import { Result } from "../util/result";
+import { Structure, StructureFlowMode, StructureFlowRegime } from "./structure";
+import { StructureKiviParams } from "./structure_kivi_params";
+import { Villemonte } from "./villemonte";
+
+export class StructureKivi extends Structure {
+
+    constructor(prms: StructureKiviParams, dbg: boolean = false) {
+        super(prms, dbg);
+    }
+
+    /**
+     * paramètres castés au bon type
+     */
+    get prms(): StructureKiviParams {
+        return this._prms as StructureKiviParams;
+    }
+
+    public Equation(sVarCalc: string): Result {
+        Structure.CheckEquation(sVarCalc);
+        const res: Result = new Result(undefined, this.getResultData());
+
+        // p : pelle
+        let p: number = this.prms.ZDV.v - this.prms.ZRAM.v;
+        let h1p: number;
+
+        if (p < 0.1) {
+            // - p ne doit pas être inférieur à 0,10 m  (Norme NF X10-311-1983)
+            res.result.addMessage(new Message(MessageCode.WARNING_STRUCTUREKIVI_PELLE_TROP_FAIBLE));
+            h1p = 0;
+        } else {
+            h1p = this.prms.h1.v / p;
+            if (h1p > 2.5) {
+                // - h/p ne doit pas être supérieur à 2,5 (Norme NF X10-311-1983)
+                res.result.addMessage(new Message(MessageCode.WARNING_STRUCTUREKIVI_HP_TROP_ELEVE));
+                h1p = 2.5;
+            }
+        }
+        const cd: number = this.prms.alpha.v + this.prms.beta.v * h1p;
+
+        let Q = cd * this.prms.L.v * Structure.R2G * Math.pow(this.prms.h1.v, 1.5);
+
+        if (res.extraResults.FlowRegime === StructureFlowRegime.SUBMERGED) {
+            Q = Villemonte(this.prms.h1.v, this.prms.h2.v, 1.5) * Q;
+        }
+
+        res.result.vCalc = Q;
+        return res;
+
+    }
+
+    protected getFlowRegime(): StructureFlowRegime {
+        if (this.prms.h2.v > 0) {
+            return StructureFlowRegime.SUBMERGED;
+        } else {
+            return StructureFlowRegime.FREE;
+        }
+    }
+
+    protected getFlowMode(): StructureFlowMode {
+        return StructureFlowMode.WEIR;
+    }
+
+    /**
+     * paramétrage de la calculabilité des paramètres
+     */
+    protected setParametersCalculability() {
+        super.setParametersCalculability();
+        this.prms.L.calculability = ParamCalculability.DICHO;
+        this.prms.alpha.calculability = ParamCalculability.DICHO;
+        this.prms.beta.calculability = ParamCalculability.FREE;
+        this.prms.ZRAM.calculability = ParamCalculability.FREE;
+    }
+}
diff --git a/src/structure/structure_kivi_params.ts b/src/structure/structure_kivi_params.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3072f5f062953dc2ad11542e73d08634a9ba628f
--- /dev/null
+++ b/src/structure/structure_kivi_params.ts
@@ -0,0 +1,41 @@
+import { ParamDefinition, ParamDomainValue } from "../param";
+import { StructureParams } from "./structure_params";
+
+/**
+ * Paramètres pour une équation de seuil rectangulaire Kindsvater-Carter & Villemonte (KIVI)
+ */
+export class StructureKiviParams extends StructureParams {
+
+    /** Largeur du seuil (m) */
+    public L: ParamDefinition;
+
+    /** Coefficient alpha de la formule de Kindsvater */
+    public alpha: ParamDefinition;
+
+    /** Coefficient béta de la formule de Kindsvater */
+    public beta: ParamDefinition;
+
+    /** Cote du radier amont */
+    public ZRAM: ParamDefinition;
+
+    constructor(
+        rQ: number,
+        rZDV: number,
+        rZ1: number,
+        rZ2: number,
+        rL: number,
+        rAlpha: number,
+        rBeta: number,
+        rZRAM: number
+    ) {
+        super(rQ, rZDV, rZ1, rZ2, Infinity);
+        this.L = new ParamDefinition("L", ParamDomainValue.POS_NULL, rL);
+        this.addParamDefinition(this.L);
+        this.alpha = new ParamDefinition("alpha", ParamDomainValue.POS, rAlpha);
+        this.addParamDefinition(this.alpha);
+        this.beta = new ParamDefinition("beta", ParamDomainValue.POS, rBeta);
+        this.addParamDefinition(this.beta);
+        this.ZRAM = new ParamDefinition("ZRAM", ParamDomainValue.POS, rZRAM);
+        this.addParamDefinition(this.ZRAM);
+    }
+}
diff --git a/src/structure/villemonte.ts b/src/structure/villemonte.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c2fdf090eb804fb167e3b52cc2b12e21d2565233
--- /dev/null
+++ b/src/structure/villemonte.ts
@@ -0,0 +1,17 @@
+/**
+ *
+ * @param h1 hauteur d'eau amont au dessus de la crête du seuil
+ * @param h2 hauteur d'eau aval au dessus de la crête du seuil
+ * @param n n est l’exposant dans les relations d’écoulement dénoyé :
+ *          déversoir proportionnel : n=1 déversoir rectangulaire : n=1,5
+ *          déversoir parabolique : n=2 déversoir triangulaire : n=2,5
+ */
+export function Villemonte(h1: number, h2: number, n: number): number {
+    if (h1 === 0) {
+        throw new Error("getK_Villemonte h1 ne peut pas être nul");
+    }
+    if (n < 1 || n > 2.5) {
+        throw new Error("getK_Villemonte n doit être compris entre 1 et 2.5");
+    }
+    return Math.pow(1 - Math.pow(h2 / h1, n), 0.385);
+}
diff --git a/src/util/message.ts b/src/util/message.ts
index 6f0cd183be78235b869a14aa2dbacbe581874a91..a6ececce4b9b6ee428fc34497a9ac1a82391996e 100644
--- a/src/util/message.ts
+++ b/src/util/message.ts
@@ -212,6 +212,17 @@ export enum MessageCode {
      * newton : dérivée nulle
      */
     ERROR_NEWTON_DERIVEE_NULLE = -701,
+
+    /**
+     * StructureKivi : La pelle du seuil doit mesurer au moins 0,1 m. Le coefficient béta est forcé à 0.
+     */
+    WARNING_STRUCTUREKIVI_PELLE_TROP_FAIBLE = 100,
+
+    /**
+     * StructureKivi : h/p ne doit pas être supérieur à 2,5. h/p est forcé à 2,5.
+     */
+    WARNING_STRUCTUREKIVI_HP_TROP_ELEVE = 101,
+
 }
 
 /**