In [1]:
import numpy as np
import escape as esc

esc.require("0.9.8")
Loading material database from C:\dev\escape-core\notebooks\repository\scattering\materials.db

Overview of the Material Database Module¶

The material database in ESCAPE stores reusable information about common materials: their names, chemical composition, density, and scattering-related constants. Instead of redefining that information in every notebook, you can load it from the database and focus on the actual model you want to build.

This notebook explains how the database is organized, how to inspect records, and how to add your own entries when needed.

In [2]:
esc.copy_db(overwrite=True)
Material database file materials.yaml has been successfully copied to C:\dev\escape-core\notebooks\repository\scattering

The copy of the material database file is stored in the current working directory.

In order to compile the new material database, the user should create an instance of the new material database using mdb method. This method will look for the YAML material database file in the current working directory and will compile the material database from the YAML file. The compiled material database is stored in the current working directory and is used by default. If the local MDB file is not found, the method will look for the MDB file in the specific folder of the package.

In the newly created materials.yaml file, the user can add new material records or edit existing ones.

As an example we add a new record:

---
name: Polybutadiene_custom
type: amorphous
density: 0.436
atoms:
  - C:
      repeat: 4
  - H:
      repeat: 6

In order to use it, we need to create a new instance of the material database:

In [3]:
custom_mdb = esc.mdb()
custom_mdb.add({
    "name": "Polybutadiene_custom",
    "type": "amorphous",
    "density": 0.436,
    "atoms": [
        {"C": {"repeat": 4}},
        {"H": {"repeat": 6}},
    ],
})
mat = esc.amorphous("Polybutadiene_custom", density="mdb", mdb=custom_mdb)
print(mat)
Loading material database from C:\dev\escape-core\notebooks\repository\scattering\materials.db

Name: Polybutadiene_custom	Parameters number:          1
Parameter           	Value          	+-	Error     	Units     	Fixed
Polybutadiene_custom density	          0.436	+-	0         	g/cm^3    	    0

The new material records can be added inline to the default or custom material database using the :meth:add_material method. In this case the new material record is not stored in the YAML file, but is added to the material database instance. It is useful for testing purposes or if the user prefers to work with temporary material records only. The information about new material records is lost when the material database instance is deleted.

In [4]:
from escape.scattering.mdb import default_mdb

rec = {
    "name": "Polybutadiene_custom",
    "type": "amorphous",
    "density": 0.436,
    "atoms": [
        {"C": {"repeat": 4}},
        {"H": {"repeat": 6}},
    ],
}
default_mdb.add(rec)
# mdb=default_mdb by default
mat = esc.amorphous("Polybutadiene_custom", density="mdb")
print(mat)
Name: Polybutadiene_custom	Parameters number:          1
Parameter           	Value          	+-	Error     	Units     	Fixed
Polybutadiene_custom density	          0.436	+-	0         	g/cm^3    	    0

Radiation sources¶

A source_obj defines the radiation type and wavelength used in SLD and reflectivity calculations. ESCAPE provides two constructors:

Constructor Radiation Typical wavelength
esc.xrays(wavelength, units) X-rays 1.54 Å (Cu Kα), 0.154 nm
esc.neutrons(wavelength, units) Neutrons 1–5 Å, 0.1–0.5 nm

Wavelength units are "angstrom" (default) or "nm".

The source object is passed to specrefl, pnrspec, and multilayer.show to select the correct scattering factors.

In [5]:
# X-ray source: Cu Kα (1.54056 Å)
src_xr = esc.xrays(1.54056)
print(f"type={src_xr.type}, wavelength={src_xr.wavelength} {src_xr.units}")

# Neutron source: 4.5 Å cold neutrons
src_n = esc.neutrons(4.5)
print(f"type={src_n.type}, wavelength={src_n.wavelength} {src_n.units}")

# Using nm units
src_xr_nm = esc.xrays(0.154056, units="nm")
print(f"type={src_xr_nm.type}, wavelength={src_xr_nm.wavelength} {src_xr_nm.units}")
type=xrays, wavelength=1.54056 angstrom
type=neutrons, wavelength=4.5 angstrom
type=xrays, wavelength=0.154056 nm

Querying the material database¶

The mdb_obj exposes two lists of available material names: crystals and amorphs. You can also query scattering factors for individual elements using mdb.sf(element, source).

In [6]:
from escape.scattering.mdb import default_mdb

# List available crystal and amorphous materials
print("Crystals:", default_mdb.crystals[:10], "...")
print("Amorphous:", default_mdb.amorphs[:10], "...")

# Scattering factor for Ni at Cu Kα
sf_Ni = default_mdb.sf("Ni", src_xr)
print(f"Ni scattering factor at Cu Kα: {sf_Ni}")

# Density from MDB
print(f"Ni amorphous density: {default_mdb.amorph_density('Ni')} g/cm³")
print(f"Si amorphous density: {default_mdb.amorph_density('Si')} g/cm³")
Crystals: ['ADP', 'AlAs', 'AlFe3', 'AlN', 'AlP', 'AlSb', 'Aluminium', 'BaSnO3', 'BaTiO3', 'Beril'] ...
Amorphous: ['Li', 'Be', 'B', 'C', 'Na', 'Mg', 'Al', 'Si', 'P', 'S'] ...
Ni scattering factor at Cu Kα: (0.0007046310642343132-1.4769415982736352e-05j)
Ni amorphous density: 8.902000427246094 g/cm³
Si amorphous density: 2.3299999237060547 g/cm³

Computing SLD values¶

Given a material and a source, material_obj.sld0(source) returns the zero-order SLD as a complex number. This is useful for checking SLD values before building a model.

In [7]:
Ni_mat = esc.amorphous("Ni", density="mdb")
Si_mat = esc.amorphous("Si", density="mdb")

sld_Ni_xr = Ni_mat.sld0(src_xr)
sld_Si_xr = Si_mat.sld0(src_xr)
sld_Ni_n  = Ni_mat.sld0(src_n)
sld_Si_n  = Si_mat.sld0(src_n)

print(f"Ni  X-ray SLD: {sld_Ni_xr:.4e} Å⁻²")
print(f"Si  X-ray SLD: {sld_Si_xr:.4e} Å⁻²")
print(f"Ni  neutron SLD: {sld_Ni_n:.4e} Å⁻²")
print(f"Si  neutron SLD: {sld_Si_n:.4e} Å⁻²")
Ni  X-ray SLD: 6.4359e-05-1.3490e-06j Å⁻²
Si  X-ray SLD: 2.0070e-05-4.5742e-07j Å⁻²
Ni  neutron SLD: 9.4078e-06-1.1404e-09j Å⁻²
Si  neutron SLD: 2.0737e-06-2.3758e-11j Å⁻²
In [ ]: