Implements Refactoring in Player Class and Initial Working Version
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
diceplayer:
|
||||
maxcyc: 3
|
||||
opt: no
|
||||
ncores: 4
|
||||
mem: 24
|
||||
maxcyc: 10
|
||||
ncores: 5
|
||||
nprocs: 4
|
||||
qmprog: 'g16'
|
||||
lps: no
|
||||
@@ -9,9 +10,9 @@ diceplayer:
|
||||
altsteps: 20000
|
||||
|
||||
dice:
|
||||
nmol: [1, 50]
|
||||
dens: 0.75
|
||||
nstep: [2000, 3000, 4000]
|
||||
nmol: [1, 1000]
|
||||
dens: 1.0
|
||||
nstep: [2000, 3000]
|
||||
isave: 1000
|
||||
outname: 'phb'
|
||||
progname: '~/.local/bin/dice'
|
||||
@@ -21,4 +22,3 @@ dice:
|
||||
gaussian:
|
||||
qmprog: 'g16'
|
||||
level: 'MP2/aug-cc-pVDZ'
|
||||
keywords: 'freq'
|
||||
|
||||
@@ -55,8 +55,25 @@ def main():
|
||||
|
||||
player = Player(args.infile)
|
||||
|
||||
player.print_keywords()
|
||||
|
||||
player.create_simulation_dir()
|
||||
|
||||
player.read_potentials()
|
||||
player.print_potentials()
|
||||
|
||||
player.prepare_system()
|
||||
|
||||
player.start()
|
||||
|
||||
logger.info("\n+" + 88 * "-" + "+\n")
|
||||
|
||||
player.print_results()
|
||||
|
||||
logger.info("\n+" + 88 * "-" + "+\n")
|
||||
|
||||
logger.info("Diceplayer finished successfully \n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
from diceplayer.shared.interface.gaussian_interface import GaussianInterface
|
||||
from diceplayer.shared.interface.dice_interface import DiceInterface
|
||||
from diceplayer.shared.utils.dataclass_protocol import Dataclass
|
||||
from diceplayer.shared.config.gaussian_dto import GaussianDTO
|
||||
from diceplayer.shared.environment.molecule import Molecule
|
||||
from diceplayer.shared.config.gaussian_config import GaussianDTO
|
||||
from diceplayer.shared.config.player_config import PlayerConfig
|
||||
from diceplayer.shared.config.dice_config import DiceConfig
|
||||
from diceplayer.shared.utils.misc import weekday_date_time
|
||||
from diceplayer.shared.config.player_dto import PlayerDTO
|
||||
from diceplayer.shared.environment.molecule import Molecule
|
||||
from diceplayer.shared.environment.system import System
|
||||
from diceplayer.shared.config.step_dto import StepDTO
|
||||
from diceplayer.shared.config.dice_dto import DiceDTO
|
||||
from diceplayer.shared.environment.atom import Atom
|
||||
from diceplayer import logger
|
||||
|
||||
from dataclasses import fields
|
||||
from pathlib import Path
|
||||
from typing import Type
|
||||
from typing import Type, List
|
||||
import logging
|
||||
import yaml
|
||||
import sys
|
||||
@@ -33,20 +32,50 @@ class Player:
|
||||
config_data.get("diceplayer")
|
||||
)
|
||||
|
||||
self.gaussian = GaussianInterface(config_data.get("gaussian"))
|
||||
self.dice = DiceInterface(config_data.get("dice"))
|
||||
self.dice_interface = DiceInterface()
|
||||
self.gaussian_interface = GaussianInterface()
|
||||
|
||||
def start(self, initial_cycle: int = 1):
|
||||
self.print_keywords()
|
||||
|
||||
self.create_simulation_dir()
|
||||
|
||||
self.read_potentials()
|
||||
self.print_potentials()
|
||||
logger.info(
|
||||
"==========================================================================================\n"
|
||||
"Starting the iterative process.\n"
|
||||
"==========================================================================================\n"
|
||||
)
|
||||
|
||||
for cycle in range(initial_cycle, self.config.maxcyc + 1):
|
||||
|
||||
logger.info(
|
||||
f"------------------------------------------------------------------------------------------\n"
|
||||
f" Step # {cycle}\n"
|
||||
f"------------------------------------------------------------------------------------------\n"
|
||||
)
|
||||
|
||||
self.dice_start(cycle)
|
||||
|
||||
try:
|
||||
self.gaussian_start(cycle)
|
||||
except StopIteration as e:
|
||||
break
|
||||
|
||||
def prepare_system(self):
|
||||
for i, mol in enumerate(self.system.molecule):
|
||||
logger.info(
|
||||
f"Molecule {i + 1} - {mol.molname}"
|
||||
)
|
||||
|
||||
mol.print_mol_info()
|
||||
logger.info(
|
||||
"\n Translating and rotating molecule to standard orientation..."
|
||||
)
|
||||
|
||||
mol.standard_orientation()
|
||||
logger.info("\n Done")
|
||||
logger.info("\nNew values:\n")
|
||||
mol.print_mol_info()
|
||||
|
||||
logger.info("\n")
|
||||
|
||||
|
||||
def create_simulation_dir(self):
|
||||
simulation_dir_path = Path(self.config.simulation_dir)
|
||||
if simulation_dir_path.exists():
|
||||
@@ -71,13 +100,10 @@ class Player:
|
||||
"##########################################################################################\n"
|
||||
"############# Welcome to DICEPLAYER version 1.0 #############\n"
|
||||
"##########################################################################################\n"
|
||||
"\n"
|
||||
)
|
||||
logger.info("Your python version is {}\n".format(sys.version))
|
||||
logger.info("\n")
|
||||
logger.info("Program started on {}\n".format(weekday_date_time()))
|
||||
logger.info("\n")
|
||||
logger.info("Environment variables:\n")
|
||||
logger.info("Environment variables:")
|
||||
for var in ENV:
|
||||
logger.info(
|
||||
"{} = {}\n".format(
|
||||
@@ -85,68 +111,55 @@ class Player:
|
||||
)
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"\n==========================================================================================\n"
|
||||
" CONTROL variables being used in this run:\n"
|
||||
"------------------------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
)
|
||||
|
||||
logger.info("\n")
|
||||
|
||||
logger.info(
|
||||
"------------------------------------------------------------------------------------------\n"
|
||||
" DICE variables being used in this run:\n"
|
||||
"------------------------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
)
|
||||
|
||||
log_keywords(self.dice.config, DiceDTO)
|
||||
|
||||
logger.info("\n")
|
||||
log_keywords(self.config.dice, DiceConfig)
|
||||
|
||||
logger.info(
|
||||
"------------------------------------------------------------------------------------------\n"
|
||||
" GAUSSIAN variables being used in this run:\n"
|
||||
"------------------------------------------------------------------------------------------\n"
|
||||
"\n"
|
||||
)
|
||||
|
||||
log_keywords(self.gaussian.config, GaussianDTO)
|
||||
log_keywords(self.config.gaussian, GaussianDTO)
|
||||
|
||||
logger.info("\n")
|
||||
|
||||
def read_potentials(self):
|
||||
ljname_path = Path(self.dice.config.ljname)
|
||||
ljname_path = Path(self.config.dice.ljname)
|
||||
if ljname_path.exists():
|
||||
with open(self.dice.config.ljname) as file:
|
||||
with open(self.config.dice.ljname) as file:
|
||||
ljc_data = file.readlines()
|
||||
else:
|
||||
raise RuntimeError(
|
||||
f"Potential file {self.dice.config.ljname} not found."
|
||||
f"Potential file {self.config.dice.ljname} not found."
|
||||
)
|
||||
|
||||
combrule = ljc_data.pop(0).split()[0]
|
||||
if combrule not in ("*", "+"):
|
||||
sys.exit(
|
||||
"Error: expected a '*' or a '+' sign in 1st line of file {}".format(
|
||||
self.dice.config.ljname
|
||||
self.config.dice.ljname
|
||||
)
|
||||
)
|
||||
self.dice.config.combrule = combrule
|
||||
self.config.dice.combrule = combrule
|
||||
|
||||
ntypes = ljc_data.pop(0).split()[0]
|
||||
if not ntypes.isdigit():
|
||||
sys.exit(
|
||||
"Error: expected an integer in the 2nd line of file {}".format(
|
||||
self.dice.config.ljname
|
||||
self.config.dice.ljname
|
||||
)
|
||||
)
|
||||
ntypes = int(ntypes)
|
||||
|
||||
if ntypes != len(self.dice.config.nmol):
|
||||
if ntypes != len(self.config.dice.nmol):
|
||||
sys.exit(
|
||||
f"Error: number of molecule types in file {self.dice.config.ljname} "
|
||||
f"Error: number of molecule types in file {self.config.dice.ljname} "
|
||||
f"must match that of 'nmol' keyword in config file"
|
||||
)
|
||||
|
||||
@@ -165,7 +178,7 @@ class Player:
|
||||
)
|
||||
|
||||
nsites = int(nsites)
|
||||
self.system.add_type(nsites, Molecule(molname))
|
||||
self.system.add_type(Molecule(molname))
|
||||
|
||||
atom_fields = ["lbl", "na", "rx", "ry", "rz", "chg", "eps", "sig"]
|
||||
for j in range(nsites):
|
||||
@@ -178,20 +191,15 @@ class Player:
|
||||
)
|
||||
|
||||
def print_potentials(self) -> None:
|
||||
|
||||
formatstr = "{:<3d} {:>3d} {:>10.5f} {:>10.5f} {:>10.5f} {:>10.6f} {:>9.5f} {:>7.4f} {:>9.4f}"
|
||||
logger.info(
|
||||
"==========================================================================================\n"
|
||||
)
|
||||
logger.info(
|
||||
f" Potential parameters from file {self.dice.config.ljname}:"
|
||||
)
|
||||
logger.info(
|
||||
f" Potential parameters from file {self.config.dice.ljname}:\n"
|
||||
"------------------------------------------------------------------------------------------"
|
||||
"\n"
|
||||
)
|
||||
|
||||
logger.info(f"Combination rule: {self.dice.config.combrule}")
|
||||
logger.info(f"Combination rule: {self.config.dice.combrule}")
|
||||
logger.info(
|
||||
f"Types of molecules: {len(self.system.molecule)}\n"
|
||||
)
|
||||
@@ -229,28 +237,50 @@ class Player:
|
||||
|
||||
logger.info("\n")
|
||||
|
||||
logger.info(
|
||||
"=========================================================================================="
|
||||
)
|
||||
|
||||
def dice_start(self, cycle: int):
|
||||
self.dice.configure(
|
||||
StepDTO(
|
||||
ncores=self.config.ncores,
|
||||
nprocs=self.config.nprocs,
|
||||
simulation_dir=self.config.simulation_dir,
|
||||
altsteps=self.config.altsteps,
|
||||
molecule=self.system.molecule,
|
||||
nmol=self.system.nmols,
|
||||
)
|
||||
self.dice_interface.configure(
|
||||
self.config,
|
||||
self.system,
|
||||
)
|
||||
|
||||
self.dice.start(cycle)
|
||||
self.dice_interface.start(cycle)
|
||||
|
||||
self.dice.reset()
|
||||
self.dice_interface.reset()
|
||||
|
||||
def gaussian_start(self, cycle: int):
|
||||
self.gaussian.start(cycle)
|
||||
self.gaussian_interface.configure(
|
||||
self.config,
|
||||
self.system,
|
||||
)
|
||||
|
||||
result = self.gaussian_interface.start(cycle)
|
||||
|
||||
self.gaussian_interface.reset()
|
||||
|
||||
if self.config.opt:
|
||||
if 'position' not in result:
|
||||
raise RuntimeError(
|
||||
'Optimization failed. No position found in result.'
|
||||
)
|
||||
|
||||
self.system.update_molecule(result['position'])
|
||||
|
||||
else:
|
||||
if 'charges' not in result:
|
||||
raise RuntimeError(
|
||||
'Charges optimization failed. No charges found in result.'
|
||||
)
|
||||
|
||||
diff = self.system.molecule[0]\
|
||||
.update_charges(result['charges'])
|
||||
|
||||
self.system.print_charges_and_dipole(cycle)
|
||||
|
||||
if diff < self.config.gaussian.chg_tol:
|
||||
logger.info(
|
||||
f'Charges converged after {cycle} cycles.'
|
||||
)
|
||||
raise StopIteration()
|
||||
|
||||
@staticmethod
|
||||
def validate_atom_dict(molecule_type, molecule_site, atom_dict: dict) -> dict:
|
||||
@@ -326,9 +356,43 @@ class Player:
|
||||
|
||||
return atom_dict
|
||||
|
||||
def print_results(self):
|
||||
formatstr = "{:<3d} {:>3d} {:>10.5f} {:>10.5f} {:>10.5f} {:>10.6f} {:>9.5f} {:>7.4f} {:>9.4f}"
|
||||
|
||||
mol = self.system.molecule[0]
|
||||
logger.info(
|
||||
"{} atoms in molecule type {}:".format(len(mol.atom), 1)
|
||||
)
|
||||
logger.info(
|
||||
"---------------------------------------------------------------------------------"
|
||||
)
|
||||
logger.info(
|
||||
"Lbl AN X Y Z Charge Epsilon Sigma Mass"
|
||||
)
|
||||
logger.info(
|
||||
"---------------------------------------------------------------------------------"
|
||||
)
|
||||
|
||||
for atom in mol.atom:
|
||||
logger.info(
|
||||
formatstr.format(
|
||||
atom.lbl,
|
||||
atom.na,
|
||||
atom.rx,
|
||||
atom.ry,
|
||||
atom.rz,
|
||||
atom.chg,
|
||||
atom.eps,
|
||||
atom.sig,
|
||||
atom.mass,
|
||||
)
|
||||
)
|
||||
|
||||
logger.info("\n")
|
||||
|
||||
@staticmethod
|
||||
def set_config(data: dict) -> PlayerDTO:
|
||||
return PlayerDTO.from_dict(data)
|
||||
def set_config(data: dict) -> PlayerConfig:
|
||||
return PlayerConfig.from_dict(data)
|
||||
|
||||
@staticmethod
|
||||
def read_keywords(infile) -> dict:
|
||||
|
||||
@@ -6,7 +6,7 @@ from typing import List
|
||||
|
||||
|
||||
@dataclass
|
||||
class DiceDTO(Dataclass):
|
||||
class DiceConfig(Dataclass):
|
||||
"""
|
||||
Data Transfer Object for the Dice configuration.
|
||||
"""
|
||||
@@ -53,4 +53,4 @@ class DiceDTO(Dataclass):
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, param: dict):
|
||||
return from_dict(DiceDTO, param)
|
||||
return from_dict(DiceConfig, param)
|
||||
@@ -11,10 +11,11 @@ class GaussianDTO(Dataclass):
|
||||
"""
|
||||
level: str
|
||||
qmprog: str
|
||||
keywords: str
|
||||
|
||||
chgmult = [0, 1]
|
||||
pop: str = 'chelpg'
|
||||
chg_tol: float = 0.01
|
||||
keywords: str = None
|
||||
|
||||
def __post_init__(self):
|
||||
if self.qmprog not in ("g03", "g09", "g16"):
|
||||
47
diceplayer/shared/config/player_config.py
Normal file
47
diceplayer/shared/config/player_config.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from diceplayer.shared.utils.dataclass_protocol import Dataclass
|
||||
from diceplayer.shared.config.gaussian_config import GaussianDTO
|
||||
from diceplayer.shared.config.dice_config import DiceConfig
|
||||
|
||||
from dataclasses import dataclass
|
||||
from dacite import from_dict
|
||||
|
||||
|
||||
@dataclass
|
||||
class PlayerConfig(Dataclass):
|
||||
"""
|
||||
Data Transfer Object for the player configuration.
|
||||
"""
|
||||
opt: bool
|
||||
maxcyc: int
|
||||
nprocs: int
|
||||
ncores: int
|
||||
|
||||
dice: DiceConfig
|
||||
gaussian: GaussianDTO
|
||||
|
||||
mem: int = None
|
||||
switchcyc: int = 3
|
||||
qmprog: str = 'g16'
|
||||
altsteps: int = 20000
|
||||
simulation_dir = 'simfiles'
|
||||
|
||||
def __post_init__(self):
|
||||
MIN_STEP = 20000
|
||||
# altsteps value is always the nearest multiple of 1000
|
||||
self.altsteps = round(max(MIN_STEP, self.altsteps) / 1000) * 1000
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, param: dict):
|
||||
if param['dice'] is None:
|
||||
raise ValueError(
|
||||
"Error: 'dice' keyword not specified in config file."
|
||||
)
|
||||
param['dice'] = DiceConfig.from_dict(param['dice'])
|
||||
|
||||
if param['gaussian'] is None:
|
||||
raise ValueError(
|
||||
"Error: 'gaussian' keyword not specified in config file."
|
||||
)
|
||||
param['gaussian'] = GaussianDTO.from_dict(param['gaussian'])
|
||||
|
||||
return from_dict(PlayerConfig, param)
|
||||
@@ -1,28 +0,0 @@
|
||||
from diceplayer.shared.utils.dataclass_protocol import Dataclass
|
||||
|
||||
from dataclasses import dataclass
|
||||
from dacite import from_dict
|
||||
|
||||
|
||||
@dataclass
|
||||
class PlayerDTO(Dataclass):
|
||||
"""
|
||||
Data Transfer Object for the player configuration.
|
||||
"""
|
||||
opt: bool
|
||||
maxcyc: int
|
||||
nprocs: int
|
||||
ncores: int
|
||||
|
||||
qmprog: str = 'g16'
|
||||
altsteps: int = 20000
|
||||
simulation_dir = 'simfiles'
|
||||
|
||||
def __post_init__(self):
|
||||
MIN_STEP = 20000
|
||||
# altsteps value is always the nearest multiple of 1000
|
||||
self.altsteps = round(max(MIN_STEP, self.altsteps) / 1000) * 1000
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, param: dict):
|
||||
return from_dict(PlayerDTO, param)
|
||||
@@ -1,22 +0,0 @@
|
||||
from diceplayer.shared.environment.molecule import Molecule
|
||||
from diceplayer.shared.config.player_dto import PlayerDTO
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
|
||||
|
||||
@dataclass
|
||||
class StepDTO:
|
||||
"""
|
||||
Data Transfer Object for the step configuration.
|
||||
"""
|
||||
ncores: int
|
||||
nprocs: int
|
||||
simulation_dir: str
|
||||
|
||||
altsteps: int
|
||||
|
||||
nmol: List[int] = None
|
||||
molecule: List[Molecule] = None
|
||||
charges: List[float] = None
|
||||
position: List[float] = None
|
||||
@@ -1,15 +1,18 @@
|
||||
import logging
|
||||
import math
|
||||
from copy import deepcopy
|
||||
from typing import List, Any, Tuple, Final, Union
|
||||
|
||||
import numpy as np
|
||||
from nptyping import NDArray, Shape, Float
|
||||
from numpy.linalg import linalg
|
||||
from __future__ import annotations
|
||||
|
||||
from diceplayer.shared.utils.ptable import ghost_number
|
||||
from diceplayer.shared.environment.atom import Atom
|
||||
from diceplayer.shared.utils.misc import BOHR2ANG
|
||||
from diceplayer.shared.utils.ptable import ghost_number
|
||||
from diceplayer import logger
|
||||
|
||||
from nptyping import NDArray, Shape, Float
|
||||
from numpy.linalg import linalg
|
||||
import numpy as np
|
||||
|
||||
from typing import List, Any, Tuple, Union
|
||||
from copy import deepcopy
|
||||
import logging
|
||||
import math
|
||||
|
||||
|
||||
class Molecule:
|
||||
@@ -185,11 +188,18 @@ class Molecule:
|
||||
|
||||
return position
|
||||
|
||||
def update_charges(self, charges: List[float]) -> None:
|
||||
|
||||
def update_charges(self, charges: NDArray) -> int:
|
||||
"""
|
||||
Updates the charges of the atoms of the molecule and
|
||||
returns the max difference between the new and old charges
|
||||
"""
|
||||
diff = 0
|
||||
for i, atom in enumerate(self.atom):
|
||||
diff = max(diff, abs(atom.chg - charges[i]))
|
||||
atom.chg = charges[i]
|
||||
|
||||
return diff
|
||||
|
||||
# @staticmethod
|
||||
# def update_hessian(
|
||||
# step: np.ndarray,
|
||||
@@ -299,48 +309,48 @@ class Molecule:
|
||||
Prints the Molecule information into a Output File
|
||||
"""
|
||||
|
||||
logging.info(
|
||||
" Center of mass = ( {:>10.4f} , {:>10.4f} , {:>10.4f} )\n".format(
|
||||
logger.info(
|
||||
" Center of mass = ( {:>10.4f} , {:>10.4f} , {:>10.4f} )".format(
|
||||
self.com[0], self.com[1], self.com[2]
|
||||
)
|
||||
)
|
||||
inertia = self.inertia_tensor()
|
||||
evals, evecs = self.principal_axes()
|
||||
|
||||
logging.info(
|
||||
" Moments of inertia = {:>9E} {:>9E} {:>9E}\n".format(
|
||||
logger.info(
|
||||
" Moments of inertia = {:>9E} {:>9E} {:>9E}".format(
|
||||
evals[0], evals[1], evals[2]
|
||||
)
|
||||
)
|
||||
|
||||
logging.info(
|
||||
" Major principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )\n".format(
|
||||
logger.info(
|
||||
" Major principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )".format(
|
||||
evecs[0, 0], evecs[1, 0], evecs[2, 0]
|
||||
)
|
||||
)
|
||||
logging.info(
|
||||
" Inter principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )\n".format(
|
||||
logger.info(
|
||||
" Inter principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )".format(
|
||||
evecs[0, 1], evecs[1, 1], evecs[2, 1]
|
||||
)
|
||||
)
|
||||
logging.info(
|
||||
" Minor principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )\n".format(
|
||||
logger.info(
|
||||
" Minor principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )".format(
|
||||
evecs[0, 2], evecs[1, 2], evecs[2, 2]
|
||||
)
|
||||
)
|
||||
|
||||
sizes = self.sizes_of_molecule()
|
||||
logging.info(
|
||||
" Characteristic lengths = ( {:>6.2f} , {:>6.2f} , {:>6.2f} )\n".format(
|
||||
logger.info(
|
||||
" Characteristic lengths = ( {:>6.2f} , {:>6.2f} , {:>6.2f} )".format(
|
||||
sizes[0], sizes[1], sizes[2]
|
||||
)
|
||||
)
|
||||
logging.info(" Total mass = {:>8.2f} au\n".format(self.total_mass))
|
||||
logger.info(" Total mass = {:>8.2f} au".format(self.total_mass))
|
||||
|
||||
chg_dip = self.charges_and_dipole()
|
||||
logging.info(" Total charge = {:>8.4f} e\n".format(chg_dip[0]))
|
||||
logging.info(
|
||||
" Dipole moment = ( {:>9.4f} , {:>9.4f} , {:>9.4f} ) Total = {:>9.4f} Debye\n\n".format(
|
||||
logger.info(" Total charge = {:>8.4f} e".format(chg_dip[0]))
|
||||
logger.info(
|
||||
" Dipole moment = ( {:>9.4f} , {:>9.4f} , {:>9.4f} ) Total = {:>9.4f} Debye".format(
|
||||
chg_dip[1], chg_dip[2], chg_dip[3], chg_dip[4]
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from diceplayer.shared.environment.molecule import Molecule
|
||||
from diceplayer.shared.utils.ptable import atomsymb
|
||||
from diceplayer.shared.utils.misc import BOHR2ANG
|
||||
from diceplayer import logger
|
||||
|
||||
from typing import List, Tuple, TextIO
|
||||
from copy import deepcopy
|
||||
@@ -20,41 +21,33 @@ class System:
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
Initializes a empty system object that will be populated afterwards
|
||||
Initializes an empty system object that will be populated afterwards
|
||||
"""
|
||||
|
||||
self.molecule: List[Molecule] = []
|
||||
self.nmols: List[int] = []
|
||||
self.molecule: List[Molecule] = []
|
||||
|
||||
def add_type(self, nmols: int, m: Molecule) -> None:
|
||||
def add_type(self, m: Molecule) -> None:
|
||||
"""
|
||||
Adds a new molecule type to the system
|
||||
|
||||
Args:
|
||||
nmols (int): Number of molecules of the new type in the system
|
||||
m (Molecule): The instance of the new type of molecule
|
||||
"""
|
||||
if isinstance(m, Molecule) is False:
|
||||
raise TypeError("Error: molecule is not a Molecule instance")
|
||||
self.molecule.append(m)
|
||||
|
||||
if isinstance(nmols, int) is False:
|
||||
raise TypeError("Error: nmols is not an integer")
|
||||
self.nmols.append(nmols)
|
||||
|
||||
def update_molecule(self, position: np.ndarray, fh: TextIO) -> None:
|
||||
def update_molecule(self, position: np.ndarray) -> None:
|
||||
"""Updates the position of the molecule in the Output file
|
||||
|
||||
Args:
|
||||
position (np.ndarray): numpy position vector
|
||||
fh (TextIO): Output file
|
||||
"""
|
||||
|
||||
position_in_ang = (position * BOHR2ANG).tolist()
|
||||
self.add_type(self.nmols[0], deepcopy(self.molecule[0]))
|
||||
self.add_type(deepcopy(self.molecule[0]))
|
||||
|
||||
for atom in self.molecule[-1].atom:
|
||||
|
||||
atom.rx = position_in_ang.pop(0)
|
||||
atom.ry = position_in_ang.pop(0)
|
||||
atom.rz = position_in_ang.pop(0)
|
||||
@@ -62,8 +55,8 @@ class System:
|
||||
rmsd, self.molecule[0] = self.rmsd_fit(-1, 0)
|
||||
self.molecule.pop(-1)
|
||||
|
||||
fh.write("\nProjected new conformation of reference molecule with RMSD fit\n")
|
||||
fh.write("RMSD = {:>8.5f} Angstrom\n".format(rmsd))
|
||||
logger.info("Projected new conformation of reference molecule with RMSD fit")
|
||||
logger.info(f"RMSD = {rmsd:>8.5f} Angstrom")
|
||||
|
||||
def rmsd_fit(self, p_index: int, r_index: int) -> Tuple[float, Molecule]:
|
||||
|
||||
@@ -200,7 +193,6 @@ class System:
|
||||
#
|
||||
# return min_dist, nearestmol
|
||||
|
||||
|
||||
# def print_geom(self, cycle: int, fh: TextIO) -> None:
|
||||
# """
|
||||
# Print the geometry of the molecule in the Output file
|
||||
@@ -220,22 +212,22 @@ class System:
|
||||
# )
|
||||
# )
|
||||
#
|
||||
# def printChargesAndDipole(self, cycle: int, fh: TextIO) -> None:
|
||||
# """
|
||||
# Print the charges and dipole of the molecule in the Output file
|
||||
#
|
||||
# Args:
|
||||
# cycle (int): Number of the cycle
|
||||
# fh (TextIO): Output file
|
||||
# """
|
||||
#
|
||||
# fh.write("Cycle # {}\n".format(cycle))
|
||||
# fh.write("Number of site: {}\n".format(len(self.molecule[0].atom)))
|
||||
#
|
||||
# chargesAndDipole = self.molecule[0].charges_and_dipole()
|
||||
#
|
||||
# fh.write(
|
||||
# "{:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f}\n".format(
|
||||
# chargesAndDipole[0], chargesAndDipole[1], chargesAndDipole[2], chargesAndDipole[3], chargesAndDipole[4]
|
||||
# )
|
||||
# )
|
||||
def print_charges_and_dipole(self, cycle: int) -> None:
|
||||
"""
|
||||
Print the charges and dipole of the molecule in the Output file
|
||||
|
||||
Args:
|
||||
cycle (int): Number of the cycle
|
||||
fh (TextIO): Output file
|
||||
"""
|
||||
|
||||
logger.info("Cycle # {}\n".format(cycle))
|
||||
logger.info("Number of site: {}\n".format(len(self.molecule[0].atom)))
|
||||
|
||||
chargesAndDipole = self.molecule[0].charges_and_dipole()
|
||||
|
||||
logger.info(
|
||||
"{:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f}\n".format(
|
||||
chargesAndDipole[0], chargesAndDipole[1], chargesAndDipole[2], chargesAndDipole[3], chargesAndDipole[4]
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
from diceplayer.shared.utils.dataclass_protocol import Dataclass
|
||||
from __future__ import annotations
|
||||
|
||||
from diceplayer.shared.config.player_config import PlayerConfig
|
||||
from diceplayer.shared.environment.system import System
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class Interface(ABC):
|
||||
__slots__ = [
|
||||
'config'
|
||||
'step',
|
||||
'system'
|
||||
]
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self, data: dict):
|
||||
pass
|
||||
def __init__(self):
|
||||
self.system: System | None = None
|
||||
self.step: PlayerConfig | None = None
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def set_config(data: dict) -> Dataclass:
|
||||
def configure(self, step: PlayerConfig, system: System):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from diceplayer.shared.config.dice_dto import DiceDTO
|
||||
from diceplayer.shared.config.step_dto import StepDTO
|
||||
from diceplayer.shared.config.player_config import PlayerConfig
|
||||
from diceplayer.shared.environment.system import System
|
||||
from diceplayer.shared.interface import Interface
|
||||
from diceplayer import logger
|
||||
|
||||
@@ -26,23 +26,14 @@ MAX_SEED: Final[int] = 4294967295
|
||||
class DiceInterface(Interface):
|
||||
title = "Diceplayer run"
|
||||
|
||||
def __init__(self, data: dict):
|
||||
self.config: DiceDTO = self.set_config(data)
|
||||
self.step: StepDTO | None = None
|
||||
|
||||
@staticmethod
|
||||
def set_config(data: dict) -> DiceDTO:
|
||||
return DiceDTO.from_dict(data)
|
||||
|
||||
def configure(self, step: any):
|
||||
def configure(self, step: PlayerConfig, system: System):
|
||||
self.step = step
|
||||
self.system = system
|
||||
|
||||
def start(self, cycle: int):
|
||||
procs = []
|
||||
sentinels = []
|
||||
|
||||
logger.info(f"---------------------- DICE - CYCLE {cycle} --------------------------\n")
|
||||
|
||||
for proc in range(1, self.step.nprocs + 1):
|
||||
p = Process(target=self._simulation_process, args=(cycle, proc))
|
||||
p.start()
|
||||
@@ -66,6 +57,7 @@ class DiceInterface(Interface):
|
||||
|
||||
def reset(self):
|
||||
del self.step
|
||||
del self.system
|
||||
|
||||
def _simulation_process(self, cycle: int, proc: int):
|
||||
setproctitle(f"diceplayer-step{cycle:0d}-p{proc:0d}")
|
||||
@@ -102,7 +94,7 @@ class DiceInterface(Interface):
|
||||
|
||||
# This is logic is used to make the initial configuration file
|
||||
# for the next cycle using the last.xyz file from the previous cycle.
|
||||
if self.config.randominit == 'first' and cycle > 1:
|
||||
if self.step.dice.randominit == 'first' and cycle > 1:
|
||||
last_xyz = Path(
|
||||
self.step.simulation_dir,
|
||||
f"step{(cycle - 1):02d}",
|
||||
@@ -115,15 +107,15 @@ class DiceInterface(Interface):
|
||||
with open(last_xyz, 'r') as last_xyz_file:
|
||||
self._make_init_file(proc_dir, last_xyz_file)
|
||||
last_xyz_file.seek(0)
|
||||
self.config.dens = self._new_density(last_xyz_file)
|
||||
self.step.dice.dens = self._new_density(last_xyz_file)
|
||||
|
||||
else:
|
||||
self._make_nvt_ter(cycle, proc_dir)
|
||||
|
||||
if len(self.config.nstep) == 2:
|
||||
self._make_nvt_eq(proc_dir)
|
||||
if len(self.step.dice.nstep) == 2:
|
||||
self._make_nvt_eq(cycle, proc_dir)
|
||||
|
||||
elif len(self.config.nstep) == 3:
|
||||
elif len(self.step.dice.nstep) == 3:
|
||||
self._make_npt_ter(cycle, proc_dir)
|
||||
self._make_npt_eq(proc_dir)
|
||||
|
||||
@@ -142,13 +134,13 @@ class DiceInterface(Interface):
|
||||
|
||||
os.chdir(proc_dir)
|
||||
|
||||
if not (self.config.randominit == 'first' and cycle > 1):
|
||||
if not (self.step.dice.randominit == 'first' and cycle > 1):
|
||||
self.run_dice_file(cycle, proc, "NVT.ter")
|
||||
|
||||
if len(self.config.nstep) == 2:
|
||||
if len(self.step.dice.nstep) == 2:
|
||||
self.run_dice_file(cycle, proc, "NVT.eq")
|
||||
|
||||
elif len(self.config.nstep) == 3:
|
||||
elif len(self.step.dice.nstep) == 3:
|
||||
self.run_dice_file(cycle, proc, "NPT.ter")
|
||||
self.run_dice_file(cycle, proc, "NPT.eq")
|
||||
|
||||
@@ -175,15 +167,15 @@ class DiceInterface(Interface):
|
||||
xyz_lines = last_xyz_file.readlines()
|
||||
|
||||
nsites_mm = 0
|
||||
for i in range(1, len(self.step.nmol)):
|
||||
nsites_mm += self.step.nmol[i] * len(self.step.molecule[i].atom)
|
||||
for i in range(1, len(self.step.dice.nmol)):
|
||||
nsites_mm += self.step.dice.nmol[i] * len(self.system.molecule[i].atom)
|
||||
|
||||
xyz_lines = xyz_lines[-nsites_mm:]
|
||||
|
||||
input_file = Path(proc_dir, self.config.outname + ".xy")
|
||||
input_file = Path(proc_dir, self.step.dice.outname + ".xy")
|
||||
with open(input_file, 'w') as f:
|
||||
|
||||
for atom in self.step.molecule[0].atom:
|
||||
for atom in self.system.molecule[0].atom:
|
||||
f.write(
|
||||
f"{atom.rx:>10.6f} {atom.ry:>10.6f} {atom.rz:>10.6f}\n"
|
||||
)
|
||||
@@ -204,8 +196,8 @@ class DiceInterface(Interface):
|
||||
volume = float(box[-3]) * float(box[-2]) * float(box[-1])
|
||||
|
||||
total_mass = 0
|
||||
for i in range(len(self.step.molecule)):
|
||||
total_mass += self.step.molecule[i].total_mass * self.step.nmol[i]
|
||||
for i in range(len(self.system.molecule)):
|
||||
total_mass += self.system.molecule[i].total_mass * self.step.dice.nmol[i]
|
||||
|
||||
density = (total_mass / volume) * UMAANG3_TO_GCM3
|
||||
|
||||
@@ -216,21 +208,21 @@ class DiceInterface(Interface):
|
||||
with open(file, 'w') as f:
|
||||
f.write(f"title = {self.title} - NVT Thermalization\n")
|
||||
f.write(f"ncores = {self.step.ncores}\n")
|
||||
f.write(f"ljname = {self.config.ljname}\n")
|
||||
f.write(f"outname = {self.config.outname}\n")
|
||||
f.write(f"ljname = {self.step.dice.ljname}\n")
|
||||
f.write(f"outname = {self.step.dice.outname}\n")
|
||||
|
||||
mol_string = " ".join(str(x) for x in self.config.nmol)
|
||||
mol_string = " ".join(str(x) for x in self.step.dice.nmol)
|
||||
f.write(f"nmol = {mol_string}\n")
|
||||
|
||||
f.write(f"dens = {self.config.dens}\n")
|
||||
f.write(f"temp = {self.config.temp}\n")
|
||||
f.write(f"dens = {self.step.dice.dens}\n")
|
||||
f.write(f"temp = {self.step.dice.temp}\n")
|
||||
|
||||
if self.config.randominit == "first" and cycle > 1:
|
||||
if self.step.dice.randominit == "first" and cycle > 1:
|
||||
f.write(f"init = yesreadxyz\n")
|
||||
f.write(f"nstep = {self.step.altsteps}\n")
|
||||
else:
|
||||
f.write(f"init = yes\n")
|
||||
f.write(f"nstep = {self.config.nstep[0]}\n")
|
||||
f.write(f"nstep = {self.step.dice.nstep[0]}\n")
|
||||
|
||||
f.write("vstep = 0\n")
|
||||
f.write("mstop = 1\n")
|
||||
@@ -241,30 +233,36 @@ class DiceInterface(Interface):
|
||||
|
||||
seed = int(1e6 * random.random())
|
||||
f.write(f"seed = {seed}\n")
|
||||
f.write(f"upbuf = {self.config.upbuf}")
|
||||
f.write(f"upbuf = {self.step.dice.upbuf}")
|
||||
|
||||
def _make_nvt_eq(self, proc_dir):
|
||||
def _make_nvt_eq(self, cycle, proc_dir):
|
||||
|
||||
file = Path(proc_dir, "NVT.eq")
|
||||
with open(file, 'w') as f:
|
||||
f.write(f"title = {self.title} - NVT Production\n")
|
||||
f.write(f"ncores = {self.step.ncores}\n")
|
||||
f.write(f"ljname = {self.config.ljname}\n")
|
||||
f.write(f"outname = {self.config.outname}\n")
|
||||
f.write(f"ljname = {self.step.dice.ljname}\n")
|
||||
f.write(f"outname = {self.step.dice.outname}\n")
|
||||
|
||||
mol_string = " ".join(str(x) for x in self.config.nmol)
|
||||
mol_string = " ".join(str(x) for x in self.step.dice.nmol)
|
||||
f.write(f"nmol = {mol_string}\n")
|
||||
|
||||
f.write(f"dens = {self.config.dens}\n")
|
||||
f.write(f"temp = {self.config.temp}\n")
|
||||
f.write(f"dens = {self.step.dice.dens}\n")
|
||||
f.write(f"temp = {self.step.dice.temp}\n")
|
||||
|
||||
if self.step.dice.randominit == "first" and cycle > 1:
|
||||
f.write("init = yesreadxyz\n")
|
||||
else:
|
||||
f.write("init = no\n")
|
||||
f.write(f"nstep = {self.config.nstep[1]}\n")
|
||||
|
||||
f.write(f"nstep = {self.step.dice.nstep[1]}\n")
|
||||
|
||||
f.write("vstep = 0\n")
|
||||
f.write("mstop = 1\n")
|
||||
f.write("accum = no\n")
|
||||
f.write("iprint = 1\n")
|
||||
|
||||
f.write(f"isave = {self.config.isave}\n")
|
||||
f.write(f"isave = {self.step.dice.isave}\n")
|
||||
f.write(f"irdf = {10 * self.step.nprocs}\n")
|
||||
|
||||
seed = int(1e6 * random.random())
|
||||
@@ -276,22 +274,22 @@ class DiceInterface(Interface):
|
||||
with open(file, 'w') as f:
|
||||
f.write(f"title = {self.title} - NPT Thermalization\n")
|
||||
f.write(f"ncores = {self.step.ncores}\n")
|
||||
f.write(f"ljname = {self.config.ljname}\n")
|
||||
f.write(f"outname = {self.config.outname}\n")
|
||||
f.write(f"ljname = {self.step.dice.ljname}\n")
|
||||
f.write(f"outname = {self.step.dice.outname}\n")
|
||||
|
||||
mol_string = " ".join(str(x) for x in self.config.nmol)
|
||||
mol_string = " ".join(str(x) for x in self.step.dice.nmol)
|
||||
f.write(f"nmol = {mol_string}\n")
|
||||
|
||||
f.write(f"press = {self.config.press}\n")
|
||||
f.write(f"temp = {self.config.temp}\n")
|
||||
f.write(f"press = {self.step.dice.press}\n")
|
||||
f.write(f"temp = {self.step.dice.temp}\n")
|
||||
|
||||
if self.config.randominit == "first" and cycle > 1:
|
||||
if self.step.dice.randominit == "first" and cycle > 1:
|
||||
f.write("init = yesreadxyz\n")
|
||||
f.write(f"dens = {self.config.dens:<8.4f}\n")
|
||||
f.write(f"dens = {self.step.dice.dens:<8.4f}\n")
|
||||
f.write(f"vstep = {int(self.step.altsteps / 5)}\n")
|
||||
else:
|
||||
f.write("init = no\n")
|
||||
f.write(f"vstep = {int(self.config.nstep[1] / 5)}\n")
|
||||
f.write(f"vstep = {int(self.step.dice.nstep[1] / 5)}\n")
|
||||
|
||||
f.write("nstep = 5\n")
|
||||
f.write("mstop = 1\n")
|
||||
@@ -308,23 +306,23 @@ class DiceInterface(Interface):
|
||||
with open(file, 'w') as f:
|
||||
f.write(f"title = {self.title} - NPT Production\n")
|
||||
f.write(f"ncores = {self.step.ncores}\n")
|
||||
f.write(f"ljname = {self.config.ljname}\n")
|
||||
f.write(f"outname = {self.config.outname}\n")
|
||||
f.write(f"ljname = {self.step.dice.ljname}\n")
|
||||
f.write(f"outname = {self.step.dice.outname}\n")
|
||||
|
||||
mol_string = " ".join(str(x) for x in self.config.nmol)
|
||||
mol_string = " ".join(str(x) for x in self.step.dice.nmol)
|
||||
f.write(f"nmol = {mol_string}\n")
|
||||
|
||||
f.write(f"press = {self.config.press}\n")
|
||||
f.write(f"temp = {self.config.temp}\n")
|
||||
f.write(f"press = {self.step.dice.press}\n")
|
||||
f.write(f"temp = {self.step.dice.temp}\n")
|
||||
|
||||
f.write(f"nstep = 5\n")
|
||||
|
||||
f.write(f"vstep = {int(self.config.nstep[2] / 5)}\n")
|
||||
f.write(f"vstep = {int(self.step.dice.nstep[2] / 5)}\n")
|
||||
f.write("init = no\n")
|
||||
f.write("mstop = 1\n")
|
||||
f.write("accum = no\n")
|
||||
f.write("iprint = 1\n")
|
||||
f.write(f"isave = {self.config.isave}\n")
|
||||
f.write(f"isave = {self.step.dice.isave}\n")
|
||||
f.write(f"irdf = {10 * self.step.nprocs}\n")
|
||||
|
||||
seed = int(1e6 * random.random())
|
||||
@@ -333,15 +331,15 @@ class DiceInterface(Interface):
|
||||
def _make_potentials(self, proc_dir):
|
||||
fstr = "{:<3d} {:>3d} {:>10.5f} {:>10.5f} {:>10.5f} {:>10.6f} {:>9.5f} {:>7.4f}\n"
|
||||
|
||||
file = Path(proc_dir, self.config.ljname)
|
||||
file = Path(proc_dir, self.step.dice.ljname)
|
||||
with open(file, 'w') as f:
|
||||
f.write(f"{self.config.combrule}\n")
|
||||
f.write(f"{len(self.step.nmol)}\n")
|
||||
f.write(f"{self.step.dice.combrule}\n")
|
||||
f.write(f"{len(self.step.dice.nmol)}\n")
|
||||
|
||||
nsites_qm = len(self.step.molecule[0].atom)
|
||||
f.write(f"{nsites_qm} {self.step.molecule[0].molname}\n")
|
||||
nsites_qm = len(self.system.molecule[0].atom)
|
||||
f.write(f"{nsites_qm} {self.system.molecule[0].molname}\n")
|
||||
|
||||
for atom in self.step.molecule[0].atom:
|
||||
for atom in self.system.molecule[0].atom:
|
||||
f.write(
|
||||
fstr.format(
|
||||
atom.lbl,
|
||||
@@ -355,7 +353,7 @@ class DiceInterface(Interface):
|
||||
)
|
||||
)
|
||||
|
||||
for mol in self.step.molecule[1:]:
|
||||
for mol in self.system.molecule[1:]:
|
||||
f.write(f"{len(mol.atom)} {mol.molname}\n")
|
||||
for atom in mol.atom:
|
||||
f.write(
|
||||
@@ -378,12 +376,12 @@ class DiceInterface(Interface):
|
||||
[
|
||||
"bash",
|
||||
"-c",
|
||||
f"exec -a dice-step{cycle}-p{proc} {self.config.progname} < {infile.name} > {outfile.name}",
|
||||
f"exec -a dice-step{cycle}-p{proc} {self.step.dice.progname} < {infile.name} > {outfile.name}",
|
||||
]
|
||||
)
|
||||
else:
|
||||
exit_status = subprocess.call(
|
||||
self.config.progname, stdin=infile, stdout=outfile
|
||||
self.step.dice.progname, stdin=infile, stdout=outfile
|
||||
)
|
||||
|
||||
if exit_status != 0:
|
||||
|
||||
@@ -1,22 +1,380 @@
|
||||
from diceplayer.shared.config.gaussian_dto import GaussianDTO
|
||||
from __future__ import annotations
|
||||
|
||||
from diceplayer.shared.config.player_config import PlayerConfig
|
||||
from diceplayer.shared.environment.molecule import Molecule
|
||||
from diceplayer.shared.environment.system import System
|
||||
from diceplayer.shared.environment.atom import Atom
|
||||
from diceplayer.shared.utils.misc import date_time
|
||||
from diceplayer.shared.utils.ptable import atomsymb
|
||||
from diceplayer.shared.interface import Interface
|
||||
from diceplayer import logger
|
||||
|
||||
from typing import Tuple, List, Dict, Any
|
||||
|
||||
from nptyping import NDArray
|
||||
import numpy as np
|
||||
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import textwrap
|
||||
import shutil
|
||||
import os
|
||||
|
||||
|
||||
class GaussianInterface(Interface):
|
||||
def configure(self, step_dto: PlayerConfig, system: System):
|
||||
self.system = system
|
||||
self.step = step_dto
|
||||
|
||||
def __init__(self, data: dict):
|
||||
self.config: GaussianDTO = self.set_config(data)
|
||||
def start(self, cycle: int) -> Dict[str, NDArray]:
|
||||
self._make_qm_dir(cycle)
|
||||
|
||||
@staticmethod
|
||||
def set_config(data: dict) -> GaussianDTO:
|
||||
return GaussianDTO.from_dict(data)
|
||||
if cycle > 1:
|
||||
self._copy_chk_file_from_previous_step(cycle)
|
||||
|
||||
def configure(self):
|
||||
pass
|
||||
asec_charges = self.populate_asec_vdw(cycle)
|
||||
self._make_gaussian_input_file(
|
||||
cycle,
|
||||
asec_charges
|
||||
)
|
||||
|
||||
def start(self, cycle: int):
|
||||
pass
|
||||
self._run_gaussian(cycle)
|
||||
self._run_formchk(cycle)
|
||||
|
||||
return_value = {}
|
||||
if self.step.opt:
|
||||
# return_value['position'] = np.array(
|
||||
# self._run_optimization(cycle)
|
||||
# )
|
||||
raise NotImplementedError("Optimization not implemented yet.")
|
||||
|
||||
else:
|
||||
return_value['charges'] = np.array(
|
||||
self._read_charges_from_fchk(cycle)
|
||||
)
|
||||
|
||||
return return_value
|
||||
|
||||
def reset(self):
|
||||
pass
|
||||
del self.step
|
||||
del self.system
|
||||
|
||||
def _make_qm_dir(self, cycle: int):
|
||||
qm_dir_path = Path(
|
||||
self.step.simulation_dir,
|
||||
f"step{cycle:02d}",
|
||||
"qm"
|
||||
)
|
||||
if not qm_dir_path.exists():
|
||||
qm_dir_path.mkdir()
|
||||
|
||||
def _copy_chk_file_from_previous_step(self, cycle: int):
|
||||
current_chk_file_path = Path(
|
||||
self.step.simulation_dir,
|
||||
f"step{cycle:02d}",
|
||||
"qm",
|
||||
f"asec.chk"
|
||||
)
|
||||
if current_chk_file_path.exists():
|
||||
raise FileExistsError(
|
||||
f"File {current_chk_file_path} already exists."
|
||||
)
|
||||
|
||||
previous_chk_file_path = Path(
|
||||
self.step.simulation_dir,
|
||||
f"step{(cycle - 1):02d}",
|
||||
"qm",
|
||||
f"asec.chk"
|
||||
)
|
||||
if not previous_chk_file_path.exists():
|
||||
raise FileNotFoundError(
|
||||
f"File {previous_chk_file_path} does not exist."
|
||||
)
|
||||
|
||||
shutil.copy(previous_chk_file_path, current_chk_file_path)
|
||||
|
||||
def populate_asec_vdw(self, cycle: int) -> list[dict]:
|
||||
norm_factor = self._calculate_norm_factor()
|
||||
|
||||
nsitesref = len(self.system.molecule[0].atom)
|
||||
|
||||
nsites_total = self._calculate_total_number_of_sites(nsitesref)
|
||||
|
||||
proc_charges = []
|
||||
for proc in range(1, self.step.nprocs + 1):
|
||||
proc_charges.append(self._read_charges_from_last_step(cycle, proc))
|
||||
|
||||
asec_charges, thickness, picked_mols = \
|
||||
self._evaluate_proc_charges(nsites_total, proc_charges)
|
||||
|
||||
logger.info(f"In average, {(sum(picked_mols) / norm_factor):^7.2f} molecules\n"
|
||||
f"were selected from each of the {len(picked_mols)} configurations\n"
|
||||
f"of the production simulations to form the ASEC, comprising a shell with\n"
|
||||
f"minimum thickness of {(sum(thickness) / norm_factor):>6.2f} Angstrom\n"
|
||||
)
|
||||
|
||||
for charge in asec_charges:
|
||||
charge['chg'] = charge['chg'] / norm_factor
|
||||
|
||||
return asec_charges
|
||||
|
||||
def _calculate_norm_factor(self) -> int:
|
||||
if self.step.dice.nstep[-1] % self.step.dice.isave == 0:
|
||||
nconfigs = round(self.step.dice.nstep[-1] / self.step.dice.isave)
|
||||
else:
|
||||
nconfigs = int(self.step.dice.nstep[-1] / self.step.dice.isave)
|
||||
|
||||
return nconfigs * self.step.nprocs
|
||||
|
||||
def _calculate_total_number_of_sites(self, nsitesref) -> int:
|
||||
nsites_total = self.step.dice.nmol[0] * nsitesref
|
||||
for i in range(1, len(self.step.dice.nmol)):
|
||||
nsites_total += self.step.dice.nmol[i] * len(self.system.molecule[i].atom)
|
||||
|
||||
return nsites_total
|
||||
|
||||
def _read_charges_from_last_step(self, cycle: int, proc: int) -> list[str]:
|
||||
last_xyz_file_path = Path(
|
||||
self.step.simulation_dir,
|
||||
f"step{cycle:02d}",
|
||||
f"p{proc:02d}",
|
||||
"last.xyz"
|
||||
)
|
||||
if not last_xyz_file_path.exists():
|
||||
raise FileNotFoundError(
|
||||
f"File {last_xyz_file_path} does not exist."
|
||||
)
|
||||
|
||||
with open(last_xyz_file_path, 'r') as last_xyz_file:
|
||||
lines = last_xyz_file.readlines()
|
||||
|
||||
return lines
|
||||
|
||||
def _evaluate_proc_charges(self, total_nsites: int, proc_charges: list[list[str]]) -> Tuple[
|
||||
List[Dict[str, float | Any]], List[float], List[int]]:
|
||||
asec_charges = []
|
||||
|
||||
thickness = []
|
||||
picked_mols = []
|
||||
|
||||
for charges in proc_charges:
|
||||
charges_nsites = int(charges.pop(0))
|
||||
if int(charges_nsites) != total_nsites:
|
||||
raise ValueError(
|
||||
f"Number of sites does not match total number of sites."
|
||||
)
|
||||
|
||||
thickness.append(
|
||||
self._calculate_proc_thickness(charges)
|
||||
)
|
||||
nsites_ref_mol = len(self.system.molecule[0].atom)
|
||||
charges = charges[nsites_ref_mol:]
|
||||
|
||||
mol_count = 0
|
||||
for type in range(len(self.step.dice.nmol)):
|
||||
if type == 0:
|
||||
# Reference Molecule must be ignored from type 0
|
||||
nmols = self.step.dice.nmol[type] - 1
|
||||
else:
|
||||
nmols = self.step.dice.nmol[type]
|
||||
|
||||
for mol in range(nmols):
|
||||
new_molecule = Molecule("ASEC TMP MOLECULE")
|
||||
for site in range(len(self.system.molecule[type].atom)):
|
||||
line = charges.pop(0).split()
|
||||
|
||||
if line[0].title() != atomsymb[self.system.molecule[type].atom[site].na].strip():
|
||||
raise SyntaxError(
|
||||
f"Error: Invalid Dice Output. Atom type does not match."
|
||||
)
|
||||
|
||||
new_molecule.add_atom(
|
||||
Atom(
|
||||
self.system.molecule[type].atom[site].lbl,
|
||||
self.system.molecule[type].atom[site].na,
|
||||
float(line[1]),
|
||||
float(line[2]),
|
||||
float(line[3]),
|
||||
self.system.molecule[type].atom[site].chg,
|
||||
self.system.molecule[type].atom[site].eps,
|
||||
self.system.molecule[type].atom[site].sig,
|
||||
)
|
||||
)
|
||||
|
||||
distance = self.system.molecule[0] \
|
||||
.minimum_distance(new_molecule)
|
||||
|
||||
if distance < thickness[-1]:
|
||||
for atom in new_molecule.atom:
|
||||
asec_charges.append(
|
||||
{"lbl": atomsymb[atom.na], "rx": atom.rx, "ry": atom.ry, "rz": atom.rz, "chg": atom.chg}
|
||||
)
|
||||
mol_count += 1
|
||||
|
||||
picked_mols.append(mol_count)
|
||||
|
||||
return asec_charges, thickness, picked_mols
|
||||
|
||||
def _calculate_proc_thickness(self, charges: list[str]) -> float:
|
||||
box = charges.pop(0).split()[-3:]
|
||||
box = [float(box[0]), float(box[1]), float(box[2])]
|
||||
sizes = self.system.molecule[0].sizes_of_molecule()
|
||||
|
||||
return min(
|
||||
[
|
||||
(box[0] - sizes[0]) / 2,
|
||||
(box[1] - sizes[1]) / 2,
|
||||
(box[2] - sizes[2]) / 2,
|
||||
]
|
||||
)
|
||||
|
||||
def _make_gaussian_input_file(self, cycle: int, asec_charges: list[dict]) -> None:
|
||||
gaussian_input_file_path = Path(
|
||||
self.step.simulation_dir,
|
||||
f"step{cycle:02d}",
|
||||
"qm",
|
||||
f"asec.gjf"
|
||||
)
|
||||
|
||||
with open(gaussian_input_file_path, 'w') as gaussian_input_file:
|
||||
gaussian_input_file.writelines(
|
||||
self._generate_gaussian_input(cycle, asec_charges)
|
||||
)
|
||||
|
||||
def _generate_gaussian_input(self, cycle: int, asec_charges: list[dict]) -> list[str]:
|
||||
gaussian_input = ["%Chk=asec.chk\n"]
|
||||
|
||||
if self.step.mem is not None:
|
||||
gaussian_input.append(f"%Mem={self.step.mem}GB\n")
|
||||
|
||||
gaussian_input.append(f"%Nprocs={self.step.nprocs * self.step.ncores}\n")
|
||||
|
||||
kwords_line = f"#P {self.step.gaussian.level}"
|
||||
|
||||
if self.step.gaussian.keywords:
|
||||
kwords_line += " " + self.step.gaussian.keywords
|
||||
|
||||
if self.step.opt == "yes":
|
||||
kwords_line += " Force"
|
||||
|
||||
kwords_line += " NoSymm"
|
||||
kwords_line += f" Pop={self.step.gaussian.pop} Density=Current"
|
||||
|
||||
if cycle > 1:
|
||||
kwords_line += " Guess=Read"
|
||||
|
||||
gaussian_input.append(textwrap.fill(kwords_line, 90))
|
||||
gaussian_input.append("\n")
|
||||
|
||||
gaussian_input.append("\nForce calculation - Cycle number {}\n".format(cycle))
|
||||
gaussian_input.append("\n")
|
||||
gaussian_input.append(f"{self.step.gaussian.chgmult[0]},{self.step.gaussian.chgmult[1]}\n")
|
||||
|
||||
for atom in self.system.molecule[0].atom:
|
||||
symbol = atomsymb[atom.na]
|
||||
gaussian_input.append(
|
||||
"{:<2s} {:>10.5f} {:>10.5f} {:>10.5f}\n".format(
|
||||
symbol, atom.rx, atom.ry, atom.rz
|
||||
)
|
||||
)
|
||||
|
||||
gaussian_input.append("\n")
|
||||
|
||||
for charge in asec_charges:
|
||||
gaussian_input.append(
|
||||
"{:>10.5f} {:>10.5f} {:>10.5f} {:>11.8f}\n".format(
|
||||
charge['rx'], charge['ry'], charge['rz'], charge['chg']
|
||||
)
|
||||
)
|
||||
|
||||
gaussian_input.append("\n")
|
||||
|
||||
return gaussian_input
|
||||
|
||||
def _run_gaussian(self, cycle: int) -> None:
|
||||
qm_dir = Path(
|
||||
self.step.simulation_dir,
|
||||
f"step{(cycle):02d}",
|
||||
"qm"
|
||||
)
|
||||
|
||||
working_dir = os.getcwd()
|
||||
os.chdir(qm_dir)
|
||||
|
||||
infile = "asec.gjf"
|
||||
|
||||
operation = None
|
||||
if self.step.opt:
|
||||
operation = "forces"
|
||||
else:
|
||||
operation = "charges"
|
||||
|
||||
logger.info(
|
||||
f"Calculation of {operation} initiated with Gaussian on {date_time()}\n"
|
||||
)
|
||||
|
||||
if shutil.which("bash") is not None:
|
||||
exit_status = subprocess.call(
|
||||
[
|
||||
"bash",
|
||||
"-c",
|
||||
"exec -a {}-step{} {} {}".format(
|
||||
self.step.gaussian.qmprog, cycle, self.step.gaussian.qmprog, infile
|
||||
),
|
||||
]
|
||||
)
|
||||
else:
|
||||
exit_status = subprocess.call([self.step.gaussian.qmprog, infile])
|
||||
|
||||
if exit_status != 0:
|
||||
raise SystemError("Gaussian process did not exit properly")
|
||||
|
||||
logger.info(f"Calculation of {operation} finished on {date_time()}")
|
||||
|
||||
os.chdir(working_dir)
|
||||
|
||||
def _run_formchk(self, cycle: int):
|
||||
qm_dir = Path(
|
||||
self.step.simulation_dir,
|
||||
f"step{(cycle):02d}",
|
||||
"qm"
|
||||
)
|
||||
|
||||
work_dir = os.getcwd()
|
||||
os.chdir(qm_dir)
|
||||
|
||||
logger.info("Formatting the checkpoint file... \n")
|
||||
|
||||
exit_status = subprocess.call(["formchk", "asec.chk"], stdout=subprocess.DEVNULL)
|
||||
|
||||
if exit_status != 0:
|
||||
raise SystemError("Formchk process did not exit properly")
|
||||
|
||||
logger.info("Done\n")
|
||||
|
||||
os.chdir(work_dir)
|
||||
|
||||
def _read_charges_from_fchk(self, cycle: int):
|
||||
fchk_file_path = Path(
|
||||
"simfiles",
|
||||
f"step{cycle:02d}",
|
||||
"qm",
|
||||
"asec.fchk"
|
||||
)
|
||||
with open(fchk_file_path) as fchk:
|
||||
fchkfile = fchk.readlines()
|
||||
|
||||
if self.step.gaussian.pop in ["chelpg", "mk"]:
|
||||
CHARGE_FLAG = "ESP Charges"
|
||||
else:
|
||||
CHARGE_FLAG = "ESP Charges"
|
||||
|
||||
start = fchkfile.pop(0).strip()
|
||||
while start.find(CHARGE_FLAG) != 0: # expression in begining of line
|
||||
start = fchkfile.pop(0).strip()
|
||||
|
||||
charges: List[float] = []
|
||||
while len(charges) < len(self.system.molecule[0].atom):
|
||||
charges.extend([float(x) for x in fchkfile.pop(0).split()])
|
||||
|
||||
return charges
|
||||
|
||||
111
tests/mocks/mock_inputs.py
Normal file
111
tests/mocks/mock_inputs.py
Normal file
@@ -0,0 +1,111 @@
|
||||
from unittest import mock
|
||||
|
||||
|
||||
def get_config_example():
|
||||
return """
|
||||
diceplayer:
|
||||
opt: no
|
||||
mem: 12
|
||||
maxcyc: 3
|
||||
ncores: 4
|
||||
nprocs: 4
|
||||
qmprog: 'g16'
|
||||
lps: no
|
||||
ghosts: no
|
||||
altsteps: 20000
|
||||
|
||||
dice:
|
||||
nmol: [1, 50]
|
||||
dens: 0.75
|
||||
nstep: [2000, 3000, 4000]
|
||||
isave: 1000
|
||||
outname: 'phb'
|
||||
progname: '~/.local/bin/dice'
|
||||
ljname: 'phb.ljc'
|
||||
randominit: 'first'
|
||||
|
||||
gaussian:
|
||||
qmprog: 'g16'
|
||||
level: 'MP2/aug-cc-pVDZ'
|
||||
keywords: 'freq'
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_exemple():
|
||||
return """\
|
||||
*
|
||||
2
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_combrule():
|
||||
return """\
|
||||
.
|
||||
2
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_ntypes():
|
||||
return """\
|
||||
*
|
||||
a
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_ntypes_config():
|
||||
return """\
|
||||
*
|
||||
3
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_nsites():
|
||||
return """\
|
||||
*
|
||||
2
|
||||
. TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_molname():
|
||||
return """\
|
||||
*
|
||||
2
|
||||
1
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def mock_open(file, *args, **kwargs):
|
||||
values = {
|
||||
"control.test.yml": get_config_example(),
|
||||
"phb.ljc": get_potentials_exemple(),
|
||||
"phb.error.combrule.ljc": get_potentials_error_combrule(),
|
||||
"phb.error.ntypes.ljc": get_potentials_error_ntypes(),
|
||||
"phb.error.ntypes.config.ljc": get_potentials_error_ntypes_config(),
|
||||
"phb.error.nsites.ljc": get_potentials_error_nsites(),
|
||||
"phb.error.molname.ljc": get_potentials_error_molname(),
|
||||
}
|
||||
mock_file = mock.mock_open(read_data=values[file])
|
||||
return mock_file()
|
||||
@@ -1,11 +1,11 @@
|
||||
from diceplayer.shared.config.dice_dto import DiceDTO
|
||||
from diceplayer.shared.config.dice_config import DiceConfig
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestDiceDto(unittest.TestCase):
|
||||
def test_class_instantiation(self):
|
||||
dice_dto = DiceDTO(
|
||||
dice_dto = DiceConfig(
|
||||
ljname='test',
|
||||
outname='test',
|
||||
dens=1.0,
|
||||
@@ -13,11 +13,11 @@ class TestDiceDto(unittest.TestCase):
|
||||
nstep=[1, 1],
|
||||
)
|
||||
|
||||
self.assertIsInstance(dice_dto, DiceDTO)
|
||||
self.assertIsInstance(dice_dto, DiceConfig)
|
||||
|
||||
def test_validate_jname(self):
|
||||
with self.assertRaises(ValueError) as ex:
|
||||
DiceDTO(
|
||||
DiceConfig(
|
||||
ljname=None,
|
||||
outname='test',
|
||||
dens=1.0,
|
||||
@@ -28,7 +28,7 @@ class TestDiceDto(unittest.TestCase):
|
||||
|
||||
def test_validate_outname(self):
|
||||
with self.assertRaises(ValueError) as ex:
|
||||
DiceDTO(
|
||||
DiceConfig(
|
||||
ljname='test',
|
||||
outname=None,
|
||||
dens=1.0,
|
||||
@@ -39,7 +39,7 @@ class TestDiceDto(unittest.TestCase):
|
||||
|
||||
def test_validate_dens(self):
|
||||
with self.assertRaises(ValueError) as ex:
|
||||
DiceDTO(
|
||||
DiceConfig(
|
||||
ljname='test',
|
||||
outname='test',
|
||||
dens=None,
|
||||
@@ -50,7 +50,7 @@ class TestDiceDto(unittest.TestCase):
|
||||
|
||||
def test_validate_nmol(self):
|
||||
with self.assertRaises(ValueError) as ex:
|
||||
DiceDTO(
|
||||
DiceConfig(
|
||||
ljname='test',
|
||||
outname='test',
|
||||
dens=1.0,
|
||||
@@ -61,7 +61,7 @@ class TestDiceDto(unittest.TestCase):
|
||||
|
||||
def test_validate_nstep(self):
|
||||
with self.assertRaises(ValueError) as ex:
|
||||
DiceDTO(
|
||||
DiceConfig(
|
||||
ljname='test',
|
||||
outname='test',
|
||||
dens=1.0,
|
||||
@@ -71,7 +71,7 @@ class TestDiceDto(unittest.TestCase):
|
||||
self.assertEqual(ex.exception, "Error: 'nstep' keyword not defined appropriately in config file")
|
||||
|
||||
def test_from_dict(self):
|
||||
dice_dto = DiceDTO.from_dict({
|
||||
dice_dto = DiceConfig.from_dict({
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'dens': 1.0,
|
||||
@@ -79,4 +79,4 @@ class TestDiceDto(unittest.TestCase):
|
||||
'nstep': [1, 1],
|
||||
})
|
||||
|
||||
self.assertIsInstance(dice_dto, DiceDTO)
|
||||
self.assertIsInstance(dice_dto, DiceConfig)
|
||||
@@ -1,4 +1,4 @@
|
||||
from diceplayer.shared.config.gaussian_dto import GaussianDTO
|
||||
from diceplayer.shared.config.gaussian_config import GaussianDTO
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
@@ -1,28 +1,84 @@
|
||||
from diceplayer.shared.config.player_dto import PlayerDTO
|
||||
from diceplayer.shared.config.gaussian_config import GaussianDTO
|
||||
from diceplayer.shared.config.player_config import PlayerConfig
|
||||
from diceplayer.shared.config.dice_config import DiceConfig
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestPlayerDTO(unittest.TestCase):
|
||||
def test_class_instantiation(self):
|
||||
player_dto = PlayerDTO(opt=True, maxcyc=100, nprocs=4, ncores=4)
|
||||
def get_config_dict():
|
||||
return {
|
||||
'opt': True,
|
||||
'mem': 12,
|
||||
'maxcyc': 100,
|
||||
'nprocs': 4,
|
||||
'ncores': 4,
|
||||
'dice': {
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
},
|
||||
'gaussian': {
|
||||
'level': 'test',
|
||||
'qmprog': 'g16',
|
||||
'keywords': 'test',
|
||||
}
|
||||
}
|
||||
|
||||
self.assertIsInstance(player_dto, PlayerDTO)
|
||||
|
||||
class TestPlayerDTO(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.dice_dto = DiceConfig(
|
||||
ljname='test',
|
||||
outname='test',
|
||||
dens=1.0,
|
||||
nmol=[1],
|
||||
nstep=[1, 1],
|
||||
)
|
||||
self.gaussian_dto = GaussianDTO(
|
||||
level='test',
|
||||
qmprog='g16',
|
||||
keywords='test',
|
||||
)
|
||||
|
||||
def test_class_instantiation(self):
|
||||
player_dto = PlayerConfig(
|
||||
opt=True,
|
||||
mem=12,
|
||||
maxcyc=100,
|
||||
nprocs=4,
|
||||
ncores=4,
|
||||
dice=self.dice_dto,
|
||||
gaussian=self.gaussian_dto
|
||||
)
|
||||
|
||||
self.assertIsInstance(player_dto, PlayerConfig)
|
||||
self.assertIsInstance(player_dto.dice, DiceConfig)
|
||||
self.assertIsInstance(player_dto.gaussian, GaussianDTO)
|
||||
|
||||
def test_min_altsteps(self):
|
||||
player_dto = PlayerDTO(opt=True, maxcyc=100, nprocs=4, ncores=4, altsteps=100)
|
||||
player_dto = PlayerConfig(
|
||||
opt=True,
|
||||
mem=12,
|
||||
maxcyc=100,
|
||||
nprocs=4,
|
||||
ncores=4,
|
||||
altsteps=100,
|
||||
dice=self.dice_dto,
|
||||
gaussian=self.gaussian_dto
|
||||
)
|
||||
|
||||
self.assertEqual(player_dto.altsteps, 20000)
|
||||
|
||||
def test_from_dict(self):
|
||||
player_dto = PlayerDTO.from_dict({
|
||||
'opt': True,
|
||||
'maxcyc': 100,
|
||||
'nprocs': 4,
|
||||
'ncores': 4,
|
||||
})
|
||||
player_dto = PlayerConfig.from_dict(
|
||||
get_config_dict()
|
||||
)
|
||||
|
||||
self.assertIsInstance(player_dto, PlayerDTO)
|
||||
self.assertIsInstance(player_dto, PlayerConfig)
|
||||
self.assertIsInstance(player_dto.dice, DiceConfig)
|
||||
self.assertIsInstance(player_dto.gaussian, GaussianDTO)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -13,18 +13,14 @@ class TestSystem(unittest.TestCase):
|
||||
|
||||
def test_add_type(self):
|
||||
system = System()
|
||||
system.add_type(0, Molecule('test'))
|
||||
system.add_type(Molecule('test'))
|
||||
|
||||
self.assertIsInstance(system.molecule, list)
|
||||
self.assertIsInstance(system.nmols, list)
|
||||
|
||||
with self.assertRaises(TypeError) as ex:
|
||||
system.add_type(0, 'test')
|
||||
system.add_type('test')
|
||||
self.assertEqual(ex.exception, 'Error: molecule is not a Molecule instance')
|
||||
|
||||
with self.assertRaises(TypeError) as ex:
|
||||
system.add_type('test', Molecule('test'))
|
||||
self.assertEqual(ex.exception, 'Error: nmols is not an integer')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
from diceplayer.shared.interface.dice_interface import DiceInterface
|
||||
from diceplayer.shared.config.player_config import PlayerConfig
|
||||
from diceplayer.shared.environment.molecule import Molecule
|
||||
from diceplayer.shared.environment.system import System
|
||||
from diceplayer.shared.environment.atom import Atom
|
||||
from diceplayer.shared.config.step_dto import StepDTO
|
||||
from diceplayer import logger
|
||||
|
||||
import yaml
|
||||
import io
|
||||
|
||||
from tests.mocks.mock_inputs import get_config_example
|
||||
from tests.mocks.mock_proc import MockConnection, MockProc
|
||||
|
||||
from unittest import mock
|
||||
@@ -16,122 +19,58 @@ class TestDiceInterface(unittest.TestCase):
|
||||
def setUp(self):
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
|
||||
config = yaml.load(get_config_example(), Loader=yaml.Loader)
|
||||
self.config = PlayerConfig.from_dict(config['diceplayer'])
|
||||
|
||||
def test_class_instantiation(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice = DiceInterface()
|
||||
|
||||
self.assertIsInstance(dice, DiceInterface)
|
||||
|
||||
def test_configure(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice = DiceInterface()
|
||||
|
||||
self.assertIsNone(dice.step)
|
||||
self.assertIsNone(dice.system)
|
||||
|
||||
dice.configure('test')
|
||||
# Ignoring the types for testing purposes
|
||||
dice.configure(self.config, System())
|
||||
|
||||
self.assertIsNotNone(dice.step)
|
||||
self.assertIsNotNone(dice.system)
|
||||
|
||||
def test_reset(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice = DiceInterface()
|
||||
|
||||
dice.configure('test')
|
||||
dice.configure(self.config, System())
|
||||
|
||||
self.assertTrue(hasattr(dice, 'step'))
|
||||
self.assertTrue(hasattr(dice, 'system'))
|
||||
|
||||
dice.reset()
|
||||
|
||||
self.assertFalse(hasattr(dice, 'step'))
|
||||
self.assertFalse(hasattr(dice, 'system'))
|
||||
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Process', MockProc())
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.connection', MockConnection)
|
||||
def test_start(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.start(1)
|
||||
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.connection', MockConnection)
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Process', MockProc(exitcode=1))
|
||||
def test_start_with_process_error(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=2,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
with self.assertRaises(SystemExit):
|
||||
dice.start(1)
|
||||
|
||||
def test_simulation_process_raises_exception(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice = DiceInterface()
|
||||
|
||||
with self.assertRaises(SystemExit):
|
||||
dice._simulation_process(1, 1)
|
||||
@@ -140,16 +79,7 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.DiceInterface._make_dice_inputs')
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.DiceInterface._run_dice')
|
||||
def test_simulation_process(self, mock_run_dice, mock_make_dice_inputs, mock_make_proc_dir):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice = DiceInterface()
|
||||
|
||||
dice._simulation_process(1, 1)
|
||||
|
||||
@@ -160,26 +90,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.mkdir')
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists')
|
||||
def test_make_proc_dir_if_simdir_exists(self, mock_path_exists, mock_path_mkdir):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
mock_path_exists.return_value = False
|
||||
|
||||
@@ -190,26 +102,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.mkdir')
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists')
|
||||
def test_make_proc_dir_if_simdir_doesnt_exists(self, mock_path_exists, mock_path_mkdir):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
mock_path_exists.return_value = False
|
||||
|
||||
@@ -218,42 +112,15 @@ class TestDiceInterface(unittest.TestCase):
|
||||
self.assertEqual(mock_path_mkdir.call_count, 2)
|
||||
|
||||
def test_make_dice_seed(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
|
||||
seed = dice._make_dice_seed()
|
||||
seed = DiceInterface._make_dice_seed()
|
||||
|
||||
self.assertIsInstance(seed, int)
|
||||
|
||||
def test_make_dice_inputs_nstep_len_two_with_randoninit_first_cycle_one(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.step.dice.nstep = [1, 1]
|
||||
|
||||
dice._make_potentials = mock.Mock()
|
||||
|
||||
@@ -281,26 +148,10 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('builtins.open', new_callable=mock.mock_open, read_data='test')
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=True)
|
||||
def test_make_dice_inputs_nstep_len_two_with_randoninit_first_cycle_two(self, mock_path_exists, mock_open):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.step.dice.nstep = [1, 1]
|
||||
|
||||
dice._make_potentials = mock.Mock()
|
||||
|
||||
@@ -327,26 +178,10 @@ class TestDiceInterface(unittest.TestCase):
|
||||
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=False)
|
||||
def test_make_dice_inputs_raises_exception_on_last_not_found(self, mock_path_exists):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.step.dice.nstep = [1, 1]
|
||||
|
||||
dice._make_potentials = mock.Mock()
|
||||
|
||||
@@ -362,26 +197,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
dice._make_dice_inputs(2, 1)
|
||||
|
||||
def test_make_dice_inputs_nstep_len_three_with_randoninit_first_cycle_one(self):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice._make_potentials = mock.Mock()
|
||||
|
||||
@@ -410,26 +227,10 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.shutil')
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=True)
|
||||
def test_run_dice_on_first_cycle_run_successful(self, mock_path_exists, mock_shutils, mock_os):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.step.dice.nstep = [1, 1, 1]
|
||||
|
||||
dice.run_dice_file = mock.Mock()
|
||||
|
||||
@@ -441,26 +242,10 @@ class TestDiceInterface(unittest.TestCase):
|
||||
self.assertEqual(dice.run_dice_file.call_count, 3)
|
||||
self.assertTrue(mock_shutils.copy.called)
|
||||
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.step.dice.nstep = [1, 1]
|
||||
|
||||
dice.run_dice_file = mock.Mock()
|
||||
|
||||
@@ -476,26 +261,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.shutil')
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=True)
|
||||
def test_run_dice_on_second_cycle_run_successful(self, mock_path_exists, mock_shutils, mock_os):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.run_dice_file = mock.Mock()
|
||||
|
||||
@@ -507,26 +274,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
self.assertEqual(dice.run_dice_file.call_count, 2)
|
||||
self.assertTrue(mock_shutils.copy.called)
|
||||
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.run_dice_file = mock.Mock()
|
||||
|
||||
@@ -542,26 +291,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.shutil')
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=False)
|
||||
def test_run_dice_on_second_cycle_run_successful(self, mock_path_exists, mock_shutils, mock_os):
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.run_dice_file = mock.Mock()
|
||||
|
||||
@@ -587,32 +318,14 @@ class TestDiceInterface(unittest.TestCase):
|
||||
secondary_molecule = Molecule('secondary_molecule')
|
||||
secondary_molecule.add_atom(example_atom)
|
||||
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[
|
||||
main_molecule,
|
||||
secondary_molecule,
|
||||
],
|
||||
nmol=[
|
||||
len(main_molecule.atom),
|
||||
len(secondary_molecule.atom),
|
||||
],
|
||||
)
|
||||
)
|
||||
system = System()
|
||||
system.add_type(main_molecule)
|
||||
system.add_type(secondary_molecule)
|
||||
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, system)
|
||||
|
||||
dice.step.dice.nmol = [1, 1]
|
||||
|
||||
last_xyz_file = io.StringIO()
|
||||
last_xyz_file.writelines([
|
||||
@@ -657,32 +370,12 @@ class TestDiceInterface(unittest.TestCase):
|
||||
secondary_molecule = Molecule('secondary_molecule')
|
||||
secondary_molecule.add_atom(example_atom)
|
||||
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[
|
||||
main_molecule,
|
||||
secondary_molecule,
|
||||
],
|
||||
nmol=[
|
||||
len(main_molecule.atom),
|
||||
len(secondary_molecule.atom),
|
||||
],
|
||||
)
|
||||
)
|
||||
system = System()
|
||||
system.add_type(main_molecule)
|
||||
system.add_type(secondary_molecule)
|
||||
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, system)
|
||||
|
||||
last_xyz_file = io.StringIO()
|
||||
last_xyz_file.writelines([
|
||||
@@ -695,33 +388,15 @@ class TestDiceInterface(unittest.TestCase):
|
||||
|
||||
density = dice._new_density(last_xyz_file)
|
||||
|
||||
self.assertEqual(density, 3.3472359000000003)
|
||||
self.assertEqual(density, 85.35451545000001)
|
||||
|
||||
@mock.patch('builtins.open', new_callable=mock.mock_open)
|
||||
@mock.patch('diceplayer.shared.interface.dice_interface.random')
|
||||
def test_make_nvt_ter(self, mock_random, mock_open):
|
||||
mock_random.random.return_value = 1
|
||||
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice._make_nvt_ter(1, 'test')
|
||||
|
||||
@@ -730,7 +405,7 @@ class TestDiceInterface(unittest.TestCase):
|
||||
|
||||
lines = list(map(lambda x: x[0][0], calls))
|
||||
|
||||
expected_lines = ['title = Diceplayer run - NVT Thermalization\n', 'ncores = 1\n', 'ljname = test\n', 'outname = test\n', 'nmol = 1\n', 'dens = 1.0\n', 'temp = 300.0\n', 'init = yes\n', 'nstep = 1\n', 'vstep = 0\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 0\n', 'irdf = 0\n', 'seed = 1000000\n', 'upbuf = 360']
|
||||
expected_lines = ['title = Diceplayer run - NVT Thermalization\n', 'ncores = 4\n', 'ljname = phb.ljc\n', 'outname = phb\n', 'nmol = 1 50\n', 'dens = 0.75\n', 'temp = 300.0\n', 'init = yes\n', 'nstep = 2000\n', 'vstep = 0\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 0\n', 'irdf = 0\n', 'seed = 1000000\n', 'upbuf = 360']
|
||||
|
||||
self.assertEqual(lines, expected_lines)
|
||||
|
||||
@@ -739,26 +414,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
def test_make_nvt_eq(self, mock_random, mock_open):
|
||||
mock_random.random.return_value = 1
|
||||
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice._make_nvt_eq('test')
|
||||
|
||||
@@ -767,7 +424,7 @@ class TestDiceInterface(unittest.TestCase):
|
||||
|
||||
lines = list(map(lambda x: x[0][0], calls))
|
||||
|
||||
expected_lines = ['title = Diceplayer run - NVT Production\n', 'ncores = 1\n', 'ljname = test\n', 'outname = test\n', 'nmol = 1\n', 'dens = 1.0\n', 'temp = 300.0\n', 'init = no\n', 'nstep = 1\n', 'vstep = 0\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 1000\n', 'irdf = 10\n', 'seed = 1000000\n']
|
||||
expected_lines = ['title = Diceplayer run - NVT Production\n', 'ncores = 4\n', 'ljname = phb.ljc\n', 'outname = phb\n', 'nmol = 1 50\n', 'dens = 0.75\n', 'temp = 300.0\n', 'init = no\n', 'nstep = 3000\n', 'vstep = 0\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 1000\n', 'irdf = 40\n', 'seed = 1000000\n']
|
||||
|
||||
self.assertEqual(lines, expected_lines)
|
||||
|
||||
@@ -776,26 +433,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
def test_make_npt_ter(self, mock_random, mock_open):
|
||||
mock_random.random.return_value = 1
|
||||
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice._make_npt_ter(1, 'test')
|
||||
|
||||
@@ -804,7 +443,7 @@ class TestDiceInterface(unittest.TestCase):
|
||||
|
||||
lines = list(map(lambda x: x[0][0], calls))
|
||||
|
||||
expected_lines = ['title = Diceplayer run - NPT Thermalization\n', 'ncores = 1\n', 'ljname = test\n', 'outname = test\n', 'nmol = 1\n', 'press = 1.0\n', 'temp = 300.0\n', 'init = no\n', 'vstep = 0\n', 'nstep = 5\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 0\n', 'irdf = 0\n', 'seed = 1000000\n']
|
||||
expected_lines = ['title = Diceplayer run - NPT Thermalization\n', 'ncores = 4\n', 'ljname = phb.ljc\n', 'outname = phb\n', 'nmol = 1 50\n', 'press = 1.0\n', 'temp = 300.0\n', 'init = no\n', 'vstep = 600\n', 'nstep = 5\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 0\n', 'irdf = 0\n', 'seed = 1000000\n']
|
||||
|
||||
self.assertEqual(lines, expected_lines)
|
||||
|
||||
@@ -813,26 +452,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
def test_make_npt_eq(self, mock_random, mock_open):
|
||||
mock_random.random.return_value = 1
|
||||
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[],
|
||||
nmol=[],
|
||||
)
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice._make_npt_eq('test')
|
||||
|
||||
@@ -841,7 +462,7 @@ class TestDiceInterface(unittest.TestCase):
|
||||
|
||||
lines = list(map(lambda x: x[0][0], calls))
|
||||
|
||||
expected_lines = ['title = Diceplayer run - NPT Production\n', 'ncores = 1\n', 'ljname = test\n', 'outname = test\n', 'nmol = 1\n', 'press = 1.0\n', 'temp = 300.0\n', 'nstep = 5\n', 'vstep = 0\n', 'init = no\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 1000\n', 'irdf = 10\n', 'seed = 1000000\n']
|
||||
expected_lines = ['title = Diceplayer run - NPT Production\n', 'ncores = 4\n', 'ljname = phb.ljc\n', 'outname = phb\n', 'nmol = 1 50\n', 'press = 1.0\n', 'temp = 300.0\n', 'nstep = 5\n', 'vstep = 800\n', 'init = no\n', 'mstop = 1\n', 'accum = no\n', 'iprint = 1\n', 'isave = 1000\n', 'irdf = 40\n', 'seed = 1000000\n']
|
||||
|
||||
self.assertEqual(lines, expected_lines)
|
||||
|
||||
@@ -864,32 +485,12 @@ class TestDiceInterface(unittest.TestCase):
|
||||
secondary_molecule = Molecule('secondary_molecule')
|
||||
secondary_molecule.add_atom(example_atom)
|
||||
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice.configure(
|
||||
StepDTO(
|
||||
ncores=1,
|
||||
nprocs=1,
|
||||
simulation_dir='test',
|
||||
altsteps=1,
|
||||
molecule=[
|
||||
main_molecule,
|
||||
secondary_molecule,
|
||||
],
|
||||
nmol=[
|
||||
len(main_molecule.atom),
|
||||
len(secondary_molecule.atom),
|
||||
],
|
||||
)
|
||||
)
|
||||
system = System()
|
||||
system.add_type(main_molecule)
|
||||
system.add_type(secondary_molecule)
|
||||
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, system)
|
||||
|
||||
dice._make_potentials('test')
|
||||
|
||||
@@ -906,16 +507,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('builtins.open', new_callable=mock.mock_open, read_data='End of simulation\nBLABLA')
|
||||
def test_run_dice_file(self, mock_open, mock_subprocess):
|
||||
mock_subprocess.call.return_value = 0
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
dice.run_dice_file(1, 1, 'test')
|
||||
|
||||
@@ -926,16 +519,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('builtins.open', new_callable=mock.mock_open, read_data='Error\nBLABLA')
|
||||
def test_run_dice_file_raises_runtime_error_on_dice_file(self, mock_open, mock_subprocess):
|
||||
mock_subprocess.call.return_value = 0
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
dice.run_dice_file(1, 1, 'test')
|
||||
@@ -944,16 +529,8 @@ class TestDiceInterface(unittest.TestCase):
|
||||
@mock.patch('builtins.open', new_callable=mock.mock_open, read_data='End of simulation\nBLABLA')
|
||||
def test_run_dice_file_raises_runtime_error_of_dice_exit_code(self, mock_open, mock_subprocess):
|
||||
mock_subprocess.call.return_value = 1
|
||||
dice = DiceInterface(
|
||||
{
|
||||
'ljname': 'test',
|
||||
'outname': 'test',
|
||||
'ncores': 1,
|
||||
'dens': 1.0,
|
||||
'nmol': [1],
|
||||
'nstep': [1, 1],
|
||||
}
|
||||
)
|
||||
dice = DiceInterface()
|
||||
dice.configure(self.config, System())
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
dice.run_dice_file(1, 1, 'test')
|
||||
|
||||
113
tests/shared/interface/test_gaussian_interface.py
Normal file
113
tests/shared/interface/test_gaussian_interface.py
Normal file
@@ -0,0 +1,113 @@
|
||||
from diceplayer.shared.interface.gaussian_interface import GaussianInterface
|
||||
from diceplayer.shared.config.player_config import PlayerConfig
|
||||
from diceplayer.shared.environment.system import System
|
||||
from diceplayer import logger
|
||||
|
||||
from tests.mocks.mock_inputs import get_config_example
|
||||
|
||||
import yaml
|
||||
import io
|
||||
|
||||
|
||||
from unittest import mock
|
||||
import unittest
|
||||
|
||||
|
||||
class TestGaussianInterface(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
|
||||
config = yaml.load(get_config_example(), Loader=yaml.Loader)
|
||||
self.config = PlayerConfig.from_dict(config['diceplayer'])
|
||||
|
||||
def test_class_instantiation(self):
|
||||
gaussian_interface = GaussianInterface()
|
||||
self.assertIsInstance(gaussian_interface, GaussianInterface)
|
||||
|
||||
def test_configure(self):
|
||||
gaussian_interface = GaussianInterface()
|
||||
|
||||
self.assertIsNone(gaussian_interface.step)
|
||||
self.assertIsNone(gaussian_interface.system)
|
||||
|
||||
gaussian_interface.configure(self.config, System())
|
||||
|
||||
self.assertIsNotNone(gaussian_interface.step)
|
||||
self.assertIsNotNone(gaussian_interface.system)
|
||||
|
||||
def test_reset(self):
|
||||
gaussian_interface = GaussianInterface()
|
||||
|
||||
gaussian_interface.configure(self.config, System())
|
||||
|
||||
self.assertIsNotNone(gaussian_interface.step)
|
||||
self.assertIsNotNone(gaussian_interface.system)
|
||||
|
||||
gaussian_interface.reset()
|
||||
|
||||
self.assertFalse(hasattr(gaussian_interface, 'step'))
|
||||
self.assertFalse(hasattr(gaussian_interface, 'system'))
|
||||
|
||||
@mock.patch('diceplayer.shared.interface.gaussian_interface.Path.mkdir')
|
||||
@mock.patch('diceplayer.shared.interface.gaussian_interface.Path.exists')
|
||||
def test_make_qm_dir(self, mock_exists, mock_mkdir):
|
||||
mock_exists.return_value = False
|
||||
|
||||
gaussian_interface = GaussianInterface()
|
||||
gaussian_interface.configure(self.config, System())
|
||||
|
||||
gaussian_interface._make_qm_dir(1)
|
||||
|
||||
mock_exists.assert_called_once()
|
||||
mock_mkdir.assert_called_once()
|
||||
|
||||
@mock.patch('diceplayer.shared.interface.gaussian_interface.shutil.copy')
|
||||
@mock.patch('diceplayer.shared.interface.gaussian_interface.Path.exists')
|
||||
def test_copy_chk_file_from_previous_step(self, mock_exists, mock_copy):
|
||||
gaussian_interface = GaussianInterface()
|
||||
gaussian_interface.configure(self.config, System())
|
||||
|
||||
mock_exists.side_effect = [False, True]
|
||||
|
||||
gaussian_interface._copy_chk_file_from_previous_step(2)
|
||||
|
||||
self.assertTrue(mock_exists.called)
|
||||
self.assertTrue(mock_copy.called)
|
||||
|
||||
@mock.patch('diceplayer.shared.interface.gaussian_interface.shutil.copy')
|
||||
@mock.patch('diceplayer.shared.interface.gaussian_interface.Path.exists')
|
||||
def test_copy_chk_file_from_previous_step_no_previous_step(self, mock_exists, mock_copy):
|
||||
gaussian_interface = GaussianInterface()
|
||||
gaussian_interface.configure(self.config, System())
|
||||
|
||||
mock_exists.side_effect = [False, False]
|
||||
|
||||
with self.assertRaises(FileNotFoundError):
|
||||
gaussian_interface._copy_chk_file_from_previous_step(2)
|
||||
|
||||
@mock.patch('diceplayer.shared.interface.gaussian_interface.shutil.copy')
|
||||
@mock.patch('diceplayer.shared.interface.gaussian_interface.Path.exists')
|
||||
def test_copy_chk_file_from_previous_step_current_exists(self, mock_exists, mock_copy):
|
||||
gaussian_interface = GaussianInterface()
|
||||
gaussian_interface.configure(self.config, System())
|
||||
|
||||
mock_exists.side_effect = [True, True]
|
||||
|
||||
with self.assertRaises(FileExistsError):
|
||||
gaussian_interface._copy_chk_file_from_previous_step(2)
|
||||
|
||||
# def test_start(self):
|
||||
# gaussian_interface = GaussianInterface()
|
||||
# gaussian_interface.configure(self.config, System())
|
||||
#
|
||||
# gaussian_interface._make_qm_dir = mock.Mock()
|
||||
# gaussian_interface._copy_chk_file_from_previous_step = mock.Mock()
|
||||
#
|
||||
# gaussian_interface.start(2)
|
||||
#
|
||||
# gaussian_interface._make_qm_dir.assert_called_once_with(2)
|
||||
# gaussian_interface._copy_chk_file_from_previous_step.assert_called_once_with(2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -3,119 +3,12 @@ from diceplayer import logger
|
||||
|
||||
import io
|
||||
|
||||
from tests.mocks.mock_inputs import mock_open
|
||||
|
||||
from unittest import mock
|
||||
import unittest
|
||||
|
||||
|
||||
def get_config_example():
|
||||
return """
|
||||
diceplayer:
|
||||
maxcyc: 3
|
||||
opt: no
|
||||
ncores: 4
|
||||
nprocs: 4
|
||||
qmprog: 'g16'
|
||||
lps: no
|
||||
ghosts: no
|
||||
altsteps: 20000
|
||||
|
||||
dice:
|
||||
nmol: [1, 50]
|
||||
dens: 0.75
|
||||
nstep: [2000, 3000, 4000]
|
||||
isave: 1000
|
||||
outname: 'phb'
|
||||
progname: '~/.local/bin/dice'
|
||||
ljname: 'phb.ljc'
|
||||
randominit: 'first'
|
||||
|
||||
gaussian:
|
||||
qmprog: 'g16'
|
||||
level: 'MP2/aug-cc-pVDZ'
|
||||
keywords: 'freq'
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_exemple():
|
||||
return """\
|
||||
*
|
||||
2
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_combrule():
|
||||
return """\
|
||||
.
|
||||
2
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_ntypes():
|
||||
return """\
|
||||
*
|
||||
a
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_ntypes_config():
|
||||
return """\
|
||||
*
|
||||
3
|
||||
1 TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_nsites():
|
||||
return """\
|
||||
*
|
||||
2
|
||||
. TEST
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def get_potentials_error_molname():
|
||||
return """\
|
||||
*
|
||||
2
|
||||
1
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
1 PLACEHOLDER
|
||||
1 1 0.000000 0.000000 0.000000 0.000000 0.0000 0.0000
|
||||
"""
|
||||
|
||||
|
||||
def mock_open(file, *args, **kwargs):
|
||||
values = {
|
||||
"control.test.yml": get_config_example(),
|
||||
"phb.ljc": get_potentials_exemple(),
|
||||
"phb.error.combrule.ljc": get_potentials_error_combrule(),
|
||||
"phb.error.ntypes.ljc": get_potentials_error_ntypes(),
|
||||
"phb.error.ntypes.config.ljc": get_potentials_error_ntypes_config(),
|
||||
"phb.error.nsites.ljc": get_potentials_error_nsites(),
|
||||
"phb.error.molname.ljc": get_potentials_error_molname(),
|
||||
}
|
||||
mock_file = mock.mock_open(read_data=values[file])
|
||||
return mock_file()
|
||||
|
||||
|
||||
class TestPlayer(unittest.TestCase):
|
||||
def setUp(self):
|
||||
logger.set_logger(stream=io.StringIO())
|
||||
@@ -131,19 +24,13 @@ class TestPlayer(unittest.TestCase):
|
||||
def test_start(self):
|
||||
player = Player("control.test.yml")
|
||||
|
||||
player.print_keywords = mock.MagicMock()
|
||||
player.create_simulation_dir = mock.MagicMock()
|
||||
player.read_potentials = mock.MagicMock()
|
||||
player.print_potentials = mock.MagicMock()
|
||||
player.gaussian_start = mock.MagicMock()
|
||||
player.dice_start = mock.MagicMock()
|
||||
|
||||
player.start(1)
|
||||
|
||||
self.assertTrue(player.print_keywords.called)
|
||||
self.assertTrue(player.create_simulation_dir.called)
|
||||
self.assertTrue(player.read_potentials.called)
|
||||
self.assertTrue(player.print_potentials.called)
|
||||
self.assertEqual(player.dice_start.call_count, 3)
|
||||
self.assertEqual(player.gaussian_start.call_count, 3)
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
@mock.patch("diceplayer.player.Path")
|
||||
@@ -178,7 +65,22 @@ class TestPlayer(unittest.TestCase):
|
||||
with self.assertLogs() as cm:
|
||||
player.print_keywords()
|
||||
|
||||
expected_output = ['INFO:diceplayer:##########################################################################################\n############# Welcome to DICEPLAYER version 1.0 #############\n##########################################################################################\n\n', 'INFO:diceplayer:Your python version is TEST\n', 'INFO:diceplayer:\n', 'INFO:diceplayer:Program started on 00 Test 0000 at 00:00:00\n', 'INFO:diceplayer:\n', 'INFO:diceplayer:Environment variables:\n', 'INFO:diceplayer:OMP_STACKSIZE = Not set\n', 'INFO:diceplayer:\n==========================================================================================\n CONTROL variables being used in this run:\n------------------------------------------------------------------------------------------\n\n', 'INFO:diceplayer:\n', 'INFO:diceplayer:------------------------------------------------------------------------------------------\n DICE variables being used in this run:\n------------------------------------------------------------------------------------------\n\n', 'INFO:diceplayer:dens = 0.75', 'INFO:diceplayer:isave = 1000', 'INFO:diceplayer:ljname = phb.ljc', 'INFO:diceplayer:nmol = [ 1 50 ]', 'INFO:diceplayer:nstep = [ 2000 3000 4000 ]', 'INFO:diceplayer:outname = phb', 'INFO:diceplayer:press = 1.0', 'INFO:diceplayer:progname = ~/.local/bin/dice', 'INFO:diceplayer:randominit = first', 'INFO:diceplayer:temp = 300.0', 'INFO:diceplayer:\n', 'INFO:diceplayer:------------------------------------------------------------------------------------------\n GAUSSIAN variables being used in this run:\n------------------------------------------------------------------------------------------\n\n', 'INFO:diceplayer:keywords = freq', 'INFO:diceplayer:level = MP2/aug-cc-pVDZ', 'INFO:diceplayer:pop = chelpg', 'INFO:diceplayer:qmprog = g16', 'INFO:diceplayer:\n']
|
||||
expected_output = [
|
||||
'INFO:diceplayer:##########################################################################################\n############# Welcome to DICEPLAYER version 1.0 #############\n##########################################################################################\n\n',
|
||||
'INFO:diceplayer:Your python version is TEST\n', 'INFO:diceplayer:\n',
|
||||
'INFO:diceplayer:Program started on 00 Test 0000 at 00:00:00\n', 'INFO:diceplayer:\n',
|
||||
'INFO:diceplayer:Environment variables:\n', 'INFO:diceplayer:OMP_STACKSIZE = Not set\n',
|
||||
'INFO:diceplayer:\n==========================================================================================\n CONTROL variables being used in this run:\n------------------------------------------------------------------------------------------\n\n',
|
||||
'INFO:diceplayer:\n',
|
||||
'INFO:diceplayer:------------------------------------------------------------------------------------------\n DICE variables being used in this run:\n------------------------------------------------------------------------------------------\n\n',
|
||||
'INFO:diceplayer:dens = 0.75', 'INFO:diceplayer:isave = 1000', 'INFO:diceplayer:ljname = phb.ljc',
|
||||
'INFO:diceplayer:nmol = [ 1 50 ]', 'INFO:diceplayer:nstep = [ 2000 3000 4000 ]',
|
||||
'INFO:diceplayer:outname = phb', 'INFO:diceplayer:press = 1.0',
|
||||
'INFO:diceplayer:progname = ~/.local/bin/dice', 'INFO:diceplayer:randominit = first',
|
||||
'INFO:diceplayer:temp = 300.0', 'INFO:diceplayer:\n',
|
||||
'INFO:diceplayer:------------------------------------------------------------------------------------------\n GAUSSIAN variables being used in this run:\n------------------------------------------------------------------------------------------\n\n',
|
||||
'INFO:diceplayer:keywords = freq', 'INFO:diceplayer:level = MP2/aug-cc-pVDZ',
|
||||
'INFO:diceplayer:pop = chelpg', 'INFO:diceplayer:qmprog = g16', 'INFO:diceplayer:\n']
|
||||
|
||||
self.assertEqual(cm.output, expected_output)
|
||||
|
||||
@@ -333,7 +235,7 @@ class TestPlayer(unittest.TestCase):
|
||||
|
||||
# Testing combrule error
|
||||
with self.assertRaises(SystemExit) as context:
|
||||
player.dice.config.ljname = "phb.error.combrule.ljc"
|
||||
player.config.dice.ljname = "phb.error.combrule.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
@@ -343,7 +245,7 @@ class TestPlayer(unittest.TestCase):
|
||||
|
||||
# Testing ntypes error
|
||||
with self.assertRaises(SystemExit) as context:
|
||||
player.dice.config.ljname = "phb.error.ntypes.ljc"
|
||||
player.config.dice.ljname = "phb.error.ntypes.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
@@ -353,7 +255,7 @@ class TestPlayer(unittest.TestCase):
|
||||
|
||||
# Testing ntypes error on config
|
||||
with self.assertRaises(SystemExit) as context:
|
||||
player.dice.config.ljname = "phb.error.ntypes.config.ljc"
|
||||
player.config.dice.ljname = "phb.error.ntypes.config.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
@@ -364,7 +266,7 @@ class TestPlayer(unittest.TestCase):
|
||||
|
||||
# Testing nsite error
|
||||
with self.assertRaises(ValueError) as context:
|
||||
player.dice.config.ljname = "phb.error.nsites.ljc"
|
||||
player.config.dice.ljname = "phb.error.nsites.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
@@ -374,7 +276,7 @@ class TestPlayer(unittest.TestCase):
|
||||
|
||||
# Testing molname error
|
||||
with self.assertRaises(ValueError) as context:
|
||||
player.dice.config.ljname = "phb.error.molname.ljc"
|
||||
player.config.dice.ljname = "phb.error.molname.ljc"
|
||||
player.read_potentials()
|
||||
|
||||
self.assertEqual(
|
||||
@@ -391,7 +293,23 @@ class TestPlayer(unittest.TestCase):
|
||||
with self.assertLogs(level='INFO') as context:
|
||||
player.print_potentials()
|
||||
|
||||
expected_output = ['INFO:diceplayer:==========================================================================================\n', 'INFO:diceplayer: Potential parameters from file phb.ljc:', 'INFO:diceplayer:------------------------------------------------------------------------------------------\n', 'INFO:diceplayer:Combination rule: *', 'INFO:diceplayer:Types of molecules: 2\n', 'INFO:diceplayer:1 atoms in molecule type 1:', 'INFO:diceplayer:---------------------------------------------------------------------------------', 'INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass', 'INFO:diceplayer:---------------------------------------------------------------------------------', 'INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079', 'INFO:diceplayer:\n', 'INFO:diceplayer:1 atoms in molecule type 2:', 'INFO:diceplayer:---------------------------------------------------------------------------------', 'INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass', 'INFO:diceplayer:---------------------------------------------------------------------------------', 'INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079', 'INFO:diceplayer:\n', 'INFO:diceplayer:==========================================================================================']
|
||||
expected_output = [
|
||||
'INFO:diceplayer:==========================================================================================\n',
|
||||
'INFO:diceplayer: Potential parameters from file phb.ljc:',
|
||||
'INFO:diceplayer:------------------------------------------------------------------------------------------\n',
|
||||
'INFO:diceplayer:Combination rule: *', 'INFO:diceplayer:Types of molecules: 2\n',
|
||||
'INFO:diceplayer:1 atoms in molecule type 1:',
|
||||
'INFO:diceplayer:---------------------------------------------------------------------------------',
|
||||
'INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass',
|
||||
'INFO:diceplayer:---------------------------------------------------------------------------------',
|
||||
'INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079',
|
||||
'INFO:diceplayer:\n', 'INFO:diceplayer:1 atoms in molecule type 2:',
|
||||
'INFO:diceplayer:---------------------------------------------------------------------------------',
|
||||
'INFO:diceplayer:Lbl AN X Y Z Charge Epsilon Sigma Mass',
|
||||
'INFO:diceplayer:---------------------------------------------------------------------------------',
|
||||
'INFO:diceplayer:1 1 0.00000 0.00000 0.00000 0.000000 0.00000 0.0000 1.0079',
|
||||
'INFO:diceplayer:\n',
|
||||
'INFO:diceplayer:==========================================================================================']
|
||||
|
||||
self.assertEqual(
|
||||
context.output,
|
||||
@@ -401,23 +319,22 @@ class TestPlayer(unittest.TestCase):
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
def test_dice_start(self):
|
||||
player = Player("control.test.yml")
|
||||
player.dice = mock.MagicMock()
|
||||
player.dice.start = mock.MagicMock()
|
||||
player.dice_interface = mock.MagicMock()
|
||||
player.dice_interface.start = mock.MagicMock()
|
||||
|
||||
player.dice_start(1)
|
||||
|
||||
player.dice.start.assert_called_once()
|
||||
|
||||
@mock.patch("builtins.open", mock_open)
|
||||
def test_gaussian_start(self):
|
||||
player = Player("control.test.yml")
|
||||
player.gaussian = mock.MagicMock()
|
||||
player.gaussian.start = mock.MagicMock()
|
||||
|
||||
player.gaussian_start(1)
|
||||
|
||||
player.gaussian.start.assert_called_once()
|
||||
player.dice_interface.start.assert_called_once()
|
||||
|
||||
# @mock.patch("builtins.open", mock_open)
|
||||
# def test_gaussian_start(self):
|
||||
# player = Player("control.test.yml")
|
||||
# player.gaussian_interface = mock.MagicMock()
|
||||
# player.gaussian_interface.start = mock.MagicMock()
|
||||
#
|
||||
# player.gaussian_start(1)
|
||||
#
|
||||
# player.gaussian_interface.start.assert_called_once()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user