Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can HTESP reproduce the Elastic Constants reported on https://next-gen.materialsproject.org? #1

Closed
hongyi-zhao opened this issue Oct 31, 2024 · 6 comments

Comments

@hongyi-zhao
Copy link

I wonder whether HTESP can reproduce the Elastic Constants reported on https://next-gen.materialsproject.org, e.g., this one: https://next-gen.materialsproject.org/materials/mp-126?

image

Regards,
Zhao

@Neraaz
Copy link
Owner

Neraaz commented Oct 31, 2024

Hi Zhao,

Thank you for the questions. I’ve reproduced results for SrAl₄ (mp-2775) and BaAl₄ (mp-1903) using the older Materials Project database (https://legacy.materialsproject.org/), where calculations were reported for the PBE functional. In the newer database versions, I occasionally observed discrepancies, likely due to the use of different exchange-correlation functionals, such as r2SCAN. I recommend reproducing the results with PBE first, as the reported values in the current Materials Project database might not consistently reflect PBE. Additionally, for elastic calculations, a much denser k-mesh or a higher energy cutoff is necessary compared to simple ground-state calculations.

Best,
Niraj

@hongyi-zhao
Copy link
Author

hongyi-zhao commented Oct 31, 2024

Recently, I tried using atomate2 with the following script to reproduce the Elastic Constants of mp-126 in the newer database:

$ cat mp-elastic.py
# The final result is very different from: https://next-gen.materialsproject.org/materials/mp-126
#$ pyenv shell datasci 
#$ module load vasp
#$ python $0

import numpy as np
from jobflow import run_locally
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer

from atomate2.common.schemas.elastic import ElasticDocument
from atomate2.vasp.flows.elastic import ElasticMaker
from atomate2.vasp.powerups import (
    update_user_incar_settings,
    update_user_potcar_functional,
    update_user_kpoints_settings,
)

from pymatgen.core import Structure
from mp_api.client import MPRester

from atomate2.vasp.powerups import add_metadata_to_flow

user_potcar_functional = "PBE_64"

with MPRester() as mpr:
    elasticity_docs = mpr.materials.elasticity.search(material_ids=["mp-126"])
    structure = elasticity_docs[0].structure

structure = SpacegroupAnalyzer(structure).get_conventional_standard_structure()

flow = ElasticMaker().make(structure, conventional=True)

flow = update_user_incar_settings(flow, {
    "GGA": "PE", 
    "ISMEAR": 2,   
    "SIGMA": 0.05
})

flow = update_user_potcar_functional(flow, user_potcar_functional)

# (Optional) add metadata to the flow task document.
# Could be useful to filter specific results from the database.
# For e.g., adding material project ID for the compound, use following lines
flow = add_metadata_to_flow(
    flow=flow,
    additional_fields={"mp_id": "mp-126", "submission_label": "mp-126_elastic_tensor-GGA-PE"},
)

responses = run_locally(flow, create_folders=True, ensure_success=True)
elastic_output = responses[flow.jobs[-1].uuid][1].output

matrix = np.array(elastic_output.elastic_tensor.ieee_format)
np.set_printoptions(precision=4, suppress=True)
print(matrix)

The result is as follows:

[[329.1842 202.1619 202.1619   0.       0.      -0.    ]
 [202.1619 329.1842 202.1619   0.       0.      -0.    ]
 [202.1619 202.1619 329.1842   0.       0.      -0.    ]
 [  0.       0.       0.      72.9088  -0.       0.    ]
 [  0.       0.       0.      -0.      72.9088   0.    ]
 [ -0.      -0.      -0.       0.       0.      72.9088]]

Could you please give me some hints on how to adjust the above script?

In the newer database versions, I occasionally observed discrepancies, likely due to the use of different exchange-correlation functionals, such as r2SCAN.

Do you have checked the detailed tasks list corresponding to a specific material, say this one in the case:
https://next-gen.materialsproject.org/materials/mp-126/tasks

image

The GGA Deformation should correspond to the elastic computations.

Regards,
Zhao

@Neraaz
Copy link
Owner

Neraaz commented Oct 31, 2024

HTESP utilizes the Pymatgen package to calculate elastic constants. You can find more details on Pymatgen’s elasticity module (https://pymatgen.org/pymatgen.analysis.elasticity.html#module-pymatgen.analysis.elasticity).

I haven't worked with the Atomate2 package yet, so I can't provide a specific answer regarding its integration or use. I recommend reaching out directly to the Atomate2 development team, as they may be able to offer more targeted guidance for your questions.

Best,
Niraj

@hongyi-zhao
Copy link
Author

hongyi-zhao commented Nov 1, 2024

We can use the following method to identify the logical relationships of the actual input files used by a specific computational task. Say, for this one: https://next-gen.materialsproject.org/materials/mp-126/tasks, take one of the GGA Deformation tasks, then the previous structure optimization task for this can be identified as follows:

In [29]: from mp_api.client import MPRester
    ...: from pymatgen.core.structure import Structure
    ...: from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
    ...: 
    ...: with MPRester() as mpr:
    ...:     # 获取形变计算的input_structure信息
    ...:     deform_task = mpr.materials.tasks.search(task_ids=["mp-2383896"])[0]
    ...:     input_dict = deform_task.transformations['history'][0]['input_structure']
    ...:     input_structure = Structure.from_dict(input_dict)
    ...: 
    ...:     # 标准化input结构
    ...:     sga_input = SpacegroupAnalyzer(input_structure)
    ...:     std_input = sga_input.get_conventional_standard_structure()
    ...: 
    ...:     print("=== Deformation Task Input Structure (Standardized) ===")
    ...:     print(std_input)
    ...: 
    ...:     # 搜索匹配的结构优化计算
    ...:     material_doc = mpr.materials.search(material_ids=["mp-126"])[0]
    ...:     calc_types = material_doc.calc_types
    ...: 
    ...:     for mpid, calc_type in calc_types.items():
    ...:         task_doc = mpr.materials.tasks.search(task_ids=[mpid])[0]
    ...: 
    ...:         if hasattr(task_doc, 'output') and hasattr(task_doc.output, 'structure'):
    ...:             opt_structure = task_doc.output.structure
    ...:             # 标准化优化结构
    ...:             sga_opt = SpacegroupAnalyzer(opt_structure)
    ...:             std_opt = sga_opt.get_conventional_standard_structure()
    ...: 
    ...:             # 直接比较标准化后的结构
    ...:             if std_input == std_opt:
    ...:                 print("\n=== Matching Structure Optimization ===")
    ...:                 print(f"Task ID: {mpid}")
    ...:                 print(f"Calc Type: {calc_type}")
    ...:                 print("Standardized Structure:")
    ...:                 print(std_opt)
    ...: 
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 14463.12it/s]
=== Deformation Task Input Structure (Standardized) ===
Full Formula (Pt4)
Reduced Formula: Pt
abc   :   3.976419   3.976419   3.976419
angles:  90.000000  90.000000  90.000000
pbc   :       True       True       True
Sites (4)
  #  SP      a    b    c
---  ----  ---  ---  ---
  0  Pt    0    0    0
  1  Pt    0    0.5  0.5
  2  Pt    0.5  0    0.5
  3  Pt    0.5  0.5  0
Retrieving MaterialsDoc documents: 100%|█████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12052.60it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12264.05it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12052.60it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11214.72it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11848.32it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12264.05it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11915.64it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11305.40it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11881.88it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12264.05it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11748.75it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11683.30it/s]
Retrieving TaskDoc documents: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 8422.30it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12372.58it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12018.06it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12228.29it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12595.51it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12520.31it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12228.29it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12052.60it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12336.19it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12087.33it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11554.56it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12052.60it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11983.73it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12710.01it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12157.40it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12052.60it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11983.73it/s]

