Integrate Refactor solver sources and dual MSVC CMake builds
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "fesa/elements/thermal_shell.h"
|
||||
#include "fesa/model/domain.h"
|
||||
#include "elements/thermal_shell_geometry.h"
|
||||
|
||||
namespace {
|
||||
using fesa::Vector3;
|
||||
@@ -210,3 +211,68 @@ TEST(ThermalShellGeometry,
|
||||
{1, 1, 0}},
|
||||
{{{0, 1, 4, 3}}, {{1, 2, 5, 4}}, {{3, 4, 7, 6}}, {{4, 5, 8, 7}}})));
|
||||
}
|
||||
|
||||
namespace {
|
||||
TEST(ThermalGeometryAction, EnclosesIndependentDyadicTangentialConstraints) {
|
||||
using namespace fesa::thermal_internal;
|
||||
// The rounded Gram matrix loses rank for delta=2^-40, while the physical
|
||||
// tangents and their exterior determinant remain certified and nonsingular.
|
||||
for (const int exponent : {-40,-27,-4,0}) {
|
||||
const double delta = std::ldexp(1.,exponent);
|
||||
Geometry geometry;
|
||||
geometry.b = {1,1,0};
|
||||
geometry.c = {1,1+delta,0};
|
||||
for (std::size_t j=0; j<3; ++j) {
|
||||
geometry.bi[j] = Interval{geometry.b[j]};
|
||||
geometry.ci[j] = Interval{geometry.c[j]};
|
||||
}
|
||||
const auto evaluated = EvaluateSurface(geometry, 0, 0, Interval{0},
|
||||
Interval{0}, {}, {});
|
||||
ASSERT_TRUE(evaluated.HasValue()) << exponent;
|
||||
const double dx[4]{-.25,.25,.25,-.25};
|
||||
const double dy[4]{-.25,-.25,.25,.25};
|
||||
for (std::size_t i=0; i<4; ++i) {
|
||||
const double gy = (dy[i]-dx[i])/delta;
|
||||
const double gx = dx[i]-gy;
|
||||
const double oracle[3]{gx,gy,0};
|
||||
for (std::size_t j=0; j<3; ++j) {
|
||||
EXPECT_DOUBLE_EQ(evaluated.Value().gradient[i][j],oracle[j]);
|
||||
const auto interval = evaluated.Value().gradient_interval[i][j];
|
||||
EXPECT_LE(interval.lower,oracle[j]);
|
||||
EXPECT_GE(interval.upper,oracle[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST(ThermalGeometryAction, PreservesWholePatchAndScaledFiniteRejections) {
|
||||
using namespace fesa::thermal_internal;
|
||||
for (const Patch patch : {
|
||||
kSquare,
|
||||
Patch{{{3,-9,-3},{1,3,-3},{-1,3,3},{-3,3,3}}},
|
||||
Patch{{{-1,4,-4},{-1,-2,2},{3,2,4},{-1,-4,-2}}}}) {
|
||||
const auto geometry = BuildGeometry(patch, {}, {});
|
||||
ASSERT_TRUE(geometry.HasValue());
|
||||
for (const double xi : {-std::sqrt(.6),0.,std::sqrt(.6)})
|
||||
for (const double eta : {-std::sqrt(.6),0.,std::sqrt(.6)})
|
||||
EXPECT_TRUE(EvaluateSurface(geometry.Value(),xi,eta,
|
||||
Interval{Down(xi),Up(xi)},Interval{Down(eta),Up(eta)},{},{}).HasValue());
|
||||
}
|
||||
const Patch folded{{{0,0,0},{1,1,0},{1,0,0},{0,1,0}}};
|
||||
const auto rejected = BuildGeometry(folded,{"part",27,"0027"},{"mesh.inp",17});
|
||||
ASSERT_FALSE(rejected.HasValue());
|
||||
EXPECT_EQ(rejected.GetStatus().Diagnostics()[0].code,
|
||||
"uncertain-thermal-shell-geometry");
|
||||
EXPECT_EQ(rejected.GetStatus().Diagnostics()[0].entity_identity,"part:0027");
|
||||
Geometry geometry;
|
||||
geometry.b = {1,0,0}; geometry.c = {0,1,0};
|
||||
geometry.bi[0] = Interval{1}; geometry.ci[1] = Interval{1};
|
||||
geometry.length_exponent = -600;
|
||||
const auto scaled = EvaluateSurface(geometry,0,0,Interval{0},Interval{0},
|
||||
{"part",27,"0027"},{"mesh.inp",17});
|
||||
ASSERT_FALSE(scaled.HasValue());
|
||||
EXPECT_EQ(scaled.GetStatus().Diagnostics()[0].code,
|
||||
"uncertain-thermal-shell-metric");
|
||||
EXPECT_EQ(scaled.GetStatus().Diagnostics()[0].message,
|
||||
"Metric inverse enclosure is not finite or excludes no zero divisor.");
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user