parallelEnvironment = True solver.fileHandlerExecutor.set_parallel_environment(parallelEnvironment, MPIrank) solver.fileHandlerExecutor.add_handler(f1HistoryHandler) solver.fileHandlerExecutor.add_handler(geneOutputHandler) solver.fileHandlerExecutor.add_handler(tangoCheckpointHandler) solver.fileHandlerExecutor.add_handler(tangoHistoryHandler) # create parameters for dataSaverHandler arraysToSave = [ 'xTurbGrid', 'H2', 'H3', 'profile', 'D', 'c', 'profileEWMATurbGrid', 'fluxTurbGrid', 'smoothedFluxTurbGrid', 'fluxEWMATurbGrid', 'DHatTurbGrid', 'cHatTurbGrid', 'thetaTurbGrid' ] # for list of possible arrays, see solver._pkgdata() dataBasename = 'datasaver' tlog.info( "Preparing DataSaver to save files with prefix {}.".format(dataBasename)) solver.dataSaverHandler.initialize_datasaver(dataBasename, maxIterations, arraysToSave) solver.dataSaverHandler.set_parallel_environment(parallelEnvironment, MPIrank) tlog.info("Entering main time loop...") startTime = time.time() while solver.ok: # Implicit time advance: iterate to solve the nonlinear equation! solver.take_timestep() if solver.reachedEnd == True: tlog.info("The solution has been reached successfully.") tlog.info("Took {} iterations".format(solver.l)) else:
# Define the contributions to the H coefficients for the Shestakov Problem H1 = np.ones_like(x) H7 = shestakov_nonlinear_diffusion.H7contrib_Source(x) HCoeffs = tango.multifield.HCoefficients(H1=H1, H7=H7) HCoeffs = HCoeffs + HCoeffsTurb return HCoeffs #============================================================================== # MAIN STARTS HERE #============================================================================== tlog.setup() tlog.info("Initializing...") L, N, dx, x, nL, n = initialize_shestakov_problem() maxIterations, lmParams, tol = initialize_parameters() fluxModel = shestakov_nonlinear_diffusion.AnalyticFluxModel(dx) label = 'n' turbHandler = tango.lodestro_method.TurbulenceHandler(dx, x, fluxModel) compute_all_H_density = ComputeAllH() lodestroMethod = tango.lodestro_method.lm(lmParams['EWMAParamTurbFlux'], lmParams['EWMAParamProfile'], lmParams['thetaParams']) field0 = tango.multifield.Field(label=label, rightBC=nL, profile_mminus1=n, compute_all_H=compute_all_H_density,
geneFluxModel.set_simulation_time(SIMTIME) # initialize the user control function, if applicable. If using it, then it needs to be passed as a parameter when initializing solver #densityICTango = fields[0].profile_mminus1 #user_control_func = UserControlFunc(densityICTango) solver = tango.solver.Solver(L, xTango, tArray, maxIterations, tol, compute_all_H_all_fields, fields) # Add the file handlers solver.fileHandlerExecutor.set_parallel_environment(parallel=True, MPIrank=MPIrank) #solver.fileHandlerExecutor.add_handler(f1HistoryHandler) #solver.fileHandlerExecutor.add_handler(geneOutputHandler) solver.fileHandlerExecutor.add_handler(tangoHistoryHandler) tlog.info( "Tango history handler setup, saving to {}.".format(filenameTangoHistory)) tlog.info("Entering main time loop...") startTime = time.time() while solver.ok: # Implicit time advance: iterate to solve the nonlinear equation! solver.take_timestep() tlog.info("Tango iterations have completed.") tlog.info("The residual at the end is {}".format(solver.errHistoryFinal[-1])) e = 1.60217662e-19 pi = solver.profiles['pi'] # finished Ti0 = pi[0] / solver.profiles['n'][0] / (1000 * e) tlog.info(f'The ion temperature at r=0 is: {Ti0} keV.')
def call_gene_low_level(simulationTime=None, rho=None, mass=None, charge=None, densityHatAllSpecies=None, temperatureHatAllSpecies=None, safetyFactor=None, Lref=None, Bref=None, rhoStar=None, Tref=None, nref=None, checkpointSuffix=0): """ Call GENE using the libgene_tango interface. Note, for analytic concentric circular geometry, the libgene_tango interface takes as input a radial coordinate r/a, where a is the minor radius. However, the rest of GENE uses x=r as the radial coordinate (whatever x is, it has dimensions of length). However, for numerical purposes, GENE normalizes things to a "hat" variable, e.g., xhat = x/Lref, That = T/Tref, etc. Note that some arrays within the function are created with order='F', meaning Fortran-style contiguous. For arrays that are only 1D, this is not strictly necessary because they are already both C-contiguous and F-contiguous. So, for example, while temperatureHat is placed into an F-contiguous array, the 1D arrays safetyFactor and magneticShear are not explicitly placed into F-contiguous arrays. Inputs: simulationTime amount of time for GENE to simulate in this call. Measured in Lref/cref (scalar). labeled simtimelim in libgene_tango.f90 rho radial grid, rho = r/a for input and output profiles. Dimensionless. (array) mass species masses, in proton masses (1D array, by species) charge species charges, in elementary charges (1D array, by species) densityHatAllSpecies species density profiles in 10^19 m^-3 on grid rho (2D array, species x space) temperatureHatAllSpecies species temperature profiles in keV on grid rho (2D array, species x space) safetyFactor safety factor q on grid rho (array) Lref reference length Lref. Measured in meters. (scalar) Bref reference magnetic field, equal to B0 for analytic geometry. Measured in Tesla. (scalar) rhoStar Parameter equal to rhoref/a = (cref/Omegaref)/a. Dimensionless. (scalar) Tref reference temperature Tref. Measured in keV. Used by GENE to determine velocity gridding so Tref should be roughly equal to plasma temperature for best gridding. (scalar) nref reference density nref. Measured in 10^19 m^-3. nref be roughly equal to plasma density. (scalar) checkpointSuffix (optional) What the libgene_tango interface refers to as the "iteration number". This is the number that gets appended to checkpoint filenames. E.g., with the default value of 0, filenames end in _000 added. (integer). Default = 0. Labeled 'it' in libgene_tango.f90 Assumptions (input parameters to gene_tango.gene_tango that I set as fixed here): electrostatic = True toroidal flow velocity = 0 Outputs: dVdxHat dVhat/dxhat on grid rho, in GENE's normalized units (1D array) sqrt_gxx sqrt(g_xx) on grid rho (1D array) avgParticleFluxHatAllSpecies time & flux-surface-averaged particle flux on grid rho, in GENE's normalized units (2D array, species x space) avgHeatFluxHatAllSpecies time & flux-surface-averaged heat flux on grid rho (2D array, species x space) """ # check inputs have been provided for var in (simulationTime, rho, mass, charge, densityHatAllSpecies, temperatureHatAllSpecies, safetyFactor, Lref, Bref, rhoStar, Tref, nref): if var is None: #logging.error("Input variables must be provided in call_gene_low_level.") raise ValueError ##################### Boilerplate ##################### electrostatic = True # Electrostatic simulation numSpecies = mass.shape[0] numRadialGridPts = len(rho) # labeled px in libgene_tango.f90 # Set up input arrays for passing to GENE massGENE = np.array(mass, dtype=fltype, order='F') chargeGENE = np.array(charge, dtype=fltype, order='F') # for 2D arrays: make a new copy. Transpose changes C-order to Fortran-order. temperatureHatAllSpeciesGENE = np.copy( temperatureHatAllSpecies).T # labeled temp_io in libgene_tango.f90 densityHatAllSpeciesGENE = np.copy( densityHatAllSpecies).T # labeled dens_io in libgene_tango.f90 toroidalVelocityGENE = np.zeros( numRadialGridPts, dtype=fltype, order='F') # labeled vrot_in in libgene_tango.f90 inverseAspectRatio = -9999.99 # used only for local simulations so irrelevant # Set up output arrays for GENE... dVdxHat = np.empty(numRadialGridPts, dtype=fltype, order='F') sqrt_gxx = np.empty(numRadialGridPts, dtype=fltype, order='F') avgParticleFluxHatAllSpecies = np.empty((numRadialGridPts, numSpecies), dtype=fltype, order='F') avgHeatFluxHatAllSpecies = np.empty((numRadialGridPts, numSpecies), dtype=fltype, order='F') temperatureOutput = np.empty((numRadialGridPts, numSpecies), dtype=fltype, order='F') densityOutput = np.empty((numRadialGridPts, numSpecies), dtype=fltype, order='F') # perform whatever calculations are required magneticShear = calculate_magnetic_shear(safetyFactor, rho) ####################### End Boilerplate ###################### tlog.info('Running GENE...') (MPIrank, dVdxHat, sqrt_gxx, avgParticleFluxHatAllSpecies, avgHeatFluxHatAllSpecies, temperatureOutput, densityOutput) = gene_tango.gene_tango( checkpointSuffix, electrostatic, simulationTime, rho, temperatureHatAllSpeciesGENE, densityHatAllSpeciesGENE, massGENE, chargeGENE, toroidalVelocityGENE, rhoStar, Tref, nref, safetyFactor, magneticShear, inverseAspectRatio, Lref, Bref, numRadialGridPts, numSpecies) tlog.info('GENE finished!') # convert from Fortran-contiguous to C-contiguous arrays for rest of Python code dVdxHat = np.ascontiguousarray( dVdxHat) # for a 1D array, doesn't actually do anything... sqrt_gxx = np.ascontiguousarray(sqrt_gxx) # for 2D arrays, transpose: this reshapes dimensions from (space x species) to (species x space) and also ensures arrays are C-contiguous avgParticleFluxHatAllSpecies = avgParticleFluxHatAllSpecies.T avgHeatFluxHatAllSpecies = avgHeatFluxHatAllSpecies.T return (dVdxHat, sqrt_gxx, avgParticleFluxHatAllSpecies, avgHeatFluxHatAllSpecies)
initialData=initialData) filenameTangoHistory = basename + '_s{}'.format(setNumber) + '.hdf5' # specify how long GENE runs between Tango iterations. Specified in Lref/cref geneFluxModel.set_simulation_time(SIMTIME) solver = tango.solver.Solver(L, xTango, tArray, maxIterations, tol, compute_all_H_all_fields, fields) # Add the file handlers solver.fileHandlerExecutor.set_parallel_environment(parallel=True, MPIrank=MPIrank) #solver.fileHandlerExecutor.add_handler(f1HistoryHandler) solver.fileHandlerExecutor.add_handler(geneOutputHandler) solver.fileHandlerExecutor.add_handler(tangoHistoryHandler) tlog.info( "Tango history handler setup, saving to {}.".format(filenameTangoHistory)) tlog.info("Entering main time loop...") startTime = time.time() while solver.ok: # Implicit time advance: iterate to solve the nonlinear equation! solver.take_timestep() if solver.reachedEnd == True: tlog.info("The solution has been reached successfully.") tlog.info("Took {} iterations".format(solver.l)) else: tlog.info("The solver failed for some reason.") tlog.info("The residual at the end is {}".format( solver.errHistoryFinal[-1]))
fluxModel, gridMapper=gridMapper) t_array = np.array([0, 1e4]) # specify the timesteps to be used. compute_all_H = ComputeAllHWithBuffer(turbhandler) solver = tng.solver.Solver(L, x, n, nL, t_array, maxIterations, tol, compute_all_H, turbhandler) # set up data saver arraysToSave = [ 'H2', 'H3', 'profile', 'fluxTurbGrid', 'xTurbGrid', 'DTurbGrid' ] # for list of possible arrays, see solver._pkgdata() dataBasename = 'ex_noisebuffer' solver.dataSaverHandler.initialize_datasaver(dataBasename, maxIterations, arraysToSave) tlog.info( "Preparing DataSaver to save files with prefix {}.".format(dataBasename)) while solver.ok: # Implicit time advance: iterate to solve the nonlinear equation! solver.take_timestep() #plt.figure() nSteadyState = solver.profile #plt.plot(x, nSteadyState) #plt.title("With Buffer: n_final") # nSteadyState2 = regular_solution() #plt.figure() #plt.plot(x, nSteadyState2) #plt.title("No Buffer: n_final")
geneOutputHandler = tango.handlers.SaveGeneOutputHandler(*geneFilesToSave, iterationInterval=1, diagdir=diagdir) ### set up Tango History handler basename = 'tangodata' restartfile = tango.restart.check_if_should_restart(basename) # returns path of restartfile as string; returns None if no restartfile found if restartfile: # Restart file exists (setNumber, startIterationNumber, t, timestepNumber, old_profiles, old_profilesEWMA, old_turb_D_EWMA, old_turb_c_EWMA) = tango.restart.read_metadata_from_previousfile(restartfile) # if the density was artificially controlled in the last run, then the density saved to Tango will be incorrected. # Fix that here if necessary. Otherwise keep line commented. # old_profiles['n'] = densityICTango tango.restart.set_ewma_iterates(fields, old_profilesEWMA, old_turb_D_EWMA, old_turb_c_EWMA) initialData = tango.handlers.TangoHistoryHandler.set_up_initialdata(setNumber, rTango, rGene, t, fields) else: # No restartfile exists. Set up for first Tango run tlog.info('Error. Should not be here. Stopping') sys.exit(1) (setNumber, startIterationNumber, t, timestepNumber) = (0, 0, tArray[1], 1) initialData = tango.handlers.TangoHistoryHandler.set_up_initialdata(setNumber, rTango, rGene, t, fields) # instantiate the handler tangoHistoryHandler = tango.handlers.TangoHistoryHandler(iterationInterval=1, basename=basename, maxIterations=maxIterations, initialData=initialData) filenameTangoHistory = basename + '_s{}'.format(setNumber) + '.hdf5' # filename that data is saved to. # specify how long GENE runs between Tango iterations. Specified in Lref/cref geneFluxModel.set_simulation_time(SIMTIME) # initialize the user control function, if applicable. If using it, then it needs to be passed as a parameter when intializaing solver # densityICTango = fields[0].profile_mminus1 # user_control_func = UserControlFunc(densityICTango)