=== Matching Structure Optimization ===
Task ID: mp-2383760
Calc Type: GGA Structure Optimization
Standardized Structure:
Full Formula (Pt4)
Reduced Formula: Pt
abc   :   3.976419   3.976419   3.976419
angles:  90.000000  90.000000  90.000000
pbc   :       True       True       True
Sites (4)
  #  SP      a    b    c
---  ----  ---  ---  ---
  0  Pt    0    0    0
  1  Pt    0    0.5  0.5
  2  Pt    0.5  0    0.5
  3  Pt    0.5  0.5  0
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12409.18it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12192.74it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11683.30it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11915.64it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11554.56it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12446.01it/s]

Furthermore, we can reproduce the corresponding calculation results using the same original input files from each sub-task of the corresponding workflow.

See materialsproject/pymatgen#3884 (reply in thread) for the related discussion.

Regards,
Zhao

@Neraaz
Copy link
Owner

Neraaz commented Nov 1, 2024

Hi Zhao,

Currently, HTESP extracts data only using the materials ID. It would be beneficial to add the capability to extract data based on the task as well, which could be implemented in the near future. Thanks !

Best,
Niraj

@hongyi-zhao
Copy link
Author

hongyi-zhao commented Nov 1, 2024

So far, I have successfully replicated the results reported by the Materials Project, relying entirely on its original data, as demonstrated below.

