Skip to content

Commit

Permalink
set homogenization functions by int ID
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicholas Ury committed Sep 6, 2024
1 parent 42e105a commit 043af52
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 62 deletions.
99 changes: 77 additions & 22 deletions kawin/diffusion/DiffusionParameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,17 @@ def buildProfile(self, x, z):
build_functions[step_info[0]](i, x, z, *step_info[1], **step_info[2])

class TemperatureParameters:
def __init__(self):
self.Tparameters = None
self.Tfunction = None
def __init__(self, *args):
if len(args) == 2:
self.setTemperatureArray(*args)
elif len(args) == 1:
if callable(args[0]):
self.setTemperatureFunction(args[0])
else:
self.setIsothermalTemperature(args[0])
else:
self.Tparameters = None
self.Tfunction = None

def setIsothermalTemperature(self, T):
self.Tparameters = T
Expand All @@ -399,28 +407,49 @@ def __call__(self, z, t):
return self.Tfunction(z, t)

class HomogenizationParameters:
def __init__(self):
self.setHomogenizationFunction('wiener upper')
self.labyrinthFactor: float = 1
self.setPostProcessFunction(None)
self.eps = 0.05
WIENER_UPPER = 0
WIENER_LOWER = 1
HASHIN_UPPER = 2
HASHIN_LOWER = 3
LABYRINTH = 4

NO_POST = 5
PREDEFINED = 6
MAJORITY = 7
EXCLUDE = 8

def __init__(self,
homogenizationFunction = None,
labyrinthFactor = 1,
eps = 0.05,
postProcessFunction = None,
postProcessArgs = None):
if homogenizationFunction is None:
homogenizationFunction = self.WIENER_UPPER
self.setHomogenizationFunction(homogenizationFunction)

self.labyrinthFactor: float = labyrinthFactor

if postProcessFunction is None:
postProcessFunction = self.NO_POST
self.setPostProcessFunction(postProcessFunction, postProcessArgs)
self.eps = eps

def setPostProcessFunction(self, functionName, functionArgs = None):
'''
Returns post process function
'''
self.postProcessParameters = [functionArgs]
if functionName is None:
if functionName == self.NO_POST:
self.postProcessFunction = _postProcessDoNothing
elif functionName == self.PREDEFINED:
self.postProcessFunction = _postProcessPredefinedMatrixPhase
elif functionName == self.MAJORITY:
self.postProcessFunction = _postProcessMajorityPhase
elif functionName == self.EXCLUDE:
self.postProcessFunction = _postProcessExcludePhases
else:
if functionName == 'predefined':
self.postProcessFunction = _postProcessPredefinedMatrixPhase
elif functionName == 'majority':
self.postProcessFunction = _postProcessMajorityPhase
elif functionName == 'exclude':
self.postProcessFunction = _postProcessExcludePhases
else:
raise "Error: post process function should be \'predefined\', \'majority\' or \'exclude\'"
raise Exception("Error: post process function should be \'predefined\', \'majority\' or \'exclude\'")

def setHomogenizationFunction(self, function):
'''
Expand All @@ -433,16 +462,42 @@ def setHomogenizationFunction(self, function):
function : str
Options - 'upper wiener', 'lower wiener', 'upper hashin-shtrikman', 'lower hashin-strikman', 'labyrinth'
'''
if 'upper' in function and 'wiener' in function:
if isinstance(function, str):
self._setHomogenizationFunctionByStr(function)
else:
self._setHomogenizationFunctionByID(function)

def _setHomogenizationFunctionByStr(self, function):
keywords_map = {
self.WIENER_UPPER: ['wiener', 'upper'],
self.WIENER_LOWER: ['wiener', 'lower'],
self.HASHIN_UPPER: ['hashin', 'upper'],
self.HASHIN_LOWER: ['hashin', 'lower'],
self.LABYRINTH: ['lab'],
}
for func_id, keywords in keywords_map.items():
if all([kw in function for kw in keywords]):
self._setHomogenizationFunctionByID(func_id)

func_types = ['wiener upper', 'wiener lower', 'hashin upper', 'hashin lower', 'labyrinth']
str_options = ', '.join(func_types)
raise Exception(f'Error: homogenization function by str should be {str_options}')

def _setHomogenizationFunctionByID(self, function):
if function == self.WIENER_UPPER:
self.homogenizationFunction = wienerUpper
elif 'lower' in function and 'wiener' in function:
elif function == self.WIENER_LOWER:
self.homogenizationFunction = wienerLower
elif 'upper' in function and 'hashin' in function:
elif function == self.HASHIN_UPPER:
self.homogenizationFunction = hashinShtrikmanUpper
elif 'lower' in function and 'hashin' in function:
elif function == self.HASHIN_LOWER:
self.homogenizationFunction = hashinShtrikmanLower
elif 'lab' in function:
elif function == self.LABYRINTH:
self.homogenizationFunction = labyrinth
else:
func_types = ['WIENER_UPPER', 'WIENER_LOWER', 'HASHIN_UPPER', 'HASHIN_LOWER', 'LABYRINTH']
int_options = ', '.join([f'HomogenizationParameters.{t}' for t in func_types])
raise Exception(f'Error: homogenization function by ID should be {int_options}')

