Skip to content

Commit

Permalink
add json saving/loading to surrogate models, remove old surrogate models
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicholas Ury committed Dec 12, 2024
1 parent 6393949 commit a1c185d
Show file tree
Hide file tree
Showing 6 changed files with 416 additions and 1,541 deletions.
8 changes: 4 additions & 4 deletions examples/02_Multicomponent_Precipitation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@
"\tFCC_L12\t0.000e+00\t\t0.0000\t\t0.0000e+00\t2.4244e+02\n",
"\n",
"N\tTime (s)\tSim Time (s)\tTemperature (K)\tAL\tCR\t\n",
"5000\t1.3e+04\t\t17.2\t\t1073\t\t8.8453\t8.5602\t\n",
"5000\t1.3e+04\t\t13.2\t\t1073\t\t8.8453\t8.5602\t\n",
"\n",
"\tPhase\tPrec Density (#/m3)\tVolume Frac\tAvg Radius (m)\tDriving Force (J/mol)\n",
"\tFCC_L12\t6.195e+20\t\t11.2806\t\t3.2974e-08\t9.0518e+00\n",
"\n",
"N\tTime (s)\tSim Time (s)\tTemperature (K)\tAL\tCR\t\n",
"7691\t1.0e+06\t\t25.7\t\t1073\t\t8.8171\t8.5673\t\n",
"7691\t1.0e+06\t\t20.3\t\t1073\t\t8.8171\t8.5673\t\n",
"\n",
"\tPhase\tPrec Density (#/m3)\tVolume Frac\tAvg Radius (m)\tDriving Force (J/mol)\n",
"\tFCC_L12\t8.583e+18\t\t11.6262\t\t1.3883e-07\t2.1529e+00\n",
Expand Down Expand Up @@ -232,13 +232,13 @@
"\tFCC_L12\t0.000e+00\t\t0.0000\t\t0.0000e+00\t2.4244e+02\n",
"\n",
"N\tTime (s)\tSim Time (s)\tTemperature (K)\tAL\tCR\t\n",
"5000\t1.3e+04\t\t14.1\t\t1073\t\t8.8606\t8.5200\t\n",
"5000\t1.3e+04\t\t13.3\t\t1073\t\t8.8606\t8.5200\t\n",
"\n",
"\tPhase\tPrec Density (#/m3)\tVolume Frac\tAvg Radius (m)\tDriving Force (J/mol)\n",
"\tFCC_L12\t6.242e+20\t\t11.4616\t\t3.3070e-08\t9.0275e+00\n",
"\n",
"N\tTime (s)\tSim Time (s)\tTemperature (K)\tAL\tCR\t\n",
"7688\t1.0e+06\t\t21.5\t\t1073\t\t8.8335\t8.5244\t\n",
"7688\t1.0e+06\t\t20.5\t\t1073\t\t8.8335\t8.5244\t\n",
"\n",
"\tPhase\tPrec Density (#/m3)\tVolume Frac\tAvg Radius (m)\tDriving Force (J/mol)\n",
"\tFCC_L12\t8.686e+18\t\t11.8159\t\t1.3905e-07\t2.1499e+00\n",
Expand Down
16 changes: 7 additions & 9 deletions examples/10_Surrogates.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"outputs": [
{
Expand All @@ -124,7 +124,6 @@
"precipitate = PrecipitateParameters('AL3ZR')\n",
"precipitate.gamma = 0.1\n",
"precipitate.volume.setVolume(1e-5, 'VM', 4)\n",
"precipitate.setup()\n",
"R = np.linspace(1e-10, 5e-9, 100)\n",
"G = precipitate.computeGibbsThomsonContribution(R)\n",
"\n",
Expand Down Expand Up @@ -160,7 +159,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 5,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -208,7 +207,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -232,7 +231,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 7,
"metadata": {},
"outputs": [
{
Expand Down Expand Up @@ -285,7 +284,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 8,
"metadata": {},
"outputs": [
{
Expand All @@ -312,7 +311,6 @@
"precipitate = PrecipitateParameters('FCC_L12')\n",
"precipitate.gamma = 0.023\n",
"precipitate.volume.setVolume(1e-5, 'VM', 4)\n",
"precipitate.setup()\n",
"Rtest = np.linspace(1e-10, 3e-8, 300)\n",
"Gtest = precipitate.computeGibbsThomsonContribution(Rtest)\n",
"\n",
Expand Down Expand Up @@ -364,9 +362,9 @@
"\n",
"The surrogates can be saved and loaded for later usage. These will not retain the thermodynamic functions used for the training, so re-training of the surrogate cannot be done after saving/loading; however, the hyperparameters can still be changed.\n",
"\n",
"$ Surrogate.save(filename) $\n",
"$ Surrogate.toJson(filename) $\n",
"\n",
"$ surr = Surrogate.load(filename) $"
"$ Surrogate.fromJson(filename) $"
]
},
{
Expand Down
1 change: 1 addition & 0 deletions kawin/precipitation/KWNEuler.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ def _calcNucleationSites(self, t, x, p):
nucleationSites += self.matrixParameters.nucleationSites.GBareaN0 - boundPrec * (AVOGADROS_NUMBER / self.matrixParameters.volume.Vm)**(2/3)

elif isinstance(nucParams[p].description, GrainEdgeDescription):
# TODO: where did sqrt(1-GBk^2) come from?
edgePrec = np.sum([np.sqrt(1 - nucParams[p2].GBk**2) * self.PBM[p2].FirstMomentFromN(x[p2]) for p2 in range(len(self.phases)) if isinstance(nucParams[p2].description, GrainEdgeDescription)])
nucleationSites += self.matrixParameters.nucleationSites.GBedgeN0 - edgePrec * (AVOGADROS_NUMBER / self.matrixParameters.volume.Vm)**(1/3)

Expand Down
17 changes: 15 additions & 2 deletions kawin/precipitation/parameters/ElasticFactors.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,6 @@ def strainEnergyBohm(self, radius):

V = 4*np.pi/3 * np.prod(radius)
S = self.Sijmn(self.Dijkl(radius, cM4))
#invTerm = np.linalg.tensorinv(self._multiply(self._c4Prec - self._c4, S) + self._c4)
invTerm = invert4rankTensor(self._multiply(cP4 - cM4, S) + cM4)
multTerm = self._multiply(invTerm, cP4)
stressC = self._multiply(cM4, self._multiply(self._multiply(S, multTerm), eigenstrain))
Expand Down Expand Up @@ -636,16 +635,28 @@ def __init__(self, shape='constant'):
self._unrotated_cPrec_4th = np.zeros((3,3,3,3))
self.rotation = np.eye(3)
self.rotationPrec = np.eye(3)

#Cached values for calculating equilibrium aspect ratio
self.ifmethod = 1
self._aspectRatios = None
self._normEnergies = None
self._cachedRange = 5
self._cachedIntervals = 100

self._description = ConstantEnergyDescription()
self._updateCallbacks = []
self.setShape(shape)

@property
def description(self):
return self._description

@description.setter
def description(self, value):
self._description = value
for callback in self._updateCallbacks:
callback()

@property
def unrotated_cMatrix_4th(self):
return self._unrotated_cMatrix_4th
Expand Down Expand Up @@ -891,6 +902,8 @@ def setAppliedStress(self, stress):
Thus, this is only valid if the following conditions are met:
The matrix phase has a single orientation (either as a single crystal or highly textured)
Precipitates will form only in a single orientation with respect to the matrix
NOTE: this is only available in EllipsoidalEnergyDescription.strainEnergyEllipsoidWithStress and is currently not used in the KWNModel
TODO: It will be nice to expand on this.
For polycrystalline matrix and randomly oriented precipitates, it should be possible
Expand Down
47 changes: 29 additions & 18 deletions kawin/tests/test_surrogate.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ def test_Surr_binary_Diff_output():
#Compare to Thermodynamics, high tolerance since we're just checking that functions are interchangeable
assert_allclose(dnkj, dnkjT, atol=0, rtol=1e-1)

@pytest.mark.skip(reason="Saving/loading not implemented in new surrogate yet")
def test_Surr_binary_save():
'''
Checks that binary surrogate can be saved and loaded to get same values
Expand All @@ -119,42 +118,49 @@ def test_Surr_binary_save():
gExtra = np.linspace(100, 1000, 5)
surr.trainInterfacialComposition(T, gExtra)

surr.trainInterdiffusivity(xtrain, [T, T + 100])
surr.trainDiffusivity(xtrain, [T, T + 100])

a, b = surr.getDrivingForce(0.004, T)
c, d = surr.getInterfacialComposition(T, 500)
e = surr.getInterdiffusivity(0.1, T + 50)

surr.save('kawin/tests/alzr')
surr.toJson('kawin/tests/alzr.json')

surr2 = BinarySurrogate.load('kawin/tests/alzr')
#surr2 = BinarySurrogate.load('kawin/tests/alzr')
surr2 = BinarySurrogate(AlZrTherm)
surr2.fromJson('kawin/tests/alzr.json')
a2, b2 = surr2.getDrivingForce(0.004, T)
c2, d2 = surr2.getInterfacialComposition(T, 500)
e2 = surr2.getInterdiffusivity(0.1, T + 50)

os.remove('kawin/tests/alzr')
os.remove('kawin/tests/alzr.json')

# assert that models will generated from json data
assert 'FCC_A1' in surr2.diffusivityModels
assert 'AL3ZR' in surr2.drivingForceModels
assert_allclose([a, b, c, d, e], [a2, b2, c2, d2, e2], rtol=1e-3)

@pytest.mark.skip(reason="Saving/loading not implemented in new surrogate yet")
def test_Surr_binary_save_missing():
'''
Checks that load function will not fail if one of the three surrogates are not trained yet
'''
surr = BinarySurrogate(AlZrTherm)
T = 673.15
xtrain = np.logspace(-5, -2, 5)
surr.trainDrivingForce(xtrain, T, scale='log')
surr.trainDrivingForce(xtrain, T, logX=True)

a, b = surr.getDrivingForce(0.004, T)

surr.save('kawin/tests/alzr')
surr.toJson('kawin/tests/alzr.json')

surr2 = BinarySurrogate.load('kawin/tests/alzr')
#surr2 = BinarySurrogate.load('kawin/tests/alzr')
surr2 = BinarySurrogate(AlZrTherm)
surr2.fromJson('kawin/tests/alzr.json')
a2, b2 = surr2.getDrivingForce(0.004, T)

os.remove('kawin/tests/alzr')
os.remove('kawin/tests/alzr.json')

assert 'AL3ZR' in surr2.drivingForceModels
assert_allclose(a, a2, atol=0, rtol=1e-3)

def test_Surr_ternary_DG_output():
Expand Down Expand Up @@ -220,7 +226,6 @@ def test_Surr_ternary_IC_output():
assert_allclose(ca, caT, atol=0, rtol=1e-1)
assert_allclose(cb, cbT, atol=0, rtol=1e-1)

@pytest.mark.skip(reason="Saving/loading not implemented in new surrogate yet")
def test_Surr_ternary_save():
'''
Checks that multicomponent surrogate can be saved and loaded
Expand All @@ -236,18 +241,21 @@ def test_Surr_ternary_save():
g, ca, cb, _, _ = surr.getGrowthAndInterfacialComposition([0.08, 0.1], T[0]+25, 900, 1e-9, 1000)
beta = surr.impingementFactor([0.08, 0.1], T[0]+25)

surr.save('kawin/tests/nicral')
surr.toJson('kawin/tests/nicral.json')

surr2 = MulticomponentSurrogate.load('kawin/tests/nicral')
#surr2 = MulticomponentSurrogate.load('kawin/tests/nicral')
surr2 = MulticomponentSurrogate(NiCrAlTherm)
surr2.fromJson('kawin/tests/nicral.json')
a2, b2 = surr2.getDrivingForce([0.08, 0.1], T[0]+25)
g2, ca2, cb2, _, _ = surr2.getGrowthAndInterfacialComposition([0.08, 0.1], T[0]+25, 900, 1e-9, 1000)
beta2 = surr2.impingementFactor([0.08, 0.1], T[0]+25)

os.remove('kawin/tests/nicral')
os.remove('kawin/tests/nicral.json')

assert 'FCC_L12' in surr2.drivingForceModels
assert 'FCC_L12' in surr2.curvatureModels
assert_allclose([a, b[0], b[1], g, ca[0], ca[1], cb[0], cb[1], beta], [a2, b2[0], b2[1], g2, ca2[0], ca2[1], cb2[0], cb2[1], beta2], atol=0, rtol=1e-3)

@pytest.mark.skip(reason="Saving/loading not implemented in new surrogate yet")
def test_Surr_ternary_save_missing():
'''
Checks that load function will not fail if one of the three surrogates are not trained yet
Expand All @@ -258,10 +266,13 @@ def test_Surr_ternary_save_missing():
surr.trainDrivingForce(x, T)

a, b = surr.getDrivingForce([0.08, 0.1], T[0]+25)
surr.save('kawin/tests/nicral')
surr.toJson('kawin/tests/nicral.json')

surr2 = MulticomponentSurrogate.load('kawin/tests/nicral')
#surr2 = MulticomponentSurrogate.load('kawin/tests/nicral')
surr2 = MulticomponentSurrogate(NiCrAlTherm)
surr2.fromJson('kawin/tests/nicral.json')
a2, b2 = surr2.getDrivingForce([0.08, 0.1], T[0]+25)
os.remove('kawin/tests/nicral')
os.remove('kawin/tests/nicral.json')

assert 'FCC_L12' in surr2.drivingForceModels
assert_allclose([a, b[0], b[1]], [a2, b2[0], b2[1]], atol=0, rtol=1e-3)
Loading

0 comments on commit a1c185d

Please sign in to comment.