Skip to content

Commit

Permalink
Merge pull request #24 from mala-project/development_graphene
Browse files Browse the repository at this point in the history
MALADA for 2D systems
  • Loading branch information
RandomDefaultUser authored Oct 24, 2024
2 parents 5fd9a48 + d995a36 commit ba66435
Show file tree
Hide file tree
Showing 26 changed files with 1,357 additions and 717 deletions.
26 changes: 14 additions & 12 deletions examples/ex01_reduced_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
params.pseudopotential["name"] = "Be.pbe-n-rrkjus_psl.1.0.0.UPF"

# This path has to be altered updated with your path.
params.pseudopotential["path"] = "/home/fiedlerl/tools/pslibrary/" \
"pbe/PSEUDOPOTENTIALS/"
params.pseudopotential["path"] = (
"/home/fiedlerl/tools/pslibrary/" "pbe/PSEUDOPOTENTIALS/"
)

# These are technical parameters for DFT and MD.
params.maximum_kpoint_try = 3
Expand All @@ -41,18 +42,19 @@

# Currently, both the crystal structure and LDOS configuration have to be
# provided by the user.
crystal_structure = malada.CrystalStructureProvider(params,
external_cif_file=
"./ex01_inputs/Be_bcc.cif")
crystal_structure = malada.CrystalStructureProvider(
params, external_cif_file="./ex01_inputs/Be_bcc.cif"
)

ldosconvergence = malada.LDOSConvergenceProvider(params,
external_ldos_configuration=
"./ex01_inputs/ldosconf.xml")
ldosconvergence = malada.LDOSConvergenceProvider(
params, external_ldos_configuration="./ex01_inputs/ldosconf.xml"
)

# After defining parameters and important files, the pipeline can be
# instantiated and run.
pipeline = malada.DataPipeline(params,
crystal_structure_provider=crystal_structure,
ldos_configuration_provider=ldosconvergence)
pipeline = malada.DataPipeline(
params,
crystal_structure_provider=crystal_structure,
ldos_configuration_provider=ldosconvergence,
)
pipeline.run()

16 changes: 10 additions & 6 deletions malada/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
Can be used to automate a data acquistion pipeline for MALA.
"""


from .version import __version__
from .utils import Parameters, SlurmParameters
from .providers import CrystalStructureProvider, SuperCellProvider,\
DFTConvergenceProvider, MDPerformanceProvider,\
MDProvider, SnapshotsProvider, LDOSConvergenceProvider,\
DFTProvider
from .providers import (
CrystalStructureProvider,
SuperCellProvider,
DFTConvergenceProvider,
MDPerformanceProvider,
MDProvider,
SnapshotsProvider,
LDOSConvergenceProvider,
DFTProvider,
)
from .pipeline import DataPipeline
from .runners import Runner, BashRunner, RunnerInterface

130 changes: 79 additions & 51 deletions malada/pipeline/pipeline.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
"""Data generation Pipeline."""
from malada import CrystalStructureProvider, SuperCellProvider, \
DFTConvergenceProvider, MDPerformanceProvider, MDProvider, \
SnapshotsProvider, LDOSConvergenceProvider, DFTProvider

from malada import (
CrystalStructureProvider,
SuperCellProvider,
DFTConvergenceProvider,
MDPerformanceProvider,
MDProvider,
SnapshotsProvider,
LDOSConvergenceProvider,
DFTProvider,
)
import os


Expand Down Expand Up @@ -39,50 +47,55 @@ class DataPipeline:
Provider for final DFT calculations and LDOS calculation
"""

