kawin.diffusion

kawin.kawin.diffusion.Diffusion

DiffusionModel(GenericModel)

class DiffusionModel(self, mesh: AbstractMesh, elements: list[str], phases: list[str], thermodynamics:GeneralThermodynamics, temperature:TemperatureParameters, constraints:DiffusionConstraints=None, record=False):

Class for defining a 1-dimensional mesh

Parameters
----------
mesh: AbstractMesh
elements : list of str
    Elements in system (first element will be assumed as the reference element)
phases : list of str
    Number of phases in the system
thermodynamics: GeneralThermodynamics
constraints: DiffusionConstraints

def DiffusionModel.reset(self):

Resets model

This involves clearing any caches in the Thermodynamics object and this model
as well as resetting the composition and phase profiles

def DiffusionModel.toDict(self):

Converts diffusion data to dictionary

def DiffusionModel.fromDict(self, data):

Converts dictionary of data to diffusion data

def DiffusionModel.setHashSensitivity(self, s):

If composition caching is used, this sets the composition precision (in sig figs) when creating a hash

Ex. if s = 2, then a composition of [0.3334, 0.3333, 0.3333] will be converted to [0.33, 0.33, 0.33] when hashing
    While this can lead to faster compute times if new compositions has the same hash, this can also lower fidelity of
    the calculations since a range of compositions could correspond to the same moblity values

Parameters
----------
s : int
    Number of sig figs when creating composition hash

def DiffusionModel.useCache(self, use):

Whether to cache compositions

Parameters
----------
use : bool

def DiffusionModel.clearCache(self):

Clears the composition cache

def DiffusionModel._getElementIndex(self, element = None):

Gets index of element in self.elements

Parameters
----------
element : str
    Specified element, will return first element if None

def DiffusionModel._getPhaseIndex(self, phase = None):

Gets index of phase in self.phases

Parameters
----------
phase : str
    Specified phase, will return first phase if None

def DiffusionModel._validateMeshComposition(self):

Checks that composition along mesh will be between min/max limits (set by DiffusionConstraints.minComposition)
Since the mesh can store y in an arbitrary shape, we use the flatten array and unflatten it to store back in the mesh

def DiffusionModel.setup(self):

General setup function for all diffusion models

This will clear any cached values in the thermodynamics function and check if all compositions add up to 1

This will also make sure that all compositions are not 0 or 1 to speed up equilibrium calculations

def DiffusionModel._getPairs(self, t, xCurr):

Returns diffusivity-response pairs for diffusive fluxes

def DiffusionModel.getFluxes(self, t, xCurr):

Computes fluxes from mesh and diffusivity-response pairs
NOTE: this directly returns the mesh outputs, so format of fluxes will correspond to the mesh

def DiffusionModel.getdXdt(self, t, xCurr):

Computes dXdt from mesh and diffusivity-respones pairs

def DiffusionModel.printHeader(self):

def DiffusionModel.printStatus(self, iteration, modelTime, simTimeElapsed):

def DiffusionModel.getCurrentX(self):

def DiffusionModel.postProcess(self, time, x):

Stores new x and t
Records new values if recording is enabled

def DiffusionModel.flattenX(self, X):

np.hstack does not flatten a 2D array, so we have to overload this function
    By itself, this doesn't actually affect the solver/iterator, but when coupled with other models,
    it becomes an issue

