Fixes Player Class Implementation

This commit is contained in:
2022-06-01 20:03:58 -03:00
parent 44cb4268ef
commit e54b3e55fa
10 changed files with 94 additions and 145 deletions

View File

@@ -1,3 +0,0 @@
{
"python.pythonPath": "/home/hideyoshi/Python/3.8/bin/python3.8"
}

View File

@@ -11,12 +11,13 @@ dice:
ncores: 3 ncores: 3
nmol: [1, 50] nmol: [1, 50]
dens: 0.75 dens: 0.75
nstep: [4000, 6000] nstep: [2000, 3000]
isave: 1000 isave: 1000
ljname: 'phb.ljc' ljname: 'phb.ljc'
outname: 'phb' outname: 'phb'
randominit: 'first' randominit: 'always'
gaussian: gaussian:
qmprog: 'g16'
level: 'MP2/aug-cc-pVDZ' level: 'MP2/aug-cc-pVDZ'
keywords: 'freq=intmodes' keywords: 'freq'

View File

@@ -31,7 +31,7 @@ class Molecule:
energy (NDArray[Any, Any]): The energy of the represented molecule energy (NDArray[Any, Any]): The energy of the represented molecule
gradient (NDArray[Any, Any]): The first derivative of the energy relative to the position gradient (NDArray[Any, Any]): The first derivative of the energy relative to the position
hessian (NDArray[Any, Any]): The second derivative of the energy relative to the position hessian (NDArray[Any, Any]): The second derivative of the energy relative to the position
totalMass (int): The total mass of the molecule total_mass (int): The total mass of the molecule
com (NDArray[Any, Any]): The center of mass of the molecule com (NDArray[Any, Any]): The center of mass of the molecule
""" """
@@ -50,7 +50,10 @@ class Molecule:
self.gradient: NDArray[Any, Any] self.gradient: NDArray[Any, Any]
self.hessian: NDArray[Any, Any] self.hessian: NDArray[Any, Any]
self.totalMass: int = 0 self.ghost_atoms: List[Atom] = []
self.lp_atoms: List[Atom] = []
self.total_mass: int = 0
self.com: NDArray[Any, Any] = None self.com: NDArray[Any, Any] = None
def add_atom(self, a: Atom) -> None: def add_atom(self, a: Atom) -> None:

View File

@@ -27,7 +27,6 @@ class Dice:
nprocs: int = None nprocs: int = None
randominit = "first" randominit = "first"
combrule = "*" combrule = "*"
ncores = 1
temp = 300.0 temp = 300.0
press = 1.0 press = 1.0
@@ -35,8 +34,8 @@ class Dice:
dens = None dens = None
ljname = None ljname = None
outname = None outname = None
nmol: List[int] = [] nmol: List[int] = None
nstep: List[int] = [] nstep: List[int] = None
upbuf = 360 upbuf = 360
def __init__(self, infile: TextIO, outfile: TextIO) -> None: def __init__(self, infile: TextIO, outfile: TextIO) -> None:
@@ -46,7 +45,7 @@ class Dice:
@NotNull(requiredArgs=["ncores", "nmol", "dens", "nstep", "ljname", "outname"]) @NotNull(requiredArgs=["ncores", "nmol", "dens", "nstep", "ljname", "outname"])
def updateKeywords(self, **data): def updateKeywords(self, **data):
self.__dict__.update(data) self.__dict__.update(**data)
def __new_density(self, cycle: int, proc: int) -> float: def __new_density(self, cycle: int, proc: int) -> float:

View File

