@geotechcli/core 0.4.119 → 0.4.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/fem-tools.js +222 -1
- package/dist/agents/fem-tools.js.map +1 -1
- package/dist/agents/swarm-planner.js +1 -1
- package/dist/agents/swarm-planner.js.map +1 -1
- package/dist/agents/swarm.d.ts.map +1 -1
- package/dist/agents/swarm.js +1 -0
- package/dist/agents/swarm.js.map +1 -1
- package/dist/fem/engineering-evidence.d.ts.map +1 -1
- package/dist/fem/engineering-evidence.js +190 -2
- package/dist/fem/engineering-evidence.js.map +1 -1
- package/dist/fem/production-readiness.js +1 -1
- package/dist/fem/production-readiness.js.map +1 -1
- package/dist/meta/metadata.json +1 -1
- package/package.json +1 -1
|
@@ -114,6 +114,21 @@ const DEFAULT_EXTERNAL_BENCHMARK_REFERENCES = [
|
|
|
114
114
|
retrievedAt: '2026-06-04',
|
|
115
115
|
},
|
|
116
116
|
},
|
|
117
|
+
{
|
|
118
|
+
id: 'opengeosys-consolidation-staggered-benchmark',
|
|
119
|
+
sourceType: 'open-source-solver',
|
|
120
|
+
label: 'OpenGeoSys staggered hydro-mechanics consolidation benchmark',
|
|
121
|
+
citation: 'OpenGeoSys Documentation, Consolidation benchmark with the staggered scheme, hydro-mechanics benchmark with analytical pressure/displacement solution, 1000 Pa top load, t = 10 s, and dt = 0.5 s comparison.',
|
|
122
|
+
referenceSolver: {
|
|
123
|
+
name: 'OpenGeoSys',
|
|
124
|
+
version: 'stable documentation',
|
|
125
|
+
vendor: 'OpenGeoSys project',
|
|
126
|
+
analysisProcedure: 'HYDRO_MECHANICS staggered fixed-stress consolidation benchmark',
|
|
127
|
+
elementType: '2D hydro-mechanics finite elements',
|
|
128
|
+
url: 'https://www.opengeosys.org/docs/benchmarks/hydro-mechanics/consolidationbenchmark/',
|
|
129
|
+
retrievedAt: '2026-06-04',
|
|
130
|
+
},
|
|
131
|
+
},
|
|
117
132
|
{
|
|
118
133
|
id: 'opengeosys-hydro-mechanics-benchmarks',
|
|
119
134
|
sourceType: 'open-source-solver',
|
|
@@ -692,7 +707,7 @@ function externalBenchmarkFinalAccepted(input) {
|
|
|
692
707
|
? { unit: input.unit }
|
|
693
708
|
: { relativeTolerance: input.tolerance, unit: input.unit }).accepted;
|
|
694
709
|
}
|
|
695
|
-
function
|
|
710
|
+
function buildDefaultExternalBenchmarkComparisonResults(input) {
|
|
696
711
|
const consolidationRequirement = DEFAULT_EXTERNAL_BENCHMARK_REQUIRED_QUANTITIES
|
|
697
712
|
.find((requirement) => requirement.id === 'consolidation-settlement-time-curve');
|
|
698
713
|
const biotRequirement = DEFAULT_EXTERNAL_BENCHMARK_REQUIRED_QUANTITIES
|
|
@@ -790,6 +805,69 @@ function buildDefaultPublishedExternalBenchmarkComparisonResults(input) {
|
|
|
790
805
|
unit: biotRequirement.unit,
|
|
791
806
|
quantity: biotRequirement.quantity,
|
|
792
807
|
}) && seriesSummarySatisfiesRequirementTolerance(biotSeries, biotRequirement);
|
|
808
|
+
const ogsPressureByY = new Map();
|
|
809
|
+
for (const node of input.openGeoSysConsolidation.nodes) {
|
|
810
|
+
const key = round(node.yM, 10);
|
|
811
|
+
const values = ogsPressureByY.get(key) ?? [];
|
|
812
|
+
values.push(node.porePressureKpa);
|
|
813
|
+
ogsPressureByY.set(key, values);
|
|
814
|
+
}
|
|
815
|
+
const ogsPoints = [...ogsPressureByY.entries()]
|
|
816
|
+
.map(([yM, pressures]) => {
|
|
817
|
+
const depthRatioFromTop = 1 - yM;
|
|
818
|
+
const actual = pressures.reduce((sum, value) => sum + value, 0) / pressures.length;
|
|
819
|
+
const expected = input.openGeoSysConsolidationLoadKpa *
|
|
820
|
+
openGeoSysConsolidationPressureRatio(depthRatioFromTop, input.openGeoSysConsolidationDimensionlessTime);
|
|
821
|
+
return {
|
|
822
|
+
x: depthRatioFromTop,
|
|
823
|
+
actual,
|
|
824
|
+
expected,
|
|
825
|
+
};
|
|
826
|
+
})
|
|
827
|
+
.sort((left, right) => right.x - left.x);
|
|
828
|
+
const ogsSeries = buildFemExternalBenchmarkSeriesSummary({
|
|
829
|
+
xQuantity: 'dimensionless depth from drained top',
|
|
830
|
+
xUnit: 'x/H',
|
|
831
|
+
yQuantity: 'load-generated excess pore pressure',
|
|
832
|
+
yUnit: 'kPa',
|
|
833
|
+
points: ogsPoints,
|
|
834
|
+
notes: [
|
|
835
|
+
'Benchmark-scale Quad4 Biot u-p load-generated pressure profile at t = 10 s compared with the OpenGeoSys staggered consolidation analytical p_D profile.',
|
|
836
|
+
'OpenGeoSys source parameters are E = 3e4 Pa, nu = 0.2, k = 1e-10 m2, viscosity = 1e-3 Pa s, sigma0 = 1000 Pa, dt = 0.5 s.',
|
|
837
|
+
],
|
|
838
|
+
});
|
|
839
|
+
const ogsActual = ogsSeries.actual.mean ?? ogsSeries.actual.final;
|
|
840
|
+
const ogsExpected = ogsSeries.expected.mean ?? ogsSeries.expected.final;
|
|
841
|
+
const ogsEvidencePayload = {
|
|
842
|
+
schemaVersion: 'fem-external-benchmark-evidence.v1',
|
|
843
|
+
caseId: 'opengeosys-staggered-consolidation-pressure-profile-t10',
|
|
844
|
+
sourceId: 'opengeosys-consolidation-staggered-benchmark',
|
|
845
|
+
method: input.openGeoSysConsolidation.method,
|
|
846
|
+
pressureEnvelopeMode: input.openGeoSysConsolidation.numericalContract.pressureEnvelopeMode,
|
|
847
|
+
pressureOvershootPolicy: input.openGeoSysConsolidation.numericalContract.pressureOvershootPolicy,
|
|
848
|
+
timeStepCount: input.openGeoSysConsolidation.timeSteps.length,
|
|
849
|
+
finalTimeSeconds: input.openGeoSysConsolidation.timeSteps.at(-1)?.timeSeconds,
|
|
850
|
+
dimensionlessTime: input.openGeoSysConsolidationDimensionlessTime,
|
|
851
|
+
transientAcceptance: input.openGeoSysConsolidation.transientAcceptance,
|
|
852
|
+
seriesHashSha256: ogsSeries.seriesHashSha256,
|
|
853
|
+
};
|
|
854
|
+
const ogsResultPayload = {
|
|
855
|
+
actual: ogsActual,
|
|
856
|
+
expected: ogsExpected,
|
|
857
|
+
maxAbsoluteError: ogsSeries.maxAbsoluteError,
|
|
858
|
+
maxRelativeError: ogsSeries.maxRelativeError,
|
|
859
|
+
resultSeriesHashSha256: ogsSeries.seriesHashSha256,
|
|
860
|
+
};
|
|
861
|
+
const ogsAccepted = input.openGeoSysConsolidation.transientAcceptance.accepted &&
|
|
862
|
+
externalBenchmarkFinalAccepted({
|
|
863
|
+
actual: ogsActual,
|
|
864
|
+
expected: ogsExpected,
|
|
865
|
+
tolerance: biotRequirement.tolerance,
|
|
866
|
+
toleranceType: biotRequirement.toleranceType,
|
|
867
|
+
unit: biotRequirement.unit,
|
|
868
|
+
quantity: biotRequirement.quantity,
|
|
869
|
+
}) &&
|
|
870
|
+
seriesSummarySatisfiesRequirementTolerance(ogsSeries, biotRequirement);
|
|
793
871
|
return [
|
|
794
872
|
{
|
|
795
873
|
id: 'published-terzaghi-1d-consolidation-tv-0-197',
|
|
@@ -849,6 +927,45 @@ function buildDefaultPublishedExternalBenchmarkComparisonResults(input) {
|
|
|
849
927
|
'Generated published-source comparison record for an alpha-zero Biot pressure-diffusion specialization; commercial solver comparison remains missing.',
|
|
850
928
|
],
|
|
851
929
|
},
|
|
930
|
+
{
|
|
931
|
+
id: 'opengeosys-consolidation-staggered-biot-pressure-profile-t10',
|
|
932
|
+
quantityRequirementId: biotRequirement.id,
|
|
933
|
+
referenceId: 'opengeosys-consolidation-staggered-benchmark',
|
|
934
|
+
caseId: 'opengeosys-staggered-consolidation-pressure-profile-t10',
|
|
935
|
+
comparisonKind: 'series-summary',
|
|
936
|
+
metricName: 'loadGeneratedExcessPorePressureProfileAtT10s',
|
|
937
|
+
quantity: biotRequirement.quantity,
|
|
938
|
+
unit: biotRequirement.unit,
|
|
939
|
+
actual: round(ogsActual, 10),
|
|
940
|
+
expected: round(ogsExpected, 10),
|
|
941
|
+
tolerance: biotRequirement.tolerance,
|
|
942
|
+
toleranceType: biotRequirement.toleranceType,
|
|
943
|
+
accepted: ogsAccepted,
|
|
944
|
+
candidateSolver: {
|
|
945
|
+
name: 'geotechCLI FEM evidence suite',
|
|
946
|
+
version: 'strong-beta',
|
|
947
|
+
solverType: 'geotechcli-kernel',
|
|
948
|
+
analysisProcedure: 'linear-elastic Quad4 Biot u-p load-generated consolidation pressure profile',
|
|
949
|
+
elementType: 'Quad4 plane-strain u-p evidence mesh',
|
|
950
|
+
runId: 'opengeosys-staggered-consolidation-pressure-profile-t10',
|
|
951
|
+
},
|
|
952
|
+
referenceSolver: {
|
|
953
|
+
name: 'OpenGeoSys',
|
|
954
|
+
version: 'stable documentation',
|
|
955
|
+
vendor: 'OpenGeoSys project',
|
|
956
|
+
solverType: 'open-source-solver',
|
|
957
|
+
analysisProcedure: 'HYDRO_MECHANICS staggered fixed-stress consolidation benchmark',
|
|
958
|
+
elementType: '2D hydro-mechanics finite elements',
|
|
959
|
+
runId: 'HydroMechanics/StaggeredScheme/ConsolidationBenchmark/consolidation_benchmark.prj',
|
|
960
|
+
},
|
|
961
|
+
evidenceHashSha256: hashFemBenchmarkPayload(ogsEvidencePayload),
|
|
962
|
+
resultHashSha256: hashFemBenchmarkPayload(ogsResultPayload),
|
|
963
|
+
seriesSummary: ogsSeries,
|
|
964
|
+
notes: [
|
|
965
|
+
'Generated open-source solver comparison record against the OpenGeoSys staggered consolidation benchmark analytical pressure profile.',
|
|
966
|
+
'This adds open-source cross-solver evidence but does not satisfy the required commercial-solver production benchmark gate.',
|
|
967
|
+
],
|
|
968
|
+
},
|
|
852
969
|
];
|
|
853
970
|
}
|
|
854
971
|
export function evaluateFemTolerance(quantity, actual, expected, absoluteTolerance, options = {}) {
|
|
@@ -1115,6 +1232,21 @@ export function terzaghiAverageConsolidation(timeFactor, terms = 80) {
|
|
|
1115
1232
|
const degree = 1 - (8 / (Math.PI * Math.PI)) * remaining;
|
|
1116
1233
|
return Math.min(1, Math.max(0, degree));
|
|
1117
1234
|
}
|
|
1235
|
+
function openGeoSysConsolidationPressureRatio(depthRatioFromTop, dimensionlessTime, terms = 120) {
|
|
1236
|
+
if (!Number.isFinite(depthRatioFromTop) || depthRatioFromTop < -1e-12 || depthRatioFromTop > 1 + 1e-12) {
|
|
1237
|
+
throw new Error('depthRatioFromTop must be finite and within [0, 1].');
|
|
1238
|
+
}
|
|
1239
|
+
if (!Number.isFinite(dimensionlessTime) || dimensionlessTime < 0) {
|
|
1240
|
+
throw new Error('dimensionlessTime must be finite and non-negative.');
|
|
1241
|
+
}
|
|
1242
|
+
const xD = Math.min(1, Math.max(0, depthRatioFromTop));
|
|
1243
|
+
let pressureRatio = 0;
|
|
1244
|
+
for (let n = 0; n < terms; n++) {
|
|
1245
|
+
const m = 0.5 * Math.PI * (2 * n + 1);
|
|
1246
|
+
pressureRatio += (2 / m) * Math.sin(m * xD) * Math.exp(-(m * m * dimensionlessTime));
|
|
1247
|
+
}
|
|
1248
|
+
return Math.max(0, pressureRatio);
|
|
1249
|
+
}
|
|
1118
1250
|
function solveTridiagonal(lower, diagonal, upper, rhs) {
|
|
1119
1251
|
const n = diagonal.length;
|
|
1120
1252
|
const cPrime = new Array(n).fill(0);
|
|
@@ -2035,6 +2167,59 @@ export function runFemEngineeringEvidenceSuite(policy = DEFAULT_FEM_CONVERGENCE_
|
|
|
2035
2167
|
biotLoadGenerated.massBalanceErrorRatio <= policy.porePressureMassBalanceTolerance
|
|
2036
2168
|
? 1
|
|
2037
2169
|
: 0, 1, 0, 'Mechanically loaded Biot consolidation must require explicit load-generated pressure mode and audit positive excess pore-pressure generation without weakening the default envelope guard.'));
|
|
2170
|
+
const openGeoSysConsolidationMesh = buildPlaneStrainRectangularMesh({
|
|
2171
|
+
widthM: 1,
|
|
2172
|
+
heightM: 1,
|
|
2173
|
+
divisionsX: 1,
|
|
2174
|
+
divisionsY: 16,
|
|
2175
|
+
materialId: 'soil',
|
|
2176
|
+
});
|
|
2177
|
+
const openGeoSysConsolidationBottomNodes = openGeoSysConsolidationMesh.nodes.filter((node) => node.yM === 0);
|
|
2178
|
+
const openGeoSysConsolidationTopNodes = openGeoSysConsolidationMesh.nodes.filter((node) => node.yM === 1);
|
|
2179
|
+
const openGeoSysConsolidationLeftNodes = openGeoSysConsolidationMesh.nodes.filter((node) => node.xM === 0);
|
|
2180
|
+
const openGeoSysConsolidationRightNodes = openGeoSysConsolidationMesh.nodes.filter((node) => node.xM === 1);
|
|
2181
|
+
const openGeoSysConsolidationYoungModulusKpa = 30;
|
|
2182
|
+
const openGeoSysConsolidationPoissonRatio = 0.2;
|
|
2183
|
+
const openGeoSysConsolidationHydraulicConductivityMPerS = 9.81e-4;
|
|
2184
|
+
const openGeoSysConsolidationLoadKpa = 1;
|
|
2185
|
+
const openGeoSysConsolidationFinalTimeSeconds = 10;
|
|
2186
|
+
const openGeoSysConsolidationLambdaPlus2MuKpa = openGeoSysConsolidationYoungModulusKpa *
|
|
2187
|
+
(1 - openGeoSysConsolidationPoissonRatio) /
|
|
2188
|
+
((1 + openGeoSysConsolidationPoissonRatio) * (1 - 2 * openGeoSysConsolidationPoissonRatio));
|
|
2189
|
+
const openGeoSysConsolidationDimensionlessTime = openGeoSysConsolidationLambdaPlus2MuKpa *
|
|
2190
|
+
(openGeoSysConsolidationHydraulicConductivityMPerS / 9.81) *
|
|
2191
|
+
openGeoSysConsolidationFinalTimeSeconds;
|
|
2192
|
+
const openGeoSysConsolidation = runPlaneStrainBiotConsolidation({
|
|
2193
|
+
schemaVersion: 'fem-plane-strain-biot-consolidation-model.v1',
|
|
2194
|
+
nodes: openGeoSysConsolidationMesh.nodes,
|
|
2195
|
+
elements: openGeoSysConsolidationMesh.elements,
|
|
2196
|
+
materials: [{
|
|
2197
|
+
id: 'soil',
|
|
2198
|
+
elasticModulusKpa: openGeoSysConsolidationYoungModulusKpa,
|
|
2199
|
+
poissonRatio: openGeoSysConsolidationPoissonRatio,
|
|
2200
|
+
hydraulicConductivityXMPerS: openGeoSysConsolidationHydraulicConductivityMPerS,
|
|
2201
|
+
hydraulicConductivityYMPerS: openGeoSysConsolidationHydraulicConductivityMPerS,
|
|
2202
|
+
biotCoefficient: 1,
|
|
2203
|
+
specificStorage1PerM: 1e-9,
|
|
2204
|
+
}],
|
|
2205
|
+
boundaryConditions: [
|
|
2206
|
+
...openGeoSysConsolidationBottomNodes.map((node) => ({ nodeId: node.id, dof: 'uy' })),
|
|
2207
|
+
...openGeoSysConsolidationLeftNodes.map((node) => ({ nodeId: node.id, dof: 'ux' })),
|
|
2208
|
+
...openGeoSysConsolidationRightNodes.map((node) => ({ nodeId: node.id, dof: 'ux' })),
|
|
2209
|
+
],
|
|
2210
|
+
porePressureBoundaryConditions: openGeoSysConsolidationTopNodes.map((node) => ({
|
|
2211
|
+
nodeId: node.id,
|
|
2212
|
+
porePressureKpa: 0,
|
|
2213
|
+
})),
|
|
2214
|
+
nodalLoads: openGeoSysConsolidationTopNodes.map((node) => ({
|
|
2215
|
+
nodeId: node.id,
|
|
2216
|
+
fyKn: -openGeoSysConsolidationLoadKpa / openGeoSysConsolidationTopNodes.length,
|
|
2217
|
+
})),
|
|
2218
|
+
initialPorePressureKpa: 0,
|
|
2219
|
+
pressureEnvelopeMode: 'load-generated-positive-pressure',
|
|
2220
|
+
timeStepsSeconds: Array.from({ length: 20 }, (_, index) => (index + 1) * 0.5),
|
|
2221
|
+
policy,
|
|
2222
|
+
});
|
|
2038
2223
|
const biotPatchMesh = buildPlaneStrainRectangularMesh({
|
|
2039
2224
|
widthM: 2,
|
|
2040
2225
|
heightM: 1,
|
|
@@ -2338,12 +2523,15 @@ export function runFemEngineeringEvidenceSuite(policy = DEFAULT_FEM_CONVERGENCE_
|
|
|
2338
2523
|
.map((item) => item.feature))];
|
|
2339
2524
|
const status = benchmarks.every((item) => item.status === 'accepted') ? 'kernel-verified' : 'blocked';
|
|
2340
2525
|
const externalBenchmarkAcceptance = buildFemExternalBenchmarkAcceptanceContract({
|
|
2341
|
-
comparisonResults:
|
|
2526
|
+
comparisonResults: buildDefaultExternalBenchmarkComparisonResults({
|
|
2342
2527
|
consolidation,
|
|
2343
2528
|
biotTerzaghi,
|
|
2344
2529
|
biotTerzaghiInitialPressureKpa,
|
|
2345
2530
|
biotTerzaghiHydraulicConductivityMPerS,
|
|
2346
2531
|
biotTerzaghiSpecificStorage1PerM,
|
|
2532
|
+
openGeoSysConsolidation,
|
|
2533
|
+
openGeoSysConsolidationDimensionlessTime,
|
|
2534
|
+
openGeoSysConsolidationLoadKpa,
|
|
2347
2535
|
}),
|
|
2348
2536
|
});
|
|
2349
2537
|
return {
|