This will convert the 2D array X to a 1D array by reshaping to 1D array of len(# elements * # nodes)

def DiffusionModel.unflattenX(self, X_flat, X_ref):

Reshape X_flat to original shape

def DiffusionModel.postSolve(self):

def DiffusionModel.getCompositions(self, time = None):

Returns composition of nodes in mesh as (N,e)
Since the diffusion model stores everything in terms of u-fraction
this is a useful way to get compositions back
We return composition in (N,e), but the mesh can be used to convert
this shape back to the internal mesh shape

Returns
-------
composition: np.ndarray (N,e)
    N is number of nodes in mesh and e is the full list of elements (including dependent)

kawin.kawin.diffusion.DiffusionParameters

HashTable

class HashTable(self):

Implements a hash table that stores mobility, phases, phase fractions and
chemical potentials for a given (composition, temperature) pair

def HashTable.enableCaching(self, is_caching: bool):

def HashTable.clearCache(self):

def HashTable.setHashSensitivity(self, s: int):

Sets sensitivity of the hash table by significant digits

For example, if a composition set is (0.5693, 0.2937) and s = 3, then
the hash will be stored as (0.569, 0.294)

Lower s values will give faster simulation times at the expense of accuracy

Parameters
----------
s : int
    Number of significant digits to keep for the hash table

def HashTable._hashingFunction(self, x: np.array, T: np.array):

Gets hash value for a (compostion, temperature) pair

Parameters
----------
x : float, list[float]
T : float

def HashTable.retrieveFromHashTable(self, x: np.array, T: np.array):

Attempts to retrieve a stored value from the hash table

Parameters
----------
x : float, [float]
T : float

Returns
-------
Value or None (if no hash table for cached value does not exist)

def HashTable.addToHashTable(self, x: np.array, T: np.array, value: any):

Attempts to add a value to the hash table
If no hash table, then this will not do anything

Parameters
----------
x : float, list[float]
T : float

TemperatureParameters

class TemperatureParameters(self, *args):

Parameter for temperature that acts like a callable function

Parameters can be one of the following:
    T : float
        Isothermal temperature
    times : list[float], temperatures : list[float]
        Array of times and temperatures (temperature becomes temperatures[i] at times[i])
    func : callable
        Function in the form of f(z,t) = T where z is spatial coordinate and t is time

def TemperatureParameters.setIsothermalTemperature(self, T: float):

Sets isothermal temperature

Parameters
----------
T : float

def TemperatureParameters.setTemperatureArray(self, times: list[float], temperatures: list[float]):

Sets array of times/temperatures

Example:
    time = [0, 1, 2]
    temperature = [100, 200, 300]
    This will set temperature to 100 at t = 0 hours, then at 1 hour, temperature = 200, then after 2 hours, temperature = 300

Parameters
----------
times : list[float]
temperatures : list[float]

def TemperatureParameters.setTemperatureFunction(self, func: Callable):

Sets temperature function

Parameters
----------
func : Callable
    Function is in the form f(z,t) = T, where z is spatial coordinate and t is time

def TemperatureParameters.call(self, z: float, t: float):

def _computeSingleMobility(therm: GeneralThermodynamics, x: np.array, T: np.array, unsortIndices: np.array, hashTable : HashTable = None) -> MobilityData:

Gets mobility data for x and T (at single composition/temperature)

If mobility does not exist for a phase or a phase is unstable, then the mobility is set to -1

Parameters
----------
therm : GeneralThermodynamics object
x : float, list[float]
    For binary, it must be a float
    For ternary, it must be list[float]
T : float
    Temperature(s)
    
Returns
-------
MobilityData

def computeMobility(therm : GeneralThermodynamics, x, T, hashTable : HashTable = None):

Gets mobility data for x and T where x and T is an array

If mobility does not exist for a phase or a phase is unstable, then the mobility is set to -1

Parameters
----------
therm : GeneralThermodynamics object
x : float or array
    For binary, it must be (1,) or (N,)
    For ternary, it must be (1,e) or (N,e)
T : float or array
    Must be (1,) or (N,)
    
Returns
-------
MobilityData

DiffusionConstraints

class DiffusionConstraints(self):

Constraints for numerical stability

Attributes
----------
minComposition : float
    Minimum composition that a node can take
vonNeumannThreshold : float
    Factor to ensure numerical stability in the single phase diffusion model
    In theory, from von Neumann stability analysis for the heat equation, this can be 0.5
    But I will use 0.4 to be safe
maxCompositionChange : float
    Max composition change a node can see per iteration in the homogenization model
    There is not an analagous method for von Neumann stability as we have for the single
    phase diffusion model, so this is a naive approach to numerical stability

def DiffusionConstraints.reset(self):

kawin.kawin.diffusion.DiffusionParameters

HashTable

class HashTable(self):

Implements a hash table that stores mobility, phases, phase fractions and
chemical potentials for a given (composition, temperature) pair

def HashTable.enableCaching(self, is_caching: bool):

def HashTable.clearCache(self):

def HashTable.setHashSensitivity(self, s: int):

Sets sensitivity of the hash table by significant digits

For example, if a composition set is (0.5693, 0.2937) and s = 3, then
the hash will be stored as (0.569, 0.294)

Lower s values will give faster simulation times at the expense of accuracy

Parameters
----------
s : int
    Number of significant digits to keep for the hash table

def HashTable._hashingFunction(self, x: np.array, T: np.array):

Gets hash value for a (compostion, temperature) pair

Parameters
----------
x : float, list[float]
T : float

def HashTable.retrieveFromHashTable(self, x: np.array, T: np.array):

Attempts to retrieve a stored value from the hash table

Parameters
----------
x : float, [float]
T : float

Returns
-------
Value or None (if no hash table for cached value does not exist)

def HashTable.addToHashTable(self, x: np.array, T: np.array, value: any):

Attempts to add a value to the hash table
If no hash table, then this will not do anything

Parameters
----------
x : float, list[float]
T : float

TemperatureParameters

class TemperatureParameters(self, *args):

Parameter for temperature that acts like a callable function

Parameters can be one of the following:
    T : float
        Isothermal temperature
    times : list[float], temperatures : list[float]
        Array of times and temperatures (temperature becomes temperatures[i] at times[i])
    func : callable
        Function in the form of f(z,t) = T where z is spatial coordinate and t is time

def TemperatureParameters.setIsothermalTemperature(self, T: float):

Sets isothermal temperature

Parameters
----------
T : float

def TemperatureParameters.setTemperatureArray(self, times: list[float], temperatures: list[float]):

Sets array of times/temperatures

Example:
    time = [0, 1, 2]
    temperature = [100, 200, 300]
    This will set temperature to 100 at t = 0 hours, then at 1 hour, temperature = 200, then after 2 hours, temperature = 300

Parameters
----------
times : list[float]
temperatures : list[float]

def TemperatureParameters.setTemperatureFunction(self, func: Callable):

Sets temperature function

Parameters
----------
func : Callable
    Function is in the form f(z,t) = T, where z is spatial coordinate and t is time

def TemperatureParameters.call(self, z: float, t: float):

def _computeSingleMobility(therm: GeneralThermodynamics, x: np.array, T: np.array, unsortIndices: np.array, hashTable : HashTable = None) -> MobilityData:

Gets mobility data for x and T (at single composition/temperature)

If mobility does not exist for a phase or a phase is unstable, then the mobility is set to -1

Parameters
----------
therm : GeneralThermodynamics object
x : float, list[float]
    For binary, it must be a float
    For ternary, it must be list[float]
T : float
    Temperature(s)
    
Returns
-------
MobilityData

def computeMobility(therm : GeneralThermodynamics, x, T, hashTable : HashTable = None):

Gets mobility data for x and T where x and T is an array

If mobility does not exist for a phase or a phase is unstable, then the mobility is set to -1

Parameters
----------
therm : GeneralThermodynamics object
x : float or array
    For binary, it must be (1,) or (N,)
    For ternary, it must be (1,e) or (N,e)
T : float or array
    Must be (1,) or (N,)
    
Returns
-------
MobilityData

DiffusionConstraints

class DiffusionConstraints(self):

Constraints for numerical stability

Attributes
----------
minComposition : float
    Minimum composition that a node can take
vonNeumannThreshold : float
    Factor to ensure numerical stability in the single phase diffusion model
    In theory, from von Neumann stability analysis for the heat equation, this can be 0.5
    But I will use 0.4 to be safe
maxCompositionChange : float
    Max composition change a node can see per iteration in the homogenization model
    There is not an analagous method for von Neumann stability as we have for the single
    phase diffusion model, so this is a naive approach to numerical stability

def DiffusionConstraints.reset(self):

kawin.kawin.diffusion.SinglePhase

SinglePhaseModel(DiffusionModel)

def SinglePhaseModel.getDt(self, dXdt):

Returns dt that was calculated from _getPairs using von-Neumann stability
This prevents double calculation of the diffusivity just to get a time step

kawin.kawin.diffusion.Homogenization

def _homogenizationMean(Ds):

Average homogenization flux
Ds should be in the shape of (m x N x y x 2)
    m - number of items to average over
    N - number of nodes
    y - number of responses
    2 - (transformation to volume fixed frame, homogenization term (\Gamma))
        transformation is in composition, so use arithmetic average
        homogenization term is in terms of mobility, so use log average (mobility is always positive)

def _idealMean(Ds):

Average homogenization flux
Ds should be in the shape of (m x N x y x 4)
    m - number of items to average over
    N - number of nodes
    y - number of responses
    4 - (transformation to volume fixed frame, temperature, homogenization term (\Gamma), inverse u term)
        transformation is in composition, so use arithmetic average
        temperature (+eps*R) is linear, so use arithmetic average
        homogenization term is in terms of mobility, so use log average
        inverse u term is inverse composition, so use harmonic mean (composition should always be > 0 based off constraints in diffusion model)

def _atNodeProduct(Ds):

HomogenizationModel(DiffusionModel)

class HomogenizationModel(self, mesh, elements, phases, thermodynamics=None, temperature=None, homogenizationParameters=None, constraints=None, record=False):

def HomogenizationModel._getPairs(self, t, xCurr):

Compute diffusivity-response pairs

J_k = -\Gamma_k d\mu_k/dz - \eps*RT*\Gamma_k/u_k du_k/dz
J^n_k = -sum(\delta_jk - u_k) J_j
dx_k/dt = -dJ^n_k/dz

For x_k, a pair would comprise of:
    (\delta_jk - u_k) \Gamma_j, \mu_k
    (\delta_jk - u_k) \eps*RT*\Gamma_k/u_k, u_k

def HomogenizationModel.getDt(self, dXdt):

Time increment
This is done by finding the time interval such that the composition
    change caused by the fluxes will be lower than self.maxCompositionChange

kawin.kawin.diffusion.HomogenizationParameters

def wienerUpper(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Upper wiener bounds for average mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def wienerLower(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Lower wiener bounds for average mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def labyrinth(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Labyrinth mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def _hashinShtrikmanGeneral(mobility: np.array, phaseFracs: np.array, extreme_mob: np.array) -> np.array:

General hashin shtrikman bounds

Ak = f^phi / (1 / (gamma^phi - gamma^alpha) + 1/(3*gamma^alpha))
gamma^* = gamma^alpha + Ak / (1 - Ak / (3*gamma^alpha))

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)
extreme_mob : list of length (e,)

Returns
-------
(e,) mobility array - e is number of elements

def hashinShtrikmanUpper(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Upper hashin shtrikman bounds for average mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def hashinShtrikmanLower(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Lower hashin shtrikman bounds for average mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def _postProcessDoNothing(mobData: MobilityData, *args, **kwargs):

def _postProcessPredefinedMatrixPhase(mobData: MobilityData, *args, **kwargs):

User will supply a predefined "alpha" phase, which the mobility is taken
from for all undefined mobility

Note: this assumes the user will know that "alpha" is continuously stable
across the diffusion couple

def _postProcessMajorityPhase(mobData: MobilityData, *args, **kwargs):

Takes the majority phase and applies the mobility for all other phases
with undefined mobility

def _postProcessExcludePhases(mobData: MobilityData, *args, **kwargs):

For all excluded phases, the mobility and phase fraction will be set to 0
This assumes that user knows the excluded phases to be minor or that the
mobility is unknown

HomogenizationParameters

class HomogenizationParameters(self, homogenizationFunction:Union[str, int]=‘wienerupper’, labyrinthFactor:float=1, eps:float=0.05, postProcessFunction:Union[str, int]=‘none’, postProcessArgs=None):

Defines homogenization and pre-process functions for the homogenization model

Parameters
----------
homogenizationFunction: Union[str, int]
    - 'wiener upper' or HomogenizationParameters.WIENER_UPPER
    - 'wiener lower' or HomogenizationParameters.WIENER_LOWER
    - 'hashin upper' or HomogenizationParameters.HASHIN_UPPER
    - 'hashin lower' or HomogenizationParameters.HASHIN_LOWER
    - 'lab' or HomogenizationParameters.LABYRINTH
labyrinthFactor : float
    If labyrinth function is used
    Must be between 1 and 2
eps : float
    Factor for the ideal entropy contribution
postProcessFunction: Union[str, int]
    Function that can modify the phase mobility based off certain conditions
    - 'none' or HomogenizationParameters.NO_POST
        - performs no preprocessing on phase mobilities
    - 'predefined' or HomogenizationParameters.PREDEFINED
        - phases with no mobility models will take on the same mobility value as the predefined phase
    - 'majority' or HomogenizationParameters.MAJORITY
        - phases with no mobility will take on the same mobility of the phase with the largest phase fraction
    - 'exclude' or HomogenizationParameters.EXCLUDE
        - phases in the exclude list will take on a mobility of 0
postProcessArgs: Any
    If 'majority' post process function is used, postProcessArgs is str corresponding to the pre-defined phase
    If 'exlude' post process function is used, postProcessArgs is list[str] corresponding to list of phases to exlude

def HomogenizationParameters.setPostProcessFunction(self, functionName: Union[str, int], functionArgs = None):

Sets post process function by str or int

Parameters
----------
functionName : Union[str, int]
    Key for post process function ('none', 'predefined', 'majority', 'exclude')
functionArgs : Any
    Additional function arguments (particularly for 'predefined' or 'exclude')

def HomogenizationParameters._setPostProcessFunctionByStr(self, functionName: str):

def HomogenizationParameters._setPostProcessFunctionByID(self, functionName: int):

def HomogenizationParameters.setHomogenizationFunction(self, function: Union[str, int]):

Sets averaging function to use for mobility

Default mobility value should be that a phase of unknown mobility will be ignored for average mobility calcs

Parameters
----------
function : str
    Options - 'upper wiener', 'lower wiener', 'upper hashin', 'lower hashin', 'lab'

def HomogenizationParameters._setHomogenizationFunctionByStr(self, function: str):

def HomogenizationParameters._setHomogenizationFunctionByID(self, function: int):

def HomogenizationParameters.setLabyrinthFactor(self, n: float):

Labyrinth factor

Parameters
----------
n : int
    Either 1 or 2
    Note: n = 1 will the same as the weiner upper bounds

def computeHomogenizationFunction(therm : GeneralThermodynamics, x, T, homogenizationParameters : HomogenizationParameters, hashTable : HashTable = None):

Compute homogenization function (defined by HomogenizationParameters) for list of x,T

Parameters
----------
therm : GeneralThermodynamics object
x : float, list[float], list[list[float]]
    Compositions
    For binary, it must be either a float or list[float] (shape N) for multiple compositions
    For ternary, it must be either list[float] (shape e) or list[list[float]] (shape N x e) for multiple compositions
T : float, list[float]
    Temperature(s)
    First dimensions must correspond to first dimension of x
diffusion_parameters: DiffusionParameters
    
Returns
-------
average mobility array - (N, e)
chemical potential array - (N, e)

Where N is size of (x,T), and e is number of elements

kawin.kawin.diffusion.HomogenizationParameters

def wienerUpper(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Upper wiener bounds for average mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def wienerLower(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Lower wiener bounds for average mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def labyrinth(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Labyrinth mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def _hashinShtrikmanGeneral(mobility: np.array, phaseFracs: np.array, extreme_mob: np.array) -> np.array:

General hashin shtrikman bounds

Ak = f^phi / (1 / (gamma^phi - gamma^alpha) + 1/(3*gamma^alpha))
gamma^* = gamma^alpha + Ak / (1 - Ak / (3*gamma^alpha))

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)
extreme_mob : list of length (e,)

Returns
-------
(e,) mobility array - e is number of elements

def hashinShtrikmanUpper(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Upper hashin shtrikman bounds for average mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def hashinShtrikmanLower(mobility: np.array, phaseFracs: np.array, *args, **kwargs) -> np.array:

Lower hashin shtrikman bounds for average mobility

Parameters
----------
mobility : list of length (p, e)
phaseFracs : list of length (p,)

Returns
-------
(e,) mobility array - e is number of elements

def _postProcessDoNothing(mobData: MobilityData, *args, **kwargs):

def _postProcessPredefinedMatrixPhase(mobData: MobilityData, *args, **kwargs):

User will supply a predefined "alpha" phase, which the mobility is taken
from for all undefined mobility

Note: this assumes the user will know that "alpha" is continuously stable
across the diffusion couple

def _postProcessMajorityPhase(mobData: MobilityData, *args, **kwargs):

Takes the majority phase and applies the mobility for all other phases
with undefined mobility

def _postProcessExcludePhases(mobData: MobilityData, *args, **kwargs):

For all excluded phases, the mobility and phase fraction will be set to 0
This assumes that user knows the excluded phases to be minor or that the
mobility is unknown

HomogenizationParameters

class HomogenizationParameters(self, homogenizationFunction:Union[str, int]=‘wienerupper’, labyrinthFactor:float=1, eps:float=0.05, postProcessFunction:Union[str, int]=‘none’, postProcessArgs=None):

Defines homogenization and pre-process functions for the homogenization model

Parameters
----------
homogenizationFunction: Union[str, int]
    - 'wiener upper' or HomogenizationParameters.WIENER_UPPER
    - 'wiener lower' or HomogenizationParameters.WIENER_LOWER
    - 'hashin upper' or HomogenizationParameters.HASHIN_UPPER
    - 'hashin lower' or HomogenizationParameters.HASHIN_LOWER
    - 'lab' or HomogenizationParameters.LABYRINTH
labyrinthFactor : float
    If labyrinth function is used
    Must be between 1 and 2
eps : float
    Factor for the ideal entropy contribution
postProcessFunction: Union[str, int]
    Function that can modify the phase mobility based off certain conditions
    - 'none' or HomogenizationParameters.NO_POST
        - performs no preprocessing on phase mobilities
    - 'predefined' or HomogenizationParameters.PREDEFINED
        - phases with no mobility models will take on the same mobility value as the predefined phase
    - 'majority' or HomogenizationParameters.MAJORITY
        - phases with no mobility will take on the same mobility of the phase with the largest phase fraction
    - 'exclude' or HomogenizationParameters.EXCLUDE
        - phases in the exclude list will take on a mobility of 0
postProcessArgs: Any
    If 'majority' post process function is used, postProcessArgs is str corresponding to the pre-defined phase
    If 'exlude' post process function is used, postProcessArgs is list[str] corresponding to list of phases to exlude

def HomogenizationParameters.setPostProcessFunction(self, functionName: Union[str, int], functionArgs = None):

Sets post process function by str or int

Parameters
----------
functionName : Union[str, int]
    Key for post process function ('none', 'predefined', 'majority', 'exclude')
functionArgs : Any
    Additional function arguments (particularly for 'predefined' or 'exclude')

def HomogenizationParameters._setPostProcessFunctionByStr(self, functionName: str):

def HomogenizationParameters._setPostProcessFunctionByID(self, functionName: int):

def HomogenizationParameters.setHomogenizationFunction(self, function: Union[str, int]):

Sets averaging function to use for mobility

Default mobility value should be that a phase of unknown mobility will be ignored for average mobility calcs

Parameters
----------
function : str
    Options - 'upper wiener', 'lower wiener', 'upper hashin', 'lower hashin', 'lab'

def HomogenizationParameters._setHomogenizationFunctionByStr(self, function: str):

def HomogenizationParameters._setHomogenizationFunctionByID(self, function: int):

def HomogenizationParameters.setLabyrinthFactor(self, n: float):

Labyrinth factor

Parameters
----------
n : int
    Either 1 or 2
    Note: n = 1 will the same as the weiner upper bounds

def computeHomogenizationFunction(therm : GeneralThermodynamics, x, T, homogenizationParameters : HomogenizationParameters, hashTable : HashTable = None):

Compute homogenization function (defined by HomogenizationParameters) for list of x,T

Parameters
----------
therm : GeneralThermodynamics object
x : float, list[float], list[list[float]]
    Compositions
    For binary, it must be either a float or list[float] (shape N) for multiple compositions
    For ternary, it must be either list[float] (shape e) or list[list[float]] (shape N x e) for multiple compositions
T : float, list[float]
    Temperature(s)
    First dimensions must correspond to first dimension of x
diffusion_parameters: DiffusionParameters
    
Returns
-------
average mobility array - (N, e)
chemical potential array - (N, e)

Where N is size of (x,T), and e is number of elements