Skip to content

Commit

Permalink
Merge branch 'main' into cleaner_node_association
Browse files Browse the repository at this point in the history
  • Loading branch information
liamhuber committed May 18, 2023
2 parents 7ec47f3 + 8f7253f commit e221e78
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 52 deletions.
109 changes: 57 additions & 52 deletions pyiron_contrib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,70 @@
import warnings

try:
from pyiron import Project
from pyiron import Project
except:
warnings.warn("pyiron module not found, importing Project from pyiron_base")
from pyiron_base import Project
warnings.warn("pyiron module not found, importing Project from pyiron_base")
from pyiron_base import Project

from pyiron_base import JOB_CLASS_DICT
from pyiron_contrib.generic.storage_interface_toolkit import StorageInterfaceFactory

Project.register_tools('storage_interface', StorageInterfaceFactory)
Project.register_tools("storage_interface", StorageInterfaceFactory)

# Make classes available for new pyiron version
JOB_CLASS_DICT['ProtoMinimGradDes'] = 'pyiron_contrib.protocol.compound.minimize'
JOB_CLASS_DICT['ProtoMD'] = 'pyiron_contrib.protocol.compound.molecular_dynamics'
JOB_CLASS_DICT['ProtoConfinedMD'] = 'pyiron_contrib.protocol.compound.molecular_dynamics'
JOB_CLASS_DICT['ProtoHarmMD'] = 'pyiron_contrib.protocol.compound.molecular_dynamics'
JOB_CLASS_DICT['ProtoNEBSer'] = 'pyiron_contrib.protocol.compound.nudged_elastic_band'
JOB_CLASS_DICT['ProtocolQMMM'] = 'pyiron_contrib.protocol.compound.qmmm'
JOB_CLASS_DICT['ProtoHarmTILDSer'] = 'pyiron_contrib.protocol.compound.thermodynamic_integration'
JOB_CLASS_DICT['ProtoHarmTILDPar'] = 'pyiron_contrib.protocol.compound.thermodynamic_integration'
JOB_CLASS_DICT['ProtoVacTILDSer'] = 'pyiron_contrib.protocol.compound.thermodynamic_integration'
JOB_CLASS_DICT['ProtoVacTILDPar'] = 'pyiron_contrib.protocol.compound.thermodynamic_integration'
JOB_CLASS_DICT['ProtoVacForm'] = 'pyiron_contrib.protocol.compound.thermodynamic_integration'
JOB_CLASS_DICT['ProtoFTSEvoSer'] = 'pyiron_contrib.protocol.compound.finite_temperature_string'
JOB_CLASS_DICT['ProtoFTSEvoPar'] = 'pyiron_contrib.protocol.compound.finite_temperature_string'
JOB_CLASS_DICT['ImageJob'] = 'pyiron_contrib.image.job'
JOB_CLASS_DICT['LangevinAse'] = 'pyiron_contrib.atomistics.interactive.langevin'
JOB_CLASS_DICT['Mixer'] = 'pyiron_contrib.atomistics.interactive.mixer'
JOB_CLASS_DICT['ParameterMaster'] = 'pyiron_contrib.atomistics.dft.parametermaster'
JOB_CLASS_DICT['MonteCarloMaster'] = 'pyiron_contrib.atomistics.interactive.montecarlo'
JOB_CLASS_DICT['RandSpg'] = 'pyiron_contrib.atomistics.randspg.randspg'
JOB_CLASS_DICT['Fenics'] = 'pyiron_contrib.continuum.fenics.job.generic'
JOB_CLASS_DICT['FenicsLinearElastic'] = 'pyiron_contrib.continuum.fenics.job.elastic'
JOB_CLASS_DICT['TrainingContainer'] = 'pyiron_contrib.atomistics.atomistics.job.trainingcontainer'
JOB_CLASS_DICT['RandomDisMaster'] = 'pyiron_contrib.atomistics.mlip.masters'
JOB_CLASS_DICT['RandomMDMaster'] = 'pyiron_contrib.atomistics.mlip.masters'
JOB_CLASS_DICT['RunnerFit'] = 'pyiron_contrib.atomistics.runner.job'
JOB_CLASS_DICT['MlipSelect'] = 'pyiron_contrib.atomistics.mlip.mlipselect'
JOB_CLASS_DICT['Mlip'] = 'pyiron_contrib.atomistics.mlip.mlip'
JOB_CLASS_DICT['LammpsMlip'] = 'pyiron_contrib.atomistics.mlip.lammps'
JOB_CLASS_DICT['MlipJob'] = 'pyiron_contrib.atomistics.mlip.mlipjob'
JOB_CLASS_DICT['Atomicrex'] = 'pyiron_contrib.atomistics.atomicrex.atomicrex_job'
JOB_CLASS_DICT['StructureMasterInt'] = 'pyiron_contrib.atomistics.atomistics.job.structurelistmasterinteractive'
JOB_CLASS_DICT['StorageJob'] = 'pyiron_contrib.RDM.storagejob'
JOB_CLASS_DICT['MlipDescriptors'] = 'pyiron_contrib.atomistics.mlip.mlipdescriptors'
JOB_CLASS_DICT['PacemakerJob'] = 'pyiron_contrib.atomistics.pacemaker.job'
JOB_CLASS_DICT['MeamFit'] = 'pyiron_contrib.atomistics.meamfit.meamfit'
JOB_CLASS_DICT['Cp2kJob'] = 'pyiron_contrib.atomistics.cp2k.job'
JOB_CLASS_DICT['PiMD'] = 'pyiron_contrib.atomistics.ipi.ipi_jobs'
JOB_CLASS_DICT['GleMD'] = 'pyiron_contrib.atomistics.ipi.ipi_jobs'
JOB_CLASS_DICT['PigletMD'] = 'pyiron_contrib.atomistics.ipi.ipi_jobs'
JOB_CLASS_DICT['LammpsInteractiveWithoutOutput'] = 'pyiron_contrib.nofiles.lammps'
JOB_CLASS_DICT['SQSJobWithoutOutput'] = 'pyiron_contrib.nofiles.sqs'
JOB_CLASS_DICT['ElasticMatrixJobWithoutFiles'] = 'pyiron_contrib.nofiles.elastic'
JOB_CLASS_DICT['MurnaghanWithoutFiles'] = 'pyiron_contrib.nofiles.murn'
JOB_CLASS_DICT['PhonopyJobWithoutFiles'] = 'pyiron_contrib.nofiles.phonopy'
JOB_CLASS_DICT['SQSMasterMPI'] = 'pyiron_contrib.nofiles.master'
JOB_CLASS_DICT['LAMMPSMinimizeMPI'] = 'pyiron_contrib.nofiles.master'
JOB_CLASS_DICT['LAMMPSElasticMPI'] = 'pyiron_contrib.nofiles.master'
JOB_CLASS_DICT['LAMMPSMinimizeElasticMPI'] = 'pyiron_contrib.nofiles.master'
JOB_CLASS_DICT.update(
{
"ProtoMinimGradDes": "pyiron_contrib.protocol.compound.minimize",
"ProtoMD": "pyiron_contrib.protocol.compound.molecular_dynamics",
"ProtoConfinedMD": "pyiron_contrib.protocol.compound.molecular_dynamics",
"ProtoHarmMD": "pyiron_contrib.protocol.compound.molecular_dynamics",
"ProtoNEBSer": "pyiron_contrib.protocol.compound.nudged_elastic_band",
"ProtocolQMMM": "pyiron_contrib.protocol.compound.qmmm",
"ProtoHarmTILDSer": "pyiron_contrib.protocol.compound.thermodynamic_integration",
"ProtoHarmTILDPar": "pyiron_contrib.protocol.compound.thermodynamic_integration",
"ProtoVacTILDSer": "pyiron_contrib.protocol.compound.thermodynamic_integration",
"ProtoVacTILDPar": "pyiron_contrib.protocol.compound.thermodynamic_integration",
"ProtoVacForm": "pyiron_contrib.protocol.compound.thermodynamic_integration",
"ProtoFTSEvoSer": "pyiron_contrib.protocol.compound.finite_temperature_string",
"ProtoFTSEvoPar": "pyiron_contrib.protocol.compound.finite_temperature_string",
"ImageJob": "pyiron_contrib.image.job",
"LangevinAse": "pyiron_contrib.atomistics.interactive.langevin",
"Mixer": "pyiron_contrib.atomistics.interactive.mixer",
"ParameterMaster": "pyiron_contrib.atomistics.dft.parametermaster",
"MonteCarloMaster": "pyiron_contrib.atomistics.interactive.montecarlo",
"RandSpg": "pyiron_contrib.atomistics.randspg.randspg",
"Fenics": "pyiron_contrib.continuum.fenics.job.generic",
"FenicsLinearElastic": "pyiron_contrib.continuum.fenics.job.elastic",
"TrainingContainer": "pyiron_contrib.atomistics.atomistics.job.trainingcontainer",
"RandomDisMaster": "pyiron_contrib.atomistics.mlip.masters",
"RandomMDMaster": "pyiron_contrib.atomistics.mlip.masters",
"RunnerFit": "pyiron_contrib.atomistics.runner.job",
"MlipSelect": "pyiron_contrib.atomistics.mlip.mlipselect",
"Mlip": "pyiron_contrib.atomistics.mlip.mlip",
"LammpsMlip": "pyiron_contrib.atomistics.mlip.lammps",
"MlipJob": "pyiron_contrib.atomistics.mlip.mlipjob",
"Atomicrex": "pyiron_contrib.atomistics.atomicrex.atomicrex_job",
"StructureMasterInt": "pyiron_contrib.atomistics.atomistics.job.structurelistmasterinteractive",
"StorageJob": "pyiron_contrib.RDM.storagejob",
"MlipDescriptors": "pyiron_contrib.atomistics.mlip.mlipdescriptors",
"PacemakerJob": "pyiron_contrib.atomistics.pacemaker.job",
"MeamFit": "pyiron_contrib.atomistics.meamfit.meamfit",
"Cp2kJob": "pyiron_contrib.atomistics.cp2k.job",
"PiMD": "pyiron_contrib.atomistics.ipi.ipi_jobs",
"GleMD": "pyiron_contrib.atomistics.ipi.ipi_jobs",
"PigletMD": "pyiron_contrib.atomistics.ipi.ipi_jobs",
"LammpsInteractiveWithoutOutput": "pyiron_contrib.nofiles.lammps",
"SQSJobWithoutOutput": "pyiron_contrib.nofiles.sqs",
"ElasticMatrixJobWithoutFiles": "pyiron_contrib.nofiles.elastic",
"MurnaghanWithoutFiles": "pyiron_contrib.nofiles.murn",
"PhonopyJobWithoutFiles": "pyiron_contrib.nofiles.phonopy",
"SQSMasterMPI": "pyiron_contrib.nofiles.master",
"LAMMPSMinimizeMPI": "pyiron_contrib.nofiles.master",
"LAMMPSElasticMPI": "pyiron_contrib.nofiles.master",
"LAMMPSMinimizeElasticMPI": "pyiron_contrib.nofiles.master",
"FitsnapJob": "pyiron_contrib.atomistics.fitsnap.job",
}
)


