/* *********************************************************************** // // Copyright (C) 2025 -- The 4D-STAR Collaboration // File Author: Emily Boudreaux // Last Modified: April 21, 2025 // // 4DSSE is free software; you can use it and/or modify // it under the terms and restrictions the GNU General Library Public // License version 3 (GPLv3) as published by the Free Software Foundation. // // 4DSSE is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with this software; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // *********************************************************************** */ #pragma once #include "mfem.hpp" #include #include "config.h" #include "probe.h" /** * @file integrators.h * @brief A collection of utilities for working with MFEM and solving the lane-emden equation. */ namespace serif { namespace polytrope { /** * @namespace polyMFEMUtils * @brief A namespace for utilities for working with MFEM and solving the lane-emden equation. */ namespace polyMFEMUtils { /** * @brief A class for nonlinear power integrator. */ class NonlinearPowerIntegrator: public mfem::NonlinearFormIntegrator { public: /** * @brief Constructor for NonlinearPowerIntegrator. * * @param coeff The function coefficient. * @param n The polytropic index. */ NonlinearPowerIntegrator(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; private: serif::config::Config& m_config = serif::config::Config::getInstance(); serif::probe::LogManager& m_logManager = serif::probe::LogManager::getInstance(); quill::Logger* m_logger = m_logManager.getLogger("log"); double m_polytropicIndex; double m_epsilon; static constexpr double m_regularizationRadius = 0.15; ///< Regularization radius for the epsilon function, used to avoid singularities in the power law. static constexpr double m_regularizationCoeff = 1.0/6.0; ///< Coefficient for the regularization term, used to ensure smoothness in the power law. }; inline double dfmod(const double epsilon, const double n) { if (n == 0.0) { return 0.0; } if (n == 1.0) { return 1.0; } return n * std::pow(epsilon, n - 1.0); } inline double fmod(const double theta, const double n, const double epsilon) { if (n == 0.0) { return 1.0; } // For n != 0 const double y_prime_at_epsilon = dfmod(epsilon, n); // Uses the robust dfmod const double y_at_epsilon = std::pow(epsilon, n); // epsilon^n // f_mod(theta) = y_at_epsilon + y_prime_at_epsilon * (theta - epsilon) return y_at_epsilon + y_prime_at_epsilon * (theta - epsilon); } } // namespace polyMFEMUtils } // namespace polytrope } // namespace serif