|
| 1 | +// SPDX-License-Identifier: LGPL-3.0-or-later |
| 2 | +// Test C++ inference for pt_expt (.pt2) backend with default_fparam. |
| 3 | +// Uses fparam_aparam_default.pt2: has_default_fparam=true, |
| 4 | +// default=[0.25852028]. |
| 5 | +#include <gtest/gtest.h> |
| 6 | + |
| 7 | +#include <algorithm> |
| 8 | +#include <cmath> |
| 9 | +#include <fstream> |
| 10 | +#include <vector> |
| 11 | + |
| 12 | +#include "DeepPot.h" |
| 13 | +#include "neighbor_list.h" |
| 14 | +#include "test_utils.h" |
| 15 | + |
| 16 | +// 1e-10 cannot pass; unclear bug or not |
| 17 | +#undef EPSILON |
| 18 | +#define EPSILON (std::is_same<VALUETYPE, double>::value ? 1e-7 : 1e-4) |
| 19 | + |
| 20 | +template <class VALUETYPE> |
| 21 | +class TestInferDeepPotDefaultFParamPtExpt : public ::testing::Test { |
| 22 | + protected: |
| 23 | + std::vector<VALUETYPE> coord = {12.83, 2.56, 2.18, 12.09, 2.87, 2.74, |
| 24 | + 00.25, 3.32, 1.68, 3.36, 3.00, 1.81, |
| 25 | + 3.51, 2.51, 2.60, 4.27, 3.22, 1.56}; |
| 26 | + std::vector<int> atype = {0, 0, 0, 0, 0, 0}; |
| 27 | + std::vector<VALUETYPE> box = {13., 0., 0., 0., 13., 0., 0., 0., 13.}; |
| 28 | + // aparam is still provided explicitly |
| 29 | + std::vector<VALUETYPE> aparam = {0.25852028, 0.25852028, 0.25852028, |
| 30 | + 0.25852028, 0.25852028, 0.25852028}; |
| 31 | + // explicit fparam for backward compat test |
| 32 | + std::vector<VALUETYPE> fparam = {0.25852028}; |
| 33 | + // expected values computed with default fparam |
| 34 | + std::vector<VALUETYPE> expected_e = { |
| 35 | + 1.596836265688982293e-01, 1.596933624175455035e-01, |
| 36 | + 1.596859462832928844e-01, 1.596779837732069107e-01, |
| 37 | + 1.596776702807257142e-01, 1.596869048501883825e-01}; |
| 38 | + std::vector<VALUETYPE> expected_f = { |
| 39 | + 1.112134318320098417e-05, 1.085230789880272913e-04, |
| 40 | + 9.298442641358670786e-07, 1.491517597320257801e-04, |
| 41 | + -1.250419527572718750e-05, -9.768265174690742383e-05, |
| 42 | + -5.021052645725076108e-05, -9.741678916887853762e-05, |
| 43 | + 9.375317764392499637e-05, 8.664103999852429459e-05, |
| 44 | + -4.538513400016661465e-05, 8.561605116672728300e-05, |
| 45 | + -2.454811055475983474e-05, 1.079491454988312375e-04, |
| 46 | + -1.656974003674590982e-04, -1.721555059017404292e-04, |
| 47 | + -6.116610604208619416e-05, 8.308097903957838235e-05}; |
| 48 | + std::vector<VALUETYPE> expected_v = { |
| 49 | + -1.264062189119718516e-04, -1.636544077308298682e-05, |
| 50 | + 4.453224130911559301e-05, -7.947403699518174416e-06, |
| 51 | + -4.603504987332694676e-05, 9.491045850088937973e-06, |
| 52 | + 4.131028921467351392e-05, 9.691472468201808941e-06, |
| 53 | + -3.323572704427467454e-05, -1.024556912293136224e-04, |
| 54 | + 5.530809120954762511e-06, 5.211030391191995666e-05, |
| 55 | + -3.851138686809712045e-06, 2.101414374152978974e-07, |
| 56 | + 3.247573516972806439e-06, 4.561253716254927361e-05, |
| 57 | + -3.865680092083368681e-06, -3.262252150841838630e-05, |
| 58 | + -1.166788692566848309e-04, -1.814499890570951256e-05, |
| 59 | + 2.155064011880963138e-05, -1.629918981392338952e-05, |
| 60 | + -3.245631268444034052e-05, 2.968538417601219450e-05, |
| 61 | + 2.463149007223181425e-05, 3.660689861518750502e-05, |
| 62 | + -3.586518711234942813e-05, -1.424206401855391917e-04, |
| 63 | + -1.017840928263479808e-05, 1.421307534994556974e-05, |
| 64 | + -8.618294024757196269e-06, -2.192409332705388475e-05, |
| 65 | + 3.461715847634955364e-05, 1.277625693457723244e-05, |
| 66 | + 3.486479415793142304e-05, -5.604161168847289151e-05, |
| 67 | + -8.612844407008964597e-05, 2.508361660152530129e-06, |
| 68 | + -1.633895954533155651e-07, 1.903591783622965016e-06, |
| 69 | + -3.028341203071198989e-05, 4.685511271783774690e-05, |
| 70 | + 2.876824509984395433e-06, 4.576515617130287920e-05, |
| 71 | + -7.108738780331674085e-05, -1.062354815105980244e-04, |
| 72 | + -2.954644717832236758e-05, 4.075640001084843372e-05, |
| 73 | + -3.138369091725702186e-05, -1.316088004849702041e-05, |
| 74 | + 1.786389692843502177e-05, 4.579187321116953935e-05, |
| 75 | + 1.869753034515599593e-05, -2.550749273395904029e-05}; |
| 76 | + int natoms; |
| 77 | + double expected_tot_e; |
| 78 | + std::vector<VALUETYPE> expected_tot_v; |
| 79 | + |
| 80 | + deepmd::DeepPot dp; |
| 81 | + |
| 82 | + void SetUp() override { |
| 83 | +#ifndef BUILD_PYTORCH |
| 84 | + GTEST_SKIP() << "Skip because PyTorch support is not enabled."; |
| 85 | +#endif |
| 86 | + dp.init("../../tests/infer/fparam_aparam_default.pt2"); |
| 87 | + |
| 88 | + natoms = expected_e.size(); |
| 89 | + EXPECT_EQ(natoms * 3, expected_f.size()); |
| 90 | + EXPECT_EQ(natoms * 9, expected_v.size()); |
| 91 | + expected_tot_e = 0.; |
| 92 | + expected_tot_v.resize(9); |
| 93 | + std::fill(expected_tot_v.begin(), expected_tot_v.end(), 0.); |
| 94 | + for (int ii = 0; ii < natoms; ++ii) { |
| 95 | + expected_tot_e += expected_e[ii]; |
| 96 | + } |
| 97 | + for (int ii = 0; ii < natoms; ++ii) { |
| 98 | + for (int dd = 0; dd < 9; ++dd) { |
| 99 | + expected_tot_v[dd] += expected_v[ii * 9 + dd]; |
| 100 | + } |
| 101 | + } |
| 102 | + }; |
| 103 | + |
| 104 | + void TearDown() override {}; |
| 105 | +}; |
| 106 | + |
| 107 | +TYPED_TEST_SUITE(TestInferDeepPotDefaultFParamPtExpt, ValueTypes); |
| 108 | + |
| 109 | +TYPED_TEST(TestInferDeepPotDefaultFParamPtExpt, attrs) { |
| 110 | + using VALUETYPE = TypeParam; |
| 111 | + deepmd::DeepPot& dp = this->dp; |
| 112 | + EXPECT_EQ(dp.dim_fparam(), 1); |
| 113 | + EXPECT_EQ(dp.dim_aparam(), 1); |
| 114 | + EXPECT_TRUE(dp.has_default_fparam()); |
| 115 | +} |
| 116 | + |
| 117 | +TYPED_TEST(TestInferDeepPotDefaultFParamPtExpt, cpu_build_nlist_empty_fparam) { |
| 118 | + using VALUETYPE = TypeParam; |
| 119 | + std::vector<VALUETYPE>& coord = this->coord; |
| 120 | + std::vector<int>& atype = this->atype; |
| 121 | + std::vector<VALUETYPE>& box = this->box; |
| 122 | + std::vector<VALUETYPE>& aparam = this->aparam; |
| 123 | + std::vector<VALUETYPE>& expected_e = this->expected_e; |
| 124 | + std::vector<VALUETYPE>& expected_f = this->expected_f; |
| 125 | + int& natoms = this->natoms; |
| 126 | + double& expected_tot_e = this->expected_tot_e; |
| 127 | + std::vector<VALUETYPE>& expected_tot_v = this->expected_tot_v; |
| 128 | + deepmd::DeepPot& dp = this->dp; |
| 129 | + double ener; |
| 130 | + std::vector<VALUETYPE> force, virial; |
| 131 | + // Empty fparam — model should use default |
| 132 | + std::vector<VALUETYPE> empty_fparam; |
| 133 | + dp.compute(ener, force, virial, coord, atype, box, empty_fparam, aparam); |
| 134 | + |
| 135 | + EXPECT_EQ(force.size(), natoms * 3); |
| 136 | + EXPECT_EQ(virial.size(), 9); |
| 137 | + |
| 138 | + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); |
| 139 | + for (int ii = 0; ii < natoms * 3; ++ii) { |
| 140 | + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); |
| 141 | + } |
| 142 | + for (int ii = 0; ii < 3 * 3; ++ii) { |
| 143 | + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); |
| 144 | + } |
| 145 | +} |
| 146 | + |
| 147 | +TYPED_TEST(TestInferDeepPotDefaultFParamPtExpt, |
| 148 | + cpu_build_nlist_explicit_fparam) { |
| 149 | + using VALUETYPE = TypeParam; |
| 150 | + std::vector<VALUETYPE>& coord = this->coord; |
| 151 | + std::vector<int>& atype = this->atype; |
| 152 | + std::vector<VALUETYPE>& box = this->box; |
| 153 | + std::vector<VALUETYPE>& fparam = this->fparam; |
| 154 | + std::vector<VALUETYPE>& aparam = this->aparam; |
| 155 | + std::vector<VALUETYPE>& expected_e = this->expected_e; |
| 156 | + std::vector<VALUETYPE>& expected_f = this->expected_f; |
| 157 | + int& natoms = this->natoms; |
| 158 | + double& expected_tot_e = this->expected_tot_e; |
| 159 | + std::vector<VALUETYPE>& expected_tot_v = this->expected_tot_v; |
| 160 | + deepmd::DeepPot& dp = this->dp; |
| 161 | + double ener; |
| 162 | + std::vector<VALUETYPE> force, virial; |
| 163 | + // Explicit fparam — backward compat |
| 164 | + dp.compute(ener, force, virial, coord, atype, box, fparam, aparam); |
| 165 | + |
| 166 | + EXPECT_EQ(force.size(), natoms * 3); |
| 167 | + EXPECT_EQ(virial.size(), 9); |
| 168 | + |
| 169 | + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); |
| 170 | + for (int ii = 0; ii < natoms * 3; ++ii) { |
| 171 | + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); |
| 172 | + } |
| 173 | + for (int ii = 0; ii < 3 * 3; ++ii) { |
| 174 | + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); |
| 175 | + } |
| 176 | +} |
| 177 | + |
| 178 | +TYPED_TEST(TestInferDeepPotDefaultFParamPtExpt, cpu_lmp_nlist_empty_fparam) { |
| 179 | + using VALUETYPE = TypeParam; |
| 180 | + std::vector<VALUETYPE>& coord = this->coord; |
| 181 | + std::vector<int>& atype = this->atype; |
| 182 | + std::vector<VALUETYPE>& box = this->box; |
| 183 | + std::vector<VALUETYPE>& aparam = this->aparam; |
| 184 | + std::vector<VALUETYPE>& expected_f = this->expected_f; |
| 185 | + int& natoms = this->natoms; |
| 186 | + double& expected_tot_e = this->expected_tot_e; |
| 187 | + std::vector<VALUETYPE>& expected_tot_v = this->expected_tot_v; |
| 188 | + deepmd::DeepPot& dp = this->dp; |
| 189 | + float rc = dp.cutoff(); |
| 190 | + int nloc = coord.size() / 3; |
| 191 | + std::vector<VALUETYPE> coord_cpy; |
| 192 | + std::vector<int> atype_cpy, mapping; |
| 193 | + std::vector<std::vector<int> > nlist_data; |
| 194 | + _build_nlist<VALUETYPE>(nlist_data, coord_cpy, atype_cpy, mapping, coord, |
| 195 | + atype, box, rc); |
| 196 | + int nall = coord_cpy.size() / 3; |
| 197 | + std::vector<int> ilist(nloc), numneigh(nloc); |
| 198 | + std::vector<int*> firstneigh(nloc); |
| 199 | + deepmd::InputNlist inlist(nloc, &ilist[0], &numneigh[0], &firstneigh[0]); |
| 200 | + convert_nlist(inlist, nlist_data); |
| 201 | + |
| 202 | + double ener; |
| 203 | + std::vector<VALUETYPE> force_, virial; |
| 204 | + std::vector<VALUETYPE> empty_fparam; |
| 205 | + dp.compute(ener, force_, virial, coord_cpy, atype_cpy, box, nall - nloc, |
| 206 | + inlist, 0, empty_fparam, aparam); |
| 207 | + std::vector<VALUETYPE> force; |
| 208 | + _fold_back<VALUETYPE>(force, force_, mapping, nloc, nall, 3); |
| 209 | + |
| 210 | + EXPECT_EQ(force.size(), natoms * 3); |
| 211 | + EXPECT_EQ(virial.size(), 9); |
| 212 | + |
| 213 | + EXPECT_LT(fabs(ener - expected_tot_e), EPSILON); |
| 214 | + for (int ii = 0; ii < natoms * 3; ++ii) { |
| 215 | + EXPECT_LT(fabs(force[ii] - expected_f[ii]), EPSILON); |
| 216 | + } |
| 217 | + for (int ii = 0; ii < 3 * 3; ++ii) { |
| 218 | + EXPECT_LT(fabs(virial[ii] - expected_tot_v[ii]), EPSILON); |
| 219 | + } |
| 220 | +} |
0 commit comments