Davout 0.1.1.dev180__py3-none-any.whl → 0.1.1.dev182__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Davout/DeepMech/aa_tests/SVD_framework/dataset_generator.py +72 -18
- Davout/DeepMech/aa_tests/SVD_framework/input_data_filler.py +13 -11
- Davout/DeepMech/aa_tests/SVD_framework/kinematics_surrogate_model.py +174 -42
- Davout/DeepMech/aa_tests/mecsol_2026_quotient_space/neural_network_trainer.py +55 -18
- Davout/DeepMech/aa_tests/tests_tool_box/test_SVD_based_NNs.py +22 -16
- Davout/DeepMech/custom_architectures/SVD_quotient_space.py +234 -12
- Davout/DeepMech/tool_box/ANN_tools.py +7 -4
- Davout/DeepMech/tool_box/FEM_surrogate_testing_tools.py +1224 -0
- Davout/DeepMech/tool_box/activation_function_utilities.py +52 -35
- Davout/DeepMech/tool_box/custom_activation_functions.py +114 -13
- Davout/DeepMech/tool_box/gpu_tools.py +21 -0
- Davout/DeepMech/tool_box/numerical_tools.py +382 -2
- Davout/DeepMech/tool_box/training_tools.py +4 -4
- Davout/GraphUtilities/aa_tests/linear_transformation_plot.py +165 -0
- Davout/GraphUtilities/aa_tests/positive_orthant_modulating_function.py +645 -0
- Davout/GraphUtilities/aa_tests/tests_plotting_tools.py +111 -24
- Davout/GraphUtilities/plotting_tools.py +657 -184
- Davout/GraphUtilities/tool_box/collage_classes.py +28 -2
- Davout/GraphUtilities/tool_box/paraview_scripts.py +10 -0
- Davout/MultiMech/tool_box/binary_tools.py +119 -100
- Davout/MultiMech/tool_box/mesh_handling_tools.py +197 -3
- Davout/PythonicUtilities/dictionary_tools.py +37 -26
- Davout/PythonicUtilities/error_and_type_tools.py +130 -0
- Davout/PythonicUtilities/function_tools.py +53 -2
- Davout/PythonicUtilities/path_tools.py +126 -15
- Davout/PythonicUtilities/tensor_and_math_tools.py +3 -3
- {davout-0.1.1.dev180.dist-info → davout-0.1.1.dev182.dist-info}/METADATA +7 -4
- {davout-0.1.1.dev180.dist-info → davout-0.1.1.dev182.dist-info}/RECORD +31 -26
- {davout-0.1.1.dev180.dist-info → davout-0.1.1.dev182.dist-info}/WHEEL +0 -0
- {davout-0.1.1.dev180.dist-info → davout-0.1.1.dev182.dist-info}/licenses/LICENSE +0 -0
- {davout-0.1.1.dev180.dist-info → davout-0.1.1.dev182.dist-info}/top_level.txt +0 -0
|
@@ -14,6 +14,8 @@ from .....Davout.DeepMech.aa_tests.mecsol_2026_quotient_space.box_with_imposed_d
|
|
|
14
14
|
|
|
15
15
|
from .....Davout.DeepMech.aa_tests.mecsol_2026_quotient_space.young_modulus_field_generator import generate_field
|
|
16
16
|
|
|
17
|
+
from input_data_filler import fill_load_steps
|
|
18
|
+
|
|
17
19
|
import numpy as np
|
|
18
20
|
|
|
19
21
|
import traceback
|
|
@@ -26,7 +28,8 @@ def generate_dataset(n_samples, limits_list, p_norm_list, results_path,
|
|
|
26
28
|
displacement_file_name, young_modulus_file, mesh_file_name, cube_size,
|
|
27
29
|
influence_radius, damping_factor, radius_power, mesh_data_class,
|
|
28
30
|
lagrange_multiplier_file_name, strain_energy_file_name,
|
|
29
|
-
|
|
31
|
+
displacement_matrix_file_name, strain_energy_matrix_file_name,
|
|
32
|
+
input_matrix_file_name, save_snapshot_displacement=False):
|
|
30
33
|
|
|
31
34
|
# Initializes the list of samples
|
|
32
35
|
|
|
@@ -162,10 +165,11 @@ save_snapshot_displacement=False):
|
|
|
162
165
|
strain_energy_file_name+"_"+simulation_number+".npy")[:,1:
|
|
163
166
|
].tolist())
|
|
164
167
|
|
|
165
|
-
# Adds the
|
|
168
|
+
# Adds the displacement gradient and, then, the Young modulus
|
|
169
|
+
# data. The variables related to the quotient space must come
|
|
170
|
+
# first
|
|
166
171
|
|
|
167
|
-
successful_sample_data = [
|
|
168
|
-
"eak E"]], sample_data[variables_indices["base E"]]]
|
|
172
|
+
successful_sample_data = []
|
|
169
173
|
|
|
170
174
|
successful_sample_data.extend(displacement_gradient[0])
|
|
171
175
|
|
|
@@ -173,6 +177,9 @@ save_snapshot_displacement=False):
|
|
|
173
177
|
|
|
174
178
|
successful_sample_data.extend(displacement_gradient[2])
|
|
175
179
|
|
|
180
|
+
successful_sample_data.extend([sample_data[variables_indices[
|
|
181
|
+
"peak E"]], sample_data[variables_indices["base E"]]])
|
|
182
|
+
|
|
176
183
|
succesful_data.append(successful_sample_data)
|
|
177
184
|
|
|
178
185
|
# Updates the list of completed simulations
|
|
@@ -189,14 +196,14 @@ save_snapshot_displacement=False):
|
|
|
189
196
|
|
|
190
197
|
# Saves the lists into binary and txt files
|
|
191
198
|
|
|
192
|
-
np.save(results_path+"//
|
|
193
|
-
|
|
199
|
+
np.save(results_path+"//"+displacement_matrix_file_name,
|
|
200
|
+
np.array(succesful_displacement))
|
|
194
201
|
|
|
195
|
-
np.save(results_path+"//
|
|
196
|
-
|
|
202
|
+
np.save(results_path+"//"+strain_energy_matrix_file_name,
|
|
203
|
+
np.array(succesful_strain_energy))
|
|
197
204
|
|
|
198
|
-
np.save(results_path+"//
|
|
199
|
-
|
|
205
|
+
np.save(results_path+"//"+input_matrix_file_name, np.array(
|
|
206
|
+
succesful_data))
|
|
200
207
|
|
|
201
208
|
list_toTxt(completed_simulations, "00_completed_simulations",
|
|
202
209
|
parent_path=results_path)
|
|
@@ -339,7 +346,7 @@ if __name__=="__main__":
|
|
|
339
346
|
|
|
340
347
|
cube_size = 0.5
|
|
341
348
|
|
|
342
|
-
n_divisions = 10
|
|
349
|
+
n_divisions = 6#10
|
|
343
350
|
|
|
344
351
|
E_extremum = 10E6
|
|
345
352
|
|
|
@@ -355,7 +362,8 @@ if __name__=="__main__":
|
|
|
355
362
|
|
|
356
363
|
# Sets the paths and files names
|
|
357
364
|
|
|
358
|
-
results_path = get_parent_path_of_file()+"//
|
|
365
|
+
results_path = (get_parent_path_of_file()+"//results_n_divisions_"+
|
|
366
|
+
str(n_divisions))
|
|
359
367
|
|
|
360
368
|
displacement_file_name = "displacement_young_modulus_field"
|
|
361
369
|
|
|
@@ -367,6 +375,31 @@ if __name__=="__main__":
|
|
|
367
375
|
|
|
368
376
|
mesh_file_name = "box_mesh_mecsol"
|
|
369
377
|
|
|
378
|
+
# Sets the file name of the data matrices
|
|
379
|
+
|
|
380
|
+
displacement_matrix_file_name = ("00_successful_displacement_matri"+
|
|
381
|
+
"x.npy")
|
|
382
|
+
|
|
383
|
+
strain_energy_matrix_file_name = ("00_successful_strain_energy_mat"+
|
|
384
|
+
"rix.npy")
|
|
385
|
+
|
|
386
|
+
input_matrix_file_name = "00_successful_data_matrix.npy"
|
|
387
|
+
|
|
388
|
+
# Sets the file names of the completed (filled-in with load-steps)
|
|
389
|
+
# data matrices and the filtered counterpart
|
|
390
|
+
|
|
391
|
+
complete_data_matrix_file_name = ("00_successful_complete_data_mat"+
|
|
392
|
+
"rix.npy")
|
|
393
|
+
|
|
394
|
+
complete_and_filtered_data_matrix_file_name = ("00_successful_comp"+
|
|
395
|
+
"lete_and_filtered_data_matrix.npy")
|
|
396
|
+
|
|
397
|
+
# Sets the initial and final time points for the simulation
|
|
398
|
+
|
|
399
|
+
initial_time = 0.2
|
|
400
|
+
|
|
401
|
+
final_time = 1.0
|
|
402
|
+
|
|
370
403
|
# Constructs the mesh
|
|
371
404
|
|
|
372
405
|
mesh_data_class = read_mshMesh({"length x": cube_size, "length y":
|
|
@@ -377,10 +410,31 @@ if __name__=="__main__":
|
|
|
377
410
|
"bias x": ["Bump", bias_factor], "bias y": ["Bump", bias_factor],
|
|
378
411
|
"bias z": ["Bump", bias_factor]})
|
|
379
412
|
|
|
380
|
-
#
|
|
413
|
+
# Defines a flag fo generating the dataset and another flag for ge-
|
|
414
|
+
# nerating the dataset with the intermediate load steps and its fil-
|
|
415
|
+
# tered version as well
|
|
416
|
+
|
|
417
|
+
flag_generate_dataset = False
|
|
418
|
+
|
|
419
|
+
flag_fill_in_load_steps = True
|
|
420
|
+
|
|
421
|
+
# Generates the dataset from skretch
|
|
422
|
+
|
|
423
|
+
if flag_generate_dataset:
|
|
424
|
+
|
|
425
|
+
generate_dataset(n_samples, limits_list, p_norm_list,
|
|
426
|
+
results_path, displacement_file_name, young_modulus_file,
|
|
427
|
+
mesh_file_name, cube_size, influence_radius, damping_factor,
|
|
428
|
+
radius_power, mesh_data_class, lagrange_multiplier_file_name,
|
|
429
|
+
strain_energy_file_name, displacement_matrix_file_name,
|
|
430
|
+
strain_energy_matrix_file_name, input_matrix_file_name,
|
|
431
|
+
save_snapshot_displacement=False)
|
|
432
|
+
|
|
433
|
+
# Fills the load-steps and generates the filtered dataset from it
|
|
434
|
+
|
|
435
|
+
if flag_fill_in_load_steps:
|
|
381
436
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
save_snapshot_displacement=False)
|
|
437
|
+
fill_load_steps(input_matrix_file_name,
|
|
438
|
+
displacement_matrix_file_name, complete_data_matrix_file_name,
|
|
439
|
+
complete_and_filtered_data_matrix_file_name, results_path,
|
|
440
|
+
initial_time, final_time)
|
|
@@ -60,10 +60,10 @@ final_time):
|
|
|
60
60
|
|
|
61
61
|
# Recovers the displacement gradient
|
|
62
62
|
|
|
63
|
-
displacement_gradient = np.array([[sample_data[
|
|
64
|
-
sample_data[
|
|
65
|
-
sample_data[
|
|
66
|
-
sample_data[
|
|
63
|
+
displacement_gradient = np.array([[sample_data[0],
|
|
64
|
+
sample_data[1], sample_data[2]], [sample_data[3],
|
|
65
|
+
sample_data[4], sample_data[5]], [sample_data[6],
|
|
66
|
+
sample_data[7], sample_data[8]]])
|
|
67
67
|
|
|
68
68
|
# Gets the corresponding deformation gradient
|
|
69
69
|
|
|
@@ -118,7 +118,7 @@ final_time):
|
|
|
118
118
|
new_disp_grad[0,1], new_disp_grad[0,2], new_disp_grad[
|
|
119
119
|
1,0], new_disp_grad[1,1], new_disp_grad[1,2],
|
|
120
120
|
new_disp_grad[2,0], new_disp_grad[2,1], new_disp_grad[
|
|
121
|
-
2,2], sample_data[
|
|
121
|
+
2,2], sample_data[9], sample_data[10]])
|
|
122
122
|
|
|
123
123
|
# Adds this sample to the filtered input data. Inserts
|
|
124
124
|
# the load-based data as the first columns, since this
|
|
@@ -137,18 +137,20 @@ final_time):
|
|
|
137
137
|
new_input_list = np.array(new_input_list)
|
|
138
138
|
|
|
139
139
|
print("The new input data matrix has shape "+str(
|
|
140
|
-
new_input_list.shape)+", whereas it had "+str(
|
|
141
|
-
|
|
142
|
-
" has "+str(displacement_matrix.shape
|
|
140
|
+
new_input_list.shape)+", whereas it had the shape "+str(
|
|
141
|
+
input_data.shape)+" before.\nThe displacement matrix, on the o"+
|
|
142
|
+
"ther hand, has shape equal to "+str(displacement_matrix.shape)+
|
|
143
|
+
"\n")
|
|
143
144
|
|
|
144
145
|
np.save(results_path+"//"+new_input_file, new_input_list)
|
|
145
146
|
|
|
146
147
|
new_filtered_input_list = np.array(new_filtered_input_list)
|
|
147
148
|
|
|
148
149
|
print("The new filtered input data matrix has shape "+str(
|
|
149
|
-
new_filtered_input_list.shape)+", whereas it had "+str(
|
|
150
|
-
input_data.shape
|
|
151
|
-
"
|
|
150
|
+
new_filtered_input_list.shape)+", whereas it had the shape "+str(
|
|
151
|
+
input_data.shape)+" before.\nThe displacement matrix, on th"+
|
|
152
|
+
"e other hand, has shape equal to "+str(displacement_matrix.shape
|
|
153
|
+
)+"\n")
|
|
152
154
|
|
|
153
155
|
np.save(results_path+"//"+new_filtered_input_file,
|
|
154
156
|
new_filtered_input_list)
|
|
@@ -5,10 +5,16 @@ import numpy as np
|
|
|
5
5
|
|
|
6
6
|
import tensorflow as tf
|
|
7
7
|
|
|
8
|
+
from .....Davout.DeepMech.tool_box.gpu_tools import give_access_of_gpu_to_tensorflow
|
|
9
|
+
|
|
10
|
+
give_access_of_gpu_to_tensorflow(True)
|
|
11
|
+
|
|
8
12
|
from time import time
|
|
9
13
|
|
|
10
14
|
from .....Davout.DeepMech.tool_box import ANN_tools, training_tools
|
|
11
15
|
|
|
16
|
+
from .....Davout.DeepMech.tool_box.numerical_tools import DataMatrixRegularization
|
|
17
|
+
|
|
12
18
|
from .....Davout.DeepMech.tool_box.loss_assembler_classes import MaximumAbsoluteError
|
|
13
19
|
|
|
14
20
|
from .....Davout.PythonicUtilities.path_tools import get_parent_path_of_file
|
|
@@ -22,12 +28,19 @@ class RVEKinematicsSurrogateModel:
|
|
|
22
28
|
activations_list_auxiliar_network, quotient_space_dimension,
|
|
23
29
|
modulating_function, displacement_data_file, input_data_file,
|
|
24
30
|
results_path, loss_metric, n_training_samples, saved_model_file,
|
|
25
|
-
n_monte_carlo_realizations, n_best_models,
|
|
31
|
+
n_monte_carlo_realizations, n_best_models, n_best_samples,
|
|
26
32
|
maximum_training_iterations, verbose_delta_iterations,
|
|
27
|
-
|
|
33
|
+
mesh_file_name, optimizer, subdofs_to_learn, parameters_dtype="flo"+
|
|
34
|
+
"at32", householder_epsilon=1.0, verbose=True, integer_dtype="int3"+
|
|
35
|
+
"2", non_orthogonal_matrices=False, device_type="CPU",
|
|
36
|
+
input_data_regularization_method=None):
|
|
28
37
|
|
|
29
38
|
# Saves the needed information
|
|
30
39
|
|
|
40
|
+
self.non_orthogonal_matrices = non_orthogonal_matrices
|
|
41
|
+
|
|
42
|
+
self.device_type = device_type
|
|
43
|
+
|
|
31
44
|
self.activations_list_main_network = activations_list_main_network
|
|
32
45
|
|
|
33
46
|
self.activations_list_auxiliar_network = (
|
|
@@ -45,6 +58,8 @@ class RVEKinematicsSurrogateModel:
|
|
|
45
58
|
|
|
46
59
|
self.loss_metric = loss_metric
|
|
47
60
|
|
|
61
|
+
self.optimizer = optimizer
|
|
62
|
+
|
|
48
63
|
self.n_training_samples = n_training_samples
|
|
49
64
|
|
|
50
65
|
self.saved_model_file = saved_model_file
|
|
@@ -53,7 +68,9 @@ class RVEKinematicsSurrogateModel:
|
|
|
53
68
|
|
|
54
69
|
self.n_best_models = n_best_models
|
|
55
70
|
|
|
56
|
-
self.
|
|
71
|
+
self.n_best_samples = n_best_samples
|
|
72
|
+
|
|
73
|
+
self.mesh_file_name = mesh_file_name
|
|
57
74
|
|
|
58
75
|
self.householder_epsilon = householder_epsilon
|
|
59
76
|
|
|
@@ -63,19 +80,56 @@ class RVEKinematicsSurrogateModel:
|
|
|
63
80
|
|
|
64
81
|
self.verbose_delta_iterations = verbose_delta_iterations
|
|
65
82
|
|
|
66
|
-
|
|
83
|
+
# Saves the tensorflow dtypes
|
|
67
84
|
|
|
68
|
-
|
|
85
|
+
self.parameters_dtype = parameters_dtype
|
|
69
86
|
|
|
70
|
-
|
|
87
|
+
self.integer_dtype = integer_dtype
|
|
71
88
|
|
|
72
|
-
|
|
89
|
+
# Converts the tensor of DOFs to a tensorflow integer tensor
|
|
90
|
+
|
|
91
|
+
self.subdofs_to_learn = tf.convert_to_tensor(subdofs_to_learn,
|
|
92
|
+
dtype=tf.as_dtype(self.integer_dtype))
|
|
93
|
+
|
|
94
|
+
# Gets the number of output neurons from the tensor of the indi-
|
|
95
|
+
# ces of the DOFs that will actually be learnt
|
|
96
|
+
|
|
97
|
+
self.n_output_neurons = self.subdofs_to_learn.shape[0]
|
|
98
|
+
|
|
99
|
+
# Reads the output data
|
|
100
|
+
|
|
101
|
+
self.whole_output_data = np.load(self.results_path+"//"+
|
|
73
102
|
self.displacement_data_file)
|
|
74
103
|
|
|
104
|
+
# Gets the numbers of samples and of total of DOFs
|
|
105
|
+
|
|
106
|
+
self.number_of_samples, self.total_number_of_dofs = (
|
|
107
|
+
self.whole_output_data.shape)
|
|
108
|
+
|
|
109
|
+
# Checks whether subdofs to learn has any DOF index that is lar-
|
|
110
|
+
# ger than the number of DOFs of the output data
|
|
111
|
+
|
|
112
|
+
if tf.reduce_max(self.subdofs_to_learn).numpy(
|
|
113
|
+
)>=self.total_number_of_dofs:
|
|
114
|
+
|
|
115
|
+
raise IndexError("The maximum DOF index requested by 'subd"+
|
|
116
|
+
"ofs_to_learn' is "+str(tf.reduce_max(self.subdofs_to_learn
|
|
117
|
+
).numpy())+". But the output data at\n"+str(
|
|
118
|
+
self.results_path+"//"+self.displacement_data_file)+"\nhas"+
|
|
119
|
+
" only "+str(self.total_number_of_dofs)+" columns")
|
|
120
|
+
|
|
121
|
+
# Otherwise, uses the subdofs to learn to retrieve the needed
|
|
122
|
+
# DOFs for training
|
|
123
|
+
|
|
124
|
+
self.output_data = self.whole_output_data[:,
|
|
125
|
+
self.subdofs_to_learn]
|
|
126
|
+
|
|
127
|
+
# Gets the input data
|
|
128
|
+
|
|
75
129
|
input_data = np.load(self.results_path+"//"+self.input_data_file)
|
|
76
130
|
|
|
77
131
|
# Checks whether there is sufficient samples in the dataset
|
|
78
|
-
|
|
132
|
+
|
|
79
133
|
if self.n_training_samples>=input_data.shape[0]:
|
|
80
134
|
|
|
81
135
|
raise IndexError(str(self.n_training_samples)+" samples we"+
|
|
@@ -83,7 +137,7 @@ class RVEKinematicsSurrogateModel:
|
|
|
83
137
|
input_data.shape[0])+" samples in the input data matrix at"+
|
|
84
138
|
":\n"+str(self.results_path+"//"+self.input_data_file))
|
|
85
139
|
|
|
86
|
-
if self.n_training_samples>=output_data.shape[0]:
|
|
140
|
+
if self.n_training_samples>=self.output_data.shape[0]:
|
|
87
141
|
|
|
88
142
|
raise IndexError(str(self.n_training_samples)+" samples we"+
|
|
89
143
|
"re asked for training, but there are only "+str(
|
|
@@ -91,26 +145,40 @@ class RVEKinematicsSurrogateModel:
|
|
|
91
145
|
"t:\n"+str(self.results_path+"//"+
|
|
92
146
|
self.displacement_data_file))
|
|
93
147
|
|
|
94
|
-
if output_data.shape[0]!=input_data.shape[0]:
|
|
148
|
+
if self.output_data.shape[0]!=input_data.shape[0]:
|
|
95
149
|
|
|
96
150
|
raise IndexError("The output data matrix has "+str(
|
|
97
|
-
output_data.shape[0])+" samples, whereas the input
|
|
98
|
-
"
|
|
99
|
-
"
|
|
151
|
+
self.output_data.shape[0])+" samples, whereas the input da"+
|
|
152
|
+
"ta matrix has "+str(input_data.shape[0])+" samples.\n\nTh"+
|
|
153
|
+
"e output data matrix is at:\n"+str(self.results_path+"//"+
|
|
100
154
|
self.displacement_data_file)+"\n\nthe input data matrix is"+
|
|
101
155
|
"at:\n"+str(self.results_path+"//"+self.input_data_file))
|
|
102
156
|
|
|
103
|
-
#
|
|
157
|
+
# Checks if a regularization technique was requested for the in-
|
|
158
|
+
# put data matrix
|
|
159
|
+
|
|
160
|
+
if input_data_regularization_method is not None:
|
|
104
161
|
|
|
105
|
-
|
|
162
|
+
# Instantiates the data regularization class
|
|
106
163
|
|
|
107
|
-
|
|
164
|
+
data_regularization_class = DataMatrixRegularization(
|
|
165
|
+
regularization_function=input_data_regularization_method)
|
|
108
166
|
|
|
109
|
-
|
|
167
|
+
# Regularizes the data matrix and saves the regularization
|
|
168
|
+
# data using this input data
|
|
110
169
|
|
|
111
|
-
|
|
170
|
+
self.input_data, _ = data_regularization_class(input_data,
|
|
171
|
+
True)
|
|
112
172
|
|
|
113
|
-
|
|
173
|
+
# Otherwise, simply saves the input data into the class
|
|
174
|
+
|
|
175
|
+
else:
|
|
176
|
+
|
|
177
|
+
self.input_data = input_data
|
|
178
|
+
|
|
179
|
+
# Gets the number of input neurons
|
|
180
|
+
|
|
181
|
+
self.n_input_neurons = self.input_data.shape[1]
|
|
114
182
|
|
|
115
183
|
# Verifies if the output layer of the main network has the same
|
|
116
184
|
# number of output neurons
|
|
@@ -121,32 +189,47 @@ class RVEKinematicsSurrogateModel:
|
|
|
121
189
|
|
|
122
190
|
n_output_neurons_main_network += value
|
|
123
191
|
|
|
124
|
-
if n_output_neurons_main_network!=n_output_neurons:
|
|
192
|
+
if n_output_neurons_main_network!=self.n_output_neurons:
|
|
125
193
|
|
|
126
194
|
raise ValueError("The main network has "+str(
|
|
127
195
|
n_output_neurons_main_network)+" neurons in the output lay"+
|
|
128
196
|
"er; whereas the data indicate that there must be "+str(
|
|
129
|
-
n_output_neurons)+" neurons in the output layer")
|
|
197
|
+
self.n_output_neurons)+" neurons in the output layer")
|
|
130
198
|
|
|
131
199
|
# Sets the architecture dictionary
|
|
132
200
|
|
|
133
|
-
custom_architecture = {"name": "SVDQuotientSpace", "
|
|
134
|
-
"
|
|
135
|
-
"
|
|
136
|
-
"
|
|
201
|
+
self.custom_architecture = {"name": "SVDQuotientSpace", "weigh"+
|
|
202
|
+
"ts modulating function": self.modulating_function, "Household"+
|
|
203
|
+
"er epsilon": self.householder_epsilon, "activations accessory"+
|
|
204
|
+
" layer list": self.activations_list_auxiliar_network, "non-or"+
|
|
205
|
+
"thogonal matrices": self.non_orthogonal_matrices, "hardware d"+
|
|
206
|
+
"evice": self.device_type, "convex with respect to quotient sp"+
|
|
207
|
+
"ace": False}
|
|
208
|
+
|
|
209
|
+
# Defines a function to train the neural network model
|
|
210
|
+
|
|
211
|
+
def train_surrogate_model(self):
|
|
212
|
+
|
|
213
|
+
# Sets the training data
|
|
214
|
+
|
|
215
|
+
training_data = self.input_data[0:self.n_training_samples,:]
|
|
216
|
+
|
|
217
|
+
training_true_values = self.output_data[0:self.n_training_samples
|
|
218
|
+
,:]
|
|
137
219
|
|
|
138
220
|
# Creates the class of neural network information
|
|
139
221
|
|
|
140
|
-
ANN_class = ANN_tools.MultiLayerModel(n_input_neurons,
|
|
222
|
+
ANN_class = ANN_tools.MultiLayerModel(self.n_input_neurons,
|
|
141
223
|
self.activations_list_main_network, enforce_customLayers=True,
|
|
142
224
|
verbose=self.verbose, parameters_dtype=self.parameters_dtype,
|
|
143
|
-
custom_architecture=custom_architecture,
|
|
144
|
-
self.quotient_space_dimension)
|
|
225
|
+
custom_architecture=self.custom_architecture,
|
|
226
|
+
input_size_main_network=self.quotient_space_dimension)
|
|
145
227
|
|
|
146
228
|
self.custom_model = ANN_class()
|
|
147
229
|
|
|
148
230
|
# Defines the loss metric
|
|
149
231
|
|
|
232
|
+
"""
|
|
150
233
|
self.live_loss_metric = None
|
|
151
234
|
|
|
152
235
|
if isinstance(self.loss_metric, str):
|
|
@@ -159,7 +242,9 @@ class RVEKinematicsSurrogateModel:
|
|
|
159
242
|
"metric by the name '"+str(self.loss_metric)+"'")
|
|
160
243
|
|
|
161
244
|
self.live_loss_metric = getattr(tf.keras.losses,
|
|
162
|
-
self.loss_metric)(dtype=tf.as_dtype(self.parameters_dtype))
|
|
245
|
+
self.loss_metric)(dtype=tf.as_dtype(self.parameters_dtype))"""
|
|
246
|
+
|
|
247
|
+
self.live_loss_metric = self.loss_metric
|
|
163
248
|
|
|
164
249
|
# Sets the optimization class for training
|
|
165
250
|
|
|
@@ -169,7 +254,7 @@ class RVEKinematicsSurrogateModel:
|
|
|
169
254
|
self.maximum_training_iterations, verbose_deltaIterations=
|
|
170
255
|
self.verbose_delta_iterations, save_model_file=
|
|
171
256
|
self.saved_model_file, match_data_float_type_to_trainables=True,
|
|
172
|
-
parent_path=self.results_path)
|
|
257
|
+
parent_path=self.results_path, optimizer=self.optimizer)
|
|
173
258
|
|
|
174
259
|
t_initial = time()
|
|
175
260
|
|
|
@@ -183,7 +268,8 @@ class RVEKinematicsSurrogateModel:
|
|
|
183
268
|
|
|
184
269
|
training_class.monte_carlo_training(n_realizations=
|
|
185
270
|
self.n_monte_carlo_realizations, best_models_rank_size=
|
|
186
|
-
self.n_best_models, show_reinitialization_distance=True
|
|
271
|
+
self.n_best_models, show_reinitialization_distance=True,
|
|
272
|
+
model_base_name=self.saved_model_file)
|
|
187
273
|
|
|
188
274
|
# Checks the loss again with the best model of the Monte Carlo
|
|
189
275
|
# training
|
|
@@ -275,6 +361,20 @@ class RVEKinematicsSurrogateModel:
|
|
|
275
361
|
|
|
276
362
|
if __name__=="__main__":
|
|
277
363
|
|
|
364
|
+
# Sets the number of transfinite divisions in the RVE mesh
|
|
365
|
+
|
|
366
|
+
n_divisions = 6
|
|
367
|
+
|
|
368
|
+
# Sets a dictionary for the number of DOFs in the mesh for each num-
|
|
369
|
+
# ber of divisions
|
|
370
|
+
|
|
371
|
+
dofs_per_number_of_divisions = {6: 3993, 8: 10125, 10: 20577}
|
|
372
|
+
|
|
373
|
+
# Defines the array with the DOFs to be learnt
|
|
374
|
+
|
|
375
|
+
subdofs_to_learn = np.arange(0, dofs_per_number_of_divisions[
|
|
376
|
+
n_divisions], 3)
|
|
377
|
+
|
|
278
378
|
# Defines the number of input neurons of the main network. Remember
|
|
279
379
|
# that the data matrix is a tensor [n_samples, n_input_variables].
|
|
280
380
|
# The first quotient_space_dimension columns must be dedicated to
|
|
@@ -286,7 +386,7 @@ if __name__=="__main__":
|
|
|
286
386
|
# Defines the number of neurons of the different hidden layers and of
|
|
287
387
|
# the output layer
|
|
288
388
|
|
|
289
|
-
n_neurons_per_layer = [100, 1000,
|
|
389
|
+
n_neurons_per_layer = [100, 1000, subdofs_to_learn.shape[0]]
|
|
290
390
|
|
|
291
391
|
# Sets a list of layers and the activation functions
|
|
292
392
|
|
|
@@ -294,11 +394,12 @@ if __name__=="__main__":
|
|
|
294
394
|
n_neurons_per_layer[0]}}, {"elu": {"number of neurons":
|
|
295
395
|
n_neurons_per_layer[1]}}, {"linear": n_neurons_per_layer[2]}]
|
|
296
396
|
|
|
297
|
-
activations_list_auxiliar_network = [{"quadratic": {"number"+
|
|
298
|
-
"
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
397
|
+
activations_list_auxiliar_network = [{"quadratic": {"number of neu"+
|
|
398
|
+
"rons": min(quotient_space_dimension, n_neurons_per_layer[0]), "a2":
|
|
399
|
+
1.0}},
|
|
400
|
+
{"quadratic": {"number of neurons": min(n_neurons_per_layer[0],
|
|
401
|
+
n_neurons_per_layer[1]), "a2": 1.0}},
|
|
402
|
+
{"quadratic": {"number of neurons": min(n_neurons_per_layer[1],
|
|
302
403
|
n_neurons_per_layer[2])}}]
|
|
303
404
|
|
|
304
405
|
# Sets the modulating function for the weights matrices
|
|
@@ -307,6 +408,8 @@ if __name__=="__main__":
|
|
|
307
408
|
|
|
308
409
|
# Sets the training information
|
|
309
410
|
|
|
411
|
+
optimizer = "Adam"
|
|
412
|
+
|
|
310
413
|
n_training_samples = 10000
|
|
311
414
|
|
|
312
415
|
maximum_training_iterations = 1000
|
|
@@ -317,20 +420,42 @@ if __name__=="__main__":
|
|
|
317
420
|
|
|
318
421
|
n_best_models = 5
|
|
319
422
|
|
|
423
|
+
n_best_samples = 10
|
|
424
|
+
|
|
320
425
|
loss_metric = "MeanSquaredError"
|
|
321
426
|
|
|
427
|
+
loss_metric = {"name": "LpNormError", "p": 12, "use_stable_impleme"+
|
|
428
|
+
"ntation": True}
|
|
429
|
+
|
|
322
430
|
parameters_dtype = "float32"
|
|
323
431
|
|
|
324
432
|
saved_model_file = "RVE_kinematics_model.keras"
|
|
325
433
|
|
|
326
434
|
# Sets the path for the data
|
|
327
435
|
|
|
328
|
-
results_path = get_parent_path_of_file()+"//
|
|
436
|
+
results_path = (get_parent_path_of_file()+"//results_n_divisions_"+
|
|
437
|
+
str(n_divisions))
|
|
329
438
|
|
|
330
439
|
displacement_data_file = "00_successful_displacement_matrix.npy"
|
|
331
440
|
|
|
332
441
|
input_data_file = "00_successful_complete_and_filtered_data_matrix.npy"
|
|
333
442
|
|
|
443
|
+
mesh_file_name = get_parent_path_of_file()+"//box_mesh_mecsol"
|
|
444
|
+
|
|
445
|
+
# Sets the method to regularize the input data matrix
|
|
446
|
+
|
|
447
|
+
input_data_regularization_method = ("maximum_absolute_order_normal"+
|
|
448
|
+
"ization")
|
|
449
|
+
|
|
450
|
+
# Sets the device type where the training will be performed
|
|
451
|
+
|
|
452
|
+
device_type = "GPU"
|
|
453
|
+
|
|
454
|
+
# Sets whether the constraint on orthogonality of the SVD matrices
|
|
455
|
+
# will not be enforced
|
|
456
|
+
|
|
457
|
+
non_orthogonal_matrices = True
|
|
458
|
+
|
|
334
459
|
# Instantiates the class that owns all information about training
|
|
335
460
|
# and testing models
|
|
336
461
|
|
|
@@ -339,14 +464,21 @@ if __name__=="__main__":
|
|
|
339
464
|
quotient_space_dimension, modulating_function,
|
|
340
465
|
displacement_data_file, input_data_file, results_path, loss_metric,
|
|
341
466
|
n_training_samples, saved_model_file, n_monte_carlo_realizations,
|
|
342
|
-
n_best_models, maximum_training_iterations,
|
|
343
|
-
|
|
344
|
-
|
|
467
|
+
n_best_models, n_best_samples, maximum_training_iterations,
|
|
468
|
+
verbose_delta_iterations, mesh_file_name, optimizer,
|
|
469
|
+
subdofs_to_learn, parameters_dtype=parameters_dtype,
|
|
470
|
+
householder_epsilon=1.0, verbose=True, device_type=
|
|
471
|
+
device_type, non_orthogonal_matrices=non_orthogonal_matrices,
|
|
472
|
+
input_data_regularization_method=input_data_regularization_method)
|
|
345
473
|
|
|
346
474
|
training_flag = True
|
|
347
475
|
|
|
476
|
+
testing_flag = False
|
|
477
|
+
|
|
348
478
|
if training_flag:
|
|
349
479
|
|
|
350
480
|
modeling_class.train_surrogate_model()
|
|
351
481
|
|
|
352
|
-
|
|
482
|
+
if testing_flag:
|
|
483
|
+
|
|
484
|
+
modeling_class.test_surrogate_model()
|