@mcp.tool()
def get_elastic_properties(
material_id: str,
) -> str:
"""
Get elastic and mechanical properties for a material.
Args:
material_id: Materials Project ID (e.g., "mp-149" for Silicon)
Returns:
JSON with elastic properties including bulk modulus, shear modulus,
Young's modulus, Poisson's ratio, and elastic tensor
"""
has_key, key_or_error = check_api_key()
if not has_key:
return json.dumps({"error": key_or_error})
try:
from mp_api.client import MPRester
with MPRester(key_or_error) as mpr:
# Get elasticity data
docs = mpr.materials.elasticity.search(
material_ids=[material_id],
)
if not docs:
return json.dumps({
"material_id": material_id,
"error": "No elastic data available for this material",
"note": "Elastic properties are only computed for a subset of materials",
})
doc = docs[0]
# Extract elastic properties
properties = {
"material_id": material_id,
"formula": doc.formula_pretty if hasattr(doc, 'formula_pretty') else None,
# Voigt-Reuss-Hill averages (most commonly used)
"bulk_modulus_vrh_GPa": doc.bulk_modulus.vrh if doc.bulk_modulus else None,
"shear_modulus_vrh_GPa": doc.shear_modulus.vrh if doc.shear_modulus else None,
"youngs_modulus_GPa": doc.young_modulus if hasattr(doc, 'young_modulus') else None,
"poisson_ratio": doc.homogeneous_poisson if hasattr(doc, 'homogeneous_poisson') else None,
# Voigt bounds (upper)
"bulk_modulus_voigt_GPa": doc.bulk_modulus.voigt if doc.bulk_modulus else None,
"shear_modulus_voigt_GPa": doc.shear_modulus.voigt if doc.shear_modulus else None,
# Reuss bounds (lower)
"bulk_modulus_reuss_GPa": doc.bulk_modulus.reuss if doc.bulk_modulus else None,
"shear_modulus_reuss_GPa": doc.shear_modulus.reuss if doc.shear_modulus else None,
# Derived properties
"universal_anisotropy": doc.universal_anisotropy if hasattr(doc, 'universal_anisotropy') else None,
"debye_temperature_K": doc.debye_temperature if hasattr(doc, 'debye_temperature') else None,
# Classification - convert enum to string
"state": str(doc.state.value) if hasattr(doc, 'state') and hasattr(doc.state, 'value') else (str(doc.state) if hasattr(doc, 'state') else None),
}
# Add elastic tensor if available (6x6 Voigt notation)
if hasattr(doc, 'elastic_tensor') and doc.elastic_tensor:
tensor = doc.elastic_tensor
if hasattr(tensor, 'ieee_format'):
properties["elastic_tensor_GPa"] = tensor.ieee_format
elif hasattr(tensor, 'raw'):
properties["elastic_tensor_GPa"] = tensor.raw
return json.dumps(properties, indent=2)
except Exception as e:
return json.dumps({"error": str(e)})