Implements the Use of a Simple DTO for Communication Between Classes

This commit is contained in:
2022-05-31 09:55:19 -03:00
parent 0d78c83e91
commit 44cb4268ef
6 changed files with 137 additions and 180 deletions

View File

@@ -1,24 +1,16 @@
from dataclasses import dataclass
from diceplayer.DPpack.Utils.PTable import *
from diceplayer.DPpack.Utils.Misc import *
from diceplayer.DPpack.Environment.Molecule import Molecule
from diceplayer.DPpack.Environment.Atom import Atom
from typing import IO, Final, Tuple, List, TextIO, Union
from numpy.core.numeric import partition
from numpy import random
from multiprocessing import Process, connection
import subprocess
import setproctitle
import os
import sys
import shutil
import subprocess
import sys
from multiprocessing import Process, connection
from typing import Final, List, TextIO
import setproctitle
from diceplayer.DPpack.Utils.Misc import *
from diceplayer.DPpack.Utils.PTable import *
from diceplayer.DPpack.Utils.StepDTO import StepDTO
from diceplayer.DPpack.Utils.Validations import NotNull
from numpy import random
DICE_END_FLAG: Final[str] = "End of simulation"
DICE_FLAG_LINE: Final[int] = -2
@@ -26,18 +18,17 @@ UMAANG3_TO_GCM3: Final[float] = 1.6605
MAX_SEED: Final[int] = 4294967295
class Dice:
title = "Diceplayer run"
progname = "dice"
path = None
nprocs: int = None
randominit = "first"
combrule = "*"
ncores = 1
temp = 300.0
press = 1.0
isave = 1000
@@ -53,14 +44,7 @@ class Dice:
self.infile = infile
self.outfile = outfile
@NotNull(requiredArgs = [
"ncores",
"nmol",
"dens",
"nstep",
"ljname",
"outname"
])
@NotNull(requiredArgs=["ncores", "nmol", "dens", "nstep", "ljname", "outname"])
def updateKeywords(self, **data):
self.__dict__.update(data)
@@ -86,9 +70,9 @@ class Dice:
volume = float(box[-3]) * float(box[-2]) * float(box[-1])
total_mass = 0
for i in range(len(self.molecule)):
for i in range(len(self.step.molecule)):
total_mass += self.molecule[i].total_mass * self.nmol[i]
total_mass += self.step.molecule[i].total_mass * self.step.nmol[i]
density = (total_mass / volume) * UMAANG3_TO_GCM3
@@ -109,9 +93,9 @@ class Dice:
except:
sys.exit("Error: cannot open file {}".format(file))
nsites = len(self.molecule[0].atom) * self.nmol[0]
for i in range(1, len(self.nmol)):
nsites += self.nmol[i] * len(self.molecule[i].atom)
nsites = len(self.step.molecule[0].atom) * self.step.nmol[0]
for i in range(1, len(self.step.nmol)):
nsites += self.step.nmol[i] * len(self.step.molecule[i].atom)
nsites += 2
@@ -132,11 +116,11 @@ class Dice:
num = time.time()
num = (num - int(num)) * 1e6
num = int((num - int(num)) * 1e6)
random.seed((os.getpid() * num) % (MAX_SEED + 1))
if self.randominit == "first" and cycle > self.initcyc:
if self.randominit == "first" and cycle > self.step.initcyc:
last_step_dir = "step{:02d}".format(cycle - 1)
last_path = sim_dir + os.sep + last_step_dir + os.sep + proc_dir
xyzfile = last_path + os.sep + "last.xyz"
@@ -149,7 +133,7 @@ class Dice:
elif len(self.nstep) == 3:
if self.randominit == "first" and cycle > self.initcyc:
if self.randominit == "first" and cycle > self.step.initcyc:
self.dens = self.__new_density(cycle, proc)
else:
self.__make_nvt_ter(cycle, path)
@@ -175,15 +159,15 @@ class Dice:
fh.write("ljname = {}\n".format(self.ljname))
fh.write("outname = {}\n".format(self.outname))
string = " ".join(str(x) for x in self.nmol)
string = " ".join(str(x) for x in self.step.nmol)
fh.write("nmol = {}\n".format(string))
fh.write("dens = {}\n".format(self.dens))
fh.write("temp = {}\n".format(self.temp))
if self.randominit == "first" and cycle > self.initcyc:
if self.randominit == "first" and cycle > self.step.initcyc:
fh.write("init = yesreadxyz\n")
fh.write("nstep = {}\n".format(self.altsteps))
fh.write("nstep = {}\n".format(self.step.altsteps))
else:
fh.write("init = yes\n")
fh.write("nstep = {}\n".format(self.nstep[0]))
@@ -214,7 +198,7 @@ class Dice:
fh.write("ljname = {}\n".format(self.ljname))
fh.write("outname = {}\n".format(self.outname))
string = " ".join(str(x) for x in self.nmol)
string = " ".join(str(x) for x in self.step.nmol)
fh.write("nmol = {}\n".format(string))
fh.write("dens = {}\n".format(self.dens))
@@ -226,7 +210,7 @@ class Dice:
fh.write("accum = no\n")
fh.write("iprint = 1\n")
fh.write("isave = {}\n".format(self.isave))
fh.write("irdf = {}\n".format(10 * self.nprocs))
fh.write("irdf = {}\n".format(10 * self.step.nprocs))
seed = int(1e6 * random.random())
fh.write("seed = {}\n".format(seed))
@@ -246,16 +230,16 @@ class Dice:
fh.write("ljname = {}\n".format(self.ljname))
fh.write("outname = {}\n".format(self.outname))
string = " ".join(str(x) for x in self.nmol)
string = " ".join(str(x) for x in self.step.nmol)
fh.write("nmol = {}\n".format(string))
fh.write("press = {}\n".format(self.press))
fh.write("temp = {}\n".format(self.temp))
if self.randominit == "first" and cycle > self.initcyc:
if self.randominit == "first" and cycle > self.step.initcyc:
fh.write("init = yesreadxyz\n")
fh.write("dens = {:<8.4f}\n".format(self.dens))
fh.write("vstep = {}\n".format(int(self.altsteps / 5)))
fh.write("vstep = {}\n".format(int(self.step.altsteps / 5)))
else:
fh.write("init = no\n")
fh.write("vstep = {}\n".format(int(self.nstep[1] / 5)))
@@ -285,7 +269,7 @@ class Dice:
fh.write("ljname = {}\n".format(self.ljname))
fh.write("outname = {}\n".format(self.outname))
string = " ".join(str(x) for x in self.nmol)
string = " ".join(str(x) for x in self.step.nmol)
fh.write("nmol = {}\n".format(string))
fh.write("press = {}\n".format(self.press))
@@ -299,7 +283,7 @@ class Dice:
fh.write("accum = no\n")
fh.write("iprint = 1\n")
fh.write("isave = {}\n".format(self.isave))
fh.write("irdf = {}\n".format(10 * self.nprocs))
fh.write("irdf = {}\n".format(10 * self.step.nprocs))
seed = int(1e6 * random.random())
fh.write("seed = {}\n".format(seed))
@@ -319,11 +303,11 @@ class Dice:
sys.exit("Error: cannot open file {}".format(file))
nsites_mm = 0
for i in range(1, len(self.nmol)):
nsites_mm += self.nmol[i] * len(self.molecule[i].atom)
for i in range(1, len(self.step.nmol)):
nsites_mm += self.step.nmol[i] * len(self.step.molecule[i].atom)
nsites_mm *= -1
xyzfile = xyzfile[nsites_mm:]
file = path + os.sep + self.outname + ".xy"
@@ -333,7 +317,7 @@ class Dice:
except:
sys.exit("Error: cannot open file {}".format(file))
for atom in self.molecule[0].atom:
for atom in self.step.molecule[0].atom:
fh.write(
"{:>10.6f} {:>10.6f} {:>10.6f}\n".format(atom.rx, atom.ry, atom.rz)
)
@@ -360,16 +344,16 @@ class Dice:
sys.exit("Error: cannot open file {}".format(file))
fh.write("{}\n".format(self.combrule))
fh.write("{}\n".format(len(self.nmol)))
fh.write("{}\n".format(len(self.step.nmol)))
nsites_qm = (
len(self.molecule[0].atom)
+ len(self.molecule[0].ghost_atoms)
+ len(self.molecule[0].lp_atoms)
len(self.step.molecule[0].atom)
+ len(self.step.molecule[0].ghost_atoms)
+ len(self.step.molecule[0].lp_atoms)
)
fh.write("{} {}\n".format(nsites_qm, self.molecule[0].molname))
for atom in self.molecule[0].atom:
fh.write("{} {}\n".format(nsites_qm, self.step.molecule[0].molname))
for atom in self.step.molecule[0].atom:
fh.write(
fstr.format(
atom.lbl,
@@ -383,23 +367,23 @@ class Dice:
)
)
ghost_label = self.molecule[0].atom[-1].lbl + 1
for i in self.molecule[0].ghost_atoms:
ghost_label = self.step.molecule[0].atom[-1].lbl + 1
for i in self.step.molecule[0].ghost_atoms:
fh.write(
fstr.format(
ghost_label,
ghost_number,
self.molecule[0].atom[i].rx,
self.molecule[0].atom[i].ry,
self.molecule[0].atom[i].rz,
self.molecule[0].atom[i].chg,
self.step.molecule[0].atom[i].rx,
self.step.molecule[0].atom[i].ry,
self.step.molecule[0].atom[i].rz,
self.step.molecule[0].atom[i].chg,
0,
0,
)
)
ghost_label += 1
for lp in self.molecule[0].lp_atoms:
for lp in self.step.molecule[0].lp_atoms:
fh.write(
fstr.format(
ghost_label,
@@ -413,7 +397,7 @@ class Dice:
)
)
for mol in self.molecule[1:]:
for mol in self.step.molecule[1:]:
fh.write("{} {}\n".format(len(mol.atom), mol.molname))
for atom in mol.atom:
fh.write(
@@ -462,7 +446,7 @@ class Dice:
if len(self.nstep) == 2:
if self.randominit == "first" and cycle > self.initcyc:
if self.randominit == "first" and cycle > self.step.initcyc:
string_tmp = "previous"
else:
string_tmp = "random"
@@ -620,7 +604,7 @@ class Dice:
)
if not self.randominit == "always" or (
(self.randominit == "first" and cycle > self.initcyc)
(self.randominit == "first" and cycle > self.step.initcyc)
):
string = " (from previous configuration) "
else:
@@ -735,28 +719,15 @@ class Dice:
except Exception as err:
sys.exit(err)
def configure(
self,
initcyc: int,
nprocs: int,
altsteps: int,
nmol: List[int],
molecule: List[Molecule],
):
self.initcyc = initcyc
self.nprocs = nprocs
self.altsteps = altsteps
self.nmol = nmol
self.molecule = molecule
def configure(self, step: StepDTO):
self.step = step
def start(self, cycle: int) -> None:
procs = []
sentinels = []
for proc in range(1, self.nprocs + 1):
for proc in range(1, self.step.nprocs + 1):
p = Process(target=self.__simulation_process, args=(cycle, proc))
p.start()
@@ -776,11 +747,8 @@ class Dice:
p.terminate()
sys.exit(status)
for proc in range(1, self.nprocs + 1):
for proc in range(1, self.step.nprocs + 1):
self.__print_last_config(cycle, proc)
def reset(self):
del self.nprocs
del self.altsteps
del self.molecule
del self.step

