22
22
from matplotlib .lines import Line2D
23
23
24
24
25
- def spherical_to_cartesian (angles ):
26
- """
27
- Convert a list of 5 spherical angles to Cartesian coordinates.
28
- Parameters
29
- ----------
30
- angles : (N,)-array
31
- List of 5 angles in radians.
32
- Returns
33
- -------
34
- coordinates : (N,6) array
35
- Cartesian coordinates computed from the input spherical angles.
36
- """
37
- assert len (angles ) == 5
38
- x1 = np .cos (angles [0 ])
39
- x2 = np .sin (angles [0 ]) * np .cos (angles [1 ])
40
- x3 = np .sin (angles [0 ]) * np .sin (angles [1 ]) * np .cos (angles [2 ])
41
- x4 = np .sin (angles [0 ]) * np .sin (angles [1 ]) * np .sin (angles [2 ]) * np .cos (angles [3 ])
42
- x5 = np .sin (angles [0 ]) * np .sin (angles [1 ]) * np .sin (angles [2 ]) * np .sin (angles [3 ]) * np .cos (angles [4 ])
43
- x6 = np .sin (angles [0 ]) * np .sin (angles [1 ]) * np .sin (angles [2 ]) * np .sin (angles [3 ]) * np .sin (angles [4 ])
44
- return np .array ([x1 , x2 , x3 , x4 , x5 , x6 ])
45
-
46
-
47
25
def creator_rnd (npoints , precision = 8 ):
48
26
"""
49
27
Generate random points in a 6D space, normalize them, and then round to the specified precision.
@@ -75,25 +53,6 @@ def creator_rnd(npoints, precision=8):
75
53
points .append (point_rounded )
76
54
return np .vstack (points )
77
55
78
- '''
79
- def find_yloc(x, sig, mat):
80
- """
81
- Function to expand unit stresses by factor and calculate yield function;
82
- used by search algorithm to find zeros of yield function.
83
- Parameters
84
- ----------
85
- x : (N,)-array
86
- Multiplyer for stress
87
- sig : (N,6) array
88
- unit stress
89
- Returns
90
- -------
91
- f : 1d-array
92
- Yield function evaluated at sig=x.sp
93
- """
94
- f = mat.calc_yf(sig * x[:, None])
95
- return f'''
96
-
97
56
98
57
def eval_variance (angles , committee ):
99
58
"""
@@ -114,14 +73,35 @@ def eval_variance(angles, committee):
114
73
Negative variance of the yield function outputs for maximization purpose.
115
74
"""
116
75
# Convert from spherical to Cartesian coordinates
117
- x = spherical_to_cartesian (angles )
76
+ x = FE . sig_spherical_to_cartesian (angles )
118
77
y = np .zeros (len (committee ))
119
78
for i , member in enumerate (committee ):
120
- y [i ] = member .calc_yf (x * member .sy )
79
+ y [i ] = member .calc_yf (x * member .sy * 0.5 )
121
80
variance = np .var (y )
122
81
return - variance
123
82
124
83
84
+ def comp_score (mat1 , mat2 , mat_ref , npoint = 100 , scale = 10 , offset = 5 ):
85
+ # analyze training result
86
+ global nsamples_init , nsamples_to_generate
87
+ loc = mat_ref .sy
88
+ X1 = np .random .normal (loc = loc , scale = scale , size = int (npoint / 2 ))
89
+ X2 = np .random .normal (loc = (loc - offset ), scale = scale , size = int (npoint / 4 ))
90
+ X3 = np .random .normal (loc = (loc + offset ), scale = scale , size = int (npoint / 4 ))
91
+ X = np .concatenate ((X1 , X2 , X3 ))
92
+ sunittest = FE .load_cases (number_3d = 0 , number_6d = len (X ))
93
+ sig_test = sunittest * X [:, None ]
94
+ yf_ml1 = mat1 .calc_yf (sig_test )
95
+ yf_ml2 = mat2 .calc_yf (sig_test )
96
+ yf_ref = mat_ref .calc_yf (sig_test )
97
+ print (f'\n *** Training scores of active learning model with { nsamples_init } initial '
98
+ f'and { nsamples_to_generate } training points:' )
99
+ FE .training_score (yf_ref , yf_ml1 )
100
+ print (f'\n *** Training scores of conventional learning model with { nsamples_init + nsamples_to_generate } '
101
+ f'training points:' )
102
+ FE .training_score (yf_ref , yf_ml2 )
103
+
104
+
125
105
def plot_variances (var_list ):
126
106
plt .plot (var_list , marker = 'o' )
127
107
plt .xlabel ('Iteration' )
@@ -166,14 +146,15 @@ def read_vectors(file_name):
166
146
vectors = np .loadtxt (file_name )
167
147
return vectors
168
148
149
+
169
150
# Query by committee parameters
170
151
# max disagreement for yf-predictions,
171
152
# for classifiers generally possible: vote_entropy, consensus_entropy or
172
153
# maximum_disagreement, cf. https://modal-python.readthedocs.io/en/latest/content/query_strategies/Disagreement-sampling.html#disagreement-sampling
173
154
174
155
nmembers = 5 # Number of committee members
175
- nsamples_init = 80 # Number of initial samples
176
- nsamples_to_generate = 60 # Number of iterations
156
+ nsamples_init = 42 # Number of initial samples
157
+ nsamples_to_generate = 30 # Number of iterations
177
158
subset_percentage = 0.8 # Percent of data used for each committee member
178
159
init_rnd = False # Train with random initial data points
179
160
file_init = None # 'DATA_sunit_iter_80.txt'
@@ -194,27 +175,27 @@ def read_vectors(file_name):
194
175
sunit = creator_rnd (nsamples_init , 8 )
195
176
else :
196
177
# alternative for training with equally spaced initial data points
197
- c = int (nsamples_init * 2 / 3 )
178
+ c = int (nsamples_init / 3 )
198
179
d = nsamples_init - c
199
180
sunit = FE .load_cases (number_3d = c , number_6d = d )
200
181
np .savetxt ('Test_Cases.txt' , sunit )
201
182
202
183
# create set of unit stresses
203
184
print ('Created {0} unit stresses (6d Voigt tensor).' .format (nsamples_init ))
204
- x1 = fsolve (mat_h .find_yloc , np .ones (nsamples_init ) * mat_h .sy , args = (sunit , ), xtol = 1.e-5 )
185
+ x1 = fsolve (mat_h .find_yloc , np .ones (nsamples_init ) * mat_h .sy , args = (sunit ,), xtol = 1.e-5 )
205
186
sig = sunit * x1 [:, None ]
206
187
print ('Calculated {} yield stresses.' .format (nsamples_init ))
207
188
208
189
# train SVC with yield stress data generated from Hill flow rule
209
- C = 4 .0
210
- gamma = 2.0
190
+ C = 3 .0
191
+ gamma = 0.5
211
192
Ce = 0.99
212
193
Fe = 0.1
213
194
Nseq = 25
214
195
vlevel = 0
215
196
gsearch = True
216
- cvals = [3 , 4 , 6 , 8 ]
217
- gvals = [1.5 , 2 .0 , 2 .5 , 3.0 ]
197
+ cvals = [1 , 2 , 3 , 4 , 5 ]
198
+ gvals = [0.7 , 1 .0 , 1 .5 , 2.0 , 2.5 ]
218
199
219
200
mat_ml = FE .Material (name = 'ML-Hill' ) # define material
220
201
mat_ml .train_SVC (C = C , gamma = gamma , Fe = Fe , Ce = Ce , Nseq = Nseq , sdata = sig , extend = False ,
@@ -233,7 +214,7 @@ def read_vectors(file_name):
233
214
committee = []
234
215
tstart = time .time ()
235
216
for j in range (nmembers ):
236
- idx = np .random .choice (np .arange (sig .shape [0 ]),
217
+ idx = np .random .choice (np .arange (sig .shape [0 ]),
237
218
int (sig .shape [0 ] * subset_percentage ),
238
219
replace = False )
239
220
mat_ml = FE .Material (name = 'ML-Hill_{}' .format (j ))
@@ -245,29 +226,29 @@ def read_vectors(file_name):
245
226
hyp_g_list .append (mat_ml .gam_yf )
246
227
committee .append (mat_ml )
247
228
tend = time .time ()
248
- print (f'***Iteration { i } :\n Time for training committee: { tend - tstart } ' )
229
+ print (f'***Iteration { i } :\n Time for training committee: { tend - tstart } ' )
249
230
250
231
# Search for next unit vector to query
251
232
tstart = time .time ()
252
- res = differential_evolution (eval_variance , bounds , args = (committee , ),
233
+ res = differential_evolution (eval_variance , bounds , args = (committee ,),
253
234
popsize = 90 , polish = True ,
254
235
updating = 'immediate' )
255
236
tend = time .time ()
256
- print (f' Time for differential evolution: { tend - tstart } ' )
237
+ print (f' Time for differential evolution: { tend - tstart } ' )
257
238
sunit_neww = res .x
258
- sunit_new = spherical_to_cartesian (sunit_neww )
239
+ sunit_new = FE . sig_spherical_to_cartesian (sunit_neww )
259
240
variance = res .fun
260
241
var .append (- variance )
261
242
262
243
# Calculate corresponding stress state and update data set
263
- x1 = fsolve (mat_h .find_yloc , mat_h .sy , args = (sunit_new , ), xtol = 1.e-5 )
244
+ x1 = fsolve (mat_h .find_yloc , mat_h .sy , args = (sunit_new ,), xtol = 1.e-5 )
264
245
sig_new = sunit_new * x1 [:, None ]
265
246
sig = np .vstack ([sig , sig_new ])
266
247
sunit = np .vstack ([sunit , sunit_new ])
267
248
268
249
# Train final model with all data sets
269
250
mat_ml = FE .Material (name = 'ML-Hill' ) # define material
270
- mat_ml .train_SVC (C = C , gamma = gamma , Fe = 0.1 , Ce = Ce , Nseq = Nseq ,
251
+ mat_ml .train_SVC (C = C , gamma = gamma , Fe = Fe , Ce = Ce , Nseq = Nseq ,
271
252
sdata = sig , extend = False ,
272
253
gridsearch = True , cvals = cvals , gvals = gvals ,
273
254
verbose = vlevel )
@@ -277,13 +258,16 @@ def read_vectors(file_name):
277
258
c = int (Ntot / 3 )
278
259
d = Ntot - c
279
260
sunit_r = FE .load_cases (number_3d = c , number_6d = d )
280
- x1 = fsolve (mat_h .find_yloc , np .ones (Ntot ) * mat_h .sy , args = (sunit_r , ), xtol = 1.e-5 )
261
+ x1 = fsolve (mat_h .find_yloc , np .ones (Ntot ) * mat_h .sy , args = (sunit_r ,), xtol = 1.e-5 )
281
262
sig_r = sunit_r * x1 [:, None ]
282
263
mat_ml_r = FE .Material (name = 'ML-Hill' ) # define material
283
- mat_ml_r .train_SVC (C = C , gamma = gamma , Fe = 0.1 , Ce = Ce , Nseq = Nseq ,
264
+ mat_ml_r .train_SVC (C = C , gamma = gamma , Fe = Fe , Ce = Ce , Nseq = Nseq ,
284
265
sdata = sig_r ,
285
266
gridsearch = True , cvals = cvals , gvals = gvals , verbose = vlevel )
286
267
268
+ # Evaluate results
269
+ comp_score (mat_ml , mat_ml_r , mat_ref = mat_h , npoint = 300 )
270
+
287
271
# Plot results
288
272
plot_yield_locus (mat_ml , mat_h , nsamples_to_generate , mat3 = mat_ml_r )
289
273
plot_variances (var )
@@ -299,7 +283,6 @@ def read_vectors(file_name):
299
283
plt .show ()
300
284
301
285
# Save data files
302
- np .savetxt ('DATA_sig_iter_{}.txt' .format (i + 1 ), sig )
303
- np .savetxt ('DATA_sunit_iter_{}.txt' .format (i + 1 ), sunit )
286
+ np .savetxt ('DATA_sig_iter_{}.txt' .format (nsamples_to_generate ), sig )
287
+ np .savetxt ('DATA_sunit_iter_{}.txt' .format (nsamples_to_generate ), sunit )
304
288
np .savetxt ('variance.txt' , var )
305
-
0 commit comments