1mod ffi;
7#[cfg(feature = "extended")]
8mod ffi_extended;
9#[cfg(feature = "extended")]
11pub mod ffi_extended_raw {
12 pub use crate::ffi_extended::*;
13}
14mod force_env;
15
16pub mod shm;
18
19pub mod worker_protocol;
21
22pub mod worker;
24
25#[cfg(feature = "mpi")]
26use mpi::{ffi::MPI_Comm_c2f, raw::AsRaw};
27
28use std::sync::atomic::{AtomicBool, Ordering};
29
30#[cfg(feature = "extended")]
31pub use force_env::GridInfo;
32pub use force_env::{CP2KError, CP2KResult, ForceEnv};
33
34#[cfg(feature = "python")]
35pub mod python;
36
37static INIT_WITH_MPI: AtomicBool = AtomicBool::new(true);
40
41pub fn init() -> CP2KResult<()> {
50 unsafe {
51 let result = ffi::cp2k_init_with_mpi_check();
52 if result != 0 {
53 return Err(CP2KError::InitializationError(format!(
54 "CP2K initialization failed with code {}",
55 result
56 )));
57 }
58 }
59 INIT_WITH_MPI.store(true, Ordering::SeqCst);
60 Ok(())
61}
62
63pub fn init_without_mpi() -> CP2KResult<()> {
65 unsafe {
66 ffi::cp2k_init_without_mpi();
67 }
68 INIT_WITH_MPI.store(false, Ordering::SeqCst);
69 Ok(())
70}
71
72pub fn finalize() -> CP2KResult<()> {
89 unsafe {
90 let result = if INIT_WITH_MPI.load(Ordering::SeqCst) {
91 ffi::cp2k_finalize_with_mpi_check()
92 } else {
93 ffi::cp2k_finalize_without_mpi();
94 0
95 };
96 if result != 0 {
97 return Err(CP2KError::FinalizationError(format!(
98 "CP2K finalization failed with code {}",
99 result
100 )));
101 }
102 }
103 Ok(())
104}
105
106pub fn finalize_without_mpi() -> CP2KResult<()> {
108 unsafe {
109 ffi::cp2k_finalize_without_mpi();
110 }
111 Ok(())
112}
113
114pub fn get_version() -> CP2KResult<String> {
116 const MAX_VERSION_LEN: usize = 256;
117 let mut version_buf = vec![0u8; MAX_VERSION_LEN];
118
119 unsafe {
120 ffi::cp2k_get_version(version_buf.as_mut_ptr() as *mut i8, MAX_VERSION_LEN as i32);
121 }
122
123 let end = version_buf
125 .iter()
126 .position(|&c| c == 0)
127 .unwrap_or(version_buf.len());
128 version_buf.truncate(end);
129
130 Ok(String::from_utf8(version_buf)?)
132}
133
134pub fn run_input(input_file: &str, output_file: &str) -> CP2KResult<()> {
136 let input_c = std::ffi::CString::new(input_file)?;
137 let output_c = std::ffi::CString::new(output_file)?;
138
139 unsafe {
140 ffi::cp2k_run_input(input_c.as_ptr(), output_c.as_ptr());
141 }
142
143 Ok(())
144}
145
146#[cfg(feature = "mpi")]
148pub fn run_input_comm(
149 input_file: &str,
150 output_file: &str,
151 comm: &mpi::topology::SimpleCommunicator,
152) -> CP2KResult<()> {
153 let input_c = std::ffi::CString::new(input_file)?;
154 let output_c = std::ffi::CString::new(output_file)?;
155 let raw_comm = comm.as_raw();
156 let fortran_comm = unsafe { MPI_Comm_c2f(raw_comm) };
157
158 unsafe {
159 ffi::cp2k_run_input_comm(input_c.as_ptr(), output_c.as_ptr(), fortran_comm);
160 }
161
162 Ok(())
163}