A set of classes to provide a more pythonic API.
This class-based API should not be used in parallel with the functional API, as it could lead to unintuitive behaviour and therefore bugs.
TODO:
[x] state
[x] log
[x] io
[ ] eigenmodes/ema
[ ] geometry
[ ] hamiltonian
[ ] reaction coordinates, interpolated E and Rx
[ ] docstrings for enums, classes and methods
Usage examples:
import os
import sys
# spirit_py_dir = os.path.dirname(os.path.realpath(__file__))
spirit_py_dir = os.path.abspath(os.path.join(os.path.dirname( __file__ ), ".."))
sys.path.insert(0, spirit_py_dir)
from spirit import constants
from spirit import version
from spirit.wrapper import State, SolverKind, LogLevel
if __name__ == '__main__':
state = State(configfile="input/input.cfg")
# Set some logging parameters
state.log.console_level = LogLevel.info
state.log.output_file_tag = 'new_state'
state.log.output_folder = 'output'
# print("level", state.log.console_level)
# Set the orientations by hand
spins = state.active_image.directions
spins[:] = [0, 0, 1]
spins.shape = (20, 20, 1, 3)
spins[48:52, 48:52, :] = [0, 0, -1]
# Use a pre-built setter
state.systems[0].set_configuration.skyrmion(r=10.0)
state.active_image.write_file("input/testimage.ovf")
# The chain is easily resized
state.systems.resize(10)
# Also by list manipulations
state.systems[9].set_configuration.plus_z()
state.systems.append(state.systems[9])
state.systems.write_file("input/testchain_first.ovf")
# Parameters can be accessed through the systems:
state.systems[2].parameters.llg.dt = 0.01
# Groups of parameters can be set from a dict:
for image in state.systems:
# image.parameters.llg.dt = 0.001
# image.parameters.llg.output_tag = "new_state"
image.parameters.llg.set({
'dt': 0.001,
'output_tag': 'new_state' })
# Chain-wide parameters are accessed through state.parameters
# state.parameters.gneb.spring_force = 0.5
state.parameters.gneb.set(
{
'dt': 0.001,
'spring_force': 0.5,
'output_tag': 'new_state'
})
# Logging is easy, by default messages go to 'All'
state.log(">>>>>> Message to all")
state.log(">>>>>> Error message", level=LogLevel.error)
if state.log.n_errors > 0:
state.log("this is intolerable!", level=LogLevel.severe)
# calc = state.calculate.gneb(n_iterations=100000)
# calc.start()
# For pre-defined output etc, use:
# state.calculate.llg(iterations=100)
# To customise what happens after each iteration, use:
# for i in state.calculation_llg(0, iterations=100):
# print(f'iteration {i}')
# if i > 10: break
# If you call a calculation, it is executed immediately
# state.calculation_llg()
# You can also assign a calculation and use it later
# calc = state.systems[0].calculation.llg(n_iterations=100)
# # calc.start() # Maybe you want to do this asynchronously
# # calc.stop() # And stop it asynchronously on some event
# calc() # Or you run it like so
# # You can also iterate over a calculation manually
# for i in state.calculation_llg(n_iterations=100):
# print(f'iteration {i}')
# for i in calc:
# print(f'iteration {i}')
# if i >= 10: break
state.systems[0].calculation.llg(solver=SolverKind.sib, n_iterations=1000000).start()
# for i in state.systems[0].calculation.llg(solver=SolverKind.sib):
# if i >= 10: break
state.systems[-1].calculation.llg(solver=SolverKind.vp, n_iterations=200).start()
state.systems.interpolate()
state.systems.write_file("input/testchain_second.ovf")
state.calculation.gneb(solver=SolverKind.vp, n_iterations=200).start()
state.systems.write_file("input/testchain_relaxed.ovf")
state.log(f'Topological charge of first image: {state.systems[0].topological_charge()}')
idx_image_minimum = 0
idx_image_sp = 10
htst_result = state.calculation.htst(idx_image_minimum, idx_image_sp, n_eigenmodes_keep=-1)
state.log("------------------------")
state.log(f"exponent = {htst_result.temperature_exponent}")
state.log(f"volume_min = {htst_result.volume_min}")
state.log(f"volume_sp = {htst_result.volume_sp}")
eigval_min = htst_result.eigenvalues_min
eigvec_min = htst_result.eigenvectors_min
eigval_sp = htst_result.eigenvalues_sp
eigvec_sp = htst_result.eigenvectors_sp
velocities = htst_result.velocities
print(eigval_min)
print(eigvec_min)
Coverage remained the same at 79.423% when pulling 0c3c99485a5aab166b0e917328e631e29ef78126 on feature-pythonic-api into 55cc299074d9947a3838d47c31e41f1a1ea691ba on develop.
Note: this API requires Python3
A set of classes to provide a more pythonic API. This class-based API should not be used in parallel with the functional API, as it could lead to unintuitive behaviour and therefore bugs.
TODO:
Usage examples: