261 :
impl_(std::make_unique<Impl>()) {
267 ::capnp::MallocMessageBuilder msg;
268 auto params = msg.initRoot<::NWChemParams>();
269 params.setBasis(opt.
basis);
270 params.setTheory(opt.
theory);
272 params.setCharge(opt.
charge);
280 if (!opt.
title.empty())
281 params.setTitle(opt.
title);
283 params.setMemoryMb(
static_cast<uint32_t
>(opt.
memory_mb));
286
288 if (block.empty()) {
289 if (const char *env = std::getenv("RGPOT_NWCHEM_INPUT_BLOCK"))
290 block = env;
291 }
292 if (block.empty() && (opt.
theory ==
"dft" || opt.
theory ==
"DFT") &&
294 block =
"dft\n xc " + opt.
scf_type +
"\n mult " +
296 }
else if (block.empty() && looks_like_dft_xc(opt.
theory)) {
297 block =
"dft\n xc " + opt.
theory +
"\n mult " +
299 }
300 if (!block.empty()) {
301 auto blocks = params.initInputBlocks(1);
302 blocks.set(0, block);
303 }
304 impl_->nwchem = std::make_unique<rgpot::NWChemPot>(params.asReader());
305 if (!
impl_->nwchem->available())
306 throw std::runtime_error(
307 "RGPOT(nwchemc): engine not available (set NWCHEMC_LIBRARY / "
308 "RGPOT_NWCHEMC_ENGINE or [RgpotPot] engine_path)");
313 std::string local_error;
314 try {
315 ::capnp::MallocMessageBuilder msg;
317 impl_->cpmd = std::make_unique<rgpot::CPMDPot>(params.asReader());
320 if (!
impl_->cpmd->available())
321 throw std::runtime_error(
322 "RGPOT(cpmdc): engine not available (set CPMDC_LIBRARY / "
323 "RGPOT_CPMDC_ENGINE or [RgpotPot] engine_path)");
324 } catch (const std::exception &ex) {
325 local_error = ex.what();
326 }
327
328
329 if (mpi_world_hint() <= 1 && !local_error.empty())
330 throw std::runtime_error(local_error);
331#if defined(__linux__) && defined(EON_RGPOT_MPI)
332
333
334 if (mpi_world_hint() > 1 && !agree_construction(local_error)) {
336 throw std::runtime_error(
337 local_error.empty()
338 ? std::string(
339 "RGPOT(cpmdc): a rank failed before the calculator split")
340 : local_error);
341 }
342#endif
343 if (!local_error.empty())
344 throw std::runtime_error(local_error);
345 if (::rgpot::calculatorsUseMpi()) {
346
347
348
349 const rgpot::CalculatorGroup g =
351 ::rgpot::finalizeMpiAtExit();
352 if (mpi_world_hint() > 1)
354 if (g.index < 0)
355 throw std::runtime_error(
356 "RGPOT(cpmdc): ranks_per_image=" +
358 " does not divide the MPI world into calculator groups");
359 impl_->groups = ::rgpot::calculatorCount();
360 impl_->group = g.index;
361 impl_->world = ::rgpot::calculatorWorldSize();
363 throw std::runtime_error(
364 "RGPOT(cpmdc): ranks_per_image needs rgpot built with MPI "
365 "(-Drgpot:with_mpi=enabled)");
366 }
371 MetatomicEngineOptions mopt;
381 impl_->metatomic = std::make_unique<MetatomicEngineLoader>(mopt);
382 if (!
impl_->metatomic->available())
383 throw std::runtime_error(
384 "RGPOT(metatomic): engine not available (set RGPOT_METATOMIC_ENGINE "
385 "or [RgpotPot] engine_path to libmetatomic_engine.so)");
390 XTBEngineOptions xopt;
399 impl_->xtb = std::make_unique<XTBEngineLoader>(xopt);
400 if (!
impl_->xtb->available())
401 throw std::runtime_error(
402 "RGPOT(xtb): engine not available (set RGPOT_XTB_ENGINE or "
403 "[RgpotPot] engine_path to libxtb_engine.so)");
404 } else {
405 throw std::runtime_error(
"RGPOT: unknown backend '" + opt.
backend +
406 "' (expected nwchemc, cpmdc, metatomic, or xtb)");
407 }
408}
void armGroupedExit() const
After MPI_Finalize, _Exit.
std::unique_ptr< Impl > impl_
::CPMDParams::Builder fillCpmdParams(::capnp::MallocMessageBuilder &msg, const RGPotEngineOptions &opt)
std::string extensions_directory
std::string engine_library
double xtb_electronic_temperature
bool torch_determinism_strict
double uncertainty_threshold
double electronic_temperature