88import rbnicsx .online
99
1010from dlrbnicsx_thermomechanical_geometric_deformation import MeshDeformationWrapperClass
11+ from dlrbnicsx_thermal import ThermalProblemOnDeformedDomain
1112
1213from mpi4py import MPI
1314from petsc4py import PETSc
2728from dlrbnicsx .train_validate_test .train_validate_test import \
2829 train_nn , validate_nn , online_nn , error_analysis
2930
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-
19531class MechanicalProblemOnDeformedDomain (abc .ABC ):
19632 def __init__ (self , mesh , subdomains , boundaries , thermalproblem ):
19733 self ._mesh = mesh
@@ -404,57 +240,6 @@ def solve(self, mu):
404240 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 )))} " )
405241 return uM_func
406242
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-
458243class MechanicalPODANNReducedProblem (abc .ABC ):
459244 def __init__ (self , mechanical_problem ) -> None :
460245 self ._basis_functions = rbnicsx .backends .FunctionsList (mechanical_problem ._VM )
@@ -525,6 +310,7 @@ def norm_error(self, u, v):
525310thermal_problem_parametric = \
526311 ThermalProblemOnDeformedDomain (mesh , cell_tags , facet_tags )
527312
313+ '''
528314# solution_mu = thermal_problem_parametric.solve(mu_ref)
529315# print(f"Solution norm at mu:{mu_ref}: {thermal_problem_parametric.inner_product_action(solution_mu)(solution_mu)}")
530316
@@ -540,7 +326,7 @@ def norm_error(self, u, v):
540326 with dolfinx.io.XDMFFile(mesh.comm, computed_file, "w") as solution_file:
541327 solution_file.write_mesh(mesh)
542328 solution_file.write_function(uT_func_plot)
543-
329+ '''
544330# Thermal POD Starts ###
545331
546332def generate_training_set (samples = pod_samples ):
@@ -554,7 +340,7 @@ def generate_training_set(samples=pod_samples):
554340 training_set_3 )))
555341 return training_set
556342
557-
343+ '''
558344thermal_training_set = rbnicsx.io.on_rank_zero(mesh.comm, generate_training_set)
559345
560346Nmax = 30
@@ -614,7 +400,7 @@ def generate_training_set(samples=pod_samples):
614400plt.savefig("thermal_eigenvalues.png")
615401
616402print(f"Eigenvalues (Thermal): {thermal_positive_eigenvalues}")
617-
403+ '''
618404# Thermal POD Ends ###
619405
620406# 5. ANN implementation
@@ -648,7 +434,7 @@ def generate_ann_output_set(problem, reduced_problem,
648434 len (reduced_problem ._basis_functions )).array .astype ("f" )
649435 return output_set
650436
651-
437+ '''
652438# Training dataset
653439thermal_ann_input_set = generate_ann_input_set(samples=ann_samples)
654440# np.random.shuffle(thermal_ann_input_set)
@@ -753,7 +539,7 @@ def generate_ann_output_set(problem, reduced_problem,
753539 print(f"Error: {thermal_error_numpy[i]}")
754540
755541# ### Thermal ANN ends
756-
542+ '''
757543mechanical_problem_parametric = \
758544 MechanicalProblemOnDeformedDomain (mesh , cell_tags , facet_tags ,
759545 thermal_problem_parametric )
@@ -943,6 +729,7 @@ def generate_ann_output_set(problem, reduced_problem,
943729
944730# ### Online phase ###
945731online_mu = np .array ([0.45 , 0.56 , 0.9 , 0.7 ])
732+ '''
946733thermal_fem_solution = thermal_problem_parametric.solve(online_mu)
947734thermal_rb_solution = \
948735 thermal_reduced_problem.reconstruct_solution(
@@ -998,7 +785,7 @@ def generate_ann_output_set(problem, reduced_problem,
998785
999786print(thermal_reduced_problem.norm_error(thermal_fem_solution, thermal_rb_solution))
1000787print(thermal_reduced_problem.compute_norm(thermal_error_function))
1001-
788+ '''
1002789mechanical_fem_solution = mechanical_problem_parametric .solve (online_mu )
1003790mechanical_rb_solution = \
1004791 mechanical_reduced_problem .reconstruct_solution (
@@ -1051,5 +838,5 @@ def generate_ann_output_set(problem, reduced_problem,
1051838 print (mechanical_reduced_problem .norm_error (mechanical_fem_solution , mechanical_rb_solution ))
1052839 print (mechanical_reduced_problem .compute_norm (mechanical_error_function ))
1053840
1054- print (f"Training time (Thermal): { thermal_elapsed_time } " )
841+ # print(f"Training time (Thermal): {thermal_elapsed_time}")
1055842print (f"Training time (Mechanical): { mechanical_elapsed_time } " )
0 commit comments