Skip to content
Snippets Groups Projects
Commit 223644ef authored by Marcin Kirsz's avatar Marcin Kirsz
Browse files

Merge branch 'develop-F_SQRT' into 'develop'

F_SQRT

See merge request !19
parents 51577ac2 2002b0b7
No related branches found
No related tags found
2 merge requests!20Patch/bf grid m sqrt,!19F_SQRT
Pipeline #53362 passed
Pipeline: MD

#53364

    Pipeline: MLIP

    #53363

      ......@@ -8,13 +8,26 @@
      class F_Base {
      public:
      virtual double calc_F(double rho, size_t c)=0;
      virtual double calc_dF(double rho, size_t c)=0;
      /**
      * @brief Calculates the embedding function value.
      * @param rho Electron density.
      * @param p Index for model parameters.
      * @return Function value F(rho).
      */
      virtual double calc_F(double rho, size_t p) = 0;
      /**
      * @brief Calculates the first derivative of the embedding function.
      * @param rho Electron density.
      * @param p Index for model parameters.
      * @return Derivative dF/d(rho).
      */
      virtual double calc_dF(double rho, size_t p) = 0;
      };
      /**
      * @class F_RLR
      * @brief Implements an embedding function of the form: \f$ s x \log(c x) \f$
      * @brief Implements an embedding function of the form: \f$ s \rho \log(c \rho) \f$
      *
      * This class supports embedding functions characterized by two main parameters:
      * - **SEMBFUNC**: Controls the depth, \f$ s \f$, of the embedding function.
      ......@@ -32,10 +45,61 @@ private:
      public:
      F_RLR(Config &conf);
      F_RLR();
      double calc_F(double rho,size_t c);
      double calc_dF(double rho,size_t c);
      double calc_F(double rho,size_t p) override;
      double calc_dF(double rho,size_t p) override;
      //~F_RLR() {
      // Do not delete config!
      //}
      };
      /**
      * @class F_SQRT
      * @brief Implements \f$ s \sqrt(\rho) \f$.
      *
      * Optional parameter:
      * - **SEMBFUNC**: Controls the strength, \f$ s \f$, of the embedding function.
      * If no; value is provided, the default is 1.
      *
      */
      class F_SQRT : public F_Base {
      private:
      Config *config = nullptr; ///< Configuration object (not owned by this class).
      v_type sgrid; ///< Controls depth or scaling factor.
      public:
      /**
      * @brief Constructs F_SQRT from a Config object.
      * @param conf Reference to a Config instance.
      *
      * The constructor extracts or initializes relevant parameter for the model from
      * the provided configuration.
      */
      F_SQRT(Config &conf);
      /**
      * @brief Default constructor for F_SQRT.
      *
      * This version does not initialize from a Config object. Users must
      * manually set sgrid if this constructor is used.
      */
      F_SQRT();
      /**
      * @brief Calculates the embedding function value using a square-root dependence.
      * @param rho Electron density.
      * @param p Index for model parameters. Here p=0
      * @return Embedding function value \f$ F(\rho) = s_{p} \sqrt{ c_{p} \rho } \f$.
      */
      double calc_F(double rho, size_t p) override;
      /**
      * @brief Calculates the derivative of the square-root embedding function.
      * @param rho Electron density.
      * @param p Index for model parameters. Here p=0
      * @return First derivative \f$ dF/d\rho = \frac{s_{p} \, {2 \sqrt{\rho}} \f$.
      */
      double calc_dF(double rho, size_t p) override;
      };
      #endif
      ......@@ -12,15 +12,45 @@ F_RLR::F_RLR(Config &conf):
      }
      F_RLR::F_RLR():
      config(nullptr)
      {}
      double F_RLR::calc_F(double rho,size_t p) {
      if (rho>0)
      return sgrid[p]*rho*log(cgrid[p]*rho);
      return 0;
      }
      double F_RLR::calc_dF(double rho,size_t p) {
      if (rho>0)
      return sgrid[p]*(log(cgrid[p]*rho)+1);
      return sgrid[p];
      }
      //////////////////////////
      // F_SQRT
      F_SQRT::F_SQRT(Config &conf):
      config(&conf)
      {
      if (!config->get<bool>("INITMB"))
      return;
      if (config->exist("SEMBFUNC")) {
      D_Base::get_grid(*config, "SEMBFUNC", sgrid);
      } else {
      sgrid.resize(1);
      sgrid[0] = 1.0;
      }
      }
      double F_RLR::calc_F(double rho,size_t c) {
      F_SQRT::F_SQRT():
      config(nullptr)
      {
      sgrid.resize(1);
      sgrid[0] = 1.0;
      }
      double F_SQRT::calc_F(double rho,size_t p) {
      if (rho>0)
      return sgrid[c]*rho*log(cgrid[c]*rho);
      return sgrid[p]*std::sqrt(rho);
      return 0;
      }
      double F_RLR::calc_dF(double rho,size_t c) {
      double F_SQRT::calc_dF(double rho,size_t p) {
      if (rho>0)
      return sgrid[c]*(log(cgrid[c]*rho)+1);
      return sgrid[c];
      return 0.5*sgrid[p]/(std::sqrt(rho));
      return 0;
      }
      #include "catch2/catch.hpp"
      #include <tadah/models/descriptors/dm/dm_func.h>
      #include <cmath>
      #include <cassert>
      /**
      * @test Checks F_RLR behavior with a simple configuration.
      * Ensures no NaN is returned and verifies plausibility of results.
      */
      TEST_CASE("F_RLR: Basic Function and Derivative", "[F_RLR]")
      {
      // Reason: "INITMB=true" triggers parameter grid load in F_RLR constructor
      Config c;
      c.remove("INITMB");
      c.add("INITMB", "true");
      c.add("SEMBFUNC", 0.2);
      c.add("CEMBFUNC", 0.3);
      F_RLR rlr(c);
      double rho = 2.0;
      size_t p = 0; // Single parameter index
      double valF = rlr.calc_F(rho, p);
      double valdF = rlr.calc_dF(rho, p);
      // Reason: Checking for no NaN or inf
      REQUIRE_FALSE(std::isnan(valF));
      REQUIRE_FALSE(std::isinf(valF));
      REQUIRE_FALSE(std::isnan(valdF));
      REQUIRE_FALSE(std::isinf(valdF));
      // Basic range checks for sanity (not strict correctness)
      REQUIRE(valF != 0.0);
      REQUIRE(valdF != 0.0);
      }
      /**
      * @test Checks F_SQRT behavior with a simple configuration.
      * Ensures no NaN is returned and verifies plausibility of results.
      */
      TEST_CASE("F_SQRT: Basic Function and Derivative", "[F_SQRT]")
      {
      // Reason: "INITMB=true" triggers sgrid load in F_SQRT constructor
      Config c;
      c.remove("INITMB");
      c.add("INITMB", "true");
      c.add("SEMBFUNC", 0.2);
      F_SQRT sqrt_func(c);
      double rho = 4.0;
      size_t p = 0; // Single parameter index
      double valF = sqrt_func.calc_F(rho, p);
      double valdF = sqrt_func.calc_dF(rho, p);
      // Reason: Checking for no NaN or inf
      REQUIRE_FALSE(std::isnan(valF));
      REQUIRE_FALSE(std::isinf(valF));
      REQUIRE_FALSE(std::isnan(valdF));
      REQUIRE_FALSE(std::isinf(valdF));
      // Basic numeric checks
      // s = 0.2, sqrt(4.0) = 2.0, so expected = 0.4 (ideal, ignoring round-off)
      REQUIRE(valF == Approx(0.4).margin(1e-12));
      // Derivative: 0.5*s / sqrt(rho) => 0.5*0.2/2.0 = 0.05
      REQUIRE(valdF == Approx(0.05).margin(1e-12));
      }
      0% Loading or .
      You are about to add 0 people to the discussion. Proceed with caution.
      Finish editing this message first!
      Please register or to comment