diff --git a/API/API.csproj b/API/API.csproj
index ec2e97f..a565daf 100644
--- a/API/API.csproj
+++ b/API/API.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/API/Services/Extensions.cs b/API/Services/Extensions.cs
index ff0611d..32e704f 100644
--- a/API/Services/Extensions.cs
+++ b/API/Services/Extensions.cs
@@ -202,7 +202,7 @@ public static Graph ToGraph(this Models.Soil soil, double[] thickness = null,
sw = sw.ConvertGravimetricToVolumetric(bdMapped).ToArray();
}
// Map water to bottom of profile.
- sw = Soil.SWMappedTo(sw, thickness, soil.Water.Thickness, ll);
+ sw = Soil.SWMappedTo(sw, thickness, soil.Water.Thickness, soil.Water.LL15, ll, soil.Water.DUL);
// Calculate plant available water.
paw = SoilUtilities.CalcPAWC(soil.Water.Thickness, ll, sw, xf)
@@ -213,8 +213,10 @@ public static Graph ToGraph(this Models.Soil soil, double[] thickness = null,
double pawc = SoilUtilities.CalcPAWC(soil.Water.Thickness, ll, soil.Water.DUL, Enumerable.Repeat(1.0, ll.Count).ToArray())
.Multiply(soil.Water.Thickness).Sum();
+ // To stop the sw line crossing over ll, constrain it to ll.
+ var swConstainedToLL = sw.LowerConstraint(ll);
return SoilGraph.Create(soil.Name, soil.Water.Thickness.ToMidPoints(), soil.Water.AirDry, soil.Water.LL15,
- soil.Water.DUL, soil.Water.SAT, ll, cropName, pawc, paw, thickness?.ToMidPoints(), sw);
+ soil.Water.DUL, soil.Water.SAT, ll, cropName, pawc, paw, thickness?.ToMidPoints(), swConstainedToLL);
}
/// Get the crop lower limit (volumetric) for a soil.
diff --git a/API/Services/SoilServices.cs b/API/Services/SoilServices.cs
index db8ddb9..8cec9f4 100644
--- a/API/Services/SoilServices.cs
+++ b/API/Services/SoilServices.cs
@@ -188,7 +188,7 @@ public static double PAW(SoilDbContext context, string fullName, string cropName
sw = sw.ConvertGravimetricToVolumetric(bdMapped);
}
- IReadOnlyList swMapped = sw.SWMappedTo(thickness, soil.Water.Thickness, ll);
+ IReadOnlyList swMapped = sw.SWMappedTo(thickness, soil.Water.Thickness, soil.Water.LL15, ll, soil.Water.DUL);
var pawByLayer = SoilUtilities.CalcPAWC(soil.Water.Thickness, ll, swMapped, xf);
return MathUtilities.Multiply(pawByLayer, soil.Water.Thickness).Sum();
}
@@ -198,22 +198,18 @@ public static double PAW(SoilDbContext context, string fullName, string cropName
/// The values to map.
/// The thickness to map to.
/// The mapped values.
- public static double[] SWMappedTo(this IReadOnlyList values, IReadOnlyList fromThickness, IReadOnlyList toThickness, IReadOnlyList ll)
+ public static double[] SWMappedTo(this IReadOnlyList values, IReadOnlyList fromThickness, IReadOnlyList toThickness, IReadOnlyList ll15, IReadOnlyList ll, IReadOnlyList dul)
{
List sw = values.ToList();
List thickness = fromThickness.ToList();
- sw.Add(0.8 * values.Last()); // 1st pseudo layer below profile.
- sw.Add(0.4 * values.Last()); // 2nd pseudo layer below profile.
- sw.Add(0.0); // 3rd pseudo layer below profile.
- thickness.Add(thickness.Last()); // 1st pseudo layer below profile.
- thickness.Add(thickness.Last()); // 2nd pseudo layer below profile.
- thickness.Add(3000); // 3rd pseudo layer below profile.
-
- var llMapped = ll.MappedTo(toThickness, thickness);
- var swMM = sw.LowerConstraint(llMapped, startIndex: values.Count)
- .Multiply(thickness);
- return SoilUtilities.MapMass(swMM, thickness.ToArray(), toThickness.ToArray())
+ sw.Add(ll15.Last()); // add a pseudo layer below profile.
+ thickness.Add(3000);
+ var swMM = sw.Multiply(thickness);
+ var swVolumetric = SoilUtilities.MapMass(swMM, thickness.ToArray(), toThickness.ToArray())
.Divide(toThickness); // convert back to volumetric
+ return swVolumetric.LowerConstraint(ll15, startIndex: 0)
+ .UpperConstraint(dul, startIndex: 0)
+ .ToArray();
}
}
\ No newline at end of file
diff --git a/Tests/UnitTest.cs b/Tests/UnitTest.cs
index 122bfc6..d39e3d9 100644
--- a/Tests/UnitTest.cs
+++ b/Tests/UnitTest.cs
@@ -217,7 +217,7 @@ public void PAW_ShouldReturnCorrectValue()
var paw = API.Services.Soil.PAW(context, "Clay (Kerikeri No1353)", cropName: "wheat",
thickness: [ 150, 500 ],
sw: [ 0.4, 0.3 ], swIsGrav: false);
- Assert.That(paw, Is.EqualTo(19.5996).Within(0.000001));
+ Assert.That(paw, Is.EqualTo(21.72).Within(0.000001));
}
@@ -233,7 +233,7 @@ public void PAWFromGravimetric_ShouldReturnCorrectValue()
var paw = API.Services.Soil.PAW(context, "Clay (Kerikeri No1353)", cropName: "wheat",
thickness: [ 150, 500 ],
sw: [ 0.4, 0.3 ], swIsGrav: true);
- Assert.That(paw, Is.EqualTo(22.165).Within(0.000001));
+ Assert.That(paw, Is.EqualTo(24.676).Within(0.000001));
}
[Test]