def setLabyrinthFactor(self, n):
'''
Expand Down
3 changes: 2 additions & 1 deletion kawin/diffusion/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .SinglePhase import SinglePhaseModel
from .Homogenization import HomogenizationModel
from .Homogenization import HomogenizationModel
from .DiffusionParameters import DiffusionParameters, HashTable, CompositionProfile, BoundaryConditions, HomogenizationParameters, TemperatureParameters
39 changes: 13 additions & 26 deletions kawin/precipitation/non_ideal/EffectiveDiffusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,31 +83,19 @@ def effectiveDiffusionDistanceApprox(self, supersaturation):
-------
Effective diffusion distance (eps) to be used as (eps*R) in the growth rate equation
'''

#Interpolation constant
a = 1.2

if hasattr(supersaturation, '__len__'):
diff = np.zeros(len(supersaturation))
indices = (supersaturation >= 0) & (supersaturation < 1)
diff[supersaturation >= 1] = 0
diff[supersaturation < 0] = 1

lam = (1 - supersaturation[indices]**a) * self.lambdaLow(supersaturation[indices]) + (supersaturation[indices]**a) * self.lambdaHigh(supersaturation[indices])
diff[indices] = supersaturation[indices] / (2 * lam**2)

return diff

else:
if supersaturation < 0:
return 1

if supersaturation >= 1:
return 0

lam = (1 - supersaturation**a) * self.lambdaLow(supersaturation) + (supersaturation**a) * self.lambdaHigh(supersaturation)

return supersaturation / (2 * lam**2)
supersaturation = np.atleast_1d(supersaturation)
diff = np.zeros(len(supersaturation))
indices = (supersaturation >= 0) & (supersaturation < 1)
diff[supersaturation >= 1] = 0
diff[supersaturation < 0] = 1

lam = (1 - supersaturation[indices]**a) * self.lambdaLow(supersaturation[indices]) + (supersaturation[indices]**a) * self.lambdaHigh(supersaturation[indices])
diff[indices] = supersaturation[indices] / (2 * lam**2)

return np.squeeze(diff)

def noDiffusionDistance(self, supersaturation):
'''
Expand All @@ -122,7 +110,6 @@ def noDiffusionDistance(self, supersaturation):
-------
1 or array of 1s
'''
if hasattr(supersaturation, '__len__'):
return np.ones(len(supersaturation), dtype=np.float32)
else:
return 1
#TODO: this can be more efficient
supersaturation = np.atleast_1d(supersaturation)
return np.squeeze(np.ones(supersaturation.shape), dtype=np.float64)
21 changes: 12 additions & 9 deletions kawin/tests/test_diffusion.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from numpy.testing import assert_allclose
import numpy as np
from kawin.diffusion import SinglePhaseModel, HomogenizationModel
from kawin.diffusion.DiffusionParameters import computeHomogenizationFunction, computeMobility, DiffusionParameters
from kawin.diffusion.DiffusionParameters import computeHomogenizationFunction, computeMobility, DiffusionParameters, HomogenizationParameters
from kawin.thermo import GeneralThermodynamics
from kawin.tests.datasets import *

Expand Down Expand Up @@ -134,10 +134,13 @@ def test_homogenizationSinglePhaseMobility():
ternaryParameters.labyrinthFactor = 2
mob_data = computeMobility(NiCrAlTherm, x, T, ternaryParameters)

mob_funcs = ['wiener upper', 'wiener lower', 'hashin upper', 'lab']
#mob_funcs = ['wiener upper', 'wiener lower', 'hashin upper', 'lab']
mob_funcs = [HomogenizationParameters.WIENER_UPPER, HomogenizationParameters.WIENER_LOWER,
HomogenizationParameters.HASHIN_UPPER, HomogenizationParameters.HASHIN_LOWER,
HomogenizationParameters.LABYRINTH]
for f in mob_funcs:
ternaryParameters.hashTable.clearCache()
ternaryParameters.homogenizationParameters.setHomogenizationFunction(mob_funcs)
ternaryParameters.homogenizationParameters.setHomogenizationFunction(f)
mob, _ = computeHomogenizationFunction(NiCrAlTherm, x, T, ternaryParameters)
assert(np.allclose(np.squeeze(mob), np.squeeze(mob_data.mobility[0]), atol=0, rtol=1e-3))

Expand Down Expand Up @@ -178,7 +181,7 @@ def test_homogenization_wiener_upper():
T = 1073

ternaryParameters = DiffusionParameters(['CR', 'AL'])
ternaryParameters.homogenizationParameters.setHomogenizationFunction('wiener upper')
ternaryParameters.homogenizationParameters.setHomogenizationFunction(HomogenizationParameters.WIENER_UPPER)

