1+ import KratosMultiphysics
2+ from KratosMultiphysics .FluidDynamicsApplication .fluid_dynamics_analysis import FluidDynamicsAnalysis
3+
4+ import json
5+
6+ import numpy as np
7+
8+ #for checking if paths exits
9+ import os
10+
11+ #importing training trajectory
12+ from simulation_trajectories import TrainingTrajectory
13+
14+
15+
16+ class FOM_Class (FluidDynamicsAnalysis ):
17+
18+ def __init__ (self , model , project_parameters ):
19+ super ().__init__ (model , project_parameters )
20+ self .control_point = 538 #a node around the middle of the geometry to capture the bufurcation
21+ self .velocity_y_at_control_point = []
22+ self .narrowing_width = []
23+ self .time_step_solution_container = []
24+ self .reynolds_number_container = []
25+
26+
27+ def InitialMeshPosition (self ):
28+ self .training_trajectory = TrainingTrajectory (self .project_parameters ["solver_settings" ]["fluid_solver_settings" ]["time_stepping" ]["time_step" ].GetDouble ())
29+ self .w = self .training_trajectory .SetUpInitialNarrowing ()
30+ self .MoveAllPartsAccordingToW ()
31+
32+ def ModifyInitialGeometry (self ):
33+ super ().ModifyInitialGeometry ()
34+ self .InitialMeshPosition ()
35+
36+
37+
38+ def MovePart (self , part_name , jacobian , centering_vector , extra_centering ):
39+ x_original = []
40+ y_original = []
41+ # first loop
42+ for node in self .model .GetModelPart (f"FluidModelPart.{ part_name } " ).Nodes :
43+ if not node .IsFixed (KratosMultiphysics .MESH_DISPLACEMENT_X ):
44+ x_original .append (node .X0 )
45+ if not node .IsFixed (KratosMultiphysics .MESH_DISPLACEMENT_Y ):
46+ y_original .append (node .Y0 )
47+ x_original = np .array (x_original ).reshape (1 ,- 1 )
48+ y_original = np .array (y_original ).reshape (1 ,- 1 )
49+ matrix_of_coordinates = np .r_ [x_original , y_original ]
50+ modified_matrix_of_coordinates = np .linalg .inv (jacobian ) @ (matrix_of_coordinates - centering_vector )
51+ modified_matrix_of_coordinates += centering_vector + extra_centering #re-locating
52+ # second loop
53+ i = 0
54+ for node in self .model .GetModelPart (f"FluidModelPart.{ part_name } " ).Nodes :
55+ if not node .IsFixed (KratosMultiphysics .MESH_DISPLACEMENT_X ):
56+ x_disp = modified_matrix_of_coordinates [0 ,i ] - node .X0
57+ node .SetSolutionStepValue (KratosMultiphysics .MESH_DISPLACEMENT_X ,0 , x_disp )
58+ if not node .IsFixed (KratosMultiphysics .MESH_DISPLACEMENT_Y ):
59+ y_disp = modified_matrix_of_coordinates [1 ,i ] - node .Y0
60+ node .SetSolutionStepValue (KratosMultiphysics .MESH_DISPLACEMENT_Y ,0 , y_disp )
61+ i += 1
62+ node .Fix (KratosMultiphysics .MESH_DISPLACEMENT_X )
63+ node .Fix (KratosMultiphysics .MESH_DISPLACEMENT_Y )
64+
65+
66+ def StoreBifurcationData (self ):
67+ # node = self.model.GetModelPart("FluidModelPart").GetNode(self.control_point)
68+ # self.velocity_y_at_control_point.append(node.GetSolutionStepValue(KratosMultiphysics.VELOCITY_Y))
69+ # self.narrowing_width.append(self.w)
70+ for node in self .model .GetModelPart ("FluidModelPart.GENERIC_Meassure" ).Nodes :
71+ pass
72+ #node = self.model.GetModelPart("Meassure").GetNode(self.control_point)
73+ self .velocity_y_at_control_point .append (node .GetSolutionStepValue (KratosMultiphysics .VELOCITY_Y ))
74+ self .narrowing_width .append (self .w )
75+
76+
77+ def MoveAllPartsAccordingToW (self ):
78+ #############################
79+ #### FREE ALL NODES ####
80+ #############################
81+ for node in self .model .GetModelPart ("FluidModelPart" ).Nodes :
82+ node .Free (KratosMultiphysics .MESH_DISPLACEMENT_X )
83+ node .Free (KratosMultiphysics .MESH_DISPLACEMENT_Y )
84+
85+ #############################
86+ #### FIXING OUTSIDE PART ####
87+ #############################
88+ for node in self .model .GetModelPart ("FluidModelPart.GENERIC_not_moving" ).Nodes :
89+ node .SetSolutionStepValue (KratosMultiphysics .MESH_DISPLACEMENT_X ,0 , 0 )
90+ node .Fix (KratosMultiphysics .MESH_DISPLACEMENT_X )
91+ node .SetSolutionStepValue (KratosMultiphysics .MESH_DISPLACEMENT_Y ,0 , 0 )
92+ node .Fix (KratosMultiphysics .MESH_DISPLACEMENT_Y )
93+
94+ #############################
95+ ### MOVE EACH SUB-PART ###
96+ #############################
97+ self .MovePart ('GENERIC_green' , np .array ([[1 ,0 ],[0 ,1 / self .w ]]), np .array ([[0 ],[1.5 ]]), np .array ([[0 ],[0 ]]))
98+ self .MovePart ('GENERIC_yellow_up' , np .array ([[1 ,0 ],[0 , (2 / (3 - self .w ))]]), np .array ([[0 ],[3 ]]), np .array ([[0 ],[0 ]]))
99+ self .MovePart ('GENERIC_yellow_down' , np .array ([[1 ,0 ],[0 , 2 / (3 - self .w )]]), np .array ([[0 ],[0 ]]), np .array ([[0 ],[0 ]]))
100+ self .MovePart ('GENERIC_blue' , np .array ([[1 ,0 ],[(self .w - 1 )/ 2 , 1 ]]), np .array ([[0 ],[0 ]]), np .array ([[0 ],[(self .w - 1 )/ 4 ]]))
101+ self .MovePart ('GENERIC_grey' , np .array ([[1 ,0 ],[(1 - self .w )/ 2 , 1 ]]), np .array ([[0 ],[0 ]]), np .array ([[0 ],[- (self .w - 1 )/ 4 ]]))
102+
103+
104+
105+ def UpdateNarrowing (self ):
106+ self .w = self .training_trajectory .UpdateW (self .w )
107+
108+
109+
110+
111+
112+ def InitializeSolutionStep (self ):
113+ super ().InitializeSolutionStep ()
114+
115+ if self .time > 10.0 : # start modifying narrowing from 10 seconds onwards (How long does it take to close????)
116+ self .UpdateNarrowing ()
117+ self .MoveAllPartsAccordingToW ()
118+
119+ print ('The current Reynolds Number is: ' , self .GetReynolds ())
120+
121+
122+
123+ def GetReynolds (self ):
124+ #TODO Make values agree with papers. Parameter to modify: dunamic viscosity niu
125+ velocities = []
126+ for node in self .model .GetModelPart ("FluidModelPart.GENERIC_narrowing_zone" ).Nodes :
127+ velocities .append (node .GetSolutionStepValue (KratosMultiphysics .VELOCITY_X , 0 ))
128+ vel_np = np .array (velocities )
129+
130+ vx = np .max (vel_np ) #np.mean(vel_np)
131+ Re = (vx * self .w ) / 0.1 #TODO retrieve dynamic viscosity in a more robust way
132+ return Re
133+
134+
135+
136+ def FinalizeSolutionStep (self ):
137+ super ().FinalizeSolutionStep ()
138+ self .StoreBifurcationData ()
139+ self .reynolds_number_container .append (self .GetReynolds ())
140+
141+ ArrayOfResults = []
142+ for node in self ._GetSolver ().fluid_solver .GetComputingModelPart ().Nodes :
143+ ArrayOfResults .append (node .GetSolutionStepValue (KratosMultiphysics .VELOCITY_X , 0 ))
144+ ArrayOfResults .append (node .GetSolutionStepValue (KratosMultiphysics .VELOCITY_Y , 0 ))
145+ ArrayOfResults .append (node .GetSolutionStepValue (KratosMultiphysics .PRESSURE , 0 ))
146+ self .time_step_solution_container .append (ArrayOfResults )
147+
148+ def GetBifuracationData (self ):
149+ return np .array (self .velocity_y_at_control_point ) , np .array (self .narrowing_width )
150+
151+ def GetReynoldsData (self ):
152+ return np .array (self .reynolds_number_container )
153+
154+ def GetSnapshotsMatrix (self ):
155+ SnapshotMatrix = np .zeros ((len (self .time_step_solution_container [0 ]), len (self .time_step_solution_container )))
156+ for i in range (len (self .time_step_solution_container )):
157+ Snapshot_i = np .array (self .time_step_solution_container [i ])
158+ SnapshotMatrix [:,i ] = Snapshot_i .transpose ()
159+ return SnapshotMatrix
160+
161+
162+
163+
164+
165+
166+
167+
168+
169+
170+
171+
172+
173+
174+
175+
176+
177+
178+
179+
180+
181+
182+ def prepare_files (working_path ):
183+ """pre-pending the absolut path of the files in the Project Parameters"""
184+ with open (working_path + '/ProblemFiles/ProjectParameters.json' ,'r' ) as f :
185+ updated_project_parameters = json .load (f )
186+ file_input_name = updated_project_parameters ["solver_settings" ]["fluid_solver_settings" ]["model_import_settings" ]["input_filename" ]
187+ materials_filename = updated_project_parameters ["solver_settings" ]["fluid_solver_settings" ]["material_import_settings" ]["materials_filename" ]
188+ gid_output_name = updated_project_parameters ["output_processes" ]["gid_output" ][0 ]["Parameters" ]["output_name" ]
189+
190+ updated_project_parameters ["solver_settings" ]["fluid_solver_settings" ]["model_import_settings" ]["input_filename" ] = working_path + '/ProblemFiles/' + file_input_name
191+ updated_project_parameters ["solver_settings" ]["fluid_solver_settings" ]["material_import_settings" ]["materials_filename" ] = working_path + '/ProblemFiles/' + materials_filename
192+ updated_project_parameters ["output_processes" ]["gid_output" ][0 ]["Parameters" ]["output_name" ] = working_path + '/Results/FOM'
193+ updated_project_parameters ["output_processes" ]["vtk_output" ] = []
194+
195+ with open (working_path + '/ProblemFiles/ProjectParameters_modified.json' ,'w' ) as f :
196+ json .dump (updated_project_parameters , f , indent = 4 )
197+
198+
199+
200+
201+
202+
203+
204+
205+
206+ def convert_to_nd (SnapshotsMatrix , number_of_dimensions = 2 ):
207+ for i in range (np .shape (SnapshotsMatrix )[1 ]):
208+ column_mean = np .mean ( SnapshotsMatrix [:,i ].reshape (- 1 ,number_of_dimensions ).reshape (- 1 ,number_of_dimensions ),0 ).reshape (- 1 ,1 )
209+ if i == 0 :
210+ columns_means = column_mean
211+ else :
212+ columns_means = np .c_ [columns_means ,column_mean ]
213+
214+ return columns_means
215+
216+
217+
218+
219+
220+
221+
222+
223+
224+
225+
226+
227+
228+
229+
230+
231+
232+ def Train_ROM ():
233+
234+ if not os .path .exists (f'./Results/FOM.post.bin' ):
235+
236+ with open ("ProblemFiles/ProjectParameters_modified.json" , 'r' ) as parameter_file :
237+ parameters = KratosMultiphysics .Parameters (parameter_file .read ())
238+ global_model = KratosMultiphysics .Model ()
239+ simulation = FOM_Class (global_model , parameters )
240+ simulation .Run ()
241+ SnapshotsMatrix = simulation .GetSnapshotsMatrix ()
242+ velocity_y , narrowing = simulation .GetBifuracationData ()
243+ reynolds = simulation .GetReynoldsData ()
244+ np .save ('Results/reynolds.npy' , reynolds )
245+ np .save ('Results/narrowing.npy' , narrowing )
246+ np .save ('Results/Velocity_y.npy' , velocity_y )
247+ np .save ('Results/SnapshotMatrix.npy' , SnapshotsMatrix )
248+
249+
250+
251+
252+
253+
254+
255+
256+
257+
258+
259+
260+
261+
262+
263+
264+
265+
266+
267+
268+
269+
270+
271+
272+ if __name__ == "__main__" :
273+ #library for passing arguments to the script from bash
274+ from sys import argv
275+
276+ working_path = argv [1 ]
277+
278+ prepare_files (working_path )
279+
280+ Train_ROM ()
0 commit comments