Skip to content

Commit

Permalink
restructured the way qm calculations are done
Browse files Browse the repository at this point in the history
  • Loading branch information
MFSJMenger committed Oct 4, 2024
1 parent b4e8cf1 commit 9110c85
Show file tree
Hide file tree
Showing 15 changed files with 1,158 additions and 722 deletions.
542 changes: 0 additions & 542 deletions qforce/additionalstructures.py

This file was deleted.

1 change: 1 addition & 0 deletions qforce/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def __init__(self, config, job):

@classmethod
def from_config(cls, _config):
print("config = ", _config)
config, job = initialize(_config)
return cls(config, job)

Expand Down
18 changes: 3 additions & 15 deletions qforce/initialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from colt import Colt
from calkeeper import CalculationKeeper
#
from .additionalstructures import AdditionalStructures
from .qm.qm import QM, implemented_qm_software, calculators
from .schemes import Computations
from .qm.qm import QM, calculators
from .forcefield.forcefield import ForceField
from .dihedral_scan import DihedralScan
from .pathkeeper import Pathways
Expand Down Expand Up @@ -36,19 +36,7 @@ def _extend_user_input(cls, questions):
questions.generate_block("qm", QM.colt_user_input)
questions.generate_block("ff", ForceField.colt_user_input)
questions.generate_block("scan", DihedralScan.colt_user_input)
questions.generate_cases("software", {key: software.colt_user_input for key, software in
implemented_qm_software.items()}, block='qm')
questions.generate_cases("preopt", {key: software.colt_user_input for key, software in
implemented_qm_software.items()}, block='qm')
questions.generate_cases("scan_software", {key: software.colt_user_input
for key, software in
implemented_qm_software.items()},
block='qm')
questions.generate_cases("charge_software", {key: software.colt_user_input
for key, software
in implemented_qm_software.items()},
block='qm')
questions.generate_block("addstructs", AdditionalStructures.colt_user_input)
questions.generate_block("addstructs", Computations.colt_user_input)
# ff terms
for name, ffcls in ForceField.implemented_md_software.items():
questions.generate_block(name, ffcls.get_questions(), block='ff')
Expand Down
92 changes: 76 additions & 16 deletions qforce/main.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,100 @@
from io import StringIO
#
from ase.io import read, write
from calkeeper import CalculationKeeper, CalculationIncompleteError

#
from .initialize import initialize
from .qm.qm import QM
from .qm.qm_base import HessianOutput
from .forcefield.forcefield import ForceField
from .molecule import Molecule
from .fragment import fragment
from .no_fragment_scanning import do_nofrag_scanning
from .dihedral_scan import DihedralScan
from .frequencies import calc_qm_vs_md_frequencies
from .fit import multi_fit
from .charge_flux import fit_charge_flux
from .misc import LOGO
from .logger import LoggerExit
from .additionalstructures import AdditionalStructures
#
from .schemes import Computations, HessianCreator, PreoptCreator, DihedralCreator


def runjob(config, job, ext_q=None, ext_lj=None):
qm = QM(job, config.qm)
qm.preopt()
qm_hessian_out = qm.get_hessian()
main_hessian = qm_hessian_out[0]
CRESTPREOPT = StringIO('''
preopt = crest
software = xtb
''')

structs = AdditionalStructures.from_config(config.addstructs)
structs.create(qm)
structs.add_hessians(qm_hessian_out)

def save_molecule(filename, molecule, comment=None):
write(filename, molecule, plain=True, comment=comment)


def runjob2(config, job, ext_q=None, ext_lj=None):
# setup the xtb preopt using crest
xtb = QM.from_questions(job, config=CRESTPREOPT, check_only=True)
# read initial structure, ase molecule structure
molecule = read(job.coord_file)
# run preopt
preopt = PreoptCreator(molecule)
preopt.run(xtb)
molecule = preopt.molecule()
# setup hessian calculation
save_molecule(xtb.pathways.get('init.xyz'), molecule,
comment=f'{job.name} - input geometry for hessian')
# get main hessian
hessian = HessianCreator(molecule)
hessian.run(xtb)
main_hessian = hessian.main_hessian()

ffcls = ForceField.implemented_md_software.get(config.ff.output_software, None)
if ffcls is None:
raise ValueError(f"Forcefield '{config.ff.output_software}' unknown!")

mol = Molecule(config, job, main_hessian, ffcls, ext_q, ext_lj)

scans = do_nofrag_scanning(mol, qm, job, config)
structs.add_dihedrals(scans)
structs = Computations.from_config(config.addstructs)
structs.register('dihedrals', DihedralCreator(mol, job, config))
# setup the actual qm calculations
qm = QM(job, config.qm)
# do all additional calculations
structs.run(qm)
# register hessian after structs were run!
structs.register('hessian', hessian)
#
mol.qm_minimum_energy, mol.qm_minimum_coords = structs.normalize()

md_hessian = multi_fit(job.logger, config.terms, mol, structs)

return mol, structs


def runjob(config, job, ext_q=None, ext_lj=None):
# setup qm calculation
qm = QM(job, config.qm)
# read initial structure, ase molecule structure
molecule = read(job.coord_file)
# run preopt
preopt = PreoptCreator(molecule)
preopt.run(qm)
molecule = preopt.molecule()
# setup hessian calculation
save_molecule(qm.pathways.get('init.xyz'), molecule,
comment=f'{job.name} - input geometry for hessian')
# get main hessian
hessian = HessianCreator(molecule)
hessian.run(qm)
main_hessian = hessian.main_hessian()

ffcls = ForceField.implemented_md_software.get(config.ff.output_software, None)
if ffcls is None:
raise ValueError(f"Forcefield '{config.ff.output_software}' unknown!")

mol = Molecule(config, job, main_hessian, ffcls, ext_q, ext_lj)

structs = AdditionalStructures.from_config(config.addstructs)
structs.register('dihedrals', DihedralCreator(mol, job, config))
# do all additional calculations
structs.run(qm)
# register hessian after structs were run!
structs.register('hessian', hessian)
#
mol.qm_minimum_energy, mol.qm_minimum_coords = structs.normalize()

md_hessian = multi_fit(job.logger, config.terms, mol, structs)
Expand Down
125 changes: 0 additions & 125 deletions qforce/no_fragment_scanning.py

This file was deleted.

5 changes: 5 additions & 0 deletions qforce/pathkeeper.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class Pathways:
'preopt': '0_preopt',
'hessian': '1_hessian',
'addstruct': '5_additional',
'hessian_new': 'hessian_new',
'hessian_charge': ['hessian', 'charge'],
'hessian_energy': ['hessian', '${idx}_en_conformer'],
'hessian_gradient': ['hessian', '${idx}_grad_conformer'],
Expand Down Expand Up @@ -173,6 +174,10 @@ def charge_filename(self, software, charge, mult):
base, ending = self.basename(software, charge, mult)
return f'{base}_charge.{ending}'

def scan_filename(self, software, charge, mult):
base, ending = self.basename(software, charge, mult)
return f'{base}_sp.{ending}'

def scan_sp_filename(self, software, charge, mult, i):
base, ending = self.basename(software, charge, mult)
return f'{base}_sp_step_{i:02d}.{ending}'
Expand Down
Loading

0 comments on commit 9110c85

Please sign in to comment.