def boltz_main_outputs(N=2**5,h=2.,period=12.,youngs=5.e9,\ visc_rp=0,width=100.,Hs_inc=3.,conc=.7,dmean=100.,ax=None): import WIM2d_f2py as Mwim # N : no of directions # h : # thickness [m] # period : # period [s] # youngs : # period [s] # visc_rp : # R-P damping parameter [m^s/s] # Hs : # sig wave height [m] # conc : # concentration [0-1] # dmean : # mean floe size [m] om = 2*np.pi/period gravity = 9.81 atten_in = np.array([h,om,youngs,visc_rp]) atten_out = Mwim.atten_youngs(atten_in) # print(atten_in) # print(atten_out) alp = conc/dmean*atten_out[4] # scattering "attenuation" [m^{-1}] alp_dis = 2*conc*atten_out[0] # damping [m^{-1}] kwtr = atten_out[2] cp = om/kwtr # phase vel (open water) [m/s] cg = cp/2. # group vel (open water, inf depth relation) [m/s] print('\n') print('width = '+str(width)+'m') print('\n') out = Fbs.solve_boltzmann(width=width, alp=alp,N=N,alp_dis=alp_dis,cg=cg,Hs=Hs_inc, f_inc=dirspec_inc_spreading) th_vec = out['angles'] dth = 2*np.pi/N xx = np.linspace(0,width,num=800) E_th = Fbs.calc_expansion(out,xx,L=width) # E0 = dth*E_th.sum(1) # integral over directions (freq spec) Hs_steady = 4*np.sqrt(E0.real) # S_th = E_th.dot(out['solution']['Rmat'].transpose()) # source term S_cos = S_th.dot(dtheta*np.cos(out['angles'])) # integral with cos over directions rhow = 1025 # kg/m^3 gravity = 9.81 # m/s^2 taux_steady = -(rhow*gravity/cp)*S_cos.real #test plot if desired if ax is not None: ax.plot(xx/1.e3,Hs_out) return xx,Hs_out
def atten_nondim(h,T,young,visc_rp): # attenuation per floe # - for scalars (ie single grid cell) # h = inputs(1) # om = inputs(2) # young = inputs(3) # visc_rp = inputs(4) om = 2*np.pi/T inputs = np.array([h,om,young,visc_rp]) outs = Mwim.atten_youngs(inputs) # calls interface to fortran code # outputs = (/damping,kice,kwtr,int_adm, # ac,modT,argR,argT/) k_visc = outs[0] kice = outs[1] kwtr = outs[2] alp_scat = outs[4] return k_visc,kice,kwtr,alp_scat
cols = ['k','b','r','g','m','c'] lstil = ['-','--','-.',':'] Nc = len(cols) loop_c = -1 loop_s = 0 ndirs = [16,32,64,128,256] fig = None labs = ['$x$, km','$H_s$, m'] for N in ndirs: # get steady state solution om = 2*np.pi/Tp_in # gravity = 9.81 atten_in = np.array([h_in,om,young,visc_rp]) atten_out = Mwim.atten_youngs(atten_in) alp = c_in/D_in*atten_out[4] # scattering "attenuation" [m^{-1}] alp_dis = 2*c_in*atten_out[0] # damping [m^{-1}] kwtr = atten_out[2] cp = om/kwtr # phase vel (open water) [m/s] cg = cp/2. # group vel (open water, inf depth relation) [m/s] # #N = pow(2,4) out = Fbs.solve_boltzmann_ft(width=ice_width, alp=alp,N=N,alp_dis=alp_dis,cg=cg,f_inc=Fbs.dirspec_inc_spreading,Hs=Hs_in) # alp2 = out['inputs'][0] # print(alp,alp2) # sys.exit('fig_test_convergence2steady') nx0 = 1.e3
def do_run_vSdir(sdf_dir=None, wave_fields=None,ice_fields=None, params_in={},mesh_e=None): dd = os.path.abspath("..") sys.path.append(dd+"/bin") sys.path.append(dd+"/py_funs") RUN_OPT = 0 run_dict = { 0: 'run "vSdir", passing directional spectrum in/out'} print("###################################################") print("Run option:") print(" "+str(RUN_OPT)+' : '+run_dict[RUN_OPT]) print("###################################################") TEST_IN_SPEC = 0 # check Hs,Tp,mwd calc'd from input spec TEST_OUT_SPEC = 0 # check Hs,Tp calc'd from output spec # check directories for outputs exist if mesh_e is None: outdir = 'out_py_io_2' else: outdir = 'out_py_io_3' dirs = [outdir, outdir+'/diagnostics', outdir+'/diagnostics/global', outdir+'/diagnostics/local', outdir+'/binaries', outdir+'/binaries/prog'] # tell fortran where to save the outputs ifd_name = 'infile_dirs.txt' fid = open(ifd_name,'w') fid.write('grid\n') fid.write(outdir+'\n') fid.close() for j in range(0,len(dirs)): dirj = dirs[j] if not os.path.exists(dirj): os.makedirs(dirj) # clear out old progress files dd = os.path.abspath(outdir+"/binaries/prog") files = os.listdir(dd) for f in files: os.remove(dd+"/"+f) # run wim2d with inputs and outputs param_dict = default_params() for key in params_in: if key not in param_dict: raise ValueError('Parameter '+key+'invalid') else: param_dict[key] = params_in[key] param_vec = param_dict2vec(param_dict) # dimensions of grid nx,ny,nfreq,ndir = Fwim.wim2d_dimensions() freq_vec = Fwim.wim2d_freq_vec(nfreq) if ice_fields is not None: # 'ice_fields' is given as input # - put data into 'ice_arrays': keys = ['icec','iceh','dfloe'] ice_arrays = np.zeros((nx,ny,len(keys))) n = 0 for key in keys: ice_arrays[:,:,n] = ice_fields[key] n = n+1 del ice_fields else: raise ValueError("No 'ice_fields' input") if sdf_dir is None: if wave_fields is not None: # 'wave_fields' is given as input # instead of sdf_dir Hs = wave_fields['Hs'] Tp = wave_fields['Tp'] mwd = wave_fields['mwd'] # Tmean = np.mean(Tp [Hs>0]) dir_mean = np.mean(mwd[Hs>0]) if nfreq==1: # check only 1 freq stdev = np.std( Tp[Hs>0]) if stdev/Tmean>1.e-3: print('Expected one frequency, but') print('std dev (Tp) = '+str(stdev)+'s') print('mean (Tp) = '+str(Tmean) +'s') raise ValueError('Tp array not consistent with 1 frequency') if ndir==1: # check only 1 dir stdev = np.std (mwd[Hs>0]) if stdev/dir_mean>1.e-3: print('Expected one direction, but') print('std dev (mwd) = '+str(stdev)+'degrees') print('mean (mwd) = '+str(dir_mean) +'degrees') raise ValueError('mwd array not consistent with 1 direction') sdf_dir = np.zeros((nx,ny,ndir,nfreq)) PI = np.pi for i in range(nx): for j in range(ny): if Hs[i,j]>0: if nfreq==1: # use single freq formula: S=A^2/2 sdf_dir[i,j,:,:] = pow(Hs[i,j]/4.0,2) else: # use Bretschneider for w in range(nfreq): om = 2*PI*freq_vec[w] sdf_dir[i,j,:,w] = Fmisc.SDF_Bretschneider(om) if ndir>1: theta_max = 90.0 theta_min = -270.0 dtheta = (theta_min-theta_max)/float(ndir) #<0 wavdir = theta_max+np.arange(ndir)*dtheta # modify spectrum depending on direction D2R = np.pi/180. # test_sum = 0. # test_sum_ = 0. for wth in range(ndir): theta_fac_ = Fmisc.theta_dirfrac(wavdir[wth]-.5*abs(dtheta),abs(dtheta),mwd[i,j])/abs(D2R*dtheta) # chi = PI/180.0*(wavdir[wth]-mwd[i,j]) # if (np.cos(chi)>0.0): # theta_fac = 2.0/PI*pow(np.cos(chi),2) # else: # theta_fac = 0.0 sdf_dir[i,j,wth,:] = sdf_dir[i,j,wth,:]*theta_fac_ # test_sum += theta_fac_ # test_sum_ += theta_fac_ # print(wavdir[wth],wavdir[wth]-.5*abs(dtheta),dtheta,mwd[i,j],theta_fac,theta_fac_) # print(test_sum*abs(dtheta),test_sum_*abs(dtheta)) # sys.exit() if 0: # test spectrum is defined OK sq = np.squeeze(sdf_dir[i,j,:,0]) m0 = np.sum(sq)*abs((PI/180.)*dtheta) print(i,j) print(4*np.sqrt(m0),Hs[i,j]) # plt.plot(wavdir/180.,sq) plt.show() # sys.exit() if TEST_IN_SPEC: # test integrals of spectrum are the same as intended: print('Testing input spectrum...') wave_fields2 = {'Hs':0,'Tp':0,'mwd':0} if nfreq==1: freq_vec_ = np.array([1./Tp_single_freq]) else: freq_vec_ = freq_vec if ndir==1: wavdir_ = np.array([mwd_single_dir]) else: wavdir_ = wavdir (wave_fields2['Hs'], wave_fields2['Tp'], wave_fields2['mwd'] ) = Fmisc.spectrum_integrals( sdf_dir,freq_vec_,wavdir_) arrays = [wave_fields2,wave_fields] keys = arrays[0].keys() for key in keys: print('Comparing field: '+key) diff = abs(arrays[0][key]-arrays[1][key]) print('Maximum difference = '+str(np.max(diff))+'\n') sys.exit() del wave_fields # finished setting sdf_dir from wave_fields else: raise ValueError("No wave inputs (need 'sdf_dir' or 'wave_fields')") # now run the WIM print(" ") print("###################################################") print("Running WIM with sdf_dir inputted") print("###################################################") print(" ") sdf_dir = sdf_dir.reshape(sdf_dir.size,order='fortran') sdf_dir = np.array(sdf_dir,dtype='float32') print(param_vec) if mesh_e is None: sdf_dir2,out_arrays = Fwim.py_wim2d_run_vsdir( sdf_dir,ice_arrays,param_vec,ndir,nfreq) os.remove(ifd_name) print(" ") print("###################################################") print("Finished call to wim2d_vSdir:") print("###################################################") print(" ") else: # mesh_e=dictionary with keys ['x','y','conc','thick','Nfloes','broken'] # > convert this to array nmesh_vars = len(mesh_e) mesh_arr = mesh_dict2arr(mesh_e,inverse=False) nmesh_e = len(mesh_arr[:,0]) # print(mesh_arr.transpose()) # sys.exit() # reshape array to a vector mesh_arr = mesh_arr.reshape( (nmesh_e*nmesh_vars,),order='fortran') # run WIM, with interpolation of Nfloes onto the mesh out = Fwim.py_wim2d_run_vsdir_mesh( sdf_dir,ice_arrays,mesh_arr, param_vec,ndir,nfreq,nmesh_e) sdf_dir2,out_arrays,mesh_arr = out os.remove(ifd_name) print(" ") print("###################################################") print("Finished call to wim2d_vSdir_mesh:") print("###################################################") print(" ") mesh_arr = mesh_arr.reshape((nmesh_e,nmesh_vars),order='fortran') mesh_e = mesh_dict2arr(mesh_arr,inverse=True) # print(mesh_arr.transpose()) sdf_dir2 = sdf_dir2.reshape((nx,ny,ndir,nfreq),order='fortran') # Dmax = out_arrays[:,:,0] # Hs = out_arrays[:,:,1] # Tp = out_arrays[:,:,2] # tau_x = out_arrays[:,:,3] # tau_y = out_arrays[:,:,4] # mwd = out_arrays[:,:,5] # convert out_arrays to dictionary out_fields = Fdat.fn_check_out_arr(out_arrays) del out_arrays if TEST_OUT_SPEC: # test integrals of spectrum are the same as intended: print('Testing integrals of output spectrum...') wave_fields2 = {'Hs':0,'Tp':0,'mwd':0} if nfreq==1: Tp_single_freq = param_dict['T_init'] freq_vec_ = np.array([1./Tp_single_freq]) else: freq_vec_ = freq_vec if ndir==1: mwd_single_dir = param_dict['mwd_init'] wavdir_ = np.array([mwd_single_dir]) else: wavdir_ = wavdir (wave_fields2['Hs'], wave_fields2['Tp'], wave_fields2['mwd'] ) = Fmisc.spectrum_integrals( sdf_dir2,freq_vec_,wavdir_) arrays = [wave_fields2,out_fields] keys = ['Hs','Tp'] # keys = arrays[0].keys() for key in keys: print('Comparing field: '+key) diff = abs(arrays[0][key]-arrays[1][key]) print('Maximum difference = '+str(np.max(diff))+'\n') if 1: # plot Tp for visual comparison # - small differences? gf = Fdat.fn_check_grid('inputs') labs = ['$x$, km','$y$, km', '$T_p$, s'] # f = Fplt.cmap_3d( gf['X']/1.e3, gf['Y']/1.e3, wave_fields2['Tp'], labs) f.show() # f = Fplt.cmap_3d( gf['X']/1.e3, gf['Y']/1.e3, out_fields['Tp'], labs) f.show() if 0: # plot Hs for visual comparison gf = Fdat.fn_check_grid('inputs') labs = ['$x$, km','$y$, km', '$H_s$, m'] # f = Fplt.cmap_3d( gf['X']/1.e3, gf['Y']/1.e3, wave_fields2['Hs'], labs) f.show() # f = Fplt.cmap_3d( gf['X']/1.e3, gf['Y']/1.e3, out_fields['Hs'], labs) f.show() sys.exit() elif 0: # test out_fields are the same as in the binary files print('Testing output fields against binary files...') arrays = 2*[1] arrays[0] = out_fields arrays[1] = Fdat.fn_check_out_bin('out_2/binaries') keys = arrays[0].keys() for key in keys: print('Comparing field: '+key) diff = abs(arrays[0][key]-arrays[1][key]) print('Maximum difference = '+str(np.max(diff))+'\n') sys.exit() return out_fields,Fdat.wim_results(outdir),mesh_e
def do_run(in_fields=None,params_in={}): if in_fields is not None: RUN_OPT = 1 else: RUN_OPT = 0 if len(params_in)>0: warnings.warn('params_in input being ignored - no input arrays') run_dict = {0: 'old version (no in/out)', 1: 'in/out'} print("###################################################") print("Run option:") print(" "+str(RUN_OPT)+' : '+run_dict[RUN_OPT]) print("###################################################") # check directories for outputs exist if (RUN_OPT == 0): outdir = 'out_py' else: outdir = 'out_py_io_1' dirs = [outdir, outdir+'/diagnostics', outdir+'/diagnostics/local', outdir+'/diagnostics/global', outdir+'/binaries', outdir+'/binaries/prog'] # tell fortran where to save the outputs ifd_name = 'infile_dirs.txt' fid = open(ifd_name,'w') fid.write('grid\n') fid.write(outdir+'\n') fid.close() for dirj in dirs: if not os.path.exists(dirj): os.makedirs(dirj) # clear out old progress files dd = os.path.abspath(outdir+"/binaries/prog") files = os.listdir(dd) for f in files: os.remove(dd+"/"+f) if RUN_OPT == 0: # run the non-IO WIM # (can still specify parameters in infile_nonIO.txt) print(" ") print("Running WIM without input/output") print("###################################################") print(" ") Fwim.py_wim2d_run() os.remove(ifd_name) print(" ") print("###################################################") print("Finished call to wim2d_run:") print("###################################################") print(" ") # load results from binary files return Fdat.wim_results(outdir) # out_fields = Fdat.fn_check_out_bin(outdir+'/binaries') else: # run wim2d with inputs and outputs param_dict = default_params() for key in params_in: if key not in param_dict: raise ValueError('Parameter '+key+' invalid') else: param_dict[key] = params_in[key] param_vec = param_dict2vec(param_dict) if 0: print(params_in) print(param_dict) print(param_vec) sys.exit() if in_fields is not None: # 'in_fields' is given as input # - put data into 'in_arrays': keys = ['icec','iceh','dfloe','Hs','Tp','mwd'] nx,ny = in_fields[keys[0]].shape in_arrays = np.zeros((nx,ny,6)) n = 0 for key in keys: in_arrays[:,:,n] = in_fields[key] n = n+1 del in_fields elif 0: # 'in_fields' not given as input # - read in inputs from saved files: in_dir = 'out_py/binaries' grid_prams = Fdat.fn_check_grid(in_dir) ice_fields,wave_fields = Fdat.fn_check_init(in_dir) # merge ice and wave fields: ice_fields.update(wave_fields) in_fields = ice_fields del wave_fields # put data into 'in_arrays': keys = ['icec','iceh','dfloe','Hs','Tp','mwd'] nx,ny = in_fields[keys[0]].shape in_arrays = np.zeros((nx,ny,6)) n = 0 for key in keys: in_arrays[:,:,n] = in_fields[key] n = n+1 del in_fields,ice_fields elif 1: # 'in_fields' not given as input # - specify 'in_arrays' manually in_dir = 'out/binaries' grid_prams = Fdat.fn_check_grid(in_dir) n = grid_prams['nx'] ny = grid_prams['ny'] X = grid_prams['X'] Y = grid_prams['Y'] LANDMASK = grid_prams['LANDMASK'] xmin = X.min() xmax = X.max() # set ice conc/thickness ICE_MASK = np.zeros((nx,ny)) ICE_MASK[np.logical_and(X>0.7*xmin,LANDMASK<1)] = 1 # i>=24 icec = 0.75*ICE_MASK iceh = 2.0*ICE_MASK dfloe = 250*ICE_MASK # set wave fields WAVE_MASK = np.zeros((nx,ny)) WAVE_MASK[X<xmin*0.8] = 1 # i<=15 Hs = 2.0*WAVE_MASK Tp = 12.0*WAVE_MASK mwd = -90.0*WAVE_MASK in_arrays[:,:,0] = icec in_arrays[:,:,1] = iceh in_arrays[:,:,2] = dfloe in_arrays[:,:,3] = Hs in_arrays[:,:,4] = Tp in_arrays[:,:,5] = mwd # run the WIM print(" ") print("###################################################") print("Running WIM with input/output") print("###################################################") print(" ") out_arrays = Fwim.py_wim2d_run_io(in_arrays,param_vec) os.remove(ifd_name) print(" ") print("###################################################") print("Finished call to wim2d_run_io:") print("###################################################") print(" ") # Dmax = out_arrays[:,:,0] # Hs = out_arrays[:,:,1] # Tp = out_arrays[:,:,2] # tau_x = out_arrays[:,:,3] # tau_y = out_arrays[:,:,4] # mwd = out_arrays[:,:,4] # convert out_arrays to dictionary out_fields = Fdat.fn_check_out_arr(out_arrays) del out_arrays return out_fields,Fdat.wim_results(outdir)