"""Module defining functions to run amset."""from__future__importannotationsimportloggingimportsubprocessimportnumpyasnpfrompydashimportgetlogger=logging.getLogger(__name__)_CONVERGENCE_PROPERTIES=("mobility.overall","seebeck")
[docs]defrun_amset()->None:"""Run amset in the current directory."""# Run AMSET using the command line as calling from python can cause issues# with multiprocessingwithopen("std_out.log","w")asf_std,open("std_err.log","w")asf_err:subprocess.call(["amset","run"],stdout=f_std,stderr=f_err)# noqa: S607
[docs]defcheck_converged(new_transport:dict,old_transport:dict,properties:tuple[str,...]=_CONVERGENCE_PROPERTIES,tolerance:float=0.1,)->bool:""" Check if all transport properties (averaged) are converged within the tol. Parameters ---------- new_transport : dict The new transport data. old_transport : dict The old transport data. properties : tuple of str List of properties for which convergence is assessed. The calculation is only flagged as converged if all properties pass the convergence checks. Options are: "conductivity", "seebeck", "mobility.overall", "electronic thermal conductivity. tolerance : float Relative convergence tolerance. Default is ``0.1`` (i.e. 10 %). Returns ------- bool Whether the new transport data is converged. """converged=Trueforpropinproperties:new_prop=get(new_transport,prop,None)old_prop=get(old_transport,prop,None)ifnew_propisNoneorold_propisNone:logger.info(f"'{prop}' not in new or old transport data, skipping...")continuenew_avg=tensor_average(new_prop)old_avg=tensor_average(old_prop)diff=np.abs((new_avg-old_avg)/new_avg)diff[~np.isfinite(diff)]=0# don't check convergence of very small numbers due to numerical noiseless_than_one=(np.abs(new_avg)<1)&(np.abs(old_avg)<1)element_converged=less_than_one|(diff<=tolerance)ifnotnp.all(element_converged):logger.info(f"{prop} is not converged - max diff: {np.max(diff)*100} %")converged=Falseifconverged:logger.info("amset calculation is converged.")returnconverged
[docs]deftensor_average(tensor:list|np.ndarray)->float|np.ndarray:"""Calculate the average of the tensor eigenvalues. Parameters ---------- tensor : list or numpy array A tensor Returns ------- float or numpy array The average of the eigenvalues. """returnnp.average(np.linalg.eigvalsh(tensor),axis=-1)