From 82c9b6a9895dbe9414c0fe19c5b6c4c0ce452f09 Mon Sep 17 00:00:00 2001 From: Joseph Signorelli Date: Thu, 5 Sep 2024 17:20:35 -0500 Subject: [PATCH 1/7] Fix indents for CHT run file (tabs) --- run/SU2_preCICE_CHT.py | 460 ++++++++++++++++++++--------------------- 1 file changed, 230 insertions(+), 230 deletions(-) diff --git a/run/SU2_preCICE_CHT.py b/run/SU2_preCICE_CHT.py index a6112a6..0c4518f 100755 --- a/run/SU2_preCICE_CHT.py +++ b/run/SU2_preCICE_CHT.py @@ -26,235 +26,235 @@ def main(): - # Command line options - parser=OptionParser() - parser.add_option("-f", "--file", dest="filename", help="Read config from FILE", metavar="FILE") - parser.add_option("--parallel", action="store_true", - help="Specify if we need to initialize MPI", dest="with_MPI", default=False) - - # preCICE options with default settings - parser.add_option("-p", "--precice-participant", dest="precice_name", help="Specify preCICE participant name", default="Fluid" ) - parser.add_option("-c", "--precice-config", dest="precice_config", help="Specify preCICE config file", default="../precice-config.xml") - parser.add_option("-m", "--precice-mesh", dest="precice_mesh", help="Specify the preCICE mesh name", default="Fluid-Mesh") - parser.add_option("-r", "--precice-reverse", action="store_true", dest="precice_reverse", help="Include flag to have SU2 write temperature, read heat flux", default=False) - - # Dimension - parser.add_option("-d", "--dimension", dest="nDim", help="Dimension of fluid domain (2D/3D)", type="int", default=2) - - (options, args) = parser.parse_args() - options.nZone = int(1) # Specify number of zones here (1) - - # Import mpi4py for parallel run - if options.with_MPI == True: - from mpi4py import MPI - comm = MPI.COMM_WORLD - rank = comm.Get_rank() - else: - comm = 0 - rank = 0 - - # Initialize the corresponding driver of SU2, this includes solver preprocessing - try: - SU2Driver = pysu2.CSinglezoneDriver(options.filename, options.nZone, comm); - except TypeError as exception: - print('A TypeError occured in pysu2.CDriver : ',exception) - if options.with_MPI == True: - print('ERROR : You are trying to initialize MPI with a serial build of the wrapper. Please, remove the --parallel option that is incompatible with a serial build.') - else: - print('ERROR : You are trying to launch a computation without initializing MPI but the wrapper has been built in parallel. Please add the --parallel option in order to initialize MPI for the wrapper.') - return - - - # Configure preCICE: - size = comm.Get_size() - try: - participant = precice.Participant(options.precice_name, options.precice_config, rank, size) - except: - print("There was an error configuring preCICE") - return - - mesh_name = options.precice_mesh - - # Check preCICE + SU2 dimensions - if options.nDim != participant.get_mesh_dimensions(mesh_name): - print("SU2 and preCICE dimensions are not the same! Exiting") - return - - CHTMarkerID = None - CHTMarker = 'interface' # Name of CHT marker to couple - - # Get all the tags with the CHT option - CHTMarkerList = SU2Driver.GetAllCHTMarkersTag() - - # Get all the markers defined on this rank and their associated indices. - allMarkerIDs = SU2Driver.GetAllBoundaryMarkers() # Returns all markers defined on this rank - - #Check if the specified marker has a CHT option and if it exists on this rank. - if CHTMarker in CHTMarkerList and CHTMarker in allMarkerIDs.keys(): - CHTMarkerID = allMarkerIDs[CHTMarker] # So: if CHTMarkerID != None, then it exists on this rank - - # Number of vertices on the specified marker (per rank) - nVertex_CHTMarker = 0 #total number of vertices (physical + halo) on this rank - nVertex_CHTMarker_HALO = 0 #number of halo vertices - nVertex_CHTMarker_PHYS = 0 #number of physical vertices - iVertices_CHTMarker_PHYS = [] #indices of vertices this rank is working on - # Note: Datatypes must be primitive as input to SU2 wrapper code, not numpy.int8, numpy.int64, etc.. So a list is used - - # If the CHT marker is defined on this rank: - if CHTMarkerID != None: - nVertex_CHTMarker = SU2Driver.GetNumberVertices(CHTMarkerID) #Total number of vertices on the marker - nVertex_CHTMarker_HALO = SU2Driver.GetNumberHaloVertices(CHTMarkerID) - nVertex_CHTMarker_PHYS = nVertex_CHTMarker - nVertex_CHTMarker_HALO - - # Obtain indices of all vertices that are being worked on on this rank - for iVertex in range(nVertex_CHTMarker): - if not SU2Driver.IsAHaloNode(CHTMarkerID, iVertex): - iVertices_CHTMarker_PHYS.append(int(iVertex)) - - # Get coords of vertices - coords = numpy.zeros((nVertex_CHTMarker_PHYS, options.nDim)) - for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): - coord_passive = SU2Driver.GetInitialMeshCoord(CHTMarkerID, iVertex) - for iDim in range(options.nDim): - coords[i, iDim] = coord_passive[iDim] - - # Set mesh vertices in preCICE: - try: - vertex_ids = participant.set_mesh_vertices(mesh_name, coords) - except: - print("Could not set mesh vertices for preCICE. Was a (known) mesh specified in the options?") - return - - # Get read and write data IDs - precice_read = "Temperature" - precice_write = "Heat-Flux" - GetFxn = SU2Driver.GetVertexNormalHeatFlux - SetFxn = SU2Driver.SetVertexTemperature - GetInitialFxn = SU2Driver.GetVertexTemperature - # Reverse coupling data read/write if -r flag included - if options.precice_reverse: - precice_read = "Heat-Flux" - precice_write = "Temperature" - GetFxn = SU2Driver.GetVertexTemperature - SetFxn = SU2Driver.SetVertexNormalHeatFlux - GetInitialFxn = SU2Driver.GetVertexNormalHeatFlux - - # Instantiate arrays to hold temperature + heat flux info - read_data = numpy.zeros(nVertex_CHTMarker_PHYS) - write_data = numpy.zeros(nVertex_CHTMarker_PHYS) - - # Retrieve some control parameters from the driver - deltaT = SU2Driver.GetUnsteady_TimeStep() - TimeIter = SU2Driver.GetTime_Iter() - nTimeIter = SU2Driver.GetnTimeIter() - time = TimeIter*deltaT - - # Set up initial data for preCICE - if (participant.requires_initial_data()): - - for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): - write_data[i] = GetInitialFxn(CHTMarkerID, iVertex) - - participant.write_data(mesh_name, precice_write, vertex_ids, write_data) - - # Initialize preCICE - participant.initialize() - - # Sleep briefly to allow for data initialization to be processed - # This should only be needed on some systems and use cases - # - sleep(3) - - # Time loop is defined in Python so that we have access to SU2 functionalities at each time step - if rank == 0: - print("\n------------------------------ Begin Solver -----------------------------\n") - sys.stdout.flush() - if options.with_MPI == True: - comm.Barrier() - - precice_saved_time = 0 - precice_saved_iter = 0 - while (participant.is_coupling_ongoing()): - # Implicit coupling - if (participant.requires_writing_checkpoint()): - # Save the state - SU2Driver.SaveOldState() - precice_saved_time = time - precice_saved_iter = TimeIter - - # Get the maximum time step size allowed by preCICE - precice_deltaT = participant.get_max_time_step_size() - - # Retrieve data from preCICE - read_data = participant.read_data(mesh_name, precice_read, vertex_ids, deltaT) - - # Set the updated values - for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): - SetFxn(CHTMarkerID, iVertex, read_data[i]) - - # Tell the SU2 drive to update the boundary conditions - SU2Driver.BoundaryConditionsUpdate() - - if options.with_MPI == True: - comm.Barrier() - - # Update timestep based on preCICE - deltaT = SU2Driver.GetUnsteady_TimeStep() - deltaT = min(precice_deltaT, deltaT) - SU2Driver.SetUnsteady_TimeStep(deltaT) - - # Time iteration preprocessing - SU2Driver.Preprocess(TimeIter) - - # Run one time iteration (e.g. dual-time) - SU2Driver.Run() - - # Postprocess the solver and exit cleanly - SU2Driver.Postprocess() - - # Update the solver for the next time iteration - SU2Driver.Update() - - # Monitor the solver - stopCalc = SU2Driver.Monitor(TimeIter) - - # Update control parameters - TimeIter += 1 - time += deltaT - - # Loop over the vertices - for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): - # Get heat fluxes at each vertex - write_data[i] = GetFxn(CHTMarkerID, iVertex) - - # Write data to preCICE - participant.write_data(mesh_name, precice_write, vertex_ids, write_data) - - # Advance preCICE - participant.advance(deltaT) - - # Implicit coupling: - if (participant.requires_reading_checkpoint()): - # Reload old state - SU2Driver.ReloadOldState() - time = precice_saved_time - TimeIter = precice_saved_iter - - if (participant.is_time_window_complete()): - SU2Driver.Output(TimeIter) - if (stopCalc == True): - break - - if options.with_MPI == True: - comm.Barrier() - - # Postprocess the solver and exit cleanly - SU2Driver.Postprocessing() - - participant.finalize() - - if SU2Driver != None: - del SU2Driver + # Command line options + parser=OptionParser() + parser.add_option("-f", "--file", dest="filename", help="Read config from FILE", metavar="FILE") + parser.add_option("--parallel", action="store_true", + help="Specify if we need to initialize MPI", dest="with_MPI", default=False) + + # preCICE options with default settings + parser.add_option("-p", "--precice-participant", dest="precice_name", help="Specify preCICE participant name", default="Fluid" ) + parser.add_option("-c", "--precice-config", dest="precice_config", help="Specify preCICE config file", default="../precice-config.xml") + parser.add_option("-m", "--precice-mesh", dest="precice_mesh", help="Specify the preCICE mesh name", default="Fluid-Mesh") + parser.add_option("-r", "--precice-reverse", action="store_true", dest="precice_reverse", help="Include flag to have SU2 write temperature, read heat flux", default=False) + + # Dimension + parser.add_option("-d", "--dimension", dest="nDim", help="Dimension of fluid domain (2D/3D)", type="int", default=2) + + (options, args) = parser.parse_args() + options.nZone = int(1) # Specify number of zones here (1) + + # Import mpi4py for parallel run + if options.with_MPI == True: + from mpi4py import MPI + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + else: + comm = 0 + rank = 0 + + # Initialize the corresponding driver of SU2, this includes solver preprocessing + try: + SU2Driver = pysu2.CSinglezoneDriver(options.filename, options.nZone, comm); + except TypeError as exception: + print('A TypeError occured in pysu2.CDriver : ',exception) + if options.with_MPI == True: + print('ERROR : You are trying to initialize MPI with a serial build of the wrapper. Please, remove the --parallel option that is incompatible with a serial build.') + else: + print('ERROR : You are trying to launch a computation without initializing MPI but the wrapper has been built in parallel. Please add the --parallel option in order to initialize MPI for the wrapper.') + return + + + # Configure preCICE: + size = comm.Get_size() + try: + participant = precice.Participant(options.precice_name, options.precice_config, rank, size) + except: + print("There was an error configuring preCICE") + return + + mesh_name = options.precice_mesh + + # Check preCICE + SU2 dimensions + if options.nDim != participant.get_mesh_dimensions(mesh_name): + print("SU2 and preCICE dimensions are not the same! Exiting") + return + + CHTMarkerID = None + CHTMarker = 'interface' # Name of CHT marker to couple + + # Get all the tags with the CHT option + CHTMarkerList = SU2Driver.GetAllCHTMarkersTag() + + # Get all the markers defined on this rank and their associated indices. + allMarkerIDs = SU2Driver.GetAllBoundaryMarkers() # Returns all markers defined on this rank + + #Check if the specified marker has a CHT option and if it exists on this rank. + if CHTMarker in CHTMarkerList and CHTMarker in allMarkerIDs.keys(): + CHTMarkerID = allMarkerIDs[CHTMarker] # So: if CHTMarkerID != None, then it exists on this rank + + # Number of vertices on the specified marker (per rank) + nVertex_CHTMarker = 0 #total number of vertices (physical + halo) on this rank + nVertex_CHTMarker_HALO = 0 #number of halo vertices + nVertex_CHTMarker_PHYS = 0 #number of physical vertices + iVertices_CHTMarker_PHYS = [] #indices of vertices this rank is working on + # Note: Datatypes must be primitive as input to SU2 wrapper code, not numpy.int8, numpy.int64, etc.. So a list is used + + # If the CHT marker is defined on this rank: + if CHTMarkerID != None: + nVertex_CHTMarker = SU2Driver.GetNumberVertices(CHTMarkerID) #Total number of vertices on the marker + nVertex_CHTMarker_HALO = SU2Driver.GetNumberHaloVertices(CHTMarkerID) + nVertex_CHTMarker_PHYS = nVertex_CHTMarker - nVertex_CHTMarker_HALO + + # Obtain indices of all vertices that are being worked on on this rank + for iVertex in range(nVertex_CHTMarker): + if not SU2Driver.IsAHaloNode(CHTMarkerID, iVertex): + iVertices_CHTMarker_PHYS.append(int(iVertex)) + + # Get coords of vertices + coords = numpy.zeros((nVertex_CHTMarker_PHYS, options.nDim)) + for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): + coord_passive = SU2Driver.GetInitialMeshCoord(CHTMarkerID, iVertex) + for iDim in range(options.nDim): + coords[i, iDim] = coord_passive[iDim] + + # Set mesh vertices in preCICE: + try: + vertex_ids = participant.set_mesh_vertices(mesh_name, coords) + except: + print("Could not set mesh vertices for preCICE. Was a (known) mesh specified in the options?") + return + + # Get read and write data IDs + precice_read = "Temperature" + precice_write = "Heat-Flux" + GetFxn = SU2Driver.GetVertexNormalHeatFlux + SetFxn = SU2Driver.SetVertexTemperature + GetInitialFxn = SU2Driver.GetVertexTemperature + # Reverse coupling data read/write if -r flag included + if options.precice_reverse: + precice_read = "Heat-Flux" + precice_write = "Temperature" + GetFxn = SU2Driver.GetVertexTemperature + SetFxn = SU2Driver.SetVertexNormalHeatFlux + GetInitialFxn = SU2Driver.GetVertexNormalHeatFlux + + # Instantiate arrays to hold temperature + heat flux info + read_data = numpy.zeros(nVertex_CHTMarker_PHYS) + write_data = numpy.zeros(nVertex_CHTMarker_PHYS) + + # Retrieve some control parameters from the driver + deltaT = SU2Driver.GetUnsteady_TimeStep() + TimeIter = SU2Driver.GetTime_Iter() + nTimeIter = SU2Driver.GetnTimeIter() + time = TimeIter*deltaT + + # Set up initial data for preCICE + if (participant.requires_initial_data()): + + for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): + write_data[i] = GetInitialFxn(CHTMarkerID, iVertex) + + participant.write_data(mesh_name, precice_write, vertex_ids, write_data) + + # Initialize preCICE + participant.initialize() + + # Sleep briefly to allow for data initialization to be processed + # This should only be needed on some systems and use cases + # + sleep(3) + + # Time loop is defined in Python so that we have access to SU2 functionalities at each time step + if rank == 0: + print("\n------------------------------ Begin Solver -----------------------------\n") + sys.stdout.flush() + if options.with_MPI == True: + comm.Barrier() + + precice_saved_time = 0 + precice_saved_iter = 0 + while (participant.is_coupling_ongoing()): + # Implicit coupling + if (participant.requires_writing_checkpoint()): + # Save the state + SU2Driver.SaveOldState() + precice_saved_time = time + precice_saved_iter = TimeIter + + # Get the maximum time step size allowed by preCICE + precice_deltaT = participant.get_max_time_step_size() + + # Retrieve data from preCICE + read_data = participant.read_data(mesh_name, precice_read, vertex_ids, deltaT) + + # Set the updated values + for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): + SetFxn(CHTMarkerID, iVertex, read_data[i]) + + # Tell the SU2 drive to update the boundary conditions + SU2Driver.BoundaryConditionsUpdate() + + if options.with_MPI == True: + comm.Barrier() + + # Update timestep based on preCICE + deltaT = SU2Driver.GetUnsteady_TimeStep() + deltaT = min(precice_deltaT, deltaT) + SU2Driver.SetUnsteady_TimeStep(deltaT) + + # Time iteration preprocessing + SU2Driver.Preprocess(TimeIter) + + # Run one time iteration (e.g. dual-time) + SU2Driver.Run() + + # Postprocess the solver and exit cleanly + SU2Driver.Postprocess() + + # Update the solver for the next time iteration + SU2Driver.Update() + + # Monitor the solver + stopCalc = SU2Driver.Monitor(TimeIter) + + # Update control parameters + TimeIter += 1 + time += deltaT + + # Loop over the vertices + for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): + # Get heat fluxes at each vertex + write_data[i] = GetFxn(CHTMarkerID, iVertex) + + # Write data to preCICE + participant.write_data(mesh_name, precice_write, vertex_ids, write_data) + + # Advance preCICE + participant.advance(deltaT) + + # Implicit coupling: + if (participant.requires_reading_checkpoint()): + # Reload old state + SU2Driver.ReloadOldState() + time = precice_saved_time + TimeIter = precice_saved_iter + + if (participant.is_time_window_complete()): + SU2Driver.Output(TimeIter) + if (stopCalc == True): + break + + if options.with_MPI == True: + comm.Barrier() + + # Postprocess the solver and exit cleanly + SU2Driver.Postprocessing() + + participant.finalize() + + if SU2Driver != None: + del SU2Driver # ------------------------------------------------------------------- # Run Main Program @@ -262,4 +262,4 @@ def main(): # this is only accessed if running from command prompt if __name__ == '__main__': - main() + main() From 2fed8f2774cce3a4cc31b1c8a88305a18efceb0e Mon Sep 17 00:00:00 2001 From: Joseph Signorelli Date: Thu, 5 Sep 2024 17:21:34 -0500 Subject: [PATCH 2/7] Fix control parameters update --- run/SU2_preCICE_CHT.py | 7 +++---- run/SU2_preCICE_FSI.py | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/run/SU2_preCICE_CHT.py b/run/SU2_preCICE_CHT.py index 0c4518f..59918c5 100755 --- a/run/SU2_preCICE_CHT.py +++ b/run/SU2_preCICE_CHT.py @@ -217,10 +217,6 @@ def main(): # Monitor the solver stopCalc = SU2Driver.Monitor(TimeIter) - - # Update control parameters - TimeIter += 1 - time += deltaT # Loop over the vertices for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): @@ -244,6 +240,9 @@ def main(): SU2Driver.Output(TimeIter) if (stopCalc == True): break + # Update control parameters + TimeIter += 1 + time += deltaT if options.with_MPI == True: comm.Barrier() diff --git a/run/SU2_preCICE_FSI.py b/run/SU2_preCICE_FSI.py index 2cceed7..e8c8dbb 100755 --- a/run/SU2_preCICE_FSI.py +++ b/run/SU2_preCICE_FSI.py @@ -211,10 +211,6 @@ def main(): # Monitor the solver stopCalc = SU2Driver.Monitor(TimeIter) - # Update control parameters - TimeIter += 1 - time += deltaT - # Loop over the vertices for i, iVertex in enumerate(iVertices_MovingMarker_PHYS): # Get forces at each vertex @@ -237,6 +233,9 @@ def main(): SU2Driver.Output(TimeIter) if (stopCalc == True): break + # Update control parameters + TimeIter += 1 + time += deltaT if options.with_MPI == True: comm.Barrier() From 096bd8abb921f8ed394a1525ebee9ffbbae1eff4 Mon Sep 17 00:00:00 2001 From: Joseph Signorelli Date: Tue, 10 Sep 2024 11:59:43 -0500 Subject: [PATCH 3/7] More spacing fixes --- run/SU2_preCICE_CHT.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/run/SU2_preCICE_CHT.py b/run/SU2_preCICE_CHT.py index 59918c5..f83819c 100755 --- a/run/SU2_preCICE_CHT.py +++ b/run/SU2_preCICE_CHT.py @@ -37,10 +37,10 @@ def main(): parser.add_option("-c", "--precice-config", dest="precice_config", help="Specify preCICE config file", default="../precice-config.xml") parser.add_option("-m", "--precice-mesh", dest="precice_mesh", help="Specify the preCICE mesh name", default="Fluid-Mesh") parser.add_option("-r", "--precice-reverse", action="store_true", dest="precice_reverse", help="Include flag to have SU2 write temperature, read heat flux", default=False) - + # Dimension parser.add_option("-d", "--dimension", dest="nDim", help="Dimension of fluid domain (2D/3D)", type="int", default=2) - + (options, args) = parser.parse_args() options.nZone = int(1) # Specify number of zones here (1) @@ -72,7 +72,7 @@ def main(): except: print("There was an error configuring preCICE") return - + mesh_name = options.precice_mesh # Check preCICE + SU2 dimensions @@ -92,7 +92,7 @@ def main(): #Check if the specified marker has a CHT option and if it exists on this rank. if CHTMarker in CHTMarkerList and CHTMarker in allMarkerIDs.keys(): CHTMarkerID = allMarkerIDs[CHTMarker] # So: if CHTMarkerID != None, then it exists on this rank - + # Number of vertices on the specified marker (per rank) nVertex_CHTMarker = 0 #total number of vertices (physical + halo) on this rank nVertex_CHTMarker_HALO = 0 #number of halo vertices @@ -186,7 +186,7 @@ def main(): precice_deltaT = participant.get_max_time_step_size() # Retrieve data from preCICE - read_data = participant.read_data(mesh_name, precice_read, vertex_ids, deltaT) + read_data = participant.read_data(mesh_name, precice_read, vertex_ids, deltaT) # Set the updated values for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): @@ -214,15 +214,15 @@ def main(): # Update the solver for the next time iteration SU2Driver.Update() - + # Monitor the solver stopCalc = SU2Driver.Monitor(TimeIter) - + # Loop over the vertices for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): # Get heat fluxes at each vertex write_data[i] = GetFxn(CHTMarkerID, iVertex) - + # Write data to preCICE participant.write_data(mesh_name, precice_write, vertex_ids, write_data) @@ -240,18 +240,18 @@ def main(): SU2Driver.Output(TimeIter) if (stopCalc == True): break - # Update control parameters - TimeIter += 1 - time += deltaT - + + TimeIter += 1 + time += deltaT + if options.with_MPI == True: comm.Barrier() - + # Postprocess the solver and exit cleanly SU2Driver.Postprocessing() - + participant.finalize() - + if SU2Driver != None: del SU2Driver From ca20d590c1946b07e7e9b349d6c2dfde471836f5 Mon Sep 17 00:00:00 2001 From: Joseph Signorelli Date: Tue, 10 Sep 2024 11:59:50 -0500 Subject: [PATCH 4/7] Reverse sign of retrieved HF from SU2 (get HF out of fluid into wall) --- run/SU2_preCICE_CHT.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run/SU2_preCICE_CHT.py b/run/SU2_preCICE_CHT.py index f83819c..f6b351f 100755 --- a/run/SU2_preCICE_CHT.py +++ b/run/SU2_preCICE_CHT.py @@ -128,7 +128,7 @@ def main(): # Get read and write data IDs precice_read = "Temperature" precice_write = "Heat-Flux" - GetFxn = SU2Driver.GetVertexNormalHeatFlux + GetFxn = lambda *args: -1*SU2Driver.GetVertexNormalHeatFlux(*args) SetFxn = SU2Driver.SetVertexTemperature GetInitialFxn = SU2Driver.GetVertexTemperature # Reverse coupling data read/write if -r flag included @@ -137,7 +137,7 @@ def main(): precice_write = "Temperature" GetFxn = SU2Driver.GetVertexTemperature SetFxn = SU2Driver.SetVertexNormalHeatFlux - GetInitialFxn = SU2Driver.GetVertexNormalHeatFlux + GetInitialFxn = lambda *args: -1*SU2Driver.GetVertexNormalHeatFlux(*args) # Instantiate arrays to hold temperature + heat flux info read_data = numpy.zeros(nVertex_CHTMarker_PHYS) From b9a9cb0e66a717bee1b92fdcd918628947fe7d7d Mon Sep 17 00:00:00 2001 From: Joseph Signorelli Date: Tue, 10 Sep 2024 13:11:09 -0500 Subject: [PATCH 5/7] More whitespace fixes --- run/SU2_preCICE_CHT.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/run/SU2_preCICE_CHT.py b/run/SU2_preCICE_CHT.py index f6b351f..851bd0c 100755 --- a/run/SU2_preCICE_CHT.py +++ b/run/SU2_preCICE_CHT.py @@ -148,6 +148,7 @@ def main(): TimeIter = SU2Driver.GetTime_Iter() nTimeIter = SU2Driver.GetnTimeIter() time = TimeIter*deltaT + # Set up initial data for preCICE if (participant.requires_initial_data()): @@ -192,7 +193,7 @@ def main(): for i, iVertex in enumerate(iVertices_CHTMarker_PHYS): SetFxn(CHTMarkerID, iVertex, read_data[i]) - # Tell the SU2 drive to update the boundary conditions + # Tell the SU2 driver to update the boundary conditions SU2Driver.BoundaryConditionsUpdate() if options.with_MPI == True: @@ -202,7 +203,7 @@ def main(): deltaT = SU2Driver.GetUnsteady_TimeStep() deltaT = min(precice_deltaT, deltaT) SU2Driver.SetUnsteady_TimeStep(deltaT) - + # Time iteration preprocessing SU2Driver.Preprocess(TimeIter) From 9ac94dba39c3a277ab8ef184af2bc53a46df03a3 Mon Sep 17 00:00:00 2001 From: Joseph Signorelli Date: Tue, 10 Sep 2024 13:12:55 -0500 Subject: [PATCH 6/7] Clean whitespaces --- run/SU2_preCICE_FSI.py | 449 +++++++++++++++++++++-------------------- 1 file changed, 228 insertions(+), 221 deletions(-) diff --git a/run/SU2_preCICE_FSI.py b/run/SU2_preCICE_FSI.py index e8c8dbb..55c7474 100755 --- a/run/SU2_preCICE_FSI.py +++ b/run/SU2_preCICE_FSI.py @@ -26,227 +26,234 @@ def main(): - # Command line options - parser=OptionParser() - parser.add_option("-f", "--file", dest="filename", help="Read config from FILE", metavar="FILE") - parser.add_option("--parallel", action="store_true", - help="Specify if we need to initialize MPI", dest="with_MPI", default=False) - - # preCICE options with default settings - parser.add_option("-p", "--precice-participant", dest="precice_name", help="Specify preCICE participant name", default="Fluid" ) - parser.add_option("-c", "--precice-config", dest="precice_config", help="Specify preCICE config file", default="../precice-config.xml") - parser.add_option("-m", "--precice-mesh", dest="precice_mesh", help="Specify the preCICE mesh name", default="Fluid-Mesh") - - # Dimension - parser.add_option("-d", "--dimension", dest="nDim", help="Dimension of fluid domain (2D/3D)", type="int", default=2) + # Command line options + parser=OptionParser() + parser.add_option("-f", "--file", dest="filename", help="Read config from FILE", metavar="FILE") + parser.add_option("--parallel", action="store_true", + help="Specify if we need to initialize MPI", dest="with_MPI", default=False) + + # preCICE options with default settings + parser.add_option("-p", "--precice-participant", dest="precice_name", help="Specify preCICE participant name", default="Fluid" ) + parser.add_option("-c", "--precice-config", dest="precice_config", help="Specify preCICE config file", default="../precice-config.xml") + parser.add_option("-m", "--precice-mesh", dest="precice_mesh", help="Specify the preCICE mesh name", default="Fluid-Mesh") + + # Dimension + parser.add_option("-d", "--dimension", dest="nDim", help="Dimension of fluid domain (2D/3D)", type="int", default=2) - (options, args) = parser.parse_args() - options.nZone = int(1) - - # Import mpi4py for parallel run - if options.with_MPI == True: - from mpi4py import MPI - comm = MPI.COMM_WORLD - rank = comm.Get_rank() - else: - comm = 0 - rank = 0 - - # Initialize the corresponding driver of SU2, this includes solver preprocessing - try: - SU2Driver = pysu2.CSinglezoneDriver(options.filename, options.nZone, comm); - except TypeError as exception: - print('A TypeError occured in pysu2.CDriver : ',exception) - if options.with_MPI == True: - print('ERROR : You are trying to initialize MPI with a serial build of the wrapper. Please, remove the --parallel option that is incompatible with a serial build.') - else: - print('ERROR : You are trying to launch a computation without initializing MPI but the wrapper has been built in parallel. Please add the --parallel option in order to initialize MPI for the wrapper.') - return - - # Configure preCICE: - size = comm.Get_size() - try: - participant = precice.Participant(options.precice_name, options.precice_config, rank, size)#, comm) - except: - print("There was an error configuring preCICE") - return - - mesh_name = options.precice_mesh - - # Check preCICE + SU2 dimensions - if options.nDim != participant.get_mesh_dimensions(mesh_name): - print("SU2 and preCICE dimensions are not the same! Exiting") - return - - MovingMarkerID = None - MovingMarker = 'interface' #specified by the user - - # Get all the tags with the moving option - MovingMarkerList = SU2Driver.GetAllDeformMeshMarkersTag() - - # Get all the markers defined on this rank and their associated indices. - allMarkerIDs = SU2Driver.GetAllBoundaryMarkers() - - # Check if the specified marker has a moving option and if it exists on this rank. - if MovingMarker in MovingMarkerList and MovingMarker in allMarkerIDs.keys(): - MovingMarkerID = allMarkerIDs[MovingMarker] - - # Number of vertices on the specified marker (per rank) - nVertex_MovingMarker = 0 #total number of vertices (physical + halo) - nVertex_MovingMarker_HALO = 0 #number of halo vertices - nVertex_MovingMarker_PHYS = 0 #number of physical vertices - iVertices_MovingMarker_PHYS = [] # indices of vertices this rank is working on - # Datatypes must be primitive as input to SU2 wrapper code, not numpy.int8, numpy.int64, etc.. So a list is used - - if MovingMarkerID != None: - nVertex_MovingMarker = SU2Driver.GetNumberVertices(MovingMarkerID) - nVertex_MovingMarker_HALO = SU2Driver.GetNumberHaloVertices(MovingMarkerID) - nVertex_MovingMarker_PHYS = nVertex_MovingMarker - nVertex_MovingMarker_HALO - - # Obtain indices of all vertices that are being worked on on this rank - for iVertex in range(nVertex_MovingMarker): - if not SU2Driver.IsAHaloNode(MovingMarkerID, iVertex): - iVertices_MovingMarker_PHYS.append(int(iVertex)) - - # Get coords of vertices - coords = numpy.zeros((nVertex_MovingMarker_PHYS, options.nDim)) - for i, iVertex in enumerate(iVertices_MovingMarker_PHYS): - coord_passive = SU2Driver.GetInitialMeshCoord(MovingMarkerID, iVertex) - for iDim in range(options.nDim): - coords[i, iDim] = coord_passive[iDim] - - # Set mesh vertices in preCICE: - vertex_ids = participant.set_mesh_vertices(mesh_name, coords) - - # Set mesh vertices in preCICE: - try: - vertex_ids = participant.set_mesh_vertices(mesh_name, coords) - except: - print("Could not set mesh vertices for preCICE. Was a (known) mesh specified in the options?") - return - - # Get read and write data IDs - # By default: - precice_read = "Displacement" - precice_write = "Force" - - # Instantiate arrays to hold displacements + forces info - displacements = numpy.zeros((nVertex_MovingMarker_PHYS,options.nDim)) - forces = numpy.zeros((nVertex_MovingMarker_PHYS,options.nDim)) - - # Retrieve some control parameters from the driver - deltaT = SU2Driver.GetUnsteady_TimeStep() - TimeIter = SU2Driver.GetTime_Iter() - nTimeIter = SU2Driver.GetnTimeIter() - time = TimeIter*deltaT - - # Set up initial data for preCICE - if (participant.requires_initial_data()): - - for i, iVertex in enumerate(iVertices_MovingMarker_PHYS): - forces[i] = SU2Driver.GetFlowLoad(MovingMarkerID, iVertex)[:-1] - - participant.write_block_vector_data(mesh_name, precice_write, vertex_ids, forces) - - # Initialize preCICE - participant.initialize() - - # Sleep briefly to allow for data initialization to be processed - # This should only be needed on some systems and use cases - # - sleep(3) - - # Time loop is defined in Python so that we have acces to SU2 functionalities at each time step - if rank == 0: - print("\n------------------------------ Begin Solver -----------------------------\n") - sys.stdout.flush() - if options.with_MPI == True: - comm.Barrier() - - precice_saved_time = 0 - precice_saved_iter = 0 - while (participant.is_coupling_ongoing()):#(TimeIter < nTimeIter): - - # Implicit coupling - if (participant.requires_writing_checkpoint()): - # Save the state - SU2Driver.SaveOldState() - precice_saved_time = time - precice_saved_iter = TimeIter - - # Get the maximum time step size allowed by preCICE - precice_deltaT = participant.get_max_time_step_size() - - # Retreive data from preCICE - displacements = participant.read_data(mesh_name, precice_read, vertex_ids, deltaT) - - # Set the updated displacements - for i, iVertex in enumerate(iVertices_MovingMarker_PHYS): - DisplX = displacements[i][0] - DisplY = displacements[i][1] - DisplZ = 0 if options.nDim == 2 else displacements[i][2] - - SU2Driver.SetMeshDisplacement(MovingMarkerID, iVertex, DisplX, DisplY, DisplZ) - - if options.with_MPI == True: - comm.Barrier() - - # Update timestep based on preCICE - deltaT = SU2Driver.GetUnsteady_TimeStep() - deltaT = min(precice_deltaT, deltaT) - SU2Driver.SetUnsteady_TimeStep(deltaT) - - # Time iteration preprocessing (mesh is deformed here) - SU2Driver.Preprocess(TimeIter) - - # Run one time iteration (e.g. dual-time) - SU2Driver.Run() - - # Postprocess the solver - SU2Driver.Postprocess() - - # Update the solver for the next time iteration - SU2Driver.Update() - - # Monitor the solver - stopCalc = SU2Driver.Monitor(TimeIter) - - # Loop over the vertices - for i, iVertex in enumerate(iVertices_MovingMarker_PHYS): - # Get forces at each vertex - forces[i] = SU2Driver.GetFlowLoad(MovingMarkerID, iVertex)[:-1] - - # Write data to preCICE - participant.write_data(mesh_name, precice_write, vertex_ids, forces) - - # Advance preCICE - participant.advance(deltaT) - - # Implicit coupling: - if (participant.requires_reading_checkpoint()): - # Reload old state - SU2Driver.ReloadOldState() - time = precice_saved_time - TimeIter = precice_saved_iter - - if (participant.is_time_window_complete()): - SU2Driver.Output(TimeIter) - if (stopCalc == True): - break - # Update control parameters - TimeIter += 1 - time += deltaT - - if options.with_MPI == True: - comm.Barrier() - - # Postprocess the solver and exit cleanly - SU2Driver.Postprocessing() - - participant.finalize() - - if SU2Driver != None: - del SU2Driver + (options, args) = parser.parse_args() + options.nZone = int(1) + + # Import mpi4py for parallel run + if options.with_MPI == True: + from mpi4py import MPI + comm = MPI.COMM_WORLD + rank = comm.Get_rank() + else: + comm = 0 + rank = 0 + + # Initialize the corresponding driver of SU2, this includes solver preprocessing + try: + SU2Driver = pysu2.CSinglezoneDriver(options.filename, options.nZone, comm); + except TypeError as exception: + print('A TypeError occured in pysu2.CDriver : ',exception) + if options.with_MPI == True: + print('ERROR : You are trying to initialize MPI with a serial build of the wrapper. Please, remove the --parallel option that is incompatible with a serial build.') + else: + print('ERROR : You are trying to launch a computation without initializing MPI but the wrapper has been built in parallel. Please add the --parallel option in order to initialize MPI for the wrapper.') + return + + # Configure preCICE: + size = comm.Get_size() + try: + participant = precice.Participant(options.precice_name, options.precice_config, rank, size)#, comm) + except: + print("There was an error configuring preCICE") + return + + mesh_name = options.precice_mesh + + # Check preCICE + SU2 dimensions + if options.nDim != participant.get_mesh_dimensions(mesh_name): + print("SU2 and preCICE dimensions are not the same! Exiting") + return + + MovingMarkerID = None + MovingMarker = 'interface' #specified by the user + + # Get all the tags with the moving option + MovingMarkerList = SU2Driver.GetAllDeformMeshMarkersTag() + + # Get all the markers defined on this rank and their associated indices. + allMarkerIDs = SU2Driver.GetAllBoundaryMarkers() + + # Check if the specified marker has a moving option and if it exists on this rank. + if MovingMarker in MovingMarkerList and MovingMarker in allMarkerIDs.keys(): + MovingMarkerID = allMarkerIDs[MovingMarker] + + # Number of vertices on the specified marker (per rank) + nVertex_MovingMarker = 0 #total number of vertices (physical + halo) + nVertex_MovingMarker_HALO = 0 #number of halo vertices + nVertex_MovingMarker_PHYS = 0 #number of physical vertices + iVertices_MovingMarker_PHYS = [] # indices of vertices this rank is working on + # Datatypes must be primitive as input to SU2 wrapper code, not numpy.int8, numpy.int64, etc.. So a list is used + + if MovingMarkerID != None: + nVertex_MovingMarker = SU2Driver.GetNumberVertices(MovingMarkerID) + nVertex_MovingMarker_HALO = SU2Driver.GetNumberHaloVertices(MovingMarkerID) + nVertex_MovingMarker_PHYS = nVertex_MovingMarker - nVertex_MovingMarker_HALO + + # Obtain indices of all vertices that are being worked on on this rank + for iVertex in range(nVertex_MovingMarker): + if not SU2Driver.IsAHaloNode(MovingMarkerID, iVertex): + iVertices_MovingMarker_PHYS.append(int(iVertex)) + + # Get coords of vertices + coords = numpy.zeros((nVertex_MovingMarker_PHYS, options.nDim)) + for i, iVertex in enumerate(iVertices_MovingMarker_PHYS): + coord_passive = SU2Driver.GetInitialMeshCoord(MovingMarkerID, iVertex) + for iDim in range(options.nDim): + coords[i, iDim] = coord_passive[iDim] + + # Set mesh vertices in preCICE: + vertex_ids = participant.set_mesh_vertices(mesh_name, coords) + + # Set mesh vertices in preCICE: + try: + vertex_ids = participant.set_mesh_vertices(mesh_name, coords) + except: + print("Could not set mesh vertices for preCICE. Was a (known) mesh specified in the options?") + return + + # Get read and write data IDs + # By default: + precice_read = "Displacement" + precice_write = "Force" + + # Instantiate arrays to hold displacements + forces info + displacements = numpy.zeros((nVertex_MovingMarker_PHYS,options.nDim)) + forces = numpy.zeros((nVertex_MovingMarker_PHYS,options.nDim)) + + # Retrieve some control parameters from the driver + deltaT = SU2Driver.GetUnsteady_TimeStep() + TimeIter = SU2Driver.GetTime_Iter() + nTimeIter = SU2Driver.GetnTimeIter() + time = TimeIter*deltaT + + # Set up initial data for preCICE + if (participant.requires_initial_data()): + + for i, iVertex in enumerate(iVertices_MovingMarker_PHYS): + forces[i] = SU2Driver.GetFlowLoad(MovingMarkerID, iVertex)[:-1] + + participant.write_block_vector_data(mesh_name, precice_write, vertex_ids, forces) + + # Initialize preCICE + participant.initialize() + + # Sleep briefly to allow for data initialization to be processed + # This should only be needed on some systems and use cases + # + sleep(3) + + # Time loop is defined in Python so that we have acces to SU2 functionalities at each time step + if rank == 0: + print("\n------------------------------ Begin Solver -----------------------------\n") + sys.stdout.flush() + if options.with_MPI == True: + comm.Barrier() + + precice_saved_time = 0 + precice_saved_iter = 0 + + # Patch for su2code/SU2#2353 + if (TimeIter == 0): + SU2Driver.Output(TimeIter) + TimeIter += 1 + time += deltaT + + while (participant.is_coupling_ongoing()):#(TimeIter < nTimeIter): + + # Implicit coupling + if (participant.requires_writing_checkpoint()): + # Save the state + SU2Driver.SaveOldState() + precice_saved_time = time + precice_saved_iter = TimeIter + + # Get the maximum time step size allowed by preCICE + precice_deltaT = participant.get_max_time_step_size() + + # Retreive data from preCICE + displacements = participant.read_data(mesh_name, precice_read, vertex_ids, deltaT) + + # Set the updated displacements + for i, iVertex in enumerate(iVertices_MovingMarker_PHYS): + DisplX = displacements[i][0] + DisplY = displacements[i][1] + DisplZ = 0 if options.nDim == 2 else displacements[i][2] + + SU2Driver.SetMeshDisplacement(MovingMarkerID, iVertex, DisplX, DisplY, DisplZ) + + if options.with_MPI == True: + comm.Barrier() + + # Update timestep based on preCICE + deltaT = SU2Driver.GetUnsteady_TimeStep() + deltaT = min(precice_deltaT, deltaT) + SU2Driver.SetUnsteady_TimeStep(deltaT) + + # Time iteration preprocessing (mesh is deformed here) + SU2Driver.Preprocess(TimeIter) + + # Run one time iteration (e.g. dual-time) + SU2Driver.Run() + + # Postprocess the solver + SU2Driver.Postprocess() + + # Update the solver for the next time iteration + SU2Driver.Update() + + # Monitor the solver + stopCalc = SU2Driver.Monitor(TimeIter) + + # Loop over the vertices + for i, iVertex in enumerate(iVertices_MovingMarker_PHYS): + # Get forces at each vertex + forces[i] = SU2Driver.GetFlowLoad(MovingMarkerID, iVertex)[:-1] + + # Write data to preCICE + participant.write_data(mesh_name, precice_write, vertex_ids, forces) + + # Advance preCICE + participant.advance(deltaT) + + # Implicit coupling: + if (participant.requires_reading_checkpoint()): + # Reload old state + SU2Driver.ReloadOldState() + time = precice_saved_time + TimeIter = precice_saved_iter + + if (participant.is_time_window_complete()): + SU2Driver.Output(TimeIter) + if (stopCalc == True): + break + # Update control parameters + TimeIter += 1 + time += deltaT + + if options.with_MPI == True: + comm.Barrier() + + # Postprocess the solver and exit cleanly + SU2Driver.Postprocessing() + + participant.finalize() + + if SU2Driver != None: + del SU2Driver # ------------------------------------------------------------------- # Run Main Program @@ -254,4 +261,4 @@ def main(): # this is only accessed if running from command prompt if __name__ == '__main__': - main() + main() From 377048b7c100748dc267fcf1772c3f2c67207fe5 Mon Sep 17 00:00:00 2001 From: Joseph Signorelli Date: Tue, 10 Sep 2024 13:13:31 -0500 Subject: [PATCH 7/7] Add patch to su2code/SU2#2353 --- run/SU2_preCICE_CHT.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/run/SU2_preCICE_CHT.py b/run/SU2_preCICE_CHT.py index 851bd0c..6f62ea2 100755 --- a/run/SU2_preCICE_CHT.py +++ b/run/SU2_preCICE_CHT.py @@ -175,6 +175,13 @@ def main(): precice_saved_time = 0 precice_saved_iter = 0 + + # Patch for su2code/SU2#2353 + if (TimeIter == 0): + SU2Driver.Output(TimeIter) + TimeIter += 1 + time += deltaT + while (participant.is_coupling_ongoing()): # Implicit coupling if (participant.requires_writing_checkpoint()):