Skip to content

Commit

Permalink
Merge branch 'master' into cp2k
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-janssen authored Feb 22, 2022
2 parents fa4f0de + d962b7b commit d8e3cf4
Show file tree
Hide file tree
Showing 16 changed files with 2,173 additions and 986 deletions.
19 changes: 9 additions & 10 deletions .ci_support/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ dependencies:
- coveralls
- coverage
- codacy-coverage
- matplotlib =3.5.0
- numpy =1.21.4
- pyiron_base =0.4.3
- pyiron_atomistics =0.2.31
- pyparsing =3.0.6
- scipy =1.7.3
- matplotlib =3.5.1
- numpy =1.22.2
- pyiron_base =0.5.5
- pyiron_atomistics =0.2.37
- pyparsing =3.0.7
- scipy =1.8.0
- seaborn =0.11.2
- scikit-image =0.19.0
- scikit-image =0.19.2
- randspg =0.0.1
- boto3
- moto
- more-itertools
- pycp2k =0.2.2
- boto3 =1.21.3
- moto =3.0.4
2 changes: 1 addition & 1 deletion .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
python-version: ["3.7", "3.8", "3.9", "3.10"]
python-version: ["3.8", "3.9", "3.10"]

steps:
- uses: actions/checkout@v2
Expand Down
7 changes: 4 additions & 3 deletions pyiron_contrib/atomistics/atomicrex/atomicrex_job.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from pyiron_contrib.atomistics.atomicrex.interactive import AtomicrexInteractive


class Atomicrex(AtomicrexInteractive):
"""Class to set up and run atomicrex jobs
"""
"""Class to set up and run atomicrex jobs"""

def __init__(self, project, job_name):
super().__init__(project, job_name)
self.__name__ = "Atomicrex"
self._executable_activate(enforce=True)
self._executable_activate(enforce=True)
94 changes: 64 additions & 30 deletions pyiron_contrib/atomistics/atomicrex/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

from pyiron_base import state, GenericJob, Executable

from pyiron_contrib.atomistics.atomicrex.general_input import GeneralARInput, AlgorithmFactory
from pyiron_contrib.atomistics.atomicrex.general_input import (
GeneralARInput,
AlgorithmFactory,
)
from pyiron_contrib.atomistics.atomicrex.structure_list import ARStructureContainer
from pyiron_contrib.atomistics.atomicrex.potential_factory import ARPotFactory
from pyiron_contrib.atomistics.atomicrex.output import Output
Expand All @@ -20,20 +23,22 @@ class PotentialFittingBase(GenericJob):
def __init__(self, project, job_name):
super().__init__(project, job_name)


class AtomicrexBase(PotentialFittingBase):
__version__ = "0.1.0"
__hdf_version__ = "0.1.0"
"""Class to set up and run atomicrex jobs"""

def __init__(self, project, job_name):
super().__init__(project, job_name)
#self._executable_activate(enforce=True)
# self._executable_activate(enforce=True)
state.publications.add(self.publication)
self.input = GeneralARInput()
self.potential = None
self.structures = ARStructureContainer()
self.output = Output()
self.factories = Factories()

self._compress_by_default = True

def plot_final_potential(self):
"""
Expand Down Expand Up @@ -74,25 +79,46 @@ def publication(self):
"issn": "0965-0393",
"doi": "10.1088/1361-651X/aa6ecf",
"url": "https://doi.org/10.1088%2F1361-651x%2Faa6ecf",
"author": ["Alexander Stukowski", "Erik Fransson", "Markus Mock", "Paul Erhart"],
"author": [
"Alexander Stukowski",
"Erik Fransson",
"Markus Mock",
"Paul Erhart",
],
}
}
}

def compress(self, files_to_compress=None):
"""
Compress the output files of a job object.
Args:
files_to_compress (list): A list of files to compress (optional)
"""
if files_to_compress is None:
if self.potential.export_file is None:
files_to_compress = self.list_files()
else:
files_to_compress = [
f for f in self.list_files() if f != self.potential.export_file
]
super().compress(files_to_compress=files_to_compress)

def collect_output(self, cwd=None):
"""Internal function that parses the output of an atomicrex job
Args:
cwd (str, optional): Working directory. Defaults to None.
"""
#self.input.from_hdf(self._hdf5)
"""
# self.input.from_hdf(self._hdf5)
if cwd is None:
cwd = self.working_directory
if self.input.__version__ == "0.1.0":
filepath = f"{cwd}/atomicrex.out"
else:
filepath = f"{cwd}/error.out"

