Commit 1153c82a authored by Alvin Noe Ladines's avatar Alvin Noe Ladines
Browse files

Fixed vasp mainfile_re, workflow convergence

parent 823e6f49
Pipeline #100381 passed with stages
in 24 minutes and 49 seconds
Subproject commit cbdce6c1287f186924e91c7d6ba2ff14e23f81ae
Subproject commit 6cd63b7bc3d17bf8aff120257d07653697d44431
......@@ -6658,6 +6658,16 @@ class GeometryOptimization(MSection):
categories=[Unused],
a_legacy=LegacyDefinition(name='input_force_maximum_tolerance'))
input_displacement_maximum_tolerance = Quantity(
type=np.dtype(np.float64),
shape=[],
unit='meter',
description='''
The input maximum displacement tolerance criterion.
''',
categories=[Unused],
a_legacy=LegacyDefinition(name='input_displacement_maximum_tolerance'))
final_energy_difference = Quantity(
type=np.dtype(np.float64),
shape=[],
......@@ -6677,6 +6687,15 @@ class GeometryOptimization(MSection):
''',
a_legacy=LegacyDefinition(name='final_force_maximum'))
final_displacement_maximum = Quantity(
type=np.dtype(np.float64),
shape=[],
unit='meter',
description='''
The maximum displacement in the last optimization step with respect to previous.
''',
a_legacy=LegacyDefinition(name='final_displacement_maximum'))
optimization_steps = Quantity(
type=int,
shape=[],
......@@ -6685,6 +6704,14 @@ class GeometryOptimization(MSection):
''',
a_legacy=LegacyDefinition(name='optimization_steps'))
is_converged_geometry = Quantity(
type=bool,
shape=[],
description='''
Indicates if the geometry convergence criteria were fulfilled.
''',
a_legacy=LegacyDefinition(name='is_converged_geometry'))
class Phonon(MSection):
'''
......
......@@ -24,16 +24,16 @@ from nomad.datamodel.metainfo.public import Workflow, GeometryOptimization, Phon
MolecularDynamics, SinglePoint
def resolve_energy_difference(energies):
delta_energy = None
def resolve_difference(values):
delta_values = None
energies = [e for e in energies if e is not None]
for n in range(-1, -len(energies), -1):
delta_energy = abs(energies[n] - energies[n - 1])
if delta_energy != 0.0:
values = [v for v in values if v is not None]
for n in range(-1, -len(values), -1):
delta_values = abs(values[n] - values[n - 1])
if delta_values != 0.0:
break
return delta_energy
return delta_values
class SinglePointNormalizer(Normalizer):
......@@ -60,15 +60,14 @@ class SinglePointNormalizer(Normalizer):
self.section.number_of_scf_steps = len(scc[-1].section_scf_iteration)
energies = [scf.energy_total_scf_iteration for scf in scc[-1].section_scf_iteration]
delta_energy = resolve_energy_difference(energies)
delta_energy = resolve_difference(energies)
if not self.section.final_scf_energy_difference and delta_energy is not None:
self.section.final_scf_energy_difference = delta_energy
if not self.section.is_converged and delta_energy is not None:
try:
threshold = self.section.section_method[-1].scf_threshold_energy_change
if threshold <= delta_energy:
self.section.is_converged = True
threshold = self.section_run.section_method[-1].scf_threshold_energy_change
self.section.is_converged = threshold <= delta_energy
except Exception:
pass
......@@ -154,13 +153,34 @@ class GeometryOptimizationNormalizer(Normalizer):
scc = self.section_run.section_single_configuration_calculation
self.section.optimization_steps = len(scc)
if not self.section.input_energy_difference_tolerance:
try:
tolerance = self.section_run.section_sampling_method[-1].geometry_optimization_energy_change
self.section.input_energy_difference_tolerance = tolerance
except Exception:
pass
if not self.section.input_force_maximum_tolerance:
try:
tolerance = self.section_run.section_sampling_method[-1].geometry_optimization_threshold_force
self.section.input_force_maximum_tolerance = tolerance
except Exception:
pass
if not self.section.input_displacement_maximum_tolerance:
try:
tolerance = self.section_run.section_sampling_method[-1].geometry_optimization_geometry_change
self.section.input_displacement_maximum_tolerance = tolerance
except Exception:
pass
if not self.section.final_energy_difference:
energies = []
for scc in self.section_run.section_single_configuration_calculation:
if scc.energy_total_T0:
energies.append(scc.energy_total_T0)
if scc.energy_total:
energies.append(scc.energy_total)
delta_energy = resolve_energy_difference(energies)
delta_energy = resolve_difference(energies)
if delta_energy is not None:
self.section.final_energy_difference = delta_energy
......@@ -174,6 +194,37 @@ class GeometryOptimizationNormalizer(Normalizer):
if max_force is not None:
self.section.final_force_maximum = max_force
if not self.section.final_displacement_maximum:
try:
system = self.section_run.system
displacements = [np.max(np.abs(
system[n].atom_positions - system[n - 1].atom_positions)) for n in range(1, len(system))]
self.section.final_displacement_maximum = resolve_difference(displacements)
except Exception:
pass
if not self.section.is_converged_geometry:
# we can have several criteria for convergence: energy, force, displacement
criteria = []
try:
criteria.append(self.section.final_energy_difference <= self.section.input_energy_difference_tolerance)
except Exception:
pass
try:
criteria.append(self.section.final_force_maximum <= self.section.input_force_maximum_tolerance)
except Exception:
pass
try:
criteria.append(self.section.final_displacement_maximum <= self.section.input_displacement_maximum_tolerance)
except Exception:
pass
# converged when either criterion is met
if criteria:
self.section.is_converged_geometry = True in criteria
class PhononNormalizer(Normalizer):
def __init__(self, entry_archive):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment