Integrate Refactor solver sources and dual MSVC CMake builds
This commit is contained in:
@@ -185,7 +185,12 @@ class ReverseParallelFor final : public fesa::ParallelFor {
|
||||
class FakeStiffnessElement final : public fesa::Element {
|
||||
public:
|
||||
FakeStiffnessElement(fesa::ElementDofLayout layout, fesa::Matrix stiffness)
|
||||
: layout_{std::move(layout)}, stiffness_{std::move(stiffness)} {}
|
||||
: layout_{std::move(layout)}, stiffness_{std::move(stiffness)},
|
||||
contribution_layout_{layout_} {}
|
||||
|
||||
void ReturnLayout(fesa::ElementDofLayout layout) {
|
||||
contribution_layout_ = std::move(layout);
|
||||
}
|
||||
|
||||
const fesa::ElementDofLayout& DofLayout() const noexcept override {
|
||||
return layout_;
|
||||
@@ -194,7 +199,7 @@ class FakeStiffnessElement final : public fesa::Element {
|
||||
fesa::Result<fesa::ElementStiffnessContribution> ComputeStiffness()
|
||||
const override {
|
||||
return fesa::Result<fesa::ElementStiffnessContribution>::Success(
|
||||
{layout_, stiffness_});
|
||||
{contribution_layout_, stiffness_});
|
||||
}
|
||||
|
||||
fesa::Result<fesa::ElementResultBundle> Recover(
|
||||
@@ -206,6 +211,7 @@ class FakeStiffnessElement final : public fesa::Element {
|
||||
private:
|
||||
fesa::ElementDofLayout layout_;
|
||||
fesa::Matrix stiffness_;
|
||||
fesa::ElementDofLayout contribution_layout_;
|
||||
};
|
||||
|
||||
fesa::Matrix MatrixFromRows(const std::vector<std::vector<double>>& rows) {
|
||||
@@ -414,4 +420,59 @@ TEST(SparseAssembly, S4AndS4rSemanticFixturesAssembleIdenticalStiffness) {
|
||||
ExpectByteIdentical(s4r.Value(), s4.Value());
|
||||
}
|
||||
|
||||
TEST(SparseAssembly, RejectsLayoutAndDimensionsInStableElementOrder) {
|
||||
auto domain = fesa::Domain::Create(MakeDefinition());
|
||||
ASSERT_TRUE(domain.HasValue());
|
||||
auto model = fesa::AnalysisModel::Create(domain.Value());
|
||||
ASSERT_TRUE(model.HasValue());
|
||||
const fesa::ElementDofLayout first_layout{
|
||||
{"Beam-1", 10, "10"}, {0U, 1U}, {fesa::DofComponent::kUx}};
|
||||
const fesa::ElementDofLayout second_layout{
|
||||
{"Beam-1", 20, "20"}, {1U, 2U}, {fesa::DofComponent::kUx}};
|
||||
FakeStiffnessElement first{first_layout, fesa::Matrix{2U, 2U}};
|
||||
FakeStiffnessElement second{second_layout, fesa::Matrix{1U, 1U}};
|
||||
const fesa::ElementView elements{std::cref(first), std::cref(second)};
|
||||
fesa::DofManager dofs;
|
||||
ASSERT_TRUE(dofs.Build(model.Value(), elements).IsOk());
|
||||
const auto original_pattern = dofs.GetSparsePattern();
|
||||
|
||||
std::vector<fesa::ElementDofLayout> invalid(5U, first_layout);
|
||||
invalid[0U].source_id.instance_name = "beam-1";
|
||||
invalid[1U].source_id.source_label = 11;
|
||||
invalid[2U].source_id.source_label_text = "010";
|
||||
invalid[3U].node_indices = {1U, 0U};
|
||||
invalid[4U].components_per_node = {fesa::DofComponent::kUy};
|
||||
fesa::SerialParallelFor serial;
|
||||
fesa::TbbParallelFor tbb;
|
||||
ReverseParallelFor reverse;
|
||||
for (const auto& layout : invalid) {
|
||||
first.ReturnLayout(layout);
|
||||
for (const fesa::ParallelFor* executor :
|
||||
std::array<const fesa::ParallelFor*, 3>{&serial, &tbb, &reverse}) {
|
||||
auto candidate =
|
||||
fesa::SparseAssembler::Assemble(elements, dofs, *executor);
|
||||
ASSERT_FALSE(candidate.HasValue());
|
||||
EXPECT_EQ(candidate.GetStatus().Category(), fesa::FailureCategory::kModel);
|
||||
ASSERT_EQ(candidate.GetStatus().Diagnostics().size(), 1U);
|
||||
const auto& diagnostic = candidate.GetStatus().Diagnostics()[0U];
|
||||
EXPECT_EQ(diagnostic.code, "invalid-assembly-layout");
|
||||
EXPECT_EQ(diagnostic.keyword, "*ELEMENT");
|
||||
EXPECT_EQ(diagnostic.entity_identity, "10");
|
||||
EXPECT_EQ(diagnostic.message,
|
||||
"Element stiffness layout must match its declared runtime layout.");
|
||||
}
|
||||
}
|
||||
first.ReturnLayout(first_layout);
|
||||
auto candidate = fesa::SparseAssembler::Assemble(elements, dofs, reverse);
|
||||
ASSERT_FALSE(candidate.HasValue());
|
||||
EXPECT_EQ(candidate.GetStatus().Diagnostics()[0U].code,
|
||||
"invalid-assembly-dimensions");
|
||||
EXPECT_EQ(candidate.GetStatus().Diagnostics()[0U].entity_identity, "20");
|
||||
EXPECT_EQ(first.DofLayout().node_indices, first_layout.node_indices);
|
||||
EXPECT_EQ(dofs.GetSparsePattern().row_offsets, original_pattern.row_offsets);
|
||||
EXPECT_EQ(dofs.GetSparsePattern().column_indices,
|
||||
original_pattern.column_indices);
|
||||
EXPECT_TRUE(dofs.ValidateInvariants().IsOk());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user