diff --git a/src/ctrl_io/mod.rs b/src/ctrl_io/mod.rs
index fe651854e0924127cd9f6bd661e3cdaf7a167b4e..70492ac2b133959a22eb381cc4ae4d720cb22fb7 100644
--- a/src/ctrl_io/mod.rs
+++ b/src/ctrl_io/mod.rs
@@ -562,7 +562,7 @@ pub fn overall_parse_and_report_on_ctrl_geom(ctrl: &mut InputKeywords, geom: &mu
} else if ctrl.restart && ! ctrl.external_init_guess {
println!("The initial guess will be obtained from the existing checkfile \n({})",&ctrl.chkfile)
} else {
- println!("The specified checkfile exists but is not loaded because the keyword 'external_init_guess' is specified");
+ println!("The specified checkfile exists but is not loaded because the guessfile is specified");
println!("It will be updated after the SCF procedure \n({})",&ctrl.chkfile)
};
@@ -1593,21 +1593,11 @@ pub fn parse_ctrl_keywords(tmp_keys: &serde_json::Value) -> anyhow::Result0 {
- // println!("The initial guess will be imported from \n({}).\n ",&tmp_input.guessfile);
- //}
- }
- }
if tmp_input.force_state_occupation.len()>0 {
- if ! tmp_input.restart {
- panic!("ERROR: force_state_occupation can not be involved without an existing chkfile \'restart\'");
+ if ! tmp_input.restart && ! tmp_input.external_init_guess {
+ panic!("ERROR: force_state_occupation can not be involved without an existing guessfile/chkfile");
} else if ! std::path::Path::new(&tmp_input.chkfile).exists() {
- panic!("ERROR: force_state_occupation can not be involved without an existing chkfile \'restart\'");
+ panic!("ERROR: force_state_occupation can not be involved without an existing guessfile/chkfile");
}
}
},
diff --git a/src/initial_guess/chkfile.rs b/src/initial_guess/chkfile.rs
new file mode 100644
index 0000000000000000000000000000000000000000..329d9a408bdbc6755e8cdfa3d07c9ed79f368598
--- /dev/null
+++ b/src/initial_guess/chkfile.rs
@@ -0,0 +1,17 @@
+pub fn has_dm(file: &hdf5::File) -> bool {
+ let mut has_dm = false;
+ if let Ok(_init_guess) = file.dataset("init_guess") {
+ has_dm = true;
+ }
+
+ has_dm
+}
+
+pub fn has_mo_coeff(file: &hdf5::File) -> bool {
+ let mut has_mo = false;
+ if let Ok(_mo_coeff) = file.dataset("scf/mo_coeff") {
+ has_mo = true;
+ }
+
+ has_mo
+}
\ No newline at end of file
diff --git a/src/initial_guess/mod.rs b/src/initial_guess/mod.rs
index 61bcf956ddf269360196d2a8d88a7b65539cc6b1..eb2d242b60e51e94c877c7f817d589e751d736b0 100644
--- a/src/initial_guess/mod.rs
+++ b/src/initial_guess/mod.rs
@@ -16,6 +16,8 @@ pub mod sap;
pub mod sad;
pub mod enxc;
mod pyrest_enxc;
+mod chkfile;
+use chkfile::{has_dm, has_mo_coeff};
enum RESTART {
HDF5,
@@ -27,78 +29,31 @@ pub fn initial_guess(scf_data: &mut SCF, mpi_operator: &Option) {
if scf_data.mol.ctrl.initial_guess.eq(&"inherit") {
scf_data.generate_occupation();
scf_data.generate_density_matrix();
- // import the initial guess density from a hdf5 file
+ // import the initial guess from guessfile
} else if scf_data.mol.ctrl.external_init_guess && scf_data.mol.ctrl.guessfile_type.eq(&"hdf5") {
- scf_data.density_matrix = initial_guess_from_hdf5guess(&scf_data.mol);
- // for DFT methods, it needs the eigenvectors to generate the hamiltonian. In consequence, we use the hf method to prepare the eigenvectors from the guess dm
- scf_data.generate_hf_hamiltonian_for_guess();
- //scf_data.generate_hf_hamiltonian();
- if scf_data.mol.ctrl.print_level>0 {println!("Initial guess energy: {:16.8}", scf_data.evaluate_hf_total_energy())};
- scf_data.diagonalize_hamiltonian(mpi_operator);
- scf_data.generate_occupation();
- scf_data.generate_density_matrix();
- // import the eigenvalues and eigen vectors from a hdf5 file directly
+ let file = hdf5::File::open(&scf_data.mol.ctrl.guessfile).unwrap();
+ if has_dm(&file) {
+ scf_data.density_matrix = initial_guess_from_hdf5guess(&scf_data.mol);
+ // for DFT methods, it needs the eigenvectors to generate the hamiltonian. In consequence, we use the hf method to prepare the eigenvectors from the guess dm
+ scf_data.generate_hf_hamiltonian_for_guess();
+ //scf_data.generate_hf_hamiltonian();
+ if scf_data.mol.ctrl.print_level>0 {println!("Initial guess energy: {:16.8}", scf_data.evaluate_hf_total_energy())};
+ scf_data.diagonalize_hamiltonian(mpi_operator);
+ scf_data.generate_occupation();
+ scf_data.generate_density_matrix();
+ } else if has_mo_coeff(&file) {
+ println!("Read MO coefficients from guessfile: {}", &scf_data.mol.ctrl.guessfile);
+ // let (eigenvectors, eigenvalues, is_occupation) = initial_guess_from_hdf5chk(
+ // &scf_data.mol, &scf_data.scftype, &scf_data.mol.ctrl.guessfile);
+ update_scf_from_hdf5chk(scf_data, scf_data.mol.ctrl.guessfile.clone());
+ }
+ // import the eigenvalues and eigen vectors from chkfile
} else if scf_data.mol.ctrl.restart && std::path::Path::new(&scf_data.mol.ctrl.chkfile).exists() {
if scf_data.mol.ctrl.chkfile_type.eq(&"hdf5") {
- let (eigenvectors, eigenvalues, is_occupation) = initial_guess_from_hdf5chk(&scf_data.mol, &scf_data.scftype);
-
- //=============================
- // for MOM projection
- //=============================
- if scf_data.mol.ctrl.force_state_occupation.len()>0 {
- let restart = scf_data.mol.ctrl.chkfile.clone();
- //let is_exist = scf_data.ref_eigenvectors.contains_key(&restart);
- //if ! is_exist {
- scf_data.ref_eigenvectors.insert(
- restart,
- (eigenvectors.clone(),[0,scf_data.mol.num_basis,scf_data.mol.num_state,scf_data.mol.spin_channel])
- );
- //};
- match scf_data.scftype {
- SCFType::RHF => {
- scf_data.mol.ctrl.force_state_occupation.iter().enumerate().for_each(|(i,x)| {
- if x.get_force_occ() > 2.0 {
- println!("ERROR: the orbital occupation number for RHF cannot be larger than 2.0");
- panic!("{}", x.formated_output_check());
- }
- if x.get_occ_spin() > 0 {
- println!("ERROR: the spin is unpolarized for RHF, and thus cannot manipulate the orbitals in BETA spin-channel");
- panic!("{}", x.formated_output_check());
- }
- })
- },
- _ => {
- scf_data.mol.ctrl.force_state_occupation.iter().enumerate().for_each(|(i,x)| {
- if x.get_force_occ() > 1.0 {
- println!("ERROR: the orbital occupation number for UHF and ROHF cannot be larger than 1.0");
- panic!("{}", x.formated_output_check());
- }
- })
-
- }
- }
- }
- //println!("{:?}", &scf_data.mol.ctrl.auxiliary_reference_states);
- if scf_data.mol.ctrl.auxiliary_reference_states.len() > 0 {
- scf_data.mol.ctrl.auxiliary_reference_states.iter().for_each(|(chkname,global_index)| {
- println!("{}", chkname);
- let is_exist = scf_data.ref_eigenvectors.contains_key(chkname);
- if ! is_exist {
- let (reference,[num_basis, num_state, spin_channel]) = import_mo_coeff_from_hdf5chkfile(chkname);
- println!("{},{},{},{},{}", chkname,global_index, num_basis, num_state, spin_channel);
- scf_data.ref_eigenvectors.insert(chkname.clone(), (reference,[global_index.clone(),num_basis, num_state, spin_channel]));
- }
- });
- ; }
- //=============================
- scf_data.eigenvalues = eigenvalues;
- scf_data.eigenvectors = eigenvectors;
- if let Some(occupation) = is_occupation {
- scf_data.occupation = occupation;
- } else {
- scf_data.generate_occupation();
- }
- scf_data.generate_density_matrix();
+ println!("Read MO coefficients from chkfile: {}", &scf_data.mol.ctrl.chkfile);
+ println!("However, the chkfile will be overwritten in the SCF procedure.");
+ println!("To prevent that, use `guessfile = your_chkfile` instead");
+ update_scf_from_hdf5chk(scf_data, scf_data.mol.ctrl.chkfile.clone());
} else {
panic!("WARNNING: at present only hdf5 type check file is supported");
}
@@ -216,6 +171,68 @@ pub fn initial_guess(scf_data: &mut SCF, mpi_operator: &Option) {
};
}
+pub fn update_scf_from_hdf5chk(scf_data: &mut SCF, chkfile: String) {
+ let (eigenvectors, eigenvalues, is_occupation) = initial_guess_from_hdf5chk(
+ &scf_data.mol, &scf_data.scftype, &chkfile);
+
+ //=============================
+ // for MOM projection
+ //=============================
+ if scf_data.mol.ctrl.force_state_occupation.len()>0 {
+ let restart = chkfile.clone();
+ //let is_exist = scf_data.ref_eigenvectors.contains_key(&restart);
+ //if ! is_exist {
+ scf_data.ref_eigenvectors.insert(
+ restart,
+ (eigenvectors.clone(),[0,scf_data.mol.num_basis,scf_data.mol.num_state,scf_data.mol.spin_channel])
+ );
+ //};
+ match scf_data.scftype {
+ SCFType::RHF => {
+ scf_data.mol.ctrl.force_state_occupation.iter().enumerate().for_each(|(i,x)| {
+ if x.get_force_occ() > 2.0 {
+ println!("ERROR: the orbital occupation number for RHF cannot be larger than 2.0");
+ panic!("{}", x.formated_output_check());
+ }
+ if x.get_occ_spin() > 0 {
+ println!("ERROR: the spin is unpolarized for RHF, and thus cannot manipulate the orbitals in BETA spin-channel");
+ panic!("{}", x.formated_output_check());
+ }
+ })
+ },
+ _ => {
+ scf_data.mol.ctrl.force_state_occupation.iter().enumerate().for_each(|(i,x)| {
+ if x.get_force_occ() > 1.0 {
+ println!("ERROR: the orbital occupation number for UHF and ROHF cannot be larger than 1.0");
+ panic!("{}", x.formated_output_check());
+ }
+ })
+
+ }
+ }
+ }
+ //println!("{:?}", &scf_data.mol.ctrl.auxiliary_reference_states);
+ if scf_data.mol.ctrl.auxiliary_reference_states.len() > 0 {
+ scf_data.mol.ctrl.auxiliary_reference_states.iter().for_each(|(chkname,global_index)| {
+ println!("{}", chkname);
+ let is_exist = scf_data.ref_eigenvectors.contains_key(chkname);
+ if ! is_exist {
+ let (reference,[num_basis, num_state, spin_channel]) = import_mo_coeff_from_hdf5chkfile(chkname);
+ println!("{},{},{},{},{}", chkname,global_index, num_basis, num_state, spin_channel);
+ scf_data.ref_eigenvectors.insert(chkname.clone(), (reference,[global_index.clone(),num_basis, num_state, spin_channel]));
+ }
+ });
+ }
+ //=============================
+ scf_data.eigenvalues = eigenvalues;
+ scf_data.eigenvectors = eigenvectors;
+ if let Some(occupation) = is_occupation {
+ scf_data.occupation = occupation;
+ } else {
+ scf_data.generate_occupation();
+ }
+ scf_data.generate_density_matrix();
+ }
pub fn initial_guess_from_hdf5guess(mol: &Molecule) -> Vec> {
if mol.ctrl.print_level>0 {println!("Importing density matrix from external initial guess file")};
@@ -230,21 +247,19 @@ pub fn initial_guess_from_hdf5guess(mol: &Molecule) -> Vec> {
dm
}
-pub fn initial_guess_from_hdf5chk(mol: &Molecule, scftype: &SCFType) -> ([MatrixFull;2],[Vec;2],Option<[Vec;2]>) {
-
+pub fn initial_guess_from_hdf5chk(mol: &Molecule, scftype: &SCFType, chkfile: &String) -> ([MatrixFull;2],[Vec;2],Option<[Vec;2]>) {
+ let mut spin_channel: usize;
if let &SCFType::ROHF = scftype {
- initial_guess_from_hdf5chkfile(&mol.ctrl.chkfile,
- 1, // only one set of MO_coeff and MO_energy
- mol.num_state,
- mol.num_basis,
- mol.ctrl.print_level)
+ spin_channel = 1;
+
} else {
- initial_guess_from_hdf5chkfile(&mol.ctrl.chkfile,
- mol.spin_channel,
+ spin_channel = mol.spin_channel;
+ }
+ initial_guess_from_hdf5chkfile(chkfile,
+ spin_channel,
mol.num_state,
mol.num_basis,
mol.ctrl.print_level)
- }
}
pub fn initial_guess_from_hdf5chkfile(