finished_triggered = False
params_triggered = False
dependent_dofs_triggered = False
Expand All @@ -104,11 +130,11 @@ def collect_output(self, cwd=None):
residuals = np.zeros(self.input.fit_algorithm.max_iter + 1)
else:
residuals = np.zeros(self.input.fit_algorithm.max_iter)

# Since every step is written out in atomicrex arange can be used.
# Needs to be adapted when atomicrex output is changed to write only every xth step.
# Unsinged 32 bit int should be enough or this will overflow anyway in most cases.
iterations = np.arange(start=1, stop=len(residuals)+1, dtype=np.uintc)
iterations = np.arange(start=1, stop=len(residuals) + 1, dtype=np.uintc)
iter_index = 0

with open(filepath, "r") as f:
Expand All @@ -118,9 +144,9 @@ def collect_output(self, cwd=None):

for l in f:
if l.startswith("ERROR"):
self.status.aborted=True
self.status.aborted = True
self.output.error = l

elif not finished_triggered:
if l.startswith("Iterations"):
l = l.split()
Expand All @@ -132,25 +158,29 @@ def collect_output(self, cwd=None):
try:
if l[1] == "iter=":
residuals[iter_index] = float(l[-1])
iter_index += 1
iter_index += 1
except IndexError:
continue
else: # if finished_triggered

else: # if finished_triggered
if params_triggered:
if not l.startswith("---"):
final_parameter_lines.append(l)
else:
# Collecting lines with final parameters finished, hand over to the potential class
self.potential._parse_final_parameters(final_parameter_lines)
self.potential._parse_final_parameters(
final_parameter_lines
)
params_triggered = False

elif structures_triggered:
if not l.startswith("---"):
final_property_lines.append(l)
else:
# Collecting structure information finished, hand over structures class
self.structures._parse_final_properties(final_property_lines)
self.structures._parse_final_properties(
final_property_lines
)
structures_triggered = False

elif dependent_dofs_triggered:
Expand All @@ -164,7 +194,7 @@ def collect_output(self, cwd=None):
# Get the number of dofs
n_fit_dofs = int(l.split("=")[1][:-3])
params_triggered = True

elif l.startswith("Computing"):
structures_triggered = True

Expand All @@ -173,29 +203,32 @@ def collect_output(self, cwd=None):
self.to_hdf()

def convergence_check(self):
"""Internal function, TODO"""
return
"""
Internal function, TODO
find something to reasonably judge convegence
"""
return True

def write_input(self, directory=None):
"""Internal function that writes input files
Args:
directory ([string], optional): Working directory. Defaults to None.
"""
"""
if directory is None:
directory = self.working_directory
self.input._write_xml_file(directory = directory)
self.potential.write_xml_file(directory = directory)
self.structures.write_xml_file(directory = directory)
self.input._write_xml_file(directory=directory)
self.potential.write_xml_file(directory=directory)
self.structures.write_xml_file(directory=directory)

def _executable_activate(self, enforce=False):
"""
Internal function that sets up and Executable() object
Internal function that sets up and Executable() object
and finds executables available in pyiron resources/atomicrex/bin
Args:
enforce (bool, optional): [description]. Defaults to False.
"""
"""
if self._executable is None or enforce:
if len(self.__module__.split(".")) > 1:
self._executable = Executable(
Expand All @@ -205,7 +238,8 @@ def _executable_activate(self, enforce=False):
)
else:
self._executable = Executable(
codename=self.__name__, path_binary_codes=state.settings.resource_paths
codename=self.__name__,
path_binary_codes=state.settings.resource_paths,
)

# Leftover of the potentials workshop.
Expand All @@ -217,20 +251,20 @@ def lammps_potential(self):
pot = self.potential_as_pd_df()
return pot


def potential_as_pd_df(self):
"""
Return the fitted potential as a pandas dataframe,
which can be used for lammps calculations.
"""
"""
return self.potential._potential_as_pd_df(job=self)


class Factories:
"""
Provides conventient acces to other factory classes.
Functionality to set up an atomicrex job can be found here.
"""
"""

def __init__(self):
self.potentials = ARPotFactory()
self.functions = FunctionFactory()
Expand Down
Loading

0 comments on commit d8e3cf4

Please sign in to comment.