def __init__(self, parameters,
crystal_structure_provider: CrystalStructureProvider = None,
supercell_provider: SuperCellProvider = None,
dft_convergence_provider: DFTConvergenceProvider = None,
md_performance_provider: MDPerformanceProvider = None,
md_provider: MDProvider = None,
snapshots_provider: SnapshotsProvider = None,
ldos_configuration_provider: LDOSConvergenceProvider = None,
dft_provider: DFTProvider = None,
):
def __init__(
self,
parameters,
crystal_structure_provider: CrystalStructureProvider = None,
supercell_provider: SuperCellProvider = None,
dft_convergence_provider: DFTConvergenceProvider = None,
md_performance_provider: MDPerformanceProvider = None,
md_provider: MDProvider = None,
snapshots_provider: SnapshotsProvider = None,
ldos_configuration_provider: LDOSConvergenceProvider = None,
dft_provider: DFTProvider = None,
):
self.parameters = parameters

# Create the providers object that were not otherwise specified.
if crystal_structure_provider is None:
self.crystal_structure_provider = \
CrystalStructureProvider(self.parameters)
self.crystal_structure_provider = CrystalStructureProvider(
self.parameters
)
else:
self.crystal_structure_provider = crystal_structure_provider
if supercell_provider is None:
self.supercell_provider = \
SuperCellProvider(self.parameters)
self.supercell_provider = SuperCellProvider(self.parameters)
else:
self.supercell_provider = supercell_provider
if dft_convergence_provider is None:
self.dft_convergence_provider = \
DFTConvergenceProvider(self.parameters)
self.dft_convergence_provider = DFTConvergenceProvider(
self.parameters
)
else:
self.dft_convergence_provider = dft_convergence_provider
if md_performance_provider is None:
self.md_performance_provider = \
MDPerformanceProvider(self.parameters)
self.md_performance_provider = MDPerformanceProvider(
self.parameters
)
else:
self.md_performance_provider = md_performance_provider
if md_provider is None:
self.md_provider = \
MDProvider(self.parameters)
self.md_provider = MDProvider(self.parameters)
else:
self.md_provider = md_provider
if snapshots_provider is None:
self.snapshots_provider = SnapshotsProvider(self.parameters)
else:
self.snapshots_provider = snapshots_provider
if ldos_configuration_provider is None:
self.ldos_configuration_provider = LDOSConvergenceProvider(self.parameters)
self.ldos_configuration_provider = LDOSConvergenceProvider(
self.parameters
)
else:
self.ldos_configuration_provider = ldos_configuration_provider
if dft_provider is None:
Expand All @@ -94,8 +107,9 @@ def run(self):
"""Run a full data generation pipeline."""
# Step one: Get the crystal structure.
print("Getting the crystal structure...")
path00 = os.path.join(self.parameters.base_folder,
"00_crystal_structure")
path00 = os.path.join(
self.parameters.base_folder, "00_crystal_structure"
)
if not os.path.exists(path00):
os.makedirs(path00)
self.crystal_structure_provider.provide(path00)
Expand All @@ -104,70 +118,84 @@ def run(self):

# Step two: Build the supercell.
print("Building supercell...")
path01 = os.path.join(self.parameters.base_folder,
"01_supercell")
path01 = os.path.join(self.parameters.base_folder, "01_supercell")
if not os.path.exists(path01):
os.makedirs(path01)
self.supercell_provider.provide(path01, self.crystal_structure_provider.cif_file)
self.supercell_provider.provide(
path01, self.crystal_structure_provider.cif_file
)
print("Building supercell: Done.")

# Step three: Converge DFT parameters.
print("Converging DFT parameters...")
path02 = os.path.join(self.parameters.base_folder, "02_dft_convergence")
path02 = os.path.join(
self.parameters.base_folder, "02_dft_convergence"
)
if not os.path.exists(path02):
os.makedirs(path02)
self.dft_convergence_provider.provide(path02,
self.supercell_provider.supercell_file)
self.dft_convergence_provider.provide(
path02, self.supercell_provider.supercell_file
)
print("Converging DFT parameters: Done.")