#$ cat reproduce-mp-elastic.py
#https://github.com/JaGeo/TutorialAtomate2Forcefields/issues/4
#$ pyenv shell datasci 
#$ module load vasp
#$ python $0

#https://materialsproject.github.io/atomate2/user/docs_schemas_emmet.html

# I have successfully replicated the results reported by [the Materials Project](https://next-gen.materialsproject.org/materials/mp-126), relying entirely on its original data, as demonstrated below.
#https://github.com/Neraaz/HTESP/issues/1#issuecomment-2451363600

import numpy as np
from jobflow import run_locally
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
from atomate2.vasp.flows.elastic import ElasticMaker
from atomate2.vasp.powerups import (
    update_user_incar_settings,
    update_user_potcar_functional,
    update_user_kpoints_settings,
)
from pymatgen.io.vasp.inputs import Kpoints
from pymatgen.core import Structure
from mp_api.client import MPRester
from atomate2.vasp.powerups import add_metadata_to_flow
#https://github.com/materialsproject/atomate2/issues/1014#issuecomment-2454955891
from atomate2.vasp.flows.mp import MPGGADoubleRelaxMaker, MPGGAStaticMaker

# All the following versions are the same one in this case:
#werner@x13dai-t:~/Public/hpc/vasp/pot$ ug 'PAW_PBE Pt ' 
#potcar/POTPAW_PBE_52/Pt/PSCTR:   TITEL  = PAW_PBE Pt 04Feb2005
#potcar/POTPAW_PBE_52/Pt/POTCAR:  PAW_PBE Pt 04Feb2005                   
#potcar/POTPAW_PBE_52/Pt/POTCAR:   TITEL  = PAW_PBE Pt 04Feb2005
#potcar/POT_PAW_PBE_64/Pt/PSCTR:   TITEL  = PAW_PBE Pt 04Feb2005
#potcar/POT_PAW_PBE_64/Pt/POTCAR:  PAW_PBE Pt 04Feb2005                   
#potcar/POT_PAW_PBE_64/Pt/POTCAR:   TITEL  = PAW_PBE Pt 04Feb2005
#potcar/POTPAW_PBE_54/Pt/PSCTR:   TITEL  = PAW_PBE Pt 04Feb2005
#potcar/POTPAW_PBE_54/Pt/POTCAR:  PAW_PBE Pt 04Feb2005                   
#potcar/POTPAW_PBE_54/Pt/POTCAR:   TITEL  = PAW_PBE Pt 04Feb2005

#user_potcar_functional = "PBE_64"
#user_potcar_functional = "PBE_52_W_HASH"
#user_potcar_functional = "PBE_54_W_HASH"