View File

@@ -1,29 +1,23 @@
from turtle import position
from diceplayer.DPpack.Environment.Atom import *
from diceplayer.DPpack.Utils.PTable import *
from diceplayer.DPpack.Utils.Misc import *
from diceplayer.DPpack.External.Dice import *
from diceplayer.DPpack.Environment.Molecule import Molecule
from diceplayer.DPpack.Environment.Atom import Atom
from typing import IO, List, TextIO
import os
import shutil
import subprocess
import sys
import textwrap
from typing import TextIO
import numpy as np
import subprocess
import os
import sys
import shutil
import textwrap
import types
from diceplayer.DPpack.Environment.Atom import Atom
from diceplayer.DPpack.Environment.Molecule import Molecule
from diceplayer.DPpack.Utils.Misc import *
from diceplayer.DPpack.Utils.PTable import *
from diceplayer.DPpack.Utils.StepDTO import StepDTO
from diceplayer.DPpack.Utils.Validations import NotNull
class Gaussian:
qmprog = "g09"
path = None
mem = None
keywords = None
chgmult = [0, 1]
@@ -35,9 +29,7 @@ class Gaussian:
def __init__(self) -> None:
pass
@NotNull(requiredArgs = [
"level"
])
@NotNull(requiredArgs=["level"])
def updateKeywords(self, **data):
self.__dict__.update(data)
@@ -71,7 +63,7 @@ class Gaussian:
while start.find("Cartesian Gradient") != 0: # expression in begining of line
start = fchkfile.pop(0).strip()
degrees = 3 * len(self.molecule[0].atom)
degrees = 3 * len(self.step.molecule[0].atom)
count = 0
while len(forces) < degrees:
values = fchkfile.pop(0).split()
@@ -90,11 +82,11 @@ class Gaussian:
"Number Number X Y Z\n"
"-----------------------------------------------------------------------\n"
)
for i in range(len(self.molecule[0].atom)):
for i in range(len(self.step.molecule[0].atom)):
fh.write(
" {:>5d} {:>3d} {:>14.9f} {:>14.9f} {:>14.9f}\n".format(
i + 1,
self.molecule[0].atom[i].na,
self.step.molecule[0].atom[i].na,
forces.pop(0),
forces.pop(0),
forces.pop(0),
@@ -129,7 +121,7 @@ class Gaussian:
while start.find("Cartesian Force Constants") != 0:
start = fchkfile.pop(0).strip()
degrees = 3 * len(self.molecule[0].atom)
degrees = 3 * len(self.step.molecule[0].atom)
last = round(degrees * (degrees + 1) / 2)
count = 0
@@ -167,7 +159,7 @@ class Gaussian:
while start.find("The second derivative matrix:") != 0:
start = logfile.pop(0).strip()
degrees = 3 * len(self.molecule[0].atom)
degrees = 3 * len(self.step.molecule[0].atom)
hessian = np.zeros((degrees, degrees))
k = 0
@@ -193,7 +185,7 @@ class Gaussian:
fh.write("Optimization cycle: {}\n".format(cycle))
fh.write("Cartesian Gradient\n")
degrees = 3 * len(self.molecule[0].atom)
degrees = 3 * len(self.step.molecule[0].atom)
for i in range(degrees):
fh.write(" {:>11.8g}".format(cur_gradient[i]))
if (i + 1) % 5 == 0 or i == degrees - 1:
@@ -229,14 +221,14 @@ class Gaussian:
fh.write("%Chk=asec.chk\n")
if self.mem != None:
fh.write("%Mem={}MB\n".format(self.mem))
fh.write("%Nprocs={}\n".format(self.nprocs * self.ncores))
fh.write("%Nprocs={}\n".format(self.step.nprocs * self.step.ncores))
kword_line = "#P " + str(self.level)
if self.keywords != None:
kword_line += " " + self.keywords
if self.opt == "yes":
if self.step.opt == "yes":
kword_line += " Force"
# kword_line += " Charge"
@@ -253,7 +245,7 @@ class Gaussian:
fh.write("\n")
fh.write("{},{}\n".format(self.chgmult[0], self.chgmult[1]))
for atom in self.molecule[0].atom:
for atom in self.step.molecule[0].atom:
symbol = atomsymb[atom.na]
fh.write(
"{:<2s} {:>10.5f} {:>10.5f} {:>10.5f}\n".format(
@@ -330,7 +322,7 @@ class Gaussian:
fh.write("\nAtomic charges:\n")
fh.write("------------------------------------\n")
for atom in self.molecule[0].atom:
for atom in self.step.molecule[0].atom:
line = glogfile.pop(0).split()
atom_str = line[1]
charge = float(line[2])
@@ -466,28 +458,9 @@ class Gaussian:
# return step
def configure(self, step: StepDTO):
def configure(
self,
initcyc: int,
nprocs: int,
ncores: int,
altsteps: int,
switchcyc: int,
opt: str,
nmol: List[int],
molecule: List[Molecule],
):
self.initcyc = initcyc
self.nprocs = nprocs
self.ncores = ncores
self.altsteps = altsteps
self.switchcyc = switchcyc
self.opt = opt
self.molecule = molecule
self.step = step
def start(self, cycle: int, outfile: TextIO, readhessian: str) -> np.ndarray:
@@ -569,10 +542,8 @@ class Gaussian:
# From 2nd step on, update the hessian
else:
outfile.write(
"\nUpdating the hessian matrix using the BFGS method... "
)
hessian = self.molecule[0].update_hessian(
outfile.write("\nUpdating the hessian matrix using the BFGS method... ")
hessian = self.step.molecule[0].update_hessian(
step, gradient, old_gradient, hessian
)
outfile.write("Done\n")
@@ -586,7 +557,7 @@ class Gaussian:
position += step
## If needed, calculate the charges
if cycle < self.switchcyc:
if cycle < self.step.switchcyc:
# internal.gaussian.make_charge_input(cycle, asec_charges)
self.run_gaussian(cycle, "charge", outfile)
@@ -615,7 +586,7 @@ class Gaussian:
## Print new info for molecule[0]
self.outfile.write("\nNew values for molecule type 1:\n\n")
self.molecule[0].print_mol_info(outfile)
self.step.molecule[0].print_mol_info(outfile)
##
## Molcas block
@@ -683,6 +654,4 @@ class Gaussian:
def reset(self):
del self.nprocs
del self.altsteps
del self.molecule
del self.step

View File

@@ -1,23 +1,21 @@
from diceplayer.DPpack.Utils.Validations import NotNull
from diceplayer.DPpack.Utils.PTable import *
from diceplayer.DPpack.Utils.Misc import *
from diceplayer.DPpack.External.Gaussian import Gaussian
from diceplayer.DPpack.External.Dice import Dice
from diceplayer.DPpack.Environment.System import System
from diceplayer.DPpack.Environment.Molecule import Molecule
from diceplayer.DPpack.Environment.Atom import Atom
from typing import TextIO
import os
import sys
import shutil
import sys
import textwrap
import types
from typing import TextIO
import yaml
from diceplayer.DPpack.Environment.Atom import Atom
from diceplayer.DPpack.Environment.Molecule import Molecule
from diceplayer.DPpack.Environment.System import System
from diceplayer.DPpack.External.Dice import Dice
from diceplayer.DPpack.External.Gaussian import Gaussian
from diceplayer.DPpack.Utils.Misc import *
from diceplayer.DPpack.Utils.PTable import *
from diceplayer.DPpack.Utils.StepDTO import StepDTO
from diceplayer.DPpack.Utils.Validations import NotNull
env = ["OMP_STACKSIZE"]
@@ -61,8 +59,9 @@ class Player:
self.combrule = None
@NotNull(requiredArgs=["maxcyc", "opt", "nprocs", "qmprog", "lps", "ghosts", "altsteps"])
@NotNull(
requiredArgs=["maxcyc", "opt", "nprocs", "qmprog", "lps", "ghosts", "altsteps"]
)
def updateKeywords(self, **data):
self.__dict__.update(data)
@@ -585,11 +584,13 @@ class Player:
def dice_start(self, cycle: int):
self.dice.configure(
self.player.initcyc,
self.player.nprocs,
self.player.altsteps,
self.system.nmols,
self.system.molecule,
StepDTO(
self.player.initcyc,
self.player.nprocs,
self.player.altsteps,
self.system.nmols,
self.system.molecule,
)
)
self.dice.start(cycle)

View File

@@ -0,0 +1,17 @@
from dataclasses import dataclass
from typing import List
from diceplayer.DPpack.Environment.Molecule import Molecule
@dataclass
class StepDTO:
initcyc: int
nprocs: int
ncores: int
altsteps: int
switchcyc: int
opt: str
nmol: List[int]
molecule: List[Molecule]

View File

@@ -12,4 +12,4 @@ def NotNull(requiredArgs=[]):
return wrapper
return _NotNull
return _NotNull

View File

@@ -1,19 +1,21 @@
#!/usr/bin/python3
from multiprocessing import Process, connection
import os, sys, time, signal
import setproctitle
import numpy as np
import argparse
import shutil
import os
import pickle
import shutil
import signal
import sys
import time
from multiprocessing import Process, connection
from diceplayer.DPpack.Utils.Misc import *
import numpy as np
import setproctitle
from diceplayer.DPpack.Player import Player
from diceplayer.DPpack.Environment.Molecule import Molecule
from diceplayer.DPpack.Environment.Atom import Atom
from diceplayer.DPpack.Environment.Molecule import Molecule
from diceplayer.DPpack.Player import Player
from diceplayer.DPpack.Utils.Misc import *
__version = "dev"
setproctitle.setproctitle("diceplayer-{}".format(__version))