diff --git a/examples/PACKAGES/metatomic/in.metatomic b/examples/PACKAGES/metatomic/in.metatomic index dddb94422cf..8dc629822e9 100644 --- a/examples/PACKAGES/metatomic/in.metatomic +++ b/examples/PACKAGES/metatomic/in.metatomic @@ -12,7 +12,7 @@ mass Ni 58.693 velocity all create 123 42 -pair_style metatomic nickel-lj.pt +pair_style metatomic nickel-lj.pt uncertainty_threshold off # pair_style metatomic nickel-lj-extensions.pt extensions collected-extensions/ pair_coeff * * 28 diff --git a/examples/PACKAGES/metatomic/nickel-lj.pt b/examples/PACKAGES/metatomic/nickel-lj.pt index 3e422923687..4a9dcbc6a20 100644 Binary files a/examples/PACKAGES/metatomic/nickel-lj.pt and b/examples/PACKAGES/metatomic/nickel-lj.pt differ diff --git a/src/KOKKOS/metatomic_system_kokkos.cpp b/src/KOKKOS/metatomic_system_kokkos.cpp index d5768f7bfbb..7482fa481ce 100644 --- a/src/KOKKOS/metatomic_system_kokkos.cpp +++ b/src/KOKKOS/metatomic_system_kokkos.cpp @@ -16,18 +16,74 @@ Filippo Bigi ------------------------------------------------------------------------- */ #include "metatomic_system_kokkos.h" - #include "metatomic_timer.h" #include "domain.h" -#include "error.h" - +#include "comm.h" #include "atom_kokkos.h" #include using namespace LAMMPS_NS; +/// Compute the inverse of the cell matrix of the system, accounting for +/// non-periodic directions by setting the corresponding rows to an unit vector +/// orthogonal to the periodic directions. This is used to compute the cell +/// shifts of neighbor pairs. +static torch::Tensor cell_inverse(const metatomic_torch::System& system) { + auto cell = system->cell().clone(); + auto periodic = system->pbc(); + + // find number of periodic directions and their indices + int n_periodic = 0; + int periodic_idx_1 = -1; + int periodic_idx_2 = -1; + for (int i = 0; i < 3; ++i) { + if (periodic[i].item()) { + n_periodic += 1; + if (periodic_idx_1 == -1) { + periodic_idx_1 = i; + } else if (periodic_idx_2 == -1) { + periodic_idx_2 = i; + } + } + } + + // adjust the box matrix to have a simple orthogonal dimension along + // non-periodic directions + if (n_periodic == 0) { + return torch::eye(3, cell.options()); + } else if (n_periodic == 1) { + assert(periodic_idx_1 != -1); + // Make the two non-periodic directions orthogonal to the periodic one + auto a = cell[periodic_idx_1]; + auto b = torch::tensor({0, 1, 0}, cell.options()); + if (torch::abs(torch::dot(a / a.norm(), b)).item() > 0.9) { + b = torch::tensor({0, 0, 1}, cell.options()); + } + auto c = torch::cross(a, b); + c /= c.norm(); + b = torch::cross(c, a); + b /= b.norm(); + + // Assign back to the cell picking the "non-periodic" indices without ifs + cell[(periodic_idx_1 + 1) % 3] = b; + cell[(periodic_idx_1 + 2) % 3] = c; + } else if (n_periodic == 2) { + assert(periodic_idx_1 != -1 && periodic_idx_2 != -1); + // Make the one non-periodic direction orthogonal to the two periodic ones + auto a = cell[periodic_idx_1]; + auto b = cell[periodic_idx_2]; + auto c = torch::cross(a, b); + c /= c.norm(); + + // Assign back to the matrix picking the "non-periodic" index without ifs + cell[(3 - periodic_idx_1 - periodic_idx_2)] = c; + } + + return cell.inverse(); +} + template using UnmanagedView = Kokkos::View>; @@ -47,11 +103,9 @@ MetatomicSystemAdaptorKokkos::MetatomicSystemAdaptorKokkos(LAMMPS *l this->strain = torch::eye(3, tensor_options); } -#include "comm.h" - template -void MetatomicSystemAdaptorKokkos::setup_neighbors_remap_kk(metatomic_torch::System& system, NeighListKokkos* list) { - auto _ = MetatomicTimer("converting kokkos neighbors with ghosts remapping"); +void MetatomicSystemAdaptorKokkos::setup_neighbors_kk(metatomic_torch::System& system, NeighListKokkos* list) { + auto _ = MetatomicTimer("converting kokkos neighbors list"); auto dtype = system->positions().scalar_type(); auto total_n_atoms = atomKK->nlocal + atomKK->nghost; @@ -144,7 +198,7 @@ void MetatomicSystemAdaptorKokkos::setup_neighbors_remap_kk(metatomi ); auto x = system->positions().detach(); - auto cell_inverse = system->cell().detach().inverse(); + auto cell_inv = cell_inverse(system); // convert from LAMMPS NL format to metatomic NL format auto expanded_arange = torch::arange( @@ -213,13 +267,11 @@ void MetatomicSystemAdaptorKokkos::setup_neighbors_remap_kk(metatomi auto distances_filt = distances.index({cutoff_mask, torch::indexing::Slice()}); // find filtered interatomic vectors using the original atoms - auto original_distances_filtered = - x.index_select(0, neighbors_original_id_filt) - - x.index_select(0, centers_original_id_filt); + auto original_distances_filtered = x.index_select(0, neighbors_original_id_filt) - x.index_select(0, centers_original_id_filt); // cell shifts auto pair_shifts = distances_filt - original_distances_filtered; - auto cell_shifts = pair_shifts.matmul(cell_inverse); + auto cell_shifts = pair_shifts.matmul(cell_inv); cell_shifts = torch::round(cell_shifts).to(torch::kInt32); if (full_list) { @@ -308,7 +360,6 @@ template metatomic_torch::System MetatomicSystemAdaptorKokkos::system_from_lmp( NeighList* list, bool do_virial, - bool remap_pairs, torch::ScalarType dtype, torch::Device device ) { @@ -348,27 +399,26 @@ metatomic_torch::System MetatomicSystemAdaptorKokkos::system_from_lm auto system_positions = this->positions.to(dtype); cell = cell.to(dtype); + // Periodic boundary conditions handling. + auto pbc = torch::tensor( + {domain->xperiodic, domain->yperiodic, domain->zperiodic}, + torch::TensorOptions().dtype(torch::kBool).device(this->device_) + ); + + cell.index_put_( + {torch::logical_not(pbc)}, + torch::tensor({0.0}, torch::TensorOptions().dtype(dtype).device(this->device_)) + ); + if (do_virial) { auto model_strain = this->strain.to(dtype); - // pretend to scale positions/cell by the strain so that - // it enters the computational graph. + // scale positions/cell by the strain so that it enters the + // computational graph. system_positions = system_positions.matmul(model_strain); cell = cell.matmul(model_strain); } - // Periodic boundary conditions handling. - // - // While Metatomic models can support mixed PBC settings, we currently - // assume that the system is fully periodic and we throw an error otherwise - if (!domain->xperiodic || !domain->yperiodic || !domain->zperiodic) { - error->one(FLERR, "metatomic/kk currently requires a fully periodic system"); - } - auto pbc = torch::tensor( - {domain->xperiodic, domain->yperiodic, domain->zperiodic}, - torch::TensorOptions().dtype(torch::kBool).device(this->device_) - ); - auto system = torch::make_intrusive( atomic_types_, system_positions, @@ -376,13 +426,9 @@ metatomic_torch::System MetatomicSystemAdaptorKokkos::system_from_lm pbc ); - if (remap_pairs) { - auto* kk_list = dynamic_cast*>(list); - assert(kk_list != nullptr); - this->setup_neighbors_remap_kk(system, kk_list); - } else { - error->one(FLERR, "the kokkos version of metatomic requires remap_pairs to be true"); - } + auto* kk_list = dynamic_cast*>(list); + assert(kk_list != nullptr); + this->setup_neighbors_kk(system, kk_list); return system; } diff --git a/src/KOKKOS/metatomic_system_kokkos.h b/src/KOKKOS/metatomic_system_kokkos.h index 3c64f1f4299..595c4a3263c 100644 --- a/src/KOKKOS/metatomic_system_kokkos.h +++ b/src/KOKKOS/metatomic_system_kokkos.h @@ -82,12 +82,11 @@ class MetatomicSystemAdaptorKokkos : public MetatomicSystemAdaptor { metatomic_torch::System system_from_lmp( NeighList* list, bool do_virial, - bool remap_pairs, torch::ScalarType dtype, torch::Device device ) override; - void setup_neighbors_remap_kk(metatomic_torch::System& system, NeighListKokkos* list); + void setup_neighbors_kk(metatomic_torch::System& system, NeighListKokkos* list); private: /// Torch device corresponding to the kokkos `DeviceType` diff --git a/src/ML-METATOMIC/metatomic_system.cpp b/src/ML-METATOMIC/metatomic_system.cpp index 3ad6d546d98..8beba20288a 100644 --- a/src/ML-METATOMIC/metatomic_system.cpp +++ b/src/ML-METATOMIC/metatomic_system.cpp @@ -27,6 +27,122 @@ using namespace LAMMPS_NS; +using vector_t = std::array; +using matrix_t = std::array, 3>; + +static vector_t cross(vector_t a, vector_t b) { + return { + a[1] * b[2] - a[2] * b[1], + a[2] * b[0] - a[0] * b[2], + a[0] * b[1] - a[1] * b[0], + }; +} + +static double dot(vector_t a, vector_t b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} + +static vector_t normalize(vector_t a) { + double norm = std::sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]); + return {a[0] / norm, a[1] / norm, a[2] / norm}; +} + +static double determinant(matrix_t a) { + return a[0][0] * (a[1][1] * a[2][2] - a[2][1] * a[1][2]) + - a[0][1] * (a[1][0] * a[2][2] - a[1][2] * a[2][0]) + + a[0][2] * (a[1][0] * a[2][1] - a[1][1] * a[2][0]); +} + +matrix_t inverse(matrix_t a) { + auto det = determinant(a); + + if (std::abs(det) < 1e-10) { + throw std::runtime_error("this matrix is not invertible"); + } + + auto inverse = matrix_t(); + inverse[0][0] = (a[1][1] * a[2][2] - a[2][1] * a[1][2]) / det; + inverse[0][1] = (a[0][2] * a[2][1] - a[0][1] * a[2][2]) / det; + inverse[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det; + inverse[1][0] = (a[1][2] * a[2][0] - a[1][0] * a[2][2]) / det; + inverse[1][1] = (a[0][0] * a[2][2] - a[0][2] * a[2][0]) / det; + inverse[1][2] = (a[1][0] * a[0][2] - a[0][0] * a[1][2]) / det; + inverse[2][0] = (a[1][0] * a[2][1] - a[2][0] * a[1][1]) / det; + inverse[2][1] = (a[2][0] * a[0][1] - a[0][0] * a[2][1]) / det; + inverse[2][2] = (a[0][0] * a[1][1] - a[1][0] * a[0][1]) / det; + return inverse; +} + +/// Compute the inverse of the cell matrix of the system, accounting for +/// non-periodic directions by setting the corresponding rows to an unit vector +/// orthogonal to the periodic directions. This is used to compute the cell +/// shifts of neighbor pairs. +static std::array, 3> cell_inverse(Domain* domain) { + auto periodic = std::array{ + static_cast(domain->xperiodic), + static_cast(domain->yperiodic), + static_cast(domain->zperiodic), + }; + + auto cell = std::array, 3>{{0}}; + cell[0][0] = domain->xprd; + cell[1][0] = domain->xy; + cell[1][1] = domain->yprd; + cell[2][0] = domain->xz; + cell[2][1] = domain->yz; + cell[2][2] = domain->zprd; + + // find number of periodic directions and their indices + int n_periodic = 0; + int periodic_idx_1 = -1; + int periodic_idx_2 = -1; + for (int i = 0; i < 3; ++i) { + if (periodic[i]) { + n_periodic += 1; + if (periodic_idx_1 == -1) { + periodic_idx_1 = i; + } else if (periodic_idx_2 == -1) { + periodic_idx_2 = i; + } + } + } + + // adjust the box matrix to have a simple orthogonal dimension along + // non-periodic directions + if (n_periodic == 0) { + return { + std::array{1, 0, 0}, + std::array{0, 1, 0}, + std::array{0, 0, 1}, + }; + } else if (n_periodic == 1) { + assert(periodic_idx_1 != -1); + // Make the two non-periodic directions orthogonal to the periodic one + auto a = cell[periodic_idx_1]; + auto b = std::array{0, 1, 0}; + if (std::abs(dot(normalize(a), b)) > 0.9) { + b = std::array{0, 0, 1}; + } + auto c = normalize(cross(a, b)); + b = normalize(cross(c, a)); + + // Assign back to the cell picking the "non-periodic" indices without ifs + cell[(periodic_idx_1 + 1) % 3] = b; + cell[(periodic_idx_1 + 2) % 3] = c; + } else if (n_periodic == 2) { + assert(periodic_idx_1 != -1 && periodic_idx_2 != -1); + // Make the one non-periodic direction orthogonal to the two periodic ones + auto a = cell[periodic_idx_1]; + auto b = cell[periodic_idx_2]; + auto c = normalize(cross(a, b)); + + // Assign back to the matrix picking the "non-periodic" index without ifs + cell[(3 - periodic_idx_1 - periodic_idx_2)] = c; + } + + return inverse(cell); +} + MetatomicSystemAdaptor::MetatomicSystemAdaptor(LAMMPS *lmp, MetatomicSystemOptions options): Pointers(lmp), options_(std::move(options)), @@ -93,21 +209,14 @@ static std::array cell_shifts( } -void MetatomicSystemAdaptor::setup_neighbors_remap(metatomic_torch::System& system, NeighList *list) { - auto _ = MetatomicTimer("converting neighbors with ghosts remapping"); +void MetatomicSystemAdaptor::setup_neighbors(metatomic_torch::System& system, NeighList *list) { + auto _ = MetatomicTimer("converting neighbors list"); auto dtype = system->positions().scalar_type(); auto device = system->positions().device(); double** x = atom->x; auto total_n_atoms = atom->nlocal + atom->nghost; - - auto cell_inv_tensor = system->cell().inverse().t().to(torch::kCPU).to(torch::kFloat64); - auto cell_inv_accessor = cell_inv_tensor.accessor(); - auto cell_inv = std::array, 3>{{ - {{cell_inv_accessor[0][0], cell_inv_accessor[0][1], cell_inv_accessor[0][2]}}, - {{cell_inv_accessor[1][0], cell_inv_accessor[1][1], cell_inv_accessor[1][2]}}, - {{cell_inv_accessor[2][0], cell_inv_accessor[2][1], cell_inv_accessor[2][2]}}, - }}; + auto cell_inv = cell_inverse(domain); { auto _ = MetatomicTimer("identifying ghosts and real atoms"); @@ -344,140 +453,9 @@ void MetatomicSystemAdaptor::setup_neighbors_remap(metatomic_torch::System& syst } } -void MetatomicSystemAdaptor::setup_neighbors_no_remap(metatomic_torch::System& system, NeighList *list) { - auto _ = MetatomicTimer("converting neighbors without ghosts remapping"); - - auto dtype = system->positions().scalar_type(); - auto device = system->positions().device(); - - double** x = atom->x; - - for (auto& cache: caches_) { - { - auto _ = MetatomicTimer("filtering LAMMPS neighbor list"); - - auto cutoff2 = cache.cutoff * cache.cutoff; - auto full_list = cache.options->full_list(); - - // convert from LAMMPS neighbors list to metatomic format - cache.known_samples.clear(); - cache.samples.clear(); - cache.distances_f32.clear(); - cache.distances_f64.clear(); - for (int ii=0; ii<(list->inum + list->gnum); ii++) { - auto atom_i = list->ilist[ii]; - - auto neighbors = list->firstneigh[ii]; - for (int jj=0; jjnumneigh[ii]; jj++) { - auto atom_j = neighbors[jj]; - - if (!full_list && atom_i > atom_j) { - // Remove extra pairs if the model requested half-lists - continue; - } - - auto distance = std::array{ - x[atom_j][0] - x[atom_i][0], - x[atom_j][1] - x[atom_i][1], - x[atom_j][2] - x[atom_i][2], - }; - - auto distance2 = ( - distance[0] * distance[0] + - distance[1] * distance[1] + - distance[2] * distance[2] - ); - if (distance2 > cutoff2) { - // LAMMPS neighbors list contains some pairs after the - // cutoff, we filter them here - continue; - } - - auto sample = std::array{atom_i, atom_j, 0, 0, 0}; - - - cache.samples.push_back(sample); - - if (dtype == torch::kFloat64) { - cache.distances_f64.push_back(distance); - } else if (dtype == torch::kFloat32) { - cache.distances_f32.push_back({ - static_cast(distance[0]), - static_cast(distance[1]), - static_cast(distance[2]) - }); - } else { - // should be unreachable - error->one(FLERR, "invalid dtype, this is a bug"); - } - } - } - } - - int64_t n_pairs = cache.samples.size(); - auto samples_values = torch::from_blob( - reinterpret_cast(cache.samples.data()), - {n_pairs, 5}, - torch::TensorOptions().dtype(torch::kInt32).device(torch::kCPU) - ); - - torch::intrusive_ptr samples; - { - auto _ = MetatomicTimer("creating samples Labels (" + std::to_string(n_pairs) +" pairs)"); - samples = torch::make_intrusive( - std::vector{"first_atom", "second_atom", "cell_shift_a", "cell_shift_b", "cell_shift_c"}, - samples_values, - metatensor::assume_unique{} - ); - } - - auto distances_vectors = torch::Tensor(); - if (dtype == torch::kFloat64) { - distances_vectors = torch::from_blob( - cache.distances_f64.data(), - {n_pairs, 3, 1}, - torch::TensorOptions().dtype(torch::kFloat64).device(torch::kCPU) - ); - } else if (dtype == torch::kFloat32) { - distances_vectors = torch::from_blob( - cache.distances_f32.data(), - {n_pairs, 3, 1}, - torch::TensorOptions().dtype(torch::kFloat32).device(torch::kCPU) - ); - } else { - // should be unreachable - error->one(FLERR, "invalid dtype, this is a bug"); - } - - { - auto _ = MetatomicTimer("moving neighbor data to dtype/device"); - distances_vectors = distances_vectors.to(dtype).to(device); - samples = samples->to(device); - } - - torch::intrusive_ptr neighbors; - { - auto _ = MetatomicTimer("creating neighbors TensorBlock"); - neighbors = torch::make_intrusive( - distances_vectors, - samples, - std::vector{ - metatensor_torch::LabelsHolder::create({"xyz"}, {{0}, {1}, {2}})->to(device), - }, - metatensor_torch::LabelsHolder::create({"distance"}, {{0}})->to(device) - ); - } - - metatomic_torch::register_autograd_neighbors(system, neighbors, options_.check_consistency); - system->add_neighbor_list(cache.options, neighbors); - } -} - - metatomic_torch::System MetatomicSystemAdaptor::system_from_lmp( NeighList* list, bool do_virial, - bool remap_pairs, torch::ScalarType dtype, torch::Device device ) { @@ -499,6 +477,7 @@ metatomic_torch::System MetatomicSystemAdaptor::system_from_lmp( // requires_grad=true since we always need gradients w.r.t. positions tensor_options.requires_grad(options_.requires_grad) ); + auto system_positions = this->positions.to(dtype).to(device); auto cell = torch::zeros({3, 3}, tensor_options); cell[0][0] = domain->xprd; @@ -510,40 +489,27 @@ metatomic_torch::System MetatomicSystemAdaptor::system_from_lmp( cell[2][1] = domain->yz; cell[2][2] = domain->zprd; - auto system_positions = this->positions.to(dtype).to(device); cell = cell.to(dtype).to(device); - if (do_virial) { - auto model_strain = this->strain.to(dtype).to(device); - - // pretend to scale positions/cell by the strain so that - // it enters the computational graph. - system_positions = system_positions.matmul(model_strain); - cell = cell.matmul(model_strain); - } - // Periodic boundary conditions handling. - // While metatomic models can support mixed PBC settings, we currently - // assume that the system is fully periodic and we throw an error otherwise - if (!domain->xperiodic || !domain->yperiodic || !domain->zperiodic) { - error->one(FLERR, "pair_style metatomic requires a fully periodic system"); - } auto pbc = torch::tensor( {domain->xperiodic, domain->yperiodic, domain->zperiodic}, torch::TensorOptions().dtype(torch::kBool).device(device) ); - // Note that something like this: - // cell.index_put_( - // {torch::logical_not(pbc)}, - // torch::tensor({0.0}, torch::TensorOptions().dtype(dtype).device(device)) - // ); - // - // would allow creating System with non-periodic directions, but we're using - // the inverse of the cell matrix to filter the neighbor list, and the cell - // matrix becomes singular if any of its rows are zero. This requires some - // changes in the neighbor list filtering code to handle non-periodic - // directions. + cell.index_put_( + {torch::logical_not(pbc)}, + torch::tensor({0.0}, torch::TensorOptions().dtype(dtype).device(device)) + ); + + if (do_virial) { + auto model_strain = this->strain.to(dtype).to(device); + + // scale positions/cell by the strain so that it enters the + // computational graph. + system_positions = system_positions.matmul(model_strain); + cell = cell.matmul(model_strain); + } auto system = torch::make_intrusive( atomic_types_.to(device), @@ -552,11 +518,7 @@ metatomic_torch::System MetatomicSystemAdaptor::system_from_lmp( pbc ); - if (remap_pairs) { - this->setup_neighbors_remap(system, list); - } else { - this->setup_neighbors_no_remap(system, list); - } + this->setup_neighbors(system, list); return system; } diff --git a/src/ML-METATOMIC/metatomic_system.h b/src/ML-METATOMIC/metatomic_system.h index 15c58a8bf8f..37854e83966 100644 --- a/src/ML-METATOMIC/metatomic_system.h +++ b/src/ML-METATOMIC/metatomic_system.h @@ -90,7 +90,6 @@ class MetatomicSystemAdaptor : public Pointers { virtual metatomic_torch::System system_from_lmp( NeighList* list, bool do_virial, - bool remap_pairs, torch::ScalarType dtype, torch::Device device ); @@ -104,14 +103,7 @@ class MetatomicSystemAdaptor : public Pointers { protected: // setup the metatomic neighbors list from the internal LAMMPS one, - // remapping periodic ghosts to the corresponding local atom - void setup_neighbors_remap(metatomic_torch::System& system, NeighList* list); - - // setup the metatomic neighbors list from the internal LAMMPS one, - // WITHOUT remapping periodic ghosts to the corresponding local atom. - // - // This produces a larger NL but skips the cost of the remapping - void setup_neighbors_no_remap(metatomic_torch::System& system, NeighList* list); + void setup_neighbors(metatomic_torch::System& system, NeighList* list); // options for this system adaptor MetatomicSystemOptions options_; diff --git a/src/ML-METATOMIC/metatomic_types.cpp b/src/ML-METATOMIC/metatomic_types.cpp index 7e95dcfb797..2867e0e3fea 100644 --- a/src/ML-METATOMIC/metatomic_types.cpp +++ b/src/ML-METATOMIC/metatomic_types.cpp @@ -25,7 +25,6 @@ using namespace LAMMPS_NS; PairMetatomicData::PairMetatomicData(std::string length_unit): device(torch::kCPU), check_consistency(false), - remap_pairs(true), non_conservative(false), max_cutoff(-1) { diff --git a/src/ML-METATOMIC/metatomic_types.h b/src/ML-METATOMIC/metatomic_types.h index 3eea1e3ea77..ce1ee64ef8a 100644 --- a/src/ML-METATOMIC/metatomic_types.h +++ b/src/ML-METATOMIC/metatomic_types.h @@ -60,9 +60,6 @@ struct PairMetatomicData { // should metatomic check the data LAMMPS send to the model // and the data the model returns? bool check_consistency; - // whether pairs should be remapped, removing pairs between ghosts if there - // is an equivalent pair involving at least one local atom. - bool remap_pairs; // whether non-conservative forces and stresses should be used bool non_conservative; // how far away the model needs to know about neighbors diff --git a/src/ML-METATOMIC/pair_metatomic.cpp b/src/ML-METATOMIC/pair_metatomic.cpp index e96caf9cdcd..d69b2686807 100644 --- a/src/ML-METATOMIC/pair_metatomic.cpp +++ b/src/ML-METATOMIC/pair_metatomic.cpp @@ -140,18 +140,6 @@ void PairMetatomic::settings(int argc, char ** argv) { error->one(FLERR, "expected after 'check_consistency' in pair_style metatomic, got '{}'", argv[i + 1]); } - i += 1; - } else if (strcmp(argv[i], "remap_pairs") == 0) { - if (i == argc - 1) { - error->one(FLERR, "expected after 'remap_pairs' in pair_style metatomic, got nothing"); - } else if (strcmp(argv[i + 1], "on") == 0) { - mta_data->remap_pairs = true; - } else if (strcmp(argv[i + 1], "off") == 0) { - mta_data->remap_pairs = false; - } else { - error->one(FLERR, "expected after 'remap_pairs' in pair_style metatomic, got '{}'", argv[i + 1]); - } - i += 1; } else if (strcmp(argv[i], "non_conservative") == 0) { if (i == argc - 1) { @@ -643,7 +631,6 @@ void PairMetatomic::compute(int eflag, int vflag) { auto system = this->system_adaptor->system_from_lmp( mta_list, static_cast(vflag_global), - mta_data->remap_pairs, dtype, mta_data->device );