llg3d 2.0.1__py3-none-any.whl → 3.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- llg3d/__init__.py +2 -4
- llg3d/benchmarks/__init__.py +1 -0
- llg3d/benchmarks/compare_commits.py +321 -0
- llg3d/benchmarks/efficiency.py +451 -0
- llg3d/benchmarks/utils.py +25 -0
- llg3d/element.py +98 -17
- llg3d/grid.py +48 -58
- llg3d/io.py +395 -0
- llg3d/main.py +32 -35
- llg3d/parameters.py +159 -49
- llg3d/post/__init__.py +1 -1
- llg3d/post/extract.py +112 -0
- llg3d/post/info.py +192 -0
- llg3d/post/m1_vs_T.py +107 -0
- llg3d/post/m1_vs_time.py +81 -0
- llg3d/post/process.py +87 -85
- llg3d/post/utils.py +38 -0
- llg3d/post/x_profiles.py +161 -0
- llg3d/py.typed +1 -0
- llg3d/solvers/__init__.py +153 -0
- llg3d/solvers/base.py +345 -0
- llg3d/solvers/experimental/__init__.py +9 -0
- llg3d/{solver → solvers/experimental}/jax.py +117 -143
- llg3d/solvers/math_utils.py +41 -0
- llg3d/solvers/mpi.py +370 -0
- llg3d/solvers/numpy.py +126 -0
- llg3d/solvers/opencl.py +439 -0
- llg3d/solvers/profiling.py +38 -0
- {llg3d-2.0.1.dist-info → llg3d-3.1.0.dist-info}/METADATA +5 -2
- llg3d-3.1.0.dist-info/RECORD +36 -0
- {llg3d-2.0.1.dist-info → llg3d-3.1.0.dist-info}/WHEEL +1 -1
- llg3d-3.1.0.dist-info/entry_points.txt +9 -0
- llg3d/output.py +0 -107
- llg3d/post/plot_results.py +0 -61
- llg3d/post/temperature.py +0 -76
- llg3d/simulation.py +0 -95
- llg3d/solver/__init__.py +0 -45
- llg3d/solver/mpi.py +0 -450
- llg3d/solver/numpy.py +0 -207
- llg3d/solver/opencl.py +0 -330
- llg3d/solver/solver.py +0 -89
- llg3d-2.0.1.dist-info/RECORD +0 -25
- llg3d-2.0.1.dist-info/entry_points.txt +0 -4
- {llg3d-2.0.1.dist-info → llg3d-3.1.0.dist-info}/licenses/AUTHORS +0 -0
- {llg3d-2.0.1.dist-info → llg3d-3.1.0.dist-info}/licenses/LICENSE +0 -0
- {llg3d-2.0.1.dist-info → llg3d-3.1.0.dist-info}/top_level.txt +0 -0
llg3d/post/plot_results.py
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Plot 1D curves from several files.
|
|
3
|
-
|
|
4
|
-
Usage:
|
|
5
|
-
|
|
6
|
-
python plot_results.py file1.txt
|
|
7
|
-
or
|
|
8
|
-
python plot_results.py file1.txt file2.txt file3.txt
|
|
9
|
-
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import argparse
|
|
13
|
-
from matplotlib import pyplot as plt
|
|
14
|
-
import numpy as np
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
DEFAULT_OUTPUT_FILE = "results.png"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def plot(*files: tuple[str], output_file: str = DEFAULT_OUTPUT_FILE):
|
|
21
|
-
"""
|
|
22
|
-
Plot the results from the given files.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
files (tuple[str]): Paths to the result files.
|
|
26
|
-
output_file (str): Path to the output image file.
|
|
27
|
-
"""
|
|
28
|
-
fig, ax = plt.subplots()
|
|
29
|
-
for file in files:
|
|
30
|
-
if not file.endswith(".txt"):
|
|
31
|
-
raise ValueError(f"File {file} does not end with .txt")
|
|
32
|
-
data = np.loadtxt(file)
|
|
33
|
-
ax.plot(data[:, 0], data[:, 1], label=file)
|
|
34
|
-
|
|
35
|
-
ax.set_xlabel("time")
|
|
36
|
-
ax.set_ylabel(r"$<m_1>$")
|
|
37
|
-
ax.legend()
|
|
38
|
-
ax.set_title(r"Space average of $m_1$ according to time")
|
|
39
|
-
fig.savefig(output_file)
|
|
40
|
-
print(f"Written to {output_file}")
|
|
41
|
-
plt.show()
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def main():
|
|
45
|
-
"""Main function to parse arguments and call the plot function."""
|
|
46
|
-
parser = argparse.ArgumentParser(description="Plot results from one or more files.")
|
|
47
|
-
parser.add_argument("files", nargs="+", type=str, help="Path to the result files.")
|
|
48
|
-
parser.add_argument(
|
|
49
|
-
"--output",
|
|
50
|
-
"-o",
|
|
51
|
-
type=str,
|
|
52
|
-
default=DEFAULT_OUTPUT_FILE,
|
|
53
|
-
help=f"Path to the output image file (default: {DEFAULT_OUTPUT_FILE}).",
|
|
54
|
-
)
|
|
55
|
-
args = parser.parse_args()
|
|
56
|
-
|
|
57
|
-
plot(*args.files, output_file=args.output)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if __name__ == "__main__":
|
|
61
|
-
main()
|
llg3d/post/temperature.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Plot the magnetization vs temperature and determine the Curie temperature."""
|
|
3
|
-
|
|
4
|
-
import argparse
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
|
|
7
|
-
import matplotlib.pyplot as plt
|
|
8
|
-
|
|
9
|
-
from .process import MagData
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def plot_m_vs_T(m: MagData, show: bool):
|
|
13
|
-
"""
|
|
14
|
-
Plots the data (T, <m>).
|
|
15
|
-
|
|
16
|
-
Interpolates the values, calculates the Curie temperature, exports to PNG.
|
|
17
|
-
|
|
18
|
-
Args:
|
|
19
|
-
m: Magnetization data object
|
|
20
|
-
show: display the graph in a graphical window
|
|
21
|
-
"""
|
|
22
|
-
print(f"T_Curie = {m.T_Curie:.0f} K")
|
|
23
|
-
|
|
24
|
-
fig, ax = plt.subplots()
|
|
25
|
-
fig.suptitle("Average magnetization vs Temperature")
|
|
26
|
-
params = m.run["params"]
|
|
27
|
-
ax.set_title(
|
|
28
|
-
params["element"]
|
|
29
|
-
+ rf", ${params['Jx']}\times{params['Jy']}\times{params['Jz']}$"
|
|
30
|
-
rf" ($dx = ${params['dx']})",
|
|
31
|
-
fontdict={"size": 10},
|
|
32
|
-
)
|
|
33
|
-
ax.plot(m.temperature, m.m1_mean, "o", label="computed")
|
|
34
|
-
ax.plot(m.T, m.interp(m.T), label="interpolated (cubic)")
|
|
35
|
-
ax.annotate(
|
|
36
|
-
"$T_{{Curie}} = {:.0f} K$".format(m.T_Curie),
|
|
37
|
-
xy=(m.T_Curie, m.interp(m.T_Curie)),
|
|
38
|
-
xytext=(m.T_Curie + 20, m.interp(m.T_Curie) + 0.01),
|
|
39
|
-
)
|
|
40
|
-
ax.axvline(x=m.T_Curie, color="k")
|
|
41
|
-
ax.set_xlabel("Temperature [K]")
|
|
42
|
-
ax.set_ylabel("Magnetization")
|
|
43
|
-
ax.legend()
|
|
44
|
-
|
|
45
|
-
if show:
|
|
46
|
-
plt.show()
|
|
47
|
-
|
|
48
|
-
image_filename = m.parentpath / "m1_mean.png"
|
|
49
|
-
fig.savefig(image_filename)
|
|
50
|
-
print(f"Image saved in {image_filename}")
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def main():
|
|
54
|
-
"""Parses the command line to execute processing functions."""
|
|
55
|
-
parser = argparse.ArgumentParser(description=__doc__)
|
|
56
|
-
parser.add_argument("--job_dir", type=Path, help="Slurm main job directory")
|
|
57
|
-
parser.add_argument(
|
|
58
|
-
"--run_file", type=Path, default="run.json", help="Path to the run.json file"
|
|
59
|
-
)
|
|
60
|
-
parser.add_argument(
|
|
61
|
-
"-s",
|
|
62
|
-
"--show",
|
|
63
|
-
action="store_true",
|
|
64
|
-
default=False,
|
|
65
|
-
help="Display the graph in a graphical window",
|
|
66
|
-
)
|
|
67
|
-
args = parser.parse_args()
|
|
68
|
-
if args.job_dir:
|
|
69
|
-
m = MagData(job_dir=args.job_dir)
|
|
70
|
-
else:
|
|
71
|
-
m = MagData(run_file=args.run_file)
|
|
72
|
-
plot_m_vs_T(m, args.show)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if __name__ == "__main__":
|
|
76
|
-
main()
|
llg3d/simulation.py
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Define the Simulation class.
|
|
3
|
-
|
|
4
|
-
Example usage:
|
|
5
|
-
|
|
6
|
-
>>> from llg3d.main import Simulation
|
|
7
|
-
>>> from llg3d.parameters import parameters
|
|
8
|
-
>>> run_parameters = {name: value["default"] for name, value in parameters.items()}
|
|
9
|
-
>>> sim = Simulation(run_parameters)
|
|
10
|
-
>>> sim.run()
|
|
11
|
-
>>> sim.save()
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
import inspect
|
|
16
|
-
|
|
17
|
-
from . import rank, size
|
|
18
|
-
from .element import get_element_class
|
|
19
|
-
from .parameters import Parameter
|
|
20
|
-
from .output import write_json
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class Simulation:
|
|
24
|
-
"""
|
|
25
|
-
Class to encapsulate the simulation logic.
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
params: Dictionary of simulation parameters.
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
json_file = "run.json" #: JSON file to store the results
|
|
32
|
-
|
|
33
|
-
def __init__(self, params: dict[str, Parameter]):
|
|
34
|
-
self.params: dict[str, Parameter] = params.copy() #: simulation parameters
|
|
35
|
-
self.simulate: callable = self._get_simulate_function_from_name(
|
|
36
|
-
self.params["solver"]
|
|
37
|
-
) #: simulation function imported from the solver module
|
|
38
|
-
self.total_time: None | float = None #: total simulation time
|
|
39
|
-
self.filenames: list[str] = [] #: list of output filenames
|
|
40
|
-
self.m1_mean: None | float = None #: space and time average of m1
|
|
41
|
-
self.params["np"] = size # Add a parameter for the number of processes
|
|
42
|
-
# Reference the element class from the element string
|
|
43
|
-
self.params["element_class"] = get_element_class(params["element"])
|
|
44
|
-
|
|
45
|
-
def run(self):
|
|
46
|
-
"""Runs the simulation and store the results."""
|
|
47
|
-
self.total_time, self.filenames, self.m1_mean = self.simulate(**self.params)
|
|
48
|
-
|
|
49
|
-
def _get_simulate_function_from_name(self, name: str) -> callable:
|
|
50
|
-
"""
|
|
51
|
-
Retrieves the simulation function for a given solver name.
|
|
52
|
-
|
|
53
|
-
Args:
|
|
54
|
-
name: Name of the solver
|
|
55
|
-
|
|
56
|
-
Returns:
|
|
57
|
-
callable: The simulation function
|
|
58
|
-
|
|
59
|
-
Example:
|
|
60
|
-
>>> simulate = self.get_simulate_function_from_name("mpi")
|
|
61
|
-
|
|
62
|
-
Will return the `simulate` function from the `llg3d.solver.mpi` module.
|
|
63
|
-
"""
|
|
64
|
-
module = __import__(f"llg3d.solver.{name}", fromlist=["simulate"])
|
|
65
|
-
return inspect.getattr_static(module, "simulate")
|
|
66
|
-
|
|
67
|
-
def save(self):
|
|
68
|
-
"""Saves the results of the simulation to a JSON file."""
|
|
69
|
-
params = self.params.copy() # save the parameters
|
|
70
|
-
del params["element_class"] # remove class object before serialization
|
|
71
|
-
if rank == 0:
|
|
72
|
-
results = {"total_time": self.total_time}
|
|
73
|
-
# Export the integral of m1
|
|
74
|
-
if len(self.filenames) > 0:
|
|
75
|
-
results["integral_file"] = self.filenames[0]
|
|
76
|
-
print(f"Integral of m1 in {self.filenames[0]}")
|
|
77
|
-
# Export the x-profiles of m1, m2 and m3
|
|
78
|
-
for i, filename in enumerate(self.filenames[1:]):
|
|
79
|
-
results[f"xprofile_m{i}"] = filename
|
|
80
|
-
print(f"x-profile of m{i} in {filename}")
|
|
81
|
-
|
|
82
|
-
print(
|
|
83
|
-
f"""\
|
|
84
|
-
N iterations = {params["N"]}
|
|
85
|
-
total_time [s] = {self.total_time:.03f}
|
|
86
|
-
time/ite [s/iter] = {self.total_time / params["N"]:.03e}\
|
|
87
|
-
"""
|
|
88
|
-
)
|
|
89
|
-
# Export the mean of m1
|
|
90
|
-
if params["N"] > params["start_averaging"]:
|
|
91
|
-
print(f"m1_mean = {self.m1_mean:e}")
|
|
92
|
-
results["m1_mean"] = float(self.m1_mean)
|
|
93
|
-
|
|
94
|
-
write_json(self.json_file, {"params": params, "results": results})
|
|
95
|
-
print(f"Summary in {self.json_file}")
|
llg3d/solver/__init__.py
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Solver module for LLG3D.
|
|
3
|
-
|
|
4
|
-
This module contains different solver implementations.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import importlib.util
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
__all__ = ["numpy", "solver", "rank", "size", "comm", "status"]
|
|
11
|
-
|
|
12
|
-
LIB_AVAILABLE: dict[str, bool] = {}
|
|
13
|
-
|
|
14
|
-
# Check for other solver availability
|
|
15
|
-
for lib in "opencl", "jax", "mpi4py":
|
|
16
|
-
if importlib.util.find_spec(lib, package=__package__) is not None:
|
|
17
|
-
LIB_AVAILABLE[lib] = True
|
|
18
|
-
__all__.append(lib)
|
|
19
|
-
else:
|
|
20
|
-
LIB_AVAILABLE[lib] = False
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# MPI utilities
|
|
24
|
-
if LIB_AVAILABLE["mpi4py"]:
|
|
25
|
-
from mpi4py import MPI
|
|
26
|
-
|
|
27
|
-
comm = MPI.COMM_WORLD
|
|
28
|
-
rank = comm.Get_rank()
|
|
29
|
-
size = comm.Get_size()
|
|
30
|
-
status = MPI.Status()
|
|
31
|
-
else:
|
|
32
|
-
# MPI library is not available: use dummy values
|
|
33
|
-
class DummyComm:
|
|
34
|
-
pass
|
|
35
|
-
|
|
36
|
-
comm = DummyComm()
|
|
37
|
-
rank = 0
|
|
38
|
-
size = 1
|
|
39
|
-
|
|
40
|
-
class DummyStatus:
|
|
41
|
-
pass
|
|
42
|
-
|
|
43
|
-
status = DummyStatus()
|
|
44
|
-
|
|
45
|
-
from . import numpy, solver # noqa: E402
|