45void MPIPot::force(
long N,
const double *R,
const int *atomicNrs,
double *F,
46 double *U,
double *variance,
const double *box) {
47 if (variance !=
nullptr) {
52 std::array<int, 1024> icwd{};
53 const std::string cwd = std::filesystem::current_path().string();
54 if (cwd.size() >= icwd.size()) {
55 throw std::runtime_error(
56 "working directory path exceeds the MPI potential buffer");
58 for (std::size_t i = 0; i < cwd.size(); ++i) {
59 icwd[i] =
static_cast<int>(
static_cast<unsigned char>(cwd[i]));
63 const int intn =
static_cast<int>(N);
64 mpi_check(MPI_Send(&intn, 1, MPI_INT,
potentialRank, 0, MPI_COMM_WORLD),
65 "MPI_Send atom count");
67 MPI_Send(atomicNrs, intn, MPI_INT,
potentialRank, 0, MPI_COMM_WORLD),
68 "MPI_Send atomic numbers");
69 mpi_check(MPI_Send(R, 3 * intn, MPI_DOUBLE,
potentialRank, 0, MPI_COMM_WORLD),
70 "MPI_Send positions");
71 mpi_check(MPI_Send(box, 9, MPI_DOUBLE,
potentialRank, 0, MPI_COMM_WORLD),
73 mpi_check(MPI_Send(&pbc, 1, MPI_INT,
potentialRank, 0, MPI_COMM_WORLD),
75 mpi_check(MPI_Send(icwd.data(),
static_cast<int>(icwd.size()), MPI_INT,
77 "MPI_Send working directory");
82 const auto usec =
static_cast<std::uint64_t
>(
poll_period * 1000000.0);
83 mpi_check(MPI_Iprobe(
potentialRank, 0, MPI_COMM_WORLD, &eon_flag,
88 std::this_thread::sleep_for(std::chrono::microseconds(usec));
90 mpi_check(MPI_Iprobe(
potentialRank, 0, MPI_COMM_WORLD, &eon_flag,
96 mpi_check(MPI_Recv(&failed, 1, MPI_INT,
potentialRank, 0, MPI_COMM_WORLD,
100 throw std::runtime_error(
"MPI potential reported a failed evaluation");
103 mpi_check(MPI_Recv(U, 1, MPI_DOUBLE,
potentialRank, 0, MPI_COMM_WORLD,
106 mpi_check(MPI_Recv(F, 3 * intn, MPI_DOUBLE,
potentialRank, 0, MPI_COMM_WORLD,
void force(long N, const double *R, const int *atomicNrs, double *F, double *U, double *variance, const double *box) override