scgo 0.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.
- benchmark/benchmark_Pt.py +101 -0
- benchmark/benchmark_Pt_surface_graphite.py +122 -0
- benchmark/benchmark_common.py +673 -0
- docs/source/conf.py +109 -0
- examples/example_pt5_2oh_graphite.py +85 -0
- examples/example_pt5_gas.py +57 -0
- examples/example_pt5_graphite.py +69 -0
- examples/example_pt5_oh_gas.py +75 -0
- scgo/__init__.py +168 -0
- scgo/algorithms/__init__.py +26 -0
- scgo/algorithms/basinhopping_go.py +693 -0
- scgo/algorithms/ga_common.py +1455 -0
- scgo/algorithms/geneticalgorithm_go_torchsim.py +1553 -0
- scgo/algorithms/simple_go.py +138 -0
- scgo/ase_ga_patches/__init__.py +7 -0
- scgo/ase_ga_patches/_vector_utils.py +23 -0
- scgo/ase_ga_patches/cutandsplicepairing.py +726 -0
- scgo/ase_ga_patches/population.py +592 -0
- scgo/ase_ga_patches/standardmutations.py +1800 -0
- scgo/calculators/__init__.py +66 -0
- scgo/calculators/ase_batch_relaxer.py +50 -0
- scgo/calculators/mace_helpers.py +167 -0
- scgo/calculators/orca_helpers.py +128 -0
- scgo/calculators/torchsim_helpers.py +738 -0
- scgo/calculators/uma_helpers.py +77 -0
- scgo/calculators/vasp_helpers.py +111 -0
- scgo/cluster_adsorbate/__init__.py +49 -0
- scgo/cluster_adsorbate/combine.py +38 -0
- scgo/cluster_adsorbate/config.py +48 -0
- scgo/cluster_adsorbate/constraints.py +78 -0
- scgo/cluster_adsorbate/feasibility.py +129 -0
- scgo/cluster_adsorbate/geometry.py +124 -0
- scgo/cluster_adsorbate/hierarchical.py +215 -0
- scgo/cluster_adsorbate/placement.py +410 -0
- scgo/cluster_adsorbate/relax.py +222 -0
- scgo/cluster_adsorbate/reposition.py +139 -0
- scgo/cluster_adsorbate/rigid.py +105 -0
- scgo/cluster_adsorbate/validation.py +118 -0
- scgo/constants.py +30 -0
- scgo/database/__init__.py +175 -0
- scgo/database/cache.py +259 -0
- scgo/database/connection.py +180 -0
- scgo/database/constants.py +10 -0
- scgo/database/discovery.py +383 -0
- scgo/database/exceptions.py +9 -0
- scgo/database/health.py +165 -0
- scgo/database/helpers.py +948 -0
- scgo/database/manager.py +211 -0
- scgo/database/metadata.py +347 -0
- scgo/database/registry.py +254 -0
- scgo/database/schema.py +176 -0
- scgo/database/streaming.py +229 -0
- scgo/database/sync.py +208 -0
- scgo/database/transactions.py +51 -0
- scgo/exceptions.py +64 -0
- scgo/initialization/__init__.py +71 -0
- scgo/initialization/atomic_radii.py +193 -0
- scgo/initialization/candidate_discovery.py +285 -0
- scgo/initialization/geometry_helpers.py +1804 -0
- scgo/initialization/initialization_config.py +205 -0
- scgo/initialization/initializers.py +1395 -0
- scgo/initialization/random_spherical.py +1091 -0
- scgo/initialization/seed_combiners.py +238 -0
- scgo/initialization/steric_scoring.py +51 -0
- scgo/initialization/strategy_allocation.py +224 -0
- scgo/initialization/templates.py +1847 -0
- scgo/minima_search/__init__.py +10 -0
- scgo/minima_search/core.py +962 -0
- scgo/param_presets.py +569 -0
- scgo/runner_api.py +1511 -0
- scgo/surface/__init__.py +63 -0
- scgo/surface/composition.py +12 -0
- scgo/surface/config.py +161 -0
- scgo/surface/constraints.py +184 -0
- scgo/surface/deposition.py +618 -0
- scgo/surface/fragment_templates.py +39 -0
- scgo/surface/objectives.py +21 -0
- scgo/surface/pbc.py +53 -0
- scgo/surface/presets.py +108 -0
- scgo/surface/validation.py +434 -0
- scgo/system_types.py +658 -0
- scgo/ts_search/__init__.py +31 -0
- scgo/ts_search/parallel_neb.py +412 -0
- scgo/ts_search/transition_state.py +1479 -0
- scgo/ts_search/transition_state_io.py +571 -0
- scgo/ts_search/transition_state_run.py +936 -0
- scgo/ts_search/ts_network.py +708 -0
- scgo/ts_search/ts_statistics.py +42 -0
- scgo/utils/__init__.py +53 -0
- scgo/utils/atoms_helpers.py +21 -0
- scgo/utils/comparators.py +255 -0
- scgo/utils/diversity_scorer.py +188 -0
- scgo/utils/fitness_strategies.py +106 -0
- scgo/utils/helpers.py +806 -0
- scgo/utils/logging.py +121 -0
- scgo/utils/mlip_extras.py +42 -0
- scgo/utils/mutation_weights.py +377 -0
- scgo/utils/optimizer_utils.py +42 -0
- scgo/utils/parallel_workers.py +25 -0
- scgo/utils/rng_helpers.py +78 -0
- scgo/utils/run_helpers.py +530 -0
- scgo/utils/run_tracking.py +196 -0
- scgo/utils/runtime_warnings.py +22 -0
- scgo/utils/timing_report.py +82 -0
- scgo/utils/torchsim_policy.py +91 -0
- scgo/utils/ts_provenance.py +48 -0
- scgo/utils/ts_runner_kwargs.py +133 -0
- scgo/utils/validation.py +175 -0
- scgo-0.1.0.dist-info/METADATA +509 -0
- scgo-0.1.0.dist-info/RECORD +235 -0
- scgo-0.1.0.dist-info/WHEEL +5 -0
- scgo-0.1.0.dist-info/licenses/LICENSE +21 -0
- scgo-0.1.0.dist-info/top_level.txt +5 -0
- tests/__init__.py +0 -0
- tests/algorithms/__init__.py +0 -0
- tests/algorithms/test_adsorbate_ga_acceptance.py +210 -0
- tests/algorithms/test_adsorbate_operator_weights.py +111 -0
- tests/algorithms/test_algorithms_ga_common.py +50 -0
- tests/algorithms/test_core_adsorbate_ga_tags.py +151 -0
- tests/algorithms/test_edge_cases.py +300 -0
- tests/algorithms/test_ga_operator_acceptance.py +554 -0
- tests/algorithms/test_geneticalgorithm_generational.py +379 -0
- tests/algorithms/test_geneticalgorithm_logging.py +59 -0
- tests/algorithms/test_reproducibility.py +1014 -0
- tests/algorithms/test_validation.py +915 -0
- tests/ase_ga_patches/__init__.py +0 -0
- tests/ase_ga_patches/test_ase_ga_patches.py +476 -0
- tests/ase_ga_patches/test_ga_mutations.py +201 -0
- tests/ase_ga_patches/test_ga_pairing.py +160 -0
- tests/ase_ga_patches/test_population_selection.py +73 -0
- tests/ase_ga_patches/test_retry_reduction.py +560 -0
- tests/ase_ga_patches/test_surface_coherence.py +418 -0
- tests/benchmarks/__init__.py +0 -0
- tests/benchmarks/test_benchmarks.py +103 -0
- tests/calculators/__init__.py +0 -0
- tests/calculators/test_calculators.py +240 -0
- tests/calculators/test_torchsim_fixatoms_mapping.py +45 -0
- tests/calculators/test_torchsim_helpers.py +393 -0
- tests/calculators/test_uma_helpers.py +66 -0
- tests/cluster_adsorbate/test_fragment_reposition.py +83 -0
- tests/cluster_adsorbate/test_frozen_adsorbate_geometry.py +109 -0
- tests/cluster_adsorbate/test_general_adsorbate.py +172 -0
- tests/cluster_adsorbate/test_multi_fragment_placement.py +83 -0
- tests/cluster_adsorbate/test_multi_fragment_site_metadata.py +44 -0
- tests/cluster_adsorbate/test_oh_on_pt_cluster.py +137 -0
- tests/cluster_adsorbate/test_placement_heuristics.py +70 -0
- tests/cluster_adsorbate/test_site_diversity.py +81 -0
- tests/conftest.py +253 -0
- tests/constants.py +41 -0
- tests/database/__init__.py +0 -0
- tests/database/test_database_core.py +1316 -0
- tests/database/test_database_metadata_adapter.py +93 -0
- tests/database/test_initialization_cache.py +105 -0
- tests/database/test_mark_final_minima.py +125 -0
- tests/database/test_mark_final_minima_dbpaths.py +60 -0
- tests/database/test_parallel_worker_ase_compat.py +45 -0
- tests/database/test_persist_provenance.py +34 -0
- tests/database/test_registry.py +231 -0
- tests/database/test_require_json1.py +29 -0
- tests/database/test_schema_utils.py +86 -0
- tests/initialization/__init__.py +0 -0
- tests/initialization/test_atomic_radii.py +59 -0
- tests/initialization/test_atomic_radii_blmin.py +23 -0
- tests/initialization/test_batch_initialization.py +513 -0
- tests/initialization/test_composition_matching.py +103 -0
- tests/initialization/test_connectivity.py +328 -0
- tests/initialization/test_geometry_helpers.py +709 -0
- tests/initialization/test_init_canonical_mtime.py +68 -0
- tests/initialization/test_init_common.py +1559 -0
- tests/initialization/test_init_logging.py +27 -0
- tests/initialization/test_init_random_spherical.py +249 -0
- tests/initialization/test_init_seed_growth.py +630 -0
- tests/initialization/test_init_smart.py +470 -0
- tests/initialization/test_init_template.py +333 -0
- tests/initialization/test_initialization_modes.py +312 -0
- tests/initialization/test_mixed_compositions.py +136 -0
- tests/initialization/test_parameter_sensitivity.py +335 -0
- tests/initialization/test_path_prefilter.py +27 -0
- tests/initialization/test_seed_combiners.py +395 -0
- tests/initialization/test_template_discovery_logs.py +41 -0
- tests/initialization/test_template_facet_vertex.py +193 -0
- tests/initialization/test_templates.py +753 -0
- tests/integration/__init__.py +0 -0
- tests/integration/test_integration.py +759 -0
- tests/integration/test_main_final_tagging.py +177 -0
- tests/integration/test_run_api.py +1009 -0
- tests/integration/test_run_go_surface.py +65 -0
- tests/integration/test_runners_emulation.py +70 -0
- tests/minima_search/__init__.py +0 -0
- tests/minima_search/test_minima_search.py +875 -0
- tests/minima_search/test_output.py +485 -0
- tests/minima_search/test_run_tracking.py +511 -0
- tests/param_presets/__init__.py +0 -0
- tests/param_presets/test_param_presets.py +367 -0
- tests/param_presets/test_param_presets_and_run_helpers.py +501 -0
- tests/surface/__init__.py +1 -0
- tests/surface/test_hierarchical_deposition.py +189 -0
- tests/surface/test_mobile_symbol_validation.py +107 -0
- tests/surface/test_slab_ga_metadata.py +42 -0
- tests/surface/test_slab_ordering_contract.py +125 -0
- tests/surface/test_slab_pbc.py +49 -0
- tests/surface/test_supported_cluster_binding.py +355 -0
- tests/surface/test_surface_constraints.py +197 -0
- tests/surface/test_surface_deposition.py +324 -0
- tests/surface/test_surface_ga_smoke.py +51 -0
- tests/surface/test_surface_ga_torchsim.py +156 -0
- tests/test_optimization_algorithm_select.py +19 -0
- tests/test_optional_extras_smoke.py +17 -0
- tests/test_runner_surface.py +85 -0
- tests/test_utils.py +780 -0
- tests/ts_search/__init__.py +0 -0
- tests/ts_search/test_neb_blockwise_alignment.py +94 -0
- tests/ts_search/test_parallel_neb.py +292 -0
- tests/ts_search/test_surface_neb_alignment.py +500 -0
- tests/ts_search/test_ts_final_minima_integration.py +212 -0
- tests/ts_search/test_ts_integration.py +1001 -0
- tests/ts_search/test_ts_integration_cu4_mace.py +564 -0
- tests/ts_search/test_ts_interpolation_mic.py +212 -0
- tests/ts_search/test_ts_network.py +395 -0
- tests/ts_search/test_ts_postprocessing.py +964 -0
- tests/ts_search/test_ts_robustness.py +306 -0
- tests/ts_search/test_ts_search.py +1027 -0
- tests/ts_search/test_ts_search_forces_failures.py +69 -0
- tests/utils/__init__.py +0 -0
- tests/utils/test_atoms_helpers.py +115 -0
- tests/utils/test_diversity_scorer.py +168 -0
- tests/utils/test_fitness_strategies.py +237 -0
- tests/utils/test_helpers.py +492 -0
- tests/utils/test_is_true_minimum.py +335 -0
- tests/utils/test_logging_trace_method.py +24 -0
- tests/utils/test_mutation_weights.py +233 -0
- tests/utils/test_optimizer_utils.py +90 -0
- tests/utils/test_rng_helpers.py +208 -0
- tests/utils/test_torchsim_policy.py +117 -0
- tests/utils/test_verbosity.py +247 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Benchmark suite for platinum clusters based on reference structures.
|
|
2
|
+
|
|
3
|
+
The utilities here drive SCGO against a curated Pt benchmark set and evaluate
|
|
4
|
+
the recovered minima primarily through geometric agreement and, secondarily,
|
|
5
|
+
relative energetic ordering. The script doubles as a pytest entry point and a
|
|
6
|
+
standalone CLI for rapid regression checks while tweaking optimization knobs.
|
|
7
|
+
|
|
8
|
+
Campaign outputs are written under
|
|
9
|
+
``benchmark/results/<formula>_<backend>_<model>/`` (for example:
|
|
10
|
+
``pt5_mace_mace_matpes_0`` or ``pt5_uma_uma-s-1p2-oc25``).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import argparse
|
|
16
|
+
import os
|
|
17
|
+
import time
|
|
18
|
+
|
|
19
|
+
import pytest
|
|
20
|
+
|
|
21
|
+
from benchmark.benchmark_common import (
|
|
22
|
+
DEFAULT_CLUSTERS,
|
|
23
|
+
MIN_RECOVERY_RATE,
|
|
24
|
+
NUM_GROUND_TRUTH,
|
|
25
|
+
add_common_benchmark_cli,
|
|
26
|
+
evaluate_cluster,
|
|
27
|
+
get_benchmark_params,
|
|
28
|
+
run_benchmark_suite,
|
|
29
|
+
)
|
|
30
|
+
from scgo.utils.logging import get_logger
|
|
31
|
+
|
|
32
|
+
BENCHMARK_SEEDS = [42, 43, 44, 45]
|
|
33
|
+
MODEL_NAME: str | None = None
|
|
34
|
+
BENCHMARK_BACKEND = os.environ.get("SCGO_BENCHMARK_BACKEND", "mace")
|
|
35
|
+
logger = get_logger(__name__)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@pytest.mark.parametrize(
|
|
39
|
+
"cluster_formula, seed",
|
|
40
|
+
[(c, s) for c in DEFAULT_CLUSTERS for s in BENCHMARK_SEEDS],
|
|
41
|
+
)
|
|
42
|
+
def test_benchmark_minima_recovery(cluster_formula: str, seed: int):
|
|
43
|
+
"""Pytest entry point for validating a single cluster benchmark run."""
|
|
44
|
+
params = get_benchmark_params(
|
|
45
|
+
seed, model_name=MODEL_NAME, backend=BENCHMARK_BACKEND
|
|
46
|
+
)
|
|
47
|
+
result = evaluate_cluster(
|
|
48
|
+
cluster_formula,
|
|
49
|
+
params=params,
|
|
50
|
+
seed=seed,
|
|
51
|
+
comparator_tolerance=0.05,
|
|
52
|
+
num_ground_truth=NUM_GROUND_TRUTH,
|
|
53
|
+
verbose=True,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
if result.skipped:
|
|
57
|
+
pytest.skip(result.skip_reason or "Benchmark skipped")
|
|
58
|
+
|
|
59
|
+
if not result.matched_indices:
|
|
60
|
+
pytest.skip(
|
|
61
|
+
f"No minima recovered for {cluster_formula}. Check optimizer settings.",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
if result.recovery_rate < MIN_RECOVERY_RATE:
|
|
65
|
+
pytest.xfail(
|
|
66
|
+
f"Recovery rate {result.recovery_rate:.2f} below threshold {MIN_RECOVERY_RATE:.2f}.",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def main() -> None:
|
|
71
|
+
"""CLI entry point for running the Pt benchmark suite."""
|
|
72
|
+
parser = argparse.ArgumentParser(
|
|
73
|
+
description="Pt cluster geometric recovery benchmark (MACE/TorchSim or UMA/ASE GA).",
|
|
74
|
+
)
|
|
75
|
+
add_common_benchmark_cli(parser)
|
|
76
|
+
args = parser.parse_args()
|
|
77
|
+
|
|
78
|
+
params = get_benchmark_params(
|
|
79
|
+
args.seed,
|
|
80
|
+
model_name=args.model_name,
|
|
81
|
+
backend=args.backend,
|
|
82
|
+
uma_task=args.uma_task,
|
|
83
|
+
)
|
|
84
|
+
params["optimizer_params"]["ga"]["niter"] = args.niter
|
|
85
|
+
params["optimizer_params"]["ga"]["population_size"] = args.population_size
|
|
86
|
+
|
|
87
|
+
t0 = time.perf_counter()
|
|
88
|
+
run_benchmark_suite(
|
|
89
|
+
clusters=args.clusters,
|
|
90
|
+
seed=args.seed,
|
|
91
|
+
params=params,
|
|
92
|
+
verbose=True,
|
|
93
|
+
backend=args.backend,
|
|
94
|
+
uma_task=args.uma_task,
|
|
95
|
+
)
|
|
96
|
+
elapsed = time.perf_counter() - t0
|
|
97
|
+
logger.info("Benchmark wall time: %.1f s (%s)", elapsed, args.backend)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if __name__ == "__main__":
|
|
101
|
+
main()
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Benchmark Pt cluster search on graphite with top-layer slab relaxation.
|
|
3
|
+
|
|
4
|
+
Mirrors ``benchmark/benchmark_Pt.py`` for a surface system: sweeps Pt cluster
|
|
5
|
+
sizes with one seed, runs SCGO over the range, and logs per-size minima from
|
|
6
|
+
the campaign. Outputs live under ``benchmark/results/pt_surface_graphite/`` (same
|
|
7
|
+
layout as gas-phase benchmarks: ``<Formula>_searches`` per size). See
|
|
8
|
+
``benchmark.benchmark_common.PT_SURFACE_GRAPHITE_RESULTS_DIR``.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import time
|
|
15
|
+
|
|
16
|
+
from benchmark.benchmark_common import (
|
|
17
|
+
DEFAULT_CLUSTERS,
|
|
18
|
+
PT_SURFACE_GRAPHITE_RESULTS_DIR,
|
|
19
|
+
add_common_benchmark_cli,
|
|
20
|
+
apply_ga_benchmark_overrides,
|
|
21
|
+
format_ga_profile_lines,
|
|
22
|
+
get_benchmark_params,
|
|
23
|
+
load_latest_ga_profile,
|
|
24
|
+
parse_atom_count,
|
|
25
|
+
)
|
|
26
|
+
from scgo.runner_api import run_go_campaign
|
|
27
|
+
from scgo.surface import (
|
|
28
|
+
DEFAULT_GRAPHITE_SLAB_LAYERS,
|
|
29
|
+
DEFAULT_GRAPHITE_SLAB_REPEAT_XY,
|
|
30
|
+
make_graphite_surface_config,
|
|
31
|
+
)
|
|
32
|
+
from scgo.utils.helpers import get_cluster_formula
|
|
33
|
+
from scgo.utils.logging import get_logger
|
|
34
|
+
|
|
35
|
+
DEFAULT_OUTPUT_ROOT = PT_SURFACE_GRAPHITE_RESULTS_DIR.resolve()
|
|
36
|
+
|
|
37
|
+
logger = get_logger(__name__)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def parse_args() -> argparse.Namespace:
|
|
41
|
+
parser = argparse.ArgumentParser(
|
|
42
|
+
description=(
|
|
43
|
+
"Run Pt-on-graphite SCGO benchmark sweep with top-layer slab relaxation."
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
add_common_benchmark_cli(parser)
|
|
47
|
+
parser.set_defaults(niter=6, population_size=24)
|
|
48
|
+
parser.add_argument("--slab-layers", type=int, default=DEFAULT_GRAPHITE_SLAB_LAYERS)
|
|
49
|
+
parser.add_argument(
|
|
50
|
+
"--slab-repeat-xy",
|
|
51
|
+
type=int,
|
|
52
|
+
default=DEFAULT_GRAPHITE_SLAB_REPEAT_XY,
|
|
53
|
+
help="In-plane supercell repeats; default is large enough for Pt4-Pt11 adsorption.",
|
|
54
|
+
)
|
|
55
|
+
return parser.parse_args()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def main() -> None:
|
|
59
|
+
args = parse_args()
|
|
60
|
+
output_root = DEFAULT_OUTPUT_ROOT
|
|
61
|
+
output_root.mkdir(parents=True, exist_ok=True)
|
|
62
|
+
clusters = args.clusters or DEFAULT_CLUSTERS
|
|
63
|
+
|
|
64
|
+
surface_config = make_graphite_surface_config(
|
|
65
|
+
slab_layers=args.slab_layers,
|
|
66
|
+
slab_repeat_xy=args.slab_repeat_xy,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
base_params = get_benchmark_params(
|
|
70
|
+
args.seed,
|
|
71
|
+
model_name=args.model_name,
|
|
72
|
+
backend=args.backend,
|
|
73
|
+
uma_task=args.uma_task,
|
|
74
|
+
)
|
|
75
|
+
params = apply_ga_benchmark_overrides(
|
|
76
|
+
base_params,
|
|
77
|
+
niter=args.niter,
|
|
78
|
+
population_size=args.population_size,
|
|
79
|
+
surface_config=surface_config,
|
|
80
|
+
n_jobs_population_init=-2,
|
|
81
|
+
batch_size=4,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
t0 = time.perf_counter()
|
|
85
|
+
|
|
86
|
+
logger.info("Per-size summary:")
|
|
87
|
+
total_minima = 0
|
|
88
|
+
for formula in clusters:
|
|
89
|
+
n_atoms = parse_atom_count(formula)
|
|
90
|
+
formula = get_cluster_formula(["Pt"] * n_atoms)
|
|
91
|
+
results = run_go_campaign(
|
|
92
|
+
[["Pt"] * n_atoms],
|
|
93
|
+
params=params,
|
|
94
|
+
seed=args.seed,
|
|
95
|
+
output_dir=output_root,
|
|
96
|
+
surface_config=surface_config,
|
|
97
|
+
system_type="surface_cluster",
|
|
98
|
+
)
|
|
99
|
+
minima = results.get(formula, [])
|
|
100
|
+
n_found = len(minima)
|
|
101
|
+
total_minima += n_found
|
|
102
|
+
if n_found == 0:
|
|
103
|
+
logger.info(" %s: 0 minima", formula)
|
|
104
|
+
continue
|
|
105
|
+
best_energy = minima[0][0]
|
|
106
|
+
logger.info(" %s: %d minima, best E=%.6f eV", formula, n_found, best_energy)
|
|
107
|
+
profile = load_latest_ga_profile(output_root, formula)
|
|
108
|
+
if profile:
|
|
109
|
+
for line in format_ga_profile_lines(profile, detailed=True, max_entries=8):
|
|
110
|
+
logger.info(" %s", line)
|
|
111
|
+
|
|
112
|
+
logger.info(
|
|
113
|
+
"Finished benchmark. Total minima saved across formulas: %d under %s",
|
|
114
|
+
total_minima,
|
|
115
|
+
output_root,
|
|
116
|
+
)
|
|
117
|
+
elapsed = time.perf_counter() - t0
|
|
118
|
+
logger.info("Benchmark wall time: %.1f s (%s)", elapsed, args.backend)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
main()
|