# Step four: Get optimal MD run parameters.
print("Testing MD performance...")
path03 = os.path.join(self.parameters.base_folder, "03_md_performance")
if not os.path.exists(path03):
os.makedirs(path03)
self.md_performance_provider.provide(path03,
self.dft_convergence_provider.
convergence_results_file)
self.md_performance_provider.provide(
path03, self.dft_convergence_provider.convergence_results_file
)
print("Testing MD performance: Done.")

# Step five: Get/Calculate a MD trajectory.
print("Getting MD trajectory...")
path04 = os.path.join(self.parameters.base_folder, "04_md")
if not os.path.exists(path04):
os.makedirs(path04)
self.md_provider.provide(path04, self.supercell_provider.supercell_file,
self.dft_convergence_provider.
convergence_results_file, self.
md_performance_provider.md_performance_xml)
self.md_provider.provide(
path04,
self.supercell_provider.supercell_file,
self.dft_convergence_provider.convergence_results_file,
self.md_performance_provider.md_performance_xml,
)
print("Getting MD trajectory: Done.")

# Step six: Parsing MD trajectory for snapshots.
print("Parsing snapshots from MD trajectory...")
path05 = os.path.join(self.parameters.base_folder, "05_snapshots")
if not os.path.exists(path05):
os.makedirs(path05)
self.snapshots_provider.provide(path05,
self.md_provider.trajectory_file,
self.md_provider.temperature_file)
self.snapshots_provider.provide(
path05,
self.md_provider.trajectory_file,
self.md_provider.temperature_file,
)
print("Parsing snapshots from MD trajectory: Done.")

# Step seven: Determining the LDOS parameters.
print("Determining LDOS parameters...")
path06 = os.path.join(self.parameters.base_folder, "06_ldosconfiguration")
path06 = os.path.join(
self.parameters.base_folder, "06_ldosconfiguration"
)
if not os.path.exists(path06):
os.makedirs(path06)
self.ldos_configuration_provider.provide(path06,
self.snapshots_provider.snapshot_file,
self.dft_convergence_provider.convergence_results_file)
self.ldos_configuration_provider.provide(
path06,
self.snapshots_provider.snapshot_file,
self.dft_convergence_provider.convergence_results_file,
)
print("Determining LDOS parameters: Done.")

# Step eight (final step): Perfroming the necessary DFT calculations.
print("Performing DFT calculation...")
path07 = os.path.join(self.parameters.base_folder,
"07_dft")
path07 = os.path.join(self.parameters.base_folder, "07_dft")
if not os.path.exists(path07):
os.makedirs(path07)
self.dft_provider.provide(path07,self.dft_convergence_provider.convergence_results_file,
self.ldos_configuration_provider.ldos_configuration_file,
self.snapshots_provider.snapshot_file)
self.dft_provider.provide(
path07,
self.dft_convergence_provider.convergence_results_file,
self.ldos_configuration_provider.ldos_configuration_file,
self.snapshots_provider.snapshot_file,
)
print("Performing DFT calculation: Done.")
16 changes: 11 additions & 5 deletions malada/providers/crystalstructure.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Provider for crystal structures."""

from .provider import Provider
import os
from shutil import copyfile
Expand Down Expand Up @@ -35,12 +36,17 @@ def provide(self, provider_path):
provider_path : string
Path in which to operate in.
"""
file_name = self.parameters.element + \
"_" + self.parameters.crystal_structure + ".cif"
self.cif_file = os.path.join(provider_path,file_name)
file_name = (
self.parameters.element
+ "_"
+ self.parameters.crystal_structure
+ ".cif"
)
self.cif_file = os.path.join(provider_path, file_name)
if self.external_cif_file is None:
raise Exception("Currently there is no way to provide a cif file"
"on the fly.")
raise Exception(
"Currently there is no way to provide a cif file" "on the fly."
)
else:

copyfile(self.external_cif_file, self.cif_file)
Expand Down
Loading

0 comments on commit ba66435

Please sign in to comment.