diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp index 3da5688ff3..b865190ad1 100644 --- a/src/MANYBODY/pair_tersoff.cpp +++ b/src/MANYBODY/pair_tersoff.cpp @@ -433,7 +433,6 @@ void PairTersoff::read_file(char *file) if (kname == elements[kelement]) break; if (kelement == nelements) continue; - // load up parameter settings and error check their values if (nparams == maxparam) { diff --git a/src/MANYBODY/pair_tersoff_zbl.cpp b/src/MANYBODY/pair_tersoff_zbl.cpp index 2b464061ca..adf78fe070 100644 --- a/src/MANYBODY/pair_tersoff_zbl.cpp +++ b/src/MANYBODY/pair_tersoff_zbl.cpp @@ -71,9 +71,15 @@ void PairTersoffZBL::read_file(char *file) // open file on proc 0 if (comm->me == 0) { - PotentialFileReader reader(lmp, file, "Tersoff"); + PotentialFileReader reader(lmp, file, "TersoffZBL", unit_convert_flag); char * line; + // transparently convert units for supported conversions + + int unit_convert = reader.get_unit_convert(); + double conversion_factor = utils::get_conversion_factor(utils::ENERGY, + unit_convert); + while((line = reader.next_line(NPARAMS_PER_LINE))) { try { ValueTokenizer values(line); @@ -97,7 +103,6 @@ void PairTersoffZBL::read_file(char *file) if (kname == elements[kelement]) break; if (kelement == nelements) continue; - // load up parameter settings and error check their values if (nparams == maxparam) { @@ -128,6 +133,11 @@ void PairTersoffZBL::read_file(char *file) params[nparams].ZBLcut = values.next_double(); params[nparams].ZBLexpscale = values.next_double(); params[nparams].powermint = int(params[nparams].powerm); + + if (unit_convert) { + params[nparams].biga *= conversion_factor; + params[nparams].bigb *= conversion_factor; + } } catch (TokenizerException & e) { error->one(FLERR, e.what()); } diff --git a/src/USER-OMP/pair_tersoff_zbl_omp.cpp b/src/USER-OMP/pair_tersoff_zbl_omp.cpp index 6a9232f888..fa6e84c71b 100644 --- a/src/USER-OMP/pair_tersoff_zbl_omp.cpp +++ b/src/USER-OMP/pair_tersoff_zbl_omp.cpp @@ -92,9 +92,16 @@ void PairTersoffZBLOMP::read_file(char *file) // open file on proc 0 if (comm->me == 0) { - PotentialFileReader reader(PairTersoff::lmp, file, "Tersoff"); + PotentialFileReader reader(PairTersoff::lmp, file, "TersoffZBLOMP", + unit_convert_flag); char * line; + // transparently convert units for supported conversions + + int unit_convert = reader.get_unit_convert(); + double conversion_factor = utils::get_conversion_factor(utils::ENERGY, + unit_convert); + while((line = reader.next_line(NPARAMS_PER_LINE))) { try { ValueTokenizer values(line); @@ -118,7 +125,6 @@ void PairTersoffZBLOMP::read_file(char *file) if (kname == elements[kelement]) break; if (kelement == nelements) continue; - // load up parameter settings and error check their values if (nparams == maxparam) { @@ -149,6 +155,11 @@ void PairTersoffZBLOMP::read_file(char *file) params[nparams].ZBLcut = values.next_double(); params[nparams].ZBLexpscale = values.next_double(); params[nparams].powermint = int(params[nparams].powerm); + + if (unit_convert) { + params[nparams].biga *= conversion_factor; + params[nparams].bigb *= conversion_factor; + } } catch (TokenizerException & e) { error->one(FLERR, e.what()); } diff --git a/unittest/formats/test_pair_unit_convert.cpp b/unittest/formats/test_pair_unit_convert.cpp index 78a34af2f0..8b96e6d46e 100644 --- a/unittest/formats/test_pair_unit_convert.cpp +++ b/unittest/formats/test_pair_unit_convert.cpp @@ -388,6 +388,94 @@ TEST_F(PairUnitConvertTest, tersoff_table) EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error)); } +TEST_F(PairUnitConvertTest, tersoff_zbl) +{ + // check if the prerequisite pair style is available + if (!info->has_style("pair", "tersoff/zbl")) GTEST_SKIP(); + + if (!verbose) ::testing::internal::CaptureStdout(); + lmp->input->one("units metal"); + lmp->input->one("read_data test_pair_unit_convert.data"); + lmp->input->one("pair_style tersoff/zbl"); + lmp->input->one("pair_coeff * * SiC.tersoff.zbl Si C"); + lmp->input->one("run 0 post no"); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + // copy pressure, energy, and force from first step + double pold; + lmp->output->thermo->evaluate_keyword("press", &pold); + double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul; + double **f = lmp->atom->f; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + fold[i][j] = f[i][j]; + + if (!verbose) ::testing::internal::CaptureStdout(); + lmp->input->one("clear"); + lmp->input->one("units real"); + lmp->input->one("read_data test_pair_unit_convert.data"); + lmp->input->one("pair_style tersoff/zbl"); + lmp->input->one("pair_coeff * * SiC.tersoff.zbl Si C"); + lmp->input->one("run 0 post no"); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + double pnew; + lmp->output->thermo->evaluate_keyword("press", &pnew); + EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error)); + double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul; + EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error)); + + f = lmp->atom->f; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error)); +} + +TEST_F(PairUnitConvertTest, tersoff_zbl_omp) +{ + // check if the prerequisite pair style is available + if (!info->has_style("pair", "tersoff/zbl/omp")) GTEST_SKIP(); + + if (!verbose) ::testing::internal::CaptureStdout(); + lmp->input->one("package omp 4"); + lmp->input->one("units metal"); + lmp->input->one("read_data test_pair_unit_convert.data"); + lmp->input->one("pair_style tersoff/zbl/omp"); + lmp->input->one("pair_coeff * * SiC.tersoff.zbl Si C"); + lmp->input->one("run 0 post no"); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + // copy pressure, energy, and force from first step + double pold; + lmp->output->thermo->evaluate_keyword("press", &pold); + double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul; + double **f = lmp->atom->f; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + fold[i][j] = f[i][j]; + + if (!verbose) ::testing::internal::CaptureStdout(); + lmp->input->one("clear"); + lmp->input->one("package omp 4"); + lmp->input->one("units real"); + lmp->input->one("read_data test_pair_unit_convert.data"); + lmp->input->one("pair_style tersoff/zbl/omp"); + lmp->input->one("pair_coeff * * SiC.tersoff.zbl Si C"); + lmp->input->one("run 0 post no"); + if (!verbose) ::testing::internal::GetCapturedStdout(); + + double pnew; + lmp->output->thermo->evaluate_keyword("press", &pnew); + EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error)); + double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul; + EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error)); + + f = lmp->atom->f; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error)); +} + TEST_F(PairUnitConvertTest, vashishta) { // check if the prerequisite pair style is available