@@ -17,21 +17,18 @@ from diceplayer.DPpack.Utils.Validations import NotNull
class Gaussian: class Gaussian:
qmprog = "g09"
mem = None mem = None
keywords = None
chgmult = [0, 1] chgmult = [0, 1]
gmiddle = None # In each case, if a filename is given, its content will be gmiddle = None # In each case, if a filename is given, its content will be
gbottom = None # inserted in the gaussian input gbottom = None # inserted in the gaussian input
pop = "chelpg" pop = "chelpg"
level = None
def __init__(self) -> None: def __init__(self) -> None:
pass pass
@NotNull(requiredArgs=["level"]) @NotNull(requiredArgs=["qmprog","level"])
def updateKeywords(self, **data): def updateKeywords(self, **data):
self.__dict__.update(data) self.__dict__.update(**data)
def run_formchk(self, cycle: int, fh: TextIO): def run_formchk(self, cycle: int, fh: TextIO):

View File

@@ -21,22 +21,32 @@ env = ["OMP_STACKSIZE"]
class Player: class Player:
maxcyc = None
opt = None
nprocs = None
qmprog = None
lps = None
ghosts = None
altsteps = None
combrule = None
TOL_RMS_FORCE = 3e-4
TOL_MAX_FORCE = 4.5e-4
TOL_RMS_STEP = 1.2e-3
TOL_MAX_SET = 1.8e-3
TRUST_RADIUS = None
continued: bool = False
def __init__(self, infile: TextIO, outfile: TextIO) -> None: def __init__(self, infile: TextIO, outfile: TextIO) -> None:
self.infile = infile self.infile = infile
self.outfile = outfile self.outfile = outfile
self.continued: bool = None
self.system = System() self.system = System()
self.player = self.Player()
self.player_keywords = [
a
for a in dir(self.player)
if not a.startswith("__") and not callable(getattr(self.player, a))
]
self.dice = Dice(infile, outfile) self.dice = Dice(infile, outfile)
self.dice_keywords = [ self.dice_keywords = [
a a
@@ -51,28 +61,20 @@ class Player:
if not a.startswith("__") and not callable(getattr(self.gaussian, a)) if not a.startswith("__") and not callable(getattr(self.gaussian, a))
] ]
self.TOL_RMS_FORCE = 3e-4
self.TOL_MAX_FORCE = 4.5e-4
self.TOL_RMS_STEP = 1.2e-3
self.TOL_MAX_SET = 1.8e-3
self.TRUST_RADIUS = None
self.combrule = None
@NotNull( @NotNull(
requiredArgs=["maxcyc", "opt", "nprocs", "qmprog", "lps", "ghosts", "altsteps"] requiredArgs=["maxcyc", "opt", "nprocs", "qmprog", "lps", "ghosts", "altsteps"]
) )
def updateKeywords(self, **data): def updateKeywords(self, **data):
self.__dict__.update(data) self.__dict__.update(**data)
def read_keywords(self) -> None: def read_keywords(self) -> None:
with self.infile as f: with self.infile as f:
data = yaml.load(f, Loader=yaml.SafeLoader) data = yaml.load(f, Loader=yaml.SafeLoader)
self.updateKeywords(data.get("diceplayer")) self.updateKeywords(**data.get("diceplayer"))
self.dice.updateKeywords(data.get("dice")) self.dice.updateKeywords(**data.get("dice"))
self.gaussian.updateKeywords(data.get("gaussian")) self.gaussian.updateKeywords(**data.get("gaussian"))
def check_keywords(self) -> None: def check_keywords(self) -> None:
@@ -108,7 +110,7 @@ class Player:
) )
# Check only if QM program is Gaussian: # Check only if QM program is Gaussian:
if self.player.qmprog in ("g03", "g09", "g16"): if self.qmprog in ("g03", "g09", "g16"):
if self.gaussian.level == None: if self.gaussian.level == None:
sys.exit( sys.exit(
@@ -126,14 +128,14 @@ class Player:
sys.exit("Error: file {} not found".format(self.gaussian.gbottom)) sys.exit("Error: file {} not found".format(self.gaussian.gbottom))
if self.gaussian.pop != "chelpg" and ( if self.gaussian.pop != "chelpg" and (
self.player.ghosts == "yes" or self.player.lps == "yes" self.ghosts == "yes" or self.lps == "yes"
): ):
sys.exit( sys.exit(
"Error: ghost atoms or lone pairs only available with 'pop = chelpg')" "Error: ghost atoms or lone pairs only available with 'pop = chelpg')"
) )
# Check only if QM program is Molcas: # Check only if QM program is Molcas:
# if self.player.qmprog == "molcas": # if self.qmprog == "molcas":
# if self.molcas.mbottom == None: # if self.molcas.mbottom == None:
# sys.exit("Error: 'mbottom' keyword not specified in file {}".format(self.infile)) # sys.exit("Error: 'mbottom' keyword not specified in file {}".format(self.infile))
@@ -144,7 +146,7 @@ class Player:
# if self.molcas.basis == None: # if self.molcas.basis == None:
# sys.exit("Error: 'basis' keyword not specified in file {}".format(self.infile)) # sys.exit("Error: 'basis' keyword not specified in file {}".format(self.infile))
if self.player.altsteps != 0: if self.altsteps != 0:
# Verifica se tem mais de 1 molecula QM # Verifica se tem mais de 1 molecula QM
# (No futuro usar o RMSD fit para poder substituir todas as moleculas QM # (No futuro usar o RMSD fit para poder substituir todas as moleculas QM
@@ -155,9 +157,9 @@ class Player:
) )
# if not zero, altsteps cannot be less than min_steps # if not zero, altsteps cannot be less than min_steps
self.player.altsteps = max(min_steps, self.player.altsteps) self.altsteps = max(min_steps, self.altsteps)
# altsteps value is always the nearest multiple of 1000 # altsteps value is always the nearest multiple of 1000
self.player.altsteps = round(self.player.altsteps / 1000) * 1000 self.altsteps = round(self.altsteps / 1000) * 1000
for i in range(len(self.dice.nstep)): for i in range(len(self.dice.nstep)):
# nstep can never be less than min_steps # nstep can never be less than min_steps
@@ -198,16 +200,6 @@ class Player:
"\n" "\n"
) )
for key in sorted(self.player_keywords):
if getattr(self.player, key) != None:
if isinstance(getattr(self.player, key), list):
string = " ".join(str(x) for x in getattr(self.player, key))
self.outfile.write("{} = {}\n".format(key, string))
else:
self.outfile.write(
"{} = {}\n".format(key, getattr(self.player, key))
)
self.outfile.write("\n") self.outfile.write("\n")
self.outfile.write( self.outfile.write(
@@ -227,7 +219,7 @@ class Player:
self.outfile.write("\n") self.outfile.write("\n")
if self.player.qmprog in ("g03", "g09", "g16"): if self.qmprog in ("g03", "g09", "g16"):
self.outfile.write( self.outfile.write(
"------------------------------------------------------------------------------------------\n" "------------------------------------------------------------------------------------------\n"
@@ -248,7 +240,7 @@ class Player:
self.outfile.write("\n") self.outfile.write("\n")
# elif self.player.qmprog == "molcas": # elif self.qmprog == "molcas":
# self.outfile.write("------------------------------------------------------------------------------------------\n" # self.outfile.write("------------------------------------------------------------------------------------------\n"
# " MOLCAS variables being used in this run:\n" # " MOLCAS variables being used in this run:\n"
@@ -492,7 +484,7 @@ class Player:
self.outfile.write("\n") self.outfile.write("\n")
if self.player.ghosts == "yes" or self.player.lps == "yes": if self.ghosts == "yes" or self.lps == "yes":
self.outfile.write( self.outfile.write(
"\n" "\n"
"------------------------------------------------------------------------------------------\n" "------------------------------------------------------------------------------------------\n"
@@ -585,11 +577,11 @@ class Player:
self.dice.configure( self.dice.configure(
StepDTO( StepDTO(
self.player.initcyc, initcyc=self.initcyc,
self.player.nprocs, nprocs=self.nprocs,
self.player.altsteps, altsteps=self.altsteps,
self.system.nmols, nmol=self.system.nmols,
self.system.molecule, molecule=self.system.molecule,
) )
) )
@@ -600,17 +592,17 @@ class Player:
def gaussian_start(self, cycle: int, geomsfh: TextIO): def gaussian_start(self, cycle: int, geomsfh: TextIO):
self.gaussian.configure( self.gaussian.configure(
self.player.initcyc, self.initcyc,
self.player.nprocs, self.nprocs,
self.dice.ncores, self.dice.ncores,
self.player.altsteps, self.altsteps,
self.player.switchcyc, self.switchcyc,
self.player.opt, self.opt,
self.system.nmols, self.system.nmols,
self.system.molecule, self.system.molecule,
) )
position = self.gaussian.start(cycle, self.outfile, self.player.readhessian) position = self.gaussian.start(cycle, self.outfile, self.readhessian)
## Update the geometry of the reference molecule ## Update the geometry of the reference molecule
self.system.update_molecule(position, self.outfile) self.system.update_molecule(position, self.outfile)
@@ -637,7 +629,7 @@ class Player:
else: else:
nconfigs = int(self.dice.nstep[-1] / self.dice.isave) nconfigs = int(self.dice.nstep[-1] / self.dice.isave)
norm_factor = nconfigs * self.player.nprocs norm_factor = nconfigs * self.nprocs
nsitesref = len(self.system.molecule[0].atom) nsitesref = len(self.system.molecule[0].atom)
# nsitesref = ( # nsitesref = (
@@ -653,7 +645,7 @@ class Player:
thickness = [] thickness = []
picked_mols = [] picked_mols = []
for proc in range(1, self.player.nprocs + 1): # Run over folders for proc in range(1, self.nprocs + 1): # Run over folders
simdir = "simfiles" simdir = "simfiles"
path = ( path = (
@@ -748,7 +740,7 @@ class Player:
asec_charges[-1]["rz"] = atom.rz asec_charges[-1]["rz"] = atom.rz
asec_charges[-1]["chg"] = atom.chg / norm_factor asec_charges[-1]["chg"] = atom.chg / norm_factor
# if self.player.vdwforces == "yes": # if self.vdwforces == "yes":
# vdw_meanfield[-1]["rx"] = atom["rx"] # vdw_meanfield[-1]["rx"] = atom["rx"]
# vdw_meanfield[-1]["ry"] = atom["ry"] # vdw_meanfield[-1]["ry"] = atom["ry"]
# vdw_meanfield[-1]["rz"] = atom["rz"] # vdw_meanfield[-1]["rz"] = atom["rz"]
@@ -810,22 +802,3 @@ class Player:
otherfh.close() otherfh.close()
return asec_charges return asec_charges
class Player:
def __init__(self) -> None:
self.maxcyc = None
self.nprocs = 1
self.switchcyc = 3
self.altsteps = 20000
self.maxstep = 0.3
self.opt = "yes"
self.freq = "no"
self.readhessian = "no"
self.lps = "no"
self.ghosts = "no"
self.vdwforces = "no"
self.tol_factor = 1.2
self.qmprog = "g16"
self.initcyc = 1

View File

@@ -7,11 +7,12 @@ from diceplayer.DPpack.Environment.Molecule import Molecule
@dataclass @dataclass
class StepDTO: class StepDTO:
initcyc: int cycle: int = None
nprocs: int initcyc: int = None
ncores: int nprocs: int = None
altsteps: int ncores: int = None
switchcyc: int altsteps: int = None
opt: str switchcyc: int = None
nmol: List[int] opt: str = None
molecule: List[Molecule] nmol: List[int] = None
molecule: List[Molecule] = None

View File

@@ -4,21 +4,15 @@ import argparse
import os import os
import pickle import pickle
import shutil import shutil
import signal
import sys import sys
import time
from multiprocessing import Process, connection
import numpy as np
import setproctitle import setproctitle
from diceplayer.DPpack.Environment.Atom import Atom
from diceplayer.DPpack.Environment.Molecule import Molecule
from diceplayer.DPpack.Player import Player from diceplayer.DPpack.Player import Player
from diceplayer.DPpack.Utils.Misc import * from diceplayer.DPpack.Utils.Misc import *
__version = "dev" __VERSION = "dev"
setproctitle.setproctitle("diceplayer-{}".format(__version)) setproctitle.setproctitle("diceplayer-{}".format(__VERSION))
if __name__ == "__main__": if __name__ == "__main__":
#### Read and store the arguments passed to the program #### #### Read and store the arguments passed to the program ####
@@ -29,12 +23,12 @@ if __name__ == "__main__":
"--continue", dest="opt_continue", default=False, action="store_true" "--continue", dest="opt_continue", default=False, action="store_true"
) )
parser.add_argument( parser.add_argument(
"--version", action="version", version="diceplayer-" + __version "--version", action="version", version="diceplayer-" + __VERSION
) )
parser.add_argument( parser.add_argument(
"-i", "-i",
dest="infile", dest="infile",
default="control.in", default="control.yml",
metavar="INFILE", metavar="INFILE",
help="input file of diceplayer [default = control.in]", help="input file of diceplayer [default = control.in]",
) )
@@ -90,9 +84,10 @@ if __name__ == "__main__":
player.print_keywords() player.print_keywords()
if args.opt_continue: if args.opt_continue:
player.player.initcyc = save[0] + 1 player.initcyc = save[0] + 1
player.system = save[1] player.system = save[1]
else: else:
player.initcyc = 1
player.read_potential() player.read_potential()
#### Check whether the executables are in the path #### Check whether the executables are in the path
@@ -126,13 +121,13 @@ if __name__ == "__main__":
make_simulation_dir() make_simulation_dir()
else: else:
simdir = "simfiles" simdir = "simfiles"
stepdir = "step{:02d}".format(player.player.initcyc) stepdir = "step{:02d}".format(player.initcyc)
if os.path.exists(simdir + os.sep + stepdir): if os.path.exists(simdir + os.sep + stepdir):
shutil.rmtree(simdir + os.sep + stepdir) shutil.rmtree(simdir + os.sep + stepdir)
#### Open the geoms.xyz file and prints the initial geometry if starting from zero #### Open the geoms.xyz file and prints the initial geometry if starting from zero
if player.player.initcyc == 1: if player.initcyc == 1:
try: try:
path = "geoms.xyz" path = "geoms.xyz"
geomsfh = open(path, "w", 1) geomsfh = open(path, "w", 1)
@@ -153,8 +148,8 @@ if __name__ == "__main__":
position = player.system.molecule[0].read_position() position = player.system.molecule[0].read_position()
## If restarting, read the last gradient and hessian ## If restarting, read the last gradient and hessian
# if player.player.initcyc > 1: # if player.initcyc > 1:
# if player.player.qmprog in ("g03", "g09", "g16"): # if player.qmprog in ("g03", "g09", "g16"):
# Gaussian.read_forces("grad_hessian.dat") # Gaussian.read_forces("grad_hessian.dat")
# Gaussian.read_hessian_fchk("grad_hessian.dat") # Gaussian.read_hessian_fchk("grad_hessian.dat")
@@ -168,9 +163,7 @@ if __name__ == "__main__":
player.outfile.write("\n" + 90 * "-" + "\n") player.outfile.write("\n" + 90 * "-" + "\n")
for cycle in range( for cycle in range(player.initcyc, player.initcyc + player.maxcyc):
player.player.initcyc, player.player.initcyc + player.player.maxcyc
):
player.outfile.write("{} Step # {}\n".format(40 * " ", cycle)) player.outfile.write("{} Step # {}\n".format(40 * " ", cycle))
player.outfile.write(90 * "-" + "\n\n") player.outfile.write(90 * "-" + "\n\n")
@@ -192,7 +185,7 @@ if __name__ == "__main__":
asec_charges = player.populate_asec_vdw(cycle) asec_charges = player.populate_asec_vdw(cycle)
## After ASEC is built, compress files bigger than 1MB ## After ASEC is built, compress files bigger than 1MB
for proc in range(1, player.player.nprocs + 1): for proc in range(1, player.nprocs + 1):
path = "step{:02d}".format(cycle) + os.sep + "p{:02d}".format(proc) path = "step{:02d}".format(cycle) + os.sep + "p{:02d}".format(proc)
compress_files_1mb(path) compress_files_1mb(path)

View File

@@ -1,15 +0,0 @@
Cycle # 0
Number of site: 12
C 1.400000 0.000000 0.000000
C 0.700000 1.212436 0.000000
C -0.700000 1.212436 0.000000
C -1.400000 0.000000 0.000000
C -0.700000 -1.212436 0.000000
C 0.700000 -1.212436 0.000000
H 2.488100 0.000000 0.000000
H 1.244000 2.154671 0.000000
H -1.244000 2.154671 0.000000
H -2.488100 0.000000 0.000000
H -1.244000 -2.154671 0.000000
H 1.244000 -2.154671 0.000000
----------------------------------------

View File

@@ -1,18 +1,18 @@
* *
2 2
12 BENZENO 12 BENZENO
1 6 0.000000 1.400000 0.000000 0.00000000 0.1100 3.7500 1 6 1.407784 0.000000 0.000000 0.00000000 0.1100 3.7500
1 6 1.212436 0.700000 0.000000 0.00000000 0.1100 3.7500 1 6 0.796966 1.274231 -0.338230 0.00000000 0.1100 3.7500
1 6 1.212436 -0.700000 0.000000 0.00000000 0.1100 3.7500 1 6 -0.703892 1.219173 -0.000000 0.00000000 0.1100 3.7500
1 6 0.000000 -1.400000 0.000000 0.00000000 0.1100 3.7500 1 6 -1.389932 -0.018988 0.227698 0.00000000 0.1100 3.7500
1 6 -1.212436 -0.700000 0.000000 0.00000000 0.1100 3.7500 1 6 -0.703892 -1.219173 0.000000 0.00000000 0.1100 3.7500
1 6 -1.212436 0.700000 0.000000 0.00000000 0.1100 3.7500 1 6 0.703892 -1.219173 0.000000 0.00000000 0.1100 3.7500
2 1 0.000000 2.488100 0.000000 0.00000000 0.0000 0.0000 2 1 2.501890 -0.000000 0.000000 0.00000000 0.0000 0.0000
2 1 2.154671 1.244000 0.000000 0.00000000 0.0000 0.0000 2 1 1.415017 2.294961 -0.608843 0.00000000 0.0000 0.0000
2 1 2.154671 -1.244000 0.000000 0.00000000 0.0000 0.0000 2 1 -1.250943 2.166698 -0.000000 0.00000000 0.0000 0.0000
2 1 0.000000 -2.488100 0.000000 0.00000000 0.0000 0.0000 2 1 -2.501890 0.000000 0.000000 0.00000000 0.0000 0.0000
2 1 -2.154671 -1.244000 0.000000 0.00000000 0.0000 0.0000 2 1 -0.519043 -2.235211 0.017991 0.00000000 0.0000 0.0000
2 1 -2.154671 1.244000 0.000000 0.00000000 0.0000 0.0000 2 1 1.250943 -2.166698 -0.000000 0.00000000 0.0000 0.0000
16 PLACEHOLDER 16 PLACEHOLDER
1 6 0.672026 -2.823446 0.002631 -0.11500000 0.0700 3.5500 1 6 0.672026 -2.823446 0.002631 -0.11500000 0.0700 3.5500
1 6 2.072026 -2.823446 0.002631 -0.11500000 0.0700 3.5500 1 6 2.072026 -2.823446 0.002631 -0.11500000 0.0700 3.5500