nomad-schema-plugin-simulation-workflow 1.0.1__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.
- nomad_schema_plugin_simulation_workflow-1.0.1.dist-info/LICENSE +202 -0
- nomad_schema_plugin_simulation_workflow-1.0.1.dist-info/METADATA +17 -0
- nomad_schema_plugin_simulation_workflow-1.0.1.dist-info/RECORD +22 -0
- nomad_schema_plugin_simulation_workflow-1.0.1.dist-info/WHEEL +5 -0
- nomad_schema_plugin_simulation_workflow-1.0.1.dist-info/entry_points.txt +2 -0
- nomad_schema_plugin_simulation_workflow-1.0.1.dist-info/top_level.txt +1 -0
- simulationworkflowschema/__init__.py +118 -0
- simulationworkflowschema/chemical_reaction.py +167 -0
- simulationworkflowschema/dmft.py +84 -0
- simulationworkflowschema/elastic.py +494 -0
- simulationworkflowschema/equation_of_state.py +213 -0
- simulationworkflowschema/general.py +505 -0
- simulationworkflowschema/geometry_optimization.py +349 -0
- simulationworkflowschema/gw.py +69 -0
- simulationworkflowschema/max_ent.py +80 -0
- simulationworkflowschema/molecular_dynamics.py +2601 -0
- simulationworkflowschema/phonon.py +196 -0
- simulationworkflowschema/photon_polarization.py +75 -0
- simulationworkflowschema/single_point.py +273 -0
- simulationworkflowschema/tb.py +77 -0
- simulationworkflowschema/thermodynamics.py +375 -0
- simulationworkflowschema/xs.py +100 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright The NOMAD Authors.
|
|
3
|
+
#
|
|
4
|
+
# This file is part of NOMAD. See https://nomad-lab.eu for further info.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
from nomad.metainfo import SubSection, Quantity, Reference
|
|
21
|
+
from nomad.datamodel.metainfo.workflow import Link
|
|
22
|
+
from runschema.calculation import Dos, BandStructure
|
|
23
|
+
from .general import (
|
|
24
|
+
ParallelSimulation,
|
|
25
|
+
SimulationWorkflowMethod,
|
|
26
|
+
SimulationWorkflowResults,
|
|
27
|
+
WORKFLOW_METHOD_NAME,
|
|
28
|
+
WORKFLOW_RESULTS_NAME,
|
|
29
|
+
)
|
|
30
|
+
from .thermodynamics import ThermodynamicsResults
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class PhononMethod(SimulationWorkflowMethod):
|
|
34
|
+
force_calculator = Quantity(
|
|
35
|
+
type=str,
|
|
36
|
+
shape=[],
|
|
37
|
+
description="""
|
|
38
|
+
Name of the program used to calculate the forces.
|
|
39
|
+
""",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
mesh_density = Quantity(
|
|
43
|
+
type=np.float64,
|
|
44
|
+
shape=[],
|
|
45
|
+
unit='1 / meter ** 3',
|
|
46
|
+
description="""
|
|
47
|
+
Density of the k-mesh for sampling.
|
|
48
|
+
""",
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
random_displacements = Quantity(
|
|
52
|
+
type=bool,
|
|
53
|
+
shape=[],
|
|
54
|
+
description="""
|
|
55
|
+
Identifies if displacements are made randomly.
|
|
56
|
+
""",
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
with_non_analytic_correction = Quantity(
|
|
60
|
+
type=bool,
|
|
61
|
+
shape=[],
|
|
62
|
+
description="""
|
|
63
|
+
Identifies if non-analytical term corrections are applied to dynamical matrix.
|
|
64
|
+
""",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
with_grueneisen_parameters = Quantity(
|
|
68
|
+
type=bool,
|
|
69
|
+
shape=[],
|
|
70
|
+
description="""
|
|
71
|
+
Identifies if Grueneisen parameters are calculated.
|
|
72
|
+
""",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class PhononResults(ThermodynamicsResults):
|
|
77
|
+
n_imaginary_frequencies = Quantity(
|
|
78
|
+
type=int,
|
|
79
|
+
shape=[],
|
|
80
|
+
description="""
|
|
81
|
+
Number of modes with imaginary frequencies.
|
|
82
|
+
""",
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
n_bands = Quantity(
|
|
86
|
+
type=np.int32,
|
|
87
|
+
shape=[],
|
|
88
|
+
description="""
|
|
89
|
+
Number of phonon bands.
|
|
90
|
+
""",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
n_qpoints = Quantity(
|
|
94
|
+
type=np.int32,
|
|
95
|
+
shape=[],
|
|
96
|
+
description="""
|
|
97
|
+
Number of q points for which phonon properties are evaluated.
|
|
98
|
+
""",
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
qpoints = Quantity(
|
|
102
|
+
type=np.float64,
|
|
103
|
+
shape=['n_qpoints', 3],
|
|
104
|
+
description="""
|
|
105
|
+
Value of the qpoints.
|
|
106
|
+
""",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
group_velocity = Quantity(
|
|
110
|
+
type=np.float64,
|
|
111
|
+
shape=['n_qpoints', 'n_bands', 3],
|
|
112
|
+
unit='meter / second',
|
|
113
|
+
description="""
|
|
114
|
+
Calculated value of the group velocity at each qpoint.
|
|
115
|
+
""",
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
n_displacements = Quantity(
|
|
119
|
+
type=np.int32,
|
|
120
|
+
shape=[],
|
|
121
|
+
description="""
|
|
122
|
+
Number of independent displacements.
|
|
123
|
+
""",
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
n_atoms = Quantity(
|
|
127
|
+
type=np.int32,
|
|
128
|
+
shape=[],
|
|
129
|
+
description="""
|
|
130
|
+
Number of atoms in the simulation cell.
|
|
131
|
+
""",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
displacements = Quantity(
|
|
135
|
+
type=np.float64,
|
|
136
|
+
shape=['n_displacements', 'n_atoms', 3],
|
|
137
|
+
unit='meter',
|
|
138
|
+
description="""
|
|
139
|
+
Value of the displacements applied to each atom in the simulation cell.
|
|
140
|
+
""",
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
dos = Quantity(
|
|
144
|
+
type=Reference(Dos),
|
|
145
|
+
shape=['n_data'],
|
|
146
|
+
description="""
|
|
147
|
+
Reference to the electronic density of states data.
|
|
148
|
+
""",
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
band_structure = Quantity(
|
|
152
|
+
type=Reference(BandStructure),
|
|
153
|
+
shape=['n_data'],
|
|
154
|
+
description="""
|
|
155
|
+
Reference to the electronic band structure data.
|
|
156
|
+
""",
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class Phonon(ParallelSimulation):
|
|
161
|
+
method = SubSection(sub_section=PhononMethod)
|
|
162
|
+
|
|
163
|
+
results = SubSection(sub_section=PhononResults)
|
|
164
|
+
|
|
165
|
+
def normalize(self, archive, logger):
|
|
166
|
+
super().normalize(archive, logger)
|
|
167
|
+
|
|
168
|
+
if not self._calculations or not self._calculations[0].band_structure_phonon:
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
if not self.method:
|
|
172
|
+
self.method = PhononMethod()
|
|
173
|
+
self.inputs.append(Link(name=WORKFLOW_METHOD_NAME, section=self.method))
|
|
174
|
+
|
|
175
|
+
if not self.results:
|
|
176
|
+
self.results = PhononResults()
|
|
177
|
+
self.outputs.append(Link(name=WORKFLOW_RESULTS_NAME, section=self.results))
|
|
178
|
+
|
|
179
|
+
ThermodynamicsResults.normalize(self.results, archive, logger)
|
|
180
|
+
|
|
181
|
+
last_calc = self._calculations[-1]
|
|
182
|
+
|
|
183
|
+
if not self.results.n_imaginary_frequencies:
|
|
184
|
+
n_imaginary = 0
|
|
185
|
+
for band_segment in last_calc.band_structure_phonon[-1].segment:
|
|
186
|
+
freq = band_segment.energies.magnitude
|
|
187
|
+
n_imaginary += np.count_nonzero(np.array(freq) < 0)
|
|
188
|
+
self.results.n_imaginary_frequencies = n_imaginary
|
|
189
|
+
|
|
190
|
+
SimulationWorkflowResults.normalize(self.results, archive, logger)
|
|
191
|
+
|
|
192
|
+
if not self.results.dos:
|
|
193
|
+
self.results.dos = last_calc.dos_phonon
|
|
194
|
+
|
|
195
|
+
if not self.results.band_structure:
|
|
196
|
+
self.results.band_structure = last_calc.band_structure_phonon
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright The NOMAD Authors.
|
|
3
|
+
#
|
|
4
|
+
# This file is part of NOMAD. See https://nomad-lab.eu for further info.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
from nomad.metainfo import SubSection, Quantity, Reference
|
|
21
|
+
from runschema.method import BSE as BSEMethodology
|
|
22
|
+
from runschema.calculation import Spectra
|
|
23
|
+
from .general import (
|
|
24
|
+
SimulationWorkflowResults,
|
|
25
|
+
SimulationWorkflowMethod,
|
|
26
|
+
ParallelSimulation,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class PhotonPolarizationResults(SimulationWorkflowResults):
|
|
31
|
+
"""Groups all polarization outputs: spectrum."""
|
|
32
|
+
|
|
33
|
+
n_polarizations = Quantity(
|
|
34
|
+
type=np.int32,
|
|
35
|
+
description="""
|
|
36
|
+
Number of polarizations for the phonons used for the calculations.
|
|
37
|
+
""",
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
spectrum_polarization = Quantity(
|
|
41
|
+
type=Reference(Spectra),
|
|
42
|
+
shape=['n_polarizations'],
|
|
43
|
+
description="""
|
|
44
|
+
Spectrum for a given polarization of the photon.
|
|
45
|
+
""",
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class PhotonPolarizationMethod(SimulationWorkflowMethod):
|
|
50
|
+
"""Defines the full macroscopic dielectric tensor methodology: BSE method reference."""
|
|
51
|
+
|
|
52
|
+
# TODO add TDDFT methodology reference.
|
|
53
|
+
|
|
54
|
+
bse_method_ref = Quantity(
|
|
55
|
+
type=Reference(BSEMethodology),
|
|
56
|
+
description="""
|
|
57
|
+
BSE methodology reference.
|
|
58
|
+
""",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class PhotonPolarization(ParallelSimulation):
|
|
63
|
+
"""The PhotonPolarization workflow is generated in an extra EntryArchive FOR all polarization
|
|
64
|
+
EntryArchives present in the upload. It groups them for a set of given method parameters.
|
|
65
|
+
|
|
66
|
+
This entry is also recognized as the full macroscopic dielectric tensor entry (e.g. calculated
|
|
67
|
+
via BSE).
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
method = SubSection(sub_section=PhotonPolarizationMethod)
|
|
71
|
+
|
|
72
|
+
results = SubSection(sub_section=PhotonPolarizationResults)
|
|
73
|
+
|
|
74
|
+
def normalize(self, archive, logger):
|
|
75
|
+
super().normalize(archive, logger)
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright The NOMAD Authors.
|
|
3
|
+
#
|
|
4
|
+
# This file is part of NOMAD. See https://nomad-lab.eu for further info.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
from nomad.metainfo import SubSection, Quantity, Reference
|
|
21
|
+
from nomad.datamodel.metainfo.workflow import Link, Task
|
|
22
|
+
from runschema.calculation import (
|
|
23
|
+
Dos,
|
|
24
|
+
BandStructure,
|
|
25
|
+
BandEnergies,
|
|
26
|
+
Density,
|
|
27
|
+
Potential,
|
|
28
|
+
Spectra,
|
|
29
|
+
)
|
|
30
|
+
from .general import (
|
|
31
|
+
SimulationWorkflowResults,
|
|
32
|
+
SimulationWorkflowMethod,
|
|
33
|
+
SimulationWorkflow,
|
|
34
|
+
INPUT_SYSTEM_NAME,
|
|
35
|
+
INPUT_METHOD_NAME,
|
|
36
|
+
OUTPUT_CALCULATION_NAME,
|
|
37
|
+
WORKFLOW_METHOD_NAME,
|
|
38
|
+
WORKFLOW_RESULTS_NAME,
|
|
39
|
+
resolve_difference,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class SinglePointResults(SimulationWorkflowResults):
|
|
44
|
+
n_scf_steps = Quantity(
|
|
45
|
+
type=int,
|
|
46
|
+
shape=[],
|
|
47
|
+
description="""
|
|
48
|
+
Number of self-consistent steps in the calculation.
|
|
49
|
+
""",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
final_scf_energy_difference = Quantity(
|
|
53
|
+
type=np.float64,
|
|
54
|
+
shape=[],
|
|
55
|
+
unit='joule',
|
|
56
|
+
description="""
|
|
57
|
+
The difference in the energy between the last two scf steps.
|
|
58
|
+
""",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
is_converged = Quantity(
|
|
62
|
+
type=bool,
|
|
63
|
+
shape=[],
|
|
64
|
+
description="""
|
|
65
|
+
Indicates if the convergence criteria were fullfilled.
|
|
66
|
+
""",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
n_data = Quantity(
|
|
70
|
+
type=np.int32,
|
|
71
|
+
shape=[],
|
|
72
|
+
description="""
|
|
73
|
+
""",
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
dos = Quantity(
|
|
77
|
+
type=Reference(Dos),
|
|
78
|
+
shape=['n_data'],
|
|
79
|
+
description="""
|
|
80
|
+
Reference to the electronic density of states data.
|
|
81
|
+
""",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
band_structure = Quantity(
|
|
85
|
+
type=Reference(BandStructure),
|
|
86
|
+
shape=['n_data'],
|
|
87
|
+
description="""
|
|
88
|
+
Reference to the electronic band structure data.
|
|
89
|
+
""",
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
eigenvalues = Quantity(
|
|
93
|
+
type=Reference(BandEnergies),
|
|
94
|
+
shape=['n_data'],
|
|
95
|
+
description="""
|
|
96
|
+
Reference to the eigenvalues.
|
|
97
|
+
""",
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
potential = Quantity(
|
|
101
|
+
type=Reference(Potential),
|
|
102
|
+
shape=['n_data'],
|
|
103
|
+
description="""
|
|
104
|
+
Reference to the potential data.
|
|
105
|
+
""",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
density_charge = Quantity(
|
|
109
|
+
type=Reference(Density),
|
|
110
|
+
shape=['n_data'],
|
|
111
|
+
description="""
|
|
112
|
+
Reference to the charge density data.
|
|
113
|
+
""",
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
spectra = Quantity(
|
|
117
|
+
type=Reference(Spectra),
|
|
118
|
+
shape=['n_data'],
|
|
119
|
+
description="""
|
|
120
|
+
Reference to the spectral data.
|
|
121
|
+
""",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class SinglePointMethod(SimulationWorkflowMethod):
|
|
126
|
+
method = Quantity(
|
|
127
|
+
type=str,
|
|
128
|
+
shape=[],
|
|
129
|
+
description="""
|
|
130
|
+
Calculation method used.
|
|
131
|
+
""",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class SinglePoint(SimulationWorkflow):
|
|
136
|
+
method = SubSection(sub_section=SinglePointMethod)
|
|
137
|
+
|
|
138
|
+
results = SubSection(sub_section=SinglePointResults)
|
|
139
|
+
|
|
140
|
+
def normalize(self, archive, logger):
|
|
141
|
+
super().normalize(archive, logger)
|
|
142
|
+
|
|
143
|
+
if not self.tasks:
|
|
144
|
+
task = Task()
|
|
145
|
+
if self._systems:
|
|
146
|
+
task.m_add_sub_section(
|
|
147
|
+
Task.inputs, Link(name=INPUT_SYSTEM_NAME, section=self._systems[0])
|
|
148
|
+
)
|
|
149
|
+
if self._methods:
|
|
150
|
+
task.m_add_sub_section(
|
|
151
|
+
Task.inputs, Link(name=INPUT_METHOD_NAME, section=self._methods[0])
|
|
152
|
+
)
|
|
153
|
+
if self._calculations:
|
|
154
|
+
task.m_add_sub_section(
|
|
155
|
+
Task.inputs,
|
|
156
|
+
Link(name=OUTPUT_CALCULATION_NAME, section=self._calculations[0]),
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
self.tasks = [task]
|
|
160
|
+
|
|
161
|
+
if not self.method:
|
|
162
|
+
self.method = SinglePointMethod()
|
|
163
|
+
|
|
164
|
+
if not self.inputs:
|
|
165
|
+
self.m_add_sub_section(
|
|
166
|
+
SimulationWorkflow.inputs,
|
|
167
|
+
Link(name=WORKFLOW_METHOD_NAME, section=self.method),
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
if not self.results:
|
|
171
|
+
self.results = SinglePointResults()
|
|
172
|
+
|
|
173
|
+
if not self.outputs:
|
|
174
|
+
self.m_add_sub_section(
|
|
175
|
+
SimulationWorkflow.outputs,
|
|
176
|
+
Link(name=WORKFLOW_RESULTS_NAME, section=self.results),
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
if not self.method.method:
|
|
180
|
+
try:
|
|
181
|
+
# TODO keep extending for other SinglePoint
|
|
182
|
+
for method_name in ['dft', 'gw', 'bse', 'dmft']:
|
|
183
|
+
if self._methods[-1].m_xpath(method_name):
|
|
184
|
+
self.method.method = method_name.upper()
|
|
185
|
+
break
|
|
186
|
+
except Exception:
|
|
187
|
+
pass
|
|
188
|
+
|
|
189
|
+
if not self._calculations:
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
last_calc = self._calculations[-1]
|
|
193
|
+
if not self.results.n_scf_steps:
|
|
194
|
+
self.results.n_scf_steps = len(last_calc.scf_iteration)
|
|
195
|
+
|
|
196
|
+
energies = [
|
|
197
|
+
scf.energy.total.value
|
|
198
|
+
for scf in last_calc.scf_iteration
|
|
199
|
+
if scf.energy is not None and scf.energy.total is not None
|
|
200
|
+
]
|
|
201
|
+
delta_energy = resolve_difference(energies)
|
|
202
|
+
if not self.results.final_scf_energy_difference and delta_energy is not None:
|
|
203
|
+
self.results.final_scf_energy_difference = delta_energy
|
|
204
|
+
|
|
205
|
+
if not self.results.is_converged and delta_energy is not None:
|
|
206
|
+
try:
|
|
207
|
+
threshold = self._methods[-1].scf.threshold_energy_change
|
|
208
|
+
self.results.is_converged = bool(delta_energy <= threshold)
|
|
209
|
+
except Exception:
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
if not self.results.dos and last_calc.dos_electronic:
|
|
213
|
+
self.results.dos = last_calc.dos_electronic
|
|
214
|
+
|
|
215
|
+
if not self.results.band_structure and last_calc.band_structure_electronic:
|
|
216
|
+
self.results.band_structure = last_calc.band_structure_electronic
|
|
217
|
+
|
|
218
|
+
if not self.results.eigenvalues and last_calc.eigenvalues:
|
|
219
|
+
self.results.eigenvalues = last_calc.eigenvalues
|
|
220
|
+
|
|
221
|
+
if not self.results.density_charge and last_calc.density_charge:
|
|
222
|
+
self.results.density_charge = last_calc.density_charge
|
|
223
|
+
|
|
224
|
+
if not self.results.potential and last_calc.potential:
|
|
225
|
+
self.results.potential = last_calc.potential
|
|
226
|
+
|
|
227
|
+
if not self.results.spectra and last_calc.spectra:
|
|
228
|
+
self.results.spectra = last_calc.spectra
|
|
229
|
+
|
|
230
|
+
SimulationWorkflowResults.normalize(self.results, archive, logger)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class ParallelSimulation(SimulationWorkflow):
|
|
234
|
+
def normalize(self, archive, logger):
|
|
235
|
+
super().normalize(archive, logger)
|
|
236
|
+
|
|
237
|
+
if not self.tasks:
|
|
238
|
+
for n, calculation in enumerate(self._calculations):
|
|
239
|
+
inputs, outputs = (
|
|
240
|
+
[],
|
|
241
|
+
[Link(name=OUTPUT_CALCULATION_NAME, section=calculation)],
|
|
242
|
+
)
|
|
243
|
+
if self._calculations[n].system_ref:
|
|
244
|
+
inputs.append(
|
|
245
|
+
Link(
|
|
246
|
+
name=INPUT_SYSTEM_NAME,
|
|
247
|
+
section=self._calculations[n].system_ref,
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
elif len(self._calculations) == len(self._systems):
|
|
251
|
+
inputs.append(
|
|
252
|
+
Link(name=INPUT_SYSTEM_NAME, section=self._systems[n])
|
|
253
|
+
)
|
|
254
|
+
else:
|
|
255
|
+
continue
|
|
256
|
+
if self._calculations[n].method_ref:
|
|
257
|
+
inputs.append(
|
|
258
|
+
Link(
|
|
259
|
+
name=INPUT_METHOD_NAME,
|
|
260
|
+
section=self._calculations[n].method_ref,
|
|
261
|
+
)
|
|
262
|
+
)
|
|
263
|
+
elif len(self._calculations) == len(self._methods):
|
|
264
|
+
inputs.append(
|
|
265
|
+
Link(name=INPUT_METHOD_NAME, section=self._methods[n])
|
|
266
|
+
)
|
|
267
|
+
elif len(self._methods) == 1:
|
|
268
|
+
inputs.append(
|
|
269
|
+
Link(name=INPUT_METHOD_NAME, section=self._methods[0])
|
|
270
|
+
)
|
|
271
|
+
self.tasks.append(
|
|
272
|
+
Task(name=f'Calculation {n}', inputs=inputs, outputs=outputs)
|
|
273
|
+
)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright The NOMAD Authors.
|
|
3
|
+
#
|
|
4
|
+
# This file is part of NOMAD. See https://nomad-lab.eu for further info.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
#
|
|
18
|
+
from nomad.metainfo import SubSection, Quantity, Reference
|
|
19
|
+
from runschema.method import TB as TBMethodology, Method
|
|
20
|
+
from .general import (
|
|
21
|
+
SimulationWorkflowResults,
|
|
22
|
+
ElectronicStructureOutputs,
|
|
23
|
+
SimulationWorkflowMethod,
|
|
24
|
+
SerialSimulation,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class FirstPrinciplesPlusTBResults(SimulationWorkflowResults):
|
|
29
|
+
"""
|
|
30
|
+
Groups first principles and TB outputs: band gaps, DOS, band structures. The
|
|
31
|
+
ResultsNormalizer takes care of adding a label 'FirstPrinciples' or 'TB' in the method
|
|
32
|
+
`get_tb_workflow_properties`.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
first_principles_outputs = SubSection(
|
|
36
|
+
sub_section=ElectronicStructureOutputs.m_def, repeats=False
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
tb_outputs = SubSection(sub_section=ElectronicStructureOutputs.m_def, repeats=False)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class FirstPrinciplesPlusTBMethod(SimulationWorkflowMethod):
|
|
43
|
+
"""
|
|
44
|
+
Specifies both the first principles and the TB input methodologies.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
# TODO refine this referencing
|
|
48
|
+
first_principles_method_ref = Quantity(
|
|
49
|
+
type=Reference(Method),
|
|
50
|
+
description="""
|
|
51
|
+
First principles methodology reference.
|
|
52
|
+
""",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
tb_method_ref = Quantity(
|
|
56
|
+
type=Reference(TBMethodology),
|
|
57
|
+
description="""
|
|
58
|
+
TB methodology reference.
|
|
59
|
+
""",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class FirstPrinciplesPlusTB(SerialSimulation):
|
|
64
|
+
"""
|
|
65
|
+
The TB (tight-binding) workflow is generated in an extra EntryArchive IF both
|
|
66
|
+
the first principles SinglePoint and the TB SinglePoint EntryArchives are present in the upload.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
method = SubSection(sub_section=FirstPrinciplesPlusTBMethod)
|
|
70
|
+
|
|
71
|
+
results = SubSection(sub_section=FirstPrinciplesPlusTBResults)
|
|
72
|
+
|
|
73
|
+
def normalize(self, archive, logger):
|
|
74
|
+
if not self.results: # creates Results section if not present
|
|
75
|
+
self.results = FirstPrinciplesPlusTBResults()
|
|
76
|
+
|
|
77
|
+
super().normalize(archive, logger)
|