#要复现MP,根据下面的检查,应该设置potcar版本与MP官方使用的一致。

#In [4]: from mp_api.client import MPRester
#   ...: 
#   ...: material_id = "mp-126"
#   ...: with MPRester() as mpr:
#   ...:     # 获取elastic数据来获取task id
#   ...:     elasticity_doc = mpr.materials.elasticity.search(material_ids=[material_id])
#   ...:     opt_id = elasticity_doc[0].fitting_data.optimization_task.string
#   ...: 
#   ...:     # 使用task id获取详细信息
#   ...:     opt_doc = mpr.materials.tasks.search([opt_id],
#   ...:         fields=["input", "calcs_reversed"])
#   ...: 
#   ...:     # 提取 potcar_spec
#   ...:     potcar_spec = opt_doc[0].calcs_reversed[0].input.potcar_spec
#   ...:     print(f"POTCAR specifications: {potcar_spec}")
#   ...: 
#Retrieving ElasticityDoc documents: 100%|█████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 7543.71it/s]
#Retrieving TaskDoc documents: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 9892.23it/s]
#POTCAR specifications: [PotcarSpec(titel='PAW_PBE Pt 05Jan2001', hash='a604ea3c6a9cc23c739b762f625cf449', summary_stats=None)]

#In [4]: opt_doc[0].calcs_reversed[0].input.potcar_spec
#Out[4]: [PotcarSpec(titel='PAW_PBE Pt 05Jan2001', hash='a604ea3c6a9cc23c739b762f625cf449', summary_stats=None)]

#https://github.com/materialsproject/api/issues/944#issuecomment-2503063154
user_potcar_functional = "PBE"

# 实际测试表明,不同的vasp版本的计算结果是一致的(差别很小,可以忽略):
#In [5]: # MP所使用的vasp版本:
#   ...: for calc in opt_doc[0].calcs_reversed:
#   ...:     print(calc.vasp_version)
#   ...: 
#5.4.4
#5.4.4

material_id = "mp-126"
with MPRester() as mpr:
    # Obtain elastic data and the related task IDs.
    elasticity_doc = mpr.materials.elasticity.search(material_ids=[material_id])
    opt_id = elasticity_doc[0].fitting_data.optimization_task.string
    first_deform_id = str(elasticity_doc[0].fitting_data.deformation_tasks[0])
    opt_doc = mpr.materials.tasks.search([opt_id],
        fields=["input", "orig_inputs", "calcs_reversed"])

    deform_dep_doc = mpr.materials.tasks.search([first_deform_id],
        fields=["input", "orig_inputs", "calcs_reversed"])

structure = mpr.materials.get_structure_by_material_id(material_id)
structure = SpacegroupAnalyzer(structure).get_conventional_standard_structure()

# Process kpoints settings
#opt_kpoints_settings = opt_doc[0].orig_inputs.kpoints
#deform_kpoints_settings = deform_dep_doc[0].orig_inputs.kpoints

# Use calcs-reversed to do the trick:
#https://materialsproject.github.io/atomate2/user/docs_schemas_emmet.html#calcs-reversed
opt_kpoints_settings = opt_doc[0].calcs_reversed[0].input.kpoints
deform_kpoints_settings = deform_dep_doc[0].calcs_reversed[0].input.kpoints

# Process INCAR settings
# Adopt the following strategy: based on the keys in `orig_inputs.incar`, use the corresponding values from `input.parameters`.
# This can be simplified into a one-liner dictionary comprehension:

#opt_incar_settings = {key: opt_doc[0].input.parameters[key] for key in opt_doc[0].orig_inputs.incar.keys() if key in opt_doc[0].input.parameters}
#deform_incar_settings = {key: deform_dep_doc[0].input.parameters[key] for key in deform_dep_doc[0].orig_inputs.incar.keys() if key in deform_dep_doc[0].input.parameters}

# Or, for better readability, you can first define variables and then achieve it as following:
#orig_incar = opt_doc[0].orig_inputs.incar
#input_params = opt_doc[0].input.parameters
#opt_incar_settings = {key: input_params[key] for key in orig_incar.keys() if key in input_params}

