8
8
import rbnicsx .online
9
9
10
10
from dlrbnicsx_thermomechanical_geometric_deformation import MeshDeformationWrapperClass
11
+ from dlrbnicsx_thermal import ThermalProblemOnDeformedDomain
11
12
12
13
from mpi4py import MPI
13
14
from petsc4py import PETSc
27
28
from dlrbnicsx .train_validate_test .train_validate_test import \
28
29
train_nn , validate_nn , online_nn , error_analysis
29
30
30
- class ThermalProblemOnDeformedDomain (abc .ABC ):
31
- def __init__ (self , mesh , subdomains , boundaries ):
32
- self ._mesh = mesh
33
- self ._subdomains = subdomains
34
- self ._boundaries = boundaries
35
- dx = ufl .Measure ("dx" , domain = mesh , subdomain_data = subdomains )
36
- ds = ufl .Measure ("ds" , domain = self ._mesh , subdomain_data = self ._boundaries )
37
- self .dx = dx
38
- self ._ds_sf = ds (11 ) + ds (20 ) + ds (21 ) + ds (22 ) + ds (23 )
39
- self ._ds_bottom = ds (1 ) + ds (31 )
40
- self ._ds_out = ds (30 )
41
- self ._ds_sym = ds (5 ) + ds (9 ) + ds (12 )
42
- self ._ds_top = ds (18 ) + ds (19 ) + ds (27 ) + ds (28 ) + ds (29 )
43
- x = ufl .SpatialCoordinate (self ._mesh )
44
- self ._VT = dolfinx .fem .FunctionSpace (self ._mesh , ("CG" , 1 ))
45
- uT , vT = ufl .TrialFunction (self ._VT ), ufl .TestFunction (self ._VT )
46
- self ._trial , self ._test = uT , vT
47
- self ._inner_product = ufl .inner (uT , vT ) * x [0 ] * ufl .dx + \
48
- ufl .inner (ufl .grad (uT ), ufl .grad (vT )) * x [0 ] * ufl .dx
49
- self .inner_product_action = \
50
- rbnicsx .backends .bilinear_form_action (self ._inner_product ,
51
- part = "real" )
52
- self ._T_f , self ._T_out , self ._T_bottom = 1773. , 300. , 300.
53
- self ._h_cf , self ._h_cout , self ._h_cbottom = 2000. , 200. , 200.
54
- self ._q_source = dolfinx .fem .Function (self ._VT )
55
- self ._q_source .x .array [:] = 0.
56
- self ._q_top = dolfinx .fem .Function (self ._VT )
57
- self ._q_top .x .array [:] = 0.
58
- self .uT_func = dolfinx .fem .Function (self ._VT )
59
- self .mu_ref = [0.6438 , 0.4313 , 1. , 0.5 ]
60
-
61
- self ._max_iterations = 20
62
- self .rtol = 1.e-4
63
- self .atol = 1.e-12
64
-
65
- def thermal_diffusivity_1 (self , sym_T ):
66
- conditions = [ufl .le (sym_T , 293. ), ufl .And (ufl .ge (sym_T , 293. ), ufl .le (sym_T , 673. )), ufl .And (ufl .ge (sym_T , 673. ), ufl .le (sym_T , 1273. )), ufl .ge (sym_T , 1273. )]
67
- interps = [8.17484662576687e-6 * sym_T ** 2 - 0.00926193251533741 * sym_T + 18.0819438190184 , 8.17484662576687e-6 * sym_T ** 2 - 0.00926193251533741 * sym_T + 18.0819438190184 , 1.76073619631904e-6 * sym_T ** 2 - 0.000628539877300632 * sym_T + 15.176807196319 , 1.76073619631904e-6 * sym_T ** 2 - 0.000628539877300632 * sym_T + 15.176807196319 ]
68
- assert len (conditions ) == len (interps )
69
- d_func = ufl .conditional (conditions [0 ], interps [0 ], interps [0 ])
70
- for i in range (1 , len (conditions )):
71
- d_func = ufl .conditional (conditions [i ], interps [i ], d_func )
72
- return d_func
73
-
74
- def thermal_diffusivity_2 (self , sym_T ):
75
- conditions = [ufl .le (sym_T , 293. ), ufl .And (ufl .ge (sym_T , 293. ), ufl .le (sym_T , 693. )), ufl .And (ufl .ge (sym_T , 673. ), ufl .le (sym_T , 1273. )), ufl .ge (sym_T , 1273. )]
76
- interps = [0.000299054192229039 * sym_T ** 2 - 0.36574217791411 * sym_T + 130.838954780164 , 0.000299054192229039 * sym_T ** 2 - 0.36574217791411 * sym_T + 130.838954780164 , - 1.10434560327197e-5 * sym_T ** 2 + 0.0516492566462166 * sym_T - 9.61326294938646 , - 1.10434560327197e-5 * sym_T ** 2 + 0.0516492566462166 * sym_T - 9.61326294938646 ]
77
- assert len (conditions ) == len (interps )
78
- d_func = ufl .conditional (conditions [0 ], interps [0 ], interps [0 ])
79
- for i in range (1 , len (conditions )):
80
- d_func = ufl .conditional (conditions [i ], interps [i ], d_func )
81
- return d_func
82
-
83
- def thermal_diffusivity_3 (self , sym_T ):
84
- conditions = [ufl .le (sym_T , 293. ), ufl .And (ufl .ge (sym_T , 293. ), ufl .le (sym_T , 693. )), ufl .And (ufl .ge (sym_T , 673. ), ufl .le (sym_T , 1273. )), ufl .ge (sym_T , 1273. )]
85
- interps = [8.17484662576687e-6 * sym_T ** 2 - 0.00926193251533741 * sym_T + 18.0819438190184 , 8.17484662576687e-6 * sym_T ** 2 - 0.00926193251533741 * sym_T + 18.0819438190184 , 1.76073619631904e-6 * sym_T ** 2 - 0.000628539877300632 * sym_T + 15.176807196319 , 1.76073619631904e-6 * sym_T ** 2 - 0.000628539877300632 * sym_T + 15.176807196319 ]
86
- assert len (conditions ) == len (interps )
87
- d_func = ufl .conditional (conditions [0 ], interps [0 ], interps [0 ])
88
- for i in range (1 , len (conditions )):
89
- d_func = ufl .conditional (conditions [i ], interps [i ], d_func )
90
- return d_func
91
-
92
- def thermal_diffusivity_4 (self , sym_T ):
93
- conditions = [ufl .le (sym_T , 293. ), ufl .And (ufl .ge (sym_T , 293. ), ufl .le (sym_T , 693. )), ufl .And (ufl .ge (sym_T , 673. ), ufl .le (sym_T , 1273. )), ufl .ge (sym_T , 1273. )]
94
- interps = [8.17484662576687e-6 * sym_T ** 2 - 0.00926193251533741 * sym_T + 18.0819438190184 , 8.17484662576687e-6 * sym_T ** 2 - 0.00926193251533741 * sym_T + 18.0819438190184 , 1.76073619631904e-6 * sym_T ** 2 - 0.000628539877300632 * sym_T + 15.176807196319 , 1.76073619631904e-6 * sym_T ** 2 - 0.000628539877300632 * sym_T + 15.176807196319 ]
95
- assert len (conditions ) == len (interps )
96
- d_func = ufl .conditional (conditions [0 ], interps [0 ], interps [0 ])
97
- for i in range (1 , len (conditions )):
98
- d_func = ufl .conditional (conditions [i ], interps [i ], d_func )
99
- return d_func
100
-
101
- def thermal_diffusivity_5 (self , sym_T ):
102
- conditions = [ufl .le (sym_T , 293. ), ufl .And (ufl .ge (sym_T , 293. ), ufl .le (sym_T , 693. )), ufl .And (ufl .ge (sym_T , 673. ), ufl .le (sym_T , 1273. )), ufl .ge (sym_T , 1273. )]
103
- interps = [3.08018064076346e-5 * sym_T ** 2 - 0.0376497392638036 * sym_T + 31.7270693260054 , 3.08018064076346e-5 * sym_T ** 2 - 0.0376497392638036 * sym_T + 31.7270693260054 , - 2.79311520109062e-6 * sym_T ** 2 + 0.00756902522154049 * sym_T + 16.5109550766871 , - 2.79311520109062e-6 * sym_T ** 2 + 0.00756902522154049 * sym_T + 16.5109550766871 ]
104
- assert len (conditions ) == len (interps )
105
- d_func = ufl .conditional (conditions [0 ], interps [0 ], interps [0 ])
106
- for i in range (1 , len (conditions )):
107
- d_func = ufl .conditional (conditions [i ], interps [i ], d_func )
108
- return d_func
109
-
110
- def thermal_diffusivity_6 (self , sym_T ):
111
- conditions = [ufl .le (sym_T , 293. ), ufl .And (ufl .ge (sym_T , 293. ), ufl .le (sym_T , 693. )), ufl .And (ufl .ge (sym_T , 673. ), ufl .le (sym_T , 1273. )), ufl .ge (sym_T , 1273. )]
112
- interps = [8.17484662576687e-6 * sym_T ** 2 - 0.00926193251533741 * sym_T + 18.0819438190184 , 8.17484662576687e-6 * sym_T ** 2 - 0.00926193251533741 * sym_T + 18.0819438190184 , 1.76073619631904e-6 * sym_T ** 2 - 0.000628539877300632 * sym_T + 15.176807196319 , 1.76073619631904e-6 * sym_T ** 2 - 0.000628539877300632 * sym_T + 15.176807196319 ]
113
- assert len (conditions ) == len (interps )
114
- d_func = ufl .conditional (conditions [0 ], interps [0 ], interps [0 ])
115
- for i in range (1 , len (conditions )):
116
- d_func = ufl .conditional (conditions [i ], interps [i ], d_func )
117
- return d_func
118
-
119
- def thermal_diffusivity_7 (self , sym_T ):
120
- conditions = [ufl .le (sym_T , 293. ), ufl .And (ufl .ge (sym_T , 293. ), ufl .le (sym_T , 693. )), ufl .And (ufl .ge (sym_T , 673. ), ufl .le (sym_T , 1273. )), ufl .ge (sym_T , 1273. )]
121
- interps = [0.000299054192229039 * sym_T ** 2 - 0.36574217791411 * sym_T + 130.838954780164 , 0.000299054192229039 * sym_T ** 2 - 0.36574217791411 * sym_T + 130.838954780164 , - 1.10434560327197e-5 * sym_T ** 2 + 0.0516492566462166 * sym_T - 9.61326294938646 , - 1.10434560327197e-5 * sym_T ** 2 + 0.0516492566462166 * sym_T - 9.61326294938646 ]
122
- assert len (conditions ) == len (interps )
123
- d_func = ufl .conditional (conditions [0 ], interps [0 ], interps [0 ])
124
- for i in range (1 , len (conditions )):
125
- d_func = ufl .conditional (conditions [i ], interps [i ], d_func )
126
- return d_func
127
-
128
- @property
129
- def lhs_form (self ):
130
- uT_func , vT = self .uT_func , self ._test
131
- x = ufl .SpatialCoordinate (self ._mesh )
132
- dx = self .dx
133
- a_T = \
134
- ufl .inner (self .thermal_diffusivity_1 (uT_func ) * ufl .grad (uT_func ), ufl .grad (vT )) * x [0 ] * dx (1 ) + \
135
- ufl .inner (self .thermal_diffusivity_2 (uT_func ) * ufl .grad (uT_func ), ufl .grad (vT )) * x [0 ] * dx (2 ) + \
136
- ufl .inner (5.3 * ufl .grad (uT_func ), ufl .grad (vT )) * x [0 ] * dx (3 ) + \
137
- ufl .inner (4.75 * ufl .grad (uT_func ), ufl .grad (vT )) * x [0 ] * dx (4 ) + \
138
- ufl .inner (self .thermal_diffusivity_5 (uT_func ) * ufl .grad (uT_func ), ufl .grad (vT )) * x [0 ] * dx (5 ) + \
139
- ufl .inner (45.6 * ufl .grad (uT_func ), ufl .grad (vT )) * x [0 ] * dx (6 ) + \
140
- ufl .inner (self .thermal_diffusivity_7 (uT_func ) * ufl .grad (uT_func ), ufl .grad (vT )) * x [0 ] * dx (7 ) + \
141
- ufl .inner (self ._h_cf * uT_func , vT ) * x [0 ] * self ._ds_sf + \
142
- ufl .inner (self ._h_cout * uT_func , vT ) * x [0 ] * self ._ds_out + \
143
- ufl .inner (self ._h_cbottom * uT_func , vT ) * x [0 ] * self ._ds_bottom
144
- return a_T
145
-
146
- @property
147
- def rhs_form (self ):
148
- vT = self ._test
149
- x = ufl .SpatialCoordinate (self ._mesh )
150
- dx = self .dx
151
- l_T = \
152
- ufl .inner (self ._q_source , vT ) * x [0 ] * dx + \
153
- self ._h_cf * vT * self ._T_f * x [0 ] * self ._ds_sf + \
154
- self ._h_cout * vT * self ._T_out * x [0 ] * self ._ds_out + \
155
- self ._h_cbottom * vT * self ._T_bottom * x [0 ] * self ._ds_bottom - \
156
- ufl .inner (self ._q_top , vT ) * x [0 ] * self ._ds_top
157
- return l_T
158
-
159
- @property
160
- def set_problem (self ):
161
- problemNonlinear = \
162
- NonlinearProblem (self .lhs_form - self .rhs_form ,
163
- self .uT_func , bcs = [])
164
- return problemNonlinear
165
-
166
- def solve (self , mu ):
167
- vT = self ._test
168
- self .mu = mu
169
- self .uT_func .x .array [:] = 350.
170
- self .uT_func .x .scatter_forward ()
171
- problemNonlinear = self .set_problem
172
- solution = dolfinx .fem .Function (self ._VT )
173
- with MeshDeformationWrapperClass (self ._mesh , self ._boundaries ,
174
- self .mu_ref , self .mu ):
175
- solver = NewtonSolver (self ._mesh .comm , problemNonlinear )
176
- solver .convergence_criterion = "incremental"
177
-
178
- solver .rtol = 1e-10
179
- solver .report = True
180
- ksp = solver .krylov_solver
181
- ksp .setFromOptions ()
182
- # dolfinx.log.set_log_level(dolfinx.log.LogLevel.INFO)
183
-
184
- n , converged = solver .solve (self .uT_func )
185
- # print(f"Computed solution array: {uT_func.x.array}")
186
- assert (converged )
187
- print (f"Number of interations: { n :d} " )
188
-
189
- solution .x .array [:] = self .uT_func .x .array .copy ()
190
- solution .x .scatter_forward ()
191
- x = ufl .SpatialCoordinate (self ._mesh )
192
- print (f"Temperature field norm: { self ._mesh .comm .allreduce (dolfinx .fem .assemble_scalar (dolfinx .fem .form (ufl .inner (solution , solution ) * x [0 ] * ufl .dx + ufl .inner (ufl .grad (solution ), ufl .grad (solution )) * x [0 ] * ufl .dx )))} " )
193
- return solution
194
-
195
31
class MechanicalProblemOnDeformedDomain (abc .ABC ):
196
32
def __init__ (self , mesh , subdomains , boundaries , thermalproblem ):
197
33
self ._mesh = mesh
@@ -404,57 +240,6 @@ def solve(self, mu):
404
240
print (f"Displacement field norm: { self ._mesh .comm .allreduce (dolfinx .fem .assemble_scalar (dolfinx .fem .form (ufl .inner (uM_func , uM_func ) * x [0 ] * ufl .dx + ufl .inner (self .epsilon (uM_func ), self .epsilon (uM_func )) * x [0 ] * ufl .dx )))} " )
405
241
return uM_func
406
242
407
- class ThermalPODANNReducedProblem (abc .ABC ):
408
- def __init__ (self , thermal_problem ) -> None :
409
- self ._basis_functions = rbnicsx .backends .FunctionsList (thermal_problem ._VT )
410
- uT , vT = ufl .TrialFunction (thermal_problem ._VT ), ufl .TestFunction (thermal_problem ._VT )
411
- x = ufl .SpatialCoordinate (thermal_problem ._mesh )
412
- self ._inner_product = ufl .inner (uT , vT ) * x [0 ] * ufl .dx + \
413
- ufl .inner (ufl .grad (uT ), ufl .grad (vT )) * x [0 ] * ufl .dx
414
- self ._inner_product_action = \
415
- rbnicsx .backends .bilinear_form_action (self ._inner_product ,
416
- part = "real" )
417
- self .input_scaling_range = [- 1. , 1. ]
418
- self .output_scaling_range = [- 1. , 1. ]
419
- self .input_range = \
420
- np .array ([[0.55 , 0.35 , 0.8 , 0.4 ], [0.75 , 0.55 , 1.2 , 0.6 ]])
421
- self .output_range = [- 6. , 3. ]
422
- self .regularisation = "EarlyStopping"
423
-
424
- def reconstruct_solution (self , reduced_solution ):
425
- """Reconstructed reduced solution on the high fidelity space."""
426
- return self ._basis_functions [:reduced_solution .size ] * \
427
- reduced_solution
428
-
429
- def compute_norm (self , function ):
430
- """Compute the norm of a function inner product
431
- on the reference domain."""
432
- return np .sqrt (self ._inner_product_action (function )(function ))
433
-
434
- def project_snapshot (self , solution , N ):
435
- return self ._project_snapshot (solution , N )
436
-
437
- def _project_snapshot (self , solution , N ):
438
- projected_snapshot = rbnicsx .online .create_vector (N )
439
- A = rbnicsx .backends .\
440
- project_matrix (self ._inner_product_action ,
441
- self ._basis_functions [:N ])
442
- F = rbnicsx .backends .\
443
- project_vector (self ._inner_product_action (solution ),
444
- self ._basis_functions [:N ])
445
- ksp = PETSc .KSP ()
446
- ksp .create (projected_snapshot .comm )
447
- ksp .setOperators (A )
448
- ksp .setType ("preonly" )
449
- ksp .getPC ().setType ("lu" )
450
- ksp .setFromOptions ()
451
- ksp .solve (F , projected_snapshot )
452
- return projected_snapshot
453
-
454
- def norm_error (self , u , v ):
455
- return self .compute_norm (u - v )/ self .compute_norm (u )
456
-
457
-
458
243
class MechanicalPODANNReducedProblem (abc .ABC ):
459
244
def __init__ (self , mechanical_problem ) -> None :
460
245
self ._basis_functions = rbnicsx .backends .FunctionsList (mechanical_problem ._VM )
@@ -525,6 +310,7 @@ def norm_error(self, u, v):
525
310
thermal_problem_parametric = \
526
311
ThermalProblemOnDeformedDomain (mesh , cell_tags , facet_tags )
527
312
313
+ '''
528
314
# solution_mu = thermal_problem_parametric.solve(mu_ref)
529
315
# print(f"Solution norm at mu:{mu_ref}: {thermal_problem_parametric.inner_product_action(solution_mu)(solution_mu)}")
530
316
@@ -540,7 +326,7 @@ def norm_error(self, u, v):
540
326
with dolfinx.io.XDMFFile(mesh.comm, computed_file, "w") as solution_file:
541
327
solution_file.write_mesh(mesh)
542
328
solution_file.write_function(uT_func_plot)
543
-
329
+ '''
544
330
# Thermal POD Starts ###
545
331
546
332
def generate_training_set (samples = pod_samples ):
@@ -554,7 +340,7 @@ def generate_training_set(samples=pod_samples):
554
340
training_set_3 )))
555
341
return training_set
556
342
557
-
343
+ '''
558
344
thermal_training_set = rbnicsx.io.on_rank_zero(mesh.comm, generate_training_set)
559
345
560
346
Nmax = 30
@@ -614,7 +400,7 @@ def generate_training_set(samples=pod_samples):
614
400
plt.savefig("thermal_eigenvalues.png")
615
401
616
402
print(f"Eigenvalues (Thermal): {thermal_positive_eigenvalues}")
617
-
403
+ '''
618
404
# Thermal POD Ends ###
619
405
620
406
# 5. ANN implementation
@@ -648,7 +434,7 @@ def generate_ann_output_set(problem, reduced_problem,
648
434
len (reduced_problem ._basis_functions )).array .astype ("f" )
649
435
return output_set
650
436
651
-
437
+ '''
652
438
# Training dataset
653
439
thermal_ann_input_set = generate_ann_input_set(samples=ann_samples)
654
440
# np.random.shuffle(thermal_ann_input_set)
@@ -753,7 +539,7 @@ def generate_ann_output_set(problem, reduced_problem,
753
539
print(f"Error: {thermal_error_numpy[i]}")
754
540
755
541
# ### Thermal ANN ends
756
-
542
+ '''
757
543
mechanical_problem_parametric = \
758
544
MechanicalProblemOnDeformedDomain (mesh , cell_tags , facet_tags ,
759
545
thermal_problem_parametric )
@@ -943,6 +729,7 @@ def generate_ann_output_set(problem, reduced_problem,
943
729
944
730
# ### Online phase ###
945
731
online_mu = np .array ([0.45 , 0.56 , 0.9 , 0.7 ])
732
+ '''
946
733
thermal_fem_solution = thermal_problem_parametric.solve(online_mu)
947
734
thermal_rb_solution = \
948
735
thermal_reduced_problem.reconstruct_solution(
@@ -998,7 +785,7 @@ def generate_ann_output_set(problem, reduced_problem,
998
785
999
786
print(thermal_reduced_problem.norm_error(thermal_fem_solution, thermal_rb_solution))
1000
787
print(thermal_reduced_problem.compute_norm(thermal_error_function))
1001
-
788
+ '''
1002
789
mechanical_fem_solution = mechanical_problem_parametric .solve (online_mu )
1003
790
mechanical_rb_solution = \
1004
791
mechanical_reduced_problem .reconstruct_solution (
@@ -1051,5 +838,5 @@ def generate_ann_output_set(problem, reduced_problem,
1051
838
print (mechanical_reduced_problem .norm_error (mechanical_fem_solution , mechanical_rb_solution ))
1052
839
print (mechanical_reduced_problem .compute_norm (mechanical_error_function ))
1053
840
1054
- print (f"Training time (Thermal): { thermal_elapsed_time } " )
841
+ # print(f"Training time (Thermal): {thermal_elapsed_time}")
1055
842
print (f"Training time (Mechanical): { mechanical_elapsed_time } " )
0 commit comments