Implements Refactoring in Player Class and Initial Working Version
This commit is contained in:
@@ -1,24 +1,24 @@
|
|||||||
diceplayer:
|
diceplayer:
|
||||||
maxcyc: 3
|
|
||||||
opt: no
|
opt: no
|
||||||
ncores: 4
|
mem: 24
|
||||||
|
maxcyc: 10
|
||||||
|
ncores: 5
|
||||||
nprocs: 4
|
nprocs: 4
|
||||||
qmprog: 'g16'
|
qmprog: 'g16'
|
||||||
lps: no
|
lps: no
|
||||||
ghosts: no
|
ghosts: no
|
||||||
altsteps: 20000
|
altsteps: 20000
|
||||||
|
|
||||||
dice:
|
dice:
|
||||||
nmol: [1, 50]
|
nmol: [1, 1000]
|
||||||
dens: 0.75
|
dens: 1.0
|
||||||
nstep: [2000, 3000, 4000]
|
nstep: [2000, 3000]
|
||||||
isave: 1000
|
isave: 1000
|
||||||
outname: 'phb'
|
outname: 'phb'
|
||||||
progname: '~/.local/bin/dice'
|
progname: '~/.local/bin/dice'
|
||||||
ljname: 'phb.ljc'
|
ljname: 'phb.ljc'
|
||||||
randominit: 'first'
|
randominit: 'first'
|
||||||
|
|
||||||
gaussian:
|
gaussian:
|
||||||
qmprog: 'g16'
|
qmprog: 'g16'
|
||||||
level: 'MP2/aug-cc-pVDZ'
|
level: 'MP2/aug-cc-pVDZ'
|
||||||
keywords: 'freq'
|
|
||||||
|
|||||||
@@ -55,8 +55,25 @@ def main():
|
|||||||
|
|
||||||
player = Player(args.infile)
|
player = Player(args.infile)
|
||||||
|
|
||||||
|
player.print_keywords()
|
||||||
|
|
||||||
|
player.create_simulation_dir()
|
||||||
|
|
||||||
|
player.read_potentials()
|
||||||
|
player.print_potentials()
|
||||||
|
|
||||||
|
player.prepare_system()
|
||||||
|
|
||||||
player.start()
|
player.start()
|
||||||
|
|
||||||
|
logger.info("\n+" + 88 * "-" + "+\n")
|
||||||
|
|
||||||
|
player.print_results()
|
||||||
|
|
||||||
|
logger.info("\n+" + 88 * "-" + "+\n")
|
||||||
|
|
||||||
|
logger.info("Diceplayer finished successfully \n")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
from diceplayer.shared.interface.gaussian_interface import GaussianInterface
|
from diceplayer.shared.interface.gaussian_interface import GaussianInterface
|
||||||
from diceplayer.shared.interface.dice_interface import DiceInterface
|
from diceplayer.shared.interface.dice_interface import DiceInterface
|
||||||
from diceplayer.shared.utils.dataclass_protocol import Dataclass
|
from diceplayer.shared.utils.dataclass_protocol import Dataclass
|
||||||
from diceplayer.shared.config.gaussian_dto import GaussianDTO
|
from diceplayer.shared.config.gaussian_config import GaussianDTO
|
||||||
from diceplayer.shared.environment.molecule import Molecule
|
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.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.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.shared.environment.atom import Atom
|
||||||
from diceplayer import logger
|
from diceplayer import logger
|
||||||
|
|
||||||
from dataclasses import fields
|
from dataclasses import fields
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Type
|
from typing import Type, List
|
||||||
import logging
|
import logging
|
||||||
import yaml
|
import yaml
|
||||||
import sys
|
import sys
|
||||||
@@ -33,20 +32,50 @@ class Player:
|
|||||||
config_data.get("diceplayer")
|
config_data.get("diceplayer")
|
||||||
)
|
)
|
||||||
|
|
||||||
self.gaussian = GaussianInterface(config_data.get("gaussian"))
|
self.dice_interface = DiceInterface()
|
||||||
self.dice = DiceInterface(config_data.get("dice"))
|
self.gaussian_interface = GaussianInterface()
|
||||||
|
|
||||||
def start(self, initial_cycle: int = 1):
|
def start(self, initial_cycle: int = 1):
|
||||||
self.print_keywords()
|
logger.info(
|
||||||
|
"==========================================================================================\n"
|
||||||
self.create_simulation_dir()
|
"Starting the iterative process.\n"
|
||||||
|
"==========================================================================================\n"
|
||||||
self.read_potentials()
|
)
|
||||||
self.print_potentials()
|
|
||||||
|
|
||||||
for cycle in range(initial_cycle, self.config.maxcyc + 1):
|
for cycle in range(initial_cycle, self.config.maxcyc + 1):
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"------------------------------------------------------------------------------------------\n"
|
||||||
|
f" Step # {cycle}\n"
|
||||||
|
f"------------------------------------------------------------------------------------------\n"
|
||||||
|
)
|
||||||
|
|
||||||
self.dice_start(cycle)
|
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):
|
def create_simulation_dir(self):
|
||||||
simulation_dir_path = Path(self.config.simulation_dir)
|
simulation_dir_path = Path(self.config.simulation_dir)
|
||||||
if simulation_dir_path.exists():
|
if simulation_dir_path.exists():
|
||||||
@@ -71,13 +100,10 @@ class Player:
|
|||||||
"##########################################################################################\n"
|
"##########################################################################################\n"
|
||||||
"############# Welcome to DICEPLAYER version 1.0 #############\n"
|
"############# Welcome to DICEPLAYER version 1.0 #############\n"
|
||||||
"##########################################################################################\n"
|
"##########################################################################################\n"
|
||||||
"\n"
|
|
||||||
)
|
)
|
||||||
logger.info("Your python version is {}\n".format(sys.version))
|
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("Program started on {}\n".format(weekday_date_time()))
|
||||||
logger.info("\n")
|
logger.info("Environment variables:")
|
||||||
logger.info("Environment variables:\n")
|
|
||||||
for var in ENV:
|
for var in ENV:
|
||||||
logger.info(
|
logger.info(
|
||||||
"{} = {}\n".format(
|
"{} = {}\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(
|
logger.info(
|
||||||
"------------------------------------------------------------------------------------------\n"
|
"------------------------------------------------------------------------------------------\n"
|
||||||
" DICE variables being used in this run:\n"
|
" DICE variables being used in this run:\n"
|
||||||
"------------------------------------------------------------------------------------------\n"
|
"------------------------------------------------------------------------------------------\n"
|
||||||
"\n"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
log_keywords(self.dice.config, DiceDTO)
|
log_keywords(self.config.dice, DiceConfig)
|
||||||
|
|
||||||
logger.info("\n")
|
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"------------------------------------------------------------------------------------------\n"
|
"------------------------------------------------------------------------------------------\n"
|
||||||
" GAUSSIAN variables being used in this run:\n"
|
" GAUSSIAN variables being used in this run:\n"
|
||||||
"------------------------------------------------------------------------------------------\n"
|
"------------------------------------------------------------------------------------------\n"
|
||||||
"\n"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
log_keywords(self.gaussian.config, GaussianDTO)
|
log_keywords(self.config.gaussian, GaussianDTO)
|
||||||
|
|
||||||
logger.info("\n")
|
logger.info("\n")
|
||||||
|
|
||||||
def read_potentials(self):
|
def read_potentials(self):
|
||||||
ljname_path = Path(self.dice.config.ljname)
|
ljname_path = Path(self.config.dice.ljname)
|
||||||
if ljname_path.exists():
|
if ljname_path.exists():
|
||||||
with open(self.dice.config.ljname) as file:
|
with open(self.config.dice.ljname) as file:
|
||||||
ljc_data = file.readlines()
|
ljc_data = file.readlines()
|
||||||
else:
|
else:
|
||||||
raise RuntimeError(
|
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]
|
combrule = ljc_data.pop(0).split()[0]
|
||||||
if combrule not in ("*", "+"):
|
if combrule not in ("*", "+"):
|
||||||
sys.exit(
|
sys.exit(
|
||||||
"Error: expected a '*' or a '+' sign in 1st line of file {}".format(
|
"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]
|
ntypes = ljc_data.pop(0).split()[0]
|
||||||
if not ntypes.isdigit():
|
if not ntypes.isdigit():
|
||||||
sys.exit(
|
sys.exit(
|
||||||
"Error: expected an integer in the 2nd line of file {}".format(
|
"Error: expected an integer in the 2nd line of file {}".format(
|
||||||
self.dice.config.ljname
|
self.config.dice.ljname
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
ntypes = int(ntypes)
|
ntypes = int(ntypes)
|
||||||
|
|
||||||
if ntypes != len(self.dice.config.nmol):
|
if ntypes != len(self.config.dice.nmol):
|
||||||
sys.exit(
|
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"
|
f"must match that of 'nmol' keyword in config file"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -165,7 +178,7 @@ class Player:
|
|||||||
)
|
)
|
||||||
|
|
||||||
nsites = int(nsites)
|
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"]
|
atom_fields = ["lbl", "na", "rx", "ry", "rz", "chg", "eps", "sig"]
|
||||||
for j in range(nsites):
|
for j in range(nsites):
|
||||||
@@ -178,20 +191,15 @@ class Player:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def print_potentials(self) -> None:
|
def print_potentials(self) -> None:
|
||||||
|
|
||||||
formatstr = "{:<3d} {:>3d} {:>10.5f} {:>10.5f} {:>10.5f} {:>10.6f} {:>9.5f} {:>7.4f} {:>9.4f}"
|
formatstr = "{:<3d} {:>3d} {:>10.5f} {:>10.5f} {:>10.5f} {:>10.6f} {:>9.5f} {:>7.4f} {:>9.4f}"
|
||||||
logger.info(
|
logger.info(
|
||||||
"==========================================================================================\n"
|
"==========================================================================================\n"
|
||||||
)
|
f" Potential parameters from file {self.config.dice.ljname}:\n"
|
||||||
logger.info(
|
|
||||||
f" Potential parameters from file {self.dice.config.ljname}:"
|
|
||||||
)
|
|
||||||
logger.info(
|
|
||||||
"------------------------------------------------------------------------------------------"
|
"------------------------------------------------------------------------------------------"
|
||||||
"\n"
|
"\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(f"Combination rule: {self.dice.config.combrule}")
|
logger.info(f"Combination rule: {self.config.dice.combrule}")
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Types of molecules: {len(self.system.molecule)}\n"
|
f"Types of molecules: {len(self.system.molecule)}\n"
|
||||||
)
|
)
|
||||||
@@ -229,28 +237,50 @@ class Player:
|
|||||||
|
|
||||||
logger.info("\n")
|
logger.info("\n")
|
||||||
|
|
||||||
logger.info(
|
|
||||||
"=========================================================================================="
|
|
||||||
)
|
|
||||||
|
|
||||||
def dice_start(self, cycle: int):
|
def dice_start(self, cycle: int):
|
||||||
self.dice.configure(
|
self.dice_interface.configure(
|
||||||
StepDTO(
|
self.config,
|
||||||
ncores=self.config.ncores,
|
self.system,
|
||||||
nprocs=self.config.nprocs,
|
|
||||||
simulation_dir=self.config.simulation_dir,
|
|
||||||
altsteps=self.config.altsteps,
|
|
||||||
molecule=self.system.molecule,
|
|
||||||
nmol=self.system.nmols,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.dice.start(cycle)
|
self.dice_interface.start(cycle)
|
||||||
|
|
||||||
self.dice.reset()
|
self.dice_interface.reset()
|
||||||
|
|
||||||
def gaussian_start(self, cycle: int):
|
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
|
@staticmethod
|
||||||
def validate_atom_dict(molecule_type, molecule_site, atom_dict: dict) -> dict:
|
def validate_atom_dict(molecule_type, molecule_site, atom_dict: dict) -> dict:
|
||||||
@@ -326,9 +356,43 @@ class Player:
|
|||||||
|
|
||||||
return atom_dict
|
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
|
@staticmethod
|
||||||
def set_config(data: dict) -> PlayerDTO:
|
def set_config(data: dict) -> PlayerConfig:
|
||||||
return PlayerDTO.from_dict(data)
|
return PlayerConfig.from_dict(data)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read_keywords(infile) -> dict:
|
def read_keywords(infile) -> dict:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from typing import List
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class DiceDTO(Dataclass):
|
class DiceConfig(Dataclass):
|
||||||
"""
|
"""
|
||||||
Data Transfer Object for the Dice configuration.
|
Data Transfer Object for the Dice configuration.
|
||||||
"""
|
"""
|
||||||
@@ -53,4 +53,4 @@ class DiceDTO(Dataclass):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, param: dict):
|
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
|
level: str
|
||||||
qmprog: str
|
qmprog: str
|
||||||
keywords: str
|
|
||||||
|
|
||||||
chgmult = [0, 1]
|
chgmult = [0, 1]
|
||||||
pop: str = 'chelpg'
|
pop: str = 'chelpg'
|
||||||
|
chg_tol: float = 0.01
|
||||||
|
keywords: str = None
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
if self.qmprog not in ("g03", "g09", "g16"):
|
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
|
from __future__ import annotations
|
||||||
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 diceplayer.shared.utils.ptable import ghost_number
|
||||||
from diceplayer.shared.environment.atom import Atom
|
from diceplayer.shared.environment.atom import Atom
|
||||||
from diceplayer.shared.utils.misc import BOHR2ANG
|
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:
|
class Molecule:
|
||||||
@@ -185,11 +188,18 @@ class Molecule:
|
|||||||
|
|
||||||
return position
|
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):
|
for i, atom in enumerate(self.atom):
|
||||||
|
diff = max(diff, abs(atom.chg - charges[i]))
|
||||||
atom.chg = charges[i]
|
atom.chg = charges[i]
|
||||||
|
|
||||||
|
return diff
|
||||||
|
|
||||||
# @staticmethod
|
# @staticmethod
|
||||||
# def update_hessian(
|
# def update_hessian(
|
||||||
# step: np.ndarray,
|
# step: np.ndarray,
|
||||||
@@ -299,48 +309,48 @@ class Molecule:
|
|||||||
Prints the Molecule information into a Output File
|
Prints the Molecule information into a Output File
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logging.info(
|
logger.info(
|
||||||
" Center of mass = ( {:>10.4f} , {:>10.4f} , {:>10.4f} )\n".format(
|
" Center of mass = ( {:>10.4f} , {:>10.4f} , {:>10.4f} )".format(
|
||||||
self.com[0], self.com[1], self.com[2]
|
self.com[0], self.com[1], self.com[2]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
inertia = self.inertia_tensor()
|
inertia = self.inertia_tensor()
|
||||||
evals, evecs = self.principal_axes()
|
evals, evecs = self.principal_axes()
|
||||||
|
|
||||||
logging.info(
|
logger.info(
|
||||||
" Moments of inertia = {:>9E} {:>9E} {:>9E}\n".format(
|
" Moments of inertia = {:>9E} {:>9E} {:>9E}".format(
|
||||||
evals[0], evals[1], evals[2]
|
evals[0], evals[1], evals[2]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
logging.info(
|
logger.info(
|
||||||
" Major principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )\n".format(
|
" Major principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )".format(
|
||||||
evecs[0, 0], evecs[1, 0], evecs[2, 0]
|
evecs[0, 0], evecs[1, 0], evecs[2, 0]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
logging.info(
|
logger.info(
|
||||||
" Inter principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )\n".format(
|
" Inter principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )".format(
|
||||||
evecs[0, 1], evecs[1, 1], evecs[2, 1]
|
evecs[0, 1], evecs[1, 1], evecs[2, 1]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
logging.info(
|
logger.info(
|
||||||
" Minor principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )\n".format(
|
" Minor principal axis = ( {:>10.6f} , {:>10.6f} , {:>10.6f} )".format(
|
||||||
evecs[0, 2], evecs[1, 2], evecs[2, 2]
|
evecs[0, 2], evecs[1, 2], evecs[2, 2]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
sizes = self.sizes_of_molecule()
|
sizes = self.sizes_of_molecule()
|
||||||
logging.info(
|
logger.info(
|
||||||
" Characteristic lengths = ( {:>6.2f} , {:>6.2f} , {:>6.2f} )\n".format(
|
" Characteristic lengths = ( {:>6.2f} , {:>6.2f} , {:>6.2f} )".format(
|
||||||
sizes[0], sizes[1], sizes[2]
|
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()
|
chg_dip = self.charges_and_dipole()
|
||||||
logging.info(" Total charge = {:>8.4f} e\n".format(chg_dip[0]))
|
logger.info(" Total charge = {:>8.4f} e".format(chg_dip[0]))
|
||||||
logging.info(
|
logger.info(
|
||||||
" Dipole moment = ( {:>9.4f} , {:>9.4f} , {:>9.4f} ) Total = {:>9.4f} Debye\n\n".format(
|
" 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]
|
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.environment.molecule import Molecule
|
||||||
from diceplayer.shared.utils.ptable import atomsymb
|
from diceplayer.shared.utils.ptable import atomsymb
|
||||||
from diceplayer.shared.utils.misc import BOHR2ANG
|
from diceplayer.shared.utils.misc import BOHR2ANG
|
||||||
|
from diceplayer import logger
|
||||||
|
|
||||||
from typing import List, Tuple, TextIO
|
from typing import List, Tuple, TextIO
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
@@ -20,41 +21,33 @@ class System:
|
|||||||
|
|
||||||
def __init__(self) -> None:
|
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.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
|
Adds a new molecule type to the system
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
nmols (int): Number of molecules of the new type in the system
|
|
||||||
m (Molecule): The instance of the new type of molecule
|
m (Molecule): The instance of the new type of molecule
|
||||||
"""
|
"""
|
||||||
if isinstance(m, Molecule) is False:
|
if isinstance(m, Molecule) is False:
|
||||||
raise TypeError("Error: molecule is not a Molecule instance")
|
raise TypeError("Error: molecule is not a Molecule instance")
|
||||||
self.molecule.append(m)
|
self.molecule.append(m)
|
||||||
|
|
||||||
if isinstance(nmols, int) is False:
|
def update_molecule(self, position: np.ndarray) -> None:
|
||||||
raise TypeError("Error: nmols is not an integer")
|
|
||||||
self.nmols.append(nmols)
|
|
||||||
|
|
||||||
def update_molecule(self, position: np.ndarray, fh: TextIO) -> None:
|
|
||||||
"""Updates the position of the molecule in the Output file
|
"""Updates the position of the molecule in the Output file
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
position (np.ndarray): numpy position vector
|
position (np.ndarray): numpy position vector
|
||||||
fh (TextIO): Output file
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
position_in_ang = (position * BOHR2ANG).tolist()
|
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:
|
for atom in self.molecule[-1].atom:
|
||||||
|
|
||||||
atom.rx = position_in_ang.pop(0)
|
atom.rx = position_in_ang.pop(0)
|
||||||
atom.ry = position_in_ang.pop(0)
|
atom.ry = position_in_ang.pop(0)
|
||||||
atom.rz = 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)
|
rmsd, self.molecule[0] = self.rmsd_fit(-1, 0)
|
||||||
self.molecule.pop(-1)
|
self.molecule.pop(-1)
|
||||||
|
|
||||||
fh.write("\nProjected new conformation of reference molecule with RMSD fit\n")
|
logger.info("Projected new conformation of reference molecule with RMSD fit")
|
||||||
fh.write("RMSD = {:>8.5f} Angstrom\n".format(rmsd))
|
logger.info(f"RMSD = {rmsd:>8.5f} Angstrom")
|
||||||
|
|
||||||
def rmsd_fit(self, p_index: int, r_index: int) -> Tuple[float, Molecule]:
|
def rmsd_fit(self, p_index: int, r_index: int) -> Tuple[float, Molecule]:
|
||||||
|
|
||||||
@@ -200,7 +193,6 @@ class System:
|
|||||||
#
|
#
|
||||||
# return min_dist, nearestmol
|
# return min_dist, nearestmol
|
||||||
|
|
||||||
|
|
||||||
# def print_geom(self, cycle: int, fh: TextIO) -> None:
|
# def print_geom(self, cycle: int, fh: TextIO) -> None:
|
||||||
# """
|
# """
|
||||||
# Print the geometry of the molecule in the Output file
|
# Print the geometry of the molecule in the Output file
|
||||||
@@ -220,22 +212,22 @@ class System:
|
|||||||
# )
|
# )
|
||||||
# )
|
# )
|
||||||
#
|
#
|
||||||
# def printChargesAndDipole(self, cycle: int, fh: TextIO) -> None:
|
def print_charges_and_dipole(self, cycle: int) -> None:
|
||||||
# """
|
"""
|
||||||
# Print the charges and dipole of the molecule in the Output file
|
Print the charges and dipole of the molecule in the Output file
|
||||||
#
|
|
||||||
# Args:
|
Args:
|
||||||
# cycle (int): Number of the cycle
|
cycle (int): Number of the cycle
|
||||||
# fh (TextIO): Output file
|
fh (TextIO): Output file
|
||||||
# """
|
"""
|
||||||
#
|
|
||||||
# fh.write("Cycle # {}\n".format(cycle))
|
logger.info("Cycle # {}\n".format(cycle))
|
||||||
# fh.write("Number of site: {}\n".format(len(self.molecule[0].atom)))
|
logger.info("Number of site: {}\n".format(len(self.molecule[0].atom)))
|
||||||
#
|
|
||||||
# chargesAndDipole = self.molecule[0].charges_and_dipole()
|
chargesAndDipole = self.molecule[0].charges_and_dipole()
|
||||||
#
|
|
||||||
# fh.write(
|
logger.info(
|
||||||
# "{:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f}\n".format(
|
"{:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f} {:>10.6f}\n".format(
|
||||||
# chargesAndDipole[0], chargesAndDipole[1], chargesAndDipole[2], chargesAndDipole[3], chargesAndDipole[4]
|
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
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
class Interface(ABC):
|
class Interface(ABC):
|
||||||
__slots__ = [
|
__slots__ = [
|
||||||
'config'
|
'step',
|
||||||
|
'system'
|
||||||
]
|
]
|
||||||
|
|
||||||
@abstractmethod
|
def __init__(self):
|
||||||
def __init__(self, data: dict):
|
self.system: System | None = None
|
||||||
pass
|
self.step: PlayerConfig | None = None
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def set_config(data: dict) -> Dataclass:
|
def configure(self, step: PlayerConfig, system: System):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from diceplayer.shared.config.dice_dto import DiceDTO
|
from diceplayer.shared.config.player_config import PlayerConfig
|
||||||
from diceplayer.shared.config.step_dto import StepDTO
|
from diceplayer.shared.environment.system import System
|
||||||
from diceplayer.shared.interface import Interface
|
from diceplayer.shared.interface import Interface
|
||||||
from diceplayer import logger
|
from diceplayer import logger
|
||||||
|
|
||||||
@@ -26,23 +26,14 @@ MAX_SEED: Final[int] = 4294967295
|
|||||||
class DiceInterface(Interface):
|
class DiceInterface(Interface):
|
||||||
title = "Diceplayer run"
|
title = "Diceplayer run"
|
||||||
|
|
||||||
def __init__(self, data: dict):
|
def configure(self, step: PlayerConfig, system: System):
|
||||||
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):
|
|
||||||
self.step = step
|
self.step = step
|
||||||
|
self.system = system
|
||||||
|
|
||||||
def start(self, cycle: int):
|
def start(self, cycle: int):
|
||||||
procs = []
|
procs = []
|
||||||
sentinels = []
|
sentinels = []
|
||||||
|
|
||||||
logger.info(f"---------------------- DICE - CYCLE {cycle} --------------------------\n")
|
|
||||||
|
|
||||||
for proc in range(1, self.step.nprocs + 1):
|
for proc in range(1, self.step.nprocs + 1):
|
||||||
p = Process(target=self._simulation_process, args=(cycle, proc))
|
p = Process(target=self._simulation_process, args=(cycle, proc))
|
||||||
p.start()
|
p.start()
|
||||||
@@ -66,6 +57,7 @@ class DiceInterface(Interface):
|
|||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
del self.step
|
del self.step
|
||||||
|
del self.system
|
||||||
|
|
||||||
def _simulation_process(self, cycle: int, proc: int):
|
def _simulation_process(self, cycle: int, proc: int):
|
||||||
setproctitle(f"diceplayer-step{cycle:0d}-p{proc:0d}")
|
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
|
# This is logic is used to make the initial configuration file
|
||||||
# for the next cycle using the last.xyz file from the previous cycle.
|
# 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(
|
last_xyz = Path(
|
||||||
self.step.simulation_dir,
|
self.step.simulation_dir,
|
||||||
f"step{(cycle - 1):02d}",
|
f"step{(cycle - 1):02d}",
|
||||||
@@ -115,15 +107,15 @@ class DiceInterface(Interface):
|
|||||||
with open(last_xyz, 'r') as last_xyz_file:
|
with open(last_xyz, 'r') as last_xyz_file:
|
||||||
self._make_init_file(proc_dir, last_xyz_file)
|
self._make_init_file(proc_dir, last_xyz_file)
|
||||||
last_xyz_file.seek(0)
|
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:
|
else:
|
||||||
self._make_nvt_ter(cycle, proc_dir)
|
self._make_nvt_ter(cycle, proc_dir)
|
||||||
|
|
||||||
if len(self.config.nstep) == 2:
|
if len(self.step.dice.nstep) == 2:
|
||||||
self._make_nvt_eq(proc_dir)
|
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_ter(cycle, proc_dir)
|
||||||
self._make_npt_eq(proc_dir)
|
self._make_npt_eq(proc_dir)
|
||||||
|
|
||||||
@@ -142,13 +134,13 @@ class DiceInterface(Interface):
|
|||||||
|
|
||||||
os.chdir(proc_dir)
|
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")
|
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")
|
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.ter")
|
||||||
self.run_dice_file(cycle, proc, "NPT.eq")
|
self.run_dice_file(cycle, proc, "NPT.eq")
|
||||||
|
|
||||||
@@ -175,15 +167,15 @@ class DiceInterface(Interface):
|
|||||||
xyz_lines = last_xyz_file.readlines()
|
xyz_lines = last_xyz_file.readlines()
|
||||||
|
|
||||||
nsites_mm = 0
|
nsites_mm = 0
|
||||||
for i in range(1, len(self.step.nmol)):
|
for i in range(1, len(self.step.dice.nmol)):
|
||||||
nsites_mm += self.step.nmol[i] * len(self.step.molecule[i].atom)
|
nsites_mm += self.step.dice.nmol[i] * len(self.system.molecule[i].atom)
|
||||||
|
|
||||||
xyz_lines = xyz_lines[-nsites_mm:]
|
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:
|
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.write(
|
||||||
f"{atom.rx:>10.6f} {atom.ry:>10.6f} {atom.rz:>10.6f}\n"
|
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])
|
volume = float(box[-3]) * float(box[-2]) * float(box[-1])
|
||||||
|
|
||||||
total_mass = 0
|
total_mass = 0
|
||||||
for i in range(len(self.step.molecule)):
|
for i in range(len(self.system.molecule)):
|
||||||
total_mass += self.step.molecule[i].total_mass * self.step.nmol[i]
|
total_mass += self.system.molecule[i].total_mass * self.step.dice.nmol[i]
|
||||||
|
|
||||||
density = (total_mass / volume) * UMAANG3_TO_GCM3
|
density = (total_mass / volume) * UMAANG3_TO_GCM3
|
||||||
|
|
||||||
@@ -216,21 +208,21 @@ class DiceInterface(Interface):
|
|||||||
with open(file, 'w') as f:
|
with open(file, 'w') as f:
|
||||||
f.write(f"title = {self.title} - NVT Thermalization\n")
|
f.write(f"title = {self.title} - NVT Thermalization\n")
|
||||||
f.write(f"ncores = {self.step.ncores}\n")
|
f.write(f"ncores = {self.step.ncores}\n")
|
||||||
f.write(f"ljname = {self.config.ljname}\n")
|
f.write(f"ljname = {self.step.dice.ljname}\n")
|
||||||
f.write(f"outname = {self.config.outname}\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"nmol = {mol_string}\n")
|
||||||
|
|
||||||
f.write(f"dens = {self.config.dens}\n")
|
f.write(f"dens = {self.step.dice.dens}\n")
|
||||||
f.write(f"temp = {self.config.temp}\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"init = yesreadxyz\n")
|
||||||
f.write(f"nstep = {self.step.altsteps}\n")
|
f.write(f"nstep = {self.step.altsteps}\n")
|
||||||
else:
|
else:
|
||||||
f.write(f"init = yes\n")
|
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("vstep = 0\n")
|
||||||
f.write("mstop = 1\n")
|
f.write("mstop = 1\n")
|
||||||
@@ -241,30 +233,36 @@ class DiceInterface(Interface):
|
|||||||
|
|
||||||
seed = int(1e6 * random.random())
|
seed = int(1e6 * random.random())
|
||||||
f.write(f"seed = {seed}\n")
|
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")
|
file = Path(proc_dir, "NVT.eq")
|
||||||
with open(file, 'w') as f:
|
with open(file, 'w') as f:
|
||||||
f.write(f"title = {self.title} - NVT Production\n")
|
f.write(f"title = {self.title} - NVT Production\n")
|
||||||
f.write(f"ncores = {self.step.ncores}\n")
|
f.write(f"ncores = {self.step.ncores}\n")
|
||||||
f.write(f"ljname = {self.config.ljname}\n")
|
f.write(f"ljname = {self.step.dice.ljname}\n")
|
||||||
f.write(f"outname = {self.config.outname}\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"nmol = {mol_string}\n")
|
||||||
|
|
||||||
f.write(f"dens = {self.config.dens}\n")
|
f.write(f"dens = {self.step.dice.dens}\n")
|
||||||
f.write(f"temp = {self.config.temp}\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("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("vstep = 0\n")
|
||||||
f.write("mstop = 1\n")
|
f.write("mstop = 1\n")
|
||||||
f.write("accum = no\n")
|
f.write("accum = no\n")
|
||||||
f.write("iprint = 1\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")
|
f.write(f"irdf = {10 * self.step.nprocs}\n")
|
||||||
|
|
||||||
seed = int(1e6 * random.random())
|
seed = int(1e6 * random.random())
|
||||||
@@ -276,22 +274,22 @@ class DiceInterface(Interface):
|
|||||||
with open(file, 'w') as f:
|
with open(file, 'w') as f:
|
||||||
f.write(f"title = {self.title} - NPT Thermalization\n")
|
f.write(f"title = {self.title} - NPT Thermalization\n")
|
||||||
f.write(f"ncores = {self.step.ncores}\n")
|
f.write(f"ncores = {self.step.ncores}\n")
|
||||||
f.write(f"ljname = {self.config.ljname}\n")
|
f.write(f"ljname = {self.step.dice.ljname}\n")
|
||||||
f.write(f"outname = {self.config.outname}\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"nmol = {mol_string}\n")
|
||||||
|
|
||||||
f.write(f"press = {self.config.press}\n")
|
f.write(f"press = {self.step.dice.press}\n")
|
||||||
f.write(f"temp = {self.config.temp}\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("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")
|
f.write(f"vstep = {int(self.step.altsteps / 5)}\n")
|
||||||
else:
|
else:
|
||||||
f.write("init = no\n")
|
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("nstep = 5\n")
|
||||||
f.write("mstop = 1\n")
|
f.write("mstop = 1\n")
|
||||||
@@ -308,23 +306,23 @@ class DiceInterface(Interface):
|
|||||||
with open(file, 'w') as f:
|
with open(file, 'w') as f:
|
||||||
f.write(f"title = {self.title} - NPT Production\n")
|
f.write(f"title = {self.title} - NPT Production\n")
|
||||||
f.write(f"ncores = {self.step.ncores}\n")
|
f.write(f"ncores = {self.step.ncores}\n")
|
||||||
f.write(f"ljname = {self.config.ljname}\n")
|
f.write(f"ljname = {self.step.dice.ljname}\n")
|
||||||
f.write(f"outname = {self.config.outname}\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"nmol = {mol_string}\n")
|
||||||
|
|
||||||
f.write(f"press = {self.config.press}\n")
|
f.write(f"press = {self.step.dice.press}\n")
|
||||||
f.write(f"temp = {self.config.temp}\n")
|
f.write(f"temp = {self.step.dice.temp}\n")
|
||||||
|
|
||||||
f.write(f"nstep = 5\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("init = no\n")
|
||||||
f.write("mstop = 1\n")
|
f.write("mstop = 1\n")
|
||||||
f.write("accum = no\n")
|
f.write("accum = no\n")
|
||||||
f.write("iprint = 1\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")
|
f.write(f"irdf = {10 * self.step.nprocs}\n")
|
||||||
|
|
||||||
seed = int(1e6 * random.random())
|
seed = int(1e6 * random.random())
|
||||||
@@ -333,15 +331,15 @@ class DiceInterface(Interface):
|
|||||||
def _make_potentials(self, proc_dir):
|
def _make_potentials(self, proc_dir):
|
||||||
fstr = "{:<3d} {:>3d} {:>10.5f} {:>10.5f} {:>10.5f} {:>10.6f} {:>9.5f} {:>7.4f}\n"
|
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:
|
with open(file, 'w') as f:
|
||||||
f.write(f"{self.config.combrule}\n")
|
f.write(f"{self.step.dice.combrule}\n")
|
||||||
f.write(f"{len(self.step.nmol)}\n")
|
f.write(f"{len(self.step.dice.nmol)}\n")
|
||||||
|
|
||||||
nsites_qm = len(self.step.molecule[0].atom)
|
nsites_qm = len(self.system.molecule[0].atom)
|
||||||
f.write(f"{nsites_qm} {self.step.molecule[0].molname}\n")
|
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(
|
f.write(
|
||||||
fstr.format(
|
fstr.format(
|
||||||
atom.lbl,
|
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")
|
f.write(f"{len(mol.atom)} {mol.molname}\n")
|
||||||
for atom in mol.atom:
|
for atom in mol.atom:
|
||||||
f.write(
|
f.write(
|
||||||
@@ -378,12 +376,12 @@ class DiceInterface(Interface):
|
|||||||
[
|
[
|
||||||
"bash",
|
"bash",
|
||||||
"-c",
|
"-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:
|
else:
|
||||||
exit_status = subprocess.call(
|
exit_status = subprocess.call(
|
||||||
self.config.progname, stdin=infile, stdout=outfile
|
self.step.dice.progname, stdin=infile, stdout=outfile
|
||||||
)
|
)
|
||||||
|
|
||||||
if exit_status != 0:
|
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.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):
|
class GaussianInterface(Interface):
|
||||||
|
def configure(self, step_dto: PlayerConfig, system: System):
|
||||||
|
self.system = system
|
||||||
|
self.step = step_dto
|
||||||
|
|
||||||
def __init__(self, data: dict):
|
def start(self, cycle: int) -> Dict[str, NDArray]:
|
||||||
self.config: GaussianDTO = self.set_config(data)
|
self._make_qm_dir(cycle)
|
||||||
|
|
||||||
@staticmethod
|
if cycle > 1:
|
||||||
def set_config(data: dict) -> GaussianDTO:
|
self._copy_chk_file_from_previous_step(cycle)
|
||||||
return GaussianDTO.from_dict(data)
|
|
||||||
|
|
||||||
def configure(self):
|
asec_charges = self.populate_asec_vdw(cycle)
|
||||||
pass
|
self._make_gaussian_input_file(
|
||||||
|
cycle,
|
||||||
|
asec_charges
|
||||||
|
)
|
||||||
|
|
||||||
def start(self, cycle: int):
|
self._run_gaussian(cycle)
|
||||||
pass
|
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):
|
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
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
class TestDiceDto(unittest.TestCase):
|
class TestDiceDto(unittest.TestCase):
|
||||||
def test_class_instantiation(self):
|
def test_class_instantiation(self):
|
||||||
dice_dto = DiceDTO(
|
dice_dto = DiceConfig(
|
||||||
ljname='test',
|
ljname='test',
|
||||||
outname='test',
|
outname='test',
|
||||||
dens=1.0,
|
dens=1.0,
|
||||||
@@ -13,11 +13,11 @@ class TestDiceDto(unittest.TestCase):
|
|||||||
nstep=[1, 1],
|
nstep=[1, 1],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertIsInstance(dice_dto, DiceDTO)
|
self.assertIsInstance(dice_dto, DiceConfig)
|
||||||
|
|
||||||
def test_validate_jname(self):
|
def test_validate_jname(self):
|
||||||
with self.assertRaises(ValueError) as ex:
|
with self.assertRaises(ValueError) as ex:
|
||||||
DiceDTO(
|
DiceConfig(
|
||||||
ljname=None,
|
ljname=None,
|
||||||
outname='test',
|
outname='test',
|
||||||
dens=1.0,
|
dens=1.0,
|
||||||
@@ -28,7 +28,7 @@ class TestDiceDto(unittest.TestCase):
|
|||||||
|
|
||||||
def test_validate_outname(self):
|
def test_validate_outname(self):
|
||||||
with self.assertRaises(ValueError) as ex:
|
with self.assertRaises(ValueError) as ex:
|
||||||
DiceDTO(
|
DiceConfig(
|
||||||
ljname='test',
|
ljname='test',
|
||||||
outname=None,
|
outname=None,
|
||||||
dens=1.0,
|
dens=1.0,
|
||||||
@@ -39,7 +39,7 @@ class TestDiceDto(unittest.TestCase):
|
|||||||
|
|
||||||
def test_validate_dens(self):
|
def test_validate_dens(self):
|
||||||
with self.assertRaises(ValueError) as ex:
|
with self.assertRaises(ValueError) as ex:
|
||||||
DiceDTO(
|
DiceConfig(
|
||||||
ljname='test',
|
ljname='test',
|
||||||
outname='test',
|
outname='test',
|
||||||
dens=None,
|
dens=None,
|
||||||
@@ -50,7 +50,7 @@ class TestDiceDto(unittest.TestCase):
|
|||||||
|
|
||||||
def test_validate_nmol(self):
|
def test_validate_nmol(self):
|
||||||
with self.assertRaises(ValueError) as ex:
|
with self.assertRaises(ValueError) as ex:
|
||||||
DiceDTO(
|
DiceConfig(
|
||||||
ljname='test',
|
ljname='test',
|
||||||
outname='test',
|
outname='test',
|
||||||
dens=1.0,
|
dens=1.0,
|
||||||
@@ -61,7 +61,7 @@ class TestDiceDto(unittest.TestCase):
|
|||||||
|
|
||||||
def test_validate_nstep(self):
|
def test_validate_nstep(self):
|
||||||
with self.assertRaises(ValueError) as ex:
|
with self.assertRaises(ValueError) as ex:
|
||||||
DiceDTO(
|
DiceConfig(
|
||||||
ljname='test',
|
ljname='test',
|
||||||
outname='test',
|
outname='test',
|
||||||
dens=1.0,
|
dens=1.0,
|
||||||
@@ -71,7 +71,7 @@ class TestDiceDto(unittest.TestCase):
|
|||||||
self.assertEqual(ex.exception, "Error: 'nstep' keyword not defined appropriately in config file")
|
self.assertEqual(ex.exception, "Error: 'nstep' keyword not defined appropriately in config file")
|
||||||
|
|
||||||
def test_from_dict(self):
|
def test_from_dict(self):
|
||||||
dice_dto = DiceDTO.from_dict({
|
dice_dto = DiceConfig.from_dict({
|
||||||
'ljname': 'test',
|
'ljname': 'test',
|
||||||
'outname': 'test',
|
'outname': 'test',
|
||||||
'dens': 1.0,
|
'dens': 1.0,
|
||||||
@@ -79,4 +79,4 @@ class TestDiceDto(unittest.TestCase):
|
|||||||
'nstep': [1, 1],
|
'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
|
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
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
class TestPlayerDTO(unittest.TestCase):
|
def get_config_dict():
|
||||||
def test_class_instantiation(self):
|
return {
|
||||||
player_dto = PlayerDTO(opt=True, maxcyc=100, nprocs=4, ncores=4)
|
'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):
|
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)
|
self.assertEqual(player_dto.altsteps, 20000)
|
||||||
|
|
||||||
def test_from_dict(self):
|
def test_from_dict(self):
|
||||||
player_dto = PlayerDTO.from_dict({
|
player_dto = PlayerConfig.from_dict(
|
||||||
'opt': True,
|
get_config_dict()
|
||||||
'maxcyc': 100,
|
)
|
||||||
'nprocs': 4,
|
|
||||||
'ncores': 4,
|
|
||||||
})
|
|
||||||
|
|
||||||
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__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -13,18 +13,14 @@ class TestSystem(unittest.TestCase):
|
|||||||
|
|
||||||
def test_add_type(self):
|
def test_add_type(self):
|
||||||
system = System()
|
system = System()
|
||||||
system.add_type(0, Molecule('test'))
|
system.add_type(Molecule('test'))
|
||||||
|
|
||||||
self.assertIsInstance(system.molecule, list)
|
self.assertIsInstance(system.molecule, list)
|
||||||
self.assertIsInstance(system.nmols, list)
|
|
||||||
|
|
||||||
with self.assertRaises(TypeError) as ex:
|
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')
|
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__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
from diceplayer.shared.interface.dice_interface import DiceInterface
|
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.molecule import Molecule
|
||||||
|
from diceplayer.shared.environment.system import System
|
||||||
from diceplayer.shared.environment.atom import Atom
|
from diceplayer.shared.environment.atom import Atom
|
||||||
from diceplayer.shared.config.step_dto import StepDTO
|
|
||||||
from diceplayer import logger
|
from diceplayer import logger
|
||||||
|
|
||||||
|
import yaml
|
||||||
import io
|
import io
|
||||||
|
|
||||||
|
from tests.mocks.mock_inputs import get_config_example
|
||||||
from tests.mocks.mock_proc import MockConnection, MockProc
|
from tests.mocks.mock_proc import MockConnection, MockProc
|
||||||
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
@@ -16,122 +19,58 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
logger.set_logger(stream=io.StringIO())
|
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):
|
def test_class_instantiation(self):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
|
||||||
'dens': 1.0,
|
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertIsInstance(dice, DiceInterface)
|
self.assertIsInstance(dice, DiceInterface)
|
||||||
|
|
||||||
def test_configure(self):
|
def test_configure(self):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
|
||||||
'dens': 1.0,
|
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertIsNone(dice.step)
|
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.step)
|
||||||
|
self.assertIsNotNone(dice.system)
|
||||||
|
|
||||||
def test_reset(self):
|
def test_reset(self):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
|
||||||
'dens': 1.0,
|
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
dice.configure('test')
|
dice.configure(self.config, System())
|
||||||
|
|
||||||
self.assertTrue(hasattr(dice, 'step'))
|
self.assertTrue(hasattr(dice, 'step'))
|
||||||
|
self.assertTrue(hasattr(dice, 'system'))
|
||||||
|
|
||||||
dice.reset()
|
dice.reset()
|
||||||
|
|
||||||
self.assertFalse(hasattr(dice, 'step'))
|
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.Process', MockProc())
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.connection', MockConnection)
|
@mock.patch('diceplayer.shared.interface.dice_interface.connection', MockConnection)
|
||||||
def test_start(self):
|
def test_start(self):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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.start(1)
|
dice.start(1)
|
||||||
|
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.connection', MockConnection)
|
@mock.patch('diceplayer.shared.interface.dice_interface.connection', MockConnection)
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.Process', MockProc(exitcode=1))
|
@mock.patch('diceplayer.shared.interface.dice_interface.Process', MockProc(exitcode=1))
|
||||||
def test_start_with_process_error(self):
|
def test_start_with_process_error(self):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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=[],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
with self.assertRaises(SystemExit):
|
with self.assertRaises(SystemExit):
|
||||||
dice.start(1)
|
dice.start(1)
|
||||||
|
|
||||||
def test_simulation_process_raises_exception(self):
|
def test_simulation_process_raises_exception(self):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
|
||||||
'dens': 1.0,
|
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
with self.assertRaises(SystemExit):
|
with self.assertRaises(SystemExit):
|
||||||
dice._simulation_process(1, 1)
|
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._make_dice_inputs')
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.DiceInterface._run_dice')
|
@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):
|
def test_simulation_process(self, mock_run_dice, mock_make_dice_inputs, mock_make_proc_dir):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
|
||||||
'dens': 1.0,
|
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
dice._simulation_process(1, 1)
|
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.mkdir')
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists')
|
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists')
|
||||||
def test_make_proc_dir_if_simdir_exists(self, mock_path_exists, mock_path_mkdir):
|
def test_make_proc_dir_if_simdir_exists(self, mock_path_exists, mock_path_mkdir):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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=[],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
mock_path_exists.return_value = False
|
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.mkdir')
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists')
|
@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):
|
def test_make_proc_dir_if_simdir_doesnt_exists(self, mock_path_exists, mock_path_mkdir):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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=[],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
mock_path_exists.return_value = False
|
mock_path_exists.return_value = False
|
||||||
|
|
||||||
@@ -218,42 +112,15 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
self.assertEqual(mock_path_mkdir.call_count, 2)
|
self.assertEqual(mock_path_mkdir.call_count, 2)
|
||||||
|
|
||||||
def test_make_dice_seed(self):
|
def test_make_dice_seed(self):
|
||||||
dice = DiceInterface(
|
seed = DiceInterface._make_dice_seed()
|
||||||
{
|
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
|
||||||
'dens': 1.0,
|
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
seed = dice._make_dice_seed()
|
|
||||||
|
|
||||||
self.assertIsInstance(seed, int)
|
self.assertIsInstance(seed, int)
|
||||||
|
|
||||||
def test_make_dice_inputs_nstep_len_two_with_randoninit_first_cycle_one(self):
|
def test_make_dice_inputs_nstep_len_two_with_randoninit_first_cycle_one(self):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
dice.step.dice.nstep = [1, 1]
|
||||||
'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._make_potentials = mock.Mock()
|
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('builtins.open', new_callable=mock.mock_open, read_data='test')
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=True)
|
@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):
|
def test_make_dice_inputs_nstep_len_two_with_randoninit_first_cycle_two(self, mock_path_exists, mock_open):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
dice.step.dice.nstep = [1, 1]
|
||||||
'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._make_potentials = mock.Mock()
|
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)
|
@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):
|
def test_make_dice_inputs_raises_exception_on_last_not_found(self, mock_path_exists):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
dice.step.dice.nstep = [1, 1]
|
||||||
'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._make_potentials = mock.Mock()
|
dice._make_potentials = mock.Mock()
|
||||||
|
|
||||||
@@ -362,26 +197,8 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
dice._make_dice_inputs(2, 1)
|
dice._make_dice_inputs(2, 1)
|
||||||
|
|
||||||
def test_make_dice_inputs_nstep_len_three_with_randoninit_first_cycle_one(self):
|
def test_make_dice_inputs_nstep_len_three_with_randoninit_first_cycle_one(self):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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._make_potentials = mock.Mock()
|
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.shutil')
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=True)
|
@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):
|
def test_run_dice_on_first_cycle_run_successful(self, mock_path_exists, mock_shutils, mock_os):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
dice.step.dice.nstep = [1, 1, 1]
|
||||||
'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.run_dice_file = mock.Mock()
|
dice.run_dice_file = mock.Mock()
|
||||||
|
|
||||||
@@ -441,26 +242,10 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
self.assertEqual(dice.run_dice_file.call_count, 3)
|
self.assertEqual(dice.run_dice_file.call_count, 3)
|
||||||
self.assertTrue(mock_shutils.copy.called)
|
self.assertTrue(mock_shutils.copy.called)
|
||||||
|
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
dice.step.dice.nstep = [1, 1]
|
||||||
'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.run_dice_file = mock.Mock()
|
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.shutil')
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=True)
|
@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):
|
def test_run_dice_on_second_cycle_run_successful(self, mock_path_exists, mock_shutils, mock_os):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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.run_dice_file = mock.Mock()
|
dice.run_dice_file = mock.Mock()
|
||||||
|
|
||||||
@@ -507,26 +274,8 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
self.assertEqual(dice.run_dice_file.call_count, 2)
|
self.assertEqual(dice.run_dice_file.call_count, 2)
|
||||||
self.assertTrue(mock_shutils.copy.called)
|
self.assertTrue(mock_shutils.copy.called)
|
||||||
|
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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.run_dice_file = mock.Mock()
|
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.shutil')
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.Path.exists', return_value=False)
|
@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):
|
def test_run_dice_on_second_cycle_run_successful(self, mock_path_exists, mock_shutils, mock_os):
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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.run_dice_file = mock.Mock()
|
dice.run_dice_file = mock.Mock()
|
||||||
|
|
||||||
@@ -587,32 +318,14 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
secondary_molecule = Molecule('secondary_molecule')
|
secondary_molecule = Molecule('secondary_molecule')
|
||||||
secondary_molecule.add_atom(example_atom)
|
secondary_molecule.add_atom(example_atom)
|
||||||
|
|
||||||
dice = DiceInterface(
|
system = System()
|
||||||
{
|
system.add_type(main_molecule)
|
||||||
'ljname': 'test',
|
system.add_type(secondary_molecule)
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
dice = DiceInterface()
|
||||||
'dens': 1.0,
|
dice.configure(self.config, system)
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
dice.step.dice.nmol = [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),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
last_xyz_file = io.StringIO()
|
last_xyz_file = io.StringIO()
|
||||||
last_xyz_file.writelines([
|
last_xyz_file.writelines([
|
||||||
@@ -657,32 +370,12 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
secondary_molecule = Molecule('secondary_molecule')
|
secondary_molecule = Molecule('secondary_molecule')
|
||||||
secondary_molecule.add_atom(example_atom)
|
secondary_molecule.add_atom(example_atom)
|
||||||
|
|
||||||
dice = DiceInterface(
|
system = System()
|
||||||
{
|
system.add_type(main_molecule)
|
||||||
'ljname': 'test',
|
system.add_type(secondary_molecule)
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
dice = DiceInterface()
|
||||||
'dens': 1.0,
|
dice.configure(self.config, system)
|
||||||
'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),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
last_xyz_file = io.StringIO()
|
last_xyz_file = io.StringIO()
|
||||||
last_xyz_file.writelines([
|
last_xyz_file.writelines([
|
||||||
@@ -695,33 +388,15 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
|
|
||||||
density = dice._new_density(last_xyz_file)
|
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('builtins.open', new_callable=mock.mock_open)
|
||||||
@mock.patch('diceplayer.shared.interface.dice_interface.random')
|
@mock.patch('diceplayer.shared.interface.dice_interface.random')
|
||||||
def test_make_nvt_ter(self, mock_random, mock_open):
|
def test_make_nvt_ter(self, mock_random, mock_open):
|
||||||
mock_random.random.return_value = 1
|
mock_random.random.return_value = 1
|
||||||
|
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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._make_nvt_ter(1, 'test')
|
dice._make_nvt_ter(1, 'test')
|
||||||
|
|
||||||
@@ -730,7 +405,7 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
|
|
||||||
lines = list(map(lambda x: x[0][0], calls))
|
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)
|
self.assertEqual(lines, expected_lines)
|
||||||
|
|
||||||
@@ -739,26 +414,8 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
def test_make_nvt_eq(self, mock_random, mock_open):
|
def test_make_nvt_eq(self, mock_random, mock_open):
|
||||||
mock_random.random.return_value = 1
|
mock_random.random.return_value = 1
|
||||||
|
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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._make_nvt_eq('test')
|
dice._make_nvt_eq('test')
|
||||||
|
|
||||||
@@ -767,7 +424,7 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
|
|
||||||
lines = list(map(lambda x: x[0][0], calls))
|
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)
|
self.assertEqual(lines, expected_lines)
|
||||||
|
|
||||||
@@ -776,26 +433,8 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
def test_make_npt_ter(self, mock_random, mock_open):
|
def test_make_npt_ter(self, mock_random, mock_open):
|
||||||
mock_random.random.return_value = 1
|
mock_random.random.return_value = 1
|
||||||
|
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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._make_npt_ter(1, 'test')
|
dice._make_npt_ter(1, 'test')
|
||||||
|
|
||||||
@@ -804,7 +443,7 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
|
|
||||||
lines = list(map(lambda x: x[0][0], calls))
|
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)
|
self.assertEqual(lines, expected_lines)
|
||||||
|
|
||||||
@@ -813,26 +452,8 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
def test_make_npt_eq(self, mock_random, mock_open):
|
def test_make_npt_eq(self, mock_random, mock_open):
|
||||||
mock_random.random.return_value = 1
|
mock_random.random.return_value = 1
|
||||||
|
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'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._make_npt_eq('test')
|
dice._make_npt_eq('test')
|
||||||
|
|
||||||
@@ -841,7 +462,7 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
|
|
||||||
lines = list(map(lambda x: x[0][0], calls))
|
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)
|
self.assertEqual(lines, expected_lines)
|
||||||
|
|
||||||
@@ -864,32 +485,12 @@ class TestDiceInterface(unittest.TestCase):
|
|||||||
secondary_molecule = Molecule('secondary_molecule')
|
secondary_molecule = Molecule('secondary_molecule')
|
||||||
secondary_molecule.add_atom(example_atom)
|
secondary_molecule.add_atom(example_atom)
|
||||||
|
|
||||||
dice = DiceInterface(
|
system = System()
|
||||||
{
|
system.add_type(main_molecule)
|
||||||
'ljname': 'test',
|
system.add_type(secondary_molecule)
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
dice = DiceInterface()
|
||||||
'dens': 1.0,
|
dice.configure(self.config, system)
|
||||||
'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),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
dice._make_potentials('test')
|
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')
|
@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):
|
def test_run_dice_file(self, mock_open, mock_subprocess):
|
||||||
mock_subprocess.call.return_value = 0
|
mock_subprocess.call.return_value = 0
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
|
||||||
'dens': 1.0,
|
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
dice.run_dice_file(1, 1, 'test')
|
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')
|
@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):
|
def test_run_dice_file_raises_runtime_error_on_dice_file(self, mock_open, mock_subprocess):
|
||||||
mock_subprocess.call.return_value = 0
|
mock_subprocess.call.return_value = 0
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
|
||||||
'dens': 1.0,
|
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
dice.run_dice_file(1, 1, 'test')
|
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')
|
@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):
|
def test_run_dice_file_raises_runtime_error_of_dice_exit_code(self, mock_open, mock_subprocess):
|
||||||
mock_subprocess.call.return_value = 1
|
mock_subprocess.call.return_value = 1
|
||||||
dice = DiceInterface(
|
dice = DiceInterface()
|
||||||
{
|
dice.configure(self.config, System())
|
||||||
'ljname': 'test',
|
|
||||||
'outname': 'test',
|
|
||||||
'ncores': 1,
|
|
||||||
'dens': 1.0,
|
|
||||||
'nmol': [1],
|
|
||||||
'nstep': [1, 1],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
dice.run_dice_file(1, 1, 'test')
|
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
|
import io
|
||||||
|
|
||||||
|
from tests.mocks.mock_inputs import mock_open
|
||||||
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
import unittest
|
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):
|
class TestPlayer(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
logger.set_logger(stream=io.StringIO())
|
logger.set_logger(stream=io.StringIO())
|
||||||
@@ -131,19 +24,13 @@ class TestPlayer(unittest.TestCase):
|
|||||||
def test_start(self):
|
def test_start(self):
|
||||||
player = Player("control.test.yml")
|
player = Player("control.test.yml")
|
||||||
|
|
||||||
player.print_keywords = mock.MagicMock()
|
player.gaussian_start = mock.MagicMock()
|
||||||
player.create_simulation_dir = mock.MagicMock()
|
|
||||||
player.read_potentials = mock.MagicMock()
|
|
||||||
player.print_potentials = mock.MagicMock()
|
|
||||||
player.dice_start = mock.MagicMock()
|
player.dice_start = mock.MagicMock()
|
||||||
|
|
||||||
player.start(1)
|
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.dice_start.call_count, 3)
|
||||||
|
self.assertEqual(player.gaussian_start.call_count, 3)
|
||||||
|
|
||||||
@mock.patch("builtins.open", mock_open)
|
@mock.patch("builtins.open", mock_open)
|
||||||
@mock.patch("diceplayer.player.Path")
|
@mock.patch("diceplayer.player.Path")
|
||||||
@@ -178,7 +65,22 @@ class TestPlayer(unittest.TestCase):
|
|||||||
with self.assertLogs() as cm:
|
with self.assertLogs() as cm:
|
||||||
player.print_keywords()
|
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)
|
self.assertEqual(cm.output, expected_output)
|
||||||
|
|
||||||
@@ -333,7 +235,7 @@ class TestPlayer(unittest.TestCase):
|
|||||||
|
|
||||||
# Testing combrule error
|
# Testing combrule error
|
||||||
with self.assertRaises(SystemExit) as context:
|
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()
|
player.read_potentials()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -343,7 +245,7 @@ class TestPlayer(unittest.TestCase):
|
|||||||
|
|
||||||
# Testing ntypes error
|
# Testing ntypes error
|
||||||
with self.assertRaises(SystemExit) as context:
|
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()
|
player.read_potentials()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -353,7 +255,7 @@ class TestPlayer(unittest.TestCase):
|
|||||||
|
|
||||||
# Testing ntypes error on config
|
# Testing ntypes error on config
|
||||||
with self.assertRaises(SystemExit) as context:
|
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()
|
player.read_potentials()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -364,7 +266,7 @@ class TestPlayer(unittest.TestCase):
|
|||||||
|
|
||||||
# Testing nsite error
|
# Testing nsite error
|
||||||
with self.assertRaises(ValueError) as context:
|
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()
|
player.read_potentials()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -374,7 +276,7 @@ class TestPlayer(unittest.TestCase):
|
|||||||
|
|
||||||
# Testing molname error
|
# Testing molname error
|
||||||
with self.assertRaises(ValueError) as context:
|
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()
|
player.read_potentials()
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@@ -391,7 +293,23 @@ class TestPlayer(unittest.TestCase):
|
|||||||
with self.assertLogs(level='INFO') as context:
|
with self.assertLogs(level='INFO') as context:
|
||||||
player.print_potentials()
|
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(
|
self.assertEqual(
|
||||||
context.output,
|
context.output,
|
||||||
@@ -401,23 +319,22 @@ class TestPlayer(unittest.TestCase):
|
|||||||
@mock.patch("builtins.open", mock_open)
|
@mock.patch("builtins.open", mock_open)
|
||||||
def test_dice_start(self):
|
def test_dice_start(self):
|
||||||
player = Player("control.test.yml")
|
player = Player("control.test.yml")
|
||||||
player.dice = mock.MagicMock()
|
player.dice_interface = mock.MagicMock()
|
||||||
player.dice.start = mock.MagicMock()
|
player.dice_interface.start = mock.MagicMock()
|
||||||
|
|
||||||
player.dice_start(1)
|
player.dice_start(1)
|
||||||
|
|
||||||
player.dice.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 = mock.MagicMock()
|
|
||||||
player.gaussian.start = mock.MagicMock()
|
|
||||||
|
|
||||||
player.gaussian_start(1)
|
|
||||||
|
|
||||||
player.gaussian.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__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Reference in New Issue
Block a user