#orig_incar = deform_dep_doc[0].orig_inputs.incar
#input_params = deform_dep_doc[0].input.parameters
#deform_incar_settings = {key: input_params[key] for key in orig_incar.keys() if key in input_params}

# Use calcs-reversed to do the trick:
#https://materialsproject.github.io/atomate2/user/docs_schemas_emmet.html#calcs-reversed
opt_incar_settings = opt_doc[0].calcs_reversed[0].input.incar
deform_incar_settings = deform_dep_doc[0].calcs_reversed[0].input.incar

# Handle MAGMOM settings correctly.
if isinstance(opt_incar_settings.get("MAGMOM", []), list):
    magmoms = {}
    for idx, site in enumerate(structure):
        if idx < len(opt_incar_settings.get("MAGMOM", [])):
            magmoms[site.species_string] = opt_incar_settings["MAGMOM"][idx]
    opt_incar_settings["MAGMOM"] = magmoms


if isinstance(deform_incar_settings.get("MAGMOM", []), list):
    magmoms = {}
    for idx, site in enumerate(structure):
        if idx < len(deform_incar_settings.get("MAGMOM", [])):
            magmoms[site.species_string] = deform_incar_settings["MAGMOM"][idx]
    deform_incar_settings["MAGMOM"] = magmoms


#Re: The meaning of "GGA = --".
#https://www.vasp.at/forum/viewtopic.php?p=29678#p29678
#If the GGA tag is not explicitly specified in INCAR, then the functional from the POTCAR (usually PBE) is used. With older VASP versions, this was indicated with "GGA = --" in OUTCAR. Since VASP.6.4.3 this is properly indicated with "GGA = PE".

#In [3]: opt_doc[0].input.parameters['GGA']
#Out[3]: '--'

#In [34]: opt_doc[0].calcs_reversed[0].input.potcar
#Out[34]: ['Pt']

#In [35]: opt_doc[0].calcs_reversed[0].input.potcar_spec
#Out[35]: [PotcarSpec(titel='PAW_PBE Pt 05Jan2001', hash='a604ea3c6a9cc23c739b762f625cf449', summary_stats=None)]

#In [36]: opt_doc[0].calcs_reversed[0].input.potcar_type
#Out[36]: ['PAW_PBE']

flow = ElasticMaker(
    bulk_relax_maker=MPGGADoubleRelaxMaker(),  # 使用MP的双重优化设置
    elastic_relax_maker=MPGGAStaticMaker(),    # 使用MP的静态计算设置
    ).make(structure, conventional=True)
flow = update_user_potcar_functional(flow, user_potcar_functional)

flow = update_user_kpoints_settings(flow, opt_kpoints_settings, name_filter="MP GGA relax")
flow = update_user_kpoints_settings(flow, deform_kpoints_settings, name_filter="MP GGA static")

flow = update_user_incar_settings(flow, opt_incar_settings, name_filter="MP GGA relax" )
flow = update_user_incar_settings(flow, deform_incar_settings, name_filter="MP GGA static")

# Add metadata.
#flow = add_metadata_to_flow(
#    flow=flow,
#    additional_fields={
#        "mp_id": "mp-126", 
#        "submission_label": "mp-126_elastic_tensor-GGA-PE"
#    },
#)

# Run the flow
responses = run_locally(flow, create_folders=True, ensure_success=True)
elastic_output = responses[flow.jobs[-1].uuid][1].output
matrix = np.array(elastic_output.elastic_tensor.ieee_format)
np.set_printoptions(precision=4, suppress=True)
print(matrix)

The result is as follows:

