From c8585bacd7c4ba20884f73c1b5154dbe3d5f44eb Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Wed, 12 Feb 2025 16:21:31 -0500 Subject: [PATCH 1/5] ci(gitignore): added .vscode --- .gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 07227a2..3d33190 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,9 @@ tags *.log *.cache *.private -*.private/ \ No newline at end of file +*.private/ + +subprojects/mfem/ +subprojects/tetgen/ + +.vscode/ From 0bf4c40699245679cfb1e037c48ebf906ec1f61a Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Wed, 12 Feb 2025 16:22:00 -0500 Subject: [PATCH 2/5] fix(mk): removed directive for mk to delete build directory every run --- mk | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mk b/mk index 6e3a90f..9bab354 100755 --- a/mk +++ b/mk @@ -1,10 +1,5 @@ #!/bin/bash -# Check if the build directory is present, and remove it -if [ -d "build" ]; then - rm -rf build -fi - # Check for the --noTest flag if [[ "$1" == "--noTest" ]]; then meson setup build -Dbuild_tests=false From 112e626760265233919cd3457ba82b1602d434b5 Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Wed, 12 Feb 2025 16:24:13 -0500 Subject: [PATCH 3/5] feat(mfem): added mfem into source tree along with patch based build system MFEM is a dependency of our code and we want to build it with our code for portability, here I add a meson subproject which fetches mfem and builds it. Because of some issues with CMake and meson I apply a patch which manually disables running tests and building examples and miniapps in mfem. This is okay as mfem here is not intenteded to be linked against other programs (though it still can be). --- build-config/meson.build | 1 + .../mfem/disable_mfem_selfcheck.patch | 41 +++++++++++++++++++ build-config/mfem/meson.build | 24 +++++++++++ meson.build | 3 ++ subprojects/mfem.wrap | 5 +++ 5 files changed, 74 insertions(+) create mode 100644 build-config/meson.build create mode 100644 build-config/mfem/disable_mfem_selfcheck.patch create mode 100644 build-config/mfem/meson.build create mode 100644 subprojects/mfem.wrap diff --git a/build-config/meson.build b/build-config/meson.build new file mode 100644 index 0000000..cefc100 --- /dev/null +++ b/build-config/meson.build @@ -0,0 +1 @@ +subdir('mfem') \ No newline at end of file diff --git a/build-config/mfem/disable_mfem_selfcheck.patch b/build-config/mfem/disable_mfem_selfcheck.patch new file mode 100644 index 0000000..8e438c0 --- /dev/null +++ b/build-config/mfem/disable_mfem_selfcheck.patch @@ -0,0 +1,41 @@ +--- subprojects/mfem/CMakeLists.txt 2025-02-12 15:54:52.454728232 -0500 ++++ CMakeLists.txt.bak 2025-02-12 16:08:06.654542689 -0500 +@@ -765,7 +765,7 @@ + if (MFEM_ENABLE_EXAMPLES) + add_subdirectory(examples) #install examples if enabled + else() +- add_subdirectory(examples EXCLUDE_FROM_ALL) ++ # add_subdirectory(examples EXCLUDE_FROM_ALL) + endif() + + # Create a target for all miniapps and, optionally, enable it. +@@ -774,7 +774,7 @@ + if (MFEM_ENABLE_MINIAPPS) + add_subdirectory(miniapps) #install miniapps if enabled + else() +- add_subdirectory(miniapps EXCLUDE_FROM_ALL) ++ # add_subdirectory(miniapps EXCLUDE_FROM_ALL) + endif() + + # Target to build all executables, i.e. everything. +@@ -801,19 +801,7 @@ + add_dependencies(${MFEM_EXEC_PREREQUISITES_TARGET_NAME} copy_data) + endif() + +-# Add 'check' target - quick test +-set(MFEM_CHECK_TARGET_NAME ${MFEM_CUSTOM_TARGET_PREFIX}check) +-if (NOT MFEM_USE_MPI) +- add_custom_target(${MFEM_CHECK_TARGET_NAME} +- ${CMAKE_CTEST_COMMAND} -R \"^ex1_ser\" -C ${CMAKE_CFG_INTDIR} +- USES_TERMINAL) +- add_dependencies(${MFEM_CHECK_TARGET_NAME} ex1) +-else() +- add_custom_target(${MFEM_CHECK_TARGET_NAME} +- ${CMAKE_CTEST_COMMAND} -R \"^ex1p\" -C ${CMAKE_CFG_INTDIR} +- USES_TERMINAL) +- add_dependencies(${MFEM_CHECK_TARGET_NAME} ex1p) +-endif() ++message(STATUS "MFEM Miniapps and Examples disabled by patch!") + + #------------------------------------------------------------------------------- + # Documentation diff --git a/build-config/mfem/meson.build b/build-config/mfem/meson.build new file mode 100644 index 0000000..84f69c8 --- /dev/null +++ b/build-config/mfem/meson.build @@ -0,0 +1,24 @@ +cmake = import('cmake') +patchFile = files('disable_mfem_selfcheck.patch') + +patch_check = run_command('grep', '-q', 'MFEM_CHECK_TARGET_NAME', 'subprojects/mfem/CMakeLists.txt', check: false) +if patch_check.returncode() == 0 + message('Patching MFEM CMakeLists.txt to remove self checks') + run_command('patch', '-p4', '-d', '../../subprojects/mfem', '-i', patchFile[0].full_path(), check: true) +else + message('MFEM CMakeLists.txt already patched') +endif + +mfem_cmake_options = cmake.subproject_options() +mfem_cmake_options.add_cmake_defines({ + 'MFEM_ENABLE_EXAMPLES': 'OFF', + 'MFEM_ENABLE_TESTING': 'OFF', + 'MFEM_ENABLE_MINIAPPS': 'OFF', + 'MFEM_USE_BENCMARK': 'OFF', +}) + +mfem_sp = cmake.subproject( + 'mfem', + options: mfem_cmake_options) +mfem_dep = mfem_sp.dependency('mfem') +add_project_arguments('-I' + meson.current_build_dir() + '/subprojects/mfem/__CMake_build/config', language: 'cpp') \ No newline at end of file diff --git a/meson.build b/meson.build index 43145c8..fa228b5 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,10 @@ project('4DSSE', 'cpp', version: '0.0.1a', default_options: ['cpp_std=c++23']) # Add default visibility for all C++ targets add_project_arguments('-fvisibility=default', language: 'cpp') +# Build external dependencies +subdir('build-config') +# Build the main project subdir('src') if get_option('build_tests') subdir('tests') diff --git a/subprojects/mfem.wrap b/subprojects/mfem.wrap new file mode 100644 index 0000000..43c167b --- /dev/null +++ b/subprojects/mfem.wrap @@ -0,0 +1,5 @@ +[wrap-git] +url = https://github.com/mfem/mfem.git +revision = master + +[cmake] \ No newline at end of file From f4be5b37336c3e3f7264f1d675ac3a68a5aa160a Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Wed, 12 Feb 2025 16:44:10 -0500 Subject: [PATCH 4/5] feat(poly): added skeleton of polytrope model the polytrope module will be used as an initial guess to the solver. A skeleton of this has been imported from https://github.com/tboudreaux/FEMPolytrope This module will need major updates still to handle 3D, proper boundary conditions, and to incorporate it with the rest of our meshing scheme --- src/poly/coeff/meson.build | 23 +++ src/poly/coeff/private/polyCoeff.cpp | 18 +++ src/poly/coeff/public/polyCoeff.h | 8 ++ src/poly/meson.build | 3 + src/poly/solver/meson.build | 0 src/poly/utils/meson.build | 24 ++++ src/poly/utils/private/polyIO.cpp | 23 +++ src/poly/utils/private/polyMFEMUtils.cpp | 175 +++++++++++++++++++++++ src/poly/utils/public/polyIO.h | 0 src/poly/utils/public/polyMFEMUtils.h | 43 ++++++ 10 files changed, 317 insertions(+) create mode 100644 src/poly/coeff/meson.build create mode 100644 src/poly/coeff/private/polyCoeff.cpp create mode 100644 src/poly/coeff/public/polyCoeff.h create mode 100644 src/poly/meson.build create mode 100644 src/poly/solver/meson.build create mode 100644 src/poly/utils/meson.build create mode 100644 src/poly/utils/private/polyIO.cpp create mode 100644 src/poly/utils/private/polyMFEMUtils.cpp create mode 100644 src/poly/utils/public/polyIO.h create mode 100644 src/poly/utils/public/polyMFEMUtils.h diff --git a/src/poly/coeff/meson.build b/src/poly/coeff/meson.build new file mode 100644 index 0000000..112a1ff --- /dev/null +++ b/src/poly/coeff/meson.build @@ -0,0 +1,23 @@ +polyCoeff_sources = files( + 'private/coeff.cpp' +) + +polyCoeff_headers = files( + 'public/coeff.h' +) + +libPolyCoeff = static_library('polyCoeff', + polyCoeff_sources, + include_directories : include_directories('.'), + cpp_args: ['-fvisibility=default'], + dependencies: [mfem_dep], + install: true +) + + +polyCoeff_dep = declare_dependency( + include_directories : include_directories('.'), + link_with : libPolyCoeff, + sources : polyCoeff_sources, + dependencies : [mfem_dep] +) \ No newline at end of file diff --git a/src/poly/coeff/private/polyCoeff.cpp b/src/poly/coeff/private/polyCoeff.cpp new file mode 100644 index 0000000..ad4d117 --- /dev/null +++ b/src/poly/coeff/private/polyCoeff.cpp @@ -0,0 +1,18 @@ +#include "mfem.hpp" +#include + +#include "coeff.h" + +double xi_coeff_func(const mfem::Vector &x) { + return std::pow(x(0), 2); +} + +void vec_xi_coeff_func(const mfem::Vector &x, mfem::Vector &v) { + v.SetSize(1); + v[0] = -std::pow(x(0), 2); +} + +double theta_initial_guess(const mfem::Vector &x, double root) { + double xi = x[0]; + return 1-std::pow(xi/root, 2); +} \ No newline at end of file diff --git a/src/poly/coeff/public/polyCoeff.h b/src/poly/coeff/public/polyCoeff.h new file mode 100644 index 0000000..46204f1 --- /dev/null +++ b/src/poly/coeff/public/polyCoeff.h @@ -0,0 +1,8 @@ +#include "mfem.hpp" +#include + +double xi_coeff_func(const mfem::Vector &x); + +void vec_xi_coeff_func(const mfem::Vector &x, mfem::Vector &v); + +double theta_initial_guess(const mfem::Vector &x, double root); \ No newline at end of file diff --git a/src/poly/meson.build b/src/poly/meson.build new file mode 100644 index 0000000..d9c272f --- /dev/null +++ b/src/poly/meson.build @@ -0,0 +1,3 @@ +subdir('coeff') +subdir('utils') +subdir('solver') \ No newline at end of file diff --git a/src/poly/solver/meson.build b/src/poly/solver/meson.build new file mode 100644 index 0000000..e69de29 diff --git a/src/poly/utils/meson.build b/src/poly/utils/meson.build new file mode 100644 index 0000000..fc072eb --- /dev/null +++ b/src/poly/utils/meson.build @@ -0,0 +1,24 @@ +polyutils_sources = files( + 'private/polyIO.cpp', + 'private/polyMFEMUtils.cpp' +) + +polyutils_headers = files( + 'public/polyIO.h', + 'public/polyMFEMUtils.h' +) + +libpolyutils = static_library('polyutils', + polyutils_sources, + include_directories : include_directories('.'), + cpp_args: ['-fvisibility=default'], + dependencies: [mfem_dep], + install: true +) + +libpolyutils_dep = declare_dependency( + include_directories : include_directories('.'), + link_with : libpolyutils, + sources : polyutils_sources, + dependencies : [mfem_dep] +) diff --git a/src/poly/utils/private/polyIO.cpp b/src/poly/utils/private/polyIO.cpp new file mode 100644 index 0000000..8eaf25b --- /dev/null +++ b/src/poly/utils/private/polyIO.cpp @@ -0,0 +1,23 @@ +#include "mfem.hpp" +#include +#include + +#include "io.h" + +void write_solution_to_csv(const mfem::GridFunction &u, const mfem::Mesh &mesh, const std::string &filename) { + std::ofstream file(filename); + if (!file.is_open()) { + std::cerr << "Error: Could not open " << filename << " for writing." << std::endl; + return; + } + + file << "xi,u\n"; // CSV header + + for (int i = 0; i < u.Size(); i++) { + double xi = mesh.GetVertex(i)[0]; // Get spatial coordinate + file << xi << "," << u[i] << "\n"; // Write to CSV + } + + file.close(); + std::cout << "Solution written to " << filename << std::endl; +} \ No newline at end of file diff --git a/src/poly/utils/private/polyMFEMUtils.cpp b/src/poly/utils/private/polyMFEMUtils.cpp new file mode 100644 index 0000000..781efab --- /dev/null +++ b/src/poly/utils/private/polyMFEMUtils.cpp @@ -0,0 +1,175 @@ +#include "mfem.hpp" +#include +#include +#include + +#include "polyMFEMUtils.h" + +NonlinearPowerIntegrator::NonlinearPowerIntegrator( + mfem::FunctionCoefficient &coeff, + double n) : coeff_(coeff), polytropicIndex(n) { + +} + +void NonlinearPowerIntegrator::AssembleElementVector( + const mfem::FiniteElement &el, + mfem::ElementTransformation &Trans, + const mfem::Vector &elfun, + mfem::Vector &elvect) { + + const mfem::IntegrationRule *ir = &mfem::IntRules.Get(el.GetGeomType(), 2 * el.GetOrder() + 3); + int dof = el.GetDof(); + elvect.SetSize(dof); + elvect = 0.0; + + mfem::Vector shape(dof); + + for (int iqp = 0; iqp < ir->GetNPoints(); iqp++) { + mfem::IntegrationPoint ip = ir->IntPoint(iqp); + Trans.SetIntPoint(&ip); + double weight = ip.weight * Trans.Weight(); + + el.CalcShape(ip, shape); + + double u_val = 0.0; + for (int j = 0; j < dof; j++) { + u_val += elfun(j) * shape(j); + } + double u_safe = std::max(u_val, 0.0); + double u_nl = std::pow(u_safe, polytropicIndex); + + double coeff_val = coeff_.Eval(Trans, ip); + double x2_u_nl = coeff_val * u_nl; + + for (int i = 0; i < dof; i++){ + elvect(i) += shape(i) * x2_u_nl * weight; + } + } +} + +void NonlinearPowerIntegrator::AssembleElementGrad ( + const mfem::FiniteElement &el, + mfem::ElementTransformation &Trans, + const mfem::Vector &elfun, + mfem::DenseMatrix &elmat) { + + const mfem::IntegrationRule *ir = &mfem::IntRules.Get(el.GetGeomType(), 2 * el.GetOrder() + 3); + int dof = el.GetDof(); + elmat.SetSize(dof); + elmat = 0.0; + mfem::Vector shape(dof); + + for (int iqp = 0; iqp < ir->GetNPoints(); iqp++) { + mfem::IntegrationPoint ip = ir->IntPoint(iqp); + Trans.SetIntPoint(&ip); + double weight = ip.weight * Trans.Weight(); + + el.CalcShape(ip, shape); + + double u_val = 0.0; + + for (int j = 0; j < dof; j++) { + u_val += elfun(j) * shape(j); + } + double coeff_val = coeff_.Eval(Trans, ip); + + + // Calculate the Jacobian + double u_safe = std::max(u_val, 0.0); + double d_u_nl = coeff_val * polytropicIndex * std::pow(u_safe, polytropicIndex - 1); + double x2_d_u_nl = d_u_nl; + + for (int i = 0; i < dof; i++) { + for (int j = 0; j < dof; j++) { + elmat(i, j) += shape(i) * x2_d_u_nl * shape(j) * weight; + } + } + + } +} + +BilinearIntegratorWrapper::BilinearIntegratorWrapper( + mfem::BilinearFormIntegrator *integratorInput + ) : integrator(integratorInput) { } + +BilinearIntegratorWrapper::~BilinearIntegratorWrapper() { + delete integrator; +} + +void BilinearIntegratorWrapper::AssembleElementVector( + const mfem::FiniteElement &el, + mfem::ElementTransformation &Trans, + const mfem::Vector &elfun, + mfem::Vector &elvect) { + int dof = el.GetDof(); + mfem::DenseMatrix elMat(dof); + integrator->AssembleElementMatrix(el, Trans, elMat); + elvect.SetSize(dof); + elvect = 0.0; + for (int i = 0; i < dof; i++) + { + double sum = 0.0; + for (int j = 0; j < dof; j++) + { + sum += elMat(i, j) * elfun(j); + } + elvect(i) = sum; + } +} + +void BilinearIntegratorWrapper::AssembleElementGrad(const mfem::FiniteElement &el, + mfem::ElementTransformation &Trans, + const mfem::Vector &elfun, + mfem::DenseMatrix &elmat) { + int dof = el.GetDof(); + elmat.SetSize(dof, dof); + elmat = 0.0; + integrator->AssembleElementMatrix(el, Trans, elmat); +} + +CompositeNonlinearIntegrator::CompositeNonlinearIntegrator() { } + + +CompositeNonlinearIntegrator::~CompositeNonlinearIntegrator() { + for (size_t i = 0; i < integrators.size(); i++) { + delete integrators[i]; + } +} + +void CompositeNonlinearIntegrator::add_integrator(mfem::NonlinearFormIntegrator *integrator) { + integrators.push_back(integrator); +} + +void CompositeNonlinearIntegrator::AssembleElementVector( + const mfem::FiniteElement &el, + mfem::ElementTransformation &Trans, + const mfem::Vector &elfun, + mfem::Vector &elvect) { + int dof = el.GetDof(); + elvect.SetSize(dof); + elvect = 0.0; + mfem::Vector temp(dof); + + for (size_t i = 0; i < integrators.size(); i++) { + temp= 0.0; + integrators[i]->AssembleElementVector(el, Trans, elfun, temp); + elvect.Add(1.0, temp); + } +} + +void CompositeNonlinearIntegrator::AssembleElementGrad( + const mfem::FiniteElement &el, + mfem::ElementTransformation &Trans, + const mfem::Vector &elfun, + mfem::DenseMatrix &elmat) { + int dof = el.GetDof(); + elmat.SetSize(dof, dof); + elmat = 0.0; + mfem::DenseMatrix temp(dof); + temp.SetSize(dof, dof); + for (size_t i = 0; i < integrators.size(); i++) { + temp = 0.0; + integrators[i] -> AssembleElementGrad(el, Trans, elfun, temp); + elmat.Add(1.0, temp); + } +} \ No newline at end of file diff --git a/src/poly/utils/public/polyIO.h b/src/poly/utils/public/polyIO.h new file mode 100644 index 0000000..e69de29 diff --git a/src/poly/utils/public/polyMFEMUtils.h b/src/poly/utils/public/polyMFEMUtils.h new file mode 100644 index 0000000..33985aa --- /dev/null +++ b/src/poly/utils/public/polyMFEMUtils.h @@ -0,0 +1,43 @@ +#include "mfem.hpp" +#include + + +void write_solution_to_csv(const mfem::GridFunction &u, const mfem::Mesh &mesh, const std::string &filename); + +class NonlinearPowerIntegrator: public mfem::NonlinearFormIntegrator { +private: + mfem::FunctionCoefficient coeff_; + double polytropicIndex; +public: + NonlinearPowerIntegrator(mfem::FunctionCoefficient &coeff, double n); + + virtual void AssembleElementVector(const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::Vector &elvect) override; + virtual void AssembleElementGrad (const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::DenseMatrix &elmat) override; +}; + +class BilinearIntegratorWrapper : public mfem::NonlinearFormIntegrator +{ +private: + mfem::BilinearFormIntegrator *integrator; +public: + BilinearIntegratorWrapper(mfem::BilinearFormIntegrator *integratorInput); + + virtual ~BilinearIntegratorWrapper() ; + + virtual void AssembleElementVector(const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::Vector &elvect) override; + virtual void AssembleElementGrad(const mfem::FiniteElement &el,mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::DenseMatrix &elmat) override; +}; + +class CompositeNonlinearIntegrator: public mfem::NonlinearFormIntegrator { + private: + std::vector integrators; + public: + CompositeNonlinearIntegrator(); + + virtual ~CompositeNonlinearIntegrator(); + + void add_integrator(mfem::NonlinearFormIntegrator *integrator); + + virtual void AssembleElementVector(const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::Vector &elvect) override; + virtual void AssembleElementGrad(const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::DenseMatrix &elmat) override; +}; \ No newline at end of file From 7330fb99069f78f21cc8a406821062589577afb1 Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Fri, 14 Feb 2025 10:50:07 -0500 Subject: [PATCH 5/5] feat(poly): initial build system for polytrope --- src/poly/coeff/private/polyCoeff.cpp | 30 +++++++-- src/poly/utils/private/polyIO.cpp | 2 +- src/poly/utils/public/polyIO.h | 16 +++++ src/poly/utils/public/polyMFEMUtils.h | 89 ++++++++++++++++++++++++++- 4 files changed, 130 insertions(+), 7 deletions(-) diff --git a/src/poly/coeff/private/polyCoeff.cpp b/src/poly/coeff/private/polyCoeff.cpp index ad4d117..c4076a0 100644 --- a/src/poly/coeff/private/polyCoeff.cpp +++ b/src/poly/coeff/private/polyCoeff.cpp @@ -3,16 +3,38 @@ #include "coeff.h" -double xi_coeff_func(const mfem::Vector &x) { +/** + * @brief Computes the xi coefficient function. + * + * @param x Input vector. + * @return double The computed xi coefficient. + */ +double xi_coeff_func(const mfem::Vector &x) +{ return std::pow(x(0), 2); } -void vec_xi_coeff_func(const mfem::Vector &x, mfem::Vector &v) { +/** + * @brief Computes the vector xi coefficient function. + * + * @param x Input vector. + * @param v Output vector to store the computed xi coefficient. + */ +void vec_xi_coeff_func(const mfem::Vector &x, mfem::Vector &v) +{ v.SetSize(1); v[0] = -std::pow(x(0), 2); } -double theta_initial_guess(const mfem::Vector &x, double root) { +/** + * @brief Computes the initial guess for theta. + * + * @param x Input vector. + * @param root Root value used in the computation. + * @return double The initial guess for theta. + */ +double theta_initial_guess(const mfem::Vector &x, double root) +{ double xi = x[0]; - return 1-std::pow(xi/root, 2); + return 1 - std::pow(xi / root, 2); } \ No newline at end of file diff --git a/src/poly/utils/private/polyIO.cpp b/src/poly/utils/private/polyIO.cpp index 8eaf25b..d540cb0 100644 --- a/src/poly/utils/private/polyIO.cpp +++ b/src/poly/utils/private/polyIO.cpp @@ -2,7 +2,7 @@ #include #include -#include "io.h" +#include "polyIO.h" void write_solution_to_csv(const mfem::GridFunction &u, const mfem::Mesh &mesh, const std::string &filename) { std::ofstream file(filename); diff --git a/src/poly/utils/public/polyIO.h b/src/poly/utils/public/polyIO.h index e69de29..9ca7ceb 100644 --- a/src/poly/utils/public/polyIO.h +++ b/src/poly/utils/public/polyIO.h @@ -0,0 +1,16 @@ +#ifndef POLY_IO_H +#define POLY_IO_H + +#include "mfem.hpp" +#include + +/** + * @brief Writes the solution to a CSV file. + * + * @param u The GridFunction containing the solution. + * @param mesh The mesh associated with the solution. + * @param filename The name of the CSV file to write to. + */ +void write_solution_to_csv(const mfem::GridFunction &u, const mfem::Mesh &mesh, const std::string &filename); + +#endif // POLY_IO_H \ No newline at end of file diff --git a/src/poly/utils/public/polyMFEMUtils.h b/src/poly/utils/public/polyMFEMUtils.h index 33985aa..ac07264 100644 --- a/src/poly/utils/public/polyMFEMUtils.h +++ b/src/poly/utils/public/polyMFEMUtils.h @@ -4,40 +4,125 @@ void write_solution_to_csv(const mfem::GridFunction &u, const mfem::Mesh &mesh, const std::string &filename); +/** + * @brief A class for nonlinear power integrator. + */ class NonlinearPowerIntegrator: public mfem::NonlinearFormIntegrator { private: mfem::FunctionCoefficient coeff_; double polytropicIndex; public: + /** + * @brief Constructor for NonlinearPowerIntegrator. + * + * @param coeff The function coefficient. + * @param n The polytropic index. + */ NonlinearPowerIntegrator(mfem::FunctionCoefficient &coeff, double n); + /** + * @brief Assembles the element vector. + * + * @param el The finite element. + * @param Trans The element transformation. + * @param elfun The element function. + * @param elvect The element vector to be assembled. + */ virtual void AssembleElementVector(const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::Vector &elvect) override; + + /** + * @brief Assembles the element gradient. + * + * @param el The finite element. + * @param Trans The element transformation. + * @param elfun The element function. + * @param elmat The element matrix to be assembled. + */ virtual void AssembleElementGrad (const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::DenseMatrix &elmat) override; }; +/** + * @brief A wrapper class for bilinear integrator. + */ class BilinearIntegratorWrapper : public mfem::NonlinearFormIntegrator { private: mfem::BilinearFormIntegrator *integrator; public: + /** + * @brief Constructor for BilinearIntegratorWrapper. + * + * @param integratorInput The bilinear form integrator input. + */ BilinearIntegratorWrapper(mfem::BilinearFormIntegrator *integratorInput); - virtual ~BilinearIntegratorWrapper() ; + /** + * @brief Destructor for BilinearIntegratorWrapper. + */ + virtual ~BilinearIntegratorWrapper(); + /** + * @brief Assembles the element vector. + * + * @param el The finite element. + * @param Trans The element transformation. + * @param elfun The element function. + * @param elvect The element vector to be assembled. + */ virtual void AssembleElementVector(const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::Vector &elvect) override; - virtual void AssembleElementGrad(const mfem::FiniteElement &el,mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::DenseMatrix &elmat) override; + + /** + * @brief Assembles the element gradient. + * + * @param el The finite element. + * @param Trans The element transformation. + * @param elfun The element function. + * @param elmat The element matrix to be assembled. + */ + virtual void AssembleElementGrad(const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::DenseMatrix &elmat) override; }; +/** + * @brief A class for composite nonlinear integrator. + */ class CompositeNonlinearIntegrator: public mfem::NonlinearFormIntegrator { private: std::vector integrators; public: + /** + * @brief Constructor for CompositeNonlinearIntegrator. + */ CompositeNonlinearIntegrator(); + /** + * @brief Destructor for CompositeNonlinearIntegrator. + */ virtual ~CompositeNonlinearIntegrator(); + /** + * @brief Adds an integrator to the composite integrator. + * + * @param integrator The nonlinear form integrator to add. + */ void add_integrator(mfem::NonlinearFormIntegrator *integrator); + /** + * @brief Assembles the element vector. + * + * @param el The finite element. + * @param Trans The element transformation. + * @param elfun The element function. + * @param elvect The element vector to be assembled. + */ virtual void AssembleElementVector(const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::Vector &elvect) override; + + /** + * @brief Assembles the element gradient. + * + * @param el The finite element. + * @param Trans The element transformation. + * @param elfun The element function. + * @param elmat The element matrix to be assembled. + */ virtual void AssembleElementGrad(const mfem::FiniteElement &el, mfem::ElementTransformation &Trans, const mfem::Vector &elfun, mfem::DenseMatrix &elmat) override; }; \ No newline at end of file