mob, _ = computeHomogenizationFunction(NiCrAlTherm, x1, T, ternaryParameters)
assert_allclose(mob, [3.927302e-22, 2.323337e-23, 6.206029e-23], atol=0, rtol=1e-3)
Expand Down Expand Up @@ -215,7 +218,7 @@ def test_homogenization_wiener_lower():
T = 1073

ternaryParameters = DiffusionParameters(['CR', 'AL'])
ternaryParameters.homogenizationParameters.setHomogenizationFunction('wiener lower')
ternaryParameters.homogenizationParameters.setHomogenizationFunction(HomogenizationParameters.WIENER_LOWER)

mob, _ = computeHomogenizationFunction(NiCrAlTherm, x1, T, ternaryParameters)
assert_allclose(mob, [3.927302e-22, 2.323337e-23, 6.206029e-23], atol=0, rtol=1e-3)
Expand Down Expand Up @@ -252,7 +255,7 @@ def test_homogenization_hashin_upper():
T = 1073

ternaryParameters = DiffusionParameters(['CR', 'AL'])
ternaryParameters.homogenizationParameters.setHomogenizationFunction('hashin upper')
ternaryParameters.homogenizationParameters.setHomogenizationFunction(HomogenizationParameters.HASHIN_UPPER)

mob, _ = computeHomogenizationFunction(NiCrAlTherm, x1, T, ternaryParameters)
assert_allclose(mob, [3.927302e-22, 2.323337e-23, 6.206029e-23], atol=0, rtol=1e-3)
Expand Down Expand Up @@ -289,7 +292,7 @@ def test_homogenization_hashin_lower():
T = 1073

ternaryParameters = DiffusionParameters(['CR', 'AL'])
ternaryParameters.homogenizationParameters.setHomogenizationFunction('hashin lower')
ternaryParameters.homogenizationParameters.setHomogenizationFunction(HomogenizationParameters.HASHIN_LOWER)

mob, _ = computeHomogenizationFunction(NiCrAlTherm, x1, T, ternaryParameters)
assert_allclose(mob, [3.927302e-22, 2.323337e-23, 6.206029e-23], atol=0, rtol=1e-3)
Expand Down Expand Up @@ -326,7 +329,7 @@ def test_homogenization_lab():
T = 1073

ternaryParameters = DiffusionParameters(['CR', 'AL'])
ternaryParameters.homogenizationParameters.setHomogenizationFunction('lab')
ternaryParameters.homogenizationParameters.setHomogenizationFunction(HomogenizationParameters.LABYRINTH)

mob, _ = computeHomogenizationFunction(NiCrAlTherm, x1, T, ternaryParameters)
assert_allclose(mob, [3.927302e-22, 2.323337e-23, 6.206029e-23], atol=0, rtol=1e-3)
Expand Down Expand Up @@ -462,7 +465,7 @@ def test_homogenization_dxdt():
m.parameters.maxCompositionChange = 0.002

#m.setMobilityFunction('hashin lower')
m.parameters.homogenizationParameters.setHomogenizationFunction('hashin lower')
m.parameters.homogenizationParameters.setHomogenizationFunction(HomogenizationParameters.HASHIN_LOWER)

m.setup()
t, x = m.getCurrentX()
Expand Down
2 changes: 1 addition & 1 deletion kawin/tests/test_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def test_diffusion_plotting():

for m in models:
#m[0].setTemperature(900)
m[0].parameters.temperature.set_isothermal_temperature(900)
m[0].parameters.temperature.setIsothermalTemperature(900)

#For each plot, check that the number of lines correspond to number of elements or phases
#For 'plot', number of lines should be elements (with or without reference) or a single element
Expand Down
6 changes: 3 additions & 3 deletions kawin/tests/test_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ def test_coupler_shape():
#Define Cr and Al composition, with step-wise change at z=0
#d_model.setCompositionLinear(0.077, 0.359, 'CR')
#d_model.setCompositionLinear(0.054, 0.062, 'AL')
d_model.parameters.composition_profile.add_linear_composition_step('CR', 0.077, 0.359)
d_model.parameters.composition_profile.add_linear_composition_step('AL', 0.054, 0.062)
d_model.parameters.compositionProfile.addLinearCompositionStep('CR', 0.077, 0.359)
d_model.parameters.compositionProfile.addLinearCompositionStep('AL', 0.054, 0.062)

d_model.setThermodynamics(NiAlCrTherm)
#d_model.setTemperature(1200 + 273.15)
d_model.parameters.temperature.set_isothermal_temperature(1200+273.15)
d_model.parameters.temperature.setIsothermalTemperature(1200+273.15)

coupled_model = Coupler([p_model, d_model])
coupled_model.setup()
Expand Down

0 comments on commit 043af52

Please sign in to comment.