diff --git a/hexrd/cli/main.py b/hexrd/cli/main.py index 426a3fd0..cb15ff5c 100644 --- a/hexrd/cli/main.py +++ b/hexrd/cli/main.py @@ -16,7 +16,7 @@ from hexrd.cli import find_orientations from hexrd.cli import fit_grains from hexrd.cli import pickle23 - +from hexrd.cli import make_material try: _version = version("hexrd") @@ -66,6 +66,7 @@ def main(): find_orientations.configure_parser(sub_parsers) fit_grains.configure_parser(sub_parsers) pickle23.configure_parser(sub_parsers) + make_material.configure_parser(sub_parsers) try: import argcomplete diff --git a/hexrd/cli/make_material.py b/hexrd/cli/make_material.py new file mode 100644 index 00000000..40ac229e --- /dev/null +++ b/hexrd/cli/make_material.py @@ -0,0 +1,39 @@ +import sys +from hexrd.cli import help + +descr = (f'make a new material file in the ' + f'hdf5 format using the command line. ' + f'user specifies the file and crystal ' + f'names') +example = """ +examples: + hexrd make_material --file material.h5 --xtal diamond +""" + + +def configure_parser(sub_parsers): + + p = sub_parsers.add_parser('make-material', + description=descr, help=descr) + + p.add_argument( + '-f', '--file', type=str, + default='test.h5', + help='name of h5 file, default = test.h5' + ) + + p.add_argument( + '-x', '--xtal', type=str, + default='xtal', + help='name of crystal, default = xtal' + ) + + p.set_defaults(func=execute) + + +def execute(args, parser): + from hexrd.material.mksupport import mk + + file = args.file + xtal = args.xtal + mk(file, xtal) diff --git a/hexrd/material/mksupport.py b/hexrd/material/mksupport.py index 73f71870..c7a9bd74 100644 --- a/hexrd/material/mksupport.py +++ b/hexrd/material/mksupport.py @@ -9,7 +9,10 @@ import numpy as np import datetime import getpass -from hexrd.material.unitcell import _StiffnessDict, _pgDict +from hexrd.material.unitcell import (_StiffnessDict, + _pgDict, + unitcell_volume) + def mk(filename, xtalname): @@ -330,8 +333,8 @@ def GetAtomInfo(): def GetAsymmetricPositions(aniU): asym = input( - "Enter asymmetric position of atom in unit cell \ - separated by comma (fractional coordinates) : ") + f'Enter asymmetric position of atom in unit cell ' + f'separated by comma (fractional coordinates) : ') asym = [x.strip() for x in asym.split(',')] for i, x in enumerate(asym): @@ -483,7 +486,6 @@ def WriteH5Data(fid, AtomInfo, lat_param, path=None): material.h5 file output @Date 01/14/2022 SS added tThWidth to materials file """ - # Add the path prefix if we have been given one if path is not None: path = f"{path}/{AtomInfo['xtalname']}" @@ -519,32 +521,41 @@ def WriteH5Data(fid, AtomInfo, lat_param, path=None): did = gid.create_dataset("stiffness", (6, 6), dtype=np.float64) did.write_direct(np.array(AtomInfo['stiffness'], dtype=np.float64)) + P = AtomInfo['pressure'] if 'pressure' in AtomInfo else 1.01325E-4 # 1 atm did = gid.create_dataset("pressure", (1,), dtype=np.float64) - did.write_direct(np.array(AtomInfo['pressure'], dtype=np.float64)) + did.write_direct(np.array(P, dtype=np.float64)) + T = AtomInfo['temperature'] if 'temperature' in AtomInfo else 293 # R.T. did = gid.create_dataset("temperature", (1,), dtype=np.float64) - did.write_direct(np.array(AtomInfo['temperature'], dtype=np.float64)) + did.write_direct(np.array(T, dtype=np.float64)) + k0 = AtomInfo['k0'] if 'k0' in AtomInfo else 100.0 did = gid.create_dataset("k0", (1,), dtype=np.float64) - did.write_direct(np.array([AtomInfo['k0']], dtype=np.float64)) + did.write_direct(np.array([k0], dtype=np.float64)) + k0p = AtomInfo['k0p'] if 'k0p' in AtomInfo else 0.0 did = gid.create_dataset("k0p", (1,), dtype=np.float64) - did.write_direct(np.array([AtomInfo['k0p']], dtype=np.float64)) + did.write_direct(np.array([k0p], dtype=np.float64)) + dk0dt = AtomInfo['dk0dt'] if 'dk0dt' in AtomInfo else 0.0 did = gid.create_dataset("dk0dt", (1,), dtype=np.float64) - did.write_direct(np.array([AtomInfo['dk0dt']], dtype=np.float64)) + did.write_direct(np.array([dk0dt], dtype=np.float64)) + dk0pdt = AtomInfo['dk0pdt'] if 'dk0pdt' in AtomInfo else 0.0 did = gid.create_dataset("dk0pdt", (1,), dtype=np.float64) - did.write_direct(np.array([AtomInfo['dk0pdt']], dtype=np.float64)) + did.write_direct(np.array([dk0pdt], dtype=np.float64)) + alpha_t = AtomInfo['alpha_t'] if 'alpha_t' in AtomInfo else 0.0 did = gid.create_dataset("alpha_t", (1,), dtype=np.float64) - did.write_direct(np.array([AtomInfo['alpha_t']], dtype=np.float64)) + did.write_direct(np.array([alpha_t], dtype=np.float64)) + dalpha_t_dt = AtomInfo['dalpha_t_dt'] if 'dalpha_t_dt' in AtomInfo else 0.0 did = gid.create_dataset("dalpha_t_dt", (1,), dtype=np.float64) - did.write_direct(np.array([AtomInfo['dalpha_t_dt']], dtype=np.float64)) + did.write_direct(np.array([dalpha_t_dt], dtype=np.float64)) + v0 = AtomInfo['v0'] if 'v0' in AtomInfo else unitcell_volume(lat_param) did = gid.create_dataset("v0", (1,), dtype=np.float64) - did.write_direct(np.array([AtomInfo['v0']], dtype=np.float64)) + did.write_direct(np.array([v0], dtype=np.float64)) if "tThWidth" in AtomInfo: did = gid.create_dataset("tThWidth", (1,), dtype=np.float64) diff --git a/hexrd/material/symbols.py b/hexrd/material/symbols.py index 637a5136..f7d2177a 100644 --- a/hexrd/material/symbols.py +++ b/hexrd/material/symbols.py @@ -1,27 +1,28 @@ - -pstr_mkxtal = "\n\n This is a program to create a HDF5 file for storing crystallographic information.\n " -pstr_mkxtal = pstr_mkxtal + " The following inputs are required:\n " -pstr_mkxtal = pstr_mkxtal + " Crystal System:\n" -pstr_mkxtal = pstr_mkxtal + " 1. Cubic\n" -pstr_mkxtal = pstr_mkxtal + " 2. Tetragonal\n" -pstr_mkxtal = pstr_mkxtal + " 3. Orthorhombic\n" -pstr_mkxtal = pstr_mkxtal + " 4. Hexagonal\n" -pstr_mkxtal = pstr_mkxtal + " 5. Trigonal\n" -pstr_mkxtal = pstr_mkxtal + " 6. Monoclinic\n" -pstr_mkxtal = pstr_mkxtal + " 7. Triclinic\n\n" -pstr_mkxtal = pstr_mkxtal + " Space group number\n" -pstr_mkxtal = pstr_mkxtal + " Atomic number (Z) for all species in unit cell\n" -pstr_mkxtal = pstr_mkxtal + " Asymmetric positions for all atoms in unit cell\n" -pstr_mkxtal = pstr_mkxtal + " Debye-Waller factors for all atoms in the unit cell\n" -pstr_mkxtal = pstr_mkxtal + " You'll be prompted for these values now\n\n" -pstr_mkxtal = pstr_mkxtal + "\n Note about the trigonal system:\n" -pstr_mkxtal = pstr_mkxtal + " -------------------------------\n" -pstr_mkxtal = pstr_mkxtal + " Primitive trigonal crystals are defined with respect to a HEXAGONAL\n" -pstr_mkxtal = pstr_mkxtal + " reference frame. Rhombohedral crystals can be referenced with\n" -pstr_mkxtal = pstr_mkxtal + " respect to a HEXAGONAL basis (first setting), or with respect to\n" -pstr_mkxtal = pstr_mkxtal + " a RHOMBOHEDRAL basis (second setting). The default setting for\n" -pstr_mkxtal = pstr_mkxtal + " trigonal symmetry is the hexagonal setting. When you select\n" -pstr_mkxtal = pstr_mkxtal + " crystal system 5 above, you will be prompted for the setting. \n" +pstr_mkxtal = ( + f'\n\n This is a program to create a HDF5 file for storing ' + f'crystallographic information.\n' + f' The following inputs are required:\n ' + f' Crystal System:\n' + f' 1. Cubic\n' + f' 2. Tetragonal\n' + f' 3. Orthorhombic\n' + f' 4. Hexagonal\n' + f' 5. Trigonal\n' + f' 6. Monoclinic\n' + f' 7. Triclinic\n\n' + f' Space group number\n' + f' Atomic number (Z) for all species in unit cell\n' + f' Asymmetric positions for all atoms in unit cell\n' + f' Debye-Waller factors for all atoms in the unit cell\n' + f' You\'ll be prompted for these values now \n\n' + f'\n Note about the trigonal system:\n' + f' -------------------------------\n' + f' Primitive trigonal crystals are defined with respect to a HEXAGONAL\n' + f' reference frame. Rhombohedral crystals can be referenced with\n' + f' respect to a HEXAGONAL basis (first setting), or with respect to\n' + f' a RHOMBOHEDRAL basis (second setting). The default setting for\n' + f' trigonal symmetry is the hexagonal setting. When you select\n' + f' crystal system 5 above, you will be prompted for the setting. \n') pstr_spacegroup = [ " P 1 ", " P -1 ", \ diff --git a/hexrd/material/unitcell.py b/hexrd/material/unitcell.py index 26f3a2fe..1e54961b 100644 --- a/hexrd/material/unitcell.py +++ b/hexrd/material/unitcell.py @@ -49,6 +49,19 @@ def _calcstar(v, sym, mat): return vsym +def unitcell_volume(lp): + '''helper function to explicitly compute unitcell + volume (in A^3) using the forula. the unitcell class + value is set using the determinant of the metric tensor + ''' + ca = np.cos(np.radians(lp['alpha'])) + cb = np.cos(np.radians(lp['beta'])) + cg = np.cos(np.radians(lp['gamma'])) + + fact = np.sqrt(1 - ca**2 - cb**2 - cg**2 + 2*ca*cb*cg) + # 1E3 factor to go from nm to A + return lp['a']*lp['b']*lp['c']*fact*1E3 + class unitcell: '''