$ module load vasp/5.4.4.pl2-oneapi.2022.3.0
$ pyenv shell datasci
$ python reproduce-mp-elastic.py
[[299.9534 221.5266 221.5266   0.       0.      -0.    ]
 [221.5266 299.9534 221.5266   0.       0.      -0.    ]
 [221.5266 221.5266 299.9534   0.       0.      -0.    ]
 [  0.       0.       0.      58.8789  -0.       0.    ]
 [  0.       0.       0.      -0.      58.8789   0.    ]
 [ -0.      -0.      -0.       0.       0.      58.8789]]

According to the documentation here, if we use the default <factory> makers of ElasticMaker implemented by atomate2, for our purpose in this case, the flow should be something like the following:

flow = ElasticMaker(
    #bulk_relax_maker=MPGGADoubleRelaxMaker(),  # 使用MP的双重优化设置
    #elastic_relax_maker=MPGGAStaticMaker(),    # 使用MP的静态计算设置
    ).make(structure, conventional=True)

# See https://materialsproject.github.io/atomate2/user/codes/vasp.html
# Based on testing, in this case, `user_potcar_functiona = "PBE"` doesn't work here.
user_potcar_functional = "PBE_54"
flow = update_user_potcar_functional(flow, user_potcar_functiona)

flow = update_user_kpoints_settings(flow, opt_kpoints_settings, name_filter="tight relax")
flow = update_user_kpoints_settings(flow, deform_kpoints_settings, name_filter="elastic relax")

flow = update_user_incar_settings(flow, opt_incar_settings, name_filter="tight relax" )
flow = update_user_incar_settings(flow, deform_incar_settings, name_filter="elastic relax")

flow = update_user_incar_settings(flow, {"GGA":"PE"} )

The result is as follows:

[[302.4796 222.4695 222.4695   0.       0.      -0.    ]
 [222.4695 302.4796 222.4695   0.       0.      -0.    ]
 [222.4695 222.4695 302.4796   0.       0.      -0.    ]
 [  0.       0.       0.      59.107   -0.       0.    ]
 [  0.       0.       0.      -0.      59.107    0.    ]
 [ -0.      -0.      -0.       0.       0.      59.107 ]]

Based on my testing, when using the default <factory> makers of ElasticMaker in atomate2, user_potcar_functional = "PBE" doesn't work, the errors are as follows:

