diff --git a/include/tadah/models/cutoffs.h b/include/tadah/models/cutoffs.h index 54036451463548002f1ca52de519ccc5be566d00..882f0c99e37ae34e3350c52e199c0ab975280d34 100644 --- a/include/tadah/models/cutoffs.h +++ b/include/tadah/models/cutoffs.h @@ -139,5 +139,20 @@ class Cut_Poly2 : public Cut_Base { double calc(double r); double calc_prime(double r); }; +class Cut_Cos_S : public Cut_Base { + private: + std::string lab = "Cut_Cos_S"; + double rcut, rcut_sq, rcut_inv; + double rcut_inner; + public: + Cut_Cos_S(); + Cut_Cos_S(double rcut); + std::string label() ; + void set_rcut(const double r); + double get_rcut(); + double get_rcut_sq(); + double calc(double r); + double calc_prime(double r); +}; //template<> inline Registry<Cut_Base,double>::Map Registry<Cut_Base,double>::registry{}; #endif diff --git a/include/tadah/models/dc_selector.h b/include/tadah/models/dc_selector.h index 0ffc2ab70f2b69051a3f668bbd08795b0ba36447..07a3539b879f0b8d3d9cdd14787f90acb161135c 100644 --- a/include/tadah/models/dc_selector.h +++ b/include/tadah/models/dc_selector.h @@ -15,7 +15,7 @@ class DC_Selector { D3_Base *d3b=nullptr; DM_Base *dmb=nullptr; - Config config; + //Config config; DC_Selector () {}; @@ -25,21 +25,21 @@ class DC_Selector { { std::cout << "Copy constructor called\n"; } - // Const Assignment operator - // Instead of deep copying - // we use a trick where we just copy - // the config file and run init() - // as in a costructor - DC_Selector& operator=(const DC_Selector& dc) - { - config=dc.config; - init(); - return *this; - } + // Const Assignment operator + // Instead of deep copying + // we use a trick where we just copy + // the config file and run init() + // as in a costructor + // DC_Selector& operator=(const DC_Selector& dc) + // { + // //config=dc.config; + // //init(); + // return *this; + // } // Assignment operator DC_Selector& operator=(DC_Selector& dc) { - std::swap(config,dc.config); + //std::swap(config,dc.config); std::swap(c2b,dc.c2b); std::swap(c3b,dc.c3b); std::swap(cmb,dc.cmb); @@ -49,12 +49,12 @@ class DC_Selector { return *this; } - DC_Selector (const Config &c): - config(c) + DC_Selector (Config &c) + //config(c) { - init(); + init(c); }; - void init() { + void init(Config &config) { double rcutzero = 0.0; // for dummies size_t bias=0; @@ -62,19 +62,19 @@ class DC_Selector { bias++; if (config.get<bool>("INIT2B")) { - double rcut2b = config.get<double>("RCUT2B"); + double rcut2b = config.get<double>("RCUT2BMAX"); c2b = CONFIG::factory<Cut_Base,double>( config.get<std::string>("RCTYPE2B"), rcut2b ); d2b = CONFIG::factory<D2_Base,Config&>( config.get<std::string>("TYPE2B"), config ); - d2b->fidx = bias; + d2b->set_fidx(bias); } else { c2b = CONFIG::factory<Cut_Base,double>( "Cut_Dummy", rcutzero ); d2b = CONFIG::factory<D2_Base,Config&>( "D2_Dummy", config ); - d2b->fidx = bias; + d2b->set_fidx(bias); } if (config.get<bool>("INIT3B")) { - double rcut3b = config.get<double>("RCUT3B"); + double rcut3b = config.get<double>("RCUT3BMAX"); c3b = CONFIG::factory<Cut_Base,double>( config.get<std::string>("RCTYPE3B"), rcut3b ); d3b = CONFIG::factory<D3_Base,Config&>( config.get<std::string>("TYPE3B"), config ); // d3b->fidx = bias; @@ -86,15 +86,15 @@ class DC_Selector { } if (config.get<bool>("INITMB")) { - double rcutmb = config.get<double>("RCUTMB"); + double rcutmb = config.get<double>("RCUTMBMAX"); cmb = CONFIG::factory<Cut_Base,double>( config.get<std::string>("RCTYPEMB"), rcutmb ); dmb = CONFIG::factory<DM_Base,Config&>( config.get<std::string>("TYPEMB"), config ); - dmb->fidx = bias + d2b->size(); + dmb->set_fidx(bias + d2b->size()); } else { cmb = CONFIG::factory<Cut_Base,double>( "Cut_Dummy", rcutzero ); dmb = CONFIG::factory<DM_Base,Config&>( "DM_Dummy", config ); - dmb->fidx = bias + d2b->size(); + dmb->set_fidx(bias + d2b->size()); } } ~DC_Selector() diff --git a/include/tadah/models/descriptors/d2/d2_all.h b/include/tadah/models/descriptors/d2/d2_all.h index ac0a29224a720ec196de5e60780c5c3f4fe27262..4b36ad4a4c2b7f1b20942d15763b819515c5b81b 100644 --- a/include/tadah/models/descriptors/d2/d2_all.h +++ b/include/tadah/models/descriptors/d2/d2_all.h @@ -5,3 +5,7 @@ #include <tadah/models/descriptors/d2/d2_eam.h> #include <tadah/models/descriptors/d2/d2_lj.h> #include <tadah/models/descriptors/d2/d2_mie.h> +#include <tadah/models/descriptors/d2/d2_zbl.h> + +#include <tadah/models/descriptors/d2/d2_join.h> +#include <tadah/models/descriptors/d2/d2_mjoin.h> diff --git a/include/tadah/models/descriptors/d2/d2_base.h b/include/tadah/models/descriptors/d2/d2_base.h index 97d5341061d3a320784c1918819f4ba10d855f7d..8e7917c74c17ba471468ed0b9f2bff27e72ce343 100644 --- a/include/tadah/models/descriptors/d2/d2_base.h +++ b/include/tadah/models/descriptors/d2/d2_base.h @@ -1,6 +1,7 @@ #ifndef D2_BASE_H #define D2_BASE_H +#include <tadah/models/cut_all.h> #include <tadah/models/descriptors/d_base.h> /** \brief Base class for all two-body type descriptors. @@ -9,42 +10,62 @@ */ class D2_Base: public D_Base { public: - size_t fidx=0; // first index in aed and fd arrays for this descriptor + D2_Base() {}; + D2_Base(Config &c): D_Base(c) { + //if (c.get<bool>("INIT2B")) { + if (c.exist("RCUT2BMAX") && c.exist("RCTYPE2B")) { + double rcut2b = c.get<double>("RCUT2BMAX"); + set_fcut(CONFIG::factory<Cut_Base,double>( c.get<std::string>("RCTYPE2B"), rcut2b ), true); + } + else { + set_fcut(new Cut_Dummy(0), true); + } + } virtual ~D2_Base() {}; + virtual std::vector<std::string> get_init_atoms(Config &c) override; /** \brief Calculate \ref AED * * Calculate Atomic Energy Descriptor for the atom local environment. */ virtual void calc_aed( + const int Zi, + const int Zj, const double rij, const double rij_sq, - const double fc_ij, - aed_type2& aed)=0; + aed_type& aed, + const double scale=1)=0; /** \brief Calculate \ref FD * * Calculate Force Descriptor for the atom local environment. * + * For two body this is essentiall df/dr where f is a descriptor function. + * Do not include negative sign (as you mifht think E=-df/dr). The negative sign + * is included elsewhere in the code. + * * Computes x-direction only. + * * The resulting vector must be scaled by the unit directional vector delij/rij + * where delij = r_i - r_j, and rij is |r_i - r_j| */ virtual void calc_dXijdri( + const int Zi, + const int Zj, const double rij, const double rij_sq, - const double fc_ij, - const double fcp_ij, - fd_type &fd_ij)=0; + fd_type &fd_ij, + const double scale=1)=0; /** \brief Calculate \ref AED + \ref FD */ virtual void calc_all( + const int Zi, + const int Zj, const double rij, const double rij_sq, - const double fc_ij, - const double fcp_ij, - aed_type2& aed, - fd_type &fd_ij)=0; - virtual std::string label()=0; + aed_type& aed, + fd_type &fd_ij, + const double scale=1)=0; /** Central difference approximation to \ref FD * @@ -56,18 +77,15 @@ public: * fd: appropriate size container to store computation * h: central difference parameter */ - template <typename CUT> - void calc_fd_approx(CUT *fc, double r, fd_type &fd, double h=1e-8) { - aed_type2 aed_n((*this).size()); // r+h - aed_type2 aed_p((*this).size()); // r-h + void calc_fd_approx(const int Zi, const int Zj, double r, fd_type &fd, double h=1e-8) { + aed_type aed_n((*this).size()); // r+h + aed_type aed_p((*this).size()); // r-h aed_n.set_zero(); aed_p.set_zero(); double rn = r-h; double rp = r+h; - double fcp = fc->calc(rp); - double fcn = fc->calc(rn); - (*this).calc_aed(rn,rn*rn,fcn,aed_n); - (*this).calc_aed(rp,rp*rp,fcp,aed_p); + (*this).calc_aed(Zi,Zj,rn,rn*rn,aed_n); + (*this).calc_aed(Zi,Zj,rp,rp*rp,aed_p); fd(0) = (0.5/h)*(aed_p - aed_n); } }; diff --git a/include/tadah/models/descriptors/d2/d2_blip.h b/include/tadah/models/descriptors/d2/d2_blip.h index bc35c823cccd362acd7beb6a393f0b2b0803cc8d..1ba3b14a89846678768aebe1084d24c95e1feaf7 100644 --- a/include/tadah/models/descriptors/d2/d2_blip.h +++ b/include/tadah/models/descriptors/d2/d2_blip.h @@ -40,37 +40,37 @@ * \ref INIT2B \ref CGRID2B \ref SGRID2B */ class D2_Blip : public D2_Base { - private: - size_t s=0; - std::string lab="D2_Blip"; - v_type etas; - v_type mius; - double get_blip(double); - double get_dblip(double, double); - v_type gen_blip_grid(double, double); - int verbose; +private: + std::string lab="D2_Blip"; + v_type etas; + v_type mius; - public: - D2_Blip(Config &config); - void calc_aed( - const double rij, - const double rij_sq, - const double fc_ij, - aed_type2 &aed); - void calc_dXijdri( - const double rij, - const double rij_sq, - const double fc_ij, - const double fcp_ij, - fd_type &fd_ij); - void calc_all( - const double rij, - const double rij_sq, - const double fc_ij, - const double fcp_ij, - aed_type2 &aed, - fd_type &fd_ij); - size_t size(); - std::string label(); +public: + D2_Blip(); + D2_Blip(Config &config); + void calc_aed( + const int Zi, + const int Zj, + const double rij, + const double , + aed_type &aed, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + fd_type &fd_ij, + const double scale=1) override; + void calc_all( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/d2/d2_bp.h b/include/tadah/models/descriptors/d2/d2_bp.h index bff4ec90dee658eb695c152ccbc2bd423e3bee3c..6dcb726cce12f69da46b3a836e5425f0ecee2275 100644 --- a/include/tadah/models/descriptors/d2/d2_bp.h +++ b/include/tadah/models/descriptors/d2/d2_bp.h @@ -25,34 +25,37 @@ * \ref INIT2B \ref CGRID2B \ref SGRID2B */ class D2_BP : public D2_Base { - private: - size_t s=0; - std::string lab="D2_BP"; - v_type etas; - v_type mius; - int verbose; +private: + std::string lab="D2_BP"; + v_type etas; + v_type mius; - public: - D2_BP(Config &config); - void calc_aed( - const double rij, - const double , - const double fc_ij, - aed_type2 &aed); - void calc_dXijdri( - const double rij, - const double , - const double fc_ij, - const double fcp_ij, - fd_type &fd_ij); - void calc_all( - const double rij, - const double , - const double fc_ij, - const double fcp_ij, - aed_type2 &aed, - fd_type &fd_ij); - size_t size(); - std::string label(); +public: + D2_BP(); + D2_BP(Config &config); + void calc_aed( + const int Zi, + const int Zj, + const double rij, + const double , + aed_type &aed, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + fd_type &fd_ij, + const double scale=1) override; + void calc_all( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/d2/d2_dummy.h b/include/tadah/models/descriptors/d2/d2_dummy.h index f55ae6bd37a79c4e161e1df6b322fe8cb0e69b86..972ec027519d85a298f7f10288b60f2582fc94b0 100644 --- a/include/tadah/models/descriptors/d2/d2_dummy.h +++ b/include/tadah/models/descriptors/d2/d2_dummy.h @@ -10,32 +10,34 @@ * */ class D2_Dummy : public D2_Base { - private: - size_t s=0; - std::string lab="D2_Dummy"; - int verbose; - public: - D2_Dummy(); - D2_Dummy(Config &); - void calc_aed( - const double, - const double, - const double, - aed_type2 &aed); - void calc_dXijdri( - const double, - const double, - const double, - const double, - fd_type &fd_ij); - void calc_all( - const double, - const double, - const double, - const double, - aed_type2 &aed, - fd_type &fd_ij); - size_t size(); - std::string label(); +private: + std::string lab="D2_Dummy"; +public: + D2_Dummy(); + D2_Dummy(Config &); + void calc_aed( + const int Zi, + const int Zj, + const double rij, + const double , + aed_type &aed, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + fd_type &fd_ij, + const double scale=1) override; + void calc_all( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/d2/d2_eam.h b/include/tadah/models/descriptors/d2/d2_eam.h index b34afd4f86149836cf085817e7738bf950182ca0..503366e6170cd63626709343a6dd11cda424f876 100644 --- a/include/tadah/models/descriptors/d2/d2_eam.h +++ b/include/tadah/models/descriptors/d2/d2_eam.h @@ -22,58 +22,60 @@ * \ref INIT2B \ref SETFL */ class D2_EAM : public D2_Base { - private: - struct eam_file { - std::string file_path; - std::vector<double> frho; - std::vector<double> rhor; - std::vector<double> z2r; - int nrho=0; - double drho=0; - int nr; - double dr; - double rdr; - double rdrho; - double rcut; - int atomic_number; - double atomic_mass; - double lattice_param; - std::string lattice; - }; - eam_file ef; +private: + struct eam_file { + std::string file_path; + std::vector<double> frho; + std::vector<double> rhor; + std::vector<double> z2r; + int nrho=0; + double drho=0; + int nr; + double dr; + double rdr; + double rdrho; + double rcut; + int atomic_number; + double atomic_mass; + double lattice_param; + std::string lattice; + }; + eam_file ef; - std::vector<std::vector<double>> frho_spline; - std::vector<std::vector<double>> rhor_spline; - std::vector<std::vector<double>> z2r_spline; + std::vector<std::vector<double>> frho_spline; + std::vector<std::vector<double>> rhor_spline; + std::vector<std::vector<double>> z2r_spline; - int verbose; + std::string lab="D2_EAM"; + void read_setfl(); + void gen_splines(int &n, double &delta, std::vector<double> &f, std::vector<std::vector<double>> &spline); - size_t s=1; - std::string lab="D2_EAM"; - void read_setfl(); - void gen_splines(int &n, double &delta, std::vector<double> &f, std::vector<std::vector<double>> &spline); - - public: - D2_EAM(Config &config); - void calc_aed( - double rij, - const double rij_sq, - const double, - aed_type2 &aed); - void calc_dXijdri( - double rij, - const double rij_sq, - const double, - const double, - fd_type &fd_ij); - void calc_all( - double rij, - const double rij_sq, - const double, - const double, - aed_type2 &aed, - fd_type &fd_ij); - size_t size(); - std::string label(); +public: + D2_EAM(); + D2_EAM(Config &config); + void calc_aed( + const int Zi, + const int Zj, + const double rij, + const double , + aed_type &aed, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + fd_type &fd_ij, + const double scale=1) override; + void calc_all( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/d2/d2_join.h b/include/tadah/models/descriptors/d2/d2_join.h new file mode 100644 index 0000000000000000000000000000000000000000..d5c9a77a50a1a4efc4974ebf7c4a1a87f6e15760 --- /dev/null +++ b/include/tadah/models/descriptors/d2/d2_join.h @@ -0,0 +1,146 @@ +#ifndef D2_JOIN_H +#define D2_JOIN_H +#include <cstddef> +#include <tadah/models/descriptors/d2/d2_base.h> + +/** + * Meta two-body descriptor for joining two different D2 descriptors. + * + */ +template<typename D1, typename D2> +class D2_Join : public D2_Base { +private: + D1 *d1 = nullptr; + D2 *d2 = nullptr; + //std::string lab="D2_Join"; + std::string lab; +public: + D2_Join(); + ~D2_Join() { + if (d1) delete d1; + if (d2) delete d2; + } + D2_Join(Config &c): D2_Base(c) + { + // prepare configs for d1 and d2 + // first we get joined grid and we have to split it between d1 and d2 + // we have to deal with -1 -2 algorithms and manual cases + // TYPE2B 1st element is type followed be grid sizes (after expansion) + // + // TODO + // We want to be able to use this class in a recurence realtion + // where d1 <- any D2 but not D2_Join + // and d2 can be any including D2_Join + // This means that we trim config for d1 and pass + // whatever is left to d2 + v_type cgrid; + cgrid.resize(c.size("CGRID2B")); + c.get<v_type>("CGRID2B",cgrid); + v_type sgrid; + sgrid.resize(c.size("SGRID2B")); + c.get<v_type>("SGRID2B",sgrid); + Config c1=c; + Config c2=c; + c1.remove("CGRID2B"); + c1.remove("SGRID2B"); + c2.remove("CGRID2B"); + c2.remove("SGRID2B"); + try { + size_t c1_cgrid_size = c.get<double>("CGRID2B",0) < 0 ? 4 : c.get<size_t>("TYPE2B",1); + size_t c1_sgrid_size = c.get<double>("SGRID2B",0) < 0 ? 4 : c.get<size_t>("TYPE2B",1); + size_t c2_cgrid_size = c.size("CGRID2B") - c1_cgrid_size; + size_t c2_sgrid_size = c.size("SGRID2B") - c1_sgrid_size; + for (size_t i=0; i<c1_cgrid_size; ++i) { + c1.add("CGRID2B",cgrid[i]); + } + for (size_t i=0; i<c1_sgrid_size; ++i) { + c1.add("SGRID2B",sgrid[i]); + } + for (size_t i=0; i<c2_cgrid_size; ++i) { + c2.add("CGRID2B",cgrid[i+c1_cgrid_size]); + } + for (size_t i=0; i<c2_sgrid_size; ++i) { + c2.add("SGRID2B",sgrid[i+c1_sgrid_size]); + } + } + catch (const std::runtime_error& e) { + std::cerr << "Grid Configuration Error: Ensure two grid generators are " + << "used for both D2 descriptors or provide manual grids. Avoid " + << "relying on a single auto grid generation for both descriptors. " + << "Details: " << e.what() << std::endl; + } + // deal with cutoffs + c1.remove("RCTYPE2B"); c2.remove("RCTYPE2B"); + c1.remove("RCUT2B"); c2.remove("RCUT2B"); + std::vector<std::string> rctype2b(c.size("RCTYPE2B")); + std::vector<std::string> rcut2b(c.size("RCUT2B")); + c.get("RCTYPE2B",rctype2b); + c.get("RCUT2B",rcut2b); + c1.add("RCTYPE2B", rctype2b[0]); + c1.add("RCUT2B", rcut2b[0]); + rctype2b.erase(rctype2b.begin()); + rcut2b.erase(rcut2b.begin()); + c2.add("RCTYPE2B", rctype2b); + c2.add("RCUT2B", rcut2b); + // std::cout << c1 << std::endl; + // std::cout << c2 << std::endl; + d1 = new D1(c1); + d2 = new D2(c2); + + // update main config file with generated grids + cgrid.resize(c1.size("CGRID2B")+c2.size("CGRID2B")); + sgrid.resize(c1.size("SGRID2B")+c2.size("SGRID2B")); + c.remove("CGRID2B"); c.remove("SGRID2B"); + for (size_t i=0; i<c1.size("CGRID2B"); ++i) { + c.add("CGRID2B",c1.get<double>("CGRID2B",i)); + c.add("SGRID2B",c1.get<double>("SGRID2B",i)); + } + for (size_t i=0; i<c2.size("CGRID2B"); ++i) { + c.add("CGRID2B",c2.get<double>("CGRID2B",i)); + c.add("SGRID2B",c2.get<double>("SGRID2B",i)); + } + + s=d1->size()+d2->size(); + lab="KUTAbezS"+d1->label()+d1->label(); + } + void calc_aed( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + const double scale=1) override { + d1->calc_aed(Zi,Zj,rij,rij_sq,aed,scale); + d2->calc_aed(Zi,Zj,rij,rij_sq,aed,scale); + } + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + fd_type &fd_ij, + const double scale=1) override { + d1->calc_dXijdri(Zi,Zj,rij,rij_sq,fd_ij,scale); + d2->calc_dXijdri(Zi,Zj,rij,rij_sq,fd_ij,scale); + } + void calc_all( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + fd_type &fd_ij, + const double scale=1) override { + d1->calc_all(Zi,Zj,rij,rij_sq,aed,fd_ij,scale); + d2->calc_all(Zi,Zj,rij,rij_sq,aed,fd_ij,scale); + } + std::string label() override { + return lab; + } + void set_fidx(size_t fidx_) override { + d1->set_fidx(fidx_); + d2->set_fidx(d1->size()+d1->get_fidx()); + } + void init() override {}; +}; +#endif diff --git a/include/tadah/models/descriptors/d2/d2_join_n.h b/include/tadah/models/descriptors/d2/d2_join_n.h new file mode 100644 index 0000000000000000000000000000000000000000..61b95684cc934fcc8646b955a903cafe4c750e89 --- /dev/null +++ b/include/tadah/models/descriptors/d2/d2_join_n.h @@ -0,0 +1,113 @@ +#ifndef D2_JOIN_N_H +#define D2_JOIN_N_H + +#include <tadah/models/descriptors/d2/d2_base.h> +#include <tuple> +#include <string> + +/** + * Meta multi-body descriptor for joining multiple D2 descriptors. + * + * <DEVELOPMENT CODE> + * Only works with D2 without grids so essentially it is useless + */ +// template<typename... Descriptors> +// class D2_Join_N : public D2_Base { +// private: +// std::tuple<Descriptors...> descriptors; +// size_t s = 0; +// std::string lab; +// +// template<size_t Index = 0> +// typename std::enable_if<Index == sizeof...(Descriptors), void>::type +// calculate_sizes() {} +// +// template<size_t Index = 0> +// typename std::enable_if<Index < sizeof...(Descriptors), void>::type +// calculate_sizes() { +// s += std::get<Index>(descriptors).size(); +// lab += std::get<Index>(descriptors).label(); +// calculate_sizes<Index + 1>(); +// } +// +// template<size_t Index = 0> +// typename std::enable_if<Index == sizeof...(Descriptors), void>::type +// calc_aed_impl(const double, const double, const double, aed_type &) {} +// +// template<size_t Index = 0> +// typename std::enable_if<Index < sizeof...(Descriptors), void>::type +// calc_aed_impl(const double rij, const double rij_sq, const double fc_ij, aed_type &aed) { +// std::get<Index>(descriptors).calc_aed(rij, rij_sq, fc_ij, aed); +// calc_aed_impl<Index + 1>(rij, rij_sq, fc_ij, aed); +// } +// +// template<size_t Index = 0> +// typename std::enable_if<Index == sizeof...(Descriptors), void>::type +// calc_dXijdri_impl(const double, const double, const double, const double, fd_type &) {} +// +// template<size_t Index = 0> +// typename std::enable_if<Index < sizeof...(Descriptors), void>::type +// calc_dXijdri_impl(const double rij, const double rij_sq, const double fc_ij, const double fcp_ij, fd_type &fd_ij) { +// std::get<Index>(descriptors).calc_dXijdri(rij, rij_sq, fc_ij, fcp_ij, fd_ij); +// calc_dXijdri_impl<Index + 1>(rij, rij_sq, fc_ij, fcp_ij, fd_ij); +// } +// +// template<size_t Index = 0> +// typename std::enable_if<Index == sizeof...(Descriptors), void>::type +// calc_all_impl(const double, const double, const double, const double, aed_type &, fd_type &) {} +// +// template<size_t Index = 0> +// typename std::enable_if<Index < sizeof...(Descriptors), void>::type +// calc_all_impl(const double rij, const double rij_sq, const double fc_ij, const double fcp_ij, aed_type &aed, fd_type &fd_ij) { +// std::get<Index>(descriptors).calc_all(rij, rij_sq, fc_ij, fcp_ij, aed, fd_ij); +// calc_all_impl<Index + 1>(rij, rij_sq, fc_ij, fcp_ij, aed, fd_ij); +// } +// +// template<size_t Index = 0> +// typename std::enable_if<Index == sizeof...(Descriptors), void>::type +// set_fidx_impl(size_t) {} +// +// template<size_t Index = 0> +// typename std::enable_if<Index < sizeof...(Descriptors), void>::type +// set_fidx_impl(size_t fidx) { +// std::get<Index>(descriptors).set_fidx(fidx); +// set_fidx_impl<Index + 1>(fidx + std::get<Index>(descriptors).size()); +// } +// +// template<typename T> +// T create_descriptor(Config &c) { +// return T(c); +// } +// +// public: +// D2_Join_N(Config &c) : descriptors(create_descriptor<Descriptors>(c)...) { +// calculate_sizes<0>(); +// } +// +// void calc_aed(const double rij, const double rij_sq, const double fc_ij, aed_type &aed) override { +// calc_aed_impl<0>(rij, rij_sq, fc_ij, aed); +// } +// +// void calc_dXijdri(const double rij, const double rij_sq, const double fc_ij, const double fcp_ij, fd_type &fd_ij) override { +// calc_dXijdri_impl<0>(rij, rij_sq, fc_ij, fcp_ij, fd_ij); +// } +// +// void calc_all(const double rij, const double rij_sq, const double fc_ij, const double fcp_ij, aed_type &aed, fd_type &fd_ij) override { +// calc_all_impl<0>(rij, rij_sq, fc_ij, fcp_ij, aed, fd_ij); +// } +// +// size_t size() override { +// return s; +// } +// +// std::string label() override { +// return lab; +// } +// +// void set_fidx(size_t fidx_) override { +// set_fidx_impl<0>(fidx_); +// } +// }; + +#endif + diff --git a/include/tadah/models/descriptors/d2/d2_lj.h b/include/tadah/models/descriptors/d2/d2_lj.h index e281f0f7708e0e3428dcfe108718914b8e9c4f83..4d8976a57c25653310f165872440980a289f00be 100644 --- a/include/tadah/models/descriptors/d2/d2_lj.h +++ b/include/tadah/models/descriptors/d2/d2_lj.h @@ -31,31 +31,34 @@ * Required Config Key: \ref INIT2B */ class D2_LJ : public D2_Base { - private: - size_t s=2; - std::string lab="D2_LJ"; - int verbose; - public: - D2_LJ(Config &config); - void calc_aed( - const double, - const double rij_sq, - const double fc_ij, - aed_type2 &aed); - void calc_dXijdri( - const double rij, - const double rij_sq, - const double fc_ij, - const double fcp_ij, - fd_type &fd_ij); - void calc_all( - const double rij, - const double rij_sq, - const double fc_ij, - const double fcp_ij, - aed_type2 &aed, - fd_type &fd_ij); - size_t size(); - std::string label(); +private: + std::string lab="D2_LJ"; +public: + D2_LJ(); + D2_LJ(Config &config); + void calc_aed( + const int Zi, + const int Zj, + const double rij, + const double , + aed_type &aed, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + fd_type &fd_ij, + const double scale=1) override; + void calc_all( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/d2/d2_mie.h b/include/tadah/models/descriptors/d2/d2_mie.h index 6e4c16dd1215fb96c69d89b63420c8273572a269..22163c66cbe9f1905e352f401649e506d75c1add 100644 --- a/include/tadah/models/descriptors/d2/d2_mie.h +++ b/include/tadah/models/descriptors/d2/d2_mie.h @@ -17,40 +17,43 @@ * * Any cutoff can be used * - * Required Config Key: \ref INIT2B \ref SGRID2B + * Required Config Key: \ref INIT2B \ref TYPE2B * - * e.g. SGID2B 12 6 + * TYPE2B D2_MIE 12 6 * * will result in Lennard-Jones type descriptor */ class D2_MIE : public D2_Base { - private: - size_t s=2; - std::string lab="D2_MIE"; - double m,n; - v_type etas; - int verbose; - public: - D2_MIE(Config &config); - void calc_aed( - const double, - const double rij_sq, - const double fc_ij, - aed_type2 &aed); - void calc_dXijdri( - const double rij, - const double rij_sq, - const double fc_ij, - const double fcp_ij, - fd_type &fd_ij); - void calc_all( - const double rij, - const double rij_sq, - const double fc_ij, - const double fcp_ij, - aed_type2 &aed, - fd_type &fd_ij); - size_t size(); - std::string label(); +private: + std::string lab="D2_MIE"; + double m,n; + v_type etas; +public: + D2_MIE(); + D2_MIE(Config &config); + void calc_aed( + const int Zi, + const int Zj, + const double rij, + const double , + aed_type &aed, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + fd_type &fd_ij, + const double scale=1) override; + void calc_all( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/d2/d2_mjoin.h b/include/tadah/models/descriptors/d2/d2_mjoin.h new file mode 100644 index 0000000000000000000000000000000000000000..fc22f65d3554194b22c869d99038a1ffba126233 --- /dev/null +++ b/include/tadah/models/descriptors/d2/d2_mjoin.h @@ -0,0 +1,59 @@ +#ifndef D2_MJOIN_H +#define D2_MJOIN_H +#include "tadah/core/registry.h" +#include <cstddef> +#include <tadah/models/descriptors/d2/d2_base.h> +#include <tadah/models/descriptors/d_mjoin.h> + +/** \brief Meta two-body descriptor for combining multiple D2 descriptors. + * + * This descriptor provides a convenient interface for concatenating multiple two-body descriptors. + * The resulting descriptor can then be used by Tadah! like any standard two-body descriptor. + * + * Each descriptor must have a specified type in a configuration file, along with a cutoff function, + * cutoff distance, and optionally SGRID2B and CGRID2B values if applicable. + * + * When listing descriptors under the TYPE2B key, you must include parameters relevant to this descriptor. + * + * Here is an example of how to configure these descriptors: + * + * ``` + * TYPE2B D2_mJoin # <-- Meta descriptor for concatenating two-body descriptors + * TYPE2B D2_MIE 11 6 # <-- MIE exponents + * RCTYPE2B Cut_Cos + * RCUT2B 3.0 + * + * TYPE2B D2_Blip 6 6 # <-- grid sizes + * RCTYPE2B Cut_Tanh + * RCUT2B 7.5 + * SGRID2B -2 6 0.1 10 # Grid for D2_Blip, blips widths, auto generated + * CGRID2B 0 0 0 0 0 0 # Grid for D2_Blip, blip centers + * ``` + * + * Note: Grids can be specified on a single line, and the order of the grids is important. + * + * There is no limit to the number of descriptors that can be concatenated. + * + * \details + * - Ensure the types and grids are correctly specified in the configuration file. + * - The cutoff functions (RCTYPE2B) and distances (RCUT2B) must be defined for each descriptor. + * - Both SGRID2B and CGRID2B should be included if relevant, with their sizes matching the given descriptors. + */ +class D2_mJoin : public D2_Base, public D_mJoin { +private: + std::vector<D2_Base*> ds; + std::vector<Config> configs; + std::string lab = "D2_mJoin"; +public: + D2_mJoin(); + ~D2_mJoin(); + D2_mJoin(Config &c); + + void calc_aed(const int Zi, const int Zj, const double rij, const double rij_sq, aed_type &aed, const double scale=1) override; + void calc_dXijdri(const int Zi, const int Zj, const double rij, const double rij_sq, fd_type &fd_ij, const double scale=1) override; + void calc_all(const int Zi, const int Zj, const double rij, const double rij_sq, aed_type &aed, fd_type &fd_ij, const double scale=1) override; + std::string label() override; + void set_fidx(size_t fidx_) override; + void init() override; +}; +#endif diff --git a/include/tadah/models/descriptors/d2/d2_zbl.h b/include/tadah/models/descriptors/d2/d2_zbl.h new file mode 100644 index 0000000000000000000000000000000000000000..585887ebb2d3dbeb759329597d42693c1e14e3e1 --- /dev/null +++ b/include/tadah/models/descriptors/d2/d2_zbl.h @@ -0,0 +1,92 @@ +#ifndef D2_ZBL_H +#define D2_ZBL_H + +#include <tadah/models/descriptors/d2/d2_base.h> + +/** + * \brief ZBL Descriptor + * + * The ZBL (Ziegler-Biersack-Littmark) potential is an empirical potential used to model short-range interactions between atoms. + * + * The constant term \( \frac{4 \pi \varepsilon_0 e^2}{1} \) is set to 1 and will be fitted as needed. + * + * The simplified expression for the ZBL potential is given by: + * + * \f[ + * V(r) = \frac{Z_1 Z_2 }{r} \phi\left(\frac{r}{a}\right) + * \f] + * + * where \( a \) is the screening length, expressed as: + * \f[ + * a = \frac{s_0 \cdot a_0}{Z_1^{p_0} + Z_2^{p_1}} + * \f] + * + * Here, \( a_0 \), \( s_0 \), \( p_0 \), and \( p_1 \) are adjustable hyperparameters. + * Setting any of these to -1 uses the default values: + * + * - \( a_0 = 0.52917721067 \) Å + * - \( s_0 = 0.88534 \) + * - \( p_0 = 0.23 \) + * - \( p_1 = 0.23 \) + * + * + * The screening function \(\phi\) is defined as: + * \f[ + * \phi(x) = 0.1818 e^{-3.2x} + 0.5099 e^{-0.9423x} + 0.2802 e^{-0.4029x} + 0.02817 e^{-0.2016x} + * \f] + * + * Required Config Key: \ref INIT2B \ref TYPE2B + * + * - TYPE2B D2_ZBL \( a_0 \) \( s_0 \) \( p_0 \) \( p_1 \) + * + * Examples: + * + * - TYPE2B D2_ZBL 0.53 0.90 0.23 0.23 # Custom parameters + * - TYPE2B D2_ZBL -1 -1 -1 -1 # Default values + * - TYPE2B D2_ZBL 0.53 -1 -1 -1 # Mix of default and custom + * + */ +class D2_ZBL : public D2_Base { +private: + std::string lab="D2_ZBL"; + double phi(const double x); // x = r/a + // dphi/dx + double dphi(const double x); // x = r/a + double screening_length(int, int); // a = + double a0=0.52917721067; // bohr radius + double s0=0.88534; // bohr radius + double p0=0.23; // bohr radius + double p1=0.23; // bohr radius + double **a = nullptr; // precomputed screening length + int types[119]; // local index of Zi + int ntypes=0; // number of elements for this calc +public: + D2_ZBL(); + D2_ZBL(Config &config); + ~D2_ZBL(); + void calc_aed( + const int Zi, + const int Zj, + const double rij, + const double , + aed_type &aed, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + fd_type &fd_ij, + const double scale=1) override; + void calc_all( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init() override; +}; +#endif diff --git a/include/tadah/models/descriptors/d3/d3_base.h b/include/tadah/models/descriptors/d3/d3_base.h index 88c216c888064605ed6534f0acf530b22bd2ef8c..c64a76bfd218d1ff385f95fe2935d2358e3e8ef2 100644 --- a/include/tadah/models/descriptors/d3/d3_base.h +++ b/include/tadah/models/descriptors/d3/d3_base.h @@ -4,37 +4,37 @@ #include <tadah/models/descriptors/d_base.h> class D3_Base: public D_Base { - public: - virtual ~D3_Base() {}; +public: + virtual ~D3_Base() {}; - virtual void calc_aed( - const size_t fidx, - const double rij, - const double rik, - const double fc_ij, - const double fc_ik, - aed_type2& aed)=0; - virtual void calc_fd( - const size_t fidx, - const double rij, - const double rik, - const double fc_ij, - const double fc_ik, - const double fcp_ij, - const double fcp_ik, - fd_type &fd_ij)=0; - virtual void calc_all( - const size_t fidx, - const double rij, - const double rik, - const double fc_ij, - const double fc_ik, - const double fcp_ij, - const double fcp_ik, - aed_type2& aed, - fd_type &fd_ij)=0; - virtual size_t size()=0; - virtual std::string label()=0; + virtual void calc_aed( + const size_t fidx, + const double rij, + const double rik, + const double fc_ij, + const double fc_ik, + aed_type& aed)=0; + virtual void calc_fd( + const size_t fidx, + const double rij, + const double rik, + const double fc_ij, + const double fc_ik, + const double fcp_ij, + const double fcp_ik, + fd_type &fd_ij)=0; + virtual void calc_all( + const size_t fidx, + const double rij, + const double rik, + const double fc_ij, + const double fc_ik, + const double fcp_ij, + const double fcp_ik, + aed_type& aed, + fd_type &fd_ij)=0; + virtual size_t size()override=0; + virtual std::string label()override=0; + virtual std::vector<std::string> get_init_atoms(Config &c) override; }; -//template<> inline Registry<D3_Base,Config&>::Map Registry<D3_Base,Config&>::registry{}; #endif diff --git a/include/tadah/models/descriptors/d3/d3_dummy.h b/include/tadah/models/descriptors/d3/d3_dummy.h index 0b5cdbdab1aad774d9adb95c74c91bf325e7b104..8cac4f5519ca893e8ed5f53aeb39fbef98be4d2c 100644 --- a/include/tadah/models/descriptors/d3/d3_dummy.h +++ b/include/tadah/models/descriptors/d3/d3_dummy.h @@ -2,39 +2,40 @@ #define D3_DUMMY_H #include <tadah/models/descriptors/d3/d3_base.h> class D3_Dummy: public D3_Base { - private: - size_t s=0; - std::string lab="D3_Dummy"; - public: - D3_Dummy(); - D3_Dummy(Config&); - void calc_aed( - const size_t fidx, - const double rij, - const double rik, - const double fc_ij, - const double fc_ik, - aed_type2& aed); - void calc_fd( - const size_t fidx, - const double rij, - const double rik, - const double fc_ij, - const double fc_ik, - const double fcp_ij, - const double fcp_ik, - fd_type &fd_ij); - void calc_all( - const size_t fidx, - const double rij, - const double rik, - const double fc_ij, - const double fc_ik, - const double fcp_ij, - const double fcp_ik, - aed_type2& aed, - fd_type &fd_ij); - size_t size(); - std::string label(); +private: + size_t s=0; + std::string lab="D3_Dummy"; +public: + D3_Dummy(); + D3_Dummy(Config&); + void calc_aed( + const size_t fidx, + const double rij, + const double rik, + const double fc_ij, + const double fc_ik, + aed_type& aed); + void calc_fd( + const size_t fidx, + const double rij, + const double rik, + const double fc_ij, + const double fc_ik, + const double fcp_ij, + const double fcp_ik, + fd_type &fd_ij); + void calc_all( + const size_t fidx, + const double rij, + const double rik, + const double fc_ij, + const double fc_ik, + const double fcp_ij, + const double fcp_ik, + aed_type& aed, + fd_type &fd_ij); + size_t size(); + std::string label(); + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/d_base.h b/include/tadah/models/descriptors/d_base.h index 8e9a25564f5fa60445d329d8d6a54fa85ff10911..e02737c67f9f8dbd1c7ac00474bf3c5e3708211b 100644 --- a/include/tadah/models/descriptors/d_base.h +++ b/include/tadah/models/descriptors/d_base.h @@ -1,56 +1,98 @@ #ifndef D_BASE_H #define D_BASE_H +#include <string> #include <tadah/core/config.h> #include <tadah/core/core_types.h> +#include <tadah/core/periodic_table.h> #include <tadah/core/registry.h> +#include <tadah/models/cut_all.h> +#include <vector> +#include <bitset> + +class Bitset2D { + static constexpr size_t N = 119; + std::bitset<N * N> data; + +public: + void init(size_t i, size_t j) { + data[i * N + j] = true; + data[j * N + i] = true; + + } + void uninit(size_t i, size_t j) { + data[i * N + j] = false; + data[j * N + i] = false; + } + bool is_init(size_t i, size_t j) const { + return data[i * N + j]; + } +}; /** \brief Base class for all descriptor types. * */ class D_Base { - public: - static void get_grid(const Config &c, std::string key, v_type &v) { - if (c.get<double>(key) < 0) { - // generate grid automatically if first element - // is<zero and int. If it is double than assume that - // grid is provided manually and min value is just smaller - // than zero. - double int_part; - if (std::modf ( c.get<double>(key), &int_part ) == 0.0) { - // automatic generation - size_t cg = abs(c.get<int>(key,1)); - double cgmin = c.get<double>(key,2); - double cgmax = c.get<double>(key,3); - if (c.get<int>(key) == -1) { - v = linspace(cgmin, cgmax, cg); - } - else if (c.get<int>(key) == -2) { - v = logspace(cgmin, cgmax, cg, exp(1)); - } - else { - throw std::runtime_error(key+" algorithm not supported\n"); - } - } - else { - v.resize(c.size(key)); - c.get<v_type>(key,v); - } - } - else { - v.resize(c.size(key)); - c.get<v_type>(key,v); - } - } - int verbose; - virtual ~D_Base() {}; - - /** \brief Return dimension of the descriptor. - */ - virtual size_t size()=0; - - /** \brief Return label of this descriptor. - */ - virtual std::string label()=0; +protected: + size_t fidx=0; // first index in aed and fd arrays for this descriptor + size_t s=0; + Cut_Base *fcut=nullptr; + +public: + std::vector<std::string> keys; // keys required by this descriptor + size_t nparams; // number of params which follow TYPExB + std::vector<bool> is_optimizable; + static void get_grid(const Config &c, std::string key, v_type &v); + static v_type get_grid(std::vector<std::string>&); // expand joined grids + int verbose; + virtual ~D_Base(); + + // return position of an argument given to TYPExB for a given key + // if key is not used, returns -1 + int get_arg_pos(const std::string &key) const; + + + /** \brief Return label of this descriptor. + */ + virtual std::string label()=0; + double weights[119] = {1}; // ignore zero index; w[1]->H + D_Base(); + D_Base(Config &c); + + virtual void set_fidx(size_t fidx_); + virtual size_t get_fidx(); + + /** + * @brief Initialize the descriptor. + * + * This method sets up the required keys names and number of parameters for the descriptor. + * + * Note: The implementation of the descriptor should not rely on these initial values, + * allowing for greater flexibility in how the Config file is parsed. + * + * The keys and parameters are utilized by other classes inheriting from this implementation, + * such as meta-descriptors. + * + */ + virtual void init() = 0; + + virtual void set_fcut(Cut_Base* cut, bool manage_memory); + + double get_rcut(); + + /** \brief Return dimension of the descriptor. + */ + virtual size_t size(); + + virtual bool is_init_for_atoms(int Zi, int Zj); + virtual void init_for_atoms(int Zi, int Zj); + virtual void init_for_atoms(const std::vector<std::string> &Zs); + virtual void uninit_for_atoms(int Zi, int Zj); + static std::vector<std::string> get_init_atoms(Config &c, std::string type); + virtual std::vector<std::string> get_init_atoms(Config &c)=0; + +private: + bool manage_memory=false; // who owns fcut + Bitset2D init_for_atoms_map; // 0th is unused }; #endif diff --git a/include/tadah/models/descriptors/d_mjoin.h b/include/tadah/models/descriptors/d_mjoin.h new file mode 100644 index 0000000000000000000000000000000000000000..182cb6d68eb28090c0c43d4c9ed9da08508c13d2 --- /dev/null +++ b/include/tadah/models/descriptors/d_mjoin.h @@ -0,0 +1,29 @@ +#ifndef D_MJOIN_H +#define D_MJOIN_H +#include <tadah/core/config.h> +#include <vector> + +/** \brief Base class to be used by meta descriptors for joining +*/ +class D_mJoin { +protected: + struct D_Type { + std::string type; + std::string rc_type; + double rcut; + std::vector<std::string> params; + Config c; + }; + std::vector<D_Type> dt; + std::string lab = "D_mJoin"; +public: + virtual ~D_mJoin(); + D_mJoin(); + static std::vector<Config> parse_config(Config &c, std::string type_str); + + static void expand_grids(Config &c, std::vector<Config> &configs, std::string type_str); + static void expand_grids(Config &c, std::string type_str); + static void expand_grids(Config &c); +}; +#endif + diff --git a/include/tadah/models/descriptors/dm/dm_all.h b/include/tadah/models/descriptors/dm/dm_all.h index 6d92d07bf484eb9cbcd1250edbe61c35ccf1c305..26e18c7b3b810c8e5f894a0ffe20e8df99d5bcb1 100644 --- a/include/tadah/models/descriptors/dm/dm_all.h +++ b/include/tadah/models/descriptors/dm/dm_all.h @@ -4,5 +4,6 @@ #include <tadah/models/descriptors/dm/dm_ead.h> #include <tadah/models/descriptors/dm/dm_blip.h> #include <tadah/models/descriptors/dm/dm_mEAD.h> +#include <tadah/models/descriptors/dm/dm_mjoin.h> #include <tadah/models/descriptors/dm/dm_func.h> diff --git a/include/tadah/models/descriptors/dm/dm_base.h b/include/tadah/models/descriptors/dm/dm_base.h index 3eba787b13569e393aa4702367f6bdd8fc54efad..825a1c52061f7763b196cc4855a41526c8fee7b0 100644 --- a/include/tadah/models/descriptors/dm/dm_base.h +++ b/include/tadah/models/descriptors/dm/dm_base.h @@ -9,9 +9,24 @@ * All many-body descriptors **must** inherit this class. */ class DM_Base: public D_Base { + +protected: + size_t rfidx=0; + size_t rhoisize=0; public: - size_t fidx=0; // first index in aed and fd arrays for this descriptor + DM_Base() {}; + DM_Base(Config &c): D_Base(c) { + //if (c.get<bool>("INITMB")) { + if (c.exist("RCUTMBMAX") && c.exist("RCTYPEMB")) { + double rcutmb = c.get<double>("RCUTMBMAX"); + set_fcut(CONFIG::factory<Cut_Base,double>( c.get<std::string>("RCTYPEMB"), rcutmb ), true); + } + else { + set_fcut(new Cut_Dummy(0), true); + } + } virtual ~DM_Base() {}; + virtual std::vector<std::string> get_init_atoms(Config &c) override; /** \brief Calculate \ref AED * @@ -19,7 +34,7 @@ public: */ virtual void calc_aed( rho_type& rho, - aed_type2 &aed)=0; + aed_type &aed)=0; /** \brief Calculate \ref FD * @@ -34,17 +49,16 @@ public: * \frac{\partial \mathbf{X}_{ji}}{\partial \mathbf{r}_i} * \f] */ - virtual int calc_dXijdri_dXjidri( + virtual void calc_dXijdri_dXjidri( + const int Zi, + const int Zj, const double rij, const double rij_sq, const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, rho_type& rhoi, rho_type& rhoj, fd_type &fd_ij, - const double wi, - const double wj)=0; + const double scale=1)=0; /** \brief Calculate \ref FD * @@ -61,62 +75,59 @@ public: * \frac{\partial \mathbf{X}_{ij}}{\partial \mathbf{r}_i} * \f] */ - virtual int calc_dXijdri( + virtual void calc_dXijdri( + const int Zi, + const int Zj, const double rij, const double rij_sq, const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, rho_type& rhoi, - fd_type &fd_ij)=0; + fd_type &fd_ij, + const double scale=1)=0; /** \brief Resize arrays for a density and F' */ virtual void init_rhoi(rho_type& rhoi)=0; /** \brief Calculate density */ virtual void calc_rho( + const int Zi, + const int Zj, const double rij, const double rij_sq, - const double fc_ij, const Vec3d &vec_ij, - rho_type& rho)=0; - - /** \brief Return size of the density array */ - virtual size_t rhoi_size()=0; + rho_type& rho, + const double scale=1)=0; - /** \brief Return size of the derivative of the embedding energy array */ - virtual size_t rhoip_size()=0; - virtual size_t size()=0; - virtual std::string label()=0; /** \brief This is just a convenient wrapper. - * - * Note that this method should not to be used when - * computational performance matter. */ - void calc_dXijdri(Vec3d &del, rho_type &rhoi, fd_type &fdij, double fc=1, double fcp=0) { + void calc_dXijdri(const int Zi, const int Zj, Vec3d &del, rho_type &rhoi, fd_type &fdij, double scale=1) { double rsq = del*del; double r = sqrt(rsq); //(p->*func)(r,rsq,del,1.0,0.0,rhoi,fdij); - int mode = (*this).calc_dXijdri(r,rsq,del,fc,fcp,rhoi,fdij); - if(mode==0) { - fdij(1)=fdij(0); - fdij(2)=fdij(0); - fdij(0)*=del[0]/r; - fdij(1)*=del[1]/r; - fdij(2)*=del[2]/r; - } + (*this).calc_dXijdri(Zi, Zj,r,rsq,del,rhoi,fdij,scale); } /** \brief This is just a convenient wrapper. - * - * Note that this method should not to be used when - * computational performance matter. */ - void calc_rho_mb(Vec3d &del, rho_type &rhoi, double fc=1) { + void calc_rho_mb(const int Zi, const int Zj, Vec3d &del, rho_type &rhoi, double scale=1) { double rsq = del*del; double r = sqrt(rsq); - ((*this).calc_rho)(r,rsq,fc,del,rhoi); + ((*this).calc_rho)(Zi, Zj,r,rsq,del,rhoi,scale); + } + /** \brief Return size of the density array */ + virtual size_t rhoi_size() { + return rhoisize; } + /** \brief Return size of the derivative of the embedding energy array */ + virtual size_t rhoip_size() { + return rhoisize; + } + virtual size_t size() { + return s; + } + virtual std::string label()=0; + virtual size_t get_rfidx(); + virtual void set_rfidx(size_t fidx_); }; #endif diff --git a/include/tadah/models/descriptors/dm/dm_blip.h b/include/tadah/models/descriptors/dm/dm_blip.h index 6858552196e9ae097641f570ffda16c19d256a5f..9cfe441f5662b316e6d53f767f1f74219ceae5c1 100644 --- a/include/tadah/models/descriptors/dm/dm_blip.h +++ b/include/tadah/models/descriptors/dm/dm_blip.h @@ -20,8 +20,6 @@ * * \ref SGRIDMB parameters control width \f$ \eta \f$ of the gaussian basis function. * - * \ref AGRIDMB parameter specify maximum value for the angular momentum \f$L_{max}\f$. - * * e.g. \f$L_{max}=2\f$ will calculate descriptors with \f$ L=0,1,2 \f$ (s,p,d orbitals). * * More information about this descriptor: @@ -33,58 +31,56 @@ * 4962–4967. https://doi.org/10.1021/acs.jpclett.9b02037</div> * * Required Config keys: - * \ref INITMB \ref CGRIDMB \ref SGRIDMB \ref AGRIDMB + * \ref INITMB \ref CGRIDMB \ref SGRIDMB */ class DM_Blip: public DM_Base { - private: - int Lmax=0; - size_t rhoisize=0; - size_t s=0; - std::string lab="DM_Blip"; - v_type sgrid; - v_type cgrid; - std::vector<std::vector<std::vector<int>>> orbitals; - std::vector<std::vector<double>> fac; - size_t gen_atomic_orbitals(int L); - double fact(int n); - double my_pow(double,int); - int verbose; - double rc; +private: + int Lmax=0; + std::string lab="DM_Blip"; + v_type sgrid; + v_type cgrid; + std::vector<std::vector<std::vector<int>>> orbitals; + std::vector<std::vector<double>> fac; + size_t gen_atomic_orbitals(int L); + double fact(int n); + double my_pow(double,int); + double rc; - public: - DM_Blip(Config&); - void calc_aed( - rho_type& rho, - aed_type2 &aed); - int calc_dXijdri_dXjidri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - rho_type& rhoj, - fd_type &fd_ij, - const double wi, - const double wj); - int calc_dXijdri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - fd_type &fd_ij); - size_t size(); - std::string label(); - void init_rhoi(rho_type& rhoi); - void calc_rho( - const double rij, - const double rij_sq, - const double fc_ij, - const Vec3d &vec_ij, - rho_type& rho); - size_t rhoi_size(); - size_t rhoip_size(); +public: + DM_Blip(); + DM_Blip(Config&); + void calc_aed( + rho_type& rho, + aed_type &aed) override; + void calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init_rhoi(rho_type& rhoi) override; + void calc_rho( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rho, + const double scale=1) override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/dm/dm_dummy.h b/include/tadah/models/descriptors/dm/dm_dummy.h index 89c2f4b712183d9c4b34a8e19ab0a9851894bd2c..c85c4b56bc23deb2ea45cdffd0b6d4dedd32ecd1 100644 --- a/include/tadah/models/descriptors/dm/dm_dummy.h +++ b/include/tadah/models/descriptors/dm/dm_dummy.h @@ -10,44 +10,43 @@ * */ class DM_Dummy: public DM_Base { - private: - size_t s=0; - std::string lab="DM_Dummy"; - public: - DM_Dummy(); - DM_Dummy(Config&); - void calc_aed( - rho_type& rho, - aed_type2 &aed); - int calc_dXijdri_dXjidri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - rho_type& rhoj, - fd_type &fd_ij, - const double wi, - const double wj); - int calc_dXijdri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - fd_type &fd_ij); - size_t size(); - std::string label(); - void init_rhoi(rho_type& rhoi); - void calc_rho( - const double rij, - const double rij_sq, - const double fc_ij, - const Vec3d &vec_ij, - rho_type& rho); - size_t rhoi_size(); - size_t rhoip_size(); +private: + std::string lab="DM_Dummy"; +public: + DM_Dummy(); + DM_Dummy(Config&); + void calc_aed( + rho_type& rho, + aed_type &aed) override; + void calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init_rhoi(rho_type& rhoi) override; + void calc_rho( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rho, + const double scale=1) override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/dm/dm_ead.h b/include/tadah/models/descriptors/dm/dm_ead.h index 5975a1ff1df9590698b17ab23e865ddc728f95db..5d5dfbf0610237868373d5472216daad6bb04087 100644 --- a/include/tadah/models/descriptors/dm/dm_ead.h +++ b/include/tadah/models/descriptors/dm/dm_ead.h @@ -19,8 +19,6 @@ * * \ref SGRIDMB parameters control width \f$ \eta \f$ of the gaussian basis function. * - * \ref AGRIDMB parameter specify maximum value for the angular momentum \f$L_{max}\f$. - * * e.g. \f$L_{max}=2\f$ will calculate descriptors with \f$ L=0,1,2 \f$ (s,p,d orbitals). * * More information about this descriptor: @@ -32,58 +30,56 @@ * 4962–4967. https://doi.org/10.1021/acs.jpclett.9b02037</div> * * Required Config keys: - * \ref INITMB \ref CGRIDMB \ref SGRIDMB \ref AGRIDMB + * \ref INITMB \ref CGRIDMB \ref SGRIDMB */ class DM_EAD: public DM_Base { - private: - int Lmax=0; - size_t rhoisize=0; - size_t s=0; - std::string lab="DM_EAD"; - v_type sgrid; - v_type cgrid; - std::vector<std::vector<std::vector<int>>> orbitals; - std::vector<std::vector<double>> fac; - size_t gen_atomic_orbitals(int L); - double fact(int n); - double my_pow(double,int); - int verbose; - double rc; +private: + int Lmax=0; + std::string lab="DM_EAD"; + v_type sgrid; + v_type cgrid; + std::vector<std::vector<std::vector<int>>> orbitals; + std::vector<std::vector<double>> fac; + size_t gen_atomic_orbitals(int L); + double fact(int n); + double my_pow(double,int); + double rc; - public: - DM_EAD(Config&); - void calc_aed( - rho_type& rho, - aed_type2 &aed); - int calc_dXijdri_dXjidri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - rho_type& rhoj, - fd_type &fd_ij, - const double wi, - const double wj); - int calc_dXijdri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - fd_type &fd_ij); - size_t size(); - std::string label(); - void init_rhoi(rho_type& rhoi); - void calc_rho( - const double rij, - const double rij_sq, - const double fc_ij, - const Vec3d &vec_ij, - rho_type& rho); - size_t rhoi_size(); - size_t rhoip_size(); +public: + DM_EAD(); + DM_EAD(Config&); + void calc_aed( + rho_type& rho, + aed_type &aed) override; + void calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init_rhoi(rho_type& rhoi) override; + void calc_rho( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rho, + const double scale=1) override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/dm/dm_eam.h b/include/tadah/models/descriptors/dm/dm_eam.h index 5687a32d1c87a1777020603ec7636a676c263a85..b522bdf7dc906ab71c021b7f5a649dd9acf3463b 100644 --- a/include/tadah/models/descriptors/dm/dm_eam.h +++ b/include/tadah/models/descriptors/dm/dm_eam.h @@ -22,72 +22,71 @@ * \ref INITMB \ref SETFL */ class DM_EAM: public DM_Base { - private: - int verbose; - struct eam_file { - std::string file_path; - std::vector<double> frho; - std::vector<double> rhor; - std::vector<double> z2r; - int nrho=0; - double drho=0; - int nr; - double dr; - double rdr; - double rdrho; - double rcut; - int atomic_number; - double atomic_mass; - double lattice_param; - std::string lattice; - double rhomax; +private: + struct eam_file { + std::string file_path; + std::vector<double> frho; + std::vector<double> rhor; + std::vector<double> z2r; + int nrho=0; + double drho=0; + int nr; + double dr; + double rdr; + double rdrho; + double rcut; + int atomic_number; + double atomic_mass; + double lattice_param; + std::string lattice; + double rhomax; - }; - eam_file ef; + }; + eam_file ef; - std::vector<std::vector<double>> frho_spline; - std::vector<std::vector<double>> rhor_spline; - std::vector<std::vector<double>> z2r_spline; + std::vector<std::vector<double>> frho_spline; + std::vector<std::vector<double>> rhor_spline; + std::vector<std::vector<double>> z2r_spline; - size_t s=1; - std::string lab="DM_EAM"; - void read_setfl(); - void gen_splines(int &n, double &delta, std::vector<double> &f, std::vector<std::vector<double>> &spline); + std::string lab="DM_EAM"; + void read_setfl(); + void gen_splines(int &n, double &delta, std::vector<double> &f, std::vector<std::vector<double>> &spline); - public: - DM_EAM(Config&); - void calc_aed( - rho_type& rho, - aed_type2 &aed); - int calc_dXijdri_dXjidri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - rho_type& rhoj, - fd_type &fd_ij, - const double wi, - const double wj); - int calc_dXijdri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - fd_type &fd_ij); - size_t size(); - std::string label(); - void init_rhoi(rho_type& rhoi); - void calc_rho( - const double rij, - const double rij_sq, - const double fc_ij, - const Vec3d &vec_ij, - rho_type& rho); - size_t rhoi_size(); - size_t rhoip_size(); +public: + DM_EAM(); + DM_EAM(Config&); + void calc_aed( + rho_type& rho, + aed_type &aed) override; + void calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init_rhoi(rho_type& rhoi) override; + void calc_rho( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rho, + const double scale=1) override; + void init() override; }; #endif diff --git a/include/tadah/models/descriptors/dm/dm_func.h b/include/tadah/models/descriptors/dm/dm_func.h index a35abd7bf2d8f318a6f99c7b569557e863ba80c3..0a94484249aaf21798a0d56be105ac9107ea92e4 100644 --- a/include/tadah/models/descriptors/dm/dm_func.h +++ b/include/tadah/models/descriptors/dm/dm_func.h @@ -7,9 +7,9 @@ #include <cstdlib> class F_Base { - public: - virtual double calc_F(double rho, size_t c)=0; - virtual double calc_dF(double rho, size_t c)=0; +public: + virtual double calc_F(double rho, size_t c)=0; + virtual double calc_dF(double rho, size_t c)=0; }; /** @@ -25,17 +25,17 @@ class F_Base { * @note Ensure the configuration keys match the descriptor requirements. */ class F_RLR: public F_Base { - private: - Config *config=nullptr; - v_type sgrid; // controls depth - v_type cgrid; // control x-intercep at 1/c - public: - F_RLR(Config &conf); - F_RLR(); - double calc_F(double rho,size_t c); - double calc_dF(double rho,size_t c); - //~F_RLR() { - // Do not delete config! - //} +private: + Config *config=nullptr; + v_type sgrid; // controls depth + v_type cgrid; // control x-intercep at 1/c +public: + F_RLR(Config &conf); + F_RLR(); + double calc_F(double rho,size_t c); + double calc_dF(double rho,size_t c); + //~F_RLR() { + // Do not delete config! + //} }; #endif diff --git a/include/tadah/models/descriptors/dm/dm_mEAD.h b/include/tadah/models/descriptors/dm/dm_mEAD.h index ec9733417818118b82cefbc7a9b9be7e3008db84..733ebce7d46514c87fcbf2b6e2fb726ecefbdb8d 100644 --- a/include/tadah/models/descriptors/dm/dm_mEAD.h +++ b/include/tadah/models/descriptors/dm/dm_mEAD.h @@ -28,7 +28,6 @@ * * \ref SGRIDMB parameters control width \f$ \eta \f$ of the gaussian basis function. * - * \ref AGRIDMB parameter specify maximum value for the angular momentum \f$L_{max}\f$. * * e.g. \f$L_{max}=2\f$ will calculate descriptors with \f$ L=0,1,2 \f$ (s,p,d orbitals). * @@ -41,61 +40,59 @@ * 4962–4967. https://doi.org/10.1021/acs.jpclett.9b02037</div> * * Required Config keys: - * \ref INITMB \ref CGRIDMB \ref SGRIDMB \ref AGRIDMB + * \ref INITMB \ref CGRIDMB \ref SGRIDMB */ template <typename F> class DM_mEAD: public DM_Base { - private: - int Lmax=0; - size_t rhoisize=0; - size_t s=0; - std::string lab="DM_mEAD"; - v_type sgrid; - v_type cgrid; - std::vector<std::vector<std::vector<int>>> orbitals; - std::vector<std::vector<double>> fac; - size_t gen_atomic_orbitals(int L); - double fact(int n); - double my_pow(double,int); - int verbose; - double rc; - F emb; +private: + int Lmax=0; + std::string lab="DM_mEAD"; + v_type sgrid; + v_type cgrid; + std::vector<std::vector<std::vector<int>>> orbitals; + std::vector<std::vector<double>> fac; + size_t gen_atomic_orbitals(int L); + double fact(int n); + double my_pow(double,int); + double rc; + F emb; - public: - DM_mEAD(Config&); - void calc_aed( - rho_type& rho, - aed_type2 &aed); - int calc_dXijdri_dXjidri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - rho_type& rhoj, - fd_type &fd_ij, - const double wi, - const double wj); - int calc_dXijdri( - const double rij, - const double rij_sq, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - fd_type &fd_ij); - size_t size(); - std::string label(); - void init_rhoi(rho_type& rhoi); - void calc_rho( - const double rij, - const double rij_sq, - const double fc_ij, - const Vec3d &vec_ij, - rho_type& rho); - size_t rhoi_size(); - size_t rhoip_size(); +public: + DM_mEAD(); + DM_mEAD(Config&); + void calc_aed( + rho_type& rho, + aed_type &aed) override; + void calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init_rhoi(rho_type& rhoi) override; + void calc_rho( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rho, + const double scale=1) override; + void init() override; }; #include "dm_mEAD.hpp" diff --git a/include/tadah/models/descriptors/dm/dm_mEAD.hpp b/include/tadah/models/descriptors/dm/dm_mEAD.hpp index ba17354ffc757cf3812410b024cd3c5c80e54756..b5493621e7d4de3725b8d4f913b32ac75592af48 100644 --- a/include/tadah/models/descriptors/dm/dm_mEAD.hpp +++ b/include/tadah/models/descriptors/dm/dm_mEAD.hpp @@ -1,316 +1,331 @@ - #include <tadah/models/descriptors/dm/dm_func.h> #include <tadah/models/descriptors/dm/dm_mEAD.h> #include <tadah/models/descriptors/d_basis_functions.h> +template <typename F> +DM_mEAD<F>::DM_mEAD() { + init(); +} + /* Index ii iterates rhoi array * rhoi array is split 50/50 into density and derivative * of the embedding function */ template <typename F> -DM_mEAD<F>::DM_mEAD(Config &config): - verbose(config.get<int>("VERBOSE")), - rc(config.get<double>("RCUTMB")), - emb(config) +DM_mEAD<F>::DM_mEAD(Config &config): DM_Base(config), + rc(config.get<double>("RCUTMBMAX")), + emb(config) { - if (!config.get<bool>("INITMB")) return; - - get_grid(config,"CGRIDMB",cgrid); - get_grid(config,"SGRIDMB",sgrid); - - if (cgrid.size()!=sgrid.size()) { - throw std::runtime_error("SGRID2B and CGRID2B arrays differ in size.\n"); - } - - Lmax = config.get<int>("AGRIDMB"); - s=sgrid.size()*(Lmax+1); - rhoisize = gen_atomic_orbitals(Lmax); - rhoisize *= sgrid.size(); - - if (verbose) { - std::cout << std::endl; - std::cout << "SGRID (SGRIDMB): " << sgrid.size() << std::endl; - for (auto e:sgrid) std::cout << e << " "; - std::cout << std::endl; - - std::cout << "CGRID (CGRIDMB): " << cgrid.size() << std::endl; - for (auto L:cgrid) std::cout << L << " "; - std::cout << std::endl; - std::cout << "rhoisize: " << rhoisize << std::endl; - } + if (!config.get<bool>("INITMB")) return; + init(); + + get_grid(config,"CGRIDMB",cgrid); + get_grid(config,"SGRIDMB",sgrid); + // update config with generated grid + config.remove("CGRIDMB"); + for (const auto &i: cgrid) config.add("CGRIDMB",i); + config.remove("SGRIDMB"); + for (const auto &i: sgrid) config.add("SGRIDMB",i); + + if (cgrid.size()!=sgrid.size()) { + throw std::runtime_error("SGRID2B and CGRID2B arrays differ in size.\n"); + } + + Lmax = config.get<int>("TYPEMB",1); + s=sgrid.size()*(Lmax+1); + rhoisize = gen_atomic_orbitals(Lmax); + rhoisize *= sgrid.size(); + + if (verbose) { + std::cout << std::endl; + std::cout << "SGRID (SGRIDMB): " << sgrid.size() << std::endl; + for (auto e:sgrid) std::cout << e << " "; + std::cout << std::endl; + + std::cout << "CGRID (CGRIDMB): " << cgrid.size() << std::endl; + for (auto L:cgrid) std::cout << L << " "; + std::cout << std::endl; + std::cout << "rhoisize: " << rhoisize << std::endl; + } + auto init_atoms = get_init_atoms(config); + init_for_atoms(init_atoms); } template <typename F> void DM_mEAD<F>::calc_aed( - rho_type& rhoi, - aed_type2 &aed) + rho_type& rhoi, + aed_type &aed) { - size_t Lshift = 0; - size_t ii=0; - for (int L=0; L<=Lmax; ++L) { - for (size_t o=0; o<orbitals[L].size(); ++o) { - const double f = fac[L][o]; - for (size_t c=0; c<cgrid.size(); c++) { - aed(c+Lshift+fidx) += f*emb.calc_F(rhoi(ii),c); - rhoi(ii+rhoisize) = f*emb.calc_dF(rhoi(ii),c); - ii++; - } - } - Lshift += sgrid.size(); + size_t Lshift = 0; + size_t ii=rfidx; + for (int L=0; L<=Lmax; ++L) { + for (size_t o=0; o<orbitals[L].size(); ++o) { + const double f = fac[L][o]; + for (size_t c=0; c<cgrid.size(); c++) { + aed(c+Lshift+fidx) += f*emb.calc_F(rhoi(ii),c); + rhoi(ii+rhoisize) = f*emb.calc_dF(rhoi(ii),c); + ii++; + } } + Lshift += sgrid.size(); + } } template <typename F> -int DM_mEAD<F>::calc_dXijdri_dXjidri( - const double rij, - const double, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - rho_type& rhoj, - fd_type &fd_ij, - const double wi, - const double wj) +void DM_mEAD<F>::calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale) { - const double x = vec_ij[0]; - const double y = vec_ij[1]; - const double z = vec_ij[2]; - - size_t Lshift = 0; - - size_t ii=rhoisize; - for (int L=0; L<=Lmax; ++L) { - for (size_t o=0; o<orbitals[L].size(); ++o) { - const int lx = orbitals[L][o][0]; - const int ly = orbitals[L][o][1]; - const int lz = orbitals[L][o][2]; - - const double powxlxij = my_pow(x,lx); - const double powylyij = my_pow(y,ly); - const double powzlzij = my_pow(z,lz); - - const double powxlxji = my_pow(-x,lx); - const double powylyji = my_pow(-y,ly); - const double powzlzji = my_pow(-z,lz); - - double txij=0.0,tyij=0.0,tzij=0.0; - double txji=0.0,tyji=0.0,tzji=0.0; - if (lx!=0) { - txij = lx*my_pow(x,lx-1)*powylyij*powzlzij; - txji = lx*my_pow(-x,lx-1)*powylyji*powzlzji; - } - if (ly!=0) { - tyij = ly*my_pow(y,ly-1)*powxlxij*powzlzij; - tyji = ly*my_pow(-y,ly-1)*powxlxji*powzlzji; - } - if (lz!=0) { - tzij = lz*my_pow(z,lz-1)*powylyij*powxlxij; - tzji = lz*my_pow(-z,lz-1)*powylyji*powxlxji; - } - const double pqrij = powxlxij*powylyij*powzlzij; - const double pqrji = powxlxji*powylyji*powzlzji; - - for (size_t c=0; c<cgrid.size(); c++) { - double bf= G(rij,sgrid[c],cgrid[c],fc_ij); - double dbf= dG(rij,sgrid[c],cgrid[c],fc_ij,fcp_ij); - - const double term2ijx=pqrij*dbf*x/rij; - const double term2ijy=pqrij*dbf*y/rij; - const double term2ijz=pqrij*dbf*z/rij; - - const double term2jix=-pqrji*dbf*x/rij; - const double term2jiy=-pqrji*dbf*y/rij; - const double term2jiz=-pqrji*dbf*z/rij; - - const double term1ijx = bf*txij; - const double term1ijy = bf*tyij; - const double term1ijz = bf*tzij; - - const double term1jix = bf*txji; - const double term1jiy = bf*tyji; - const double term1jiz = bf*tzji; - - fd_ij(c+Lshift+fidx,0) += - rhoi(ii)*(term1ijx + term2ijx)*wj - -rhoj(ii)*(term1jix + term2jix)*wi - ; - - fd_ij(c+Lshift+fidx,1) += - rhoi(ii)*(term1ijy + term2ijy)*wj - -rhoj(ii)*(term1jiy + term2jiy)*wi - ; - - fd_ij(c+Lshift+fidx,2) += - rhoi(ii)*(term1ijz + term2ijz)*wj - -rhoj(ii)*(term1jiz + term2jiz)*wi - ; - ii++; - } - } - Lshift+=sgrid.size(); + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + const double x = vec_ij[0]; + const double y = vec_ij[1]; + const double z = vec_ij[2]; + + size_t Lshift = 0; + + double wi = weights[Zi]; + double wj = weights[Zj]; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); + + size_t ii=rhoisize+rfidx; + for (int L=0; L<=Lmax; ++L) { + for (size_t o=0; o<orbitals[L].size(); ++o) { + const int lx = orbitals[L][o][0]; + const int ly = orbitals[L][o][1]; + const int lz = orbitals[L][o][2]; + + const double powxlxij = my_pow(x,lx); + const double powylyij = my_pow(y,ly); + const double powzlzij = my_pow(z,lz); + + const double powxlxji = my_pow(-x,lx); + const double powylyji = my_pow(-y,ly); + const double powzlzji = my_pow(-z,lz); + + double txij=0.0,tyij=0.0,tzij=0.0; + double txji=0.0,tyji=0.0,tzji=0.0; + if (lx!=0) { + txij = lx*my_pow(x,lx-1)*powylyij*powzlzij; + txji = lx*my_pow(-x,lx-1)*powylyji*powzlzji; + } + if (ly!=0) { + tyij = ly*my_pow(y,ly-1)*powxlxij*powzlzij; + tyji = ly*my_pow(-y,ly-1)*powxlxji*powzlzji; + } + if (lz!=0) { + tzij = lz*my_pow(z,lz-1)*powylyij*powxlxij; + tzji = lz*my_pow(-z,lz-1)*powylyji*powxlxji; + } + const double pqrij = powxlxij*powylyij*powzlzij; + const double pqrji = powxlxji*powylyji*powzlzji; + + for (size_t c=0; c<cgrid.size(); c++) { + double bf= G(rij,sgrid[c],cgrid[c],fc_ij); + double dbf= dG(rij,sgrid[c],cgrid[c],fc_ij,fcp_ij); + + const double term2ijx=pqrij*dbf*x/rij; + const double term2ijy=pqrij*dbf*y/rij; + const double term2ijz=pqrij*dbf*z/rij; + + const double term2jix=-pqrji*dbf*x/rij; + const double term2jiy=-pqrji*dbf*y/rij; + const double term2jiz=-pqrji*dbf*z/rij; + + const double term1ijx = bf*txij; + const double term1ijy = bf*tyij; + const double term1ijz = bf*tzij; + + const double term1jix = bf*txji; + const double term1jiy = bf*tyji; + const double term1jiz = bf*tzji; + + fd_ij(c+Lshift+fidx,0) += scale*( + rhoi(ii)*(term1ijx + term2ijx)*wj + -rhoj(ii)*(term1jix + term2jix)*wi) + ; + + fd_ij(c+Lshift+fidx,1) += scale*( + rhoi(ii)*(term1ijy + term2ijy)*wj + -rhoj(ii)*(term1jiy + term2jiy)*wi) + ; + + fd_ij(c+Lshift+fidx,2) += scale*( + rhoi(ii)*(term1ijz + term2ijz)*wj + -rhoj(ii)*(term1jiz + term2jiz)*wi) + ; + ii++; + } } - - return 1; - + Lshift+=sgrid.size(); + } } template <typename F> -int DM_mEAD<F>::calc_dXijdri( - const double rij, - const double, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - fd_type &fd_ij) +void DM_mEAD<F>::calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale) { - const double x = vec_ij[0]; - const double y = vec_ij[1]; - const double z = vec_ij[2]; - - size_t Lshift = 0; - - size_t ii=rhoisize; - for (int L=0; L<=Lmax; ++L) { - for (size_t o=0; o<orbitals[L].size(); ++o) { - const int lx = orbitals[L][o][0]; - const int ly = orbitals[L][o][1]; - const int lz = orbitals[L][o][2]; - - const double powxlxij = my_pow(x,lx); - const double powylyij = my_pow(y,ly); - const double powzlzij = my_pow(z,lz); - - double txij=0.0,tyij=0.0,tzij=0.0; - if (lx!=0) { - txij = lx*my_pow(x,lx-1)*powylyij*powzlzij; - } - if (ly!=0) { - tyij = ly*my_pow(y,ly-1)*powxlxij*powzlzij; - } - if (lz!=0) { - tzij = lz*my_pow(z,lz-1)*powylyij*powxlxij; - } - const double pqrij = powxlxij*powylyij*powzlzij; - - for (size_t c=0; c<cgrid.size(); c++) { - double bf= G(rij,sgrid[c],cgrid[c],fc_ij); - double dbf= dG(rij,sgrid[c],cgrid[c],fc_ij,fcp_ij); - - const double term2ijx=pqrij*dbf*x/rij; - const double term2ijy=pqrij*dbf*y/rij; - const double term2ijz=pqrij*dbf*z/rij; - - const double term1ijx = bf*txij; - const double term1ijy = bf*tyij; - const double term1ijz = bf*tzij; - - fd_ij(c+Lshift+fidx,0) += - rhoi(ii)*(term1ijx + term2ijx) - ; - - fd_ij(c+Lshift+fidx,1) += - rhoi(ii)*(term1ijy + term2ijy) - ; - - fd_ij(c+Lshift+fidx,2) += - rhoi(ii)*(term1ijz + term2ijz) - ; - ii++; - } - } - Lshift+=sgrid.size(); + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + const double x = vec_ij[0]; + const double y = vec_ij[1]; + const double z = vec_ij[2]; + + double wj = weights[Zj]; + double fc_ij = scale*wj*fcut->calc(rij); + double fcp_ij = scale*wj*fcut->calc_prime(rij); + + size_t Lshift = 0; + + size_t ii=rhoisize+rfidx; + for (int L=0; L<=Lmax; ++L) { + for (size_t o=0; o<orbitals[L].size(); ++o) { + const int lx = orbitals[L][o][0]; + const int ly = orbitals[L][o][1]; + const int lz = orbitals[L][o][2]; + + const double powxlxij = my_pow(x,lx); + const double powylyij = my_pow(y,ly); + const double powzlzij = my_pow(z,lz); + + double txij=0.0,tyij=0.0,tzij=0.0; + if (lx!=0) { + txij = lx*my_pow(x,lx-1)*powylyij*powzlzij; + } + if (ly!=0) { + tyij = ly*my_pow(y,ly-1)*powxlxij*powzlzij; + } + if (lz!=0) { + tzij = lz*my_pow(z,lz-1)*powylyij*powxlxij; + } + const double pqrij = powxlxij*powylyij*powzlzij; + + for (size_t c=0; c<cgrid.size(); c++) { + double bf= G(rij,sgrid[c],cgrid[c],fc_ij); + double dbf= dG(rij,sgrid[c],cgrid[c],fc_ij,fcp_ij); + + const double term2ijx=pqrij*dbf*x/rij; + const double term2ijy=pqrij*dbf*y/rij; + const double term2ijz=pqrij*dbf*z/rij; + + const double term1ijx = bf*txij; + const double term1ijy = bf*tyij; + const double term1ijz = bf*tzij; + + fd_ij(c+Lshift+fidx,0) += + rhoi(ii)*(term1ijx + term2ijx) + ; + + fd_ij(c+Lshift+fidx,1) += + rhoi(ii)*(term1ijy + term2ijy) + ; + + fd_ij(c+Lshift+fidx,2) += + rhoi(ii)*(term1ijz + term2ijz) + ; + ii++; + } } - - return 1; - -} -template <typename F> -size_t DM_mEAD<F>::size() { - return s; + Lshift+=sgrid.size(); + } } template <typename F> std::string DM_mEAD<F>::label() { - return lab; + return lab; } template <typename F> void DM_mEAD<F>::init_rhoi(rho_type& rhoi) { - rhoi.resize(2*rhoisize); - rhoi.set_zero(); + rhoi.resize(2*rhoisize); + rhoi.set_zero(); } template <typename F> void DM_mEAD<F>::calc_rho( - const double rij, - const double, - const double fc_ij, - const Vec3d &vec_ij, - rho_type& rhoi) + const int Zi, + const int Zj, + const double rij, + const double, + const Vec3d &vec_ij, + rho_type& rhoi, + const double scale) { - size_t ii=0; - for (int L=0; L<=Lmax; ++L) { - for (size_t o=0; o<orbitals[L].size(); ++o) { - const size_t lx = orbitals[L][o][0]; - const size_t ly = orbitals[L][o][1]; - const size_t lz = orbitals[L][o][2]; - double t = (my_pow(vec_ij[0],lx)*my_pow(vec_ij[1],ly)*my_pow(vec_ij[2],lz)); - for (size_t c=0; c<cgrid.size(); c++) { - rhoi(ii++) += G(rij,sgrid[c],cgrid[c],fc_ij)*t; - } - } + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + size_t ii=rfidx; + double fc_ij = scale*weights[Zj]*fcut->calc(rij); + for (int L=0; L<=Lmax; ++L) { + for (size_t o=0; o<orbitals[L].size(); ++o) { + const size_t lx = orbitals[L][o][0]; + const size_t ly = orbitals[L][o][1]; + const size_t lz = orbitals[L][o][2]; + double t = (my_pow(vec_ij[0],lx)*my_pow(vec_ij[1],ly)*my_pow(vec_ij[2],lz)); + for (size_t c=0; c<cgrid.size(); c++) { + rhoi(ii++) += G(rij,sgrid[c],cgrid[c],fc_ij)*t; + } } + } } template <typename F> size_t DM_mEAD<F>::gen_atomic_orbitals(int Lmax) { - orbitals.resize(Lmax+1); - fac.resize(Lmax+1); - - size_t count = 0; - for (int L = 0; L <= Lmax; ++L) { - for (int lx = 0; lx <= L; ++lx) { - for (int ly = 0; ly <= L; ++ly) { - for (int lz = 0; lz <= L; ++lz) { - if (lx+ly+lz == L) { - std::vector<int> o = {lx, ly, lz}; - orbitals[L].push_back(o); - const double f = fact(L)/(fact(lx)*fact(ly)*fact(lz))/my_pow(4*rc,L); - fac[L].push_back(f); - count++; - } - } - } + orbitals.resize(Lmax+1); + fac.resize(Lmax+1); + + size_t count = 0; + for (int L = 0; L <= Lmax; ++L) { + for (int lx = 0; lx <= L; ++lx) { + for (int ly = 0; ly <= L; ++ly) { + for (int lz = 0; lz <= L; ++lz) { + if (lx+ly+lz == L) { + std::vector<int> o = {lx, ly, lz}; + orbitals[L].push_back(o); + const double f = fact(L)/(fact(lx)*fact(ly)*fact(lz))/my_pow(4*rc,L); + fac[L].push_back(f); + count++; + } } + } } - return count; + } + return count; } template <typename F> double DM_mEAD<F>::fact(int n) { - double f=1.0; - while (n) { - f *= n; - --n; - } - return f; + double f=1.0; + while (n) { + f *= n; + --n; + } + return f; } template <typename F> double DM_mEAD<F>::my_pow(double x, int n){ - double r = 1.0; + double r = 1.0; - while(n > 0){ - r *= x; - --n; - } - return r; + while(n > 0){ + r *= x; + --n; + } + return r; } template <typename F> -size_t DM_mEAD<F>::rhoi_size() { - return rhoisize; +void DM_mEAD<F>::init() { + keys.push_back("CGRIDMB"); + keys.push_back("SGRIDMB"); + keys.push_back("CEMBFUNC"); + keys.push_back("SEMBFUNC"); + nparams=5; } -template <typename F> -size_t DM_mEAD<F>::rhoip_size() { - return rhoisize; -} - diff --git a/include/tadah/models/descriptors/dm/dm_mjoin.h b/include/tadah/models/descriptors/dm/dm_mjoin.h new file mode 100644 index 0000000000000000000000000000000000000000..164adf93cae87d0a954dd8a73e4fafb0068aec9f --- /dev/null +++ b/include/tadah/models/descriptors/dm/dm_mjoin.h @@ -0,0 +1,92 @@ +#ifndef DM_MJOIN_H +#define DM_MJOIN_H + +#include "tadah/core/registry.h" +#include <cstddef> +#include <tadah/models/descriptors/dm/dm_base.h> +#include <tadah/models/descriptors/d_mjoin.h> + +/** \brief Meta many-body descriptor for combining multiple DM descriptors. + * + * This descriptor provides an interface for concatenating various many-body descriptors. + * The resulting descriptor can then be used by Tadah! like any standard many-body descriptor. + * + * Each descriptor must have a specified type in a configuration file, along with a cutoff function, + * cutoff distance, and other optional keys that are typically expected for this descriptor, + * such as SGRIDMB and CGRIDMB. + * + * When listing descriptors under the TYPEMB key, include parameters relevant to this descriptor. + * + * Here is an example of configuring these descriptors: + * + * ``` + * TYPEMB DM_mJoin # Meta descriptor for concatenating many-body descriptors + * TYPEMB DM_EAD 1 5 5 # L number, cgrid, sgrid + * RCTYPEMB Cut_Cos + * RCUTMB 3.0 + * CGRIDMB -1 5 0 3.0 # Grid for DM_EAD, blips centers, auto-generated + * SGRIDMB -2 5 1.0 10.0 # Grid for DM_EAD, blips widths, auto-generated + * + * TYPEMB DM_Blip 0 7 7 # L number, cgrid, sgrid + * RCTYPEMB Cut_Tanh + * RCUTMB 7.5 + * SGRIDMB -2 7 0.1 10 # Grid for DM_Blip, blips widths, auto-generated + * CGRIDMB 0 0 0 0 0 0 0 # Grid for DM_Blip, blips centers + * ``` + * + * Note: Grids can be specified on a single line, and the order of the grids should match the order of descriptors. + * + * There is no limit to the number of descriptors that can be concatenated. + * + * \details + * - Ensure the types and grids are correctly specified in the configuration file. + * - The cutoff functions (RCTYPEMB) and distances (RCUTMB) must be defined for each descriptor. + * - Both SGRIDMB and CGRIDMB should be included if relevant, with their sizes matching the given descriptors. + */ +class DM_mJoin : public DM_Base, public D_mJoin { +private: + std::vector<DM_Base*> ds; + std::vector<Config> configs; + std::string lab = "DM_mJoin"; +public: + DM_mJoin(); + ~DM_mJoin(); + DM_mJoin(Config &c); + void calc_aed( + rho_type& rho, + aed_type &aed) override; + void calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale=1) override; + void calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale=1) override; + std::string label() override; + void init_rhoi(rho_type& rhoi) override; + void calc_rho( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rho, + const double scale=1) override; + void set_fidx(size_t fidx_) override; + void set_rfidx(size_t rfidx_) override; + void init() override; +}; + +#endif diff --git a/include/tadah/models/ekm.h b/include/tadah/models/ekm.h index 9a07ced93a9992ce279bfd7c94e5ecaea5a28010..fa4540fde674435e607deab4732aaaaff093c34c 100644 --- a/include/tadah/models/ekm.h +++ b/include/tadah/models/ekm.h @@ -126,8 +126,8 @@ class EKM { delete[] c; } - aed_type2 project(aed_type2 &aed, Matrix &basis) { - aed_type2 temp(basis.cols()); + aed_type project(aed_type &aed, Matrix &basis) { + aed_type temp(basis.cols()); for (size_t b=0; b<basis.cols(); b++) { temp(b) = kernel(aed,basis[b]); } diff --git a/include/tadah/models/functions/basis_functions/bf_base.h b/include/tadah/models/functions/basis_functions/bf_base.h index c68da2165b4f6a67c8ee3b6b91da4f9dc23b602f..c73c6f0fc2b8cd4963a3f14e7abcb17624ccc5b4 100644 --- a/include/tadah/models/functions/basis_functions/bf_base.h +++ b/include/tadah/models/functions/basis_functions/bf_base.h @@ -8,11 +8,14 @@ /** \brief Base class to be used by all basis functions */ struct BF_Base: public virtual Function_Base { - virtual ~BF_Base(); - virtual double epredict(const t_type &, const aed_type2& ) const=0; - virtual double fpredict(const t_type &, const fd_type &, - const aed_type2& , const size_t ) const=0; - virtual force_type fpredict(const t_type &, const fd_type &, - const aed_type2& ) const=0; + BF_Base(); + BF_Base(const Config &c); + virtual ~BF_Base(); + + // virtual double epredict(const t_type &, const aed_type& ) const=0; + // virtual double fpredict(const t_type &, const fd_type &, + // const aed_type& , const size_t ) const=0; + // virtual force_type fpredict(const t_type &, const fd_type &, + // const aed_type& ) const=0; }; #endif diff --git a/include/tadah/models/functions/basis_functions/bf_linear.h b/include/tadah/models/functions/basis_functions/bf_linear.h index ca3609797fb182f0e396132a22e7b44ef56297d4..0fe0b70bdd93f2d22aa07b23d2eb5605265e4951 100644 --- a/include/tadah/models/functions/basis_functions/bf_linear.h +++ b/include/tadah/models/functions/basis_functions/bf_linear.h @@ -24,7 +24,7 @@ struct BF_Linear : public virtual BF_Base { * @brief Retrieve the label of the basis function. * @return String label of the basis function. */ - std::string get_label() const; + std::string get_label() const override; std::string label = "BF_Linear"; ///< Label identifying the basis function. @@ -34,7 +34,7 @@ struct BF_Linear : public virtual BF_Base { * @param aed Atomic descriptors. * @return Predicted energy. */ - double epredict(const t_type &weights, const aed_type2 &aed) const; + double epredict(const t_type &weights, const aed_type &aed) const override; /** * @brief Predicts force for a specific dimension using the linear basis function. @@ -45,7 +45,7 @@ struct BF_Linear : public virtual BF_Base { * @return Predicted force component. */ double fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2 &aedi, const size_t k) const; + const aed_type &aedi, const size_t k) const override; /** * @brief Predicts forces using the linear basis function. @@ -55,6 +55,6 @@ struct BF_Linear : public virtual BF_Base { * @return Predicted forces. */ force_type fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2 &aedi) const; + const aed_type &aedi) const override; }; #endif diff --git a/include/tadah/models/functions/basis_functions/bf_polynomial2.h b/include/tadah/models/functions/basis_functions/bf_polynomial2.h index f8dcd9f6d29f69e47bbf20a6a4160c0a71a47489..150fc6e3694a200d924678d814043e3047c22964 100644 --- a/include/tadah/models/functions/basis_functions/bf_polynomial2.h +++ b/include/tadah/models/functions/basis_functions/bf_polynomial2.h @@ -26,7 +26,7 @@ struct BF_Polynomial2 : public virtual BF_Base { * @brief Retrieve the label of the basis function. * @return String label of the basis function. */ - std::string get_label() const; + std::string get_label() const override; /** * @brief Predicts energy using the polynomial basis function. @@ -34,7 +34,7 @@ struct BF_Polynomial2 : public virtual BF_Base { * @param aed Atomic descriptors. * @return Predicted energy. */ - double epredict(const t_type &weights, const aed_type2 &aed) const; + double epredict(const t_type &weights, const aed_type &aed) const override; /** * @brief Predicts force for a specific dimension using the polynomial basis function. @@ -45,7 +45,7 @@ struct BF_Polynomial2 : public virtual BF_Base { * @return Predicted force component. */ double fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2 &aedi, const size_t k) const; + const aed_type &aedi, const size_t k) const override; /** * @brief Predicts forces using the polynomial basis function. @@ -55,6 +55,6 @@ struct BF_Polynomial2 : public virtual BF_Base { * @return Predicted forces. */ force_type fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2 &aedi) const; + const aed_type &aedi) const override; }; #endif diff --git a/include/tadah/models/functions/function_base.h b/include/tadah/models/functions/function_base.h index 01d73b7d9789b40d38ab52fed24dd0605a690024..468037fc67eb8e4a5f9cdc061f5cdc7a74f9fc3f 100644 --- a/include/tadah/models/functions/function_base.h +++ b/include/tadah/models/functions/function_base.h @@ -8,35 +8,31 @@ /** Base class for Kernels and Basis Functions */ struct Function_Base { - private: - int verbose; - - public: - Function_Base() { - verbose=0; - } - Function_Base(const Config &c) { - verbose = c.get<int>("VERBOSE"); - } - void set_verbose(int v) { verbose=v; } - int get_verbose() { return verbose; } - - // Derived classes must implement Derived() and Derived(Config) - virtual ~Function_Base() {}; - - // For Kernels - virtual double operator() (const aed_type2& , const aed_type2& ) { return 0.0; }; - virtual aed_type2 derivative(const aed_type2& , const aed_type2& ) { return aed_type2(); }; - virtual double prime(const aed_type2& , const aed_type2& , - const aed_type2& ) { return 0.0; } - virtual void set_basis(const Matrix ) {}; - - /** \brief Return label of this object */ - virtual std::string get_label() const=0; - virtual double epredict(const t_type &, const aed_type2& ) const=0; - virtual double fpredict(const t_type &, const fd_type &, - const aed_type2&, const size_t ) const=0; - virtual force_type fpredict(const t_type &, const fd_type &, - const aed_type2& ) const=0; +private: + int verbose; + +public: + Function_Base(); + Function_Base(const Config &c); + void set_verbose(int v); + int get_verbose(); + + // Derived classes must implement Derived() and Derived(Config) + virtual ~Function_Base(); + + // For Kernels + virtual double operator() (const aed_type& , const aed_type& ) const; + virtual aed_type derivative(const aed_type& , const aed_type& ) const; + virtual double prime(const aed_type& , const aed_type& , + const aed_type& ) const; + virtual void set_basis(const Matrix ); + + /** \brief Return label of this object */ + virtual std::string get_label() const=0; + virtual double epredict(const t_type &, const aed_type& ) const=0; + virtual double fpredict(const t_type &, const fd_type &, + const aed_type&, const size_t ) const=0; + virtual force_type fpredict(const t_type &, const fd_type &, + const aed_type& ) const=0; }; #endif diff --git a/include/tadah/models/functions/kernels/kern_base.h b/include/tadah/models/functions/kernels/kern_base.h index 41da02ea2f2218cdf862763fc03aabf32f8fa25a..21a0a81e7c6ccadf1fd32512cff4ba0cb31419f1 100644 --- a/include/tadah/models/functions/kernels/kern_base.h +++ b/include/tadah/models/functions/kernels/kern_base.h @@ -16,23 +16,25 @@ class Kern_Base: public virtual Function_Base { public: Matrix basis; + Kern_Base(); + Kern_Base(const Config &c); virtual ~Kern_Base(); - /** - * Calculate kernel value given two vectors - * - * - b = basis vector - * - af = atomic energy descriptor - */ - virtual double operator() (const aed_type2 &b, const aed_type2 &af) const=0; - - /** - * Calculate the kernel derivative wrt to the second argument - * - * - b = basis vector - * - af = atomic energy descriptor - */ - virtual aed_type2 derivative(const aed_type2 &b, const aed_type2 &af) const=0; + // /** + // * Calculate kernel value given two vectors + // * + // * - b = basis vector + // * - af = atomic energy descriptor + // */ + virtual double operator() (const aed_type &b, const aed_type &af) const=0; + // + // /** + // * Calculate the kernel derivative wrt to the second argument + // * + // * - b = basis vector + // * - af = atomic energy descriptor + // */ + virtual aed_type derivative(const aed_type &b, const aed_type &af) const=0; /** * Calculate inner product of the kernel derivative @@ -43,8 +45,8 @@ class Kern_Base: public virtual Function_Base { * - ff = force descriptor (TODO i-th dir component of it) * TODO consider calculating all 3-directions at once */ - virtual double prime(const aed_type2 &b, const aed_type2 &af, - const aed_type2 &ff) const=0; + virtual double prime(const aed_type &b, const aed_type &af, + const aed_type &ff) const=0; /** \brief Set basis for calculations */ virtual void set_basis(const Matrix b); @@ -54,11 +56,11 @@ class Kern_Base: public virtual Function_Base { /** \brief Return basis stored by this object */ virtual Matrix get_basis(); - virtual double epredict(const t_type &kweights, const aed_type2 &aed) const; + virtual double epredict(const t_type &kweights, const aed_type &aed) const; virtual double fpredict(const t_type &kweights, const fd_type &fdij, - const aed_type2 &aedi, const size_t k) const; + const aed_type &aedi, const size_t k) const; virtual force_type fpredict(const t_type &kweights, const fd_type &fdij, - const aed_type2 &aedi) const; + const aed_type &aedi) const; virtual void read_basis_from_config(const Config &config, Matrix &b); diff --git a/include/tadah/models/functions/kernels/kern_linear.h b/include/tadah/models/functions/kernels/kern_linear.h index 697d85f8f3466cc6b1f6cf5bba8068a302513168..64d581eeffa2e2b3f589b879afac4a3b81c11132 100644 --- a/include/tadah/models/functions/kernels/kern_linear.h +++ b/include/tadah/models/functions/kernels/kern_linear.h @@ -18,21 +18,21 @@ class Kern_Linear : public virtual Kern_Base { public: Kern_Linear (); Kern_Linear (const Config &c); - std::string get_label() const; + std::string get_label() const override; /** * Label used for this class */ std::string label = "Kern_Linear"; - double operator() (const aed_type2& b, const aed_type2& af) const; - aed_type2 derivative(const aed_type2& b, const aed_type2& ) const; - double prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const; - void set_basis(const Matrix ) {} + double operator() (const aed_type& b, const aed_type& af) const override; + aed_type derivative(const aed_type& b, const aed_type& ) const override; + double prime(const aed_type& b, const aed_type& af, const aed_type& ff) const override; + void set_basis(const Matrix ) override {} - double epredict(const t_type &weights, const aed_type2& aed) const; + double epredict(const t_type &weights, const aed_type& aed) const override; double fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2& aedi, const size_t k) const; + const aed_type& aedi, const size_t k) const override; force_type fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2& aedi) const; + const aed_type& aedi) const override; }; #endif diff --git a/include/tadah/models/functions/kernels/kern_lq.h b/include/tadah/models/functions/kernels/kern_lq.h index 7dbfb7edeadf128662464313a18bbb4a02576b0e..6850a95631b4a2afb340dfabd121267526929040 100644 --- a/include/tadah/models/functions/kernels/kern_lq.h +++ b/include/tadah/models/functions/kernels/kern_lq.h @@ -24,10 +24,10 @@ class Kern_LQ : public virtual Kern_Base { * Label used for this class */ std::string label = "Kern_LQ"; - double operator() (const aed_type2& b, const aed_type2& af) const; - aed_type2 derivative(const aed_type2& b, const aed_type2& af) const; - double prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const; - std::string get_label() const; + double operator() (const aed_type& b, const aed_type& af) const override; + aed_type derivative(const aed_type& b, const aed_type& af) const override; + double prime(const aed_type& b, const aed_type& af, const aed_type& ff) const override; + std::string get_label() const override; }; #endif diff --git a/include/tadah/models/functions/kernels/kern_polynomial.h b/include/tadah/models/functions/kernels/kern_polynomial.h index 246724921c4705196fa72f9ad360c6ec515d5f64..88fc2b33aec14954ce2c952b5c09205fa91646fb 100644 --- a/include/tadah/models/functions/kernels/kern_polynomial.h +++ b/include/tadah/models/functions/kernels/kern_polynomial.h @@ -27,10 +27,10 @@ class Kern_Polynomial : public virtual Kern_Base { * Label used for this class */ std::string label = "Kern_Polynomial"; - std::string get_label() const; - double operator() (const aed_type2& b, const aed_type2& af) const; - aed_type2 derivative(const aed_type2& b, const aed_type2& af) const; - double prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const; + std::string get_label() const override; + double operator() (const aed_type& b, const aed_type& af) const override; + aed_type derivative(const aed_type& b, const aed_type& af) const override; + double prime(const aed_type& b, const aed_type& af, const aed_type& ff) const override; }; #endif diff --git a/include/tadah/models/functions/kernels/kern_quadratic.h b/include/tadah/models/functions/kernels/kern_quadratic.h index 187c3e8ccd3564c2ec2edd5a9e202e6acbae96f4..6db5c11c5c898503023ab79aba89adb14bb231a0 100644 --- a/include/tadah/models/functions/kernels/kern_quadratic.h +++ b/include/tadah/models/functions/kernels/kern_quadratic.h @@ -23,10 +23,10 @@ class Kern_Quadratic : public virtual Kern_Base { * Label used for this class */ std::string label = "Kern_Quadratic"; - double operator() (const aed_type2& b, const aed_type2& af) const; - aed_type2 derivative(const aed_type2& b, const aed_type2& af) const; - double prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const; - std::string get_label() const; + double operator() (const aed_type& b, const aed_type& af) const override; + aed_type derivative(const aed_type& b, const aed_type& af) const override; + double prime(const aed_type& b, const aed_type& af, const aed_type& ff) const override; + std::string get_label() const override; }; #endif diff --git a/include/tadah/models/functions/kernels/kern_rbf.h b/include/tadah/models/functions/kernels/kern_rbf.h index 340d45726dc400c9dd2e9024ed65e70073621e28..322a765122f927c896dd6449e5b9ac2328552e95 100644 --- a/include/tadah/models/functions/kernels/kern_rbf.h +++ b/include/tadah/models/functions/kernels/kern_rbf.h @@ -25,10 +25,10 @@ class Kern_RBF : public virtual Kern_Base { Kern_RBF (); Kern_RBF (const Config &c); std::string label = "Kern_RBF"; - double operator() (const aed_type2& b, const aed_type2& af) const; - aed_type2 derivative(const aed_type2& b, const aed_type2& af) const; - double prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const; - std::string get_label() const; + double operator() (const aed_type& b, const aed_type& af) const override; + aed_type derivative(const aed_type& b, const aed_type& af) const override; + double prime(const aed_type& b, const aed_type& af, const aed_type& ff) const override; + std::string get_label() const override; private: double gamma; diff --git a/include/tadah/models/functions/kernels/kern_sigmoid.h b/include/tadah/models/functions/kernels/kern_sigmoid.h index 7f9c0f6971288943b1a0281ea8eff531197c02a2..c76189cac974fa294c4856641171ca9bae963f39 100644 --- a/include/tadah/models/functions/kernels/kern_sigmoid.h +++ b/include/tadah/models/functions/kernels/kern_sigmoid.h @@ -26,10 +26,10 @@ class Kern_Sigmoid : public virtual Kern_Base { Kern_Sigmoid (); Kern_Sigmoid (const Config &c); std::string label = "Kern_Sigmoid"; - double operator() (const aed_type2& b, const aed_type2& af) const; - aed_type2 derivative(const aed_type2& b, const aed_type2& af) const; - double prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const; - std::string get_label() const; + double operator() (const aed_type& b, const aed_type& af) const override; + aed_type derivative(const aed_type& b, const aed_type& af) const override; + double prime(const aed_type& b, const aed_type& af, const aed_type& ff) const override; + std::string get_label() const override; }; #endif diff --git a/include/tadah/models/m_blr_core.h b/include/tadah/models/m_blr_core.h index d4d4b182caff33c3959efc45dd5d1192554e1d9f..144d1c82428d996b4cbcdfda9dcb8558ca826005 100644 --- a/include/tadah/models/m_blr_core.h +++ b/include/tadah/models/m_blr_core.h @@ -59,7 +59,7 @@ public: * @param v Input vector for prediction. * @return Predicted value. */ - double predict(const aed_type2 &v) const { + double predict(const aed_type &v) const { return bf.epredict(get_weights(), v); } diff --git a/include/tadah/models/m_blr_train.h b/include/tadah/models/m_blr_train.h index d78bd4354854846a4201de64e5adc459bb07c5b2..fdbc457cff90ed6bf89224f2bd81ef5993ae7c97 100644 --- a/include/tadah/models/m_blr_train.h +++ b/include/tadah/models/m_blr_train.h @@ -1,6 +1,8 @@ #ifndef M_BLR_TRAIN_H #define M_BLR_TRAIN_H +#include "tadah/core/core_types.h" +#include "tadah/core/utils.h" #include <tadah/models/m_train.h> #include <tadah/models/m_blr_core.h> #include <tadah/models/linear_regressor.h> @@ -9,6 +11,7 @@ #include <tadah/core/config.h> #include <iostream> +#include <vector> /** * @class M_BLR_Train @@ -54,13 +57,63 @@ public: * @param T Target vector. * @throws std::runtime_error if the object is already trained. */ - void train(phi_type &Phi, t_type &T) { - if (trained) { - throw std::runtime_error("This object is already trained!"); + void train(phi_type &Phi, t_type &T) { + if (trained) { + throw std::runtime_error("This object is already trained!"); + } + + if (config.exist("FIXWEIGHT") && config.exist("FIXINDEX")) { + std::vector<std::string> indices_str(config.size("FIXINDEX")); + config.get("FIXINDEX", indices_str); + + // Parse indices and perform checks + std::vector<size_t> indices = parse_indices(indices_str); + + // Check that the min index is >= 1 and max index is <= Phi.cols() + if (!indices.empty()) { + size_t max_index = *std::max_element(indices.begin(), indices.end()); + if (*std::min_element(indices.begin(), indices.end()) < 1 || max_index > Phi.cols()) { + throw std::runtime_error("FIXINDEX: Indices out of bounds: valid range is from 1 to " + std::to_string(Phi.cols())); } - LinearRegressor::train(config, Phi, T, weights, Sigma); - trained = true; + } + + // Adjust for 0-based indexing + for (auto &i : indices) i--; + + t_type w_f(config.size("FIXWEIGHT")); + if (w_f.size() != indices.size()) { + throw std::runtime_error("FIXWEIGHT and FIXINDEX differ in size: " + std::to_string(w_f.size()) + " and " + std::to_string(indices.size())); + } + + config.get("FIXWEIGHT", w_f); + + t_type T_r; + auto move_map = prep_train_with_residuals(Phi, T, indices, w_f, T_r); + + // Resize Phi for training + Phi.resize(Phi.rows(), Phi.cols() - indices.size()); + + LinearRegressor::train(config, Phi, T_r, weights, Sigma); + + t_type w_temp(weights.size() + indices.size()); + + for (size_t i = 0; i < w_f.size(); ++i) { + w_temp[w_temp.size() - w_f.size() + i] = w_f[i]; + } + + for (size_t i = 0; i < weights.size(); ++i) { + w_temp[i] = weights[i]; + } + + weights = w_temp; + reverse_vector(weights, move_map); + trained = true; + } + else { + LinearRegressor::train(config, Phi, T, weights, Sigma); + trained = true; } + } }; #endif // M_BLR_TRAIN_H diff --git a/include/tadah/models/m_core.h b/include/tadah/models/m_core.h index a0a2a4ac08cb083859804ab6a1cfb8ec479d2839..96e3e0f2d4f83927883f91489fe3fb35cd444312 100644 --- a/include/tadah/models/m_core.h +++ b/include/tadah/models/m_core.h @@ -12,10 +12,12 @@ */ class M_Core { public: - int verbose; ///< Verbose level for logging. + int verbose = 0; ///< Verbose level for logging. bool trained = false; ///< Indicates if the model has been trained. t_type weights; ///< Weights vector for the model. + int is_verbose() {return verbose;} + /** * @brief Virtual destructor for polymorphic deletion. */ @@ -56,7 +58,7 @@ public: * @param v Input vector for prediction. * @return Predicted value. */ - virtual double predict(const aed_type2 &v) const = 0; + virtual double predict(const aed_type &v) const = 0; /** * @brief Pure virtual function to get weights' uncertainty. diff --git a/include/tadah/models/m_krr_core.h b/include/tadah/models/m_krr_core.h index 2182e6b2feab37845370c80d4cc1800e28c008a4..9eef34c77459ec9fc986ba1cf6043f0b01110c52 100644 --- a/include/tadah/models/m_krr_core.h +++ b/include/tadah/models/m_krr_core.h @@ -64,7 +64,7 @@ public: * @param v Input vector for prediction. * @return Predicted value. */ - double predict(const aed_type2 &v) const { + double predict(const aed_type &v) const { return kernel.epredict(weights, v); } diff --git a/include/tadah/models/m_krr_train.h b/include/tadah/models/m_krr_train.h index c6160f6f7804c7e6c013ee1eeb76d2f0703a744d..d4e79033377c3051f1cc9c3df054ff2ea439378a 100644 --- a/include/tadah/models/m_krr_train.h +++ b/include/tadah/models/m_krr_train.h @@ -60,21 +60,74 @@ public: * @param T Target vector. * @throws std::runtime_error if the object is already trained. */ - void train(phi_type &Phi, t_type &T) { - if (trained) { - throw std::runtime_error("This object is already trained!"); - } - if (kernel.get_label() != "Kern_Linear") { - ekm.project(Phi); + void train(phi_type &Phi, t_type &T) { + if (trained) { + throw std::runtime_error("This object is already trained!"); + } + + if (config.exist("FIXWEIGHT") && config.exist("FIXINDEX")) { + std::vector<std::string> indices_str(config.size("FIXINDEX")); + config.get("FIXINDEX", indices_str); + + // Parse indices and perform checks + std::vector<size_t> indices = parse_indices(indices_str); + + // Check that the min index is >= 1 and max index is <= Phi.cols() + if (!indices.empty()) { + size_t max_index = *std::max_element(indices.begin(), indices.end()); + if (*std::min_element(indices.begin(), indices.end()) < 1 || max_index > Phi.cols()) { + throw std::runtime_error("FIXINDEX: Indices out of bounds: valid range is from 1 to " + std::to_string(Phi.cols())); } - LinearRegressor::train(config, Phi, T, weights, Sigma); + } + + // Adjust for 0-based indexing + for (auto &i : indices) i--; + + t_type w_f(config.size("FIXWEIGHT")); + if (w_f.size() != indices.size()) { + throw std::runtime_error("FIXWEIGHT and FIXINDEX differ in size: " + std::to_string(w_f.size()) + " and " + std::to_string(indices.size())); + } + + config.get("FIXWEIGHT", w_f); - if (kernel.get_label() != "Kern_Linear") { - weights = ekm.EKM_mat * weights; + t_type T_r; + auto move_map = prep_train_with_residuals(Phi, T, indices, w_f, T_r); + + reverse_columns(Phi, move_map); + + for (const auto &i : indices) { + for (size_t j=0; j<Phi.rows(); ++j) { + Phi(j,i)=0; } - trained = true; + } + + if (kernel.get_label() != "Kern_Linear") { + ekm.project(Phi); + } + LinearRegressor::train(config, Phi, T_r, weights, Sigma); + if (kernel.get_label() != "Kern_Linear") { + weights = ekm.EKM_mat * weights; + } + + // reverse_vector(weights, move_map); + for (size_t i=0; i<indices.size(); ++i) { + weights[indices[i]]=w_f[i]; + } + trained = true; + } + else { + if (kernel.get_label() != "Kern_Linear") { + ekm.project(Phi); + } + LinearRegressor::train(config, Phi, T, weights, Sigma); + if (kernel.get_label() != "Kern_Linear") { + weights = ekm.EKM_mat * weights; + } + trained = true; } + } + /** * @brief Standard KRR training using covariance matrix computation. * @@ -90,7 +143,7 @@ public: if (lambda < 0) throw std::runtime_error("This KRR implementation cannot use LAMBDA -1 (Evidence Approximation)"); - std::cout << "Computing Kernel Matrix" << std::endl; + if (M_KRR_Core<Kern>::is_verbose()) std::cout << "Computing Kernel Matrix" << std::endl; Matrix K(B.cols(), B.cols()); for (size_t i = 0; i < K.cols(); i++) { @@ -99,12 +152,12 @@ public: if (i == j) K(i, j) += lambda; } } + if (M_KRR_Core<Kern>::is_verbose()) std::cout << "Matrix condition number: " << condition_number(K) << std::endl; - std::cout << "Solving..." << std::flush; + if (M_KRR_Core<Kern>::is_verbose()) std::cout << "Solving..." << std::flush; weights = solve_posv(K, T); - std::cout << "Done" << std::endl; + if (M_KRR_Core<Kern>::is_verbose()) std::cout << "Done" << std::endl; - std::cout << "Matrix condition number: " << condition_number(K) << std::endl; trained = true; } diff --git a/include/tadah/models/m_predict.h b/include/tadah/models/m_predict.h index 233c75d3ef013c8ccb73a8f77dbffe57c3afd500..04ac366c951e61aa1c046c4c35561817343085fc 100644 --- a/include/tadah/models/m_predict.h +++ b/include/tadah/models/m_predict.h @@ -17,13 +17,13 @@ class M_Predict { * If aed contains sum over all nearest neighbours than the result is * a local atomic energy \f$ E_i \f$. * */ - virtual double epredict(const aed_type2 &aed) const=0; + virtual double epredict(const aed_type &aed) const=0; /** \brief Predict force between a pair of atoms in a k-direction. */ - virtual double fpredict(const fd_type &fdij, const aed_type2 &aedi, size_t k) const=0; + virtual double fpredict(const fd_type &fdij, const aed_type &aedi, size_t k) const=0; /** \brief Predict force between a pair of atoms. */ virtual force_type fpredict(const fd_type &fdij, - const aed_type2 &aedi) const=0; + const aed_type &aedi) const=0; }; #endif diff --git a/include/tadah/models/m_train.h b/include/tadah/models/m_train.h index abcf824b5854cc95dcd74f40be423e2e87a4686a..09a2113636d4173ead1c8980ca4f1439f1e8e4ac 100644 --- a/include/tadah/models/m_train.h +++ b/include/tadah/models/m_train.h @@ -2,6 +2,7 @@ #define M_TRAIN_H #include <tadah/core/core_types.h> +#include <tadah/core/utils.h> /** * @class M_Train @@ -11,12 +12,12 @@ */ class M_Train { public: - /** + /** * @brief Virtual destructor for polymorphic deletion. */ - virtual ~M_Train() {} + virtual ~M_Train() {} - /** + /** * @brief Pure virtual function to train the model. * * Must be implemented by derived classes. @@ -24,7 +25,62 @@ public: * @param Phi Design matrix containing input features. * @param T Target vector for training. */ - virtual void train(phi_type &Phi, t_type &T) = 0; + virtual void train(phi_type &Phi, t_type &T) = 0; + + /** + * Swaps columns and fits a reduced matrix to obtain residuals. + * + * This function processes a full matrix Phi by swapping columns specified by indices, + * creating a new pointer for the fixed matrix Phi_f, and then use w_f weights + * to obtain prediction T_f = Phi_f w_f. The function then copmutes the residual vector + * T_r = T - T_f. On exit, the Phi matrix is rearranged such that the indices.size() + * rightmost columns of the original matrix are the same as Phi_f. + * The function return a mapping between columns of original Phi matrix and rearranged. + * + * @param Phi The full matrix to be reduced and fitted to the adjusted target + * vector. + * @param T The full target vector to which the reduced matrix Phi will + * be fitted. + * @param indices A vector of indices specifying which columns in the + * original matrix are fixed and should be considered during + * the regression. + * @param w_f A vector of fixed weights corresponding to the specified + * indices. These weights are used to adjust the target + * vector, resulting in residuals. + */ + template <typename M> + std::vector<size_t> prep_train_with_residuals( + Matrix_Base<M> &Phi, t_type &T, std::vector<size_t> &indices, const t_type w_f, t_type &T_r) { + + if (w_f.size() != indices.size()) { + throw std::runtime_error("Size of w_f must be equal to size of indices."); + } + + std::sort(indices.begin(), indices.end()); + + if (indices.back() >= Phi.cols()) { + throw std::runtime_error("Largest index is greater than the number of columns in Phi."); + } + + std::vector<size_t> move_map = move_columns_in_place(Phi,indices); + + // indices.size() = 1 + // indices[0] 1 + // 1 4 7 1 7 4 + // 2 5 8 -> 2 8 5 + // 3 6 9 3 9 6 + // Phi Phi_o Phi_f + // move_map = {0,2,1} + + // the fixed columns are to the right + MatrixView Phi_f(Phi, Phi.cols()-indices.size()); + + t_type T_f = Phi_f * w_f; + + T_r = T-T_f; + + return move_map; + } }; #endif // M_TRAIN_H diff --git a/src/bf_base.cpp b/src/bf_base.cpp index 043999f13df608d87e3e3898b943daa3162dd772..67b6d57af50cb9b0971b8fec95e4800b667e70cd 100644 --- a/src/bf_base.cpp +++ b/src/bf_base.cpp @@ -1,2 +1,4 @@ #include <tadah/models/functions/basis_functions/bf_base.h> +BF_Base::BF_Base(const Config &c): Function_Base(c) {} +BF_Base::BF_Base() {} BF_Base::~BF_Base() {} diff --git a/src/bf_linear.cpp b/src/bf_linear.cpp index 50a612bc42f3b25e6e61d4f12d56e288689f6a56..7647f638530ecab013a4695b964f933e75ac78cc 100644 --- a/src/bf_linear.cpp +++ b/src/bf_linear.cpp @@ -1,21 +1,23 @@ #include <tadah/models/functions/basis_functions/bf_linear.h> BF_Linear::BF_Linear() {} -BF_Linear::BF_Linear(const Config &c): Function_Base(c) {} +BF_Linear::BF_Linear(const Config &c): + Function_Base(c), + BF_Base(c) {} std::string BF_Linear::get_label() const { return label; } -double BF_Linear::epredict(const t_type &weights, const aed_type2& aed) const +double BF_Linear::epredict(const t_type &weights, const aed_type& aed) const { return weights*aed; } double BF_Linear::fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2& , const size_t k) const + const aed_type& , const size_t k) const { return -1*(fdij(k) * weights); } force_type BF_Linear::fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2& ) const + const aed_type& ) const { return -1*(fdij * weights); } diff --git a/src/bf_polynomial2.cpp b/src/bf_polynomial2.cpp index 8d6e6fc037e11220fa1dd03e0541a2fc090bcfab..d3ee5b3280f1d43c12d9e6ae332fe1378ca8d25c 100644 --- a/src/bf_polynomial2.cpp +++ b/src/bf_polynomial2.cpp @@ -1,14 +1,15 @@ #include <tadah/models/functions/basis_functions/bf_polynomial2.h> - BF_Polynomial2::BF_Polynomial2() {} -BF_Polynomial2::BF_Polynomial2(const Config &c): Function_Base(c) +BF_Polynomial2::BF_Polynomial2(const Config &c): + Function_Base(c), + BF_Base(c) {} std::string BF_Polynomial2::get_label() const { return label; } -double BF_Polynomial2::epredict(const t_type &weights, const aed_type2& aed) const +double BF_Polynomial2::epredict(const t_type &weights, const aed_type& aed) const { size_t b=0; double res=0.0; @@ -20,7 +21,7 @@ double BF_Polynomial2::epredict(const t_type &weights, const aed_type2& aed) con return res; } double BF_Polynomial2::fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2& aedi, const size_t k) const + const aed_type& aedi, const size_t k) const { double res=0.0; size_t b=0; @@ -32,7 +33,7 @@ double BF_Polynomial2::fpredict(const t_type &weights, const fd_type &fdij, return res; } force_type BF_Polynomial2::fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2& aedi) const + const aed_type& aedi) const { force_type v; for (size_t k=0; k<3; ++k) { diff --git a/src/cutoffs.cpp b/src/cutoffs.cpp index 768516ace7cce8618d73b8eb91677554b26d3f0e..b818cdab76a7d70389bed0b258fca95b2de6751c 100644 --- a/src/cutoffs.cpp +++ b/src/cutoffs.cpp @@ -5,6 +5,7 @@ template<> CONFIG::Registry<Cut_Base,double>::Map CONFIG::Registry<Cut_Base,double>::registry{}; CONFIG::Registry<Cut_Base,double>::Register<Cut_Cos> Cut_Cos_1( "Cut_Cos" ); +CONFIG::Registry<Cut_Base,double>::Register<Cut_Cos_S> Cut_Cos_S_1( "Cut_Cos_S" ); CONFIG::Registry<Cut_Base,double>::Register<Cut_Tanh> Cut_Tanh_1( "Cut_Tanh" ); CONFIG::Registry<Cut_Base,double>::Register<Cut_Poly2> Cut_Poly_1( "Cut_Poly2" ); CONFIG::Registry<Cut_Base,double>::Register<Cut_Dummy> Cut_Dummy_1( "Cut_Dummy" ); @@ -165,3 +166,44 @@ double Cut_Poly2::calc_prime(double r) { double rs=r-rcut_inner; return -30.0*(rs-1.0)*(rs-1.0)*rs*rs; } + +Cut_Cos_S::Cut_Cos_S() {} +Cut_Cos_S::Cut_Cos_S(double rcut) +{ + set_rcut(rcut); + test_rcut(rcut); +} + +std::string Cut_Cos_S::label() { + return lab; +} + +void Cut_Cos_S::set_rcut(const double r) { + test_rcut(r); + rcut=r; + rcut_sq=r*r; + rcut_inv= r<=0 ? 0.0 : 1.0/r; + rcut_inner=rcut-1.0; +} +double Cut_Cos_S::get_rcut() { + return rcut; +} + +double Cut_Cos_S::get_rcut_sq() { + return rcut_sq; +} + +double Cut_Cos_S::calc(double r) { + if (r>=rcut) return 0.0; + else if (r<= rcut_inner) return 1.0; + double rs = (r-rcut_inner)/(rcut-rcut_inner); + return 0.5*(1+std::cos(M_PI*rs)); +} +double Cut_Cos_S::calc_prime(double r) { + if (r>=rcut || r<= rcut_inner) return 0.0; + else { + double rs = (r - rcut_inner) / (rcut - rcut_inner); + double drs_dr = 1.0 / (rcut - rcut_inner); + return -0.5 * M_PI * std::sin(M_PI * rs) * drs_dr; + } +} diff --git a/src/d2_all.cpp b/src/d2_all.cpp index 458293d8f2a171850da5841cd22256be707a9a7f..7bbf5088789054d7685c0cd8435815f3144b9374 100644 --- a/src/d2_all.cpp +++ b/src/d2_all.cpp @@ -1,16 +1,52 @@ -#include <tadah/models/descriptors/d2/d2_base.h> -#include <tadah/models/descriptors/d2/d2_dummy.h> -#include <tadah/models/descriptors/d2/d2_blip.h> -#include <tadah/models/descriptors/d2/d2_bp.h> -#include <tadah/models/descriptors/d2/d2_eam.h> -#include <tadah/models/descriptors/d2/d2_lj.h> -#include <tadah/models/descriptors/d2/d2_mie.h> +#include "tadah/models/descriptors/d2/d2_all.h" +template<> CONFIG::Registry<D_Base>::Map CONFIG::Registry<D_Base>::registry{}; +template<> CONFIG::Registry<D_Base,Config&>::Map CONFIG::Registry<D_Base,Config&>::registry{}; template<> CONFIG::Registry<D2_Base,Config&>::Map CONFIG::Registry<D2_Base,Config&>::registry{}; +CONFIG::Registry<D_Base,Config&>::Register<D2_Blip> D2_Blip_00( "D2_Blip" ); +CONFIG::Registry<D_Base,Config&>::Register<D2_BP> D2_BP_00( "D2_BP" ); +CONFIG::Registry<D_Base,Config&>::Register<D2_Dummy> D2_Dummy_00( "D2_Dummy" ); +CONFIG::Registry<D_Base,Config&>::Register<D2_EAM> D2_EAM_00( "D2_EAM" ); +CONFIG::Registry<D_Base,Config&>::Register<D2_LJ> D2_LJ_00( "D2_LJ" ); +CONFIG::Registry<D_Base,Config&>::Register<D2_MIE> D2_MIE_00( "D2_MIE" ); +CONFIG::Registry<D_Base,Config&>::Register<D2_ZBL> D2_ZBL_00( "D2_ZBL" ); +CONFIG::Registry<D_Base,Config&>::Register<D2_mJoin> D2_mJoin_00( "D2_mJoin" ); + +CONFIG::Registry<D_Base>::Register<D2_Blip> D2_Blip_0( "D2_Blip" ); +CONFIG::Registry<D_Base>::Register<D2_BP> D2_BP_0( "D2_BP" ); +CONFIG::Registry<D_Base>::Register<D2_Dummy> D2_Dummy_0( "D2_Dummy" ); +CONFIG::Registry<D_Base>::Register<D2_EAM> D2_EAM_0( "D2_EAM" ); +CONFIG::Registry<D_Base>::Register<D2_LJ> D2_LJ_0( "D2_LJ" ); +CONFIG::Registry<D_Base>::Register<D2_MIE> D2_MIE_0( "D2_MIE" ); +CONFIG::Registry<D_Base>::Register<D2_ZBL> D2_ZBL_0( "D2_ZBL" ); +CONFIG::Registry<D_Base>::Register<D2_mJoin> D2_mJoin_0( "D2_mJoin" ); + CONFIG::Registry<D2_Base,Config&>::Register<D2_Blip> D2_Blip_1( "D2_Blip" ); CONFIG::Registry<D2_Base,Config&>::Register<D2_BP> D2_BP_1( "D2_BP" ); CONFIG::Registry<D2_Base,Config&>::Register<D2_Dummy> D2_Dummy_1( "D2_Dummy" ); CONFIG::Registry<D2_Base,Config&>::Register<D2_EAM> D2_EAM_1( "D2_EAM" ); CONFIG::Registry<D2_Base,Config&>::Register<D2_LJ> D2_LJ_1( "D2_LJ" ); -CONFIG::Registry<D2_Base,Config&>::Register<D2_MIE> D2_MIE_1( "D2_MIE" ); \ No newline at end of file +CONFIG::Registry<D2_Base,Config&>::Register<D2_MIE> D2_MIE_1( "D2_MIE" ); +CONFIG::Registry<D2_Base,Config&>::Register<D2_ZBL> D2_ZBL_1( "D2_ZBL" ); +CONFIG::Registry<D2_Base,Config&>::Register<D2_mJoin> D2_mJoin_1( "D2_mJoin" ); + + + +// This is in development +CONFIG::Registry<D2_Base,Config&>::Register<D2_Join<D2_LJ,D2_BP>> D2_JOIN_1( "D2_LJ+BP" ); +CONFIG::Registry<D2_Base,Config&>::Register<D2_Join<D2_LJ,D2_Blip>> D2_JOIN_2( "D2_LJ+Blip" ); + +CONFIG::Registry<D2_Base,Config&>::Register<D2_Join<D2_MIE,D2_BP>> D2_JOIN_3( "D2_MIE+BP" ); +CONFIG::Registry<D2_Base,Config&>::Register<D2_Join<D2_MIE,D2_Blip>> D2_JOIN_4( "D2_MIE+Blip" ); + +CONFIG::Registry<D2_Base,Config&>::Register<D2_Join<D2_Blip,D2_Blip>> D2_JOIN_5( "D2_Blip_x2" ); +CONFIG::Registry<D2_Base,Config&>::Register<D2_Join<D2_BP,D2_BP>> D2_JOIN_6( "D2_BP_x2" ); + +CONFIG::Registry<D2_Base,Config&>::Register<D2_Join<D2_EAM,D2_BP>> D2_JOIN_7( "D2_EAM+BP" ); +CONFIG::Registry<D2_Base,Config&>::Register<D2_Join<D2_EAM,D2_Blip>> D2_JOIN_8( "D2_EAM+Blip" ); + +CONFIG::Registry<D2_Base,Config&>::Register<D2_Join<D2_BP,D2_Blip>> D2_JOIN_9( "D2_BP+Blip" ); + +// CONFIG::Registry<D2_Base,Config&>::Register<D2_Join_N<D2_LJ,D2_LJ>> D2_JOIN_3( "D2_LJ_D2_LJ" ); +//CONFIG::Registry<D2_Base,Config&>::Register<D2_Join_N<D2_LJ,D2_LJ,D2_LJ>> D2_JOIN_4( "D2_LJ_D2_LJ_D2_LJ" ); diff --git a/src/d2_base.cpp b/src/d2_base.cpp index 00abcd05957115e8b4026f6b4ad322c8ae77e57b..106639caf445a093db172ccbd18d4e6da02370fa 100644 --- a/src/d2_base.cpp +++ b/src/d2_base.cpp @@ -1 +1,13 @@ #include <tadah/models/descriptors/d2/d2_base.h> + +std::vector<std::string> D2_Base::get_init_atoms(Config &c) { + if (!c.exist("TYPE2B")) { + std::cerr << "Warning: TYPE2B key was not found. " + "Atom pairs must be initialized manually." << std::endl; + return {}; + } + std::vector<std::string> init_atoms(c.size("TYPE2B")); + c.get("TYPE2B", init_atoms); + init_atoms.erase(init_atoms.begin(), init_atoms.begin() + nparams+1); + return init_atoms; +} diff --git a/src/d2_blip.cpp b/src/d2_blip.cpp index ce95084970e28ee4b6baabae8a5a00de5455a61f..3c16d5b275c25ba4b9c0092c316138f8a181836c 100644 --- a/src/d2_blip.cpp +++ b/src/d2_blip.cpp @@ -1,17 +1,24 @@ +#include "tadah/models/descriptors/d_base.h" #include <tadah/models/descriptors/d2/d2_blip.h> #include <tadah/models/descriptors/d_basis_functions.h> #include <cstdlib> #include <stdexcept> - -D2_Blip::D2_Blip(Config &c): - verbose(c.get<int>("VERBOSE")) +D2_Blip::D2_Blip() { + init(); +} +D2_Blip::D2_Blip(Config &c): D2_Base(c) { - if (!c.get<bool>("INIT2B")) return; + init(); get_grid(c,"CGRID2B",mius); get_grid(c,"SGRID2B",etas); + // update config with generated grid + c.remove("CGRID2B"); + for (const auto &m: mius) c.add("CGRID2B",m); + c.remove("SGRID2B"); + for (const auto &e: etas) c.add("SGRID2B",e); if (verbose) { std::cout << std::endl; @@ -34,54 +41,70 @@ D2_Blip::D2_Blip(Config &c): } s=mius.size(); + + auto init_atoms = get_init_atoms(c); + init_for_atoms(init_atoms); } void D2_Blip::calc_aed( + const int Zi, + const int Zj, const double rij, - const double , - const double fc_ij, - aed_type2 &aed) + const double, + aed_type &aed, + const double scale) { - + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; size_t i=fidx; + double fc_ij = fcut->calc(rij); for (size_t c=0; c<mius.size(); c++) { double t = B(etas[c]*(rij-mius[c]),fc_ij); - aed(i++) += t; + aed(i++) += scale*weights[Zj]*t; } } void D2_Blip::calc_dXijdri( + const int Zi, + const int Zj, const double rij, const double , - const double fc_ij, - const double fcp_ij, - fd_type &fd_ij) + fd_type &fd_ij, + const double scale) { + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; size_t i=fidx; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); for (size_t c=0; c<mius.size(); c++) { - fd_ij(i++,0) = dB(etas[c]*(rij-mius[c]),etas[c],fc_ij,fcp_ij); + fd_ij(i++,0) = scale*weights[Zj]*dB(etas[c]*(rij-mius[c]),etas[c],fc_ij,fcp_ij); } } void D2_Blip::calc_all( + const int Zi, + const int Zj, const double rij, const double , - const double fc_ij, - const double fcp_ij, - aed_type2 &aed, - fd_type &fd_ij) + aed_type &aed, + fd_type &fd_ij, + const double scale) { + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; size_t i=fidx; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); for (size_t c=0; c<mius.size(); c++) { - aed(i) += B(etas[c]*(rij-mius[c]),fc_ij); - fd_ij(i,0) = dB(etas[c]*(rij-mius[c]),etas[c],fc_ij,fcp_ij); + aed(i) += scale*weights[Zj]*B(etas[c]*(rij-mius[c]),fc_ij); + fd_ij(i,0) = scale*weights[Zj]*dB(etas[c]*(rij-mius[c]),etas[c],fc_ij,fcp_ij); ++i; } } -size_t D2_Blip::size() { - return s; -} std::string D2_Blip::label() { return lab; } +void D2_Blip::init() { + keys.push_back("CGRID2B"); + keys.push_back("SGRID2B"); + nparams=2; +} diff --git a/src/d2_bp.cpp b/src/d2_bp.cpp index 61b28e46bae7f36226c91929ed1e08e7e7d9d73d..2b564f7f404ff8cdb184124bf0057a8a47c5f8e4 100644 --- a/src/d2_bp.cpp +++ b/src/d2_bp.cpp @@ -1,14 +1,21 @@ #include <tadah/models/descriptors/d2/d2_bp.h> #include <tadah/models/descriptors/d_basis_functions.h> -D2_BP::D2_BP(Config &c): - verbose(c.get<int>("VERBOSE")) -{ +D2_BP::D2_BP() { + init(); +} +D2_BP::D2_BP(Config &c): D2_Base(c) { + init(); if (!c.get<bool>("INIT2B")) return; get_grid(c,"CGRID2B",mius); get_grid(c,"SGRID2B",etas); + // update config with generated grid + c.remove("CGRID2B"); + for (const auto &m: mius) c.add("CGRID2B",m); + c.remove("SGRID2B"); + for (const auto &e: etas) c.add("SGRID2B",e); if (verbose) { std::cout << std::endl; @@ -30,53 +37,68 @@ D2_BP::D2_BP(Config &c): throw std::runtime_error("At least one of SGRID2B values is zero.\n"); } - s=mius.size(); + s = mius.size(); + auto init_atoms = get_init_atoms(c); + init_for_atoms(init_atoms); } void D2_BP::calc_aed( + const int Zi, + const int Zj, const double rij, const double , - const double fc_ij, - aed_type2 &aed) + aed_type &aed, + const double scale) { + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; size_t i=fidx; + double fc_ij = fcut->calc(rij); for (size_t c=0; c<mius.size(); c++) { - aed(i++) += G(rij,etas[c],mius[c],fc_ij); + aed(i++) += scale*weights[Zj]*G(rij,etas[c],mius[c],fc_ij); } } void D2_BP::calc_dXijdri( + const int Zi, + const int Zj, const double rij, const double , - const double fc_ij, - const double fcp_ij, - fd_type &fd_ij) + fd_type &fd_ij, + const double scale) { + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; size_t i=fidx; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); for (size_t c=0; c<mius.size(); c++) { - fd_ij(i++,0) = dG(rij,etas[c],mius[c],fc_ij,fcp_ij); + fd_ij(i++,0) = scale*weights[Zj]*dG(rij,etas[c],mius[c],fc_ij,fcp_ij); } } void D2_BP::calc_all( + const int Zi, + const int Zj, const double rij, const double , - const double fc_ij, - const double fcp_ij, - aed_type2 &aed, - fd_type &fd_ij) + aed_type &aed, + fd_type &fd_ij, + const double scale) { - + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; size_t i=fidx; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); for (size_t c=0; c<mius.size(); c++) { - aed(i) += G(rij,etas[c],mius[c],fc_ij); - fd_ij(i,0) = dG(rij,etas[c],mius[c],fc_ij,fcp_ij); + aed(i) += scale*weights[Zj]*G(rij,etas[c],mius[c],fc_ij); + fd_ij(i,0) = scale*weights[Zj]*dG(rij,etas[c],mius[c],fc_ij,fcp_ij); ++i; } } -size_t D2_BP::size() { - return s; -} std::string D2_BP::label() { return lab; } +void D2_BP::init() { + keys.push_back("CGRID2B"); + keys.push_back("SGRID2B"); + nparams=2; +} diff --git a/src/d2_dummy.cpp b/src/d2_dummy.cpp index 760f7e684f0f80343b88121646e8f29ebd38e289..043e85e690ff393aae0c70df378ba685a61c7d37 100644 --- a/src/d2_dummy.cpp +++ b/src/d2_dummy.cpp @@ -1,27 +1,38 @@ +#include "tadah/models/descriptors/d2/d2_base.h" #include <tadah/models/descriptors/d2/d2_dummy.h> -D2_Dummy::D2_Dummy() {} -D2_Dummy::D2_Dummy(Config &c): - verbose(c.get<int>("VERBOSE")) -{} +D2_Dummy::D2_Dummy() { + init(); +} +D2_Dummy::D2_Dummy(Config &c): D2_Base(c) +{ + init(); +} void D2_Dummy::calc_aed( - const double, - const double, - const double, - aed_type2 & ) {} + const int, + const int, + const double, + const double, + aed_type&, + const double) {} + void D2_Dummy::calc_dXijdri( - const double, - const double, - const double, - const double, - fd_type &) {} + const int, + const int, + const double, + const double, + fd_type &, + const double) {} void D2_Dummy::calc_all( - const double, - const double, - const double, - const double, - aed_type2 & , - fd_type &) {} -size_t D2_Dummy::size() { return s; } + const int, + const int, + const double, + const double, + aed_type & , + fd_type &, + const double) {} std::string D2_Dummy::label() { return lab; } +void D2_Dummy::init() { + nparams=0; +} diff --git a/src/d2_eam.cpp b/src/d2_eam.cpp index b54afb61ce511b7c139b9ce90071d20cf9e27712..90b8b7969ddf2e1b8a7f325982d26a62b621c11c 100644 --- a/src/d2_eam.cpp +++ b/src/d2_eam.cpp @@ -1,174 +1,178 @@ +#include "tadah/models/descriptors/d2/d2_base.h" #include <tadah/models/descriptors/d2/d2_eam.h> -D2_EAM::D2_EAM(Config &c): - verbose(c.get<int>("VERBOSE")) +D2_EAM::D2_EAM() { + init(); +} +D2_EAM::D2_EAM(Config &c): D2_Base(c) { - if (!c.get<bool>("INIT2B")) { - s=0; - return; + if (!c.get<bool>("INIT2B")) return; + init(); + s=1; + ef.file_path = c("SETFL")[0]; + read_setfl(); + + if (std::abs(ef.rcut - c.get<double>("RCUT2B")) > std::numeric_limits<double>::min()) { + if (verbose) { + std::cout << std::endl; + std::cout << "Config file cutoff and setfl file cutoff differ: " + << c.get<double>("RCUT2B") << " " << ef.rcut << std::endl; + std::cout << "Enforcing SETFL file cutoff: " << ef.rcut << std::endl; } - ef.file_path = c("SETFL")[0]; - read_setfl(); - - if (std::abs(ef.rcut - c.get<double>("RCUT2B")) > std::numeric_limits<double>::min()) { - if (verbose) { - std::cout << std::endl; - std::cout << "Config file cutoff and setfl file cutoff differ: " - << c.get<double>("RCUT2B") << " " << ef.rcut << std::endl; - std::cout << "Enforcing SETFL file cutoff: " << ef.rcut << std::endl; - } - c.remove("RCUT2B"); - c.add("RCUT2B", ef.rcut); - c.postprocess(); - } - - - frho_spline.resize(ef.nrho+1, std::vector<double>(7)); - rhor_spline.resize(ef.nr+1, std::vector<double>(7)); - z2r_spline.resize(ef.nr+1, std::vector<double>(7)); + c.remove("RCUT2B"); + c.add("RCUT2B", ef.rcut); + c.postprocess(); + } + frho_spline.resize(ef.nrho+1, std::vector<double>(7)); + rhor_spline.resize(ef.nr+1, std::vector<double>(7)); + z2r_spline.resize(ef.nr+1, std::vector<double>(7)); - gen_splines(ef.nrho, ef.drho, ef.frho, frho_spline); - gen_splines(ef.nr, ef.dr, ef.rhor, rhor_spline); - gen_splines(ef.nr, ef.dr, ef.z2r, z2r_spline); + gen_splines(ef.nrho, ef.drho, ef.frho, frho_spline); + gen_splines(ef.nr, ef.dr, ef.rhor, rhor_spline); + gen_splines(ef.nr, ef.dr, ef.z2r, z2r_spline); + auto init_atoms = get_init_atoms(c); + init_for_atoms(init_atoms); } void D2_EAM::calc_aed( - const double rij, - const double, - const double, - aed_type2 &aed) + const int Zi, + const int Zj, + const double rij, + const double, + aed_type &aed, + const double scale) { - - double r = rij; - const double recip = 1.0/r; - double p = r*ef.rdr + 1.0; - int m = static_cast<int> (p); - m = std::min(m,ef.nr-1); - p -= m; - p = std::min(p,1.0); - double z2 = ((z2r_spline[m][3]*p + z2r_spline[m][4])*p + z2r_spline[m][5])*p + z2r_spline[m][6]; - aed(fidx) += z2*recip; - + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double r = rij; + const double recip = 1.0/r; + double p = r*ef.rdr + 1.0; + int m = static_cast<int> (p); + m = std::min(m,ef.nr-1); + p -= m; + p = std::min(p,1.0); + double z2 = ((z2r_spline[m][3]*p + z2r_spline[m][4])*p + z2r_spline[m][5])*p + z2r_spline[m][6]; + aed(fidx) += scale*z2*recip; } void D2_EAM::calc_dXijdri( - const double rij, - const double, - const double, - const double, - fd_type &fd_ij) + const int Zi, + const int Zj, + const double rij, + const double, + fd_type &fd_ij, + const double scale) { - - const double r = rij; - const double recip = 1.0/r; - double p = r*ef.rdr + 1.0; - int m = static_cast<int> (p); - m = std::min(m,ef.nr-1); - p -= m; - p = std::min(p,1.0); - double z2p = (z2r_spline[m][0]*p + z2r_spline[m][1])*p + z2r_spline[m][2]; - double z2 = ((z2r_spline[m][3]*p + z2r_spline[m][4])*p + z2r_spline[m][5])*p + z2r_spline[m][6]; - //double phi = z2*recip; - //double phip = z2p*recip - z2*recip*recip; - - fd_ij(fidx,0) = (z2p*recip - z2*recip*recip); - //force_fp_ij[first_idx] = 0.5*(z2p*recip - z2*recip*recip); + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + const double r = rij; + const double recip = 1.0/r; + double p = r*ef.rdr + 1.0; + int m = static_cast<int> (p); + m = std::min(m,ef.nr-1); + p -= m; + p = std::min(p,1.0); + double z2p = (z2r_spline[m][0]*p + z2r_spline[m][1])*p + z2r_spline[m][2]; + double z2 = ((z2r_spline[m][3]*p + z2r_spline[m][4])*p + z2r_spline[m][5])*p + z2r_spline[m][6]; + //double phi = z2*recip; + //double phip = z2p*recip - z2*recip*recip; + + fd_ij(fidx,0) = scale*(z2p*recip - z2*recip*recip); + //force_fp_ij[first_idx] = 0.5*(z2p*recip - z2*recip*recip); } void D2_EAM::calc_all( - const double rij, - const double, - const double, - const double, - aed_type2 &aed, - fd_type &fd_ij) + const int Zi, + const int Zj, + const double rij, + const double, + aed_type &aed, + fd_type &fd_ij, + const double scale) { - double r = rij; - const double recip = 1.0/r; - double p = r*ef.rdr + 1.0; - int m = static_cast<int> (p); - m = std::min(m,ef.nr-1); - p -= m; - p = std::min(p,1.0); - double z2 = ((z2r_spline[m][3]*p + z2r_spline[m][4])*p + z2r_spline[m][5])*p + z2r_spline[m][6]; - aed(fidx) += z2*recip; - - double z2p = (z2r_spline[m][0]*p + z2r_spline[m][1])*p + z2r_spline[m][2]; - // 0.5 b/c full neighbour list is used TODO check - fd_ij(fidx,0) = (z2p*recip - z2*recip*recip); - - -} -size_t D2_EAM::size() { - return s; + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double r = rij; + const double recip = 1.0/r; + double p = r*ef.rdr + 1.0; + int m = static_cast<int> (p); + m = std::min(m,ef.nr-1); + p -= m; + p = std::min(p,1.0); + double z2 = ((z2r_spline[m][3]*p + z2r_spline[m][4])*p + z2r_spline[m][5])*p + z2r_spline[m][6]; + aed(fidx) += scale*z2*recip; + + double z2p = (z2r_spline[m][0]*p + z2r_spline[m][1])*p + z2r_spline[m][2]; + // 0.5 b/c full neighbour list is used TODO check + fd_ij(fidx,0) = scale*(z2p*recip - z2*recip*recip); } std::string D2_EAM::label() { - return lab; + return lab; } void D2_EAM::read_setfl() { - std::string line; - std::ifstream in_file(ef.file_path); - if (!in_file.good()) - throw std::runtime_error("SETFL file does not exists.\n"); - - if (in_file.is_open()) { - if (verbose) - std::cout << std::endl << "<D2_EAM> Reading setfl: " << ef.file_path << std::endl; - // skip ficgridt 3 comment lines - getline (in_file,line); - getline (in_file,line); - getline (in_file,line); - // skip number of types and types - getline (in_file,line); - // read 5th line - in_file >> ef.nrho >> ef.drho >> ef.nr >> ef.dr >> ef.rcut; - in_file >> ef.atomic_number >> ef.atomic_mass >> ef.lattice_param >> ef.lattice; - ef.rdr = 1.0/ef.dr; - ef.rdrho = 1.0/ef.drho; - // prepare arrays - ef.frho.resize(ef.nrho); - ef.rhor.resize(ef.nr); - ef.z2r.resize(ef.nr); - // read all data - for (int i=0; i<ef.nrho; ++i) in_file >> ef.frho[i]; - for (int i=0; i<ef.nr; ++i) in_file >> ef.rhor[i]; - for (int i=0; i<ef.nr; ++i) in_file >> ef.z2r[i]; - in_file.close(); - } - else { - if (verbose) std::cout << "<D2_EAM> Unable to open file: " << ef.file_path << std::endl;; - } + std::string line; + std::ifstream in_file(ef.file_path); + if (!in_file.good()) + throw std::runtime_error("SETFL file does not exists.\n"); + + if (in_file.is_open()) { + if (verbose) + std::cout << std::endl << "<D2_EAM> Reading setfl: " << ef.file_path << std::endl; + // skip ficgridt 3 comment lines + getline (in_file,line); + getline (in_file,line); + getline (in_file,line); + // skip number of types and types + getline (in_file,line); + // read 5th line + in_file >> ef.nrho >> ef.drho >> ef.nr >> ef.dr >> ef.rcut; + in_file >> ef.atomic_number >> ef.atomic_mass >> ef.lattice_param >> ef.lattice; + ef.rdr = 1.0/ef.dr; + ef.rdrho = 1.0/ef.drho; + // prepare arrays + ef.frho.resize(ef.nrho); + ef.rhor.resize(ef.nr); + ef.z2r.resize(ef.nr); + // read all data + for (int i=0; i<ef.nrho; ++i) in_file >> ef.frho[i]; + for (int i=0; i<ef.nr; ++i) in_file >> ef.rhor[i]; + for (int i=0; i<ef.nr; ++i) in_file >> ef.z2r[i]; + in_file.close(); + } + else { + if (verbose) std::cout << "<D2_EAM> Unable to open file: " << ef.file_path << std::endl;; + } } void D2_EAM::gen_splines(int &n, double &delta, std::vector<double> &f, - std::vector<std::vector<double>> &spline) + std::vector<std::vector<double>> &spline) { - // in lammps f is n+1, here is size n - for (int m=1; m<=n; m++) spline[m][6] = f[m-1]; - - spline[1][5] = spline[2][6] - spline[1][6]; - spline[2][5] = 0.5 * (spline[3][6]-spline[1][6]); - spline[n-1][5] = 0.5 * (spline[n][6]-spline[n-2][6]); - spline[n][5] = spline[n][6] - spline[n-1][6]; - - for (int m = 3; m <= n-2; m++) - spline[m][5] = ((spline[m-2][6]-spline[m+2][6]) + - 8.0*(spline[m+1][6]-spline[m-1][6])) / 12.0; - - for (int m = 1; m <= n-1; m++) { - spline[m][4] = 3.0*(spline[m+1][6]-spline[m][6]) - 2.0*spline[m][5] - spline[m+1][5]; - spline[m][3] = spline[m][5] + spline[m+1][5] - 2.0*(spline[m+1][6]-spline[m][6]); - } - - spline[n][4] = 0.0; - spline[n][3] = 0.0; - - for (int m = 1; m <= n; m++) { - spline[m][2] = spline[m][5]/delta; - spline[m][1] = 2.0*spline[m][4]/delta; - spline[m][0] = 3.0*spline[m][3]/delta; - } + // in lammps f is n+1, here is size n + for (int m=1; m<=n; m++) spline[m][6] = f[m-1]; + + spline[1][5] = spline[2][6] - spline[1][6]; + spline[2][5] = 0.5 * (spline[3][6]-spline[1][6]); + spline[n-1][5] = 0.5 * (spline[n][6]-spline[n-2][6]); + spline[n][5] = spline[n][6] - spline[n-1][6]; + + for (int m = 3; m <= n-2; m++) + spline[m][5] = ((spline[m-2][6]-spline[m+2][6]) + + 8.0*(spline[m+1][6]-spline[m-1][6])) / 12.0; + + for (int m = 1; m <= n-1; m++) { + spline[m][4] = 3.0*(spline[m+1][6]-spline[m][6]) - 2.0*spline[m][5] - spline[m+1][5]; + spline[m][3] = spline[m][5] + spline[m+1][5] - 2.0*(spline[m+1][6]-spline[m][6]); + } + + spline[n][4] = 0.0; + spline[n][3] = 0.0; + + for (int m = 1; m <= n; m++) { + spline[m][2] = spline[m][5]/delta; + spline[m][1] = 2.0*spline[m][4]/delta; + spline[m][0] = 3.0*spline[m][3]/delta; + } +} +void D2_EAM::init() { + nparams=1; } diff --git a/src/d2_lj.cpp b/src/d2_lj.cpp index b5ba992f05174bd2b10071aaa60381952b8b9539..3d4158322588b40d8d411a81a25ed85d4a1c380e 100644 --- a/src/d2_lj.cpp +++ b/src/d2_lj.cpp @@ -1,59 +1,77 @@ +#include "tadah/models/descriptors/d2/d2_base.h" #include <tadah/models/descriptors/d2/d2_lj.h> -D2_LJ::D2_LJ(Config &c): - verbose(c.get<int>("VERBOSE")) +D2_LJ::D2_LJ() { + init(); +} +D2_LJ::D2_LJ(Config &c): D2_Base(c) { - if (!c.get<bool>("INIT2B")) { - s=0; - } + if (!c.get<bool>("INIT2B")) return; + init(); + s=2; + + auto init_atoms = get_init_atoms(c); + init_for_atoms(init_atoms); } void D2_LJ::calc_aed( - const double, - const double rij_sq, - const double fc_ij, - aed_type2 &aed) + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + const double scale) { - double r2_inv = 1.0/rij_sq; - double r6_inv = r2_inv*r2_inv*r2_inv; + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double r2_inv = 1.0/rij_sq; + double r6_inv = r2_inv*r2_inv*r2_inv; + double fc_ij = fcut->calc(rij); - aed(fidx) -= r6_inv*fc_ij; - aed(fidx+1) += r6_inv*r6_inv*fc_ij; + aed(fidx) -= scale*weights[Zj]*(r6_inv*fc_ij); + aed(fidx+1) += scale*weights[Zj]*(r6_inv*r6_inv*fc_ij); } void D2_LJ::calc_dXijdri( - const double rij, - const double rij_sq, - const double fc_ij, - const double fcp_ij, - fd_type &fd_ij) + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + fd_type &fd_ij, + const double scale) { + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; - double r2_inv = 1.0/rij_sq; - double r6_inv = r2_inv*r2_inv*r2_inv; + double r2_inv = 1.0/rij_sq; + double r6_inv = r2_inv*r2_inv*r2_inv; - fd_ij(fidx,0) = 6.0*r6_inv*r2_inv*rij*fc_ij - fcp_ij*r6_inv; - fd_ij(fidx+1,0) = -12.0*r6_inv*r6_inv*r2_inv*rij*fc_ij + fcp_ij*r6_inv*r6_inv; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); + fd_ij(fidx,0) =scale*weights[Zj]*( 6.0*r6_inv*r2_inv*rij*fc_ij - fcp_ij*r6_inv); + fd_ij(fidx+1,0) =scale*weights[Zj]*( -12.0*r6_inv*r6_inv*r2_inv*rij*fc_ij + fcp_ij*r6_inv*r6_inv); } void D2_LJ::calc_all( - const double rij, - const double rij_sq, - const double fc_ij, - const double fcp_ij, - aed_type2 &aed, - fd_type &fd_ij) + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + aed_type &aed, + fd_type &fd_ij, + const double scale) { - double r2_inv = 1.0/rij_sq; - double r6_inv = r2_inv*r2_inv*r2_inv; + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double r2_inv = 1.0/rij_sq; + double r6_inv = r2_inv*r2_inv*r2_inv; - aed(fidx) -= r6_inv*fc_ij; - aed(fidx+1) += r6_inv*r6_inv*fc_ij; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); + aed(fidx) -= scale*weights[Zj]*r6_inv*fc_ij; + aed(fidx+1) += scale*weights[Zj]*r6_inv*r6_inv*fc_ij; - fd_ij(fidx,0) = 6.0*r6_inv*r2_inv*rij*fc_ij - fcp_ij*r6_inv; - fd_ij(fidx+1,0) = -12.0*r6_inv*r6_inv*r2_inv*rij*fc_ij + fcp_ij*r6_inv*r6_inv; -} -size_t D2_LJ::size() { - return s; + fd_ij(fidx,0) = scale*weights[Zj]*(6.0*r6_inv*r2_inv*rij*fc_ij - fcp_ij*r6_inv); + fd_ij(fidx+1,0) = scale*weights[Zj]*(-12.0*r6_inv*r6_inv*r2_inv*rij*fc_ij + fcp_ij*r6_inv*r6_inv); } std::string D2_LJ::label() { - return lab; + return lab; +} +void D2_LJ::init() { + nparams=0; } diff --git a/src/d2_mie.cpp b/src/d2_mie.cpp index 1813d477c9a920fda9e8c99bb2a6c5a21dfac6f5..450c2d9f7f5e14818c7498112969cd5ae0a63114 100644 --- a/src/d2_mie.cpp +++ b/src/d2_mie.cpp @@ -1,71 +1,81 @@ +#include "tadah/models/descriptors/d2/d2_base.h" #include <tadah/models/descriptors/d2/d2_mie.h> - -D2_MIE::D2_MIE(Config &c): - verbose(c.get<int>("VERBOSE")) +D2_MIE::D2_MIE() { + init(); +} +D2_MIE::D2_MIE(Config &c): D2_Base(c) { - if (!c.get<bool>("INIT2B")) { - s=0; - return; - } - get_grid(c,"SGRID2B",etas); - if (etas.size()!=2) { - throw std::runtime_error("Number of elements in SGRID2B is != 2\n\ - Mie descriptor requires SGRID2B with two positive elements.\n"); - } - n=etas[1]; - m=etas[0]; - if (n<0 || m<0) { - throw std::runtime_error("Both Mie exponents must by positive\n"); - } + if (!c.get<bool>("INIT2B")) return; + init(); + s=2; + n = c.get<double>("TYPE2B",1); + m = c.get<double>("TYPE2B",2); + if (n<0 || m<0) { + throw std::runtime_error("Both Mie exponents must by positive\n"); + } + auto init_atoms = get_init_atoms(c); + init_for_atoms(init_atoms); } void D2_MIE::calc_aed( - const double rij, - const double, - const double fc_ij, - aed_type2 &aed) + const int Zi, + const int Zj, + const double rij, + const double, + aed_type &aed, + const double scale) { - double rn_inv = 1.0/pow(rij,n); - double rm_inv = 1.0/pow(rij,m); + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double rn_inv = 1.0/pow(rij,n); + double rm_inv = 1.0/pow(rij,m); + double fc_ij = fcut->calc(rij); - aed(fidx) -= rn_inv*fc_ij; - aed(fidx+1) += rm_inv*fc_ij; + aed(fidx) -= scale*weights[Zj]*rn_inv*fc_ij; + aed(fidx+1) += scale*weights[Zj]*rm_inv*fc_ij; } void D2_MIE::calc_dXijdri( - const double rij, - const double, - const double fc_ij, - const double fcp_ij, - fd_type &fd_ij) + const int Zi, + const int Zj, + const double rij, + const double, + fd_type &fd_ij, + const double scale) { + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); - fd_ij(fidx,0) = n/pow(rij,n+1)*fc_ij - fcp_ij/pow(rij,n); - fd_ij(fidx+1,0) = -m/pow(rij,m+1)*fc_ij + fcp_ij/pow(rij,m); - + fd_ij(fidx,0) = scale*weights[Zj]*(n/pow(rij,n+1)*fc_ij - fcp_ij/pow(rij,n)); + fd_ij(fidx+1,0) = scale*weights[Zj]*(-m/pow(rij,m+1)*fc_ij + fcp_ij/pow(rij,m)); } void D2_MIE::calc_all( - const double rij, - const double, - const double fc_ij, - const double fcp_ij, - aed_type2 &aed, - fd_type &fd_ij) + const int Zi, + const int Zj, + const double rij, + const double, + aed_type &aed, + fd_type &fd_ij, + const double scale) { + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; - double rn_inv = 1.0/pow(rij,n); - double rm_inv = 1.0/pow(rij,m); + double rn_inv = 1.0/pow(rij,n); + double rm_inv = 1.0/pow(rij,m); - aed(fidx) -= rn_inv*fc_ij; - aed(fidx+1) += rm_inv*fc_ij; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); - fd_ij(fidx,0) = n*rn_inv/rij*fc_ij - fcp_ij*rn_inv; - fd_ij(fidx+1,0) = -m*rm_inv/rij*fc_ij + fcp_ij*rm_inv; + aed(fidx) -= scale*weights[Zj]*rn_inv*fc_ij; + aed(fidx+1) += scale*weights[Zj]*rm_inv*fc_ij; + + fd_ij(fidx,0) = scale*weights[Zj]*(n*rn_inv/rij*fc_ij - fcp_ij*rn_inv); + fd_ij(fidx+1,0) = scale*weights[Zj]*(-m*rm_inv/rij*fc_ij + fcp_ij*rm_inv); -} -size_t D2_MIE::size() { - return s; } std::string D2_MIE::label() { - return lab; + return lab; +} +void D2_MIE::init() { + nparams=2; } diff --git a/src/d2_mjoin.cpp b/src/d2_mjoin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7988ea337f62bd5441dced1771e225016a801e75 --- /dev/null +++ b/src/d2_mjoin.cpp @@ -0,0 +1,61 @@ +#include <cstddef> +#include <tadah/models/descriptors/d2/d2_mjoin.h> + +D2_mJoin::D2_mJoin() { + init(); +} +D2_mJoin::~D2_mJoin() { + for (auto d : ds) if (d) delete d; +} + +D2_mJoin::D2_mJoin(Config &c) : D2_Base(c) { + init(); + configs = parse_config(c, "TYPE2B"); + expand_grids(c, configs, "TYPE2B"); + + for (auto &c1 : configs) { + ds.push_back(CONFIG::factory<D2_Base, Config&>(c1.get<std::string>("TYPE2B"), c1)); + s += ds.back()->size(); + } +} + +void D2_mJoin::calc_aed(const int Zi, const int Zj, const double rij, + const double rij_sq, aed_type &aed, const double scale) { + for (auto d : ds) { + d->calc_aed(Zi, Zj, rij, rij_sq, aed, scale); + } +} + +void D2_mJoin::calc_dXijdri(const int Zi, const int Zj, const double rij, + const double rij_sq, fd_type &fd_ij, const double scale) { + for (auto d : ds) { + d->calc_dXijdri(Zi, Zj, rij, rij_sq, fd_ij, scale); + } +} + +void D2_mJoin::calc_all(const int Zi, const int Zj, const double rij, + const double rij_sq, aed_type &aed, fd_type &fd_ij, const double scale) { + for (auto d : ds) { + d->calc_all(Zi, Zj, rij, rij_sq, aed, fd_ij, scale); + } +} + +std::string D2_mJoin::label() { + return lab; +} + +void D2_mJoin::set_fidx(size_t fidx_) { + ds[0]->set_fidx(fidx_); + size_t s = 0; + for (size_t i = 1; i < ds.size(); ++i) { + s += ds[i - 1]->size(); + ds[i]->set_fidx(fidx_ + s); + } +} + +void D2_mJoin::init() { + keys.push_back("TYPE2B"); + keys.push_back("RCTYPE2B"); + keys.push_back("RCUT2B"); + nparams=std::numeric_limits<size_t>::max(); +} diff --git a/src/d2_zbl.cpp b/src/d2_zbl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90542c77445c885ee858139fe391348f1fe3ddd8 --- /dev/null +++ b/src/d2_zbl.cpp @@ -0,0 +1,133 @@ +#include <tadah/models/descriptors/d2/d2_zbl.h> + +D2_ZBL::D2_ZBL() { + init(); +} +D2_ZBL::D2_ZBL(Config &c): D2_Base(c) +{ + if (!c.get<bool>("INIT2B")) return; + init(); + s=1; + double temp; + temp = c.get<double>("TYPE2B",1); + if (temp!=-1) a0=temp; + temp = c.get<double>("TYPE2B",2); + if (temp!=-1) s0=temp; + temp = c.get<double>("TYPE2B",3); + if (temp!=-1) p0=temp; + temp = c.get<double>("TYPE2B",4); + if (temp!=-1) p1=temp; + + if (verbose) + std::cout << label() << ": " << a0 << " " + << s0 << " " << p0 << " " << p1 << std::endl; + + ntypes = c.size("ATOMS"); + a = new double*[ntypes]; + for (int i = 0; i < ntypes; ++i) { + a[i] = new double[ntypes]; + } + for (int i=0; i<ntypes; ++i) { + std::string symboli = c.get<std::string>("ATOMS",i); + int Zi = PeriodicTable::find_by_symbol(symboli).Z; + types[Zi] = i; + for (int j=0; j<ntypes; ++j) { + std::string symbolj = c.get<std::string>("ATOMS",j); + int Zj = PeriodicTable::find_by_symbol(symbolj).Z; + a[i][j] = screening_length(Zi,Zj); + } + } + auto init_atoms = get_init_atoms(c); + init_for_atoms(init_atoms); +} +D2_ZBL::~D2_ZBL() { + if (a) { + for (int i = 0; i < ntypes; ++i) { + delete[] a[i]; + } + delete[] a; + a = nullptr; + } +} + +void D2_ZBL::calc_aed( + const int Zi, + const int Zj, + const double rij, + const double, + aed_type &aed, + const double scale) +{ + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double fc_ij = fcut->calc(rij); + double a_ = a[types[Zi]][types[Zj]]; + double x = rij / a_; + double p = phi(x); + aed(fidx) += scale*weights[Zj]*(Zi * Zj / rij) * p * fc_ij; +} +void D2_ZBL::calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double, + fd_type &fd_ij, + const double scale) +{ + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double r_inv = 1.0/rij; + double a_ = a[types[Zi]][types[Zj]]; + double x = rij / a_; + double p = phi(x); + double dp = dphi(x); + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); + + double E_ZBL = (Zi * Zj * r_inv) * p; + double dE_ZBL_r = -(Zi * Zj * r_inv*r_inv)*p + dp*(Zi * Zj * r_inv) / a_ ; + fd_ij(fidx,0) = scale*weights[Zj]*(E_ZBL*fcp_ij + dE_ZBL_r*fc_ij); +} +void D2_ZBL::calc_all( + const int Zi, + const int Zj, + const double rij, + const double, + aed_type &aed, + fd_type &fd_ij, + const double scale) +{ + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double r_inv = 1.0/rij; + double a_ = a[types[Zi]][types[Zj]]; + double x = rij / a_; + double p = phi(x); + double dp = dphi(x); + + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); + + aed(fidx) += scale*weights[Zj]*(Zi * Zj * r_inv) * p * fc_ij; + double E_ZBL = (Zi * Zj * r_inv) * p; + double dE_ZBL_r = -(Zi * Zj * r_inv*r_inv)*p + dp*(Zi * Zj * r_inv) / a_ ; + fd_ij(fidx,0) = scale*weights[Zj]*(E_ZBL*fcp_ij + dE_ZBL_r*fc_ij); +} +std::string D2_ZBL::label() { + return lab; +} +void D2_ZBL::init() { + nparams=4; +} +double D2_ZBL::phi(double x) { + return 0.1818 * std::exp(-3.2 * x) + + 0.5099 * std::exp(-0.9423 * x) + + 0.2802 * std::exp(-0.4029 * x) + + 0.02817 * std::exp(-0.2016 * x); +} +double D2_ZBL::dphi(double x) { + return -3.2 * 0.1818 * std::exp(-3.2 * x) - + 0.9423 * 0.5099 * std::exp(-0.9423 * x) - + 0.4029 * 0.2802 * std::exp(-0.4029 * x) - + 0.2016 * 0.02817 * std::exp(-0.2016 * x); +} +double D2_ZBL::screening_length(int Zi, int Zj) { + return (s0 * a0) / (std::pow(Zi, p0) + std::pow(Zj, p1)); +} diff --git a/src/d3_all.cpp b/src/d3_all.cpp index e87c091bb7445a89188cac9604ab20734565a02a..ef0e046d12eb576d18e5192a9e6b89f1efc3d1d2 100644 --- a/src/d3_all.cpp +++ b/src/d3_all.cpp @@ -1,6 +1,8 @@ #include <tadah/models/descriptors/d3/d3_base.h> #include <tadah/models/descriptors/d3/d3_dummy.h> +template<> CONFIG::Registry<D3_Base>::Map CONFIG::Registry<D3_Base>::registry{}; template<> CONFIG::Registry<D3_Base,Config&>::Map CONFIG::Registry<D3_Base,Config&>::registry{}; +CONFIG::Registry<D3_Base>::Register<D3_Dummy> D3_Dummy_0( "D3_Dummy" ); CONFIG::Registry<D3_Base,Config&>::Register<D3_Dummy> D3_Dummy_1( "D3_Dummy" ); diff --git a/src/d3_base.cpp b/src/d3_base.cpp index bf59bc896569e2267f1bc1deb8cde5d32d56e769..fe5fa6932ef38b78dac3fd4d1bdf9f5f990629df 100644 --- a/src/d3_base.cpp +++ b/src/d3_base.cpp @@ -1,3 +1,6 @@ #include <tadah/models/descriptors/d3/d3_base.h> //template struct Registry<D3_Base, Config &>; +std::vector<std::string> D3_Base::get_init_atoms(Config &c) { + return {}; +} diff --git a/src/d3_dummy.cpp b/src/d3_dummy.cpp index 049d6a321880ffa736aad9e7d0d9f6002cfd8b9b..e8354d96866879e77c3269a6306c1b7da4e1b728 100644 --- a/src/d3_dummy.cpp +++ b/src/d3_dummy.cpp @@ -1,7 +1,11 @@ #include <tadah/models/descriptors/d3/d3_dummy.h> -D3_Dummy::D3_Dummy() {} -D3_Dummy::D3_Dummy(Config &) {} +D3_Dummy::D3_Dummy() { + init(); +} +D3_Dummy::D3_Dummy(Config &) { + init(); +} void D3_Dummy::calc_aed( const size_t, @@ -9,7 +13,7 @@ void D3_Dummy::calc_aed( const double, const double, const double, - aed_type2& ) {} + aed_type& ) {} void D3_Dummy::calc_fd( const size_t, const double, @@ -27,7 +31,10 @@ void D3_Dummy::calc_all( const double, const double, const double, - aed_type2& , + aed_type& , fd_type &) {} size_t D3_Dummy::size() { return s;} std::string D3_Dummy::label() {return lab;} +void D3_Dummy::init() { + nparams=0; +} diff --git a/src/d_base.cpp b/src/d_base.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bb1e15831abb9bd00a59a8d82dc4dbbc7197c1ce --- /dev/null +++ b/src/d_base.cpp @@ -0,0 +1,154 @@ +#include "tadah/core/core_types.h" +#include "tadah/core/utils.h" +#include <string> +#include <tadah/models/descriptors/d_base.h> +#include <vector> +void D_Base::get_grid(const Config &c, std::string key, v_type &v) { + if (c.get<double>(key) < 0) { + // generate grid automatically if first element + // is<zero and int. If it is double than assume that + // grid is provided manually and min value is just smaller + // than zero. + double int_part; + if (std::modf ( c.get<double>(key), &int_part ) == 0.0) { + // automatic generation + size_t cg = abs(c.get<int>(key,1)); + double cgmin = c.get<double>(key,2); + double cgmax = c.get<double>(key,3); + if (c.get<int>(key) == -1) { + v = linspace(cgmin, cgmax, cg); + } + else if (c.get<int>(key) == -2) { + v = logspace(cgmin, cgmax, cg, exp(1)); + } + else { + throw std::runtime_error(key+" algorithm not supported\n"); + } + } + else { + v.resize(c.size(key)); + c.get<v_type>(key,v); + } + } + else { + v.resize(c.size(key)); + c.get<v_type>(key,v); + } +} +v_type D_Base::get_grid(std::vector<std::string>&vold) { + v_type vnew; + auto it = vold.begin(); + while (it != vold.end()) { + std::string token = *it++; + if (token == "-1") { + size_t cg = std::stoul(*it++); + double cgmin = std::stod(*it++); + double cgmax = std::stod(*it++); + v_type v = linspace(cgmin, cgmax, cg); + vnew.insert(vnew.end(), v.begin(), v.end()); + } + else if (token == "-2") { + size_t cg = std::stoul(*it++); + double cgmin = std::stod(*it++); + double cgmax = std::stod(*it++); + v_type v = logspace(cgmin, cgmax, cg, exp(1)); + vnew.insert(vnew.end(), v.begin(), v.end()); + } + else if (std::stod(token) < -2) { + throw std::runtime_error("Either algorithm is not supported or negative value was encountered in a grid: " + token); + } + else { + vnew.push_back(std::stod(token)); + } + } + return vnew; +} +D_Base::~D_Base() { + if (this->manage_memory && fcut) { + delete fcut; + } +} + +D_Base::D_Base() {} +D_Base::D_Base(Config &c): + verbose(c.get<int>("VERBOSE")) +{ + std::fill_n(weights, 119, 1.0); + if (c.exist("ATOMS")) { + for (size_t i=0; i<c.size("ATOMS"); ++i) { + std::string symbol = c.get<std::string>("ATOMS",i); + double wi = c.get<double>("WATOMS",i); + int Z = PeriodicTable::find_by_symbol(symbol).Z; + weights[Z]=wi; + } + } +} +void D_Base::set_fidx(size_t fidx_) { fidx=fidx_; } +size_t D_Base::get_fidx() { return fidx; } +void D_Base::set_fcut(Cut_Base* cut, bool manage_memory) { + if (this->manage_memory && fcut != cut) { + delete fcut; + } + fcut = cut; + this->manage_memory = manage_memory; +} +int D_Base::get_arg_pos(const std::string &key) const { + auto it = std::find(keys.begin(), keys.end(), key); + + if (it == keys.end()) return -1; + + return std::distance(keys.begin(), it)+(nparams-keys.size()); +} +size_t D_Base::size() { return s; }; +double D_Base::get_rcut() { + return fcut->get_rcut(); +} +bool D_Base::is_init_for_atoms(int Zi, int Zj) { + return init_for_atoms_map.is_init(Zi,Zj) ; +} +void D_Base::init_for_atoms(int Zi, int Zj) { + init_for_atoms_map.init(Zi,Zj); +} +void D_Base::uninit_for_atoms(int Zi, int Zj) { + init_for_atoms_map.uninit(Zi,Zj); +} +void D_Base::init_for_atoms(const std::vector<std::string> &Zs) { + if (Zs.size() % 2 != 0) { + throw std::invalid_argument("The vector size must be even."); + } + + for (size_t i = 0; i < Zs.size(); i += 2) { + if (Zs[i] == "*" && Zs[i+1] != "*") { + int Zj = PeriodicTable::find_by_symbol(Zs[i+1]).Z; + for (int Zi = 1; Zi < 119; ++Zi) { + init_for_atoms(Zi, Zj); + } + } + else if (Zs[i] != "*" && Zs[i+1] == "*") { + int Zi = PeriodicTable::find_by_symbol(Zs[i]).Z; + for (int Zj = 1; Zj < 119; ++Zj) { + init_for_atoms(Zi, Zj); + } + } + else if (Zs[i] == "*" && Zs[i+1] == "*") { + for (int Zi = 1; Zi < 119; ++Zi) { + for (int Zj = Zi; Zj < 119; ++Zj) { + init_for_atoms(Zi, Zj); + } + } + } + else { + int Zi = PeriodicTable::find_by_symbol(Zs[i]).Z; + int Zj = PeriodicTable::find_by_symbol(Zs[i+1]).Z; + init_for_atoms(Zi, Zj); + } + } +} +std::vector<std::string> D_Base::get_init_atoms(Config &c, std::string type) { + std::vector<std::string> init_atoms(c.size(type)); + c.get(type, init_atoms); + std::unique_ptr<D_Base> d(CONFIG::factory<D_Base>(init_atoms[0])); + size_t nparams = d->nparams; + init_atoms.erase(init_atoms.begin(), init_atoms.begin() + nparams); + return init_atoms; +} diff --git a/src/d_mjoin.cpp b/src/d_mjoin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c1e3682847470463bac4b166858ce768017ac11 --- /dev/null +++ b/src/d_mjoin.cpp @@ -0,0 +1,188 @@ +#include "tadah/core/registry.h" +#include <cstddef> +#include <iostream> +#include <string> +#include <tadah/models/descriptors/d_mjoin.h> +#include <tadah/models/descriptors/d_base.h> +#include <vector> + +D_mJoin::D_mJoin() {} +D_mJoin::~D_mJoin() {} + +std::vector<std::string> convert_to_strings(const v_type& vec, int precision) { + std::vector<std::string> result; + std::ostringstream oss; + oss << std::fixed << std::setprecision(precision); + + for (double num : vec) { + oss.str(""); // Clear the stream + oss << num; + result.push_back(oss.str()); + } + + return result; +} + +void D_mJoin::expand_grids(Config &c) { + if (c.exist("TYPE2B")) { + std::vector<Config> configs1 = parse_config(c, "TYPE2B"); + expand_grids(c,configs1,"TYPE2B"); + } + if (c.exist("TYPEMB")) { + std::vector<Config> configs2 = parse_config(c, "TYPEMB"); + expand_grids(c,configs2,"TYPEMB"); + } +} +void D_mJoin::expand_grids(Config &c, std::string type_str) { + std::vector<Config> configs = parse_config(c, type_str); + expand_grids(c,configs,type_str); +} +void D_mJoin::expand_grids(Config &c, std::vector<Config> &configs,std::string type_str) { + if (type_str=="TYPE2B") { + c.remove("CGRID2B"); c.remove("SGRID2B"); + for (auto &c1 : configs) { + if (c1.exist("CGRID2B")) + for (size_t i = 0; i < c1.size("CGRID2B"); ++i) + c.add("CGRID2B", c1.get<double>("CGRID2B", i)); + if (c1.exist("SGRID2B")) + for (size_t i = 0; i < c1.size("SGRID2B"); ++i) + c.add("SGRID2B", c1.get<double>("SGRID2B", i)); + } + } + else if (type_str=="TYPEMB") { + c.remove("CGRIDMB"); c.remove("SGRIDMB"); + c.remove("CEMBFUNC"); c.remove("SEMBFUNC"); + + for (auto &c1 : configs) { + if (c1.exist("CGRIDMB")) + for (size_t i = 0; i < c1.size("CGRIDMB"); ++i) + c.add("CGRIDMB", c1.get<double>("CGRIDMB", i)); + if (c1.exist("SGRIDMB")) + for (size_t i = 0; i < c1.size("SGRIDMB"); ++i) + c.add("SGRIDMB", c1.get<double>("SGRIDMB", i)); + if (c1.exist("CEMBFUNC")) + for (size_t i = 0; i < c1.size("CEMBFUNC"); ++i) + c.add("CEMBFUNC", c1.get<double>("CEMBFUNC", i)); + if (c1.exist("SEMBFUNC")) + for (size_t i = 0; i < c1.size("SEMBFUNC"); ++i) + c.add("SEMBFUNC", c1.get<double>("SEMBFUNC", i)); + } + } + else { + std::cerr << "Cannot expand config grid: wrong keyword: " << type_str << std::endl; + } +} +std::vector<Config> D_mJoin::parse_config(Config &c, std::string type_str) { + std::string prefix = type_str=="TYPE2B" ? "D2_" : "DM_"; + std::string rctypekey = "RC" + type_str; + std::string rcutkey = "RCUT" + type_str.substr(type_str.size() - 2); + std::string cgridkey = "CGRID" + type_str.substr(type_str.size() - 2); + std::string sgridkey = "SGRID" + type_str.substr(type_str.size() - 2); + + std::map<std::string, std::vector<std::string>::iterator> data_map; + + std::vector<std::string> types(c.size(type_str)); // including params TYPE2B D2_Blip 7 7 + c.get(type_str, types); + //types.erase(types.begin()); // remove D2_mJoin or DM_mJoin + std::string pattern="mJoin"; + types.erase( + std::remove_if(types.begin(), types.end(), [&pattern](const std::string& s) { + return s.find(pattern) != std::string::npos; + }), + types.end() + ); + + std::vector<std::string> rctypes(c.size(rctypekey)); + c.get(rctypekey, rctypes); + data_map[rctypekey]=rctypes.begin(); + + std::vector<std::string> rcut(c.size(rcutkey)); + c.get(rcutkey, rcut); + data_map[rcutkey]=rcut.begin(); + + size_t p = c.get<size_t>("OUTPREC"); + std::vector<std::string> cgrid; + if (c.exist(cgridkey)) { + cgrid.resize(c.size(cgridkey)); + c.get(cgridkey, cgrid); + cgrid = convert_to_strings(D_Base::get_grid(cgrid),p); + data_map[cgridkey] = cgrid.begin(); + } + std::vector<std::string> sgrid; + if (c.exist(sgridkey)) { + sgrid.resize(c.size(sgridkey)); + c.get(sgridkey, sgrid); + sgrid = convert_to_strings(D_Base::get_grid(sgrid),p); + data_map[sgridkey] = sgrid.begin(); + } + std::vector<std::string> cembgrid; + if (c.exist("CEMBFUNC")) { + cembgrid.resize(c.size("CEMBFUNC")); + c.get("CEMBFUNC", cembgrid); + cembgrid = convert_to_strings(D_Base::get_grid(cembgrid),p); + data_map["CEMBFUNC"] = cembgrid.begin(); + } + std::vector<std::string> sembgrid; + if (c.exist("SEMBFUNC")) { + sembgrid.resize(c.size("SEMBFUNC")); + c.get("SEMBFUNC", sembgrid); + sembgrid = convert_to_strings(D_Base::get_grid(sembgrid),p); + data_map["SEMBFUNC"] = sembgrid.begin(); + } + + std::vector<Config> configs; + for (auto it = types.begin(); it != types.end();) { + Config c1 = c; + c1.remove(type_str); c1.remove(rctypekey); c1.remove(rcutkey); + c1.remove(cgridkey); c1.remove(sgridkey); + const auto token = *it++; + c1.add(type_str,token); + c1.add(rctypekey,*(data_map[rctypekey]++)); + c1.add(rcutkey,*(data_map[rcutkey]++)); + D_Base *d = CONFIG::factory<D_Base>(token); + size_t fparam = d->nparams - d->keys.size(); + for (size_t j=0; j<fparam; ++j) { + c1.add(type_str,*it++); + } + + for (const auto& k : d->keys) { + int n = std::stoi(*it++); + c1.add(type_str,n); + for (int j = 0; j < n; ++j) { + c1.add(k,*(data_map[k]++)); + } + } + + // read init atoms + size_t found_init_atoms=0; + while (it != types.end()) { + if (it->find(prefix) == 0) { + break; + } + c1.add(type_str,*it++); + found_init_atoms++; + } + // if (it != types.end() && it != types.begin()) { + // --it; + // } + if (!found_init_atoms) { + throw std::runtime_error( + "Error: No element types specified. " + "Please provide element types for this calculator. " + "For example: '"+token+" Ti Ti Ti Nb' sets the calculator to compute Ti-Ti and Ti-Nb interactions. " + "Token: " + token); + } + + if (found_init_atoms % 2 != 0) { + throw std::runtime_error( + "Error: Element types must be provided in pairs. " + "Ensure each element is paired correctly. " + "For instance, '" + token + " Ti * Nb Zr' means that interactions of Ti with any atom, as well as Nb-Zr, will be computed. " + "Token: " + token); + } + + configs.push_back(c1); + delete d; + } + return configs; +} diff --git a/src/dm_all.cpp b/src/dm_all.cpp index 6f0b293fd48a496043b66f826e13829b550c03a8..326872c40105c839cda67802dc309b7f8ef84455 100644 --- a/src/dm_all.cpp +++ b/src/dm_all.cpp @@ -1,11 +1,27 @@ #include <tadah/models/descriptors/dm/dm_all.h> +template<> CONFIG::Registry<DM_Base>::Map CONFIG::Registry<DM_Base>::registry{}; template<> CONFIG::Registry<DM_Base,Config&>::Map CONFIG::Registry<DM_Base,Config&>::registry{}; -CONFIG::Registry<DM_Base,Config&>::Register<DM_Blip> DM_Blip_1( "DM_Blip" ); -CONFIG::Registry<DM_Base,Config&>::Register<DM_Dummy> DM_Dummy_1( "DM_Dummy" ); -CONFIG::Registry<DM_Base,Config&>::Register<DM_EAD> DM_EAD_1( "DM_EAD" ); -CONFIG::Registry<DM_Base,Config&>::Register<DM_EAM> DM_EAM_1( "DM_EAM" ); -CONFIG::Registry<DM_Base,Config&>::Register<DM_mEAD<F_RLR>> DM_mEAM_1("DM_mEAD"); +CONFIG::Registry<D_Base>::Register<DM_Blip> DM_Blip_0( "DM_Blip" ); +CONFIG::Registry<D_Base>::Register<DM_Dummy> DM_Dummy_0( "DM_Dummy" ); +CONFIG::Registry<D_Base>::Register<DM_EAD> DM_EAD_0( "DM_EAD" ); +CONFIG::Registry<D_Base>::Register<DM_EAM> DM_EAM_0( "DM_EAM" ); +CONFIG::Registry<D_Base>::Register<DM_mEAD<F_RLR>> DM_mEAM_0("DM_mEAD"); +CONFIG::Registry<D_Base>::Register<DM_mJoin> DM_mJoin_0("DM_mJoin"); + +CONFIG::Registry<DM_Base>::Register<DM_Blip> DM_Blip_1( "DM_Blip" ); +CONFIG::Registry<DM_Base>::Register<DM_Dummy> DM_Dummy_1( "DM_Dummy" ); +CONFIG::Registry<DM_Base>::Register<DM_EAD> DM_EAD_1( "DM_EAD" ); +CONFIG::Registry<DM_Base>::Register<DM_EAM> DM_EAM_1( "DM_EAM" ); +CONFIG::Registry<DM_Base>::Register<DM_mEAD<F_RLR>> DM_mEAM_1("DM_mEAD"); +CONFIG::Registry<DM_Base>::Register<DM_mJoin> DM_mJoin_1("DM_mJoin"); + +CONFIG::Registry<DM_Base,Config&>::Register<DM_Blip> DM_Blip_2( "DM_Blip" ); +CONFIG::Registry<DM_Base,Config&>::Register<DM_Dummy> DM_Dummy_2( "DM_Dummy" ); +CONFIG::Registry<DM_Base,Config&>::Register<DM_EAD> DM_EAD_2( "DM_EAD" ); +CONFIG::Registry<DM_Base,Config&>::Register<DM_EAM> DM_EAM_2( "DM_EAM" ); +CONFIG::Registry<DM_Base,Config&>::Register<DM_mEAD<F_RLR>> DM_mEAM_2("DM_mEAD"); +CONFIG::Registry<DM_Base,Config&>::Register<DM_mJoin> DM_mJoin_2( "DM_mJoin" ); //template<> Registry<DM_Base,F_Base&,Config&>::Map Registry<DM_Base,F_Base&,Config&>::registry{}; //Registry<DM_Base,Config&>::Register<DM_mEAD<F_RLR>> DM_mEAD_1( "DM_mEAD" ); diff --git a/src/dm_base.cpp b/src/dm_base.cpp index a76605da06946d74afac69f10e502df2037d6e3d..7b9f557c26bfb2f37fe564f464cfb29f981f318e 100644 --- a/src/dm_base.cpp +++ b/src/dm_base.cpp @@ -1 +1,15 @@ #include <tadah/models/descriptors/dm/dm_base.h> +void DM_Base::set_rfidx(size_t rfidx_) { rfidx=rfidx_; } +size_t DM_Base::get_rfidx() { return rfidx; } + +std::vector<std::string> DM_Base::get_init_atoms(Config &c) { + if (!c.exist("TYPEMB")) { + std::cerr << "Warning: TYPEMB key was not found. " + "Atom pairs must be initialized manually." << std::endl; + return {}; + } + std::vector<std::string> init_atoms(c.size("TYPEMB")); + c.get("TYPEMB", init_atoms); + init_atoms.erase(init_atoms.begin(), init_atoms.begin() + nparams + 1); + return init_atoms; +} diff --git a/src/dm_blip.cpp b/src/dm_blip.cpp index 85708251949e30ea48e9e05e7f1a2abbc7b48016..48408d27b4d4d1cd18eaaa0d2451773f165d97f0 100644 --- a/src/dm_blip.cpp +++ b/src/dm_blip.cpp @@ -1,298 +1,312 @@ +#include "tadah/models/descriptors/dm/dm_base.h" #include <tadah/models/descriptors/dm/dm_blip.h> #include <tadah/models/descriptors/d_basis_functions.h> #include <vector> -#include <iomanip> - -DM_Blip::DM_Blip(Config &c): - verbose(c.get<int>("VERBOSE")), - rc(c.get<double>("RCUTMB")) +DM_Blip::DM_Blip() { + init(); +} +DM_Blip::DM_Blip(Config &c): DM_Base(c), + rc(c.get<double>("RCUTMBMAX")) { - - if (!c.get<bool>("INITMB")) return; - - get_grid(c,"CGRIDMB",cgrid); - get_grid(c,"SGRIDMB",sgrid); - if (cgrid.size()!=sgrid.size()) { - - throw std::runtime_error("SGRID2B and CGRID2B arrays differ in size.\n"); - } - - Lmax = c.get<int>("AGRIDMB"); - s=sgrid.size()*(Lmax+1); - rhoisize = gen_atomic_orbitals(Lmax); - rhoisize *= sgrid.size(); - - if (verbose) { - std::cout << std::endl; - std::cout << "SGRID (SGRIDMB): " << sgrid.size() << std::endl; - for (auto e:sgrid) std::cout << e << " "; - std::cout << std::endl; - - std::cout << "CGRID (CGRIDMB): " << cgrid.size() << std::endl; - for (auto L:cgrid) std::cout << L << " "; - std::cout << std::endl; - std::cout << "rhoisize: " << rhoisize << std::endl; - } + if (!c.get<bool>("INITMB")) return; + init(); + + get_grid(c,"CGRIDMB",cgrid); + get_grid(c,"SGRIDMB",sgrid); + // update config with generated grid + c.remove("CGRIDMB"); + for (const auto &i: cgrid) c.add("CGRIDMB",i); + c.remove("SGRIDMB"); + for (const auto &i: sgrid) c.add("SGRIDMB",i); + if (cgrid.size()!=sgrid.size()) { + + throw std::runtime_error("SGRID2B and CGRID2B arrays differ in size.\n"); + } + + Lmax = c.get<int>("TYPEMB",1); + s=sgrid.size()*(Lmax+1); + rhoisize = gen_atomic_orbitals(Lmax); + rhoisize *= sgrid.size(); + + if (verbose) { + std::cout << std::endl; + std::cout << "SGRID (SGRIDMB): " << sgrid.size() << std::endl; + for (auto e:sgrid) std::cout << e << " "; + std::cout << std::endl; + + std::cout << "CGRID (CGRIDMB): " << cgrid.size() << std::endl; + for (auto L:cgrid) std::cout << L << " "; + std::cout << std::endl; + std::cout << "rhoisize: " << rhoisize << std::endl; + } + auto init_atoms = get_init_atoms(c); + init_for_atoms(init_atoms); } void DM_Blip::calc_aed( - rho_type& rhoi, - aed_type2 &aed) + rho_type& rhoi, + aed_type &aed) { - size_t Lshift = 0; - size_t ii=0; - for (int L=0; L<=Lmax; ++L) { - for (size_t o=0; o<orbitals[L].size(); ++o) { - const double f = fac[L][o]; - for (size_t c=0; c<cgrid.size(); c++) { - aed(c+Lshift+fidx) += f*rhoi(ii)*rhoi(ii); - rhoi(ii+rhoisize) = 2.0*f*rhoi(ii); - ii++; - } - } - Lshift += sgrid.size(); + size_t Lshift = 0; + size_t ii=rfidx; + for (int L=0; L<=Lmax; ++L) { + for (size_t o=0; o<orbitals[L].size(); ++o) { + const double f = fac[L][o]; + for (size_t c=0; c<cgrid.size(); c++) { + aed(c+Lshift+fidx) += f*rhoi(ii)*rhoi(ii); + rhoi(ii+rhoisize) = 2.0*f*rhoi(ii); + ii++; + } } + Lshift += sgrid.size(); + } } -int DM_Blip::calc_dXijdri_dXjidri( - const double rij, - const double, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - rho_type& rhoj, - fd_type &fd_ij, - const double wi, - const double wj) +void DM_Blip::calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale) { - const double x = vec_ij[0]; - const double y = vec_ij[1]; - const double z = vec_ij[2]; - - size_t Lshift = 0; - - size_t ii=rhoisize; - for (int L=0; L<=Lmax; ++L) { - for (size_t o=0; o<orbitals[L].size(); ++o) { - const int lx = orbitals[L][o][0]; - const int ly = orbitals[L][o][1]; - const int lz = orbitals[L][o][2]; - - const double powxlxij = my_pow(x,lx); - const double powylyij = my_pow(y,ly); - const double powzlzij = my_pow(z,lz); - - const double powxlxji = my_pow(-x,lx); - const double powylyji = my_pow(-y,ly); - const double powzlzji = my_pow(-z,lz); - - double txij=0.0,tyij=0.0,tzij=0.0; - double txji=0.0,tyji=0.0,tzji=0.0; - if (lx!=0) { - txij = lx*my_pow(x,lx-1)*powylyij*powzlzij; - txji = lx*my_pow(-x,lx-1)*powylyji*powzlzji; - } - if (ly!=0) { - tyij = ly*my_pow(y,ly-1)*powxlxij*powzlzij; - tyji = ly*my_pow(-y,ly-1)*powxlxji*powzlzji; - } - if (lz!=0) { - tzij = lz*my_pow(z,lz-1)*powylyij*powxlxij; - tzji = lz*my_pow(-z,lz-1)*powylyji*powxlxji; - } - const double pqrij = powxlxij*powylyij*powzlzij; - const double pqrji = powxlxji*powylyji*powzlzji; - - for (size_t c=0; c<cgrid.size(); c++) { - double blip = B(sgrid[c]*(rij-cgrid[c]),fc_ij); - double dblip = dB(sgrid[c]*(rij-cgrid[c]),sgrid[c],fc_ij,fcp_ij); - const double term2ijx=pqrij*dblip*x/rij; - const double term2ijy=pqrij*dblip*y/rij; - const double term2ijz=pqrij*dblip*z/rij; - - const double term2jix=-pqrji*dblip*x/rij; - const double term2jiy=-pqrji*dblip*y/rij; - const double term2jiz=-pqrji*dblip*z/rij; - - const double term1ijx = blip*txij; - const double term1ijy = blip*tyij; - const double term1ijz = blip*tzij; - - const double term1jix = blip*txji; - const double term1jiy = blip*tyji; - const double term1jiz = blip*tzji; - - fd_ij(c+Lshift+fidx,0) += - rhoi(ii)*(term1ijx + term2ijx)*wj - -rhoj(ii)*(term1jix + term2jix)*wi - ; - - fd_ij(c+Lshift+fidx,1) += - rhoi(ii)*(term1ijy + term2ijy)*wj - -rhoj(ii)*(term1jiy + term2jiy)*wi - ; - - fd_ij(c+Lshift+fidx,2) += - rhoi(ii)*(term1ijz + term2ijz)*wj - -rhoj(ii)*(term1jiz + term2jiz)*wi - ; - ii++; - } - } - Lshift+=sgrid.size(); + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + + const double x = vec_ij[0]; + const double y = vec_ij[1]; + const double z = vec_ij[2]; + + double wi = weights[Zi]; + double wj = weights[Zj]; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); + + size_t Lshift = 0; + + size_t ii=rhoisize+rfidx; + for (int L=0; L<=Lmax; ++L) { + for (size_t o=0; o<orbitals[L].size(); ++o) { + const int lx = orbitals[L][o][0]; + const int ly = orbitals[L][o][1]; + const int lz = orbitals[L][o][2]; + + const double powxlxij = my_pow(x,lx); + const double powylyij = my_pow(y,ly); + const double powzlzij = my_pow(z,lz); + + const double powxlxji = my_pow(-x,lx); + const double powylyji = my_pow(-y,ly); + const double powzlzji = my_pow(-z,lz); + + double txij=0.0,tyij=0.0,tzij=0.0; + double txji=0.0,tyji=0.0,tzji=0.0; + if (lx!=0) { + txij = lx*my_pow(x,lx-1)*powylyij*powzlzij; + txji = lx*my_pow(-x,lx-1)*powylyji*powzlzji; + } + if (ly!=0) { + tyij = ly*my_pow(y,ly-1)*powxlxij*powzlzij; + tyji = ly*my_pow(-y,ly-1)*powxlxji*powzlzji; + } + if (lz!=0) { + tzij = lz*my_pow(z,lz-1)*powylyij*powxlxij; + tzji = lz*my_pow(-z,lz-1)*powylyji*powxlxji; + } + const double pqrij = powxlxij*powylyij*powzlzij; + const double pqrji = powxlxji*powylyji*powzlzji; + + for (size_t c=0; c<cgrid.size(); c++) { + double blip = B(sgrid[c]*(rij-cgrid[c]),fc_ij); + double dblip = dB(sgrid[c]*(rij-cgrid[c]),sgrid[c],fc_ij,fcp_ij); + const double term2ijx=pqrij*dblip*x/rij; + const double term2ijy=pqrij*dblip*y/rij; + const double term2ijz=pqrij*dblip*z/rij; + + const double term2jix=-pqrji*dblip*x/rij; + const double term2jiy=-pqrji*dblip*y/rij; + const double term2jiz=-pqrji*dblip*z/rij; + + const double term1ijx = blip*txij; + const double term1ijy = blip*tyij; + const double term1ijz = blip*tzij; + + const double term1jix = blip*txji; + const double term1jiy = blip*tyji; + const double term1jiz = blip*tzji; + + fd_ij(c+Lshift+fidx,0) += scale*( + rhoi(ii)*(term1ijx + term2ijx)*wj + -rhoj(ii)*(term1jix + term2jix)*wi) + ; + + fd_ij(c+Lshift+fidx,1) += scale*( + rhoi(ii)*(term1ijy + term2ijy)*wj + -rhoj(ii)*(term1jiy + term2jiy)*wi) + ; + + fd_ij(c+Lshift+fidx,2) += scale*( + rhoi(ii)*(term1ijz + term2ijz)*wj + -rhoj(ii)*(term1jiz + term2jiz)*wi) + ; + ii++; + } } - - return 1; - + Lshift+=sgrid.size(); + } } -int DM_Blip::calc_dXijdri( - const double rij, - const double, - const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, - rho_type& rhoi, - fd_type &fd_ij) +void DM_Blip::calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale) { - const double x = vec_ij[0]; - const double y = vec_ij[1]; - const double z = vec_ij[2]; - - size_t Lshift = 0; - - size_t ii=rhoisize; - for (int L=0; L<=Lmax; ++L) { - for (size_t o=0; o<orbitals[L].size(); ++o) { - const int lx = orbitals[L][o][0]; - const int ly = orbitals[L][o][1]; - const int lz = orbitals[L][o][2]; - - const double powxlxij = my_pow(x,lx); - const double powylyij = my_pow(y,ly); - const double powzlzij = my_pow(z,lz); - - double txij=0.0,tyij=0.0,tzij=0.0; - if (lx!=0) { - txij = lx*my_pow(x,lx-1)*powylyij*powzlzij; - } - if (ly!=0) { - tyij = ly*my_pow(y,ly-1)*powxlxij*powzlzij; - } - if (lz!=0) { - tzij = lz*my_pow(z,lz-1)*powylyij*powxlxij; - } - const double pqrij = powxlxij*powylyij*powzlzij; - - for (size_t c=0; c<cgrid.size(); c++) { - double blip = B(sgrid[c]*(rij-cgrid[c]),fc_ij); - double dblip = dB(sgrid[c]*(rij-cgrid[c]),sgrid[c],fc_ij,fcp_ij); - - const double term2ijx=pqrij*dblip*x/rij; - const double term2ijy=pqrij*dblip*y/rij; - const double term2ijz=pqrij*dblip*z/rij; - - const double term1ijx = blip*txij; - const double term1ijy = blip*tyij; - const double term1ijz = blip*tzij; - - fd_ij(c+Lshift+fidx,0) += - rhoi(ii)*(term1ijx + term2ijx) - ; - - fd_ij(c+Lshift+fidx,1) += - rhoi(ii)*(term1ijy + term2ijy) - ; - - fd_ij(c+Lshift+fidx,2) += - rhoi(ii)*(term1ijz + term2ijz) - ; - ii++; - } - } - Lshift+=sgrid.size(); + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + const double x = vec_ij[0]; + const double y = vec_ij[1]; + const double z = vec_ij[2]; + + double wj = weights[Zj]; + double fc_ij = scale*wj*fcut->calc(rij); + double fcp_ij = scale*wj*fcut->calc_prime(rij); + + size_t Lshift = 0; + + size_t ii=rhoisize+rfidx; + for (int L=0; L<=Lmax; ++L) { + for (size_t o=0; o<orbitals[L].size(); ++o) { + const int lx = orbitals[L][o][0]; + const int ly = orbitals[L][o][1]; + const int lz = orbitals[L][o][2]; + + const double powxlxij = my_pow(x,lx); + const double powylyij = my_pow(y,ly); + const double powzlzij = my_pow(z,lz); + + double txij=0.0,tyij=0.0,tzij=0.0; + if (lx!=0) { + txij = lx*my_pow(x,lx-1)*powylyij*powzlzij; + } + if (ly!=0) { + tyij = ly*my_pow(y,ly-1)*powxlxij*powzlzij; + } + if (lz!=0) { + tzij = lz*my_pow(z,lz-1)*powylyij*powxlxij; + } + const double pqrij = powxlxij*powylyij*powzlzij; + + for (size_t c=0; c<cgrid.size(); c++) { + double blip = B(sgrid[c]*(rij-cgrid[c]),fc_ij); + double dblip = dB(sgrid[c]*(rij-cgrid[c]),sgrid[c],fc_ij,fcp_ij); + + const double term2ijx=pqrij*dblip*x/rij; + const double term2ijy=pqrij*dblip*y/rij; + const double term2ijz=pqrij*dblip*z/rij; + + const double term1ijx = blip*txij; + const double term1ijy = blip*tyij; + const double term1ijz = blip*tzij; + + fd_ij(c+Lshift+fidx,0) += + rhoi(ii)*(term1ijx + term2ijx) + ; + + fd_ij(c+Lshift+fidx,1) += + rhoi(ii)*(term1ijy + term2ijy) + ; + + fd_ij(c+Lshift+fidx,2) += + rhoi(ii)*(term1ijz + term2ijz) + ; + ii++; + } } - - return 1; - -} -size_t DM_Blip::size() { - return s; + Lshift+=sgrid.size(); + } } std::string DM_Blip::label() { - return lab; + return lab; } void DM_Blip::init_rhoi(rho_type& rhoi) { - rhoi.resize(2*rhoisize); - rhoi.set_zero(); + rhoi.resize(2*rhoisize); + rhoi.set_zero(); } void DM_Blip::calc_rho( - const double rij, - const double, - const double fc_ij, - const Vec3d &vec_ij, - rho_type& rhoi) + const int Zi, + const int Zj, + const double rij, + const double, + const Vec3d &vec_ij, + rho_type& rhoi, + const double scale) { - size_t ii=0; - for (int L=0; L<=Lmax; ++L) { - for (size_t o=0; o<orbitals[L].size(); ++o) { - const size_t lx = orbitals[L][o][0]; - const size_t ly = orbitals[L][o][1]; - const size_t lz = orbitals[L][o][2]; - double t = (my_pow(vec_ij[0],lx)*my_pow(vec_ij[1],ly)*my_pow(vec_ij[2],lz)); - for (size_t c=0; c<cgrid.size(); c++) { - rhoi(ii++) += B(sgrid[c]*(rij-cgrid[c]),fc_ij)*t; - } - } + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + size_t ii=rfidx; + double fc_ij = scale*weights[Zj]*fcut->calc(rij); + for (int L=0; L<=Lmax; ++L) { + for (size_t o=0; o<orbitals[L].size(); ++o) { + const size_t lx = orbitals[L][o][0]; + const size_t ly = orbitals[L][o][1]; + const size_t lz = orbitals[L][o][2]; + double t = (my_pow(vec_ij[0],lx)*my_pow(vec_ij[1],ly)*my_pow(vec_ij[2],lz)); + for (size_t c=0; c<cgrid.size(); c++) { + rhoi(ii++) += B(sgrid[c]*(rij-cgrid[c]),fc_ij)*t; + } } + } } size_t DM_Blip::gen_atomic_orbitals(int Lmax) { - orbitals.resize(Lmax+1); - fac.resize(Lmax+1); - - size_t count = 0; - for (int L = 0; L <= Lmax; ++L) { - for (int lx = 0; lx <= L; ++lx) { - for (int ly = 0; ly <= L; ++ly) { - for (int lz = 0; lz <= L; ++lz) { - if (lx+ly+lz == L) { - std::vector<int> o = {lx, ly, lz}; - orbitals[L].push_back(o); - const double f = fact(L)/(fact(lx)*fact(ly)*fact(lz))/my_pow(4*rc,L); - fac[L].push_back(f); - count++; - } - } - } + orbitals.resize(Lmax+1); + fac.resize(Lmax+1); + + size_t count = 0; + for (int L = 0; L <= Lmax; ++L) { + for (int lx = 0; lx <= L; ++lx) { + for (int ly = 0; ly <= L; ++ly) { + for (int lz = 0; lz <= L; ++lz) { + if (lx+ly+lz == L) { + std::vector<int> o = {lx, ly, lz}; + orbitals[L].push_back(o); + const double f = fact(L)/(fact(lx)*fact(ly)*fact(lz))/my_pow(4*rc,L); + fac[L].push_back(f); + count++; + } } + } } - return count; + } + return count; } double DM_Blip::fact(int n) { - double f=1.0; - while (n) { - f *= n; - --n; - } - return f; + double f=1.0; + while (n) { + f *= n; + --n; + } + return f; } double DM_Blip::my_pow(double x, int n){ - double r = 1.0; + double r = 1.0; - while(n > 0){ - r *= x; - --n; - } + while(n > 0){ + r *= x; + --n; + } - return r; -} -size_t DM_Blip::rhoi_size() { - return rhoisize; + return r; } -size_t DM_Blip::rhoip_size() { - return rhoisize; +void DM_Blip::init() { + keys.push_back("CGRIDMB"); + keys.push_back("SGRIDMB"); + nparams=3; } diff --git a/src/dm_dummy.cpp b/src/dm_dummy.cpp index bdc648deac72d5d8dabe5ecaa32ba05d9918bea4..cd85a757738bb99bbe6ea0c1bc6018a6c096392c 100644 --- a/src/dm_dummy.cpp +++ b/src/dm_dummy.cpp @@ -1,38 +1,45 @@ +#include "tadah/models/descriptors/dm/dm_base.h" #include <tadah/models/descriptors/dm/dm_dummy.h> -DM_Dummy::DM_Dummy() {} -DM_Dummy::DM_Dummy(Config&) {} +DM_Dummy::DM_Dummy() { + init(); +} +DM_Dummy::DM_Dummy(Config&c): DM_Base(c) { + init(); +} void DM_Dummy::calc_aed( - rho_type&, - aed_type2 & ) {} -int DM_Dummy::calc_dXijdri_dXjidri( - const double, - const double, - const Vec3d &, - const double, - const double, - rho_type&, - rho_type&, - fd_type &, - const double, - const double) { return 0; } -int DM_Dummy::calc_dXijdri( - const double, - const double, - const Vec3d &, - const double, - const double, - rho_type&, - fd_type &) { return 0; } -size_t DM_Dummy::size() { return s;} + rho_type&, + aed_type & ) {} +void DM_Dummy::calc_dXijdri_dXjidri( + const int, + const int, + const double, + const double, + const Vec3d &, + rho_type&, + rho_type&, + fd_type &, + const double) {} +void DM_Dummy::calc_dXijdri( + const int, + const int, + const double, + const double, + const Vec3d &, + rho_type&, + fd_type &, + const double) {} std::string DM_Dummy::label() {return lab;} void DM_Dummy::init_rhoi(rho_type&) {} void DM_Dummy::calc_rho( - const double, - const double, - const double, - const Vec3d &, - rho_type&) {} -size_t DM_Dummy::rhoi_size() { return 0; } -size_t DM_Dummy::rhoip_size() { return 0; } + const int, + const int, + const double, + const double, + const Vec3d &, + rho_type&, + const double) {} +void DM_Dummy::init() { + nparams=0; +} diff --git a/src/dm_ead.cpp b/src/dm_ead.cpp index 3cb78a7ff892a0b9e7a1cd78bbc022e23f45aaf0..8cb83aaa524773dd2052e86b6829eed84d8fbb88 100644 --- a/src/dm_ead.cpp +++ b/src/dm_ead.cpp @@ -1,31 +1,37 @@ +#include "tadah/models/descriptors/dm/dm_base.h" #include <tadah/models/descriptors/dm/dm_ead.h> #include <tadah/models/descriptors/d_basis_functions.h> #include <stdexcept> #include <vector> -#include <iomanip> - +DM_EAD::DM_EAD() { + init(); +} /* Index ii iterates rhoi array * rhoi array is split 50/50 into density and derivative * of the embedding function */ -DM_EAD::DM_EAD(Config &config): - verbose(config.get<int>("VERBOSE")), - rc(config.get<double>("RCUTMB")) +DM_EAD::DM_EAD(Config &config): DM_Base(config), + rc(config.get<double>("RCUTMBMAX")) { - if (!config.get<bool>("INITMB")) { throw std::runtime_error("INITMB=false; cannot initialize "+label()+"\n"); } + init(); get_grid(config,"CGRIDMB",cgrid); get_grid(config,"SGRIDMB",sgrid); + // update config with generated grid + config.remove("CGRIDMB"); + for (const auto &i: cgrid) config.add("CGRIDMB",i); + config.remove("SGRIDMB"); + for (const auto &i: sgrid) config.add("SGRIDMB",i); if (cgrid.size()!=sgrid.size()) { throw std::runtime_error("SGRID2B and CGRID2B arrays differ in size.\n"); } - Lmax = config.get<int>("AGRIDMB"); + Lmax = config.get<int>("TYPEMB",1); s=sgrid.size()*(Lmax+1); rhoisize = gen_atomic_orbitals(Lmax); rhoisize *= sgrid.size(); @@ -41,14 +47,16 @@ DM_EAD::DM_EAD(Config &config): std::cout << std::endl; std::cout << "rhoisize: " << rhoisize << std::endl; } + auto init_atoms = get_init_atoms(config); + init_for_atoms(init_atoms); } void DM_EAD::calc_aed( rho_type& rhoi, - aed_type2 &aed) + aed_type &aed) { size_t Lshift = 0; - size_t ii=0; + size_t ii=rfidx; for (int L=0; L<=Lmax; ++L) { for (size_t o=0; o<orbitals[L].size(); ++o) { const double f = fac[L][o]; @@ -61,25 +69,30 @@ void DM_EAD::calc_aed( Lshift += sgrid.size(); } } -int DM_EAD::calc_dXijdri_dXjidri( +void DM_EAD::calc_dXijdri_dXjidri( + const int Zi, + const int Zj, const double rij, const double, const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, rho_type& rhoi, rho_type& rhoj, fd_type &fd_ij, - const double wi, - const double wj) + const double scale) { + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; const double x = vec_ij[0]; const double y = vec_ij[1]; const double z = vec_ij[2]; + double wi = weights[Zi]; + double wj = weights[Zj]; + double fc_ij = fcut->calc(rij); + double fcp_ij = fcut->calc_prime(rij); + size_t Lshift = 0; - size_t ii=rhoisize; + size_t ii=rhoisize+rfidx; for (int L=0; L<=Lmax; ++L) { for (size_t o=0; o<orbitals[L].size(); ++o) { const int lx = orbitals[L][o][0]; @@ -131,45 +144,48 @@ int DM_EAD::calc_dXijdri_dXjidri( const double term1jiy = gauss*tyji; const double term1jiz = gauss*tzji; - fd_ij(c+Lshift+fidx,0) += + fd_ij(c+Lshift+fidx,0) += scale*( rhoi(ii)*(term1ijx + term2ijx)*wj - -rhoj(ii)*(term1jix + term2jix)*wi + -rhoj(ii)*(term1jix + term2jix)*wi) ; - fd_ij(c+Lshift+fidx,1) += + fd_ij(c+Lshift+fidx,1) += scale*( rhoi(ii)*(term1ijy + term2ijy)*wj - -rhoj(ii)*(term1jiy + term2jiy)*wi + -rhoj(ii)*(term1jiy + term2jiy)*wi) ; - fd_ij(c+Lshift+fidx,2) += + fd_ij(c+Lshift+fidx,2) += scale*( rhoi(ii)*(term1ijz + term2ijz)*wj - -rhoj(ii)*(term1jiz + term2jiz)*wi + -rhoj(ii)*(term1jiz + term2jiz)*wi) ; ii++; } } Lshift+=sgrid.size(); } - - return 1; - } -int DM_EAD::calc_dXijdri( +void DM_EAD::calc_dXijdri( + const int Zi, + const int Zj, const double rij, const double, const Vec3d &vec_ij, - const double fc_ij, - const double fcp_ij, rho_type& rhoi, - fd_type &fd_ij) + fd_type &fd_ij, + const double scale) { + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; const double x = vec_ij[0]; const double y = vec_ij[1]; const double z = vec_ij[2]; + double wj = weights[Zj]; + double fc_ij = scale*wj*fcut->calc(rij); + double fcp_ij = scale*wj*fcut->calc_prime(rij); + size_t Lshift = 0; - size_t ii=rhoisize; + size_t ii=rhoisize+rfidx; for (int L=0; L<=Lmax; ++L) { for (size_t o=0; o<orbitals[L].size(); ++o) { const int lx = orbitals[L][o][0]; @@ -220,12 +236,6 @@ int DM_EAD::calc_dXijdri( } Lshift+=sgrid.size(); } - - return 1; - -} -size_t DM_EAD::size() { - return s; } std::string DM_EAD::label() { return lab; @@ -237,13 +247,17 @@ void DM_EAD::init_rhoi(rho_type& rhoi) rhoi.set_zero(); } void DM_EAD::calc_rho( + const int Zi, + const int Zj, const double rij, const double, - const double fc_ij, const Vec3d &vec_ij, - rho_type& rhoi) + rho_type& rhoi, + const double scale) { - size_t ii=0; + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + size_t ii=rfidx; + double fc_ij = scale*weights[Zj]*fcut->calc(rij); for (int L=0; L<=Lmax; ++L) { for (size_t o=0; o<orbitals[L].size(); ++o) { const size_t lx = orbitals[L][o][0]; @@ -297,9 +311,8 @@ double DM_EAD::my_pow(double x, int n){ } return r; } -size_t DM_EAD::rhoi_size() { - return rhoisize; -} -size_t DM_EAD::rhoip_size() { - return rhoisize; +void DM_EAD::init() { + keys.push_back("CGRIDMB"); + keys.push_back("SGRIDMB"); + nparams=3; } diff --git a/src/dm_eam.cpp b/src/dm_eam.cpp index 4aecee7abe9cb6381c793bba81e202f33d27f305..3408b29ec065c682f7d3e17ac63758d7b4621365 100644 --- a/src/dm_eam.cpp +++ b/src/dm_eam.cpp @@ -1,217 +1,220 @@ +#include "tadah/models/descriptors/dm/dm_base.h" #include <tadah/models/descriptors/dm/dm_eam.h> -DM_EAM::DM_EAM(Config &c): - verbose(c.get<int>("VERBOSE")) +DM_EAM::DM_EAM() { + init(); +} +DM_EAM::DM_EAM(Config &c): DM_Base(c) { - if (!c.get<bool>("INITMB")) { - s=0; - return; - } - ef.file_path = c("SETFL")[0]; - read_setfl(); - - if (std::abs(ef.rcut - c.get<double>("RCUTMB")) > std::numeric_limits<double>::min()) { - if (verbose) { - std::cout << "Config file cutoff and setfl file cutoff differ: " - << c.get<double>("RCUTMB") << " " << ef.rcut << std::endl; - std::cout << "Enforcing SETFL file cutoff: " << ef.rcut << std::endl; - } - c.remove("RCUTMB"); - c.add("RCUTMB", ef.rcut); - c.postprocess(); + init(); + if (!c.get<bool>("INITMB")) return; + s=1; + ef.file_path = c.get<std::string>("TYPEMB",1); + read_setfl(); + + if (std::abs(ef.rcut - c.get<double>("RCUTMB")) > std::numeric_limits<double>::min()) { + if (verbose) { + std::cout << "Config file cutoff and setfl file cutoff differ: " + << c.get<double>("RCUTMB") << " " << ef.rcut << std::endl; + std::cout << "Enforcing SETFL file cutoff: " << ef.rcut << std::endl; } - - - frho_spline.resize(ef.nrho+1, std::vector<double>(7)); - rhor_spline.resize(ef.nr+1, std::vector<double>(7)); - z2r_spline.resize(ef.nr+1, std::vector<double>(7)); - - - gen_splines(ef.nrho, ef.drho, ef.frho, frho_spline); - gen_splines(ef.nr, ef.dr, ef.rhor, rhor_spline); - gen_splines(ef.nr, ef.dr, ef.z2r, z2r_spline); - + c.remove("RCUTMB"); + c.add("RCUTMB", ef.rcut); + c.postprocess(); + } + + frho_spline.resize(ef.nrho+1, std::vector<double>(7)); + rhor_spline.resize(ef.nr+1, std::vector<double>(7)); + z2r_spline.resize(ef.nr+1, std::vector<double>(7)); + + gen_splines(ef.nrho, ef.drho, ef.frho, frho_spline); + gen_splines(ef.nr, ef.dr, ef.rhor, rhor_spline); + gen_splines(ef.nr, ef.dr, ef.z2r, z2r_spline); + + rhoisize = 1; + auto init_atoms = get_init_atoms(c); + init_for_atoms(init_atoms); } void DM_EAM::calc_aed( - rho_type& rho, - aed_type2 &aed) + rho_type& rho, + aed_type &aed) { - //std::cout << "rho[i]: " << rho(0) << std::endl; - double p = rho(0)*ef.rdrho + 1.0; - int m = static_cast<int> (p); - m = std::max(1,std::min(m,ef.nrho-1)); - p -= m; - p = std::min(p,1.0); - //std::vector<double> coeff = frho_spline[m]; - double phi = ((frho_spline[m][3]*p + frho_spline[m][4])*p + frho_spline[m][5])*p + frho_spline[m][6]; + //std::cout << "rho[i]: " << rho(0) << std::endl; + double p = rho(rfidx)*ef.rdrho + 1.0; + int m = static_cast<int> (p); + m = std::max(1,std::min(m,ef.nrho-1)); + p -= m; + p = std::min(p,1.0); + //std::vector<double> coeff = frho_spline[m]; + double phi = ((frho_spline[m][3]*p + frho_spline[m][4])*p + frho_spline[m][5])*p + frho_spline[m][6]; - rho(1) = (frho_spline[m][0]*p + frho_spline[m][1])*p + frho_spline[m][2]; // lammps fp[i] - //std::cout << "fp[i]: " << rho(1) << std::endl; + rho(1+rfidx) = (frho_spline[m][0]*p + frho_spline[m][1])*p + frho_spline[m][2]; // lammps fp[i] + //std::cout << "fp[i]: " << rho(1) << std::endl; - if (rho(0) > ef.rhomax) phi += rho(1) * (rho(0)-ef.rhomax); - //phi *= scale[type[i]][type[i]]; + if (rho(rfidx) > ef.rhomax) phi += rho(1+rfidx) * (rho(rfidx)-ef.rhomax); + //phi *= scale[type[i]][type[i]]; - aed(fidx) += phi; + aed(fidx) += phi; } -int DM_EAM::calc_dXijdri_dXjidri( - const double rij, - const double, - const Vec3d &, - const double, - const double, - rho_type& rhoi, - rho_type& rhoj, - fd_type &fd_ij, - const double, - const double) +void DM_EAM::calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale) { - double r = rij; - //double recip = 1.0/r; - double p = r*ef.rdr + 1.0; - int m = static_cast<int> (p); - m = std::min(m,ef.nr-1); - p -= m; - p = std::min(p,1.0); - //std::vector<double> coeff = rhor_spline[m]; - double rhoip = (rhor_spline[m][0]*p + rhor_spline[m][1])*p + rhor_spline[m][2]; - double rhojp = (rhor_spline[m][0]*p + rhor_spline[m][1])*p + rhor_spline[m][2]; - - // here rho_i[1] is a derivative of rho_i at local atom, similarly for rho_j - //double psip = rho_i[1]*rhojp + rho_j[1]*rhoip; - double psip = rhoi(1)*rhojp - rhoj(1)*rhoip; - - fd_ij(fidx,0) = psip; // requires *delij*recip in the main loop - return 0; - + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double r = rij; + double rinv = 1/r; + double p = r*ef.rdr + 1.0; + int m = static_cast<int> (p); + m = std::min(m,ef.nr-1); + p -= m; + p = std::min(p,1.0); + double rhoip = (rhor_spline[m][0]*p + rhor_spline[m][1])*p + rhor_spline[m][2]; + double rhojp = (rhor_spline[m][0]*p + rhor_spline[m][1])*p + rhor_spline[m][2]; + + // here rho_i[1] is a derivative of rho_i at local atom, similarly for rho_j + //double psip = rho_i[1]*rhojp + rho_j[1]*rhoip; + double psip = rhoi(rfidx+1)*rhojp + rhoj(rfidx+1)*rhoip; + + double f = scale*psip*rinv; + fd_ij(fidx,0) = f*vec_ij[0]; + fd_ij(fidx,1) = f*vec_ij[1]; + fd_ij(fidx,2) = f*vec_ij[2]; } -int DM_EAM::calc_dXijdri( - const double rij, - const double, - const Vec3d &, - const double, - const double, - rho_type& rhoi, - fd_type &fd_ij) +void DM_EAM::calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale) { - double r = rij; - //double recip = 1.0/r; - double p = r*ef.rdr + 1.0; - int m = static_cast<int> (p); - m = std::min(m,ef.nr-1); - p -= m; - p = std::min(p,1.0); - double rhojp = (rhor_spline[m][0]*p + rhor_spline[m][1])*p + rhor_spline[m][2]; - - // here rho_i[1] is a derivative of rho_i at local atom - double psip = rhoi(1)*rhojp; - - fd_ij(fidx,0) = psip; // requires *delij*recip in the main loop - return 0; - -} -size_t DM_EAM::size() { - return s; + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double r = rij; + double rinv = 1/r; + double p = r*ef.rdr + 1.0; + int m = static_cast<int> (p); + m = std::min(m,ef.nr-1); + p -= m; + p = std::min(p,1.0); + double rhojp = (rhor_spline[m][0]*p + rhor_spline[m][1])*p + rhor_spline[m][2]; + + // here rho_i[1] is a derivative of rho_i at local atom + double psip = rhoi(rfidx+1)*rhojp; + + double f = scale*psip*rinv; + fd_ij(fidx,0) = f*vec_ij[0]; + fd_ij(fidx,1) = f*vec_ij[1]; + fd_ij(fidx,2) = f*vec_ij[2]; } std::string DM_EAM::label() { - return lab; + return lab; } void DM_EAM::read_setfl() { - std::string line; - std::ifstream in_file(ef.file_path); - if (!in_file.good()) - throw std::runtime_error("SETFL file does not exists.\n"); - - if (in_file.is_open()) { - if (verbose) - std::cout << "<DM_EAM> Reading setfl: " << ef.file_path << std::endl; - // skip ficgridt 3 comment lines - getline (in_file,line); - getline (in_file,line); - getline (in_file,line); - // skip number of types and types - getline (in_file,line); - // read 5th line - in_file >> ef.nrho >> ef.drho >> ef.nr >> ef.dr >> ef.rcut; - in_file >> ef.atomic_number >> ef.atomic_mass >> ef.lattice_param >> ef.lattice; - ef.rdr = 1.0/ef.dr; - ef.rdrho = 1.0/ef.drho; - // prepare arrays - ef.frho.resize(ef.nrho); - ef.rhor.resize(ef.nr); - ef.z2r.resize(ef.nr); - // read all data - for (int i=0; i<ef.nrho; ++i) in_file >> ef.frho[i]; - for (int i=0; i<ef.nr; ++i) in_file >> ef.rhor[i]; - for (int i=0; i<ef.nr; ++i) in_file >> ef.z2r[i]; - in_file.close(); - } - else { - std::cout << "<DM_EAM> Unable to open file: " << ef.file_path << std::endl;; - } - // get max value of rho - //ef.rhomax = *std::max_element(ef.rhor.begin(), ef.rhor.end()); - ef.rhomax = (ef.nrho-1) * ef.drho; + std::string line; + std::ifstream in_file(ef.file_path); + if (!in_file.good()) + throw std::runtime_error("SETFL file does not exists.\n"); + + if (in_file.is_open()) { + if (verbose) + std::cout << "<DM_EAM> Reading setfl: " << ef.file_path << std::endl; + // skip ficgridt 3 comment lines + getline (in_file,line); + getline (in_file,line); + getline (in_file,line); + // skip number of types and types + getline (in_file,line); + // read 5th line + in_file >> ef.nrho >> ef.drho >> ef.nr >> ef.dr >> ef.rcut; + in_file >> ef.atomic_number >> ef.atomic_mass >> ef.lattice_param >> ef.lattice; + ef.rdr = 1.0/ef.dr; + ef.rdrho = 1.0/ef.drho; + // prepare arrays + ef.frho.resize(ef.nrho); + ef.rhor.resize(ef.nr); + ef.z2r.resize(ef.nr); + // read all data + for (int i=0; i<ef.nrho; ++i) in_file >> ef.frho[i]; + for (int i=0; i<ef.nr; ++i) in_file >> ef.rhor[i]; + for (int i=0; i<ef.nr; ++i) in_file >> ef.z2r[i]; + in_file.close(); + } + else { + std::cout << "<DM_EAM> Unable to open file: " << ef.file_path << std::endl;; + } + // get max value of rho + //ef.rhomax = *std::max_element(ef.rhor.begin(), ef.rhor.end()); + ef.rhomax = (ef.nrho-1) * ef.drho; } void DM_EAM::gen_splines(int &n, double &delta, std::vector<double> &f, - std::vector<std::vector<double>> &spline) + std::vector<std::vector<double>> &spline) { - // in lammps f is n+1, here is size n - for (int m=1; m<=n; m++) spline[m][6] = f[m-1]; - - spline[1][5] = spline[2][6] - spline[1][6]; - spline[2][5] = 0.5 * (spline[3][6]-spline[1][6]); - spline[n-1][5] = 0.5 * (spline[n][6]-spline[n-2][6]); - spline[n][5] = spline[n][6] - spline[n-1][6]; - - for (int m = 3; m <= n-2; m++) - spline[m][5] = ((spline[m-2][6]-spline[m+2][6]) + - 8.0*(spline[m+1][6]-spline[m-1][6])) / 12.0; - - for (int m = 1; m <= n-1; m++) { - spline[m][4] = 3.0*(spline[m+1][6]-spline[m][6]) - 2.0*spline[m][5] - spline[m+1][5]; - spline[m][3] = spline[m][5] + spline[m+1][5] - 2.0*(spline[m+1][6]-spline[m][6]); - } - - spline[n][4] = 0.0; - spline[n][3] = 0.0; - - for (int m = 1; m <= n; m++) { - spline[m][2] = spline[m][5]/delta; - spline[m][1] = 2.0*spline[m][4]/delta; - spline[m][0] = 3.0*spline[m][3]/delta; - } + // in lammps f is n+1, here is size n + for (int m=1; m<=n; m++) spline[m][6] = f[m-1]; + + spline[1][5] = spline[2][6] - spline[1][6]; + spline[2][5] = 0.5 * (spline[3][6]-spline[1][6]); + spline[n-1][5] = 0.5 * (spline[n][6]-spline[n-2][6]); + spline[n][5] = spline[n][6] - spline[n-1][6]; + + for (int m = 3; m <= n-2; m++) + spline[m][5] = ((spline[m-2][6]-spline[m+2][6]) + + 8.0*(spline[m+1][6]-spline[m-1][6])) / 12.0; + + for (int m = 1; m <= n-1; m++) { + spline[m][4] = 3.0*(spline[m+1][6]-spline[m][6]) - 2.0*spline[m][5] - spline[m+1][5]; + spline[m][3] = spline[m][5] + spline[m+1][5] - 2.0*(spline[m+1][6]-spline[m][6]); + } + + spline[n][4] = 0.0; + spline[n][3] = 0.0; + + for (int m = 1; m <= n; m++) { + spline[m][2] = spline[m][5]/delta; + spline[m][1] = 2.0*spline[m][4]/delta; + spline[m][0] = 3.0*spline[m][3]/delta; + } } void DM_EAM::init_rhoi(rho_type& rhoi) { - rhoi.resize(2); - rhoi.set_zero(); + rhoi.resize(2); + rhoi.set_zero(); } void DM_EAM::calc_rho( - const double rij, - const double, - const double, - const Vec3d &, - rho_type& rho) + const int Zi, + const int Zj, + const double rij, + const double, + const Vec3d &, + rho_type& rho, + const double scale) { - double r = rij; - double p = r*ef.rdr + 1.0; - int m = static_cast<int> (p); - m = std::min(m,ef.nr-1); - p -= m; - p = std::min(p,1.0); - std::vector<double> coeff = rhor_spline[m]; - rho(0) += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; + if (!is_init_for_atoms(Zi,Zj) || rij > get_rcut()) return; + double r = rij; + double p = r*ef.rdr + 1.0; + int m = static_cast<int> (p); + m = std::min(m,ef.nr-1); + p -= m; + p = std::min(p,1.0); + std::vector<double> coeff = rhor_spline[m]; + rho(rfidx) += scale*( ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]); } -size_t DM_EAM::rhoi_size() { - return 1; -} -size_t DM_EAM::rhoip_size() { - return 1; +void DM_EAM::init() { + nparams=1; } diff --git a/src/dm_mjoin.cpp b/src/dm_mjoin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f1d9cb02765cc17d3d0fd95e9459b585bd455365 --- /dev/null +++ b/src/dm_mjoin.cpp @@ -0,0 +1,103 @@ +#include <cstddef> +#include <tadah/models/descriptors/dm/dm_mjoin.h> + +DM_mJoin::DM_mJoin() { + init(); +} +DM_mJoin::~DM_mJoin() { + for (auto d : ds) if (d) delete d; +} + +DM_mJoin::DM_mJoin(Config &c) : DM_Base(c) { + init(); + configs = parse_config(c, "TYPEMB"); + expand_grids(c, configs, "TYPEMB"); + + for (auto &c1 : configs) { + ds.push_back(CONFIG::factory<DM_Base, Config&>(c1.get<std::string>("TYPEMB"), c1)); + s += ds.back()->size(); + rhoisize += ds.back()->rhoi_size(); + } + set_rfidx(0); +} + +void DM_mJoin::calc_aed(rho_type& rho, aed_type &aed) { + for (auto d : ds) { + d->calc_aed(rho, aed); + } +} +void DM_mJoin::calc_dXijdri_dXjidri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + rho_type& rhoj, + fd_type &fd_ij, + const double scale) { + for (auto d : ds) { + d->calc_dXijdri_dXjidri(Zi,Zj,rij,rij_sq,vec_ij,rhoi,rhoj,fd_ij,scale); + } +} +void DM_mJoin::calc_dXijdri( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rhoi, + fd_type &fd_ij, + const double scale) { + for (auto d : ds) { + d->calc_dXijdri(Zi,Zj,rij,rij_sq,vec_ij,rhoi,fd_ij,scale); + } +} +void DM_mJoin::init_rhoi(rho_type& rhoi) { + rhoi.resize(2*rhoisize); + rhoi.set_zero(); +} +void DM_mJoin::calc_rho( + const int Zi, + const int Zj, + const double rij, + const double rij_sq, + const Vec3d &vec_ij, + rho_type& rho, + const double scale) { + for (auto d : ds) { + d->calc_rho(Zi,Zj,rij,rij_sq,vec_ij,rho,scale); + } +} +std::string DM_mJoin::label() { + return lab; +} + +void DM_mJoin::set_fidx(size_t fidx_) { + fidx = fidx_; + ds[0]->set_fidx(fidx_); + size_t s = 0; + for (size_t i = 1; i < ds.size(); ++i) { + s += ds[i - 1]->size(); + ds[i]->set_fidx(fidx_ + s); + } +} +void DM_mJoin::set_rfidx(size_t rfidx_) { + rfidx = rfidx_; + ds[0]->set_rfidx(rfidx_); + size_t s = 0; + for (size_t i = 1; i < ds.size(); ++i) { + s += ds[i - 1]->rhoi_size(); + s += ds[i - 1]->rhoip_size(); + ds[i]->set_rfidx(rfidx_ + s); + } +} + +void DM_mJoin::init() { + // not really sure about this + keys.push_back("TYPEMB"); + keys.push_back("RCTYPEMB"); + keys.push_back("RCUTMB"); + nparams=std::numeric_limits<size_t>::max(); +} + diff --git a/src/function_base.cpp b/src/function_base.cpp index 8e80b849351153537c6986563dac26e5d447d3b7..5b272de2bd825afebee99e58c97ff4036f92c67e 100644 --- a/src/function_base.cpp +++ b/src/function_base.cpp @@ -1,2 +1,17 @@ #include <tadah/models/functions/function_base.h> +Function_Base::Function_Base(): verbose(0) { +} +Function_Base::Function_Base(const Config &c) { + verbose = (c.exist("VERBOSE")) ? c.get<int>("VERBOSE") : 0; +} +void Function_Base::set_verbose(int v) { verbose=v; } +int Function_Base::get_verbose() { return verbose; } + +Function_Base::~Function_Base() {} + +double Function_Base::operator() (const aed_type& , const aed_type& ) const { return 0.0; } +aed_type Function_Base::derivative(const aed_type& , const aed_type& ) const { return aed_type(); } +double Function_Base::prime(const aed_type& , const aed_type& , + const aed_type& ) const { return 0.0; } +void Function_Base::set_basis(const Matrix ) {} diff --git a/src/kern_base.cpp b/src/kern_base.cpp index 557cfd1964a3ee8c9c5fa0c8b5bafa1e92a62c6a..1a431efa800ebe9bbf85bfd11f4f5b1c712a4cfe 100644 --- a/src/kern_base.cpp +++ b/src/kern_base.cpp @@ -1,57 +1,59 @@ #include <tadah/models/functions/kernels/kern_base.h> +Kern_Base::Kern_Base() {} +Kern_Base::Kern_Base(const Config &c): Function_Base(c) {} Kern_Base::~Kern_Base() {} void Kern_Base::set_basis(const Matrix b) { - basis = b; + basis = b; } -double Kern_Base::epredict(const t_type &kweights, const aed_type2 &aed) const +double Kern_Base::epredict(const t_type &kweights, const aed_type &aed) const { - double energy=0; - for (size_t b=0; b<basis.cols(); ++b) { - energy += kweights[b]*(*this)(basis.col(b),aed); - } - return energy; + double energy=0; + for (size_t b=0; b<basis.cols(); ++b) { + energy += kweights[b]*(*this)(basis.col(b),aed); + } + return energy; } double Kern_Base::fpredict(const t_type &kweights, const fd_type &fdij, - const aed_type2 &aedi, const size_t k) const + const aed_type &aedi, const size_t k) const { - double res=0.0; - for (size_t b=0; b<basis.cols(); ++b) { - res -= kweights[b]*(*this).prime(basis.col(b),aedi,fdij(k)); - } - return res; + double res=0.0; + for (size_t b=0; b<basis.cols(); ++b) { + res -= kweights[b]*(*this).prime(basis.col(b),aedi,fdij(k)); + } + return res; } force_type Kern_Base::fpredict(const t_type &kweights, const fd_type &fdij, - const aed_type2 &aedi) const + const aed_type &aedi) const { - force_type v; - v.set_zero(); - for (size_t b=0; b<basis.cols(); ++b) { - for (size_t k=0; k<3; ++k) { - v(k) -= kweights[b]*(*this).prime(basis.col(b),aedi,fdij(k)); - } + force_type v; + v.set_zero(); + for (size_t b=0; b<basis.cols(); ++b) { + for (size_t k=0; k<3; ++k) { + v(k) -= kweights[b]*(*this).prime(basis.col(b),aedi,fdij(k)); } - return v; + } + return v; } void Kern_Base::read_basis_from_config(const Config &config, Matrix &b) { - // storage is in column-major order - if (!(config.exist("SBASIS") && config.exist("BASIS"))) return; - size_t sbasis = config.get<size_t>("SBASIS"); - size_t vlen = config("BASIS").size()/sbasis; - std::vector<double> temp(sbasis*vlen); - config.get<std::vector<double>>("BASIS",temp); - b.resize(vlen,sbasis); // aeds are in column-major order - size_t ii=0; - for (size_t i=0;i<sbasis; ++i) { - for (size_t j=0;j<vlen; ++j) { - b(j,i) = temp[ii++]; - } + // storage is in column-major order + if (!(config.exist("SBASIS") && config.exist("BASIS"))) return; + size_t sbasis = config.get<size_t>("SBASIS"); + size_t vlen = config("BASIS").size()/sbasis; + std::vector<double> temp(sbasis*vlen); + config.get<std::vector<double>>("BASIS",temp); + b.resize(vlen,sbasis); // aeds are in column-major order + size_t ii=0; + for (size_t i=0;i<sbasis; ++i) { + for (size_t j=0;j<vlen; ++j) { + b(j,i) = temp[ii++]; } + } } const Matrix &Kern_Base::get_basis() const { - return basis; + return basis; } Matrix Kern_Base::get_basis() { - return basis; + return basis; } diff --git a/src/kern_linear.cpp b/src/kern_linear.cpp index 52e6ee0563c58b64a160b6a9bad9cc9232700047..0faf649a1862347049fb8948dd060cb444f240e5 100644 --- a/src/kern_linear.cpp +++ b/src/kern_linear.cpp @@ -2,17 +2,18 @@ Kern_Linear::Kern_Linear() {} Kern_Linear::Kern_Linear (const Config &c): - Function_Base(c) + Function_Base(c), + Kern_Base(c) {} -double Kern_Linear::operator() (const aed_type2& b, const aed_type2& af) const +double Kern_Linear::operator() (const aed_type& b, const aed_type& af) const { return b*af;; } -aed_type2 Kern_Linear::derivative(const aed_type2& b, const aed_type2&) const +aed_type Kern_Linear::derivative(const aed_type& b, const aed_type&) const { return b; } -double Kern_Linear::prime(const aed_type2& b, const aed_type2& , const aed_type2& ff) const +double Kern_Linear::prime(const aed_type& b, const aed_type& , const aed_type& ff) const { // return derivative(b,af).transpose() * ff; return b * ff; @@ -21,17 +22,17 @@ std::string Kern_Linear::get_label() const { return label; } -double Kern_Linear::epredict(const t_type &weights, const aed_type2& aed) const +double Kern_Linear::epredict(const t_type &weights, const aed_type& aed) const { return weights*aed; } double Kern_Linear::fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2& , const size_t k) const + const aed_type& , const size_t k) const { return -(fdij(k) * weights); } force_type Kern_Linear::fpredict(const t_type &weights, const fd_type &fdij, - const aed_type2& ) const + const aed_type& ) const { return -(fdij * weights); } diff --git a/src/kern_lq.cpp b/src/kern_lq.cpp index 4a4733d011ff47b9435e762fd3401ae418215680..e8b1f5e04c9783a46a8459af08861ea84dc49183 100644 --- a/src/kern_lq.cpp +++ b/src/kern_lq.cpp @@ -2,22 +2,23 @@ Kern_LQ::Kern_LQ () {} Kern_LQ::Kern_LQ (const Config &c): - Function_Base(c) + Function_Base(c), + Kern_Base(c) { if (get_verbose()) std::cout << std::endl << label << std::endl; read_basis_from_config(c,basis); } -double Kern_LQ::operator() (const aed_type2& b, const aed_type2& af) const +double Kern_LQ::operator() (const aed_type& b, const aed_type& af) const { double x = b*af; return x*x + x; } -aed_type2 Kern_LQ::derivative(const aed_type2& b, const aed_type2& af) const +aed_type Kern_LQ::derivative(const aed_type& b, const aed_type& af) const { double temp = 2.0 * b*af; return temp*b + b; } -double Kern_LQ::prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const +double Kern_LQ::prime(const aed_type& b, const aed_type& af, const aed_type& ff) const { return derivative(b, af)*ff; } diff --git a/src/kern_polynomial.cpp b/src/kern_polynomial.cpp index cdc3a625f99ec1c14eaaa0c58015e87305256a2a..ca31fad2d44a935b25f7f292ab3f9a503f047eff 100644 --- a/src/kern_polynomial.cpp +++ b/src/kern_polynomial.cpp @@ -3,6 +3,7 @@ Kern_Polynomial::Kern_Polynomial () {} Kern_Polynomial::Kern_Polynomial (const Config &config): Function_Base(config), + Kern_Base(config), d(config.get<int>("MPARAMS",0)), gamma(config.get<double>("MPARAMS",1)), c(config.get<double>("MPARAMS",2)) @@ -11,15 +12,15 @@ Kern_Polynomial::Kern_Polynomial (const Config &config): <<" | gamma: " << gamma << " | c: " << c << std::endl; read_basis_from_config(config,basis); } -double Kern_Polynomial::operator() (const aed_type2& b, const aed_type2& af) const +double Kern_Polynomial::operator() (const aed_type& b, const aed_type& af) const { return std::pow(gamma*(b*af)+c,d); } -aed_type2 Kern_Polynomial::derivative(const aed_type2& b, const aed_type2& af) const +aed_type Kern_Polynomial::derivative(const aed_type& b, const aed_type& af) const { return d*gamma*std::pow(gamma*(b*af)+c,d-1)*b; } -double Kern_Polynomial::prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const +double Kern_Polynomial::prime(const aed_type& b, const aed_type& af, const aed_type& ff) const { return derivative(b, af)*ff; } diff --git a/src/kern_quadratic.cpp b/src/kern_quadratic.cpp index 1f1961533c5c63c898296cd8938ab3cc39f224ab..3e772ad1323e173528624c326a2d2ac363b20798 100644 --- a/src/kern_quadratic.cpp +++ b/src/kern_quadratic.cpp @@ -2,28 +2,29 @@ Kern_Quadratic::Kern_Quadratic () {} Kern_Quadratic::Kern_Quadratic (const Config &c): - Function_Base(c) + Function_Base(c), + Kern_Base(c) { if (get_verbose()) std::cout << std::endl << label << std::endl; read_basis_from_config(c,basis); } -double Kern_Quadratic::operator() (const aed_type2& b, const aed_type2& af) const +double Kern_Quadratic::operator() (const aed_type& b, const aed_type& af) const { double x = b*af; return x*x; } -aed_type2 Kern_Quadratic::derivative(const aed_type2& b, const aed_type2& af) const +aed_type Kern_Quadratic::derivative(const aed_type& b, const aed_type& af) const { - double temp = 2.0 * b*af; - return b*temp;; + double temp = 2*(b*af); + return b*temp; } -double Kern_Quadratic::prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const +double Kern_Quadratic::prime(const aed_type& b, const aed_type& af, const aed_type& ff) const { //return dot(derivative(b, af), ff); // it is faster this way - double scale = 2.0*b*af; - return scale*ff*b; + double scale = 2.0*(b*af); + return scale*(ff*b); } std::string Kern_Quadratic::get_label() const { diff --git a/src/kern_rbf.cpp b/src/kern_rbf.cpp index f8fb5132de4cfb39388febf24eb8f75d315a514d..e35ed017e6f391cc2aadbf4573286c4c011f7283 100644 --- a/src/kern_rbf.cpp +++ b/src/kern_rbf.cpp @@ -3,25 +3,27 @@ Kern_RBF::Kern_RBF () {} Kern_RBF::Kern_RBF (const Config &c): Function_Base(c), + Kern_Base(c), sigma(c.get<double>("MPARAMS")), - gamma(1.0/(2.0*sigma*sigma)) + gamma(1.0/(sigma*sigma)) { if (get_verbose()) std::cout << std::endl << label << " | sigma: " << sigma << " | gamma: " << gamma << std::endl; read_basis_from_config(c,basis); } -double Kern_RBF::operator() (const aed_type2& b, const aed_type2& af) const +double Kern_RBF::operator() (const aed_type& b, const aed_type& af) const { - const aed_type2 v = af-b; - return exp(-gamma*(v*v)); + const aed_type v = (af-b); + return exp(-0.5*gamma*(v*v)); } -aed_type2 Kern_RBF::derivative(const aed_type2& b, const aed_type2& af) const +aed_type Kern_RBF::derivative(const aed_type& b, const aed_type& af) const { - return -2.0*gamma*(af-b)*(*this)(af,b); + return gamma*(b-af)*(*this)(b,af); } -double Kern_RBF::prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const +double Kern_RBF::prime(const aed_type& b, const aed_type& af, const aed_type& ff) const { + // std::cout << "f: " << ff << std::endl; return derivative(b, af)*ff; } std::string Kern_RBF::get_label() const diff --git a/src/kern_sigmoid.cpp b/src/kern_sigmoid.cpp index b3fbd49b57b8d9b5cfe75cc9e0609910c6608af0..419bb9e3201726ebb93e52315597387398dc617a 100644 --- a/src/kern_sigmoid.cpp +++ b/src/kern_sigmoid.cpp @@ -3,6 +3,7 @@ Kern_Sigmoid::Kern_Sigmoid () {} Kern_Sigmoid::Kern_Sigmoid (const Config &config): Function_Base(config), + Kern_Base(config), gamma(config.get<double>("MPARAMS",0)), c(config.get<double>("MPARAMS",1)) { @@ -11,15 +12,15 @@ Kern_Sigmoid::Kern_Sigmoid (const Config &config): read_basis_from_config(config,basis); } -double Kern_Sigmoid::operator() (const aed_type2& b, const aed_type2& af) const +double Kern_Sigmoid::operator() (const aed_type& b, const aed_type& af) const { return std::tanh(gamma*(b*af)+c); } -aed_type2 Kern_Sigmoid::derivative(const aed_type2& b, const aed_type2& af) const +aed_type Kern_Sigmoid::derivative(const aed_type& b, const aed_type& af) const { return gamma*(1.0-std::pow((*this)(af,b),2))*b; } -double Kern_Sigmoid::prime(const aed_type2& b, const aed_type2& af, const aed_type2& ff) const +double Kern_Sigmoid::prime(const aed_type& b, const aed_type& af, const aed_type& ff) const { return derivative(b, af)*ff; } diff --git a/src/m_train.cpp b/src/m_train.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3bc76b5d0f4d61120e9393a0672072a6319e8fdb --- /dev/null +++ b/src/m_train.cpp @@ -0,0 +1,4 @@ +#include <tadah/models/m_train.h> + +// void M_Train::train_with_residuals( +// } diff --git a/tests/test_basis_functions.cpp b/tests/test_basis_functions.cpp index 6af366dc176446b9afe24b63608d903725c52ba3..15005544be7f580916abfd6ea73f669dd23197b5 100644 --- a/tests/test_basis_functions.cpp +++ b/tests/test_basis_functions.cpp @@ -16,9 +16,9 @@ TEST_CASE( "Testing BF_Linear", "[basis_functions]" ) { BF_Linear bf; - aed_type2 w(2); + aed_type w(2); w.random(); - aed_type2 aed(2); + aed_type aed(2); aed.random(); fd_type fd(2); fd.random(); @@ -32,7 +32,7 @@ TEST_CASE( "Testing BF_Linear", "[basis_functions]" ) { double fy = -1*(w*fd(1)); double fz = -1*(w*fd(2)); //central_difference< - // aed_type2, aed_type2,BF_Linear, &BF_Linear::epredict> + // aed_type, aed_type,BF_Linear, &BF_Linear::epredict> // (); force_type f = bf.fpredict(w,fd,aed); REQUIRE_THAT(fx, Catch::Matchers::WithinRel(bf.fpredict(w,fd,aed,0))); @@ -50,9 +50,9 @@ TEST_CASE( "Testing BF_Linear", "[basis_functions]" ) { } TEST_CASE( "Testing BF_Polynomial2", "[basis_functions]" ) { BF_Polynomial2 bf; - aed_type2 w(3); + aed_type w(3); w.random(12345); - aed_type2 aed(2); + aed_type aed(2); aed.random(12345); fd_type fd(2); fd.random(12345); diff --git a/tests/test_cutoffs.cpp b/tests/test_cutoffs.cpp index 997b03d627c019336081df0585fb294391e17935..aaac9d0561436505138407296c7b83e4475939c8 100644 --- a/tests/test_cutoffs.cpp +++ b/tests/test_cutoffs.cpp @@ -162,3 +162,46 @@ TEST_CASE( "Testing Cutoffs: Cut_Poly2", "[Cut_Poly2]" ) { Catch::Matchers::WithinAbs(-1.728, 1e-12)); delete c2b; } +TEST_CASE( "Testing Cutoffs: Cut_Cos_s", "[Cut_Cos_S]" ) { + + REQUIRE_NOTHROW(Cut_Cos_S()); + double rcut2b = 6.2; + double rcut2bsq = rcut2b*rcut2b; + using Cut = Cut_Cos_S; + std::string cuttype = "Cut_Cos_S"; + Cut_Base *c2b = new Cut( rcut2b ); + + REQUIRE( c2b->label() == cuttype ); + + REQUIRE( c2b->calc(rcut2b) < std::numeric_limits<double>::min() ); + REQUIRE( c2b->calc_prime(rcut2b) < std::numeric_limits<double>::min() ); + REQUIRE( std::abs(c2b->get_rcut()-rcut2b)<std::numeric_limits<double>::min() ); + REQUIRE( std::abs(c2b->get_rcut_sq()-rcut2bsq)<std::numeric_limits<double>::min() ); + + // cutoff cannot be negative + double temp = -0.1; + REQUIRE_THROWS(Cut( temp )); + REQUIRE_THROWS_AS(c2b->set_rcut(temp), std::runtime_error); + REQUIRE_THROWS_AS(c2b->test_rcut(temp), std::runtime_error); + + // recheck after resetting cutoff + rcut2b=3.4; + rcut2bsq=rcut2b*rcut2b; + c2b->set_rcut(100000); + c2b->set_rcut(rcut2b); + REQUIRE( c2b->calc(rcut2b) < std::numeric_limits<double>::min() ); + REQUIRE( c2b->calc_prime(rcut2b) < std::numeric_limits<double>::min() ); + REQUIRE( std::abs(c2b->get_rcut()-rcut2b)<std::numeric_limits<double>::min() ); + REQUIRE( std::abs(c2b->get_rcut_sq()-rcut2bsq)<std::numeric_limits<double>::min() ); + + REQUIRE_THAT(c2b->calc(2.0), + Catch::Matchers::WithinAbs(1, 1e-12)); + REQUIRE_THAT(c2b->calc_prime(2.0), + Catch::Matchers::WithinAbs(0, 1e-12)); + + REQUIRE_THAT(c2b->calc(3.0), + Catch::Matchers::WithinAbs(0.3454915028, 1e-10)); + REQUIRE_THAT(c2b->calc_prime(3.0), + Catch::Matchers::WithinAbs(-1.4939160824, 1e-10)); + delete c2b; +} diff --git a/tests/test_d2.cpp b/tests/test_d2.cpp index 7991eaa4e5885a57ee3989dab1f3d1c35ec8f494..84faae1792def1f4ed44f0dec4f6747da653d05a 100644 --- a/tests/test_d2.cpp +++ b/tests/test_d2.cpp @@ -1,23 +1,29 @@ #include "catch2/catch.hpp" #include <tadah/models/descriptors/d2/d2_all.h> #include <tadah/core/maths.h> +#include <tadah/core/periodic_table.h> #include <tadah/models/cutoffs.h> template<typename D, typename C> void test_d2(Config &c, double r) { - std::streambuf *orig = std::cout.rdbuf(); + // std::streambuf *orig = std::cout.rdbuf(); std::stringstream ss; - std::cout.rdbuf (ss.rdbuf()); // redirect cout + // std::cout.rdbuf (ss.rdbuf()); // redirect cout + c.add("TYPE2B","H"); + c.add("TYPE2B","H"); + std::cout << c << std::endl; D d(c); - std::cout.rdbuf (orig); // restore + // std::cout.rdbuf (orig); // restore double rcut = c.get<double>("RCUT2B"); + // d.init_for_atoms(1,1); C fc(rcut); - aed_type2 aed(d.size()); - d.calc_aed(r,r*r,fc.calc(r),aed); + d.set_fcut(&fc, false); + aed_type aed(d.size()); + d.calc_aed(1,1,r,r*r,aed); fd_type fd(d.size()); - d.calc_dXijdri(r,r*r,fc.calc(r),fc.calc_prime(r),fd); + d.calc_dXijdri(1,1,r,r*r,fd); fd_type fda(d.size()); - d.calc_fd_approx(&fc, r, fda, 1e-6); + d.calc_fd_approx(1,1, r, fda, 1e-6); // Convert to std::vector, as catch2 matchers require these std::vector<double> fx(fd[0].data(),fd[0].data()+fd[0].size()); @@ -36,9 +42,9 @@ void test_d2(Config &c, double r) { REQUIRE_THAT(fya, Catch::Matchers::Approx(fy)); REQUIRE_THAT(fza, Catch::Matchers::Approx(fz)); - aed_type2 aed2(d.size()); + aed_type aed2(d.size()); fd_type fd2(d.size()); - d.calc_all(r,r*r,fc.calc(r),fc.calc_prime(r),aed2,fd2); + d.calc_all(1,1,r,r*r,aed2,fd2); std::vector<double> fx2(fd2[0].data(),fd2[0].data()+fd2[0].size()); std::vector<double> fy2(fd2[1].data(),fd2[1].data()+fd2[1].size()); std::vector<double> fz2(fd2[2].data(),fd2[2].data()+fd2[2].size()); @@ -50,11 +56,13 @@ void test_d2(Config &c, double r) { template<typename D> void test_D2(Config &c) { - std::streambuf *orig = std::cout.rdbuf(); + // std::streambuf *orig = std::cout.rdbuf(); std::stringstream ss; - std::cout.rdbuf (ss.rdbuf()); // redirect cout + // std::cout.rdbuf (ss.rdbuf()); // redirect cout c.remove("VERBOSE"); c.add("VERBOSE", 1); + c.add("ATOMS", "H"); + c.add("WATOMS", 1); // We cannot test r=rcut as finite difference will fail // but we can test r slightly smaller than rcut std::vector<double> rs = {2,2.0001,2.0123,5,11}; @@ -73,143 +81,213 @@ void test_D2(Config &c) { Config c2; // INIT2B=false D d(c2); REQUIRE(d.size()==0); - std::cout.rdbuf (orig); // restore + // std::cout.rdbuf (orig); // restore } -TEST_CASE( "Testing D2_Dummy", "[D2]" ) { - Config c; - double rcut=5.1; - c.remove("INIT2B"); - c.add("INIT2B", "true"); - c.add("RCUT2B", rcut); - test_d2<D2_Dummy,Cut_Dummy>(c,1); +// Fixture for initialization +struct TestFixture { + TestFixture() { + PeriodicTable::initialize(); + } +}; + +TEST_CASE_METHOD(TestFixture, "Testing D2_Dummy", "[D2]") { + Config c; + double rcut = 5.1; + c.remove("INIT2B"); + c.add("INIT2B", "true"); + c.add("RCUT2B", rcut); + test_d2<D2_Dummy, Cut_Dummy>(c, 1); - REQUIRE_NOTHROW(D2_Dummy()); - REQUIRE(D2_Dummy().label()=="D2_Dummy"); + REQUIRE_NOTHROW(D2_Dummy()); + REQUIRE(D2_Dummy().label() == "D2_Dummy"); } -TEST_CASE( "Testing D2_LJ", "[D2]" ) { - Config c; - c.remove("INIT2B"); - c.add("INIT2B", "true"); - test_D2<D2_LJ>(c); - - D2_LJ d(c); - REQUIRE(d.size()==2); - REQUIRE(d.label()=="D2_LJ"); + +TEST_CASE_METHOD(TestFixture, "Testing D2_LJ", "[D2]") { + Config c; + c.remove("INIT2B"); + c.add("INIT2B", "true"); + c.add("TYPE2B", "D2_LJ"); + test_D2<D2_LJ>(c); + + D2_LJ d(c); + REQUIRE(d.size() == 2); + REQUIRE(d.label() == "D2_LJ"); } -TEST_CASE( "Testing D2_BLIP", "[D2]" ) { - std::streambuf *orig = std::cout.rdbuf(); - std::stringstream ss; - std::cout.rdbuf (ss.rdbuf()); // redirect cout - using D = D2_Blip; - Config c; - c.remove("INIT2B"); - c.add("INIT2B", "true"); - c.add("SGRID2B","0.01 0.4 5.6"); - c.add("CGRID2B","0.0 1.2 3.4"); - test_D2<D>(c); - D d(c); - REQUIRE(d.size()==3); - REQUIRE(d.label()=="D2_Blip"); - - // test throws - c.remove("SGRID2B"); - c.remove("CGRID2B"); - c.add("SGRID2B","0.4 5.6"); - c.add("CGRID2B","0.0 1.2 3.4"); - REQUIRE_THROWS(D(c)); - c.remove("SGRID2B"); - c.remove("CGRID2B"); - c.add("SGRID2B","0.4 5.6"); - c.add("CGRID2B","0.0"); - REQUIRE_THROWS(D(c)); - - c.remove("SGRID2B"); - c.remove("CGRID2B"); - c.add("SGRID2B","0.0 0.4 5.6"); - c.add("CGRID2B","0.0 1.2 3.4"); - REQUIRE_THROWS(D(c)); - std::cout.rdbuf (orig); // restore + +TEST_CASE_METHOD(TestFixture, "Testing D2_BLIP", "[D2]") { + // std::streambuf *orig = std::cout.rdbuf(); + std::stringstream ss; + // std::cout.rdbuf(ss.rdbuf()); // redirect cout + using D = D2_Blip; + + Config c; + c.remove("INIT2B"); + c.add("INIT2B", "true"); + c.add("SGRID2B", "0.01 0.4 5.6"); + c.add("CGRID2B", "0.0 1.2 3.4"); + c.add("TYPE2B", "D2_Blip"); + c.add("TYPE2B", 3); + c.add("TYPE2B", 3); + test_D2<D>(c); + + D d(c); + REQUIRE(d.size() == 3); + REQUIRE(d.label() == "D2_Blip"); + + // Test throws + c.remove("SGRID2B"); + c.remove("CGRID2B"); + c.add("SGRID2B", "0.4 5.6"); + c.add("CGRID2B", "0.0 1.2 3.4"); + REQUIRE_THROWS(D(c)); + + c.remove("SGRID2B"); + c.remove("CGRID2B"); + c.add("SGRID2B", "0.4 5.6"); + c.add("CGRID2B", "0.0"); + REQUIRE_THROWS(D(c)); + + c.remove("SGRID2B"); + c.remove("CGRID2B"); + c.add("SGRID2B", "0.0 0.4 5.6"); + c.add("CGRID2B", "0.0 1.2 3.4"); + REQUIRE_THROWS(D(c)); + + // std::cout.rdbuf(orig); // restore } -TEST_CASE( "Testing D2_BP", "[D2]" ) { - std::streambuf *orig = std::cout.rdbuf(); - std::stringstream ss; - std::cout.rdbuf (ss.rdbuf()); // redirect cout - using D = D2_BP; - Config c; - c.remove("INIT2B"); - c.add("INIT2B", "true"); - c.add("SGRID2B","0.01 0.4"); - c.add("CGRID2B","0.0 1.2"); - test_D2<D>(c); - D d(c); - REQUIRE(d.size()==2); - REQUIRE(d.label()=="D2_BP"); - // test throws - c.remove("SGRID2B"); - c.remove("CGRID2B"); - c.add("SGRID2B","0.4 5.6"); - c.add("CGRID2B","0.0 1.2 3.4"); - REQUIRE_THROWS(D(c)); - c.remove("SGRID2B"); - c.remove("CGRID2B"); - c.add("SGRID2B","0.4 5.6"); - c.add("CGRID2B","0.0"); - REQUIRE_THROWS(D(c)); - - c.remove("SGRID2B"); - c.remove("CGRID2B"); - c.add("SGRID2B","0.0 0.4"); - c.add("CGRID2B","0.0 1.2"); - REQUIRE_THROWS(D(c)); - std::cout.rdbuf (orig); // restore + +TEST_CASE_METHOD(TestFixture, "Testing D2_BP", "[D2]") { + // std::streambuf *orig = std::cout.rdbuf(); + std::stringstream ss; + // std::cout.rdbuf(ss.rdbuf()); // redirect cout + using D = D2_BP; + + Config c; + c.remove("INIT2B"); + c.add("INIT2B", "true"); + c.add("SGRID2B", "0.01 0.4"); + c.add("CGRID2B", "0.0 1.2"); + c.add("TYPE2B", "D2_BP"); + c.add("TYPE2B", 2); + c.add("TYPE2B", 2); + test_D2<D>(c); + + D d(c); + REQUIRE(d.size() == 2); + REQUIRE(d.label() == "D2_BP"); + + // Test throws + c.remove("SGRID2B"); + c.remove("CGRID2B"); + c.add("SGRID2B", "0.4 5.6"); + c.add("CGRID2B", "0.0 1.2 3.4"); + REQUIRE_THROWS(D(c)); + + c.remove("SGRID2B"); + c.remove("CGRID2B"); + c.add("SGRID2B", "0.4 5.6"); + c.add("CGRID2B", "0.0"); + REQUIRE_THROWS(D(c)); + + c.remove("SGRID2B"); + c.remove("CGRID2B"); + c.add("SGRID2B", "0.0 0.4"); + c.add("CGRID2B", "0.0 1.2"); + REQUIRE_THROWS(D(c)); + + // std::cout.rdbuf(orig); // restore } -TEST_CASE( "Testing D2_EAM", "[D2]" ) { - std::streambuf *orig = std::cout.rdbuf(); - std::stringstream ss; - std::cout.rdbuf (ss.rdbuf()); // redirect cout - Config c; - c.remove("INIT2B"); - c.add("INIT2B", "true"); - c.add("SETFL","tests_data/eam.alloy"); - test_D2<D2_EAM>(c); - D2_EAM d(c); - REQUIRE(d.size()==1); - REQUIRE(d.label()=="D2_EAM"); - - // thors - Config c_err; - c_err.remove("INIT2B"); - c_err.add("INIT2B", "true"); - c_err.add("SETFL","path/to/nowhere"); - REQUIRE_THROWS(D2_EAM(c_err)); - std::cout.rdbuf (orig); // restore + +TEST_CASE_METHOD(TestFixture, "Testing D2_EAM", "[D2]") { + // std::streambuf *orig = std::cout.rdbuf(); + std::stringstream ss; + // std::cout.rdbuf(ss.rdbuf()); // redirect cout + + Config c; + c.remove("INIT2B"); + c.add("INIT2B", "true"); + c.add("SETFL", "tests_data/eam.alloy"); + test_D2<D2_EAM>(c); + + D2_EAM d(c); + REQUIRE(d.size() == 1); + REQUIRE(d.label() == "D2_EAM"); + + // Test throws + Config c_err; + c_err.remove("INIT2B"); + c_err.add("INIT2B", "true"); + c_err.add("SETFL", "path/to/nowhere"); + REQUIRE_THROWS(D2_EAM(c_err)); + + // std::cout.rdbuf(orig); // restore } -TEST_CASE( "Testing D2_MIE", "[D2]" ) { - Config c; - c.remove("INIT2B"); - c.add("INIT2B", "true"); - c.add("SGRID2B","7 13"); - test_D2<D2_MIE>(c); - D2_MIE d(c); - REQUIRE(d.size()==2); - REQUIRE(d.label()=="D2_MIE"); - - // test throws - c.remove("SGRID2B"); - c.add("SGRID2B","7"); - REQUIRE_THROWS(D2_MIE(c)); - - c.remove("SGRID2B"); - c.add("SGRID2B","7 8 9"); - REQUIRE_THROWS(D2_MIE(c)); - - c.remove("SGRID2B"); - c.add("SGRID2B","-8 9"); - REQUIRE_THROWS(D2_MIE(c)); - - c.remove("SGRID2B"); - c.add("SGRID2B","8 -9"); - REQUIRE_THROWS(D2_MIE(c)); + +TEST_CASE_METHOD(TestFixture, "Testing D2_MIE", "[D2]") { + Config c; + c.remove("INIT2B"); + c.add("INIT2B", "true"); + c.add("TYPE2B", "D2_MIE"); + c.add("TYPE2B", 7); + c.add("TYPE2B", 13); + test_D2<D2_MIE>(c); + + D2_MIE d(c); + REQUIRE(d.size() == 2); + REQUIRE(d.label() == "D2_MIE"); + + // Test throws + c.remove("TYPE2B"); + c.add("TYPE2B", "D2_MIE"); + c.add("TYPE2B", 7); + REQUIRE_THROWS(D2_MIE(c)); + + c.remove("TYPE2B"); + c.add("TYPE2B", "D2_MIE"); + c.add("TYPE2B", 7); + c.add("TYPE2B", -8); + REQUIRE_THROWS(D2_MIE(c)); + + c.remove("TYPE2B"); + c.add("TYPE2B", "D2_MIE"); + c.add("TYPE2B", -7); + c.add("TYPE2B", 8); + REQUIRE_THROWS(D2_MIE(c)); + +} +TEST_CASE_METHOD(TestFixture, "Testing D2_ZBL", "[D2]") { + Config c; + c.remove("INIT2B"); + c.add("INIT2B", "true"); + c.add("TYPE2B", "D2_ZBL"); + c.add("TYPE2B", -1); + c.add("TYPE2B", -1); + c.add("TYPE2B", -1); + c.add("TYPE2B", -1); + test_D2<D2_ZBL>(c); + + D2_ZBL d(c); + REQUIRE(d.size() == 1); + REQUIRE(d.label() == "D2_ZBL"); + + // Test throws + c.remove("TYPE2B"); + c.add("TYPE2B", "D2_ZBL"); + c.add("TYPE2B", 7); + REQUIRE_THROWS(D2_ZBL(c)); + + c.remove("TYPE2B"); + c.add("TYPE2B", "D2_ZBL"); + c.add("TYPE2B", -7); + c.add("TYPE2B", -8); + REQUIRE_THROWS(D2_ZBL(c)); + + c.remove("TYPE2B"); + c.add("TYPE2B", "D2_ZBL"); + c.add("TYPE2B", 7); + c.add("TYPE2B", 8); + c.add("TYPE2B", 9); + REQUIRE_THROWS(D2_ZBL(c)); } diff --git a/tests/test_d3.cpp b/tests/test_d3.cpp index a0927942b17955b69a4432479177efd668f53ad8..c8327eb67166aaf0641f5bc73c554ca269fa1dee 100644 --- a/tests/test_d3.cpp +++ b/tests/test_d3.cpp @@ -13,7 +13,7 @@ TEST_CASE( "Testing D3_Dummy", "[D3]" ) { D3_Dummy d(c); REQUIRE(d.size()==0); REQUIRE(d.label()=="D3_Dummy"); - aed_type2 aed; + aed_type aed; fd_type fd; REQUIRE_NOTHROW(d.calc_aed(0,0,0,0,0,aed)); REQUIRE_NOTHROW(d.calc_all(0,0,0,0,0,0.0,0.0,aed,fd)); diff --git a/tests/test_dm.cpp b/tests/test_dm.cpp index 268f72e8b38763b0baebe7dc75df49758f6ab273..1800b4c1e71cb3c58f56ddea67cc212bb0111df0 100644 --- a/tests/test_dm.cpp +++ b/tests/test_dm.cpp @@ -6,8 +6,8 @@ #include <cmath> #include <vector> -template <typename DM, typename CUT> -void central_difference_mb(DM *dm, CUT *fc, std::vector<Vec3d> &positions, +template <typename DM> +void central_difference_mb(DM *dm, std::vector<Vec3d> &positions, size_t j, fd_type &fdij, double h=1e-10) { //size_t i=0; @@ -30,22 +30,22 @@ void central_difference_mb(DM *dm, CUT *fc, std::vector<Vec3d> &positions, Vec3d del12n = x1-xjn; Vec3d del12p = x1-xjp; - aed_type2 rhoip; - aed_type2 rhoin; + aed_type rhoip; + aed_type rhoin; dm->init_rhoi(rhoip); dm->init_rhoi(rhoin); - dm->calc_rho_mb(del12p, rhoip,fc->calc(std::sqrt(del12p*del12p))); - dm->calc_rho_mb(del13, rhoip,fc->calc(std::sqrt(del13*del13))); - dm->calc_rho_mb(del14, rhoip,fc->calc(std::sqrt(del14*del14))); + dm->calc_rho_mb(1,1,del12p, rhoip); + dm->calc_rho_mb(1,1,del13, rhoip); + dm->calc_rho_mb(1,1,del14, rhoip); - dm->calc_rho_mb(del12n, rhoin,fc->calc(std::sqrt(del12n*del12n))); - dm->calc_rho_mb(del13, rhoin ,fc->calc(std::sqrt(del13*del13))); - dm->calc_rho_mb(del14, rhoin ,fc->calc(std::sqrt(del14*del14))); + dm->calc_rho_mb(1,1,del12n, rhoin); + dm->calc_rho_mb(1,1,del13, rhoin ); + dm->calc_rho_mb(1,1,del14, rhoin ); - aed_type2 aedip(fdij.rows()); - aed_type2 aedin(fdij.rows()); + aed_type aedip(fdij.rows()); + aed_type aedin(fdij.rows()); aedip.set_zero(); aedin.set_zero(); dm->calc_aed(rhoip, aedip); @@ -59,6 +59,10 @@ template<typename DM, typename CUT> void test_case(Config &config_mb, std::string label, size_t size) { + config_mb.add("ATOMS", "H"); + config_mb.add("WATOMS", 1); + config_mb.add("TYPEMB", "H"); + config_mb.add("TYPEMB", "H"); // Define a simple system of 4 atoms // Will calculate forces acting on the first atom Vec3d x1(0.0,0.0,0.0); @@ -67,56 +71,35 @@ void test_case(Config &config_mb, Vec3d x4(-4.11,5.33,-3.44); std::vector<Vec3d> positions = {x1,x2,x3,x4}; - Vec3d del12 = x1-x2; - Vec3d del13 = x1-x3; - Vec3d del14 = x1-x4; - - Vec3d del21 = x2-x1; - Vec3d del23 = x2-x3; - Vec3d del24 = x2-x4; - - Vec3d del31 = x3-x1; - Vec3d del32 = x3-x2; - Vec3d del34 = x3-x4; - - Vec3d del41 = x4-x1; - Vec3d del42 = x4-x2; - Vec3d del43 = x4-x3; - - double rsq12 = del12*del12; - double rsq13 = del13*del13; - double rsq14 = del14*del14; - double r12 = sqrt(rsq12); - double r13 = sqrt(rsq13); - double r14 = sqrt(rsq14); - - double rsq21 = del21*del21; - double rsq23 = del23*del23; - double rsq24 = del24*del24; - double r21 = sqrt(rsq21); - double r23 = sqrt(rsq23); - double r24 = sqrt(rsq24); - - double rsq31 = del31*del31; - double rsq32 = del32*del32; - double rsq34 = del34*del34; - double r31 = sqrt(rsq31); - double r32 = sqrt(rsq32); - double r34 = sqrt(rsq34); - - double rsq41 = del41*del41; - double rsq42 = del42*del42; - double rsq43 = del43*del43; - double r41 = sqrt(rsq41); - double r42 = sqrt(rsq42); - double r43 = sqrt(rsq43); + Vec3d del12 = x1-x2; Vec3d del21 = x2-x1; + Vec3d del13 = x1-x3; Vec3d del23 = x2-x3; + Vec3d del14 = x1-x4; Vec3d del24 = x2-x4; + + Vec3d del31 = x3-x1; Vec3d del41 = x4-x1; + Vec3d del32 = x3-x2; Vec3d del42 = x4-x2; + Vec3d del34 = x3-x4; Vec3d del43 = x4-x3; + + double rsq12 = del12*del12; double rsq21 = del21*del21; + double rsq13 = del13*del13; double rsq23 = del23*del23; + double rsq14 = del14*del14; double rsq24 = del24*del24; + double r12 = sqrt(rsq12); double r21 = sqrt(rsq21); + double r13 = sqrt(rsq13); double r23 = sqrt(rsq23); + double r14 = sqrt(rsq14); double r24 = sqrt(rsq24); + + double rsq31 = del31*del31; double rsq41 = del41*del41; + double rsq32 = del32*del32; double rsq42 = del42*del42; + double rsq34 = del34*del34; double rsq43 = del43*del43; + double r31 = sqrt(rsq31); double r41 = sqrt(rsq41); + double r32 = sqrt(rsq32); double r42 = sqrt(rsq42); + double r34 = sqrt(rsq34); double r43 = sqrt(rsq43); CUT fc(config_mb.get<double>("RCUTMB")); DM dm(config_mb); - aed_type2 aed1(dm.size()); - aed_type2 aed2(dm.size()); - aed_type2 aed3(dm.size()); - aed_type2 aed4(dm.size()); + dm.set_fcut(&fc,false); + aed_type aed1(dm.size()); + aed_type aed2(dm.size()); + aed_type aed3(dm.size()); + aed_type aed4(dm.size()); aed1.set_zero(); aed2.set_zero(); aed3.set_zero(); @@ -166,43 +149,42 @@ void test_case(Config &config_mb, dm.init_rhoi(rho3); dm.init_rhoi(rho4); - dm.calc_rho_mb(del12, rho1,fc.calc(r12)); - dm.calc_rho_mb(del13, rho1,fc.calc(r13)); - dm.calc_rho_mb(del14, rho1,fc.calc(r14)); + dm.calc_rho_mb(1,1,del12, rho1); + dm.calc_rho_mb(1,1,del13, rho1); + dm.calc_rho_mb(1,1,del14, rho1); - dm.calc_rho_mb(del21, rho2,fc.calc(r21)); - dm.calc_rho_mb(del23, rho2,fc.calc(r23)); - dm.calc_rho_mb(del24, rho2,fc.calc(r24)); + dm.calc_rho_mb(1,1,del21, rho2); + dm.calc_rho_mb(1,1,del23, rho2); + dm.calc_rho_mb(1,1,del24, rho2); - dm.calc_rho_mb(del31, rho3,fc.calc(r31)); - dm.calc_rho_mb(del32, rho3,fc.calc(r32)); - dm.calc_rho_mb(del34, rho3,fc.calc(r34)); + dm.calc_rho_mb(1,1,del31, rho3); + dm.calc_rho_mb(1,1,del32, rho3); + dm.calc_rho_mb(1,1,del34, rho3); - dm.calc_rho_mb(del41, rho4,fc.calc(r41)); - dm.calc_rho_mb(del42, rho4,fc.calc(r42)); - dm.calc_rho_mb(del43, rho4,fc.calc(r43)); + dm.calc_rho_mb(1,1,del41, rho4); + dm.calc_rho_mb(1,1,del42, rho4); + dm.calc_rho_mb(1,1,del43, rho4); dm.calc_aed(rho1,aed1); dm.calc_aed(rho2,aed2); dm.calc_aed(rho3,aed3); dm.calc_aed(rho4,aed4); - int mode = - dm.calc_dXijdri(r12,rsq12,del12,fc.calc(r12),fc.calc_prime(r12),rho1,fd12); - dm.calc_dXijdri(r13,rsq13,del13,fc.calc(r13),fc.calc_prime(r13),rho1,fd13); - dm.calc_dXijdri(r14,rsq14,del14,fc.calc(r14),fc.calc_prime(r14),rho1,fd14); + dm.calc_dXijdri(1,1,r12,rsq12,del12,rho1,fd12); + dm.calc_dXijdri(1,1,r13,rsq13,del13,rho1,fd13); + dm.calc_dXijdri(1,1,r14,rsq14,del14,rho1,fd14); - dm.calc_dXijdri(r21,rsq21,del21,fc.calc(r21),fc.calc_prime(r21),rho2,fd21); - dm.calc_dXijdri(r23,rsq23,del23,fc.calc(r23),fc.calc_prime(r23),rho2,fd23); - dm.calc_dXijdri(r24,rsq24,del24,fc.calc(r24),fc.calc_prime(r24),rho2,fd24); + dm.calc_dXijdri(1,1,r21,rsq21,del21,rho2,fd21); + dm.calc_dXijdri(1,1,r23,rsq23,del23,rho2,fd23); + dm.calc_dXijdri(1,1,r24,rsq24,del24,rho2,fd24); - dm.calc_dXijdri(r31,rsq31,del31,fc.calc(r31),fc.calc_prime(r31),rho3,fd31); - dm.calc_dXijdri(r32,rsq32,del32,fc.calc(r32),fc.calc_prime(r32),rho3,fd32); - dm.calc_dXijdri(r34,rsq34,del34,fc.calc(r34),fc.calc_prime(r34),rho3,fd34); + dm.calc_dXijdri(1,1,r31,rsq31,del31,rho3,fd31); + dm.calc_dXijdri(1,1,r32,rsq32,del32,rho3,fd32); + dm.calc_dXijdri(1,1,r34,rsq34,del34,rho3,fd34); - dm.calc_dXijdri(r41,rsq41,del41,fc.calc(r41),fc.calc_prime(r41),rho4,fd41); - dm.calc_dXijdri(r42,rsq42,del42,fc.calc(r42),fc.calc_prime(r42),rho4,fd42); - dm.calc_dXijdri(r43,rsq43,del43,fc.calc(r43),fc.calc_prime(r43),rho4,fd43); + dm.calc_dXijdri(1,1,r41,rsq41,del41,rho4,fd41); + dm.calc_dXijdri(1,1,r42,rsq42,del42,rho4,fd42); + dm.calc_dXijdri(1,1,r43,rsq43,del43,rho4,fd43); fd_type FD12(dm.size()); fd_type FD13(dm.size()); @@ -235,33 +217,21 @@ void test_case(Config &config_mb, FD41.set_zero(); FD42.set_zero(); FD43.set_zero(); - dm.calc_dXijdri_dXjidri(r12,rsq12,del12,fc.calc(r12),fc.calc_prime(r12), - rho1,rho2,FD12,1,1); - dm.calc_dXijdri_dXjidri(r13,rsq13,del13,fc.calc(r13),fc.calc_prime(r13), - rho1,rho3,FD13,1,1); - dm.calc_dXijdri_dXjidri(r14,rsq14,del14,fc.calc(r14),fc.calc_prime(r14), - rho1,rho4,FD14,1,1); - - dm.calc_dXijdri_dXjidri(r21,rsq21,del21,fc.calc(r21),fc.calc_prime(r21), - rho2,rho1,FD21,1,1); - dm.calc_dXijdri_dXjidri(r23,rsq23,del23,fc.calc(r23),fc.calc_prime(r23), - rho2,rho3,FD23,1,1); - dm.calc_dXijdri_dXjidri(r24,rsq24,del24,fc.calc(r24),fc.calc_prime(r24), - rho2,rho4,FD24,1,1); - - dm.calc_dXijdri_dXjidri(r31,rsq31,del31,fc.calc(r31),fc.calc_prime(r31), - rho3,rho1,FD31,1,1); - dm.calc_dXijdri_dXjidri(r32,rsq32,del32,fc.calc(r32),fc.calc_prime(r32), - rho3,rho2,FD32,1,1); - dm.calc_dXijdri_dXjidri(r34,rsq34,del34,fc.calc(r34),fc.calc_prime(r34), - rho3,rho4,FD34,1,1); - - dm.calc_dXijdri_dXjidri(r41,rsq41,del41,fc.calc(r41),fc.calc_prime(r41), - rho4,rho1,FD41,1,1); - dm.calc_dXijdri_dXjidri(r42,rsq42,del42,fc.calc(r42),fc.calc_prime(r42), - rho4,rho2,FD42,1,1); - dm.calc_dXijdri_dXjidri(r43,rsq43,del43,fc.calc(r43),fc.calc_prime(r43), - rho4,rho3,FD43,1,1); + dm.calc_dXijdri_dXjidri(1,1,r12,rsq12,del12,rho1,rho2,FD12,1); + dm.calc_dXijdri_dXjidri(1,1,r13,rsq13,del13,rho1,rho3,FD13,1); + dm.calc_dXijdri_dXjidri(1,1,r14,rsq14,del14,rho1,rho4,FD14,1); + + dm.calc_dXijdri_dXjidri(1,1,r21,rsq21,del21,rho2,rho1,FD21,1); + dm.calc_dXijdri_dXjidri(1,1,r23,rsq23,del23,rho2,rho3,FD23,1); + dm.calc_dXijdri_dXjidri(1,1,r24,rsq24,del24,rho2,rho4,FD24,1); + + dm.calc_dXijdri_dXjidri(1,1,r31,rsq31,del31,rho3,rho1,FD31,1); + dm.calc_dXijdri_dXjidri(1,1,r32,rsq32,del32,rho3,rho2,FD32,1); + dm.calc_dXijdri_dXjidri(1,1,r34,rsq34,del34,rho3,rho4,FD34,1); + + dm.calc_dXijdri_dXjidri(1,1,r41,rsq41,del41,rho4,rho1,FD41,1); + dm.calc_dXijdri_dXjidri(1,1,r42,rsq42,del42,rho4,rho2,FD42,1); + dm.calc_dXijdri_dXjidri(1,1,r43,rsq43,del43,rho4,rho3,FD43,1); REQUIRE(FD12.isApprox(fd12-fd21,1e-6)); REQUIRE(FD13.isApprox(fd13-fd31,1e-6)); @@ -279,25 +249,6 @@ void test_case(Config &config_mb, REQUIRE(FD42.isApprox(fd42-fd24,1e-6)); REQUIRE(FD43.isApprox(fd43-fd34,1e-6)); - // Do scalling just before approximation - if (mode==0) { - fd12[0] *= del12[0]/r12; - fd13[0] *= del13[0]/r13; - fd14[0] *= del14[0]/r14; - - fd21[0] *= del21[0]/r21; - fd23[0] *= del23[0]/r23; - fd24[0] *= del24[0]/r24; - - fd31[0] *= del31[0]/r31; - fd32[0] *= del32[0]/r32; - fd34[0] *= del34[0]/r34; - - fd41[0] *= del41[0]/r41; - fd42[0] *= del42[0]/r42; - fd43[0] *= del43[0]/r43; - } - // Calculate approximation fd_type fd12a(dm.size()); fd_type fd13a(dm.size()); @@ -306,9 +257,9 @@ void test_case(Config &config_mb, fd13a.set_zero(); fd14a.set_zero(); double margin=1e-5; - central_difference_mb(&dm,&fc,positions, 1, fd12a, 1e-8); - central_difference_mb(&dm,&fc,positions, 2, fd13a, 1e-8); - central_difference_mb(&dm,&fc,positions, 3, fd14a, 1e-8); + central_difference_mb(&dm,positions, 1, fd12a, 1e-8); + central_difference_mb(&dm,positions, 2, fd13a, 1e-8); + central_difference_mb(&dm,positions, 3, fd14a, 1e-8); std::vector<double> fx12(fd12[0].data(),fd12[0].data()+fd12[0].size()); std::vector<double> fy12(fd12[1].data(),fd12[1].data()+fd12[1].size()); @@ -343,117 +294,149 @@ void test_case(Config &config_mb, REQUIRE(dm.label() == label); REQUIRE(dm.size() == size); } -TEST_CASE( "Testing DM_EAD 1", "[DM]" ) { - Config config_mb; - config_mb.add("RCUTMB",10); - config_mb.remove("INITMB"); - config_mb.add("INITMB","true"); - config_mb.add("AGRIDMB","2"); - config_mb.add("CGRIDMB","1 2"); - config_mb.add("SGRIDMB","0.1 0.2"); - test_case<DM_EAD,Cut_Dummy>(config_mb, "DM_EAD", 3*2); - test_case<DM_EAD,Cut_Cos>(config_mb, "DM_EAD", 3*2); - test_case<DM_EAD,Cut_Tanh>(config_mb, "DM_EAD", 3*2); - test_case<DM_EAD,Cut_Poly2>(config_mb, "DM_EAD", 3*2); + +// Fixture to initialize the PeriodicTable +struct TestFixture { + TestFixture() { + PeriodicTable::initialize(); + } +}; +TEST_CASE_METHOD(TestFixture, "Testing DM_EAD 1", "[DM]") { + Config config_mb; + config_mb.add("RCUTMB", 10); + config_mb.remove("INITMB"); + config_mb.add("INITMB", "true"); + config_mb.add("TYPEMB", "DM_EAD"); + config_mb.add("TYPEMB", 2); + config_mb.add("TYPEMB", 2); + config_mb.add("TYPEMB", 2); + config_mb.add("CGRIDMB", "1 2"); + config_mb.add("SGRIDMB", "0.1 0.2"); + test_case<DM_EAD, Cut_Dummy>(config_mb, "DM_EAD", 3 * 2); + test_case<DM_EAD, Cut_Cos>(config_mb, "DM_EAD", 3 * 2); + test_case<DM_EAD, Cut_Tanh>(config_mb, "DM_EAD", 3 * 2); + test_case<DM_EAD, Cut_Poly2>(config_mb, "DM_EAD", 3 * 2); } -TEST_CASE( "Testing DM_EAD 2", "[DM]" ) { - Config config_mb; - config_mb.add("RCUTMB",6); - config_mb.remove("INITMB"); - config_mb.add("INITMB","true"); - config_mb.add("AGRIDMB","3"); - config_mb.add("CGRIDMB","1 2 3"); - config_mb.add("SGRIDMB","0.1 0.2 0.9"); - test_case<DM_EAD,Cut_Dummy>(config_mb, "DM_EAD", 4*3); - test_case<DM_EAD,Cut_Cos>(config_mb, "DM_EAD", 4*3); - test_case<DM_EAD,Cut_Tanh>(config_mb, "DM_EAD", 4*3); - test_case<DM_EAD,Cut_Poly2>(config_mb, "DM_EAD", 4*3); + +TEST_CASE_METHOD(TestFixture, "Testing DM_EAD 2", "[DM]") { + Config config_mb; + config_mb.add("RCUTMB", 6); + config_mb.remove("INITMB"); + config_mb.add("INITMB", "true"); + config_mb.add("TYPEMB", "DM_EAD"); + config_mb.add("TYPEMB", 3); + config_mb.add("TYPEMB", 3); + config_mb.add("TYPEMB", 3); + config_mb.add("CGRIDMB", "1 2 3"); + config_mb.add("SGRIDMB", "0.1 0.2 0.9"); + test_case<DM_EAD, Cut_Dummy>(config_mb, "DM_EAD", 4 * 3); + test_case<DM_EAD, Cut_Cos>(config_mb, "DM_EAD", 4 * 3); + test_case<DM_EAD, Cut_Tanh>(config_mb, "DM_EAD", 4 * 3); + test_case<DM_EAD, Cut_Poly2>(config_mb, "DM_EAD", 4 * 3); } -TEST_CASE( "Testing DM_Blip 1", "[DM]" ) { - Config config_mb; - config_mb.add("RCUTMB",10); - config_mb.remove("INITMB"); - config_mb.add("INITMB","true"); - config_mb.add("AGRIDMB","2"); - config_mb.add("CGRIDMB","1 2"); - config_mb.add("SGRIDMB","0.1 0.2"); - test_case<DM_Blip,Cut_Dummy>(config_mb, "DM_Blip", 3*2); - test_case<DM_Blip,Cut_Cos>(config_mb, "DM_Blip", 3*2); - test_case<DM_Blip,Cut_Tanh>(config_mb, "DM_Blip", 3*2); - test_case<DM_Blip,Cut_Poly2>(config_mb, "DM_Blip", 3*2); + +TEST_CASE_METHOD(TestFixture, "Testing DM_Blip 1", "[DM]") { + Config config_mb; + config_mb.add("RCUTMB", 10); + config_mb.remove("INITMB"); + config_mb.add("INITMB", "true"); + config_mb.add("TYPEMB", "DM_Blip"); + config_mb.add("TYPEMB", 2); + config_mb.add("TYPEMB", 2); + config_mb.add("TYPEMB", 2); + config_mb.add("CGRIDMB", "1 2"); + config_mb.add("SGRIDMB", "0.1 0.2"); + test_case<DM_Blip, Cut_Dummy>(config_mb, "DM_Blip", 3 * 2); + test_case<DM_Blip, Cut_Cos>(config_mb, "DM_Blip", 3 * 2); + test_case<DM_Blip, Cut_Tanh>(config_mb, "DM_Blip", 3 * 2); + test_case<DM_Blip, Cut_Poly2>(config_mb, "DM_Blip", 3 * 2); } -TEST_CASE( "Testing DM_Blip 2", "[DM]" ) { - Config config_mb; - config_mb.add("RCUTMB",6); - config_mb.remove("INITMB"); - config_mb.add("INITMB","true"); - config_mb.add("AGRIDMB","3"); - config_mb.add("CGRIDMB","1 2 3"); - config_mb.add("SGRIDMB","0.1 0.2 0.9"); - test_case<DM_Blip,Cut_Dummy>(config_mb, "DM_Blip", 4*3); - test_case<DM_Blip,Cut_Cos>(config_mb, "DM_Blip", 4*3); - test_case<DM_Blip,Cut_Tanh>(config_mb, "DM_Blip", 4*3); - test_case<DM_Blip,Cut_Poly2>(config_mb, "DM_Blip", 4*3); + +TEST_CASE_METHOD(TestFixture, "Testing DM_Blip 2", "[DM]") { + Config config_mb; + config_mb.add("RCUTMB", 6); + config_mb.remove("INITMB"); + config_mb.add("INITMB", "true"); + config_mb.add("TYPEMB", "DM_Blip"); + config_mb.add("TYPEMB", 3); + config_mb.add("TYPEMB", 3); + config_mb.add("TYPEMB", 3); + config_mb.add("CGRIDMB", "1 2 3"); + config_mb.add("SGRIDMB", "0.1 0.2 0.9"); + test_case<DM_Blip, Cut_Dummy>(config_mb, "DM_Blip", 4 * 3); + test_case<DM_Blip, Cut_Cos>(config_mb, "DM_Blip", 4 * 3); + test_case<DM_Blip, Cut_Tanh>(config_mb, "DM_Blip", 4 * 3); + test_case<DM_Blip, Cut_Poly2>(config_mb, "DM_Blip", 4 * 3); } -TEST_CASE( "Testing DM_EAM 1", "[DM]" ) { - Config config_mb; - config_mb.add("RCUTMB",5.58190742024); - config_mb.remove("INITMB"); - config_mb.add("INITMB","true"); - config_mb.add("SETFL","tests_data/eam.alloy"); - test_case<DM_EAM,Cut_Dummy>(config_mb, "DM_EAM", 1); - - // throws - Config c_err; - c_err.remove("INITMB"); - c_err.add("INITMB", "true"); - c_err.add("SETFL","path/to/nowhere"); - REQUIRE_THROWS(DM_EAM(c_err)); + +TEST_CASE_METHOD(TestFixture, "Testing DM_EAM 1", "[DM]") { + Config config_mb; + config_mb.add("RCUTMB", 5.58190742024); + config_mb.remove("INITMB"); + config_mb.add("INITMB", "true"); + config_mb.add("TYPEMB", "DM_EAM"); + config_mb.add("TYPEMB", "tests_data/eam.alloy"); + test_case<DM_EAM, Cut_Dummy>(config_mb, "DM_EAM", 1); + + // Throws + Config c_err; + c_err.remove("INITMB"); + c_err.add("INITMB", "true"); + c_err.add("TYPEMB", "DM_EAM"); + c_err.add("TYPEMB", "path/to/nowhere"); + REQUIRE_THROWS(DM_EAM(c_err)); } -TEST_CASE( "Testing DM_EAM 2", "[DM]" ) { - Config config_mb; - config_mb.add("RCUTMB",5.58190742024); - config_mb.remove("INITMB"); - config_mb.add("INITMB","true"); - config_mb.add("SETFL","tests_data/eam.alloy"); - test_case<DM_EAM,Cut_Dummy>(config_mb, "DM_EAM", 1); + +TEST_CASE_METHOD(TestFixture, "Testing DM_EAM 2", "[DM]") { + Config config_mb; + config_mb.add("RCUTMB", 5.58190742024); + config_mb.remove("INITMB"); + config_mb.add("INITMB", "true"); + config_mb.add("TYPEMB", "DM_EAM"); + config_mb.add("TYPEMB", "tests_data/eam.alloy"); + test_case<DM_EAM, Cut_Dummy>(config_mb, "DM_EAM", 1); } -TEST_CASE( "Testing DM_Dummy 1", "[DM]" ) { - Config config_mb; - config_mb.add("RCUTMB",5.58190742024); - config_mb.remove("INITMB"); - config_mb.add("INITMB","true"); - config_mb.add("SETFL","tests_data/eam.alloy"); - test_case<DM_EAM,Cut_Dummy>(config_mb, "DM_EAM", 1); - - // throws - Config c_err; - c_err.remove("INITMB"); - c_err.add("INITMB", "true"); - c_err.add("SETFL","path/to/nowhere"); - REQUIRE_THROWS(DM_EAM(c_err)); + +TEST_CASE_METHOD(TestFixture, "Testing DM_EAM 3", "[DM]") { + Config config_mb; + config_mb.add("RCUTMB", 5.58190742024); + config_mb.remove("INITMB"); + config_mb.add("INITMB", "true"); + config_mb.add("TYPEMB", "DM_EAM"); + config_mb.add("TYPEMB", "tests_data/eam.alloy"); + test_case<DM_EAM, Cut_Dummy>(config_mb, "DM_EAM", 1); + + // Throws + Config c_err; + c_err.remove("INITMB"); + c_err.add("INITMB", "true"); + c_err.add("SETFL", "path/to/nowhere"); + REQUIRE_THROWS(DM_EAM(c_err)); } -TEST_CASE( "Testing DM_Dummy", "[DM]" ) { - Config c; - c.add("RCUTMB",5.58190742024); - c.remove("INITMB"); - c.add("INITMB","true"); - - REQUIRE_NOTHROW(DM_Dummy()); - REQUIRE_NOTHROW(DM_Dummy(c)); - - DM_Dummy d(c); - REQUIRE(d.size()==0); - REQUIRE(d.label()=="DM_Dummy"); - aed_type2 aed; - rho_type rho1; - fd_type fd; - Vec3d del; - REQUIRE_NOTHROW(d.calc_aed(rho1,aed)); - REQUIRE_NOTHROW(d.init_rhoi(rho1)); - REQUIRE_NOTHROW(d.calc_rho(0,0,0,del,rho1)); - REQUIRE_NOTHROW(d.calc_dXijdri(0,0,del,0,0,rho1,fd)); - REQUIRE_NOTHROW(d.calc_dXijdri_dXjidri(0,0,del,0,0,rho1,rho1,fd,1,1)); - REQUIRE(d.rhoi_size()==0); - REQUIRE(d.rhoip_size()==0); + +TEST_CASE_METHOD(TestFixture, "Testing DM_Dummy", "[DM]") { + Config c; + c.add("RCUTMB", 5.58190742024); + c.add("RCTYPEMB", "Cut_Cos"); + c.remove("INITMB"); + c.add("INITMB", "true"); + c.add("TYPEMB", "DM_Dummy"); + + REQUIRE_NOTHROW(DM_Dummy()); + REQUIRE_NOTHROW(DM_Dummy(c)); + + DM_Dummy d(c); + REQUIRE(d.size() == 0); + REQUIRE(d.label() == "DM_Dummy"); + aed_type aed; + rho_type rho1; + fd_type fd; + Vec3d del; + REQUIRE_NOTHROW(d.calc_aed(rho1, aed)); + REQUIRE_NOTHROW(d.init_rhoi(rho1)); + REQUIRE_NOTHROW(d.calc_rho(0,0, 0, 0, del, rho1)); + REQUIRE_NOTHROW(d.calc_dXijdri(1,1, 0, 0, del, rho1, fd)); + REQUIRE_NOTHROW(d.calc_dXijdri_dXjidri(1, 1, 0, 0, del, rho1, rho1, fd, 1)); + REQUIRE(d.rhoi_size() == 0); + REQUIRE(d.rhoip_size() == 0); } diff --git a/tests/test_factory_cutoffs.cpp b/tests/test_factory_cutoffs.cpp index 22e6a45a02e21e94fee71d27054eb8294ac5b5f1..2b19927b0722a5797634de870585a235bfedd7cd 100644 --- a/tests/test_factory_cutoffs.cpp +++ b/tests/test_factory_cutoffs.cpp @@ -36,5 +36,6 @@ TEST_CASE( "Testing Factory: Cutoffs", "[factory_cutoffs]" ) { REQUIRE( c2b->calc_prime(rcut2b) < std::numeric_limits<double>::min() ); REQUIRE( std::abs(c2b->get_rcut()-rcut2b)<std::numeric_limits<double>::min() ); REQUIRE( std::abs(c2b->get_rcut_sq()-rcut2bsq)<std::numeric_limits<double>::min() ); + if (c2b) delete c2b; }; } diff --git a/tests/test_factory_functions.cpp b/tests/test_factory_functions.cpp index 41704b1521be78f1f32ae636bb149a7cbdb8f6cd..191e2ed3bcb4afce94633c6b5a9d53b053785683 100644 --- a/tests/test_factory_functions.cpp +++ b/tests/test_factory_functions.cpp @@ -51,5 +51,6 @@ TEST_CASE( "Testing Factory: Functions", "[factory_functions]" ) { //REQUIRE( c2b->calc_prime(rcut2b) < std::numeric_limits<double>::min() ); //REQUIRE( std::abs(c2b->get_rcut()-rcut2b)<std::numeric_limits<double>::min() ); //REQUIRE( std::abs(c2b->get_rcut_sq()-rcut2bsq)<std::numeric_limits<double>::min() ); + if (fb) delete fb; } } diff --git a/tests/test_kernels.cpp b/tests/test_kernels.cpp index 5066d6ce0b41d30d1a55c789751327b6c3f44551..66271a75de4ba48f0505c53882caf25fbc4b371f 100644 --- a/tests/test_kernels.cpp +++ b/tests/test_kernels.cpp @@ -29,9 +29,9 @@ TEST_CASE( "Testing Kern_Base", "[kernels]" ) { REQUIRE(Kern_RBF().get_label()=="Kern_RBF"); REQUIRE(Kern_Sigmoid().get_label()=="Kern_Sigmoid"); - aed_type2 w(2); + aed_type w(2); w.random(123,-1e-1,1e-1); - aed_type2 aed(3); + aed_type aed(3); aed.random(993,-1e-1,1e-1); fd_type fd(3); fd.random(753,-1e-1,1e-1); @@ -65,8 +65,8 @@ TEST_CASE( "Testing Kern_Base", "[kernels]" ) { for(size_t i=0;i<2;++i) for(size_t j=0;j<3;++j) { - REQUIRE_THAT(matbas(i,j), - Catch::Matchers::WithinAbs(test_basis(i,j),1e-12)); + REQUIRE_THAT(matbas(j,i), + Catch::Matchers::WithinAbs(test_basis(j,i),1e-12)); } } TEST_CASE( "Testing Kern_Linear 1", "[kernels]" ) { @@ -74,9 +74,9 @@ TEST_CASE( "Testing Kern_Linear 1", "[kernels]" ) { Config c; REQUIRE_NOTHROW(K(c)); K kern; - aed_type2 w(4); + aed_type w(4); w.random(); - aed_type2 aed(4); + aed_type aed(4); aed.random(); fd_type fd(4); fd.random(); @@ -100,9 +100,9 @@ TEST_CASE( "Testing Kern_Linear 2", "[kernels]" ) { // Kern_Linear and BF_Linear should give the same anwer Kern_Linear kern; BF_Linear bf; - aed_type2 w(2); + aed_type w(2); w.random(); - aed_type2 aed(2); + aed_type aed(2); aed.random(); fd_type fd(2); fd.random(); @@ -125,9 +125,9 @@ TEST_CASE( "Testing Kern_Linear 3", "[kernels]" ) { using K=Kern_Linear; K kern; - aed_type2 w(2); + aed_type w(2); w.random(12345); - aed_type2 aed(2); + aed_type aed(2); aed.random(12345); fd_type fd(2); fd.random(12345); @@ -151,15 +151,15 @@ TEST_CASE( "Testing Kern_Quadratic", "[kernels]" ) { basis.random(); kern.set_basis(basis); - aed_type2 w(2); + aed_type w(2); w.random(12345); - aed_type2 aed(2); + aed_type aed(2); aed.random(12345); fd_type fd(2); fd.random(12345); for (size_t i=0; i<basis.cols(); ++i) { - const aed_type2 &b = basis.col(i); + const aed_type &b = basis.col(i); // test operator() REQUIRE_THAT((b*aed)*(b*aed), Catch::Matchers::WithinRel(kern(b,aed),1e-10)); @@ -168,7 +168,7 @@ TEST_CASE( "Testing Kern_Quadratic", "[kernels]" ) { isApprox(kern.derivative(b,aed),1e-10)); // test prime for (size_t k=0; k<3; ++k) { - REQUIRE(( (2*b*aed)*fd(k)*b )==(kern.prime(b,aed,fd(k)))); + REQUIRE( (2 * b * aed * fd(k) * b) == Approx(kern.prime(b, aed, fd(k))).epsilon(1e-10) ); REQUIRE_THAT(kern.derivative(b, aed)*fd(k), Catch::Matchers::WithinRel(kern.prime(b,aed,fd(k)),1e-10)); } @@ -184,15 +184,15 @@ TEST_CASE( "Testing Kern_LQ", "[kernels]" ) { basis.random(); kern.set_basis(basis); - aed_type2 w(2); + aed_type w(2); w.random(12345); - aed_type2 aed(2); + aed_type aed(2); aed.random(12345); fd_type fd(2); fd.random(12345); for (size_t i=0; i<basis.cols(); ++i) { - const aed_type2 &b = basis.col(i); + const aed_type &b = basis.col(i); // test operator() REQUIRE_THAT(((b*aed)*(b*aed))+(b*aed), Catch::Matchers::WithinRel(kern(b,aed),1e-10)); @@ -224,15 +224,15 @@ TEST_CASE( "Testing Kern_RBF", "[kernels]" ) { basis.random(123,-1e-1,1e-1); kern.set_basis(basis); - aed_type2 w(2); + aed_type w(2); w.random(23,-1e-1,1e-1); - aed_type2 aed(2); + aed_type aed(2); aed.random(143,-1e-1,1e-1); fd_type fd(2); fd.random(133,-1e-1,1e-1); for (size_t i=0; i<basis.cols(); ++i) { - const aed_type2 &b = basis.col(i); + const aed_type &b = basis.col(i); // test operator() REQUIRE_THAT(exp(-g*((aed-b)*(aed-b))), Catch::Matchers::WithinRel(kern(b,aed))); @@ -266,15 +266,15 @@ TEST_CASE( "Testing Kern_Sigmoid", "[kernels]" ) { basis.random(123,-1e-1,1e-1); kern.set_basis(basis); - aed_type2 w(2); + aed_type w(2); w.random(23,-1e-1,1e-1); - aed_type2 aed(2); + aed_type aed(2); aed.random(143,-1e-1,1e-1); fd_type fd(2); fd.random(133,-1e-1,1e-1); for (size_t i=0; i<basis.cols(); ++i) { - const aed_type2 &b = basis.col(i); + const aed_type &b = basis.col(i); // test operator() REQUIRE_THAT(std::tanh(g*(b*aed)+s), Catch::Matchers::WithinRel(kern(b,aed))); // test derivative @@ -309,15 +309,15 @@ TEST_CASE( "Testing Kern_Polynomial", "[kernels]" ) { basis.random(123,-1e-1,1e-1); kern.set_basis(basis); - aed_type2 w(2); + aed_type w(2); w.random(23,-1e-1,1e-1); - aed_type2 aed(2); + aed_type aed(2); aed.random(143,-1e-1,1e-1); fd_type fd(2); fd.random(133,-1e-1,1e-1); for (size_t i=0; i<basis.cols(); ++i) { - const aed_type2 &b = basis.col(i); + const aed_type &b = basis.col(i); // test operator() REQUIRE_THAT(std::pow(g*(b*aed)+s,d), Catch::Matchers::WithinRel(kern(b,aed))); // test derivative diff --git a/tests/test_ols.cpp b/tests/test_ols.cpp index 81c776452f59e941b865b4b99b4dfdb72b4935b9..8e6e63ef051166372c659f795660ea477a1b22d4 100644 --- a/tests/test_ols.cpp +++ b/tests/test_ols.cpp @@ -7,15 +7,15 @@ TEST_CASE("Testing OLS") { Matrix Phi1(3, 3, {1, 4, 7, 2, 5, 8, 3, 6, 9}); Matrix Phi2(3, 3, {1, 4, 7, 2, 5, 8, 3, 6, 9}); - aed_type2 b1(3); + aed_type b1(3); b1[0]=1; b1[1]=1; b1[2]=1; - aed_type2 w(3); - aed_type2 b2=b1; + aed_type w(3); + aed_type b2=b1; OLS::solve(Phi1,b1,w); - aed_type2 p= Phi2*w; + aed_type p= Phi2*w; REQUIRE_THAT(p[0], Catch::Matchers::WithinRel(b2[0])); REQUIRE_THAT(p[1], Catch::Matchers::WithinRel(b2[1])); REQUIRE_THAT(p[2], Catch::Matchers::WithinRel(b2[2])); diff --git a/tests/test_ridge_regression.cpp b/tests/test_ridge_regression.cpp index 317d6af615ed7e19d6f1ef4c322f35421f368b46..5c56e51d2d9f950b528ebcca92a2af82d3230dd4 100644 --- a/tests/test_ridge_regression.cpp +++ b/tests/test_ridge_regression.cpp @@ -6,17 +6,17 @@ TEST_CASE("Testing RR") { Matrix Phi1(3, 3, {1, 4, 7, 2, 5, 8, 3, 6, 9}); Matrix Phi2(3, 3, {1, 4, 7, 2, 5, 8, 3, 6, 9}); - aed_type2 b1(3); + aed_type b1(3); b1[0]=1; b1[1]=1; b1[2]=1; - aed_type2 w(3); - aed_type2 b2=b1; + aed_type w(3); + aed_type b2=b1; SECTION("lambda zero") { double lambda = 0; RidgeRegression::solve(Phi1,b1,w, lambda); - aed_type2 p= Phi2*w; + aed_type p= Phi2*w; REQUIRE_THAT(p[0], Catch::Matchers::WithinRel(b2[0])); REQUIRE_THAT(p[1], Catch::Matchers::WithinRel(b2[1])); REQUIRE_THAT(p[2], Catch::Matchers::WithinRel(b2[2])); @@ -24,7 +24,7 @@ TEST_CASE("Testing RR") { SECTION("small lambda ") { double lambda = 1e-10; RidgeRegression::solve(Phi1,b1,w, lambda); - aed_type2 p= Phi2*w; + aed_type p= Phi2*w; REQUIRE(p.isApprox(b2,lambda)); } } diff --git a/tests/test_svd.cpp b/tests/test_svd.cpp index e86a18524a947601f5884977c8a7fee5d1632e7d..d434096dbfc846836abec24fd1fa514d81f726db 100644 --- a/tests/test_svd.cpp +++ b/tests/test_svd.cpp @@ -1,7 +1,6 @@ #include "catch2/catch.hpp" #include <tadah/core/maths.h> #include <tadah/models/svd.h> -#include <iomanip> void multiplyMatrices(const double* A, const double* B, double* C, int m, int n, int p) { // C = A * B @@ -76,7 +75,7 @@ TEST_CASE("SVD Numeric Accuracy - Column-Major Order") { Matrix mU (U, m,n); Matrix mVT (VT,n,n); - aed_type2 vec(S, n); + aed_type vec(S, n); REQUIRE_THAT(16.848103352614209, Catch::Matchers::WithinRel(S[0])); REQUIRE_THAT(1.068369514554709, Catch::Matchers::WithinRel(S[1])); REQUIRE_THAT(0, Catch::Matchers::WithinAbs(S[2],1e-15));