import numpy as np
import escape as esc
esc.require('0.9.7')
from escape.utils.widgets import show
Loading material database from /home/dkor/Data/Development/workspace_escape/escape/notebooks/repository/scattering/materials.db
Overview of Material Module¶
In ESCAPE version <=0.9.6
the escape.scattering.material
module contained only generic methods for creating amorphous and crystalline material objects.
These generic helper methods are not very convenient because they require the user to define scattering length density parameters with initial values.
Calculating these values from compound and mass density is straightforward but tedious.
To simplify the input of materials and their parameters, the material database module escape.scattering.mdb
has been created.
The material database module is used by non-generic methods in escape.scattering.material
.
In this notebook we give examples of how to use it.
Amorphous materials¶
There are a number of possible scenarios.
The user wants to create a material object with
- mass density as an independent parameter of the model. The material has a record in the material database.
- mass density as an independent parameter of the model. The material is given by the formula.
- scattering length density as an independent parameter of the model. The material has a record in the Material Database.
- scattering length density as an independent parameter of the model. The material is given by the formula, the density is given as a constant.
Let's look at the first scenario. As material we choose deuterated polystyrene (compound: C8D8) with a mass density of $1.05\;g/cm^3$.
This material has a corresponding record in the Material Database with the name Polystyrene
.
md = esc.par("PS density", 1.05, units="g/cm^3")
PS = esc.amorphous(name="PS", mid="Polystyrene", density=md)
print(PS)
Name: PS Parameters number: 1 Parameter Value +- Error Units Fixed PS density 1.05 +- 0 g/cm^3 0
In the example above, we have defined the density parameter, but we could also use the default density value from the record by using "mdb"
as the density argument.
PS = esc.amorphous(name="Polystyrene", density="mdb")
print(PS)
Name: Polystyrene Parameters number: 1 Parameter Value +- Error Units Fixed Polystyrene density 1.05 +- 0 g/cm^3 0
For the second scenario the density сфт be given as a float constant or parameter, the units for density are always $g/cm^3$.
Mdb
keyword leads to an automatic creation of density parameter using
In this scenario no material records are used from the database, only the chemical element information and the corresponding scattering factor tables.
PS = esc.amorphous(name="Polystyrene", formula="C8H8", density=1.05)
print(PS)
Name: Polystyrene Parameters number: 0 Parameter Value +- Error Units Fixed
For scenario three we should use dwsld0re
and dwsld0im
arguments instead of density
. We set density explicitly to None, saying that we are not going to use it. The dwsld0re
and dwsld0im
arguments are the multiplication factors for the calculated SLD value $\rho_{re} = \rho_{0re}dw_{re}$ and $\rho_{im} = \rho_{0im}dw_{im}$. By default they are equal to None and we should at least set them to one, which means that the scattering length density is calculated using information from the material database, but does not take part in the optimisation.
PS = esc.amorphous(name="Polystyrene", density=None, dwsld0re=1, dwsld0im=1)
#prints nothing
print(PS)
Name: Polystyrene Parameters number: 0 Parameter Value +- Error Units Fixed
Or with dwsld0re
and dwsld0im
as parameters.
dwsld0 = esc.par("dwSLD", 1)
PS = esc.amorphous(name="Polystyrene", density=None, dwsld0re=dwsld0, dwsld0im=dwsld0)
print(PS)
Name: Polystyrene Parameters number: 1 Parameter Value +- Error Units Fixed dwSLD 1 +- 0 0
Or in auto
mode.
PS = esc.amorphous(name="Polystyrene", density=None, dwsld0re="auto", dwsld0im="auto")
print(PS)
Name: Polystyrene Parameters number: 2 Parameter Value +- Error Units Fixed Polystyrene DwSLD0Re 1 +- 0 0 Polystyrene DwSLD0Im 1 +- 0 0
Scenario four is straightforward.
PS = esc.amorphous(name="Polystyrene", formula="C8H8", density=1.05, dwsld0re=dwsld0, dwsld0im=dwsld0)
#prints nothing
print(PS)
Name: Polystyrene Parameters number: 1 Parameter Value +- Error Units Fixed dwSLD 1 +- 0 0
Crystalline materials¶
Crystalline material objects are created in the same way as amorphous material ovjects. The only difference is that they do not support formulas, so there should always be a corresponding record in the material database and only scenarios 1 and 3 listed above are possible.
Below are some examples:
GaAs = esc.crystal(name="GaAs", density="mdb")
print(GaAs)
Name: GaAs Parameters number: 1 Parameter Value +- Error Units Fixed GaAs density 5.3176 +- 0 g/cm^3 0
dwsld0 = esc.par("dwSLD0", 1)
dwsldh = esc.par("dwSLDh", 1)
GaAs = esc.crystal(name="GaAs", density=None, dwsld0re=dwsld0, dwsld0im=dwsld0,
dwsldhre=dwsldh, dwsldhim=dwsldh)
print(GaAs)
Name: GaAs Parameters number: 2 Parameter Value +- Error Units Fixed dwSLD0 1 +- 0 0 dwSLDh 1 +- 0 0
Magnetic material¶
For the case of polarized neutrons and magnetic material, the magnetic scattering length density has to be included in the model.
The user can provide it as a constant value or a parameter using sldm
argument which is None
by default.
Fe = esc.amorphous("Fe", density="mdb", sldm=esc.par(value=5, scale=1e-6, units="1/A^2"))
print(Fe)
Name: Fe Parameters number: 2 Parameter Value +- Error Units Fixed Fe density 7.874 +- 0 g/cm^3 0 Fe SLDm 5 +- 0 x1e-06 1/A^2 0
Gradient materials¶
ESCAPE supports gradient materials, which are currently only relevant for layered samples. To indicate a material as a gradient material, the user should provide two arguments: numslices
, the number of slices in the gradient material, and zvar
, a variable_obj
which represents the Cartesian Z-axis perpendicular to the sample plane.
All input arguments that represent parameters in the amorphous method should be of type functor_obj
, or they will be converted to this type if possible.
#linear density profile
z = esc.var('Z')
density_0 = esc.par('density_0', 7.874)
density_1 = esc.par('density_1', 8.86)
density = density_0 + (density_1-density_0)*z
Fe = esc.amorphous("Fe", density=density, numslices=10, zvar=z)
print(Fe)
Name: Fe Parameters number: 2 Parameter Value +- Error Units Fixed density_0 7.874 +- 0 0 density_1 8.86 +- 0 0
Layered samples given by formula¶
With the support of the Material Database module, it is now possible to define multilayer samples with formulas such as this:
Air/Fe(10)/Si(1)Fe(10)//Si
Each element of this formula is the name of the material record in the database. The '/' character is a layer separator. The value in parentheses is the thickness of the layer. The first and last elements are the foreground and background layers (environment and substrate) and do not require a thickness value.
ml = esc.multilayer(name= "Multilayer", formula="Air//Fe(100)/Si(10)/Fe(100)//Si", bydensity=False)
show(ml, source=esc.xrays(1.54056))
Layer stacks are also supported, for example:
[Fe(100)/Si(10)Fe(100)]x10//Si
Air foreground was added by default if skipped.
ml = esc.multilayer(name= "Multilayer",
formula="[Fe(100)/Si(10)/Fe(100)]x10//Si(2)", bydensity=True)
show(ml, source=esc.neutrons(wavelength=4.5))
Every element in the multilayer or layerstack formula is a material name. Since the records with the same name but with different material types (i.e. amorphous, crystal) are allowed it is necessary to specify the material type which is amorphous by default. If the material type is crystal then the formula should be written as follows:
[GaAs{cr}(100)/AlAs{cr}(50)]x10//GaAs{cr}
Use {am}
for amorphous materials and {cr}
for crystal materials.
ml = esc.multilayer(name= "Multilayer",
formula="[GaAs{cr}(100)/AlAs{cr}(50)]x10//GaAs{cr}", bydensity=True)
show(ml, source=esc.xrays(1.54056))
Customization of roughness values is also possible.
ml = esc.multilayer(name= "Multilayer", formula="[GaAs{cr}(10.3,1.1)/AlAs{cr}(5,2)]x10//GaAs{cr}(5.2)", bydensity=True) print(ml)
If your layer or material has been defined previously you can reuse it in the formula using its variable name.
Fe_custom = esc.amorphous("Fe", density="mdb")
Si_layer = esc.layer("Si layer", material="Si", thkn=esc.par(value=10), bydensity=True)
#don't forget to add the globals dictionary which contain all the variables defined above
ml=esc.multilayer(name="Multilayer", formula="Air//Fe_custom(10)/Si_layer//Si", bydensity=False, globals=globals())
print(ml)
Name: Multilayer Parameters number: 7 Parameter Value +- Error Units Fixed Fe density 7.874 +- 0 g/cm^3 0 Layer-Fe: Thickness 10 +- 0 0 Layer-Fe: Roughness Sigma 0.1 +- 0 0 Si density 2.33 +- 0 g/cm^3 0 Si layer: Thickness 10 +- 0 0 Si DwSLD0Re 1 +- 0 0 Si DwSLD0Im 1 +- 0 0