132 double *F,
double *U,
double *variance,
135 std::vector<std::string> symbols;
137 for (
long i = 0; i < N; ++i) {
138 symbols.emplace_back(atomicNumber2symbol(atomicNrs[i]));
144 std::cout <<
"Waiting for NWChem client connection..." << std::endl;
146 std::cout <<
"NWChem client connected." << std::endl;
150 char status_buffer[
MSG_LEN + 1] = {0};
156 if (std::string(status_buffer) !=
"READY") {
157 throw std::runtime_error(
158 "Handshake failed: NWChem client not READY. It sent: " +
159 std::string(status_buffer));
161 std::cout <<
"NWChem server is connected and READY." << std::endl;
165 char status_buffer[
MSG_LEN + 1] = {0};
169 if (std::string(status_buffer) ==
"NEEDINIT") {
172 int32_t init_payload[] = {0, 1};
174 send_exact(&init_payload,
sizeof(init_payload));
181 if (std::string(status_buffer) !=
"READY") {
182 throw std::runtime_error(
"NWChem server not ready for new positions!");
186 std::vector<double> pos_bohr(N * 3);
187 for (
size_t i = 0; i < pos_bohr.size(); ++i) {
194 double invcell_T[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
195 double cell_T[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
202 send_exact(pos_bohr.data(), pos_bohr.size() *
sizeof(
double));
208 if (std::string(status_buffer) ==
"HAVEDATA") {
218 if (std::string(status_buffer) !=
"FORCEREADY") {
219 throw std::runtime_error(
"Expected FORCEREADY, got " +
220 std::string(status_buffer));
226 std::vector<double> forces_ha_bohr(N * 3);
233 throw std::runtime_error(
"Atom count mismatch from NWChem");
234 recv_exact(forces_ha_bohr.data(), forces_ha_bohr.size() *
sizeof(
double));
238 std::vector<char> extra_buf(extra_len);
244 for (
int i = 0; i < N * 3; ++i) {
256 listen_fd = socket(domain, SOCK_STREAM, 0);
258 throw std::runtime_error(
"Failed to create socket.");
263 sockaddr_un sock_addr{};
264 sock_addr.sun_family = AF_UNIX;
266 sizeof(sock_addr.sun_path) - 1);
269 sizeof(sock_addr.sun_family) + strlen(sock_addr.sun_path);
270 if (::bind(
listen_fd, (
struct sockaddr *)&sock_addr, addr_len) < 0) {
271 perror(
"UNIX bind failed");
272 throw std::runtime_error(
"Failed to bind UNIX socket.");
276 setsockopt(
listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
277 sockaddr_in sock_addr{};
278 sock_addr.sin_family = AF_INET;
280 sock_addr.sin_port = htons(
port);
282 if (::bind(
listen_fd, (
struct sockaddr *)&sock_addr,
sizeof(sock_addr)) <
284 perror(
"TCP bind failed");
285 throw std::runtime_error(
"Failed to bind TCP socket.");
290 perror(
"listen() failed");
291 throw std::runtime_error(
"Socket listen() failed.");
void force(long N, const double *R, const int *atomicNrs, double *F, double *U, double *variance, const double *box) override
The method called to compute forces and energy.