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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
    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()
Beispiel #5
0
# 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]