def main(): # Command line options parser=OptionParser() parser.add_option("-f", "--file", dest="filename", help="Read config from FILE", metavar="FILE") parser.add_option("--nDim", dest="nDim", default=2, help="Define the number of DIMENSIONS", metavar="DIMENSIONS") parser.add_option("--nZone", dest="nZone", default=1, help="Define the number of ZONES", metavar="ZONES") parser.add_option("--periodic", dest="periodic", default="False", help="Define whether the problem has periodic boundary conditions", metavar="PERIODIC") parser.add_option("--parallel", action="store_true", help="Specify if we need to initialize MPI", dest="with_MPI", default=False) parser.add_option("--fsi", dest="fsi", default="False", help="Launch the FSI driver", metavar="FSI") parser.add_option("--fem", dest="fem", default="False", help="Launch the FEM driver (General driver)", metavar="FEM") parser.add_option("--harmonic_balance", dest="harmonic_balance", default="False", help="Launch the Harmonic Balance (HB) driver", metavar="HB") parser.add_option("--poisson_equation", dest="poisson_equation", default="False", help="Launch the poisson equation driver (General driver)", metavar="POIS_EQ") parser.add_option("--wave_equation", dest="wave_equation", default="False", help="Launch the wave equation driver (General driver)", metavar="WAVE_EQ") parser.add_option("--heat_equation", dest="heat_equation", default="False", help="Launch the heat equation driver (General driver)", metavar="HEAT_EQ") (options, args) = parser.parse_args() options.nDim = int( options.nDim ) options.nZone = int( options.nZone ) options.periodic = options.periodic.upper() == 'TRUE' options.fsi = options.fsi.upper() == 'TRUE' options.fem = options.fem.upper() == 'TRUE' options.harmonic_balance = options.harmonic_balance.upper() == 'TRUE' options.poisson_equation = options.poisson_equation.upper() == 'TRUE' options.wave_equation = options.wave_equation.upper() == 'TRUE' options.heat_equation = options.heat_equation.upper() == 'TRUE' # 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: if (options.nZone == 1) and ( options.fem or options.poisson_equation or options.wave_equation or options.heat_equation ): SU2Driver = pysu2.CGeneralDriver(options.filename, options.nZone, options.nDim, options.periodic, comm); elif options.harmonic_balance: SU2Driver = pysu2.CHBDriver(options.filename, options.nZone, options.nDim, options.periodic, comm); elif (options.nZone == 2) and (options.fsi): SU2Driver = pysu2.CFSIDriver(options.filename, options.nZone, options.nDim, options.periodic, comm); else: SU2Driver = pysu2.CFluidDriver(options.filename, options.nZone, options.nDim, options.periodic, 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 CHTMarkerID = None CHTMarker = 'plate' # Specified by the user # 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() #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] # Number of vertices on the specified marker (per rank) nVertex_CHTMarker = 0 #total number of vertices (physical + halo) nVertex_CHTMarker_HALO = 0 #number of halo vertices nVertex_CHTMarker_PHYS = 0 #number of physical vertices if CHTMarkerID != None: nVertex_CHTMarker = SU2Driver.GetNumberVertices(CHTMarkerID) nVertex_CHTMarker_HALO = SU2Driver.GetNumberHaloVertices(CHTMarkerID) nVertex_CHTMarker_PHYS = nVertex_CHTMarker - nVertex_CHTMarker_HALO # Retrieve some control parameters from the driver deltaT = SU2Driver.GetUnsteady_TimeStep() TimeIter = SU2Driver.GetExtIter() nTimeIter = SU2Driver.GetnExtIter() time = TimeIter*deltaT # 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() while (TimeIter < nTimeIter): # Time iteration preprocessing SU2Driver.PreprocessExtIter(TimeIter) # Define the homogeneous unsteady wall temperature on the structure (user defined) WallTemp = 293.0 + 57.0*sin(2*pi*time) # Set this temperature to all the vertices on the specified CHT marker for iVertex in range(nVertex_CHTMarker): SU2Driver.SetVertexTemperature(CHTMarkerID, iVertex, WallTemp) # Tell the SU2 drive to update the boundary conditions SU2Driver.BoundaryConditionsUpdate() # Run one time iteration (e.g. dual-time) SU2Driver.Run() # Update the solver for the next time iteration SU2Driver.Update() # Monitor the solver and output solution to file if required stopCalc = SU2Driver.Monitor(TimeIter) SU2Driver.Output(TimeIter) if (stopCalc == True): break # Update control parameters TimeIter += 1 time += deltaT # Postprocess the solver and exit cleanly SU2Driver.Postprocessing() if SU2Driver != None: del SU2Driver
def main(): # --- Get the FSI conig file name form the 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) (options, args)=parser.parse_args() if options.with_MPI == True: from mpi4py import MPI # MPI is initialized from now by python and can be continued in C++ ! comm = MPI.COMM_WORLD myid = comm.Get_rank() numberPart = comm.Get_size() have_MPI = True else: comm = 0 myid = 0 numberPart = 1 have_MPI = False rootProcess = 0 # --- Set the working directory --- # if myid == rootProcess: if os.getcwd() not in sys.path: sys.path.append(os.getcwd()) print("Setting working directory : {}".format(os.getcwd())) else: print ("Working directory is set to {}".format(os.getcwd())) # starts timer start = timer.time() confFile = str(options.filename) FSI_config = FSI.io.FSIConfig(confFile) # FSI configuration file CFD_ConFile = FSI_config['CFD_CONFIG_FILE_NAME'] # CFD configuration file CSD_ConFile = FSI_config['CSD_CONFIG_FILE_NAME'] # CSD configuration file CSD_Solver = FSI_config['CSD_SOLVER'] # CSD solver if have_MPI == True: comm.barrier() # --- Initialize the fluid solver --- # if myid == rootProcess: print('\n***************************** Initializing fluid solver *****************************') try: FluidSolver = pysu2.CFluidDriver(CFD_ConFile, 1, FSI_config['NDIM'], comm) except TypeError as exception: print('A TypeError occured in pysu2.CSingleZoneDriver : ',exception) if have_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 if have_MPI == True: comm.barrier() # --- Initialize the solid solver --- # (!! for now we are using only serial solid solvers) if myid == rootProcess: print('\n***************************** Initializing solid solver *****************************') if CSD_Solver == 'METAFOR': from MetaforSolver import MtfSolver SolidSolver = MtfSolver(CSD_ConFile) elif CSD_Solver == 'NATIVE': import NativeSolid SolidSolver = NativeSolid.NativeSolidSolver(CSD_ConFile, True) elif CSD_Solver == 'GETDP': import GetDPSolver SolidSolver = GetDPSolver.GetDPSolver(CSD_ConFile, True) elif CSD_Solver == 'TESTER': SolidSolver = FSI.PitchPlungeAirfoilStructuralTester.Solver(CSD_ConFile) else: SolidSolver = None if have_MPI == True: comm.barrier() # --- Initialize and set the FSI interface (coupling environement) --- # if myid == rootProcess: print('\n***************************** Initializing FSI interface *****************************') if have_MPI == True: comm.barrier() FSIInterface = FSI.Interface(FSI_config, FluidSolver, SolidSolver, have_MPI) if myid == rootProcess: print('\n***************************** Connect fluid and solid solvers *****************************') if have_MPI == True: comm.barrier() FSIInterface.connect(FSI_config, FluidSolver, SolidSolver) if myid == rootProcess: print('\n***************************** Mapping fluid-solid interfaces *****************************') if have_MPI == True: comm.barrier() FSIInterface.interfaceMapping(FluidSolver, SolidSolver, FSI_config) if have_MPI == True: comm.barrier() # --- Launch a steady or unsteady FSI computation --- # if FSI_config['UNSTEADY_SIMULATION'] == "YES": try: FSIInterface.UnsteadyFSI(FSI_config, FluidSolver, SolidSolver) except NameError as exception: if myid == rootProcess: print('An NameError occured in FSIInterface.UnsteadyFSI : ',exception) except TypeError as exception: if myid == rootProcess: print('A TypeError occured in FSIInterface.UnsteadyFSI : ',exception) except KeyboardInterrupt as exception : if myid == rootProcess: print('A KeyboardInterrupt occured in FSIInterface.UnsteadyFSI : ',exception) else: try: NbExtIter = FSI_config['NB_EXT_ITER'] FSIInterface.SteadyFSI(FSI_config, FluidSolver, SolidSolver) except NameError as exception: if myid == rootProcess: print('An NameError occured in FSIInterface.SteadyFSI : ',exception) except TypeError as exception: if myid == rootProcess: print('A TypeError occured in FSIInterface.SteadyFSI : ',exception) except KeyboardInterrupt as exception : if myid == rootProcess: print('A KeyboardInterrupt occured in FSIInterface.SteadyFSI : ',exception) if have_MPI == True: comm.barrier() # --- Exit cleanly the fluid and solid solvers --- # FluidSolver.Postprocessing() if myid == rootProcess: SolidSolver.exit() if have_MPI == True: comm.barrier() # stops timer stop = timer.time() elapsedTime = stop-start if myid == rootProcess: print("\n Computation successfully performed in {} seconds.".format(elapsedTime)) return
def main(): # Command line options parser = OptionParser() parser.add_option("-f", "--file", dest="filename", help="Read config from FILE", metavar="FILE") parser.add_option("--nDim", dest="nDim", default=2, help="Define the number of DIMENSIONS", metavar="DIMENSIONS") parser.add_option("--nZone", dest="nZone", default=1, help="Define the number of ZONES", metavar="ZONES") parser.add_option("--parallel", action="store_true", help="Specify if we need to initialize MPI", dest="with_MPI", default=False) parser.add_option("--fsi", dest="fsi", default="False", help="Launch the FSI driver", metavar="FSI") parser.add_option("--fem", dest="fem", default="False", help="Launch the FEM driver (General driver)", metavar="FEM") parser.add_option("--harmonic_balance", dest="harmonic_balance", default="False", help="Launch the Harmonic Balance (HB) driver", metavar="HB") parser.add_option( "--poisson_equation", dest="poisson_equation", default="False", help="Launch the poisson equation driver (General driver)", metavar="POIS_EQ") parser.add_option("--wave_equation", dest="wave_equation", default="False", help="Launch the wave equation driver (General driver)", metavar="WAVE_EQ") parser.add_option("--heat_equation", dest="heat_equation", default="False", help="Launch the heat equation driver (General driver)", metavar="HEAT_EQ") (options, args) = parser.parse_args() options.nDim = int(options.nDim) options.nZone = int(options.nZone) options.fsi = options.fsi.upper() == 'TRUE' options.fem = options.fem.upper() == 'TRUE' options.harmonic_balance = options.harmonic_balance.upper() == 'TRUE' options.poisson_equation = options.poisson_equation.upper() == 'TRUE' options.wave_equation = options.wave_equation.upper() == 'TRUE' options.heat_equation = options.heat_equation.upper() == 'TRUE' if options.filename == None: raise Exception("No config file provided. Use -f flag") if options.with_MPI == True: from mpi4py import MPI # use mpi4py for parallel run (also valid for serial) comm = MPI.COMM_WORLD else: comm = 0 # Initialize the corresponding driver of SU2, this includes solver preprocessing try: if (options.nZone == 1) and (options.fem or options.poisson_equation or options.wave_equation or options.heat_equation): SU2Driver = pysu2.CGeneralDriver(options.filename, options.nZone, options.nDim, comm) elif options.harmonic_balance: SU2Driver = pysu2.CHBDriver(options.filename, options.nZone, options.nDim, comm) elif (options.nZone == 2) and (options.fsi): SU2Driver = pysu2.CFSIDriver(options.filename, options.nZone, options.nDim, comm) else: SU2Driver = pysu2.CFluidDriver(options.filename, options.nZone, options.nDim, 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 # Launch the solver for the entire computation SU2Driver.StartSolver() # Postprocess the solver and exit cleanly SU2Driver.Postprocessing() if SU2Driver != None: del SU2Driver
def __init__(self, confFile, nDim, computationType, nodalLoadsType, have_MPI, MPIComm=None): """ Initialize the SU2 solver and all the required interface variables. """ # --- Instantiate the single zone driver of SU2 --- # # @todo [Adrien Crovato ]Change CFluidDriver constructor # as of SU2-6.1.0, a new way of handling periodic boundary conditon has been implemented # Consequently CDriver(config, nZone, nDim, MPIComm) changed to CFluidDriver(config, nZone, nDim, val_periodic, MPIComm) # Since periodic BC are not used yet in CUPyDO, I just adapted the constructor. This will have to be changed... try: self.SU2 = pysu2.CFluidDriver(confFile, 1, nDim, False, MPIComm) except TypeError as exception: print('A TypeError occured in pysu2.CSingleZoneDriver : ', exception) if have_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.' ) allMovingMarkersTags = self.SU2.GetAllMovingMarkersTag( ) # list containing the tags of all moving markers allCHTMarkersTags = self.SU2.GetAllCHTMarkersTag() allMarkersID = self.SU2.GetAllBoundaryMarkers( ) # dic : allMarkersID['marker_tag'] = marker_ID self.fluidInterfaceID = None # identification of the f/s boundary, currently limited to one boundary, by default the first tag in allMovingMarkersTags if not allMovingMarkersTags and not allCHTMarkersTags: #raise Exception('No interface for FSI was defined.') self.fluidInterfaceID = None elif allMovingMarkersTags and not allCHTMarkersTags: if allMovingMarkersTags[0] in allMarkersID.keys(): self.fluidInterfaceID = allMarkersID[allMovingMarkersTags[0]] elif not allMovingMarkersTags and allCHTMarkersTags: if allCHTMarkersTags[0] in allMarkersID.keys(): self.fluidInterfaceID = allMarkersID[allCHTMarkersTags[0]] elif allMovingMarkersTags and allCHTMarkersTags: if allMovingMarkersTags[0] == allCHTMarkersTags[0]: if allMovingMarkersTags[0] in allMarkersID.keys(): self.fluidInterfaceID = allMarkersID[ allMovingMarkersTags[0]] else: raise Exception( "Moving and CHT markers have to be the same!\n") self.computationType = computationType # computation type : steady (default) or unsteady self.nodalLoadsType = nodalLoadsType # nodal loads type to extract : force (in N, default) or pressure (in Pa) # --- Calculate the number of nodes (on each partition) --- # self.nNodes = 0 self.nHaloNode = 0 self.nPhysicalNodes = 0 if self.fluidInterfaceID != None: self.nNodes = self.SU2.GetNumberVertices( self.fluidInterfaceID ) # numbers of nodes at the f/s interface (halo+physical) self.nHaloNode = self.SU2.GetNumberHaloVertices( self.fluidInterfaceID ) # numbers of nodes at the f/s interface (halo) self.nPhysicalNodes = self.nNodes - self.nHaloNode # numbers of nodes at the f/s interface (physical) self.nodalInitialPos_X = np.zeros( (self.nPhysicalNodes)) # initial position of the f/s interface self.nodalInitialPos_Y = np.zeros((self.nPhysicalNodes)) self.nodalInitialPos_Z = np.zeros((self.nPhysicalNodes)) self.haloNodesPositionsInit = {} FluidSolver.__init__(self) # --- Initialize the interface position and the nodal loads --- # PhysicalIndex = 0 for iVertex in range(self.nNodes): posX = self.SU2.GetVertexCoordX(self.fluidInterfaceID, iVertex) posY = self.SU2.GetVertexCoordY(self.fluidInterfaceID, iVertex) posZ = self.SU2.GetVertexCoordZ(self.fluidInterfaceID, iVertex) if self.SU2.IsAHaloNode(self.fluidInterfaceID, iVertex): GlobalIndex = self.SU2.GetVertexGlobalIndex( self.fluidInterfaceID, iVertex) self.haloNodeList[GlobalIndex] = iVertex self.haloNodesPositionsInit[GlobalIndex] = (posX, posY, posZ) else: self.SU2.ComputeVertexForces(self.fluidInterfaceID, iVertex) Fx = self.SU2.GetVertexForceX(self.fluidInterfaceID, iVertex) Fy = self.SU2.GetVertexForceY(self.fluidInterfaceID, iVertex) Fz = self.SU2.GetVertexForceZ(self.fluidInterfaceID, iVertex) Temp = self.SU2.GetVertexTemperature(self.fluidInterfaceID, iVertex) self.nodalInitialPos_X[PhysicalIndex] = posX self.nodalInitialPos_Y[PhysicalIndex] = posY self.nodalInitialPos_Z[PhysicalIndex] = posZ self.nodalLoad_X[PhysicalIndex] = Fx self.nodalLoad_Y[PhysicalIndex] = Fy self.nodalLoad_Z[PhysicalIndex] = Fz self.nodalTemperature[PhysicalIndex] = Temp PhysicalIndex += 1 self.initRealTimeData()
# Split the communicator n_tacs_procs = 1 comm = MPI.COMM_WORLD world_rank = comm.Get_rank() if world_rank < n_tacs_procs: color = 55 key = world_rank else: color = MPI.UNDEFINED key = world_rank tacs_comm = comm.Split(color, key) ndim = 3 SU2_CFD_ConfigFile = 'inv_ONERAM6.cfg' su2 = pysu2.CFluidDriver(SU2_CFD_ConfigFile, 1, ndim, False, comm) # Create model onera = FUNtoFEMmodel('onera') wing = Body('wing', fun3d=False) onera.add_body(wing) cruise = Scenario('cruise', steps=50) onera.add_scenario(cruise) # Instatiate the flow and structural solvers solvers = {} qinf = 101325.0 # freestream pressure gamma = 1.4 # ratio of specific heats with_conv_hist = True adapt_growth = [7]