from ._version import get_versions
Expand Down
89 changes: 89 additions & 0 deletions pyiron_contrib/atomistics/fitsnap/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import numpy as np
from pybispectrum import calc_bispectrum_names
from fitsnap3lib.scrapers.ase_funcs import get_apre, create_shared_arrays


def ase_scraper(
s, frames, energies, forces, stresses=[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
):
"""
Custom function to allocate shared arrays used in Calculator and build the internal list of
dictionaries `data` of configuration info. Customized version of `fitsnap3lib.scrapers.ase_funcs`.
Args:
s: fitsnap instance.
frames: list or array of ASE atoms objects.
energies: array of energies.
forces: array of forces for all configurations.
stresses: array of stresses for all configurations.
Creates a list of data dictionaries `s.data` suitable for fitsnap descriptor calculation.
If running in parallel, this list will be distributed over procs, so that each proc will have a
portion of the list.
"""

create_shared_arrays(s, frames)
s.data = [
collate_data(a, e, f, s)
for (a, e, f, s) in zip(frames, energies, forces, stresses)
]


def collate_data(atoms, energy, forces, stresses):
"""
Function to organize fitting data for FitSNAP from ASE atoms objects.
Args:
atoms: ASE atoms object for a single configuration of atoms.
energy: energy of a configuration.
forces: numpy array of forces for a configuration.
stresses: numpy array of stresses for a configuration.
Returns a fitsnap data dictionary for a single configuration.
"""

# make a data dictionary for this config

apre = get_apre(cell=atoms.cell)
R = np.dot(np.linalg.inv(atoms.cell), apre)

positions = np.matmul(atoms.get_positions(), R)
cell = apre.T

data = {}
data["PositionsStyle"] = "angstrom"
data["AtomTypeStyle"] = "chemicalsymbol"
data["StressStyle"] = "bar"
data["LatticeStyle"] = "angstrom"
data["EnergyStyle"] = "electronvolt"
data["ForcesStyle"] = "electronvoltperangstrom"
data["Group"] = "Displaced_BCC"
data["File"] = None
data["Stress"] = stresses
data["Positions"] = positions
data["Energy"] = energy
data["AtomTypes"] = atoms.get_chemical_symbols()
data["NumAtoms"] = len(atoms)
data["Forces"] = forces
data["QMLattice"] = cell
data["test_bool"] = 0
data["Lattice"] = cell
data["Rotation"] = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
data["Translation"] = np.zeros((len(atoms), 3))
data["eweight"] = 1.0
data["fweight"] = 1.0 / 150.0
data["vweight"] = 0.0

return data


def subsample_twojmax(total_bispect, twojmax_lst):
bi_spect_names_str_lst = [str(lst) for lst in total_bispect]
twojmax_master_str_lst = [
[str(lst) for lst in calc_bispectrum_names(twojmax=tjm)] for tjm in twojmax_lst
]
ind_lst = [
[desc in desc_lst for desc in bi_spect_names_str_lst]
for desc_lst in twojmax_master_str_lst
]
return ind_lst
101 changes: 101 additions & 0 deletions pyiron_contrib/atomistics/fitsnap/job.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
from mpi4py import MPI
from fitsnap3lib.fitsnap import FitSnap
from pyiron_base import PythonTemplateJob, DataContainer
from pyiron_lanl.fitsnap.common import ase_scraper


default_input = settings = {
"BISPECTRUM": {
"numTypes": 1,
"twojmax": 8,
"rcutfac": 4.812302818,
"rfac0": 0.99363,
"rmin0": 0.0,
"wj": 1.0,
"radelem": 0.5,
"type": "Be",
"wselfallflag": 0,
"chemflag": 0,
"bzeroflag": 0,
"quadraticflag": 0,
},
"CALCULATOR": {
"calculator": "LAMMPSSNAP",
"energy": 1, # Calculate energy descriptors
"force": 1, # Calculate force descriptors
"stress": 0, # Calculate virial descriptors
},
"REFERENCE": {
"units": "metal",
"atom_style": "atomic",
"pair_style": "hybrid/overlay zero 10.0 zbl 4.0 4.8",
"pair_coeff1": "* * zero",
"pair_coeff2": "1 1 zbl 74 74",
},
"SOLVER": {"solver": "SVD", "compute_testerrs": 1, "detailed_errors": 1},
"EXTRAS": {
"dump_descriptors": 0,
"dump_truth": 0,
"dump_weights": 0,
"dump_dataframe": 0,
},
"MEMORY": {"override": 0},
}


class FitsnapJob(PythonTemplateJob):
def __init__(self, project, job_name):
super(FitsnapJob, self).__init__(project, job_name)
self.__version__ = "0.1"
self.__name__ = "FitsnapJob"
self.input.update(default_input)
self._lst_of_struct = []
self._lst_of_energies = []
self._lst_of_forces = []
self._coefficients = []

@property
def list_of_structures(self):
return self._lst_of_struct

@list_of_structures.setter
def list_of_structures(self, structure_lst):
self._lst_of_struct = structure_lst

@property
def list_of_energies(self):
return self._lst_of_energies

@list_of_energies.setter
def list_of_energies(self, energies):
self._lst_of_energies = energies

@property
def coefficients(self):
return self._coefficients

@property
def list_of_forces(self):
return self._lst_of_forces

@list_of_forces.setter
def list_of_forces(self, forces):
self._lst_of_forces = forces

def run_static(self):
comm = MPI.COMM_WORLD
input_dict = self.input.to_builtin()
snap = FitSnap(input_dict, comm=comm, arglist=["--overwrite"])
ase_scraper(
snap, self._lst_of_struct, self._lst_of_energies, self._lst_of_forces
)
snap.process_configs()
snap.solver.perform_fit()
self._coefficients = snap.solver.fit
self.status.finished = True

def to_hdf(self, hdf=None, group_name=None):
super(FitsnapJob, self).to_hdf(hdf=hdf, group_name=group_name)

def from_hdf(self, hdf=None, group_name=None):
super(FitsnapJob, self).from_hdf(hdf=hdf, group_name=group_name)

0 comments on commit e221e78

Please sign in to comment.