feat(surface): surface deformation prescriptions

restricted the unknown state vector to surface deformation and implemented one prescription, NodalRadialSurface, while the full volumetric displacment field is reconstructed analytically from that. This reduced the number of degrees of freedom in the system by a factor of 80 while also removing many null vectors from the system.
This commit is contained in:
2026-09-01 11:50:13 -04:00
parent 0a7f18c5c7
commit 85500fef3b
40 changed files with 8924 additions and 1164 deletions

View File

@@ -6,6 +6,7 @@
#include <fourdst/config/config.h>
#include <mfem.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <fstream>
#include <iomanip>
#include <iostream>
@@ -14,8 +15,6 @@
#include <string>
#include <string_view>
#include <vector>
#include <catch2/catch_test_case_info.hpp>
import mean_field;
import test_helpers;
@@ -23,7 +22,7 @@ import experiment;
using namespace experiment;
static std::string escape_csv(const std::string& value) {
static std::string escape_csv(const std::string &value) {
if (value.find_first_of(",\"\n") == std::string::npos) {
return value;
}
@@ -51,11 +50,11 @@ static void write_experiment_csv() {
std::set<std::string> parameter_names;
std::set<std::string> metric_names;
for (const ExperimentResult& result : results) {
for (const auto& [name, value] : result.parameters) {
for (const ExperimentResult &result : results) {
for (const auto &[name, value] : result.parameters) {
parameter_names.insert(name);
}
for (const auto& [name, value] : result.metrics) {
for (const auto &[name, value] : result.metrics) {
metric_names.insert(name);
}
}
@@ -68,22 +67,22 @@ static void write_experiment_csv() {
}
output << "experiment,case";
for (const std::string& name : parameter_names) {
for (const std::string &name : parameter_names) {
output << ',' << escape_csv(name);
}
for (const std::string& name : metric_names) {
for (const std::string &name : metric_names) {
output << ',' << escape_csv(name);
}
output << '\n';
output << std::setprecision(17);
for (const ExperimentResult& result : results) {
for (const ExperimentResult &result : results) {
output << escape_csv(result.experiment_name) << ',' << escape_csv(result.case_name);
for (const std::string& name : parameter_names) {
for (const std::string &name : parameter_names) {
const auto iterator = result.parameters.find(name);
output << ',' << (iterator == result.parameters.end() ? "" : escape_csv(iterator->second));
}
for (const std::string& name : metric_names) {
for (const std::string &name : metric_names) {
const auto iterator = result.metrics.find(name);
output << ',';
if (iterator != result.metrics.end()) {
@@ -104,24 +103,28 @@ public:
return "Compact console reporter that writes structured experiment measurements to CSV.";
}
void testCaseEnded(const Catch::TestCaseStats& statistics) override {
void testCaseEnded(const Catch::TestCaseStats &statistics) override {
StreamingReporterBase::testCaseEnded(statistics);
const bool passed = statistics.totals.assertions.allPassed();
std::cout << (passed ? "PASS " : "FAIL ")
<< statistics.testInfo->name
<< " (" << statistics.totals.assertions.passed
<< " assertions)\n";
std::cout << (passed ? "PASS " : "FAIL ") << statistics.testInfo->name << " ("
<< statistics.totals.assertions.passed << " assertions)\n";
}
void testRunEnded(const Catch::TestRunStats& statistics) override {
void testRunEnded(const Catch::TestRunStats &statistics) override {
StreamingReporterBase::testRunEnded(statistics);
write_experiment_csv();
}
};
CATCH_REGISTER_REPORTER("experiment", ExperimentReporter)
CATCH_REGISTER_REPORTER(
"experiment",
ExperimentReporter
)
int main(int argc, char* argv[]) {
int main(
int argc,
char *argv[]
) {
fourdst::config::Config<mean_field::utils::Args> config;
CLI::App app{"Mean Field accuracy experiments"};
@@ -149,39 +152,39 @@ int main(int argc, char* argv[]) {
}
}
std::vector<const char*> configuration_argv;
std::vector<const char *> configuration_argv;
configuration_argv.reserve(configuration_arguments.size());
for (const std::string& argument : configuration_arguments) {
for (const std::string &argument : configuration_arguments) {
configuration_argv.push_back(argument.c_str());
}
try {
app.parse(static_cast<int>(configuration_argv.size()), configuration_argv.data());
} catch (const CLI::ParseError& error) {
} catch (const CLI::ParseError &error) {
return app.exit(error);
}
std::vector<std::string> catch_arguments{argv[0]};
for (const std::string& argument : app.remaining()) {
for (const std::string &argument : app.remaining()) {
catch_arguments.push_back(argument);
}
for (const std::string& argument : catch_arguments_from_command_line) {
for (const std::string &argument : catch_arguments_from_command_line) {
catch_arguments.push_back(argument);
}
bool has_reporter = false;
for (const std::string& argument : catch_arguments) {
has_reporter = has_reporter || argument == "-r" || argument == "--reporter" ||
argument.starts_with("-r=") || argument.starts_with("--reporter=");
for (const std::string &argument : catch_arguments) {
has_reporter = has_reporter || argument == "-r" || argument == "--reporter" || argument.starts_with("-r=") ||
argument.starts_with("--reporter=");
}
if (!has_reporter) {
catch_arguments.emplace_back("--reporter");
catch_arguments.emplace_back("experiment");
}
std::vector<const char*> catch_argv;
std::vector<const char *> catch_argv;
catch_argv.reserve(catch_arguments.size());
for (const std::string& argument : catch_arguments) {
for (const std::string &argument : catch_arguments) {
catch_argv.push_back(argument.c_str());
}