def draglift(simulations, d_cylinder=0.1, u_0=1.0, flow_dir='y', t_start=-1, sortby='dx'): """ Compute mean drag coefficient, rms lift coefficient, and Strouhal number for flow past a circular cylinder. If the flow is steady, only drag and lift coefficients are computed. Call signature: draglift(simulations) Keyword arguments: *simulations* array of simulation names to be included in the computations *d_cylinder*: diameter of the cylinder *u_0* velocity at the inlet *flow_dir*: direction of the flow *t_start* time to start the drag computations from should be where the a steady vortex shedding has developed *sortby* property to sort the arrays by typical choices for parametric studies are grid size, length of domain, etc. Returns three arrays: mean C_D, rms C_L, St """ from pencilnew import sim # Find directories to include in accuracy assessment sims = [] for simulation in simulations: sims.append(sim.get(simulation, quiet=True)) # Sort simulations sims = sim.sort(sims, sortby, reverse=True) dragliftst = np.empty([len(simulations), 4]) for i, thissim in enumerate(sims): dragliftst[i, 0] = thissim.get_value(sortby) dragliftst[i, 1:] = compute_drag(thissim.get_ts(), d_cylinder, u_0, flow_dir, t_start) return dragliftst
def draglift(simulations, sortby='dx', **kwargs): """ Compute mean drag coefficient, rms lift coefficient, and Strouhal number for flow past a circular cylinder. If the flow is steady, only drag and lift coefficients are computed. Call signature: draglift(simulations, d_cylinder=0.1, u_0=1.0, flow_dir='y', t_start=-1, sortby='dx'): Keyword arguments: *simulations* array of simulation names to be included in the computations *d_cylinder*: diameter of the cylinder *u_0* velocity at the inlet *flow_dir*: direction of the flow *t_start* time to start the drag computations from should be where the a steady vortex shedding has developed *sortby* property to sort the arrays by typical choices for parametric studies are grid size, length of domain, etc. Returns object with information: sim-name, drag (mean), lift (rms), and st (non-dim shedding frequency) """ sims = [] for simulation in simulations: sims.append(sim.get(simulation, quiet=True)) # Sort simulations sims = sim.sort(sims, sortby, reverse=True) draglift_tmp = [] for i, thissim in enumerate(sims): draglift_tmp.append(Draglift()) draglift_tmp[i].set_name(thissim) draglift_tmp[i].compute(thissim, **kwargs) return draglift_tmp
def draglift(simulations, sortby='dx', **kwargs): """ Compute mean drag coefficient, rms lift coefficient, and Strouhal number for flow past a circular cylinder. If the flow is steady, only drag and lift coefficients are computed. Call signature: draglift(simulations, d_cylinder=0.1, u_0=1.0, flow_dir='y', t_start=-1, sortby='dx'): Keyword arguments: *simulations* array of simulation names to be included in the computations *d_cylinder*: diameter of the cylinder *u_0* velocity at the inlet *flow_dir*: direction of the flow *t_start* time to start the drag computations from should be where the a steady vortex shedding has developed *sortby* property to sort the arrays by typical choices for parametric studies are grid size, length of domain, etc. Returns object with information: sim-name, drag (mean), lift (rms), and st (non-dim shedding frequency) """ sims = [] for simulation in simulations: sims.append(sim.get(simulation,quiet=True)) # Sort simulations sims = sim.sort(sims,sortby,reverse=True) draglift_tmp = [] for i,thissim in enumerate(sims): draglift_tmp.append(Draglift()) draglift_tmp[i].set_name(thissim) draglift_tmp[i].compute(thissim, **kwargs) return draglift_tmp
def twonorm_accuracy(simulations, field='ux', strip=0, varfile='ogvar.dat', direction='x', noerr=True): """ Assessment of accuracy of simulation: Computes the two-norm error of all available simulation, where the simulation with the maximum amount of grid points is used as the correct/reference solution. E.g., for runs with grid points assessment of accuracy of x-component of velocity along the y-direction, for runs with grid points nxgrid = n, 2n, 4n, 8n, compute || u_n - u_0 || = dy \sum\limits_{n=0}^n (sqrt(u_n(x_n)-u_0(x_8n))) for all runs (except for the 8n case, used as reference). Requires that the runs have matching grids, that is, grid refined by a factor of 2m, and grids adjusted so that the grid point overlap (needs ofset if periodic BC is used). call signature: twonorm_accuracy(simulations) Keyword arguments: *simulations* array of simulation names to be included in the computations *field* variable used in accuracy assessment *strip*: index for strip along coordinate *varfile*: name of varfile to read from each sim *direction*: compute two-norm along 'x' or 'y' direction *noerr*: set to false if you want to return an array of maximum error along strip, in addition to the two-norm Returns array of two-norms where the larges array is used as base """ import numpy as np import os as os from pencilnew import read from pencilnew import sim # Find directories to include in accuracy assessment sims = [] for simulation in simulations: sims.append(sim.get(simulation, quiet=True)) # Sort runs by size of grid spacing if (direction == 'x' or direction == 'r'): sims = sim.sort(sims, 'dx', reverse=True) elif (direction == 'y' or direction == 'th'): sims = sim.sort(sims, 'dy', reverse=True) # From this point we only need the varfile to compute accuracy # Need to update dim to ogdim for reading of ogvar to be done # correctly from simulation object for i, thissim in enumerate(sims): sims[i].dim = read.ogdim(datadir=thissim.datadir) sims[i] = read.ogvar(sim=thissim, trimall=True) # Check that increase in size is correct for use in two-norm calculation nsims = len(sims) nx_min = sims[0].r.size ny_min = sims[0].th.size for thissim in sims: if ((thissim.r.size - 1) % (nx_min - 1) != 0): print('ERROR: Incorrect size in r-dir') print('sims.r', thissim.r.size) return False if (thissim.th.size % ny_min != 0): print('ERROR: Incorrect size in th-dir') return False # Now we are sure that first coordinate of r and th are the same for all runs # Can compute the two-norms for increasing sizes. Use largest size as normalization of error twonorms = np.zeros(nsims - 1) maxerrs = np.zeros(nsims - 1) if (direction == 'x' or direction == 'r'): dh = sims[0].dx n2_factor = int(dh / sims[-1].dx) elif (direction == 'y' or direction == 'th'): dh = sims[0].dy n2_factor = int(dh / sims[-1].dy) attribute = getattr(sims[-1], field) if (field == 'ux' or field == 'uy'): u2 = attribute[0::n2_factor, 0::n2_factor] else: u2 = attribute[0, 0::n2_factor, 0::n2_factor] strip = int(strip) i = 0 for thissim in sims[:-1]: if (direction == 'x' or direction == 'r'): n2_factor = int(dh / thissim.dx) elif (direction == 'y' or direction == 'th'): n2_factor = int(dh / thissim.dy) attribute = getattr(thissim, field) if (field == 'ux' or field == 'uy'): u1 = attribute[0::n2_factor, 0::n2_factor] else: u1 = attribute[0, 0::n2_factor, 0::n2_factor] if (direction == 'x' or direction == 'r'): twonorms[i] = (twonorm(u1[:, strip], u2[:, strip], dh)) maxerrs[i] = (maxerror(u1[:, strip], u2[:, strip])) elif (direction == 'y' or direction == 'th'): twonorms[i] = (twonorm(u1[strip, :], u2[strip, :], dh)) maxerrs[i] = (maxerror(u1[strip, :], u2[strip, :])) i = i + 1 print('Two-norm computed for field:', field, ', along strip:', strip) if (direction == 'x'): print('Along x-direction') elif (direction == 'r'): print('Along r-direction') elif (direction == 'y'): print('Along y-direction') elif (direction == 'th'): print('Along th-direction') if not noerr: return twonorms, maxerrs else: return twonorms
def twonorm_accuracy1D(simulations, field='ur', strip=1, direction='r', varfile='ogvar.dat',noerr=True, quiet=True): """ Assessment of accuracy of simulation: Computes the two-norm error of all available simulation, where the simulation with the maximum amount of grid points is used as the correct/reference solution. E.g., for runs with grid points assessment of accuracy of x-component of velocity along the y-direction, for runs with grid points nxgrid = n, 2n, 4n, 8n, compute || u_n - u_0 || = dy \sum\limits_{n=0}^n (sqrt(u_n(x_n)-u_0(x_8n))) for all runs (except for the 8n case, used as reference). Requires that the runs have matching grids, that is, grid refined by a factor of 2m, and grids adjusted so that the grid point overlap (needs ofset if periodic BC is used). call signature: twonorm_accuracy(simulations) Keyword arguments: *simulations* array of simulation names to be included in the computations *field* variable used in accuracy assessment *varfile*: name of varfile to read from each sim *noerr*: set to false if you want to return an array of maximum error along strip, in addition to the two-norm Returns array of two-norms where the larges array is used as base """ import numpy as np import os as os from pencilnew import read from pencilnew import sim # Find directories to include in accuracy assessment sims = [] for simulation in simulations: sims.append(sim.get(simulation,quiet=True)) # Sort runs by size of grid spacing sims = sim.sort(sims,'dx',reverse=True) # From this point we only need the varfile to compute accuracy # Need to update dim to ogdim for reading of ogvar to be done # correctly from simulation object for i,thissim in enumerate(sims): sims[i].dim = read.ogdim(datadir=thissim.datadir) sims[i] = read.ogvar(sim=thissim,trimall=True,varfile=varfile) # Check that increase in size is correct for use in two-norm calculation nsims = len(sims) nx_min = sims[0].r.size ny_min = sims[0].th.size for thissim in sims: if((thissim.r.size-1)%(nx_min-1) != 0): print('ERROR: Incorrect size in r-dir') print('sims.r',thissim.r.size) print('nx_min',nx_min) return False if(thissim.th.size%ny_min != 0): print('ERROR: Incorrect size in th-dir') return False # Check that all var-files are for the same time t = sims[0].t for thissim in sims: if thissim.t != t: print('WARNING: Incorrect time for one or more simulations') # Now we are sure that first coordinate of r and th are the same for all runs # Can compute the two-norms for increasing sizes. Use largest size as normalization of error twonorms = np.zeros(nsims-1) maxerrs = np.zeros(nsims-1) # Compute array of factor used to jump indices when comparing two arrays of size N and 2N etc. # Usually n2_fac = [8, 4, 2] or similar n2_fac = np.empty(nsims-1) for i,thissim in enumerate(sims[:-1]): n2_fac[i]=thissim.dx/sims[-1].dx u2 = getattr(sims[-1],field) if not(field=='ux' or field=='uy'): u2 = u2[0,:,:] for i,thissim in enumerate(sims[:-1]): u1 = getattr(thissim,field) if not(field=='ux' or field=='uy'): u1 = u1[0,:,:] dr=np.empty(thissim.r.size) dr[0:-1] = thissim.r[1:]-thissim.r[0:-1] dr[-1]=dr[-2] dth = thissim.dy twonorms[i]=0. n2=n2_fac[i] if(direction=='r'): r=sims[0].r[strip] j=int(strip*sims[0].dx/thissim.dx) for k in range(thissim.th.size): twonorms[i]=twonorms[i]+dth*r*(u1[k,j]-u2[int(k*n2),int(j*n2)])**2 elif(direction=='th'): k=int(strip*sims[0].dx/thissim.dx) for j in range(thissim.r.size): twonorms[i]=twonorms[i]+dr[j]*(u1[k,j]-u2[int(k*n2),int(j*n2)])**2 else: print('ERROR: Invalid direction chosen') return False twonorms[i] = np.sqrt(twonorms[i]) if not noerr: return twonorms, maxerrs else: return twonorms
def twonorm_accuracy(simulations, field='ux', strip=0, var_file='ogvar.dat',direction='x',noerr=True, quiet=True): """ Assessment of accuracy of simulation: Computes the two-norm error of all available simulation, where the simulation with the maximum amount of grid points is used as the correct/reference solution. E.g., for runs with grid points assessment of accuracy of x-component of velocity along the y-direction, for runs with grid points nxgrid = n, 2n, 4n, 8n, compute || u_n - u_0 || = dy \sum\limits_{n=0}^n (sqrt(u_n(x_n)-u_0(x_8n))) for all runs (except for the 8n case, used as reference). Requires that the runs have matching grids, that is, grid refined by a factor of 2m, and grids adjusted so that the grid point overlap (needs ofset if periodic BC is used). call signature: twonorm_accuracy(simulations) Keyword arguments: *simulations* array of simulation names to be included in the computations *field* variable used in accuracy assessment *strip*: index for strip along coordinate *var_file*: name of varfile to read from each sim *direction*: compute two-norm along 'x' or 'y' direction *noerr*: set to false if you want to return an array of maximum error along strip, in addition to the two-norm Returns array of two-norms where the larges array is used as base """ import numpy as np import os as os from pencilnew import read from pencilnew import sim # Find directories to include in accuracy assessment sims = [] for simulation in simulations: sims.append(sim.get(simulation,quiet=True)) # Sort runs by size of grid spacing if(direction=='x' or direction=='r'): sims = sim.sort(sims,'nx',reverse=False) elif(direction=='y' or direction=='th'): sims = sim.sort(sims,'ny',reverse=False) # From this point we only need the varfile to compute accuracy # Need to update dim to ogdim for reading of ogvar to be done # correctly from simulation object for i,thissim in enumerate(sims): sims[i].dim = read.ogdim(datadir=thissim.datadir) sims[i] = read.ogvar(sim=thissim,trimall=True,var_file=var_file) # Check that increase in size is correct for use in two-norm calculation nsims = len(sims) nx_min = sims[0].r.size ny_min = sims[0].th.size for thissim in sims: if((thissim.r.size-1)%(nx_min-1) != 0): print('ERROR: Incorrect size in r-dir') print('sims.r',thissim.r.size) print('nx_min',nx_min) return False if(thissim.th.size%ny_min != 0): print('ERROR: Incorrect size in th-dir') return False # Check that all var-files are for the same time t = sims[0].t for thissim in sims: if thissim.t != t: print('WARNING: Incorrect time for one or more simulations') # Now we are sure that first coordinate of r and th are the same for all runs # Can compute the two-norms for increasing sizes. Use largest size as normalization of error twonorms = np.zeros(nsims-1) maxerrs = np.zeros(nsims-1) if(direction=='x' or direction=='r'): dh = sims[0].dx n2_factor = int(dh/sims[-1].dx) elif(direction=='y' or direction=='th'): dh = sims[0].dy n2_factor = int(dh/sims[-1].dy) attribute = getattr(sims[-1],field) if(field=='ux' or field=='uy'): u2 = attribute[0::n2_factor,0::n2_factor] else: u2 = attribute[0,0::n2_factor,0::n2_factor] strip=int(strip) if(direction=='x' or direction=='r'): dh = sims[-1].dx dx_max = sims[0].dx n2_factor = int(thissim.dx/dh) #for i,thissim in enumerate(sims[:-1]): # strips[i]=int(thissim.dx/dx_max*strip) #n1_factor = int(sims[0].dx/sims[-1].dx) elif(direction=='y' or direction=='th'): dh = sims[-1].dy dx_max = sims[0].dy #for i,thissim in enumerate(sims[:-1]): # strips[i]=int(thissim.dy/dx_max*strip) #n1_factor = int(sims[0].dx/sims[-1].dy) attribute = getattr(sims[-1],field) # if(field=='ux' or field=='uy'): # u2 = attribute[0::n2_factor,0::n2_factor] # else: # u2 = attribute[0,0::n2_factor,0::n2_factor] j=1 for i, thissim in enumerate(sims[:-1]): n1_factor = 1 if(direction=='x' or direction=='r'): n2_factor = int(thissim.dx/dh) elif(direction=='y' or direction=='th'): n2_factor = int(thissim.dy/dh) u1 = getattr(thissim,field) if(field=='ux' or field=='uy'): u2 = attribute[0::n2_factor,0::n2_factor] #u1 = u1[0::n1_factor] else: u2 = attribute[0,0::n2_factor,0::n2_factor] u1 = u1[0,:,:]#0::n1_factor,:] #u1 = u1[0,0::n1_factor,:] radius_l=sims[-1].r[0::n2_factor] if(direction=='x' or direction=='r'): twonorms[i] = (twonorm(u1[:,strip*j],u2[:,strip*j],thissim.dy*sims[0].r[strip])) maxerrs[i] = (maxerror(u1[:,strip*j],u2[:,strip*j])) elif(direction=='y' or direction=='th'): twonorms[i] = (twonorm(u1[strip*j,:],u2[strip*j,:],thissim.dx)) maxerrs[i] = (maxerror(u1[strip*j,:],u2[strip*j,:])) j=j*2 # n1_factor = 1 # u1 = getattr(thissim,field) # if(not(field=='ux' or field=='uy')): # u1=u1[0,:,:] # # if(direction=='x' or direction=='r'): # n1_factor = int(dx_max/thissim.dx) # n2_factor = int(thissim.dx/dh) # u1 = u1[:,0::n1_factor] # u2 = attribute[0,0::n2_factor,0::n2_factor] # u2 = u2[:,0::n1_factor] # elif(direction=='y' or direction=='th'): # n1_factor = int(dx_max/thissim.dy) # n2_factor = int(thissim.dy/dh) # u1 = u1[0::n1_factor,:] # u2 = attribute[0,0::n2_factor,0::n2_factor] # u2 = u2[0::n1_factor,:] # # if(direction=='x' or direction=='r'): # twonorms[i] = (twonorm(u1[:,strip],u2[:,strip],thissim.dy*sims[0].r[strip])) # maxerrs[i] = (maxerror(u1[:,strip],u2[:,strip])) # elif(direction=='y' or direction=='th'): # twonorms[i] = (twonorm(u1[strip,:],u2[strip,:],thissim.dx)) # maxerrs[i] = (maxerror(u1[strip,:],u2[strip,:])) if(not quiet): print('Two-norm computed for field:',field,', along strip:',strip) if(direction=='x'): print('Along x-direction') elif(direction=='r'): print('Along r-direction') elif(direction=='y'): print('Along y-direction') elif(direction=='th'): print('Along th-direction') if not noerr: return twonorms, maxerrs else: return twonorms
def twonorm_accuracy1D(simulations, field='ur', strip=1, direction='r', varfile='ogvar.dat', noerr=True, quiet=True): """ Assessment of accuracy of simulation: Computes the two-norm error of all available simulation, where the simulation with the maximum amount of grid points is used as the correct/reference solution. E.g., for runs with grid points assessment of accuracy of x-component of velocity along the y-direction, for runs with grid points nxgrid = n, 2n, 4n, 8n, compute || u_n - u_0 || = dy \sum\limits_{n=0}^n (sqrt(u_n(x_n)-u_0(x_8n))) for all runs (except for the 8n case, used as reference). Requires that the runs have matching grids, that is, grid refined by a factor of 2m, and grids adjusted so that the grid point overlap (needs ofset if periodic BC is used). call signature: twonorm_accuracy(simulations) Keyword arguments: *simulations* array of simulation names to be included in the computations *field* variable used in accuracy assessment *varfile*: name of varfile to read from each sim *noerr*: set to false if you want to return an array of maximum error along strip, in addition to the two-norm Returns array of two-norms where the larges array is used as base """ import numpy as np import os as os from pencilnew import read from pencilnew import sim # Find directories to include in accuracy assessment sims = [] for simulation in simulations: sims.append(sim.get(simulation, quiet=True)) # Sort runs by size of grid spacing sims = sim.sort(sims, 'dx', reverse=True) # From this point we only need the varfile to compute accuracy # Need to update dim to ogdim for reading of ogvar to be done # correctly from simulation object for i, thissim in enumerate(sims): sims[i].dim = read.ogdim(datadir=thissim.datadir) sims[i] = read.ogvar(sim=thissim, trimall=True, varfile=varfile) # Check that increase in size is correct for use in two-norm calculation nsims = len(sims) nx_min = sims[0].r.size ny_min = sims[0].th.size for thissim in sims: if ((thissim.r.size - 1) % (nx_min - 1) != 0): print('ERROR: Incorrect size in r-dir') print('sims.r', thissim.r.size) print('nx_min', nx_min) return False if (thissim.th.size % ny_min != 0): print('ERROR: Incorrect size in th-dir') return False # Check that all var-files are for the same time t = sims[0].t for thissim in sims: if thissim.t != t: print('WARNING: Incorrect time for one or more simulations') # Now we are sure that first coordinate of r and th are the same for all runs # Can compute the two-norms for increasing sizes. Use largest size as normalization of error twonorms = np.zeros(nsims - 1) maxerrs = np.zeros(nsims - 1) # Compute array of factor used to jump indices when comparing two arrays of size N and 2N etc. # Usually n2_fac = [8, 4, 2] or similar n2_fac = np.empty(nsims - 1) for i, thissim in enumerate(sims[:-1]): n2_fac[i] = thissim.dx / sims[-1].dx u2 = getattr(sims[-1], field) if not (field == 'ux' or field == 'uy'): u2 = u2[0, :, :] for i, thissim in enumerate(sims[:-1]): u1 = getattr(thissim, field) if not (field == 'ux' or field == 'uy'): u1 = u1[0, :, :] dr = np.empty(thissim.r.size) dr[0:-1] = thissim.r[1:] - thissim.r[0:-1] dr[-1] = dr[-2] dth = thissim.dy twonorms[i] = 0. n2 = n2_fac[i] if (direction == 'r'): r = sims[0].r[strip] j = int(strip * sims[0].dx / thissim.dx) for k in range(thissim.th.size): twonorms[i] = twonorms[i] + dth * r * ( u1[k, j] - u2[int(k * n2), int(j * n2)])**2 elif (direction == 'th'): k = int(strip * sims[0].dx / thissim.dx) for j in range(thissim.r.size): twonorms[i] = twonorms[i] + dr[j] * ( u1[k, j] - u2[int(k * n2), int(j * n2)])**2 else: print('ERROR: Invalid direction chosen') return False twonorms[i] = np.sqrt(twonorms[i]) if not noerr: return twonorms, maxerrs else: return twonorms