def mesh_seed_points(): ''' Compute mesh seed points using subroutine exponseed Adapted for PyUEDGE based on Jaervinen's 174270 H-mode case ''' grd.isupstreamx = 1 # Sets X-pt as limit for nonorthogonal mesh com.reset_core_og = 1 # Forces orthogonal diff above X-point # grd.kxmesh=0 # Manual definition of seed points # grd.kxmesh = 0 grd.fraclplt[1] = 0.6 #frac div leg with near-plate spacing grd.alfxdiv[1] = 0.21 #expon factor for cell-size expansion grd.alfxcore[1] = 0.4 #expon factor for cell-size expansion grd.shift_seed_leg[:2] = [0.2, 0.25] grd.shift_seed_core[:2] = [1.2, 1.0] grd.nxlplt[:2] = [6, 6] #num poloidal cells in leg-plate region grd.nxlxpt[:2] = [ 4, 4 ] #num pol cells in leg-xpt region; note nxplt+nxlxpt=nxleg must be satisfied grd.fcorenunif = 0.4 # Fraction of poloidal mesh with exponential scaling bbb.issfon = 0 bbb.ftol = 1e20 bbb.exmain() # Generate all arrays bbb.issfon = 1 bbb.ftol = 1e-8 # Restore defaults grd.kxmesh = 0 grd.exponseed()
def Initialize(self, ftol=1e20, restart=0, dtreal=1e10, SetDefaultNumerics=True): """ Initialize UEDGE simulation Args: ftol (TYPE, optional): tolerance for nksol solver. Defaults to 1e20. restart (TYPE, optional): Restart status for exmain() (0|1). Defaults to 0. dtreal (TYPE, optional): timestep for nksol solver. Defaults to 1e10. """ dtreal_bkp = bbb.dtreal ftol_bkp = bbb.ftol bbb.dtreal = dtreal bbb.ftol = ftol if (bbb.iterm == 1 and bbb.ijactot > 1): self.PrintInfo("Initial successful time-step exists", Back.GREEN) #if SetDefaultNumerics: self.SetDefaultNumerics() bbb.dtreal = dtreal_bkp bbb.ftol = ftol_bkp return else: self.PrintInfo("Taking initial step with Jacobian:", Back.CYAN) bbb.icntnunk = 0 ResetNewGeo = bbb.newgeo bbb.newgeo = 1 try: resetpandf = com.OMPParallelPandf1 com.OMPParallelPandf1 = 0 except: pass bbb.exmain() try: com.OMPParallelPandf1 = resetpandf except: pass sys.stdout.flush() bbb.newgeo = ResetNewGeo if (bbb.iterm != 1): self.PrintInfo("Error: converge an initial time-step first", Back.RED) bbb.exmain_aborted = 1 bbb.dtreal = dtreal_bkp bbb.ftol = ftol_bkp #if SetDefaultNumerics: self.SetDefaultNumerics() return else: self.PrintInfo("First initial time-step has converged", Back.GREEN) #if SetDefaultNumerics: self.SetDefaultNumerics() bbb.dtreal = dtreal_bkp bbb.ftol = ftol_bkp return
def diagnose(): bbb.issfon = 0 bbb.ftol = 1e20 bbb.exmain() bbb.issfon = 1 bbb.ftol = 1e-8 species() models() recycling() equations()
def reconv(path='.', dtreal=1e-9): ''' Reconverges all cases in subfolders in path (default current folder)''' from os import chdir, getcwd, walk from uedge.rundt import rundt from uedge import bbb from uedge.hdf5 import hdf5_save from importlib import reload path = getcwd() # Get list of subdirectories in path dirs = natsort(next(walk(path))[1]) f = open('reconv.log', 'w+') f.write('Runnin in ' + path + ':\n') f.close try: dirs.remove('grid') except: pass try: dirs.remove('rates') except: pass try: dirs.remove('ignore') except: pass for d in dirs: # Move to dir with input file chdir(path + "/" + d + "/data") print('==================') print('CONVERGING DIRECOTRY ' + d) print('==================') import input as i reload(i) i.restore_input() bbb.dtreal = 1e-9 bbb.exmain() rundt(dtreal) hdf5_save('../solutions/' + bbb.label[0].decode('UTF-8') + '.hdf5') f = open(path + '/reconv.log', 'a') if bbb.iterm == 1: f.write('Case ' + d + ' reconverged successfully!\n') else: f.write('Case ' + d + ' NOT reconverged!\n') f.close chdir(path)
def set_constant_div(D_perp=1, Chi_e=2): ''' Freezes the radial transport parameters and sets constant diffusivities and e- heat diff below X-point set_constant_div(*keys) Optional parameters D_perp (1) - Constant divertor diffusivities for all species Chi_e (2) - Constant electron heat diffusivities ''' """==================================================================================================== SET CONSTANT DIVERTOR DIFFUSIVITIES ====================================================================================================""" # Execute exmain without evaluating the convergence to generate and populate # the arrays used by UEDGE. bbb.issfon = 0 bbb.ftol = 1e20 bbb.exmain() # Use *_use arrays for radial diffusivities bbb.isbohmcalc = 0 # Set diffusivities of the *_use arrays in the divertor SOL # (common and private flux region) to 1.0 m2/s (D_perp) # and 2.0 m2/s (kye). Set the ion particle diffusivities # in the divertor to 1 m2/s # H+ bbb.dif_use[:com.ixpt1[0] + 1, :, 0] = D_perp bbb.dif_use[com.ixpt2[0] + 1:, :, 0] = D_perp # Carbon bbb.dif_use[:com.ixpt1[0] + 1, :, com.nhsp:] = D_perp bbb.dif_use[com.ixpt2[0] + 1:, :, com.nhsp:] = D_perp # Set electron heat diffusivities in divertor to 2m2/s bbb.kye_use[:com.ixpt1[0] + 1, :] = Chi_e bbb.kye_use[com.ixpt2[0] + 1:, ] = Chi_e # Switches to solve equations to convergence bbb.issfon = 1 bbb.ftol = 1e-8
def create_database(savename=None, sortlocation='mp', outpath='.', path='.', subpath='data', commands=[], ret=True, variables=None): ''' Creates a database Parameters: savename If set, saves dict as pickle named 'savename' sortlocation Location for sorting by te: 'core' or 'mp' outpath Path to location where pickle is saved path Path to parent directory subpath Path to input.py within child directories of path: path/*/supath/input.py commands List of commands to be executed before restoring solution variables List of all variable names, including package, to be stored ret Boolean whether to return dict or not ''' from os import getcwd, chdir, remove, walk from os.path import abspath from uedge.uexec import uexec from pickle import dump from uedge import bbb from importlib import reload outpath = abspath(outpath) # Get absolute path of out directory chdir(path) # Go to the parent directory parent = getcwd() # Get path to parent # Get list of subdirectories in path dirs = natsort(next(walk(path))[1]) # Omit supporting file directories try: dirs.remove('grid') except: pass try: dirs.remove('rates') except: pass try: dirs.remove('ignore') except: pass if len(dirs) == 0: return 'No directories found! Aborting...' # Empty list to return retl = [] if variables is None: variables = default_variables() for child in dirs: # Loop through all directories print('******************************') print('*** Directory: ' + child + ' ***') print('******************************') readcase(child, subpath) # Restore the case # Execute any commands before executing for cmd in commands: exec(cmd) in globals(), locals() # Read and repopulate all arrays bbb.issfon = 0 bbb.ftol = 1e20 bbb.exmain() retl.append(CASE(variables)) chdir(parent) lst = SETUP(retl) # Get the sep and xpt locations if sortlocation == 'core': lst.sort_core('bbb.ne') elif sortlocation == 'mp': lst.sort_mp('bbb.ne') else: print('Error! Unknown sortin location "' + sortlocation + '". Terminating...') chdir(outpath) # Check if save requested if savename is not None: with open(savename, 'wb') as f: dump(lst, f) if ret: return lst
def RunTime(self, **kwargs): """ Args: Verbose (TYPE, optional): DESCRIPTION. Defaults to False. Returns: Status='mainloop'|'tstop'|'dtkill'|'aborted' """ bbb.exmain_aborted = 0 self.PrintInfo('----Starting Main Loop ----') while bbb.exmain_aborted == 0: # Main loop----------------------------------------------- for imain in range(self.Imax): self.Status = 'mainloop' bbb.icntnunk = 0 self.Controlftol() bbb.ftol = self.Updateftol() self.PrintTimeStepModif(imain) self.PrintCurrentIteration(imain) try: bbb.exmain( ) # take a single step at the present bbb.dtreal except Exception as e: self.PrintError(e, imain) self.Status = 'error' return self.Status bbb.newgeo = 0 sys.stdout.flush() if bbb.exmain_aborted == 1: break if (bbb.iterm == 1 and bbb.exmain_aborted != 1): self.AutoSave() self.SaveLast( ) # Save data in file SaveDir/CaseName/last.npy bbb.dt_tot += bbb.dtreal self.dt_tot = bbb.dt_tot #self.TimeEvolution() if bbb.dt_tot >= bbb.t_stop: bbb.exmain_aborted = 1 self.SaveFinalState() self.Status = 'tstop' return self.Status if (bbb.ijactot > 1): # Second loop ----------------------------------------------------------------------------------- bbb.icntnunk = 1 bbb.isdtsfscal = 0 for ii2 in range( self.Jmax ): #take ii2max steps at the present time-step if bbb.exmain_aborted == 1: break bbb.ftol = self.Updateftol() self.PrintCurrentIteration(imain, ii2) try: bbb.exmain( ) # take a single step at the present bbb.dtreal except Exception as e: self.PrintError(e, imain, ii2) self.Status = 'error' return self.Status sys.stdout.flush() if bbb.iterm == 1 and bbb.exmain_aborted != 1: self.SaveLast( ) # Save data in file SaveDir/CaseName/last.npy bbb.dt_tot += bbb.dtreal self.dt_tot = bbb.dt_tot #self.TimeEvolution() else: break if bbb.dt_tot >= bbb.t_stop: self.PrintInfo('SUCCESS: dt_tot >= t_stop') self.SaveFinalState() self.Status = 'tstop' return self.Status # End Second loop ----------------------------------------------------------------------------------- if bbb.exmain_aborted == 1: break # Handle success/error ------------------------------------------------------------------------------ if (bbb.iterm == 1): bbb.dtreal *= self.mult_dt_fwd self.dtreal = bbb.dtreal else: #print bad eqn, cut dtreal by 3 self.Itrouble() self.PrintInfo( 'Converg. fails for bbb.dtreal; reduce time-step by 3', Back.RED) bbb.dtreal /= self.mult_dt_bwd self.dtreal = bbb.dtreal # if bbb.iterm==2 and bbb.dtreal<self.dtLowThreshold: bbb.iterm = 1 if (bbb.dtreal < bbb.dt_kill): self.PrintInfo('FAILURE: time-step < dt_kill', Back.RED) bbb.exmain_aborted = 1 self.Status = 'dtkill' return self.Status # End of main loop -------------------------------------------------------- -------------------------------- if bbb.exmain_aborted == 1: self.Status = 'aborted' return self.Status
def conv_ncore_step(d, name, t_stop=100, ii1max=100, nstop=1.5e20, dtreal=1e-9): """ Simple function to incrementally change the density of a converged solution """ from uedge import bbb from uedge.rundt import rundt from uedge.hdf5 import hdf5_save isbcwdt = bbb.isbcwdt # Check if we are increasing or decreasing! if d > 0: increasing = True else: increasing = False # Setup dt-run bbb.t_stop = t_stop # Set stop time bbb.ii1max = ii1max # Set max outer loop iterations while True: bbb.dtreal = dtreal # Small step size to ensure convergence bbb.ncore[0] += d # Increase step size print('===================================') print('Solving for ncore[0]={:.2E}'.format(bbb.ncore[0])) print('===================================') ''' bbb.exmain() # Check convergence at small dt # Check that we can get started if bbb.iterm!=1: # The case did not converge bbb.isbcwdt=1 # Relax BC:s and try again bbb.exmain() # Check convergence if bbb.iterm!=1: # Case will not converge return "Case does not converge at dtreal=1e-9 w/ isbcwdt=1. Aborting..." # We have an initially converging case. Start dt-rund bbb.dt_tot=0 # Reset time if bbb.isbcwdt==1: # We have relaxed BC:s - do a small step first # Advance to a micro-second bbb.t_stop=1e-5 rundt(bbb.dtreal) # Set BCs and run to SS bbb.isbcwdt=0 bbb.t_stop=t_stop rundt(bbb.dtreal) else: rundt(bbb.dtreal) ''' rundt(bbb.dtreal) # If run with BC relaxation, ensure convergence without relaxation if bbb.isbcwdt == 1: bbb.isbcwdt = 0 rundt(1e-6) # We should now have a steady-state solution: ensure this! bbb.dtreal = 1e20 bbb.itermx = 30 bbb.icntnunk = 0 bbb.ftol = 1e-8 bbb.exmain() # Check if SS or not if bbb.iterm == 1: # SS solution # Save to solutions with appropriate name hdf5_save("../solutions/{}_{:.3E}_ss.hdf5".format( name, bbb.ncore[0])) else: hdf5_save("../solutions/{}_{:.2E}_failed.hdf5".format( name, bbb.ncore[0])) print("Ramp did not converge for variable: {:.2E}. Aborting...". format(bbb.ncore[0])) break if increasing: if bbb.ncore[0] > nstop: break else: if bbb.ncore[0] < nstop: break bbb.isbcwdt = isbcwdt
def ani_row(variable, plotrow, ylim=False, yaxis='lin', path='.', show_animation=True, savename=False, fps=10, figsize=(1.618 * 6, 6), keys={}, steps="", framerate=1, output='gif', database=None, subplot=None, commands=[]): """ Function creating a flux-tube plot animation ani_row(var,row,**keys) Arguments: var: Variable name to be plotted as string row: Index of row to be plotted Keyword arguments show[=True]: Boolean determining whether to show plot or not save[=False]: If animation is to be saved, save must be set as path and save file name interval[=1000]: Time in ms each frame is shown figsize Tuple containing the figure width and height keys: A dictionary containing the keyword arguments of ft plot commands: List of strings containing UEDGE commands to be executed before evaluation, e.g. turning coefficients on or off steps: String with text to displayed in front of second col values in animation title """ # from pandas import read_csv from uedge import bbb, com from os import chdir, getcwd, walk from matplotlib.animation import ArtistAnimation from matplotlib.pyplot import axes, subplots_adjust, figure, show, close from uedge.contrib.holm10.ue_plot import row from uedge.contrib.holm10.utils import readcase func = row chdir(path) path = getcwd() # Get list of subdirectories in path dirs = natsort(next(walk(path))[1]) dirs = dirs[::framerate] # Omit supporting file directories try: dirs.remove('grid') except: pass try: dirs.remove('rates') except: pass try: dirs.remove('ignore') except: pass if len(dirs) == 0: return 'No directories found! Aborting...' # Extract original title for repeat use try: origtitle = keys['title'] except: origtitle = '' # Fig for dislpay fig = figure(figsize=figsize) fig.patch.set_visible(False) ims = [] # Empty array to store frames # Set common key params keys['row'] = plotrow keys['yaxis'] = yaxis keys['ylim'] = ylim if database is None: for frame in range(len(dirs)): # Verbose print("Frame ", frame + 1, " of ", len(dirs)) print("===========================") readcase('{}/{}'.format(path, dirs[frame])) # Execute any requested commands for cmd in commands: exec(cmd) bbb.ftol = 1e20 bbb.issfon = 0 bbb.exmain() # Add timestamp to plot title keys['title'] = origtitle + ' ' + steps + str(bbb.ncore[0]) # This is a dirty solution, but as the Forthon objects are only pointed to by python the values stored cannot (to my knowledge) be directly accessed by python (list of vars, etc). Instead one must execute a string statement to get the parameter passed onto the function exec('keys["z"]=[' + variable + ']') ims.append([create_im(keys, func, figsize, subplot=subplot)]) # Append frame to list else: for frame in range(len(database)): # Verbose print("Frame ", frame + 1, " of ", len(dirs)) print("===========================") keys['z'] = database[frame]['var'] ims.append([create_im(keys, func, figsize, subplot=subplot)]) # Append frame to list # Turn off extra pair of axes, make the animation "fullscreen" ax = axes() ax.axis('off') subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0) ani = ArtistAnimation(fig, ims, interval=int(1000.0 / fps), blit=True, repeat_delay=1000) # Create animation in fig chdir(path) # Go back to dir where function called if savename is not False: # Show and store if requested save_animation(ani, savename, output, fps) if show_animation is True: return ani else: close()
def rundt( dtreal=1e-9,nfe_tot=0,savedir='../solutions',dt_tot=0,ii1max=500,ii2max=5,ftol_dt=1e-5,itermx=7,rlx=0.9,n_stor=0, tstor=(1e-3,4e-2),incpset=7,dtmfnk3=1e-4): ''' Function advancing case time-dependently: increasing time-stepping is the default to attain SS solution rdrundt(dtreal,**keys) Variables Keyword parameters: dtreal[1e-9] The inital time step time nfe_tot[0] Number of function evaluations savedir[savedt] Directory where hdf5 savefile is written dt_tot[0] Total time accummulated: default option resets time between runs ii1max[500] Outer loop (dt-changing) iterations ii2max[5] Inner loop (steps at dt) iterations ftol_dt[1e-5] Time-dependent fnrm tolerance itermx[7] Max. number of linear iterations allowed rlx[0.9] Max. allowed change in variable at each iteration n_stor[0] Number of linearly spaced hdf5 dumps tstor_s[(1e-3,4e-2)] Tuple with start and stop times for storing snapshots to HDF5 incpset[7] Iterations until Jacobian is recomputed dtmfnk[1e-4] dtreal for mfnksol signchange if ismfnkauto=1 (default) The above defaults are based on rdinitdt. Additional UEDGE parameters used in the function, assuming their default values are: bbb.rdtphidtr[1e20] # Ratio dtphi/dtreal bbb.ismfnkauto[1] # If =1, mfnksol=3 for dtreal<dtmfnk3, otherwise=-3 bbb.mult_dt[3.4] # Factor expanding dtreal after each successful inner loop bbb.itermxrdc[7] # Itermx used by the script bbb.ftol_min[1e-9] # Value of fnrm where time advance will stop bbb.t_stop[100] # Value of dt_tot (sec) where calculation will stop bbb.dt_max[100] # Max. time step for dtreal bbb.dt_kill[1e-14] # Min. allowed time step; rdcontdt stops if reached bbb.deldt_min[0.04] # Minimum relative change allowed for model_dt > 0 bbb.numrevjmax[2] # Number of dt reductions before Jac recalculated bbb.numfwdjmax[1] # Number of dt increases before Jac recalculated bbb.ismmaxuc[1] # =1 for intern calc mmaxu; =0,set mmaxu & dont chng bbb.irev[-1] # Flag to allow reduced dt advance after cutback bbb.initjac[0] # If=1, calc initial Jac upon reading rdcontdt bbb.ipt[1] # Index of variable; value printed at step # If ipt not reset from unity, ipt=idxte(nx,iysptrx+1) Additional comments (from rdcontdt): This file runs a time-dependent case using dtreal. First, a converged solution for a (usually small) dtreal is obtained: UEDGE must report iterm=1 at the end. Then the control parameters are adjusted. If a mistake is made, to restart this file without a Jacobian evaluation, be sure to reset iterm=1 (=> last step was successful) ''' from uedge import bbb,com from uedge.hdf5 import hdf5_save from numpy import sqrt,append,array,expand_dims from os.path import exists from copy import copy # Store the original values dt_tot_o=bbb.dt_tot ii1max_o=bbb.ii1max ii2max_o=bbb.ii2max ftol_dt_o=bbb.ftol_dt itermx_o=bbb.itermx rlx_o=bbb.rlx n_stor_o=bbb.n_stor tstor_s_o=bbb.tstor_s tstor_e_o=bbb.tstor_e incpset_o=bbb.incpset dtmfnk3_o=bbb.dtmfnk3 icntnunk_o=bbb.icntnunk ftol_o=bbb.ftol # Set inital time-step to dtreal bbb.dtreal=dtreal # Check if successful time-step exists (bbb.iterm=1) if (bbb.iterm == 1 and bbb.ijactot>1): print("Initial successful time-step exists") bbb.dtreal = bbb.dtreal*bbb.mult_dt #compensates dtreal divided by mult_dt below else: print("*---------------------------------------------------------*") print("Need to take initial step with Jacobian; trying to do here") print("*---------------------------------------------------------*") bbb.icntnunk = 0 bbb.exmain() if bbb.exmain_aborted == 1: # If exmain is aborted, exit script bbb.exmain_aborted == 0 # Restore False for consecutive runs return bbb.dtreal = bbb.dtreal*bbb.mult_dt #compensates dtreal divided by mult_dt below if (bbb.iterm != 1): print("*--------------------------------------------------------------*") print("Error: converge an initial time-step first; then retry rdcontdt") print("*--------------------------------------------------------------*") return # Set UEDGE variables to the prescribed values bbb.dt_tot=dt_tot bbb.ii1max=ii1max bbb.ii2max=ii2max bbb.ftol_dt=ftol_dt bbb.itermx=itermx bbb.rlx=rlx bbb.n_stor=n_stor bbb.tstor_s=tstor[0] bbb.tstor_e=tstor[1] bbb.incpset=incpset bbb.dtmfnk3=dtmfnk3 # Saved intermediates counter i_stor=0 # Helper variables nfe_tot = max(nfe_tot,0) deldt_0 = bbb.deldt # Empty dictionary for writing data=dict() storevar= [ ['ni', bbb.ni], ['up', bbb.up], ['te', bbb.te], ['ti', bbb.ti], ['tg', bbb.tg], ['ng', bbb.ng], ['phi', bbb.phi], ['dt_tot', bbb.dt_tot], ['nfe', None], ['dtreal', bbb.dtreal] ] # Linearly spaced time slices for writing dt_stor = (bbb.tstor_e - bbb.tstor_s)/(bbb.n_stor - 1) isdtsf_sav = bbb.isdtsfscal if(bbb.ipt==1): # No index requested # Check for first variable solved: order is defined as Te,Ti,ni,ng,Tg,phi for eq in [bbb.idxte, bbb.idxti, bbb.idxn, bbb.idxg, bbb.idxtg, bbb.idxu]: # If multi-species: if len(eq.shape)==3: # Loop through all species to find first solved for index in range(eq.shape[2]): # See if equation is solved if eq[:,:,index].min()!=0: ipt=eq[com.nx-1,com.iysptrx+1,index] break # If not, see if equation is solved else: if eq.min()!=0: ipt=eq[com.nx-1,com.iysptrx+1] break bbb.irev = -1 # forces second branch of irev in ii1 loop below if (bbb.iterm == 1): # successful initial run with dtreal bbb.dtreal = bbb.dtreal/bbb.mult_dt # gives same dtreal after irev loop else: # unsuccessful initial run; reduce dtreal bbb.dtreal = bbb.dtreal/(3*bbb.mult_dt) # causes dt=dt/mult_dt after irev loop if (bbb.initjac == 0): bbb.newgeo=0 dtreal_sav = bbb.dtreal bbb.itermx = bbb.itermxrdc bbb.dtreal = bbb.dtreal/bbb.mult_dt #adjust for mult. to follow; mult_dt in rdinitdt bbb.dtphi = bbb.rdtphidtr*bbb.dtreal bbb.ylodt = bbb.yl bbb.pandf1 (-1, -1, 0, bbb.neq, 1., bbb.yl, bbb.yldot) fnrm_old = sqrt(sum((bbb.yldot[0:bbb.neq]*bbb.sfscal[0:bbb.neq])**2)) if (bbb.initjac == 1): fnrm_old=1.e20 print("initial fnrm ={:.4E}".format(fnrm_old)) for ii1 in range( 1, bbb.ii1max+1): if (bbb.ismfnkauto==1): bbb.mfnksol = 3 # adjust the time-step if (bbb.irev == 0): # Only used after a dt reduc. success. completes loop ii2 for fixed dt bbb.dtreal = min(3*bbb.dtreal,bbb.t_stop) #first move forward after reduction bbb.dtphi = bbb.rdtphidtr*bbb.dtreal if (bbb.ismfnkauto==1 and bbb.dtreal > bbb.dtmfnk3): bbb.mfnksol = -3 bbb.deldt = 3*bbb.deldt else: # either increase or decrease dtreal; depends on mult_dt bbb.dtreal = min(bbb.mult_dt*bbb.dtreal,bbb.t_stop) bbb.dtphi = bbb.rdtphidtr*bbb.dtreal if (bbb.ismfnkauto==1 and bbb.dtreal > bbb.dtmfnk3): bbb.mfnksol = -3 bbb.deldt = bbb.mult_dt*bbb.deldt bbb.dtreal = min(bbb.dtreal,bbb.dt_max) bbb.dtphi = bbb.rdtphidtr*bbb.dtreal if (bbb.ismfnkauto==1 and bbb.dtreal > bbb.dtmfnk3): bbb.mfnksol = -3 bbb.deldt = min(bbb.deldt,deldt_0) bbb.deldt = max(bbb.deldt,bbb.deldt_min) nsteps_nk=1 print('--------------------------------------------------------------------') print('--------------------------------------------------------------------') print(' ') print('*** Number time-step changes = {} New time-step = {:.4E}'.format(ii1, bbb.dtreal)) print('--------------------------------------------------------------------') bbb.itermx = bbb.itermxrdc if (ii1>1 or bbb.initjac==1): # first time calc Jac if initjac=1 if (bbb.irev == 1): # decrease in bbb.dtreal if (bbb.numrev < bbb.numrevjmax and \ bbb.numrfcum < bbb.numrevjmax+bbb.numfwdjmax): #dont recom bbb.jac bbb.icntnunk = 1 bbb.numrfcum = bbb.numrfcum + 1 else: # force bbb.jac calc, reset numrev bbb.icntnunk = 0 bbb.numrev = -1 # yields api.zero in next statement bbb.numrfcum = 0 bbb.numrev = bbb.numrev + 1 bbb.numfwd = 0 else: # increase in bbb.dtreal if (bbb.numfwd < bbb.numfwdjmax and \ bbb.numrfcum < bbb.numrevjmax+bbb.numfwdjmax): #dont recomp bbb.jac bbb.icntnunk = 1 bbb.numrfcum = bbb.numrfcum + 1 else: bbb.icntnunk = 0 #recompute jacobian for increase dt bbb.numfwd = -1 bbb.numrfcum = 0 bbb.numfwd = bbb.numfwd + 1 bbb.numrev = 0 #bbb.restart counter for dt reversals bbb.isdtsfscal = isdtsf_sav bbb.ftol = max(min(bbb.ftol_dt, 0.01*fnrm_old),bbb.ftol_min) bbb.exmain() # take a single step at the present bbb.dtreal if bbb.exmain_aborted == 1: # If exmain is aborted, exit script bbb.exmain_aborted = 0 # Restore False for consecutive runs return if (bbb.iterm == 1): bbb.dt_tot += bbb.dtreal nfe_tot += bbb.nfe[0,0] bbb.ylodt = bbb.yl bbb.pandf1 (-1, -1, 0, bbb.neq, 1., bbb.yl, bbb.yldot) fnrm_old = sqrt(sum((bbb.yldot[0:bbb.neq-1]*bbb.sfscal[0:bbb.neq-1])**2)) if (bbb.dt_tot>=0.9999999*bbb.t_stop or fnrm_old<bbb.ftol_min): print(' ') print('*****************************************************') print('** SUCCESS: frnm < bbb.ftol; or dt_tot >= t_stop **') print('*****************************************************') break bbb.icntnunk = 1 bbb.isdtsfscal = 0 for ii2 in range( 1, bbb.ii2max+1): #take ii2max steps at the present time-step if (bbb.iterm == 1): bbb.itermx = bbb.itermxrdc bbb.ftol = max(min(bbb.ftol_dt, 0.01*fnrm_old),bbb.ftol_min) bbb.exmain() if bbb.exmain_aborted == 1: # If exmain is aborted, exit script bbb.exmain_aborted = 0 # Restore False for consecutive runs return if (bbb.iterm == 1): bbb.ylodt = bbb.yl bbb.pandf1 (-1, -1, 0, bbb.neq, 1., bbb.yl, bbb.yldot) fnrm_old = sqrt(sum((bbb.yldot[0:bbb.neq-1]*bbb.sfscal[0:bbb.neq-1])**2)) print("Total time = {:.4E}; Timestep = {:.4E}".format(bbb.dt_tot,bbb.dtreal)) print("variable index ipt = {} bbb.yl[ipt] = {:.4E}".format(ipt,bbb.yl[ipt])) dtreal_sav = bbb.dtreal bbb.dt_tot += bbb.dtreal nfe_tot += bbb.nfe[0,0] if exists(savedir): hdf5_save('{}/{}_last_ii2.hdf5'.format(savedir,bbb.label[0].decode('UTF-8'))) else: print('Folder {} not found, saving output to cwd...'.format(savedir)) hdf5_save('{}_last_ii2.hdf5'.format(bbb.label[0].decode('UTF-8'))) if (bbb.dt_tot>=0.999999999999*bbb.t_stop or fnrm_old<bbb.ftol_min): print(' ') print('*****************************************************') print('** SUCCESS: frnm < bbb.ftol; or dt_tot >= t_stop **') print('*****************************************************') break print(" ") ## Store variables if a storage time has been crossed if (bbb.dt_tot >= tstor[0]+dt_stor*i_stor and i_stor<bbb.n_stor): # Check if variables are already present for var in storevar: if var[0]=='nfe': var[1]=nfe_tot # Update non-pointer variable if var[0]=='dtreal': var[1]=copy(bbb.dtreal) # Update variable: unsure why pointer does not update if var[0]=='dt_tot': var[1]=copy(bbb.dt_tot) # Update variable: unsure why pointer does not update # Check if array initialized if var[0] in data.keys(): data[var[0]]=append(data[var[0]],expand_dims(array(copy(var[1])),axis=0),axis=0) else: data[var[0]]=expand_dims(array(copy(var[1])),axis=0) i_stor = i_stor + 1 ## End of storage section if (bbb.dt_tot>=bbb.t_stop or fnrm_old<bbb.ftol_min): break # need for both loops bbb.irev = bbb.irev-1 if (bbb.iterm != 1): #print bad eqn, cut dtreal by 3, set irev flag itroub() if (bbb.dtreal < bbb.dt_kill): print(' ') print('*************************************') print('** FAILURE: time-step < dt_kill **') print('*************************************') break bbb.irev = 1 print('*** Converg. fails for bbb.dtreal; reduce time-step by 3, try again') print('----------------------------------------------------------------- ') bbb.dtreal = bbb.dtreal/(3*bbb.mult_dt) bbb.dtphi = bbb.rdtphidtr*bbb.dtreal if (bbb.ismfnkauto==1 and bbb.dtreal > bbb.dtmfnk3): bbb.mfnksol = -3 bbb.deldt = bbb.deldt/(3*bbb.mult_dt) bbb.iterm = 1 # Save the data to HDF5 if n_stor>0: if exists(savedir): save_dt('{}/dt_{}.hdf5'.format(savedir,bbb.label[0].decode('UTF-8')),data) else: print('Folder {} not found, saving output to cwd...'.format(savedir)) save_dt('dt_{}.hdf5'.format(bbb.label[0].decode('UTF-8')),data) # Restore the original values bbb.dt_tot=dt_tot_o bbb.ii1max=ii1max_o bbb.ii2max=ii2max_o bbb.ftol_dt=ftol_dt_o bbb.itermx=itermx_o bbb.rlx=rlx_o bbb.n_stor=n_stor_o bbb.tstor_s=tstor_s_o bbb.tstor_e=tstor_e_o bbb.incpset=incpset_o bbb.dtmfnk3=dtmfnk3_o bbb.icntnunk=icntnunk_o bbb.ftol=ftol_o bbb.dtreal=1e20
def ani_vec(varx, vary, path='.', norm=None, zoom='div', show_animation=True, savename=False, fps=10, figsize=(1.618 * 6, 6), keys={}, steps="", framerate=1, output='gif', database=None, subplot=None, commands=[], s=None): """ Function creating an animated vector plot ani_vec(poldata,raddata,keys**) Arguments: poldata: Variable name of x-directional quantities to be plotted as string raddata: Variable name of y-directional quantities to be plotted as string Keyword arguments zoom[='div']: Zoom of animation, options are: divertor ('div'), device ('device'), inner target ('it') or outer target ('ot') norm[=None]: Normalization to an arrow length s[=0] Index to be plotted in case multispecies arrays are supplied path: Path show[=True]: Boolean determining whether to show plot or not save[=False]: If animation is to be saved, save must be set as path and save file name interval[=1000]: Time in ms each frame is shown figsize Tuple containing the figure width and height keys: A dictionary containing the keyword arguments of ft plot commands: List of strings containing UEDGE commands to be executed before evaluation, e.g. turning coefficients on or off steps: String with text to displayed in front of second col values in animation title """ # from pandas import read_csv from uedge import bbb, com from os import chdir, getcwd, walk from matplotlib.animation import ArtistAnimation from matplotlib.pyplot import axes, subplots_adjust, figure, show, close from uedge.contrib.ue_plot import vector from importlib import reload from uedge.contrib.utils import readcase func = vector # Common keys keys['norm'] = norm keys['s'] = s keys['zoom'] = zoom chdir(path) path = getcwd() # Get list of subdirectories in path dirs = natsort(next(walk(path))[1]) dirs = dirs[::framerate] # Omit supporting file directories try: dirs.remove('grid') except: pass try: dirs.remove('rates') except: pass try: dirs.remove('ignore') except: pass if len(dirs) == 0: return 'No directories found! Aborting...' # Extract original title for repeat use try: origtitle = keys['title'] except: origtitle = '' # Fig for dislpay fig = figure(figsize=figsize) fig.patch.set_visible(False) ims = [] # Empty array to store frames if database is None: # Pass plotfunc-specific parameters to the function for frame in range(len(dirs)): # Verbose print("Frame ", frame + 1, " of ", len(dirs)) print("===========================") readcase('{}/{}'.format(path, dirs[frame])) # Execute any requested commands for cmd in commands: exec(cmd) bbb.ftol = 1e20 bbb.issfon = 0 bbb.exmain() # Add timestamp to plot title keys['title'] = origtitle + ' ' + steps + str(bbb.ncore[0]) # This is a dirty solution, but as the Forthon objects are only pointed to by python the values stored cannot (to my knowledge) be directly accessed by python (list of vars, etc). Instead one must execute a string statement to get the parameter passed onto the function exec('keys["x"]=[' + varx + ']') exec('keys["y"]=[' + vary + ']') ims.append([create_im(keys, func, figsize, subplot=subplot)]) # Append frame to list else: for frame in range(len(database)): # Verbose print("Frame ", frame + 1, " of ", len(dirs)) print("===========================") keys['x'] = database[frame]['varx'] keys['y'] = database[frame]['vary'] ims.append([create_im(keys, func, figsize, subplot=subplot)]) # Append frame to list # Turn off extra pair of axes, make the animation "fullscreen" ax = axes() ax.axis('off') subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0) ani = ArtistAnimation(fig, ims, interval=int(1000.0 / fps), blit=True, repeat_delay=1000) # Create animation in fig chdir(path) # Go back to dir where function called if savename is not False: # Show and store if requested save_animation(ani, savename, output, fps) if show_animation is True: return ani else: close()
def create_EIRENE(path='.',subpath='data'): ''' Creates a database Parameters: savename If set, saves dict as pickle named 'savename' sortlocation Location for sorting by te: 'core' or 'mp' outpath Path to location where pickle is saved path Path to parent directory subpath Path to input.py within child directories of path: path/*/supath/input.py commands List of commands to be executed before restoring solution variables List of all variable names, including package, to be stored ret Boolean whether to return dict or not ''' from os import getcwd,chdir,remove,walk from os.path import abspath from uedge import bbb,com from importlib import reload def natsort(l): from re import split convert = lambda text: int(text) if text.isdigit() else text.lower() alphanum_key = lambda key: [ convert(c) for c in split('([0-9]+)', key) ] return sorted(l, key = alphanum_key) chdir(path) # Go to the parent directory parent=getcwd() # Get path to parent # Get list of subdirectories in path dirs=natsort(next(walk(path))[1]) # Omit supporting file directories try: dirs.remove('grid') except: pass try: dirs.remove('rates') except: pass try: dirs.remove('ignore') except: pass if len(dirs)==0: return 'No directories found! Aborting...' loop=0 for child in dirs: # Loop through all directories loop+=1 # TODO: exmain every Nth step print('******************************') print('*** Directory: '+child+' ***') print('******************************') chdir('{}/{}'.format(child,subpath)) import input as i reload(i) i.restore_input() # Read and repopulate all arrays bbb.issfon=0;bbb.ftol=1e20;bbb.exmain() bbb.write_eirene(verbatim=False) chdir(parent)
def quickconverge(): ''' Converges case w/o Jac eval ''' bbb.issfon=0;bbb.ftol=1e20;bbb.exmain();bbb.issfon=1;bbb.ftol=1e-8