Retrieving ElasticityDoc documents: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11066.77it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11748.75it/s]
Retrieving TaskDoc documents: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 11397.57it/s]
Retrieving MaterialsDoc documents: 100%|█████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 12052.60it/s]
/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/pymatgen/io/vasp/sets.py:288: BadInputSetWarning: Overriding the POTCAR functional is generally not recommended  as it significantly affects the results of calculations and compatibility with other calculations done with the same input set. Note that some POTCAR symbols specified in the configuration file may not be available in the selected functional.
  warnings.warn(
2024-12-03 15:15:25,322 INFO Started executing jobs locally
INFO:jobflow.managers.local:Started executing jobs locally
2024-12-03 15:15:25,326 INFO Starting job - tight relax 1 (b1114acc-f678-422c-b7be-507d466d84b7)
INFO:jobflow.core.job:Starting job - tight relax 1 (b1114acc-f678-422c-b7be-507d466d84b7)
2024-12-03 15:17:59,916 INFO Finished job - tight relax 1 (b1114acc-f678-422c-b7be-507d466d84b7)
INFO:jobflow.core.job:Finished job - tight relax 1 (b1114acc-f678-422c-b7be-507d466d84b7)
2024-12-03 15:17:59,916 WARNING Response.stored_data is not supported with local manager.
WARNING:jobflow.managers.local:Response.stored_data is not supported with local manager.
2024-12-03 15:17:59,916 INFO Starting job - tight relax 2 (fe53b8e8-73cd-4d92-9d8b-0b7b554edc80)
INFO:jobflow.core.job:Starting job - tight relax 2 (fe53b8e8-73cd-4d92-9d8b-0b7b554edc80)
/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/common/files.py:268: UserWarning: /home/werner/test/job_2024-12-03-07-17-59-916535-18175/INCAR is not gzipped, skipping...
  file_client.gunzip(directory / file, host=host, force=force)
/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/common/files.py:268: UserWarning: /home/werner/test/job_2024-12-03-07-17-59-916535-18175/OUTCAR is not gzipped, skipping...
  file_client.gunzip(directory / file, host=host, force=force)
/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/common/files.py:268: UserWarning: /home/werner/test/job_2024-12-03-07-17-59-916535-18175/CONTCAR is not gzipped, skipping...
  file_client.gunzip(directory / file, host=host, force=force)
/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/common/files.py:268: UserWarning: /home/werner/test/job_2024-12-03-07-17-59-916535-18175/vasprun.xml is not gzipped, skipping...
  file_client.gunzip(directory / file, host=host, force=force)
/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/common/files.py:268: UserWarning: /home/werner/test/job_2024-12-03-07-17-59-916535-18175/POTCAR is not gzipped, skipping...
  file_client.gunzip(directory / file, host=host, force=force)
/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/common/files.py:268: UserWarning: /home/werner/test/job_2024-12-03-07-17-59-916535-18175/KPOINTS is not gzipped, skipping...
  file_client.gunzip(directory / file, host=host, force=force)
ERROR:VasprunXMLValidator:Failed to load vasprun.xml
Traceback (most recent call last):
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/custodian/vasp/validators.py", line 33, in check
    load_vasprun(os.path.join(directory, "vasprun.xml"))
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/custodian/utils.py", line 80, in __call__
    result = self.func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/custodian/vasp/io.py", line 21, in load_vasprun
    return Vasprun(filepath, **vasprun_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/pymatgen/io/vasp/outputs.py", line 336, in __init__
    self._parse(
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/pymatgen/io/vasp/outputs.py", line 384, in _parse
    for event, elem in ET.iterparse(stream, events=["start", "end"]):
  File "/home/werner/.pyenv/versions/3.11.1/lib/python3.11/xml/etree/ElementTree.py", line 1255, in iterator
    root = pullparser._close_and_return_root()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/.pyenv/versions/3.11.1/lib/python3.11/xml/etree/ElementTree.py", line 1298, in _close_and_return_root
    root = self._parser.close()
           ^^^^^^^^^^^^^^^^^^^^
xml.etree.ElementTree.ParseError: no element found: line 2544, column 0
ERROR:custodian.custodian:Validation failed: VasprunXMLValidator
2024-12-03 15:21:24,003 INFO tight relax 2 failed with exception:
Traceback (most recent call last):
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/jobflow/managers/local.py", line 114, in _run_job
    response = job.run(store=store)
               ^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/jobflow/core/job.py", line 600, in run
    response = function(*self.function_args, **self.function_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/vasp/jobs/base.py", line 228, in make
    run_vasp(**self.run_vasp_kwargs)
  File "/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/vasp/run.py", line 161, in run_vasp
    custodian_manager.run()
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/custodian/custodian.py", line 385, in run
    self._run_job(job_n, job)
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/custodian/custodian.py", line 513, in _run_job
    raise ValidationError(msg, raises=True, validator=validator)
custodian.custodian.ValidationError: Validation failed: VasprunXMLValidator

INFO:jobflow.managers.local:tight relax 2 failed with exception:
Traceback (most recent call last):
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/jobflow/managers/local.py", line 114, in _run_job
    response = job.run(store=store)
               ^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/jobflow/core/job.py", line 600, in run
    response = function(*self.function_args, **self.function_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/vasp/jobs/base.py", line 228, in make
    run_vasp(**self.run_vasp_kwargs)
  File "/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/vasp/run.py", line 161, in run_vasp
    custodian_manager.run()
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/custodian/custodian.py", line 385, in run
    self._run_job(job_n, job)
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/custodian/custodian.py", line 513, in _run_job
    raise ValidationError(msg, raises=True, validator=validator)
custodian.custodian.ValidationError: Validation failed: VasprunXMLValidator

2024-12-03 15:21:24,004 INFO Starting job - fit_elastic_tensor (dc3c5c30-c52d-4e97-aa06-bc3a6380282e)
INFO:jobflow.core.job:Starting job - fit_elastic_tensor (dc3c5c30-c52d-4e97-aa06-bc3a6380282e)
2024-12-03 15:21:24,022 INFO fit_elastic_tensor failed with exception:
Traceback (most recent call last):
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/jobflow/managers/local.py", line 114, in _run_job
    response = job.run(store=store)
               ^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/jobflow/core/job.py", line 600, in run
    response = function(*self.function_args, **self.function_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/common/jobs/elastic.py", line 218, in fit_elastic_tensor
    for data in deformation_data:
TypeError: 'NoneType' object is not iterable

INFO:jobflow.managers.local:fit_elastic_tensor failed with exception:
Traceback (most recent call last):
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/jobflow/managers/local.py", line 114, in _run_job
    response = job.run(store=store)
               ^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/jobflow/core/job.py", line 600, in run
    response = function(*self.function_args, **self.function_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/werner/Public/repo/github.com/materialsproject/atomate2.git/src/atomate2/common/jobs/elastic.py", line 218, in fit_elastic_tensor
    for data in deformation_data:
TypeError: 'NoneType' object is not iterable

2024-12-03 15:21:24,022 INFO Finished executing jobs locally
INFO:jobflow.managers.local:Finished executing jobs locally
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[15], line 171
    159 flow = update_user_incar_settings(flow, {"GGA":"PE"} )
    161 # Add metadata.
    162 #flow = add_metadata_to_flow(
    163 #    flow=flow,
   (...)
    169 
    170 # Run the flow
--> 171 responses = run_locally(flow, create_folders=True, ensure_success=True)
    172 elastic_output = responses[flow.jobs[-1].uuid][1].output
    173 matrix = np.array(elastic_output.elastic_tensor.ieee_format)

File ~/.pyenv/versions/3.11.1/envs/datasci/lib/python3.11/site-packages/jobflow/managers/local.py:181, in run_locally(flow, log, store, create_folders, root_dir, ensure_success, allow_external_references, raise_immediately)
    178 logger.info("Finished executing jobs locally")
    180 if ensure_success and not finished_successfully:
--> 181     raise RuntimeError("Flow did not finish running successfully")
    183 return dict(responses)

RuntimeError: Flow did not finish running successfully

As you can see, the result is the same as the one reported by the Materials Project:

In [8]: from mp_api.client import MPRester
   ...: 
   ...: with MPRester() as mpr:
   ...:     elasticity_doc = mpr.materials.elasticity.search(material_ids=["mp-126"])
   ...:     print(elasticity_doc[0].elastic_tensor.raw)
   ...: 
Retrieving ElasticityDoc documents: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 17924.38it/s]
((300.4965181204997, 221.77204403016452, 221.77204403016452, 1.5543122344752188e-15, 1.3322676295501875e-15, 5.551115123125781e-15), (221.77204403016452, 300.4965181204997, 221.77204403016458, 1.3322676295501875e-15, 1.5543122344752188e-15, 2.791547977519229e-14), (221.77204403016452, 221.77204403016458, 300.49651812049973, 6.661338147750939e-16, 5.551115123125784e-15, 1.5543122344752182e-15), (1.5543122344752188e-15, 1.3322676295501875e-15, 6.661338147750939e-16, 57.738028947926864, 0.0, -2.440413917789469e-31), (1.3322676295501875e-15, 1.5543122344752188e-15, 5.551115123125784e-15, 0.0, 57.73802894792688, -1.602552228361556e-15), (5.551115123125781e-15, 2.791547977519229e-14, 1.5543122344752182e-15, -2.440413917789469e-31, -1.602552228361556e-15, 57.73802894792694))

image

Next, I will use the above method to reproduce the elastic constants of https://next-gen.materialsproject.org/materials/mp-126 with HTESP.

See below for the related discussions:
materialsproject/jobflow#700
materialsproject/api#944 (comment)

Regards,
Zhao

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants