├── .gitignore
├── docu
├── matvis
│ ├── .dropbox.attr
│ ├── LT.png
│ ├── Lu.png
│ ├── Lv.png
│ ├── GTx.png
│ ├── GTy.png
│ ├── Gqx.png
│ ├── Gqy.png
│ ├── Gux.png
│ ├── Guy.png
│ ├── Gvx.png
│ ├── Gvy.png
│ ├── ITq.png
│ ├── ITu.png
│ ├── ITv.png
│ ├── IqT.png
│ ├── Iqu.png
│ ├── Iqv.png
│ ├── IuT.png
│ ├── Iuq.png
│ ├── Iuv.png
│ ├── IvT.png
│ ├── Ivq.png
│ ├── Ivu.png
│ ├── LLT.png
│ ├── LLu.png
│ ├── LLv.png
│ ├── AL_stencil1.png
│ ├── AL_stencil2.png
│ ├── relative_nodes.png
│ └── scripts
│ │ ├── grid_vis.py
│ │ ├── matvis.py
│ │ ├── forc_vis.py
│ │ └── grid_vis_rel.py
├── thesis_methods.pdf
├── thesis_appendix.pdf
└── swm_documentation.pdf
├── plot
├── plots
│ ├── e_mean.png
│ ├── spec_eke.pdf
│ ├── energymap.png
│ ├── power_maps.png
│ ├── bs_timescales.pdf
│ ├── mean_section.pdf
│ ├── power_maps_bs.png
│ ├── pv_gradient.pdf
│ ├── Ro_hist_nadiga.pdf
│ ├── budget_closure.pdf
│ ├── energy_timeseries.pdf
│ ├── power_maps_bs_weak.png
│ ├── relvort_snapshot.png
│ ├── energy_budget_terms.png
│ ├── power_maps_bs_cntrl.png
│ ├── power_maps_bs_strong.png
│ └── power_maps_bs_crosssection.png
├── mean_e_plot.py
├── spec_plot.py
├── last_timestep_plot.py
├── Ro_hist_plot.py
├── mean_sections_plot.py
├── powermap_plot.py
├── pv_gradient.py
├── powermap_bs_crosssection.py
├── Ro_hist_plot_balu.py
├── streamplot.py
├── energy_timeseries.py
├── powermap_plot_bs.py
└── energymap_plot.py
├── calc
├── process
│ ├── var_subset_e.py
│ ├── var_subset.py
│ └── var_subset_last.py
├── mean_e_calc.py
├── misc
│ ├── streamfunction.py
│ ├── streamf_calc.py
│ ├── pv_calc.py
│ ├── pv_plot.py
│ ├── tempautocorr.py
│ ├── tempautocorr_plot.py
│ ├── ReRo_hist_plot.py
│ ├── cospec_calc.py
│ ├── Re_hist_plot.py
│ ├── trispec_calc.py
│ ├── ReRo_hist.py
│ ├── taylor_diagram_plot.py
│ ├── taylor_convergence.py
│ ├── trispec_plot.py
│ ├── cospec_plot.py
│ ├── tempautocorr_plot_bf.py
│ ├── spec_ens _calc.py
│ ├── trispec.py
│ ├── Re_hist_calc.py
│ ├── diss_vis.py
│ ├── c_diss_plot.py
│ ├── Re_hist_calc_bs.py
│ └── Re_hist_calc_bs_old.py
├── Ro_hist_calc.py
├── floats
│ ├── floats_plot.py
│ ├── floats_plot_bf.py
│ ├── floats_calc_meanflow.py
│ └── floats_calc.py
├── power_inout_calc.py
├── mean_calc.py
├── mean_timeseries_calc.py
├── spec_calc.py
└── power_inout_bs_calc.py
├── swm_run.py
├── README.md
├── swm_integration.py
├── swm_rhs.py
└── swm_output.py
/.gitignore:
--------------------------------------------------------------------------------
1 | data
2 | *.nc
3 |
--------------------------------------------------------------------------------
/docu/matvis/.dropbox.attr:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/docu/matvis/LT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/LT.png
--------------------------------------------------------------------------------
/docu/matvis/Lu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Lu.png
--------------------------------------------------------------------------------
/docu/matvis/Lv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Lv.png
--------------------------------------------------------------------------------
/docu/matvis/GTx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/GTx.png
--------------------------------------------------------------------------------
/docu/matvis/GTy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/GTy.png
--------------------------------------------------------------------------------
/docu/matvis/Gqx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Gqx.png
--------------------------------------------------------------------------------
/docu/matvis/Gqy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Gqy.png
--------------------------------------------------------------------------------
/docu/matvis/Gux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Gux.png
--------------------------------------------------------------------------------
/docu/matvis/Guy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Guy.png
--------------------------------------------------------------------------------
/docu/matvis/Gvx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Gvx.png
--------------------------------------------------------------------------------
/docu/matvis/Gvy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Gvy.png
--------------------------------------------------------------------------------
/docu/matvis/ITq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/ITq.png
--------------------------------------------------------------------------------
/docu/matvis/ITu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/ITu.png
--------------------------------------------------------------------------------
/docu/matvis/ITv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/ITv.png
--------------------------------------------------------------------------------
/docu/matvis/IqT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/IqT.png
--------------------------------------------------------------------------------
/docu/matvis/Iqu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Iqu.png
--------------------------------------------------------------------------------
/docu/matvis/Iqv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Iqv.png
--------------------------------------------------------------------------------
/docu/matvis/IuT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/IuT.png
--------------------------------------------------------------------------------
/docu/matvis/Iuq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Iuq.png
--------------------------------------------------------------------------------
/docu/matvis/Iuv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Iuv.png
--------------------------------------------------------------------------------
/docu/matvis/IvT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/IvT.png
--------------------------------------------------------------------------------
/docu/matvis/Ivq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Ivq.png
--------------------------------------------------------------------------------
/docu/matvis/Ivu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/Ivu.png
--------------------------------------------------------------------------------
/docu/matvis/LLT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/LLT.png
--------------------------------------------------------------------------------
/docu/matvis/LLu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/LLu.png
--------------------------------------------------------------------------------
/docu/matvis/LLv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/LLv.png
--------------------------------------------------------------------------------
/docu/thesis_methods.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/thesis_methods.pdf
--------------------------------------------------------------------------------
/plot/plots/e_mean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/e_mean.png
--------------------------------------------------------------------------------
/plot/plots/spec_eke.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/spec_eke.pdf
--------------------------------------------------------------------------------
/docu/thesis_appendix.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/thesis_appendix.pdf
--------------------------------------------------------------------------------
/plot/plots/energymap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/energymap.png
--------------------------------------------------------------------------------
/plot/plots/power_maps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/power_maps.png
--------------------------------------------------------------------------------
/docu/matvis/AL_stencil1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/AL_stencil1.png
--------------------------------------------------------------------------------
/docu/matvis/AL_stencil2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/AL_stencil2.png
--------------------------------------------------------------------------------
/docu/swm_documentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/swm_documentation.pdf
--------------------------------------------------------------------------------
/plot/plots/bs_timescales.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/bs_timescales.pdf
--------------------------------------------------------------------------------
/plot/plots/mean_section.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/mean_section.pdf
--------------------------------------------------------------------------------
/plot/plots/power_maps_bs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/power_maps_bs.png
--------------------------------------------------------------------------------
/plot/plots/pv_gradient.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/pv_gradient.pdf
--------------------------------------------------------------------------------
/docu/matvis/relative_nodes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/docu/matvis/relative_nodes.png
--------------------------------------------------------------------------------
/plot/plots/Ro_hist_nadiga.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/Ro_hist_nadiga.pdf
--------------------------------------------------------------------------------
/plot/plots/budget_closure.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/budget_closure.pdf
--------------------------------------------------------------------------------
/plot/plots/energy_timeseries.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/energy_timeseries.pdf
--------------------------------------------------------------------------------
/plot/plots/power_maps_bs_weak.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/power_maps_bs_weak.png
--------------------------------------------------------------------------------
/plot/plots/relvort_snapshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/relvort_snapshot.png
--------------------------------------------------------------------------------
/plot/plots/energy_budget_terms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/energy_budget_terms.png
--------------------------------------------------------------------------------
/plot/plots/power_maps_bs_cntrl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/power_maps_bs_cntrl.png
--------------------------------------------------------------------------------
/plot/plots/power_maps_bs_strong.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/power_maps_bs_strong.png
--------------------------------------------------------------------------------
/plot/plots/power_maps_bs_crosssection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/milankl/swm/HEAD/plot/plots/power_maps_bs_crosssection.png
--------------------------------------------------------------------------------
/calc/process/var_subset_e.py:
--------------------------------------------------------------------------------
1 | ## READ VARIABLE FROM SEVERAL NCFILES and store subset of it as NPY
2 | from __future__ import print_function
3 |
4 | path = '/home/mkloewer/python/swm/'
5 |
6 | import os; os.chdir(path) # change working directory
7 | import numpy as np
8 | from netCDF4 import Dataset
9 |
10 | # OPTIONS
11 | runfolder = [10,11,12,13,14,15]
12 | sub = 4
13 |
14 | for r in runfolder:
15 | print(('Subsampling from run %i') % r)
16 |
17 | ## read data
18 | runpath = path+'data/run%04i' % r
19 | nce = Dataset(runpath+'/e.nc')
20 | e = nce['e'][:][::sub,:,:]
21 | nce.close()
22 |
23 | # save subset as .npy
24 | np.save(runpath+'/e_sub.npy',e)
25 | del e
26 |
--------------------------------------------------------------------------------
/swm_run.py:
--------------------------------------------------------------------------------
1 | ## SHALLOW WATER MODEL
2 | from __future__ import print_function # tested with python 3.6 and 2.7.12
3 |
4 | # path
5 | import os
6 | path = os.getcwd() + '/'
7 |
8 | # import modules
9 | import numpy as np # version 1.11.3-py36
10 | from scipy import sparse # version 0.19-py36
11 | import time as tictoc
12 | from netCDF4 import Dataset # version 1.2.4-py36, hdf5 version 1.8.17-py36, hdf4 version 4.2.12-py36
13 | import glob
14 | import zipfile
15 |
16 | ## import all functions
17 | exec(open(path+'swm_param.py').read())
18 | exec(open(path+'swm_operators.py').read())
19 | exec(open(path+'swm_rhs.py').read())
20 | exec(open(path+'swm_integration.py').read())
21 | exec(open(path+'swm_output.py').read())
22 |
23 | ## set all parameters and initial conditions, and run model
24 | u,v,eta = set_param()
25 | u,v,eta = time_integration(u,v,eta)
26 |
--------------------------------------------------------------------------------
/calc/mean_e_calc.py:
--------------------------------------------------------------------------------
1 | ## PRODUCE MEAN CALCULATIONS AND EXPORT AS .NPY
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 |
10 | # OPTIONS
11 | runfolder = 15
12 | print('Calculating subgrid-EKE means from run ' + str(runfolder))
13 |
14 | ## read data
15 | runpath = path+'data/run%04i' % runfolder
16 |
17 | skip = 5*365
18 | e = np.load(runpath+'/e_sub.npy')[skip:,:,:]
19 | print('run %i read.' % runfolder)
20 |
21 | ## create ouputfolder
22 | try:
23 | os.mkdir(runpath+'/analysis')
24 | except:
25 | pass
26 |
27 | ## U,V,H mean
28 | em = e.mean(axis=0)
29 | print('e mean done.')
30 |
31 | ## STORING
32 | dic = dict()
33 | all_var2export = ['em']
34 |
35 | for v in all_var2export:
36 | exec('dic[v] ='+v)
37 |
38 | np.save(runpath+'/analysis/mean_e.npy',dic)
39 | print('Everything stored.')
40 |
--------------------------------------------------------------------------------
/calc/process/var_subset.py:
--------------------------------------------------------------------------------
1 | ## READ VARIABLE FROM SEVERAL NCFILES and store subset of it as NPY
2 | from __future__ import print_function
3 |
4 | path = '/home/mkloewer/python/swm/'
5 |
6 | import os; os.chdir(path) # change working directory
7 | import numpy as np
8 | from netCDF4 import Dataset
9 |
10 |
11 | # OPTIONS
12 | runfolder = [14]
13 | sub = 4
14 |
15 | for r in runfolder:
16 | print(('Subsampling from run %i') % r)
17 |
18 | # read data
19 | runpath = path+'data/run%04i' % r
20 |
21 | ncu = Dataset(runpath+'/u.nc')
22 | u = ncu['u'][:][::sub,:,:]
23 | ncu.close()
24 | print('u read.')
25 | np.save(runpath+'/u_sub.npy',u)
26 | del u
27 |
28 | ncv = Dataset(runpath+'/v.nc')
29 | v = ncv['v'][:][::sub,:,:]
30 | ncv.close()
31 | print('v read.')
32 | np.save(runpath+'/v_sub.npy',v)
33 | del v
34 |
35 | nceta = Dataset(runpath+'/eta.nc')
36 | eta = nceta['eta'][:][::sub,:,:]
37 | time = nceta['t'][::sub] # in seconds
38 | t = time / 3600. / 24. # in days
39 | nceta.close()
40 | print('eta read.')
41 | np.save(runpath+'/eta_sub.npy',eta)
42 | np.save(runpath+'/t_sub.npy',time)
43 | del eta
44 | del time,t
45 |
--------------------------------------------------------------------------------
/calc/process/var_subset_last.py:
--------------------------------------------------------------------------------
1 | ## READ VARIABLE FROM SEVERAL NCFILES and store subset of it as NPY
2 | from __future__ import print_function
3 |
4 | path = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/data/'
5 | #path = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
6 |
7 | import os; os.chdir(path) # change working directory
8 | import numpy as np
9 | from netCDF4 import Dataset
10 |
11 | # OPTIONS
12 | runfolder = [0,6]
13 | s = 40 # read s-th last time step
14 |
15 |
16 | for r in runfolder:
17 | print(('Store last time step from run %i') % r)
18 |
19 | ## read data
20 | runpath = path+'run%04i' % r
21 |
22 | ncu = Dataset(runpath+'/u.nc')
23 | u = ncu['u'][-s,:,:]
24 | ncu.close()
25 | print('u read.')
26 | np.save(runpath+'/u_last.npy',u)
27 | del u
28 |
29 | ncv = Dataset(runpath+'/v.nc')
30 | v = ncv['v'][-s,:,:]
31 | ncv.close()
32 | print('v read.')
33 | np.save(runpath+'/v_last.npy',v)
34 | del v
35 |
36 | nceta = Dataset(runpath+'/eta.nc')
37 | eta = nceta['eta'][-s,:,:]
38 | #time = nceta['t'][::sub] # in seconds
39 | #t = time / 3600. / 24. # in days
40 | nceta.close()
41 | print('eta read.')
42 | np.save(runpath+'/eta_last.npy',eta)
43 | del eta
44 |
--------------------------------------------------------------------------------
/calc/misc/streamfunction.py:
--------------------------------------------------------------------------------
1 | # PLOT STREAMFUNCTION
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | from scipy.integrate import cumtrapz
8 | import matplotlib.pyplot as plt
9 | import time as tictoc
10 | from netCDF4 import Dataset
11 | import glob
12 | from cmocean import cm
13 |
14 | ## OPTIONS
15 | runfolder = [3,10]
16 | print('Compare mean plots from run ' + str(runfolder))
17 |
18 | ## read data
19 |
20 | runpath1 = path+'data/run%04i' % runfolder[0]
21 | D1 = np.load(runpath1+'/analysis/mean.npy').all()
22 | param1 = np.load(runpath1+'/param.npy').all()
23 |
24 | # runpath2 = path+'data/run%04i' % runfolder[1]
25 | # D2 = np.load(runpath2+'/analysis/mean.npy').all()
26 | # param2 = np.load(runpath2+'/param.npy').all()
27 | #
28 | # runpath3 = path+'stoch/data/run%04i' % 5
29 | # D3 = np.load(runpath3+'/analysis/mean.npy').all()
30 | # param3 = np.load(runpath3+'/param.npy').all()
31 |
32 | ## CALCULATE STREAMFUNCTION
33 | global param
34 | param = np.load(runpath1+'/param.npy').all()
35 | exec(open(path+'swm_operators.py').read())
36 | exec(open(path+'swm_output.py').read())
37 | param['output'] = 0
38 | set_grad_mat()
39 | set_interp_mat()
40 |
41 | PSI1v = cumtrapz(v2mat(D1['vm']),axis=1,dx=param['dx'],initial=0)
42 | PSI1u = -cumtrapz(u2mat(D1['um']),axis=0,dx=param['dy'],initial=0)
43 |
44 | levs = np.linspace(-abs(PSI1u).max(),abs(PSI1u).max(),64)
45 |
46 | fig,(ax1,ax2) = plt.subplots(1,2,sharex=True,sharey=True)
47 |
48 | ax1.contourf(param['x_v'],param['y_v'],PSI1v,levs,cmap=cm.balance)
49 | ax2.contourf(param['x_u'],param['y_u'],PSI1u,levs,cmap=cm.balance)
50 |
51 | plt.show()
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.repostatus.org/#inactive)
2 |
3 | # swm - Shallow water model
4 | Shallow water equations solver with finite differences. Arakawa C-grid, Arakawa and Lamb advection scheme, Shchepetkin and O'Brian-like biharmonic diffusion operator. 4th order Runge-Kutta for time integration.
5 |
6 | A documentation is available at http://www.github.com/milankl/swm/tree/master/docu
7 |
8 | This model is written in python, relies on numpy, scipy and netCDF4.
9 |
10 | This program is free software: you can redistribute it and/or modify
11 | it under the terms of the GNU General Public License as published by
12 | the Free Software Foundation, either version 3 of the License, or
13 | (at your option) any later version.
14 |
15 | This program is distributed in the hope that it will be useful,
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | GNU General Public License for more details.
19 |
20 | You should have received a copy of the GNU General Public License
21 | along with this program. If not, see .
22 |
23 | # RUN
24 |
25 | You may want to change settings in swm_param.py before you run the model. Then simply do
26 |
27 | python swm_run.py
28 |
29 | # Energy budget-based backscatter
30 |
31 | An implementation of the energy budget-based backscatter as described in Kloewer et al 2018, Ocean Modelling can be found in the separate branch "backscatter".
32 |
33 | Copyright (C) 2018, Milan Kloewer (milan.kloewer@physics.ox.ac.uk, milank.de)
34 |
35 | # Citation
36 |
37 | If you use this package in your research, please cite us
38 |
39 | > Klöwer M, MF Jansen, M Claus, RJ Greatbatch and S Thomsen, 2018. *Energy budget-based backscatter in a shallow water model of a double gyre basin*, __Ocean Modelling__, 132, [10.1016/j.ocemod.2018.09.006](https://doi.org/10.1016/j.ocemod.2018.09.006)
40 |
--------------------------------------------------------------------------------
/docu/matvis/scripts/grid_vis.py:
--------------------------------------------------------------------------------
1 | ## Visualize Arakawa C-grid numbering
2 | import numpy as np
3 | import matplotlib.pyplot as plt
4 |
5 | nx = 3
6 | ny = 3
7 |
8 | Lx = nx
9 | Ly = ny
10 |
11 | dx = Lx/nx
12 | dy = Ly/ny
13 |
14 | # grid vectors for T-points
15 | x_T = np.arange(dx/2.,Lx,dx)
16 | y_T = np.arange(dy/2.,Ly,dy)
17 |
18 | # grid vectors for u-points
19 | x_u = x_T[:-1] + dx/2.
20 | y_u = y_T
21 |
22 | #grid vectors for v-points
23 | x_v = x_T
24 | y_v = y_T[:-1] + dy/2.
25 |
26 | # grid vectors for q-points
27 | x_q = np.arange(0,Lx+dx/2.,dx)
28 | y_q = np.arange(0,Ly+dy/2.,dy)
29 |
30 | ## meshgrid
31 |
32 | xx_T,yy_T = np.meshgrid(x_T,y_T)
33 | xx_u,yy_u = np.meshgrid(x_u,y_u)
34 | xx_v,yy_v = np.meshgrid(x_v,y_v)
35 | xx_q,yy_q = np.meshgrid(x_q,y_q)
36 |
37 | xx_T = xx_T.flatten()
38 | xx_u = xx_u.flatten()
39 | xx_v = xx_v.flatten()
40 | xx_q = xx_q.flatten()
41 |
42 | yy_T = yy_T.flatten()
43 | yy_u = yy_u.flatten()
44 | yy_v = yy_v.flatten()
45 | yy_q = yy_q.flatten()
46 |
47 | fig,ax = plt.subplots(1,1)
48 |
49 | ax.plot(xx_T,yy_T,'r.',ms=10,mec='k')
50 | ax.plot(xx_u,yy_u,'g.',ms=10,mec='k')
51 | ax.plot(xx_v,yy_v,'b.',ms=10,mec='k')
52 | ax.plot(xx_q,yy_q,'k.',ms=10)
53 |
54 | ax.plot(x_v,[0]*nx,'b.',ms=10,alpha=.6)
55 | ax.plot(x_v,[Ly]*nx,'b.',ms=10,alpha=.6)
56 | ax.plot([0]*ny,y_u,'g.',ms=10,alpha=.6)
57 | ax.plot([Lx]*ny,y_u,'g.',ms=10,alpha=.6)
58 |
59 |
60 | plt.grid()
61 |
62 | for xx,yy,vv in zip([xx_T,xx_u,xx_v,xx_q],[yy_T,yy_u,yy_v,yy_q],['T','u','v','q']):
63 | for i in range(len(xx)):
64 | ax.text(xx[i]+0.03,yy[i]+0.03,r'$'+vv+'_{%i}$' %(i+1),fontsize=15)
65 |
66 | ax.set_xlabel(r'$x$')
67 | ax.set_ylabel(r'$y$')
68 |
69 | ax.set_xticks(range(Lx+1))
70 | ax.set_yticks(range(Ly+1))
71 |
72 | ax.set_xlim(-0.1,nx+0.1)
73 | ax.set_ylim(-0.1,ny+0.1)
74 |
75 | ax.set_frame_on(False)
76 |
77 | dxstring = [(r'$%i\Delta x$' % i) if i > 1 else r'$\Delta x$' for i in range(1,nx)]
78 | dystring = [(r'$%i\Delta y$' % i) if i > 1 else r'$\Delta y$' for i in range(1,ny)]
79 |
80 | ax.set_xticklabels([r'$0$']+dxstring+[r'$L_x$'])
81 | ax.set_yticklabels([r'$0$']+dystring+[r'$L_y$'])
82 | plt.tight_layout()
83 | plt.show()
--------------------------------------------------------------------------------
/calc/misc/streamf_calc.py:
--------------------------------------------------------------------------------
1 | ## PRODUCE MEAN CALCULATIONS FOR STREAMFUNCTIONS AND OUTPUT AS .NPY
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 | import glob
10 |
11 | # OPTIONS
12 | runfolder = [2,3]
13 | print('Calculating means from run ' + str(runfolder))
14 |
15 | ## read data
16 | for r,i in zip(runfolder,range(len(runfolder))):
17 | runpath = path+'data/run%04i' % r
18 |
19 | if i == 0:
20 | u = np.load(runpath+'/u_sub.npy')
21 | v = np.load(runpath+'/v_sub.npy')
22 | h = np.load(runpath+'/h_sub.npy')
23 | time = np.load(runpath+'/t_sub.npy')
24 | print('run %i read.' % r)
25 |
26 | else:
27 | u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))
28 | v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))
29 | h = np.concatenate((h,np.load(runpath+'/h_sub.npy')))
30 | time = np.hstack((time,np.load(runpath+'/t_sub.npy')))
31 | print('run %i read.' % r)
32 |
33 | t = time / 3600. / 24. # in days
34 | ## read param
35 | global param
36 | param = np.load(runpath+'/param.npy').all()
37 | param['dat_type'] = np.float32
38 |
39 | # import functions
40 | exec(open(path+'swm_param.py').read())
41 | exec(open(path+'swm_operators.py').read())
42 | exec(open(path+'swm_output.py').read())
43 | param['output'] = 0
44 |
45 | set_grad_mat()
46 | set_interp_mat()
47 | set_lapl_mat()
48 | set_coriolis()
49 |
50 | tlen = len(time)
51 | ## create ouputfolder
52 | try:
53 | os.mkdir(runpath+'/analysis')
54 | except:
55 | pass
56 |
57 | ## reshape u,v
58 | u = u.reshape((tlen,param['Nu'])).T
59 | v = v.reshape((tlen,param['Nv'])).T
60 | h = h.reshape((tlen,param['NT'])).T
61 | print('Reshape done.')
62 |
63 | ## U,V,H mean
64 | uhm = (u * ITu.dot(h)).mean(axis=1) # temporal averages
65 | vhm = (v * ITv.dot(h)).mean(axis=1)
66 | print('uh,vh mean done.')
67 |
68 | ## STORING
69 | dic = dict()
70 | all_var2export = ['uhm','vhm']
71 |
72 | for v in all_var2export:
73 | exec('dic[v] ='+v)
74 |
75 | np.save(runpath+'/analysis/uh_vh_mean.npy',dic)
76 | print('Everything stored.')
--------------------------------------------------------------------------------
/docu/matvis/scripts/matvis.py:
--------------------------------------------------------------------------------
1 | ## PLOTTING OPERATOR MATRICES
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | import matplotlib.pyplot as plt
9 | from cmocean import cm
10 |
11 | # import functions
12 | exec(open(path+'swm_operators.py').read())
13 | exec(open(path+'swm_output.py').read())
14 | param = dict()
15 | param['output'] = 0
16 | param['dat_type'] = np.float32
17 |
18 | param['dx'] = 1
19 | param['dy'] = 1
20 | param['nx'] = 3
21 | param['ny'] = 3
22 | param['NT'] = param['nx']*param['ny']
23 | param['Nu'] = (param['nx']-1)*param['ny']
24 | param['Nv'] = (param['ny']-1)*param['nx']
25 | param['Nq'] = (param['nx']+1)*(param['ny']+1)
26 |
27 | set_grad_mat()
28 | set_interp_mat()
29 | set_lapl_mat()
30 | set_arakawa_mat()
31 |
32 | ##
33 |
34 | #mnames = ['GTx','GTy','Gux','Guy','Gvx','Gvy','Gqy','Gqx']
35 | #mnames = ['Lu','Lv','LT']
36 | mnames = ['IuT','ITu','IvT','ITv','Iuv','Ivu','ITq','IqT','Iqu','Iuq','Iqv','Ivq']
37 |
38 | for mname in mnames:
39 | exec('M = '+mname)
40 | levs = np.sort(np.array(list(set(M.data))))
41 | linlevs = np.arange(1,len(levs)+1)
42 |
43 | # replace data by linlevs
44 | idx = []
45 | for l in levs:
46 | idx.append(M.data == l)
47 |
48 | for i,r in zip(idx,range(len(idx))):
49 | M.data[i] = linlevs[r]
50 |
51 | M = M.todense()
52 | M = np.ma.masked_array(M,mask=(M == 0))
53 |
54 | aspectratio = M.shape[0]/M.shape[1]
55 |
56 | fig,ax = plt.subplots(1,1,figsize=(6,5*aspectratio))
57 |
58 | if len(levs) > 1:
59 | cmapd = cm.thermal.from_list('cmapd',plt.cm.jet(np.linspace(0,1,len(linlevs))),len(linlevs))
60 | else:
61 | cmapd = cm.thermal.from_list('cmapd',plt.cm.gray([0,1]),2)
62 |
63 |
64 | q = ax.matshow(M,cmap=cmapd,vmin=.5,vmax=linlevs.max()+.5)
65 | cbar = plt.colorbar(q,ax=ax,ticks=linlevs,drawedges=True)
66 | cbar.ax.set_yticklabels(levs)
67 | ax.set_xlabel(r'$\mathbf{'+mname[0]+'}^'+mname[2]+'_'+mname[1]+'$ for $n_x =$%i, $n_y =$%i' % (param['nx'],param['ny']),fontsize=20)
68 | plt.tight_layout()
69 | fig.savefig(path+'matvis/img/'+mname+'.png',dpi=150)
70 | plt.close(fig)
71 | #plt.show()
--------------------------------------------------------------------------------
/plot/mean_e_plot.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 |
3 | path = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
4 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
5 |
6 | import numpy as np
7 | import matplotlib.pyplot as plt
8 | from cmocean import cm
9 |
10 | plt.rcParams['mathtext.fontset'] = 'cm'
11 | plt.rcParams['mathtext.rm'] = 'serif'
12 |
13 | runfolders = [0,3,8]
14 |
15 | D = []
16 | p = []
17 |
18 | for r in runfolders:
19 | runpath = path+'run%04i' % r
20 | D.append(np.load(runpath+'/analysis/mean_e.npy').all()['em'])
21 | p.append(np.load(runpath+'/param.npy').all())
22 |
23 | ##
24 | expo = 1/3.
25 |
26 | for i in range(len(D)):
27 | D[i] = np.sign(D[i])*abs(D[i])**expo
28 |
29 | ## colormap
30 |
31 | thermal2 = cm.thermal.from_list('thermal2',np.vstack(([0.5,0.5,0.5,1],cm.thermal(np.arange(1,256)))))
32 |
33 |
34 | ## plotting
35 |
36 | levs = np.linspace(0,np.percentile(np.array(D),98),32)
37 |
38 | s = 1e3
39 |
40 | fig,axs = plt.subplots(1,len(D),sharex=True,sharey=True,figsize=(10,4.8))
41 | fig.tight_layout(rect=[0.03,.15,1,0.9])
42 | fig.subplots_adjust(wspace=0.03,hspace=0.03)
43 |
44 | pos = axs[0].get_position()
45 | pos2 = axs[-1].get_position()
46 | cax = fig.add_axes([pos.x0,0.1,pos2.x1-pos.x0,0.03])
47 |
48 | for i,(iD,ip) in enumerate(zip(D,p)):
49 | q = axs[i].contourf(ip['x_T']/s,ip['y_T']/s,iD,levs,extend='both',cmap=thermal2)
50 |
51 |
52 | axs[0].set_title('LR + weak backscatter')
53 | axs[1].set_title('LR + moderate backscatter')
54 | axs[2].set_title('LR + strong backscatter')
55 |
56 | tiks = np.array([0,0.005,0.05,.2,.5,1,1.8,2.4])
57 |
58 | cbar = fig.colorbar(q,cax=cax,orientation='horizontal',ticks=tiks**expo)
59 | cbar.set_label(r'[m$^3$s$^{-2}$]')
60 | cbar.set_ticklabels(tiks)
61 |
62 | axs[0].set_xticks([0,1000,2000,3000])
63 | axs[1].set_xticks([0,1000,2000,3000])
64 | axs[2].set_xticks([0,1000,2000,3000])
65 | axs[0].set_yticks([0,1000,2000,3000])
66 |
67 | axs[0].set_title('a',loc='left',fontweight='bold')
68 | axs[1].set_title('b',loc='left',fontweight='bold')
69 | axs[2].set_title('c',loc='left',fontweight='bold')
70 |
71 | axs[0].set_ylabel(r'$y$ [km]')
72 | axs[1].set_xlabel(r'$x$ [km]')
73 |
74 |
75 | plt.suptitle(r'Climatological mean subgrid-EKE $\overline{e}$',x=0.22)
76 |
77 | plt.savefig(outpath+'plots/e_mean.png',dpi=300)
78 | plt.close(fig)
--------------------------------------------------------------------------------
/docu/matvis/scripts/forc_vis.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 | from matplotlib import gridspec
4 |
5 | plt.rcParams['mathtext.fontset'] = 'cm'
6 | plt.rcParams['mathtext.rm'] = 'serif'
7 |
8 | param = dict()
9 |
10 | param['nx'] = 128 # number of grid points in x-direction
11 | param['ny'] = 128 # number of grid points in y-direction
12 |
13 | param['Lx'] = 3840e3 # basin width L [meters]
14 | param['Ly'] = 3840e3 # north-south basin extent [meters]
15 |
16 | param['dx'] = param['Lx'] / param['nx'] # grid spacing in x-direction
17 | param['dy'] = param['Ly'] / param['ny'] # grid spacing in y-direction
18 |
19 | param['x_T'] = np.arange(param['dx']/2.,param['Lx'],param['dx'])
20 | param['y_T'] = np.arange(param['dy']/2.,param['Ly'],param['dy'])
21 |
22 | # grid vectors for u-points
23 | param['x_u'] = param['x_T'][:-1] + param['dx']/2.
24 | param['y_u'] = param['y_T']
25 |
26 | Lx,Ly = param['Lx'],param['Ly'] # for convenience
27 | param['rho'] = 1e3 # density
28 |
29 | xx_u,yy_u = np.meshgrid(param['x_u'],param['y_u'])
30 |
31 | param['Fx0'] = 0.12 # was 0.12
32 | Fx = param['Fx0']*(np.cos(2*np.pi*(yy_u-Ly/2)/Ly) + 2*np.sin(np.pi*(yy_u - Ly/2)/Ly))
33 |
34 |
35 | fig = plt.figure(figsize=(6, 4.5))
36 | gs = gridspec.GridSpec(1, 2, width_ratios=[3, 1])
37 | ax0 = plt.subplot(gs[0])
38 | ax1 = plt.subplot(gs[1])
39 |
40 | s = 6
41 | ax0.quiver(xx_u[2::s,::s]/1e3,yy_u[2::s,::s]/1e3,Fx[2::s,::s],np.zeros_like(Fx)[2::s,::s], scale=6, headwidth=5)
42 |
43 | ax0.set_title('a',loc='left',fontweight='bold')
44 | ax0.set_title(r'$(F_x,F_y)$')
45 | ax0.set_xlabel(r'$x$ [km]')
46 | ax0.set_ylabel(r'$y$ [km]')
47 |
48 | ax0.set_xlim(0,Lx/1e3)
49 | ax0.set_ylim(0,Ly/1e3)
50 |
51 | ax0.scatter(300,1920,40,'C0',label='Point A')
52 | ax0.scatter(2880,1920,40,'C1',label='Point B')
53 |
54 | ax0.legend(loc=1)
55 |
56 | ax1.plot(Fx[:,0],param['y_u'],lw=1.5)
57 | ax1.plot(np.zeros_like(param['y_u']),param['y_u'],lw=0.5,alpha=0.5,color='k')
58 | ax1.set_title('b',loc='left',fontweight='bold')
59 | ax1.set_title(r'$\gamma(y)$')
60 | ax1.set_ylim(0,Ly)
61 | ax1.set_yticks([])
62 | ax1.set_xticks([-0.2,0,0.2])
63 | ax1.set_xticklabels([-0.2,0,0.2])
64 | ax1.set_xlabel('[Pa]')
65 |
66 |
67 |
68 |
69 | plt.tight_layout()
70 | plt.savefig('/home/mkloewer/Dropbox/thesis/Chapter1/Chapter1Figs/forcing.pdf')
--------------------------------------------------------------------------------
/calc/misc/pv_calc.py:
--------------------------------------------------------------------------------
1 | ## PRODUCE MEAN CALCULATIONS AND EXPORT AS .NPY
2 | # FOR POTENTIAL VORTICITY
3 | from __future__ import print_function
4 | path = '/home/mkloewer/python/swm/'
5 | import os; os.chdir(path) # change working directory
6 | import numpy as np
7 | from scipy import sparse
8 | import time as tictoc
9 | from netCDF4 import Dataset
10 | import glob
11 |
12 | # OPTIONS
13 | runfolder = [3]
14 | print('Calculating means from run ' + str(runfolder))
15 |
16 | ## read data
17 | for r,i in zip(runfolder,range(len(runfolder))):
18 | runpath = path+'data/run%04i' % r
19 |
20 | if i == 0:
21 | u = np.load(runpath+'/u_sub.npy')
22 | v = np.load(runpath+'/v_sub.npy')
23 | h = np.load(runpath+'/h_sub.npy')
24 | time = np.load(runpath+'/t_sub.npy')
25 | print('run %i read.' % r)
26 |
27 | else:
28 | u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))
29 | v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))
30 | h = np.concatenate((h,np.load(runpath+'/h_sub.npy')))
31 | time = np.hstack((time,np.load(runpath+'/t_sub.npy')))
32 | print('run %i read.' % r)
33 |
34 | t = time / 3600. / 24. # in days
35 | ## read param
36 | global param
37 | param = np.load(runpath+'/param.npy').all()
38 | param['dat_type'] = np.float32
39 |
40 | # import functions
41 | exec(open(path+'swm_param.py').read())
42 | exec(open(path+'swm_operators.py').read())
43 | exec(open(path+'swm_output.py').read())
44 | param['output'] = 0
45 |
46 | set_grad_mat()
47 | set_interp_mat()
48 | set_lapl_mat()
49 | set_coriolis()
50 |
51 | tlen = len(time)
52 | ## create ouputfolder
53 | try:
54 | os.mkdir(runpath+'/analysis')
55 | except:
56 | pass
57 |
58 | ## reshape u,v
59 | u = u.reshape((tlen,param['Nu'])).T
60 | v = v.reshape((tlen,param['Nv'])).T
61 | h = h.reshape((tlen,param['NT'])).T
62 | print('Reshape done.')
63 |
64 | h_q = ITq.dot(h+param['H'])
65 |
66 | ## POTENTIAL VORTICITY MEAN
67 | Z = (Gvx.dot(v) - Guy.dot(u))
68 | PVm = ((f_q + Z.T).T/h_q).mean(axis=1)
69 |
70 | ## LENGTH SCALE MEAN
71 | KE = .5*(IuT.dot((u.T - u.mean(axis=1)).T**2) + IvT.dot((v.T - v.mean(axis=1)).T**2))
72 | Lm = np.sqrt(KE/IqT.dot(Z**2))
73 |
74 | ## STORING
75 | dic = dict()
76 | all_var2export = ['PVm','Lm']
77 |
78 | for var in all_var2export:
79 | exec('dic[var] ='+var)
80 |
81 | np.save(runpath+'/analysis/PVm_Lm.npy',dic)
82 | print('Everything stored.')
--------------------------------------------------------------------------------
/calc/misc/pv_plot.py:
--------------------------------------------------------------------------------
1 | ## PLOT PV MEAN
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | from scipy.integrate import cumtrapz
8 | import matplotlib.pyplot as plt
9 | import time as tictoc
10 | from netCDF4 import Dataset
11 | import glob
12 | from cmocean import cm
13 |
14 | # OPTIONS
15 | runfolder = [3,10]
16 | print('Compare mean plots from run ' + str(runfolder))
17 |
18 | ## read data
19 |
20 | runpath1 = path+'data/run%04i' % runfolder[0]
21 | D1 = np.load(runpath1+'/analysis/PVm_Lm.npy').all()
22 | D11 = np.load(runpath1+'/analysis/mean.npy').all()
23 | param1 = np.load(runpath1+'/param.npy').all()
24 |
25 | runpath2 = path+'data/run%04i' % runfolder[1]
26 | D2 = np.load(runpath2+'/analysis/PVm_Lm.npy').all()
27 | D21 = np.load(runpath2+'/analysis/mean.npy').all()
28 | param2 = np.load(runpath2+'/param.npy').all()
29 |
30 | #runpath3 = path+'stoch/data/run%04i' % 7
31 | #D3 = np.load(runpath3+'/analysis/PVm_Lm.npy').all()
32 | #param3 = np.load(runpath3+'/param.npy').all()
33 |
34 | # import functions
35 | exec(open(path+'swm_param.py').read())
36 | exec(open(path+'swm_operators.py').read())
37 | exec(open(path+'swm_output.py').read())
38 | exec(open(path+'swm_rhs.py').read())
39 | param1['output'] = 0
40 | param2['output'] = 0
41 |
42 | ## Plotting
43 | fig,axs = plt.subplots(1,2,sharex=True,sharey=True,figsize=(6,4))
44 | fig.tight_layout(rect=[0,.13,1,0.95])
45 | fig.subplots_adjust(wspace=0.05,hspace=0.05)
46 |
47 | pos = axs[0].get_position()
48 | pos2 = axs[-1].get_position()
49 | cax = fig.add_axes([pos.x0,0.13,pos2.x1-pos.x0,0.03])
50 |
51 | s = 1e7 # scaling factor
52 |
53 | levs = np.linspace(np.percentile(D2['PVm'],1)*s,np.percentile(D2['PVm'],99)*s,32)
54 |
55 | global param
56 | for i,(D,p) in enumerate(zip([D1,D2],[param1,param2])):
57 | param = p
58 | q = axs[i].contourf(p['x_q'],p['y_q'],q2mat(D['PVm'])*1e7,levs,cmap=cm.thermal,extend='both')
59 |
60 | cbar = fig.colorbar(q,cax=cax,orientation='horizontal')
61 | cbar.set_label('Potential Vorticity [$m^{-1}s^{-1} \cdot$ 1e-7]')
62 | cbar.set_ticks([1,1.25,1.5,1.75,2])
63 | axs[0].set_xticks([0,p['Lx']])
64 | axs[0].set_yticks([0,p['Ly']])
65 |
66 | axs[0].set_xticklabels([0,r'$L_x$'])
67 | axs[0].set_yticklabels([0,r'$L_y$'])
68 |
69 | axs[0].set_xlim(0,param['Lx'])
70 | axs[0].set_ylim(0,param['Ly'])
71 |
72 | axs[0].set_title(r'Low resolution, $\Delta x = 30$km')
73 | axs[1].set_title(r'High resolution, $\Delta x = 7.5$km')
74 |
75 | plt.savefig(path+'compare/pv_mean.png',dpi=300)
76 | plt.close(fig)
--------------------------------------------------------------------------------
/calc/misc/tempautocorr.py:
--------------------------------------------------------------------------------
1 | ## COMPUTE AND PRODUCE TIMESCALE PLOTS
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | import matplotlib.pyplot as plt
7 | from netCDF4 import Dataset
8 |
9 | def acf(x,l):
10 | """ autocorrelation function of vector x up to lag l."""
11 | return np.array([1]+[np.corrcoef(x[:-i],x[i:])[0,1] for i in range(1,l)])
12 |
13 | def findc(x,a):
14 | """ find crossing of vector x with value a."""
15 | return np.argmin(abs(x-a))
16 |
17 | runfolders = [7,8,9,10]
18 |
19 | p1 = np.array([300,1920])*1e3
20 | p2 = np.array([2880,1920])*1e3
21 | pi = np.zeros((3,2,2),dtype=np.int) # (u,v,T) x (p1,p2) x (i,j)
22 |
23 | ## read data
24 | for r,i in zip(runfolders,range(len(runfolders))):
25 | runpath = path+'data/run%04i' % r
26 | param = np.load(runpath+'/param.npy').all()
27 |
28 | # find p1 and p2 indices
29 | for ig,g in enumerate(['u','v','T']):
30 | for ip,p in enumerate([p1,p2]):
31 | for ij,xy in enumerate(['x','y']):
32 | pi[ig,ip,ij] = findc(param[xy+'_'+g],p[ij])
33 |
34 | ncu = Dataset(runpath+'/u.nc')
35 | ncv = Dataset(runpath+'/v.nc')
36 | nch = Dataset(runpath+'/h.nc')
37 |
38 | istart = 0
39 |
40 | if i == 0:
41 | u = ncu.variables['u'][istart:,pi[0,:,0],pi[0,:,1]][:,[0,1],[0,1]]
42 | v = ncv.variables['v'][istart:,pi[1,:,0],pi[1,:,1]][:,[0,1],[0,1]]
43 | h = nch.variables['h'][istart:,pi[2,:,0],pi[2,:,1]][:,[0,1],[0,1]]
44 | t = nch.variables['t'][istart:]
45 |
46 | else:
47 | u = np.concatenate((u,ncu.variables['u'][1:,pi[0,:,0],pi[0,:,1]][:,[0,1],[0,1]]))
48 | v = np.concatenate((v,ncv.variables['v'][1:,pi[1,:,0],pi[1,:,1]][:,[0,1],[0,1]]))
49 | h = np.concatenate((h,nch.variables['h'][1:,pi[2,:,0],pi[2,:,1]][:,[0,1],[0,1]]))
50 | t = np.hstack((t,nch.variables['t'][1:]))
51 |
52 | ncu.close()
53 | ncv.close()
54 | nch.close()
55 |
56 | print('run %i read.' % r)
57 |
58 | ## computation
59 | l = 200 # in 1/4 days
60 |
61 | acfs = np.zeros((l,3,2))
62 | for iv,var in enumerate([u,v,h]):
63 | for ip in range(2):
64 | acfs[:,iv,ip] = acf(var[:,ip],l)
65 |
66 | dt = t[1]-t[0]
67 | time = np.arange(l)*dt/24/3600
68 |
69 | ## STORING
70 | dic = dict()
71 | all_var2export = ['time','acfs','p1','p2']
72 |
73 | for var in all_var2export:
74 | exec('dic[var] ='+var)
75 |
76 | np.save(runpath+'/analysis/acfs.npy',dic)
77 | print('Everything stored.')
78 |
--------------------------------------------------------------------------------
/calc/misc/tempautocorr_plot.py:
--------------------------------------------------------------------------------
1 | ## TEMPAUTOCORR PLOT
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | import matplotlib.pyplot as plt
7 | from scipy.integrate import cumtrapz
8 |
9 | ## read data
10 |
11 | runpath1 = path+'data/run%04i' % 3
12 | D1 = np.load(runpath1+'/analysis/acfs.npy').all()
13 | param1 = np.load(runpath1+'/param.npy').all()
14 |
15 | runpath2 = path+'data/run%04i' % 10
16 | D2 = np.load(runpath2+'/analysis/acfs.npy').all()
17 | param2 = np.load(runpath2+'/param.npy').all()
18 |
19 | runpath3 = path+'stoch/data/run%04i' % 13
20 | D3 = np.load(runpath3+'/analysis/acfs.npy').all()
21 | param3 = np.load(runpath3+'/param.npy').all()
22 |
23 | runpath4 = path+'stoch/data/run%04i' % 12
24 | D4 = np.load(runpath4+'/analysis/acfs.npy').all()
25 | param4 = np.load(runpath4+'/param.npy').all()
26 |
27 | runpath5 = path+'stoch/data/run%04i' % 14
28 | D5 = np.load(runpath5+'/analysis/acfs.npy').all()
29 | param5 = np.load(runpath5+'/param.npy').all()
30 |
31 | ## Plotting
32 |
33 | fig,axs = plt.subplots(2,3,sharex=True,sharey=True,figsize=(9,6))
34 | plt.tight_layout(rect=[0.05,.05,1,0.93])
35 | fig.subplots_adjust(wspace=0.05,hspace=0.26)
36 |
37 | for i in range(3):
38 | for j in range(2):
39 | axs[j,i].plot(D1['time'],D1['acfs'][:,i,j],'C0',label=r'Low resolution, $\Delta x = 30$km',lw=2)
40 | axs[j,i].plot(D2['time'],D2['acfs'][:,i,j],'C2',label=r'High resolution, $\Delta x = 7.5$km',lw=2)
41 | axs[j,i].plot(D3['time'],D3['acfs'][:,i,j],'C3',label=r'Low res. + backscatter, $n_{diss}$=%.2f' % param3['n_diss'],lw=1)
42 | axs[j,i].plot(D4['time'],D4['acfs'][:,i,j],'C1',label=r'Low res. + backscatter, $n_{diss}$=%.2f' % param4['n_diss'],lw=1)
43 | axs[j,i].plot(D5['time'],D5['acfs'][:,i,j],'C4',label=r'Low res. + backscatter, $n_{diss}$=%.2f' % param5['n_diss'],lw=1)
44 | axs[j,i].plot([0,50],[0,0],'C7',alpha=.5)
45 |
46 | axs[0,0].set_xlim(0,49)
47 | axs[0,0].set_ylim(-0.9,1)
48 |
49 | axs[1,1].legend(bbox_to_anchor=(-1, 1.02, 3., .102), loc=3, fontsize=9, ncol=3, mode="expand", borderaxespad=0.)
50 |
51 | axs[0,0].set_title(r'$u$')
52 | axs[0,1].set_title(r'$v$')
53 | axs[0,2].set_title(r'$h$')
54 |
55 | axs[1,0].set_xlabel('lag [days]')
56 | axs[1,1].set_xlabel('lag [days]')
57 | axs[1,2].set_xlabel('lag [days]')
58 |
59 | axs[0,0].set_ylabel('Point A (x=%ikm,y=%ikm)' % tuple(D1['p1']/1e3))
60 | axs[1,0].set_ylabel('Point B (x=%ikm,y=%ikm)' % tuple(D1['p2']/1e3))
61 |
62 | plt.suptitle('Autocorrelation function',x=0.53)
63 |
64 | plt.savefig(path+'compare/autocorrelation.png',dpi=150)
65 | plt.close(fig)
66 | #plt.show()
--------------------------------------------------------------------------------
/calc/misc/ReRo_hist_plot.py:
--------------------------------------------------------------------------------
1 | ## HISTOGRAM PLOTTING FOR REYNOLDS AND ROSSBY NUMBERS
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import matplotlib.pyplot as plt
8 | import time as tictoc
9 | from netCDF4 import Dataset
10 | import glob
11 | import matplotlib
12 |
13 | # OPTIONS
14 | runfolder = [3,10]
15 | print('Creating ReRo histogram plot from run '+str(runfolder))
16 |
17 | ## read data
18 | runpath = path+'data/run%04i' % runfolder[0]
19 | D1 = np.load(runpath+'/analysis/ReRo_hist.npy').all()
20 | D11 = np.load(runpath+'/analysis/mean.npy').all()
21 |
22 | runpath = path+'data/run%04i' % runfolder[1]
23 | D2 = np.load(runpath+'/analysis/ReRo_hist.npy').all()
24 | D21 = np.load(runpath+'/analysis/mean.npy').all()
25 |
26 | runpath = path+'stoch/data/run%04i' % 12
27 | D3 = np.load(runpath+'/analysis/ReRo_hist.npy').all()
28 | D31 = np.load(runpath+'/analysis/mean.npy').all()
29 |
30 | ## PLOT
31 | fig,ax1 = plt.subplots(1,1,figsize=(8,6))
32 |
33 | levs = np.array([12000,40000,106000])
34 |
35 | ax1.contour(D2['Re_mid'],D2['Ro_mid'],D2['ReRoH'].T,levs*16.,colors='C2',linewidths=np.linspace(1,5,3),alpha=0.8)
36 | ax1.contour(D1['Re_mid'],D1['Ro_mid'],D1['ReRoH'].T,levs,colors='C0',linewidths=np.linspace(1,5,3),alpha=0.8)
37 | ax1.contour(D3['Re_mid'],D3['Ro_mid'],D3['ReRoH'].T,levs,colors='C1',linewidths=np.linspace(1,5,3),alpha=0.8)
38 |
39 | maxij = [0,]*3
40 | maxij[0] = np.unravel_index(np.argmax(D1['ReRoH']),(200,200))
41 | maxij[1] = np.unravel_index(np.argmax(D2['ReRoH']),(200,200))
42 | maxij[2] = np.unravel_index(np.argmax(D3['ReRoH']),(200,200))
43 |
44 | Remaxs = [D['Re_mid'][ij[0]] for D,ij in zip([D1,D2,D3],maxij)]
45 | Romaxs = [D['Ro_mid'][ij[1]] for D,ij in zip([D1,D2,D3],maxij)]
46 |
47 | Remeans = [np.log10(D['Rem'].mean()) for D in [D11,D21,D31]]
48 | Romeans = [np.log10(D['Rom'].mean()) for D in [D11,D21,D31]]
49 |
50 | ax1.scatter(Remaxs,Romaxs,80,c=['C0','C2','C1'],edgecolors='k',zorder=2,label='mode')
51 | ax1.scatter(Remeans,Romeans,80,c=['C0','C2','C1'],edgecolors='k',zorder=2,label='mean',marker='v')
52 |
53 | # for legend
54 | ax1.plot([0,0],[0,0],'C2',label=r'High resolution, $\Delta x = 7.5$km')
55 | ax1.plot([0,0],[0,0],'C0',label=r'Low resolution, $\Delta x = 30$km')
56 | ax1.plot([0,0],[0,0],'C1',label=r'Low resolution + backscatter')
57 |
58 | ax1.legend(loc=4,scatterpoints=3)
59 |
60 | ax1.set_xlim(0,4)
61 | ax1.set_ylim(-3,0)
62 | ax1.set_xlabel(r'$\log_{10}(Re)$')
63 | ax1.set_ylabel(r'$\log_{10}(Ro)$')
64 | ax1.set_title('2D Histogram of Reynolds and Rossby number')
65 |
66 | plt.tight_layout()
67 | plt.savefig(path+'compare/ReRo_2dhist.png')
68 | plt.close(fig)
--------------------------------------------------------------------------------
/calc/Ro_hist_calc.py:
--------------------------------------------------------------------------------
1 | ## HISTOGRAM COMPUTATIONS FOR REYNOLDS AND ROSSBY NUMBERS
2 | from __future__ import print_function
3 |
4 | # path
5 | import os
6 | #path = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/'
7 | path = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
8 | os.chdir(path) # change working directory
9 |
10 | # import functions
11 | funpath = '/network/home/aopp/kloewer/git/swm/'
12 | exec(open(funpath+'swm_param.py').read())
13 | exec(open(funpath+'swm_operators.py').read())
14 |
15 | import numpy as np
16 | from scipy import sparse
17 |
18 | # OPTIONS
19 | runfolder = [5]
20 | print('Calculating Rossby histograms from run ' + str(runfolder))
21 |
22 | RoH = []
23 | Ro_mean = []
24 | Ro_median = []
25 |
26 | ## read data - calculate each run separately
27 | for r,i in zip(runfolder,range(len(runfolder))):
28 | runpath = path+'run%04i' % r
29 |
30 | if i == 0:
31 | skip = 5*365
32 | else:
33 | skip = 0
34 |
35 | u = np.load(runpath+'/u_sub.npy')[skip:,...]
36 | v = np.load(runpath+'/v_sub.npy')[skip:,...]
37 | #eta = np.load(runpath+'/eta_sub.npy')[skip:,...]
38 | t = np.load(runpath+'/t_sub.npy')[skip:,...]
39 | print('run %i read.' % r)
40 |
41 | ## read param
42 | global param
43 | param = np.load(runpath+'/param.npy').all()
44 |
45 | set_grad_mat()
46 | set_interp_mat()
47 | set_coriolis()
48 |
49 | tlen = len(t)
50 | ## create ouputfolder
51 | try:
52 | os.mkdir(runpath+'/analysis')
53 | except:
54 | pass
55 |
56 | ## reshape u,v
57 | u = u.reshape((tlen,param['Nu'])).T
58 | v = v.reshape((tlen,param['Nv'])).T
59 | print('Reshape done.')
60 |
61 | ## COMPUTE ROSSBY VIA DEFORMATION RATE
62 |
63 | # Deformation rate / coriolis parameter
64 | Ro = (np.sqrt((Gux.dot(u) - Gvy.dot(v))**2 + IqT.dot((Guy.dot(u) + Gvx.dot(v))**2)).T / f_T).flatten()
65 | print('Ro computed.')
66 |
67 | Ro_mean.append(Ro.mean())
68 | Ro_median.append(np.median(Ro))
69 | Ro = np.log10(Ro)
70 |
71 | # histogram
72 | Ro_min = -5. # in log scale
73 | Ro_max = 0.5
74 | N = 300
75 |
76 | RoH_temp,Ro_edges = np.histogram(Ro,np.linspace(Ro_min,Ro_max,N))
77 | print('Ro histogram done.')
78 | del Ro
79 |
80 | # store each run in a list
81 | RoH.append(RoH_temp)
82 |
83 | Ro_mid = Ro_edges[:-1] + np.diff(Ro_edges)/2.
84 |
85 |
86 | RoH = np.array(RoH).sum(axis=0)
87 | Ro_mean = np.array(Ro_mean).mean()
88 | Ro_median = np.median(np.array(Ro_median)) #actually median of medians though...
89 |
90 | ## STORING in last
91 | dic = dict()
92 | all_var2export = ['RoH','Ro_mid','Ro_edges','Ro_mean','Ro_median']
93 |
94 | for vars in all_var2export:
95 | exec('dic[vars] ='+vars)
96 |
97 | np.save(runpath+'/analysis/Ro_defo_hist.npy',dic)
98 |
--------------------------------------------------------------------------------
/calc/misc/cospec_calc.py:
--------------------------------------------------------------------------------
1 | ## COMPUTE COSPEC
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 | import glob
10 | import matplotlib.pyplot as plt
11 |
12 | # OPTIONS
13 | runfolder = [2,3]
14 | print('Calculating cospecs from run ' + str(runfolder))
15 |
16 | def cospec(A,dx,dt):
17 | """ assumed shape of A is time x space. """
18 | nt,nx = np.shape(A)
19 |
20 | f = np.fft.fftfreq(nt,dt)
21 | k = np.fft.fftfreq(nx,dx)
22 |
23 | idxf = int(np.ceil(nt/2.)) # index of maximum positive frequency
24 | idxk = int(np.ceil(nx/2.)) # index of maximum positive wavenumber
25 |
26 | # 2D FFT
27 | p = abs(np.fft.fft2(A))**2
28 |
29 | f = f[1:idxf] # kill 0 and negative frequencies
30 | # reorder to have -kmax to +kmax
31 | k = np.hstack((k[idxk:],k[1:idxk]))
32 | # apply also for p
33 | p = np.hstack((p[1:idxf,idxk:],p[1:idxf,1:idxk]))[:,::-1]
34 |
35 | #TODO issue: p_max is shifted by -1 in positive k-direction
36 | return f,k,p
37 |
38 | ## read data
39 | for r,i in zip(runfolder,range(len(runfolder))):
40 | runpath = path+'data/run%04i' % r
41 |
42 | if i == 0:
43 | u = np.load(runpath+'/u_sub.npy')
44 | v = np.load(runpath+'/v_sub.npy')
45 | #h = np.load(runpath+'/h_sub.npy')
46 | time = np.load(runpath+'/t_sub.npy')
47 | print('run %i read.' % r)
48 |
49 | else:
50 | u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))
51 | v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))
52 | #h = np.concatenate((h,np.load(runpath+'/h_sub.npy')))
53 | time = np.hstack((time,np.load(runpath+'/t_sub.npy')))
54 | print('run %i read.' % r)
55 |
56 | t = time / 3600. / 24. # in days
57 | dt = time[1] - time[0]
58 |
59 | ## read param
60 | global param
61 | param = np.load(runpath+'/param.npy').all()
62 |
63 | # import functions
64 | exec(open(path+'swm_param.py').read())
65 | exec(open(path+'swm_operators.py').read())
66 | exec(open(path+'swm_output.py').read())
67 | param['output'] = 0
68 |
69 | set_grad_mat()
70 | set_interp_mat()
71 | set_lapl_mat()
72 | set_coriolis()
73 |
74 | tlen = len(time)
75 |
76 | ##
77 | p_all = []
78 |
79 | lats = range(10,125,5)
80 | lats = [64]
81 | #lons = [64]
82 | for lat in lats:
83 | #for lon in lons:
84 | #f,k,p = cospec(u[:,:,lon],param['dy'],dt)
85 | f,k,pu = cospec(u[:,lat,:],param['dx'],dt)
86 | f,k,pv = cospec(v[:,lat,:-1],param['dx'],dt)
87 |
88 | p_all.append(pu+pv)
89 | print(lat)
90 | #print(lon)
91 |
92 | p = np.array(p_all).mean(axis=0)
93 |
94 | ##
95 |
96 | dic = dict()
97 | all_var2export = ['f','k','p']
98 |
99 | for v in all_var2export:
100 | exec('dic[v] ='+v)
101 |
102 | np.save(runpath+'/analysis/cospec_eke_1lat.npy',dic)
103 | print('Everything stored.')
--------------------------------------------------------------------------------
/docu/matvis/scripts/grid_vis_rel.py:
--------------------------------------------------------------------------------
1 | ## Visualize Arakawa C-grid numbering
2 | import numpy as np
3 | import matplotlib.pyplot as plt
4 | import matplotlib as mpl
5 |
6 | mpl.rcParams['mathtext.fontset'] = 'cm'
7 | mpl.rcParams['mathtext.rm'] = 'serif'
8 |
9 |
10 | nx = 3
11 | ny = 3
12 |
13 | Lx = nx
14 | Ly = ny
15 |
16 | dx = Lx/nx
17 | dy = Ly/ny
18 |
19 | # grid vectors for T-points
20 | x_T = np.arange(dx/2.,Lx,dx)
21 | y_T = np.arange(dy/2.,Ly,dy)
22 |
23 | # grid vectors for u-points
24 | x_u = x_T[:-1] + dx/2.
25 | y_u = y_T
26 |
27 | #grid vectors for v-points
28 | x_v = x_T
29 | y_v = y_T[:-1] + dy/2.
30 |
31 | # grid vectors for q-points
32 | x_q = np.arange(0,Lx+dx/2.,dx)
33 | y_q = np.arange(0,Ly+dy/2.,dy)
34 |
35 | ## meshgrid
36 |
37 | xx_T,yy_T = np.meshgrid(x_T,y_T)
38 | xx_u,yy_u = np.meshgrid(x_u,y_u)
39 | xx_v,yy_v = np.meshgrid(x_v,y_v)
40 | xx_q,yy_q = np.meshgrid(x_q,y_q)
41 |
42 | xx_T = xx_T.flatten()
43 | xx_u = xx_u.flatten()
44 | xx_v = xx_v.flatten()
45 | xx_q = xx_q.flatten()
46 |
47 | yy_T = yy_T.flatten()
48 | yy_u = yy_u.flatten()
49 | yy_v = yy_v.flatten()
50 | yy_q = yy_q.flatten()
51 |
52 | fig,ax = plt.subplots(1,1,figsize=(3,3))
53 |
54 | ax.plot(xx_T,yy_T,'r.',ms=10,mec='k')
55 | ax.plot(xx_u,yy_u,'g.',ms=10,mec='k')
56 | ax.plot(xx_v,yy_v,'b.',ms=10,mec='k')
57 | ax.plot(xx_q,yy_q,'k.',ms=10)
58 |
59 | ax.plot(x_v,[0]*nx,'b.',ms=10,alpha=.6)
60 | ax.plot(x_v,[Ly]*nx,'b.',ms=10,alpha=.6)
61 | ax.plot([0]*ny,y_u,'g.',ms=10,alpha=.6)
62 | ax.plot([Lx]*ny,y_u,'g.',ms=10,alpha=.6)
63 |
64 |
65 | plt.grid()
66 |
67 | #for xx,yy,vv in zip([xx_T,xx_u,xx_v,xx_q],[yy_T,yy_u,yy_v,yy_q],['T','u','v','q']):
68 | # for i in range(len(xx)):
69 | # ax.text(xx[i]+0.03,yy[i]+0.03,r'$'+vv+'_{%i}$' %(i+1),fontsize=15)
70 |
71 | s = 0.02
72 |
73 | ax.text(xx_T[4]+s,yy_T[4]+s,r'$T$',fontsize=15)
74 | ax.text(xx_u[3]+s,yy_u[3]+s,r'$u^\rightarrow$',fontsize=15)
75 | ax.text(xx_u[2]+s,yy_u[2]+s,r'$u^\leftarrow$',fontsize=15)
76 |
77 | ax.text(xx_v[4]+s,yy_v[4]+s,r'$v^\uparrow$',fontsize=15)
78 | ax.text(xx_v[1]+s,yy_v[1]+s,r'$v^\downarrow$',fontsize=15)
79 |
80 | ax.text(xx_q[5]+s,yy_q[5]+s,r'$q^\swarrow$',fontsize=15)
81 | ax.text(xx_q[6]+s,yy_q[6]+s,r'$q^\searrow$',fontsize=15)
82 |
83 | ax.text(xx_q[9]+s,yy_q[9]+s,r'$q^\nwarrow$',fontsize=15)
84 | ax.text(xx_q[10]+s,yy_q[10]+s,r'$q^\nearrow$',fontsize=15)
85 |
86 | ax.set_xlabel(r'$\Delta x$',size=15)
87 | ax.set_ylabel(r'$\Delta y$',size=15)
88 |
89 | ax.set_xticks(range(Lx+1))
90 | ax.set_yticks(range(Ly+1))
91 |
92 | ax.set_xlim(0.8,2.2)
93 | ax.set_ylim(0.8,2.2)
94 |
95 | ax.set_frame_on(False)
96 |
97 | #dxstring = [(r'$%i\Delta x$' % i) if i > 1 else r'$\Delta x$' for i in range(1,nx)]
98 | #dystring = [(r'$%i\Delta y$' % i) if i > 1 else r'$\Delta y$' for i in range(1,ny)]
99 |
100 | #ax.set_xticklabels([r'$0$']+dxstring+[r'$L_x$'])
101 | #ax.set_yticklabels([r'$0$']+dystring+[r'$L_y$'])
102 | ax.set_xticklabels([])
103 | ax.set_yticklabels([])
104 | plt.tight_layout()
105 | fig.savefig(path+'matvis/relative_nodes.png',dpi=150)
106 | plt.close(fig)
--------------------------------------------------------------------------------
/calc/misc/Re_hist_plot.py:
--------------------------------------------------------------------------------
1 | ## HISTOGRAM PLOTTING FOR REYNOLDS AND ROSSBY NUMBERS
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import matplotlib.pyplot as plt
8 | import time as tictoc
9 | from netCDF4 import Dataset
10 | import glob
11 | import matplotlib
12 |
13 | plt.rcParams['mathtext.fontset'] = 'cm'
14 | plt.rcParams['mathtext.rm'] = 'serif'
15 |
16 | # OPTIONS
17 | # runfolder = [0,6,10,14,15]
18 | # print('Creating ReRo histogram plot from run '+str(runfolder))
19 | #
20 | # # read data
21 | # runpath = path+'data/run%04i' % runfolder[0]
22 | # D1 = np.load(runpath+'/analysis/Re_hist.npy').all()
23 | #
24 | # runpath = path+'data/run%04i' % runfolder[1]
25 | # D2 = np.load(runpath+'/analysis/Re_hist.npy').all()
26 | #
27 | # runpath = path+'data/run%04i' % runfolder[2]
28 | # D3 = np.load(runpath+'/analysis/Re_hist.npy').all()
29 | #
30 | # runpath = path+'data/run%04i' % runfolder[3]
31 | # D4 = np.load(runpath+'/analysis/Re_hist.npy').all()
32 | #
33 | # runpath = path+'data/run%04i' % runfolder[4]
34 | # D5 = np.load(runpath+'/analysis/Re_hist.npy').all()
35 |
36 |
37 | # OPTIONS
38 | runfolder = [3,10,13,12,14]
39 | print('Creating ReRo histogram plot from run '+str(runfolder))
40 |
41 | ## read data
42 | runpath = path+'data/newold/run%04i' % runfolder[0]
43 | D1 = np.load(runpath+'/analysis/Re_hist.npy').all()
44 |
45 | runpath = path+'data/newold/run%04i' % runfolder[1]
46 | D2 = np.load(runpath+'/analysis/Re_hist.npy').all()
47 |
48 | runpath = path+'stoch/data/run%04i' % runfolder[2]
49 | D3 = np.load(runpath+'/analysis/Re_hist.npy').all()
50 |
51 | runpath = path+'stoch/data/run%04i' % runfolder[3]
52 | D4 = np.load(runpath+'/analysis/Re_hist.npy').all()
53 |
54 | runpath = path+'stoch/data/run%04i' % runfolder[4]
55 | D5 = np.load(runpath+'/analysis/Re_hist.npy').all()
56 |
57 | ## PLOT
58 | fig,ax1 = plt.subplots(1,1,figsize=(8,6))
59 |
60 | ax1.plot(D1['Re_mid'],D1['ReH'],'C0',label=r'Low resolution, $\Delta x = $30km',lw=3)
61 | ax1.plot(D2['Re_mid'],D2['ReH']/16,'C2',label=r'High resolution, $\Delta x = $7.5km',lw=3)
62 | ax1.plot(D3['Re_mid'],D3['ReH'],'C3',label=r'LR + weak backscatter',ls='--')
63 | ax1.plot(D4['Re_mid'],D4['ReH'],'C1',label=r'LR + moderate backscatter',ls='--')
64 | ax1.plot(D5['Re_mid'],D5['ReH'],'C5',label=r'LR + strong backscatter',ls='--')
65 |
66 | ax1.axvline(np.log10(D1['Re_mean']),c='C0',ls='-',lw=2)
67 | ax1.axvline(np.log10(D2['Re_mean']),c='C2',ls='-',lw=2)
68 | ax1.axvline(np.log10(D3['Re_mean']),c='C3',ls='--')
69 | ax1.axvline(np.log10(D4['Re_mean']),c='C1',ls='--')
70 | ax1.axvline(np.log10(D5['Re_mean']),c='C5',ls='--')
71 |
72 | ax1.text(np.log10(D1['Re_mean']),5e5,'mean($R_e$)',rotation=90,ha='right',color='k')
73 |
74 | #ax1.set_yscale('log')
75 |
76 | ax1.legend(loc=2)
77 |
78 | ax1.set_xlim(-3,5)
79 | ax1.set_ylim(1,3e6)
80 |
81 | ax1.set_title('Reynolds number histogram',loc='left')
82 | ax1.set_xlabel('log$_{10}(R_e)$')
83 | ax1.set_ylabel(r'$N$')
84 |
85 | plt.tight_layout()
86 | plt.savefig(path+'compare/Re_hist_nobf.png')
87 | plt.close(fig)
--------------------------------------------------------------------------------
/swm_integration.py:
--------------------------------------------------------------------------------
1 | ## TIME INTEGRATION
2 | def time_integration(u,v,eta):
3 |
4 | tic = tictoc.time() # measure time
5 | global dt
6 | dt = param['dt'] # for convenience
7 | t = param['t0'] # initial time
8 | feedback_ini(u,v,eta,t) # output
9 |
10 | ## RUNGE KUTTA 4th ORDER
11 | rk_a = np.array([1/6.,1/3.,1/3.,1/6.])
12 | rk_b = np.array([0.5,0.5,1.])
13 |
14 | # can't trigger deep copy through [:] use .copy() instead
15 | u0,v0,eta0 = u.copy(),v.copy(),eta.copy()
16 | u1,v1,eta1 = u.copy(),v.copy(),eta.copy()
17 |
18 | global i # iteration index
19 | for i in range(param['Nt']):
20 |
21 | # trigger deep copy through [:]
22 | u1[:],v1[:],eta1[:] = u,v,eta
23 |
24 | for rki in range(4):
25 | du,dv,deta = rhs(u1,v1,eta1)
26 |
27 | if rki < 3: # RHS update for the next RK-step
28 | u1 = u + rk_b[rki]*dt*du
29 | v1 = v + rk_b[rki]*dt*dv
30 | eta1 = eta + rk_b[rki]*dt*deta
31 |
32 | # Summing all the RHS on the go
33 | u0 += rk_a[rki]*dt*du
34 | v0 += rk_a[rki]*dt*dv
35 | eta0 += rk_a[rki]*dt*deta
36 |
37 | # deep copy through [:]
38 | u[:],v[:],eta[:] = u0,v0,eta0
39 |
40 | t += dt
41 | feedback(u,v,eta,t,tic)
42 |
43 | print(('Integration done in '+readable_secs(tictoc.time() - tic)+' on '+tictoc.asctime()))
44 | output_txt(('\nTime integration done in '+readable_secs(tictoc.time() - tic)+' on '+tictoc.asctime()))
45 |
46 | # finalising output
47 | if param['output']:
48 | output_nc_fin() # finalise nc file
49 | output_txt_fin() # finalise info txt file
50 |
51 | return u,v,eta
52 |
53 | ## FEEDBACK ON INTEGRATION
54 | def feedback_ini(u,v,eta,t):
55 | if param['output']:
56 | output_nc_ini()
57 | output_nc(u,v,eta,t) # store initial conditions
58 | output_param() # store the param dictionnary
59 |
60 | # Store information in txt file
61 | output_txt('Integrating %.1f days with dt=%.2f min in %i time steps' % (param['Ndays'],dt/60.,param['Nt']))
62 | output_txt('Time integration scheme is '+param['scheme']+' with CFL = %.2f' % param['cfl'])
63 | output_txt('')
64 | output_txt('Starting shallow water model on '+tictoc.asctime())
65 | print(('Starting shallow water model run %i on ' % param['run_id'])+tictoc.asctime())
66 | else:
67 | print('Starting shallow water model on '+tictoc.asctime())
68 |
69 | def feedback(u,v,eta,t,tic):
70 | if (i+1) % param['output_n'] == 0:
71 | if param['output']: # storing u,v,h as netCDF4
72 | output_nc(u,v,eta,t)
73 |
74 | # feedback on progress every 5% step.
75 | if ((i+1)/param['Nt']*100 % 5) < (i/param['Nt']*100 % 5):
76 | progress = str(int((i+1)/param['Nt']*100.))+'%'
77 | print(progress, end='\r')
78 | if i > 100:
79 | output_txt(progress,'\n')
80 |
81 | if i == 100:
82 | # estimate total time for integration after 100 time steps.
83 | duration_est(tic)
84 |
--------------------------------------------------------------------------------
/calc/misc/trispec_calc.py:
--------------------------------------------------------------------------------
1 | ## COMPUTE TRISPEC
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 | import glob
10 | import matplotlib.pyplot as plt
11 |
12 | # OPTIONS
13 | runfolder = [3]
14 | print('Calculating 3D spectrogramms from run ' + str(runfolder))
15 |
16 | ##
17 | def trispec(a,dt,dx,dy):
18 | """ Computes a wavenumber-frequency plot for 3D (t,x,y) data via radial (k = sqrt(kx**2 + ky**2)) integration. TODO: correct normalisation, so that the integral in normal space corresponds to the integral in Fourier space.
19 | """
20 |
21 | nt,ny,nx = np.shape(a)
22 | kx = (1/(dx))*np.hstack((np.arange(0,(nx+1)/2.),np.arange(-nx/2.+1,0)))/float(nx)
23 | ky = (1/(dy))*np.hstack((np.arange(0,(ny+1)/2.),np.arange(-ny/2.+1,0)))/float(ny)
24 | f = (1/(dt))*np.hstack((np.arange(0,(nt+1)/2.),np.arange(-nt/2.+1,0)))/float(nt)
25 |
26 | kxx,kyy = np.meshgrid(kx,ky)
27 | # radial distance from kx,ky = 0
28 | kk = np.sqrt(kxx**2 + kyy**2)
29 |
30 | if nx >= ny: #kill negative wavenumbers
31 | k = kx[:int(nx/2)+1]
32 | else:
33 | k = ky[:int(ny/2)+1]
34 |
35 | f = f[:int(nt/2)+1] #kill negative frequencies
36 | dk = k[1] - k[0]
37 |
38 | # create radial coordinates, associated with k[i]
39 | # nearest point interpolation to get points within the -.5,.5 annulus
40 | rcoords = []
41 | for i in range(len(k)):
42 | rcoords.append(np.where((kk>(k[i]-.5*dk))*(kk<=(k[i]+.5*dk))))
43 |
44 | # 3D FFT
45 | p = np.fft.fftn(a)
46 | p = np.real(p * np.conj(p))
47 |
48 | # mulitply by dk to have the corresponding integral
49 | spec = np.zeros((len(f),len(k)))
50 | for i in range(len(k)):
51 | spec[:,i] = np.sum(p[:int(nt/2)+1,rcoords[i][0],rcoords[i][1]],axis=1)*dk
52 |
53 | return k[1:],f[1:],spec[1:,1:] # eliminate zero frequency and zero wavenumber
54 |
55 | ## read data
56 | for r,i in zip(runfolder,range(len(runfolder))):
57 | runpath = path+'data/run%04i' % r
58 |
59 | if i == 0:
60 | #u = np.load(runpath+'/u_sub.npy')
61 | #v = np.load(runpath+'/v_sub.npy')
62 | h = np.load(runpath+'/h_sub.npy')
63 | time = np.load(runpath+'/t_sub.npy')
64 | print('run %i read.' % r)
65 |
66 | else:
67 | #u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))
68 | #v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))
69 | h = np.concatenate((h,np.load(runpath+'/h_sub.npy')))
70 | time = np.hstack((time,np.load(runpath+'/t_sub.npy')))
71 | print('run %i read.' % r)
72 |
73 | t = time / 3600. / 24. # in days
74 | tlen = len(time)
75 | dt = time[1] - time[0]
76 |
77 | ## read param
78 | global param
79 | param = np.load(runpath+'/param.npy').all()
80 |
81 | ##
82 | k,f,p = trispec(h,dt,param['dx'],param['dy'])
83 |
84 | ##
85 | dic = dict()
86 | all_var2export = ['f','k','p']
87 |
88 | for v in all_var2export:
89 | exec('dic[v] ='+v)
90 |
91 | np.save(runpath+'/analysis/trispec_h.npy',dic)
92 | print('Everything stored.')
--------------------------------------------------------------------------------
/plot/spec_plot.py:
--------------------------------------------------------------------------------
1 | ## EKE SPEC PLOT
2 | from __future__ import print_function
3 |
4 | path1 = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
5 | path2 = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/data/'
6 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
7 |
8 | import os; os.chdir(path2) # change working directory
9 | import numpy as np
10 | from scipy import sparse
11 | import time as tictoc
12 | from netCDF4 import Dataset
13 | import glob
14 | import matplotlib.pyplot as plt
15 | from cmocean import cm
16 |
17 | plt.rcParams['mathtext.fontset'] = 'cm'
18 | plt.rcParams['mathtext.rm'] = 'serif'
19 |
20 | # OPTIONS
21 | runfolder = [0,6,0,3,8]
22 | print('Compare ek spec plots from run ' + str(runfolder))
23 |
24 | runpath1 = path2+'run%04i' % runfolder[0]
25 | D1 = np.load(runpath1+'/analysis/spec_eke.npy').all()
26 | param1 = np.load(runpath1+'/param.npy').all()
27 |
28 | runpath2 = path2+'run%04i' % runfolder[1]
29 | D2 = np.load(runpath2+'/analysis/spec_eke.npy').all()
30 | param2 = np.load(runpath2+'/param.npy').all()
31 |
32 | runpath3 = path1+'run%04i' % runfolder[2]
33 | D3 = np.load(runpath3+'/analysis/spec_eke.npy').all()
34 | param3 = np.load(runpath3+'/param.npy').all()
35 |
36 | runpath4 = path1+'run%04i' % runfolder[3]
37 | D4 = np.load(runpath4+'/analysis/spec_eke.npy').all()
38 | param4 = np.load(runpath4+'/param.npy').all()
39 |
40 | runpath5 = path1+'run%04i' % runfolder[4]
41 | D5 = np.load(runpath5+'/analysis/spec_eke.npy').all()
42 | param5 = np.load(runpath5+'/param.npy').all()
43 |
44 | Ro_max = param1['c_phase']/(param1['f_0'] - param1['beta']*param1['Ly']/2.)
45 | Ro_min = param1['c_phase']/(param1['f_0'] + param1['beta']*param1['Ly']/2.)
46 |
47 | ## PLOTTING
48 |
49 | kf = 1e3
50 |
51 | fig,ax = plt.subplots(1,1,figsize=(7,5))
52 |
53 | ax.loglog(D1['k']*kf,D1['p']/(2*np.pi),'C0',label=r'Low resolution $\Delta x = $30km',lw=2)
54 | ax.loglog(D2['k']*kf,D2['p']/(2*np.pi),'C2',label=r'High resolution $\Delta x = $7.5km',lw=2)
55 | ax.loglog(D3['k']*kf,D3['p']/(2*np.pi),'C1',label=r'LR + weak backscatter',ls='--')
56 | ax.loglog(D4['k']*kf,D4['p']/(2*np.pi),'C3',label=r'LR + moderate backscatter',ls='--')
57 | ax.loglog(D5['k']*kf,D5['p']/(2*np.pi),'C5',label=r'LR + strong backscatter',ls='--')
58 |
59 | ylim = ax.get_ylim()
60 |
61 | ax.loglog(kf/Ro_max*np.ones(2),ylim,'k',lw=0.5)
62 | ax.loglog(kf/Ro_min*np.ones(2),ylim,'k',lw=0.5)
63 |
64 | ax.text(1/1900,5e-1,'$L_{Ro}^{max}$',rotation=90,fontsize=12)
65 | ax.text(1/590,5e-1,'$L_{Ro}^{min}$',rotation=90,fontsize=12)
66 |
67 | k1 = D1['k'][7]*kf
68 | k2 = D1['k'][-1]*kf
69 |
70 | s = 2e-4
71 | ax.loglog([k1,k2],[s*k1**(-3),s*k2**(-3)],'C4',label=r'$K^{-3}$')
72 |
73 | xtick = np.array([4000,2000,1000,500,200,100,50,20,10])
74 | xtickm = np.array([3000,900,800,700,600,400,300,90,80,70,60,40,30])
75 | ax.set_xticks(1./xtick)
76 | ax.set_xticks(1./xtickm,minor=True)
77 | ax.set_xticklabels([],minor=True)
78 | ax.set_xticklabels(xtick)
79 |
80 | ax.set_xlim(D1['k'][1]*kf,1./xtick[-1])
81 | ax.set_ylim(*ylim)
82 |
83 | ax.set_xticklabels(ax.xaxis.get_majorticklabels(), rotation=90)
84 |
85 | ax.set_ylabel('EKE [m$^3$s$^{-2}$]')
86 | ax.set_xlabel('wavelength [km]')
87 |
88 | ax.legend(loc=1)
89 | ax.set_title('Eddy kinetic energy spectrum',loc='left')
90 |
91 | plt.tight_layout()
92 | plt.savefig(outpath+'plots/spec_eke.eps')
93 | plt.close(fig)
--------------------------------------------------------------------------------
/calc/misc/ReRo_hist.py:
--------------------------------------------------------------------------------
1 | ## HISTOGRAM COMPUTATIONS FOR REYNOLDS AND ROSSBY NUMBERS
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 | import glob
10 |
11 | # OPTIONS
12 | runfolder = [12]
13 | print('Calculating histograms from run ' + str(runfolder))
14 |
15 | ## read data
16 | for r,i in zip(runfolder,range(len(runfolder))):
17 | runpath = path+'stoch/data/run%04i' % r
18 |
19 | if i == 0:
20 | u = np.load(runpath+'/u_sub.npy')[10*365:,:,:]
21 | v = np.load(runpath+'/v_sub.npy')[10*365:,:,:]
22 | h = np.load(runpath+'/h_sub.npy')[10*365:,:,:]
23 | time = np.load(runpath+'/t_sub.npy')[10*365:]
24 | print('run %i read.' % r)
25 |
26 | else:
27 | u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))
28 | v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))
29 | h = np.concatenate((h,np.load(runpath+'/h_sub.npy')))
30 | time = np.hstack((time,np.load(runpath+'/t_sub.npy')))
31 | print('run %i read.' % r)
32 |
33 | t = time / 3600. / 24. # in days
34 | ## read param
35 | global param
36 | param = np.load(runpath+'/param.npy').all()
37 |
38 | # import functions
39 | exec(open(path+'swm_param.py').read())
40 | exec(open(path+'swm_operators.py').read())
41 | exec(open(path+'swm_output.py').read())
42 | param['output'] = 0
43 |
44 | set_grad_mat()
45 | set_interp_mat()
46 | set_lapl_mat()
47 | set_coriolis()
48 |
49 | tlen = len(time)
50 | ## create ouputfolder
51 | try:
52 | os.mkdir(runpath+'/analysis')
53 | except:
54 | pass
55 |
56 | ## reshape u,v
57 | u = u.reshape((tlen,param['Nu'])).T
58 | v = v.reshape((tlen,param['Nv'])).T
59 | h = h.reshape((tlen,param['NT'])).T
60 | print('Reshape done.')
61 |
62 | ## COMPUTE REYNOLDS, ROSSBY
63 | u_T = IuT.dot(u)
64 | v_T = IvT.dot(v)
65 | print('u,v interpolation done.')
66 |
67 | #advective term
68 | adv_u = u_T*Gux.dot(u) + v_T*IqT.dot(Guy.dot(u))
69 | adv_v = u_T*IqT.dot(Gvx.dot(v)) + v_T*Gvy.dot(v)
70 | del u_T,v_T
71 | adv_term = np.sqrt(adv_u**2 + adv_v**2)
72 | del adv_u, adv_v
73 | print('Advection term done.')
74 |
75 | #coriolis term
76 | cor_term = (f_T*np.sqrt(IuT.dot(u**2) + IvT.dot(v**2)).T).T
77 | print('Coriolis term done.')
78 |
79 | #diffusive term
80 | diff_u = param['nu_B']*LLu.dot(u)
81 | diff_v = param['nu_B']*LLv.dot(v)
82 | diff_term = np.sqrt(IuT.dot(diff_u**2) + IvT.dot(diff_v**2))
83 | del diff_u,diff_v
84 | print('Diffusion term done.')
85 |
86 | # actual numbers
87 | Re = np.log10(adv_term / diff_term).flatten()
88 | Ro = np.log10(adv_term / cor_term).flatten()
89 | del adv_term, cor_term, diff_term
90 | print('Non dim numbers computed.')
91 |
92 | # histogram
93 | ReRoH,Re_edges,Ro_edges = np.histogram2d(Re,Ro,200)
94 | print('ReRo histogram done.')
95 | del Re,Ro
96 |
97 | Re_mid = Re_edges[:-1] + np.diff(Re_edges)/2.
98 | Ro_mid = Ro_edges[:-1] + np.diff(Ro_edges)/2.
99 |
100 | ## STORING
101 | dic = dict()
102 | all_var2export = ['ReRoH','Re_mid','Ro_mid','Re_edges','Ro_edges']
103 |
104 | for v in all_var2export:
105 | exec('dic[v] ='+v)
106 |
107 | np.save(runpath+'/analysis/ReRo_hist.npy',dic)
--------------------------------------------------------------------------------
/calc/misc/taylor_diagram_plot.py:
--------------------------------------------------------------------------------
1 | ## TAYLOR DIAGRAM PLOT
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 | import glob
10 | import matplotlib.pyplot as plt
11 | from cmocean import cm
12 |
13 | exec(open(path+'analyses/taylor_diagram.py').read())
14 |
15 | # OPTIONS
16 | runfolder = [3,10]
17 | print('Compare mean plots from run ' + str(runfolder))
18 |
19 | ## read data
20 |
21 | runpath1 = path+'data/run%04i' % runfolder[0]
22 | D1 = np.load(runpath1+'/analysis/mean.npy').all()
23 | param1 = np.load(runpath1+'/param.npy').all()
24 |
25 | runpath2 = path+'data/run%04i' % runfolder[1]
26 | D2 = np.load(runpath2+'/analysis/mean.npy').all()
27 | param2 = np.load(runpath2+'/param.npy').all()
28 |
29 | runpath3 = path+'stoch/data/run%04i' % 13
30 | D3 = np.load(runpath3+'/analysis/mean.npy').all()
31 | param3 = np.load(runpath3+'/param.npy').all()
32 |
33 | runpath4 = path+'stoch/data/run%04i' % 12
34 | D4 = np.load(runpath4+'/analysis/mean.npy').all()
35 | param4 = np.load(runpath4+'/param.npy').all()
36 |
37 | runpath5 = path+'stoch/data/run%04i' % 14
38 | D5 = np.load(runpath5+'/analysis/mean.npy').all()
39 | param5 = np.load(runpath5+'/param.npy').all()
40 |
41 | um,vm,hm = grid_interpolation(D2['um'],D2['vm'],D2['hm'],param2,param1)
42 |
43 | ##
44 | # low resolution
45 | stitle = r'Taylor Diagram: $\overline{u}$, $\overline{v}$, $\overline{h}$'
46 |
47 | fig,ax = taylor_diag(hm, D1['hm'], norm=True,label=r'$h$',color='C0',marker='o')
48 | taylor_diag(um, D1['um'], norm=True,label=r'$u$',add=True,ax=ax,color='C0',marker='o')
49 | taylor_diag(vm, D1['vm'], norm=True,label=r'$v$',add=True,ax=ax,color='C0',marker='o')
50 |
51 | # plus backscatter
52 | taylor_diag(hm, D3['hm'], norm=True,label=r'$h$',add=True,ax=ax,color='C3')
53 | taylor_diag(um, D3['um'], norm=True,label=r'$u$',add=True,ax=ax,color='C3')
54 | taylor_diag(vm, D3['vm'], norm=True,label=r'$v$',add=True,ax=ax,color='C3')
55 |
56 | # plus backscatter
57 | taylor_diag(hm, D4['hm'], norm=True,label=r'$h$',add=True,ax=ax,color='C1')
58 | taylor_diag(um, D4['um'], norm=True,label=r'$u$',add=True,ax=ax,color='C1')
59 | taylor_diag(vm, D4['vm'], norm=True,label=r'$v$',add=True,ax=ax,color='C1')
60 |
61 | # plus backscatter
62 | taylor_diag(hm, D5['hm'], norm=True,label=r'$h$',add=True,ax=ax,color='C4')
63 | taylor_diag(um, D5['um'], norm=True,label=r'$u$',add=True,ax=ax,color='C4')
64 | taylor_diag(vm, D5['vm'], norm=True,label=r'$v$',add=True,ax=ax,color='C4',title=stitle)
65 |
66 | ax.scatter(-np.ones(3),-np.ones(3),5,'C0',marker='o',label=r'Low resolution, $\Delta x = 30$km')
67 | ax.scatter(-np.ones(3),-np.ones(3),5,'C2',marker='o',label=r'High resolution, $\Delta x = 7.5$km')
68 | ax.scatter(-np.ones(3),-np.ones(3),5,'C3',marker='^',label=r'$\Delta x = 30$km + backscatter, $n_{diss} = %.2f$' % param3['n_diss'])
69 | ax.scatter(-np.ones(3),-np.ones(3),5,'C1',marker='^',label=r'$\Delta x = 30$km + backscatter, $n_{diss} = %.2f$' % param4['n_diss'])
70 | ax.scatter(-np.ones(3),-np.ones(3),5,'C4',marker='^',label=r'$\Delta x = 30$km + backscatter, $n_{diss} = %.2f$' % param5['n_diss'])
71 |
72 | plt.legend(loc=1,scatterpoints=3)
73 |
74 | plt.tight_layout()
75 | plt.savefig(path+'compare/Taylor_uvh_mean.png',dpi=150)
76 | plt.close(fig)
--------------------------------------------------------------------------------
/calc/misc/taylor_convergence.py:
--------------------------------------------------------------------------------
1 | ## TAYLOR DIAGRAM PLOT
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 | import glob
10 | import matplotlib.pyplot as plt
11 | from cmocean import cm
12 |
13 | exec(open(path+'analyses/taylor_diagram.py').read())
14 |
15 | # OPTIONS
16 | runfolder = [3,10,11,12,13]
17 | print('Compare mean plots from run ' + str(runfolder))
18 |
19 | ## read data
20 |
21 | runpath1 = path+'data/run%04i' % runfolder[0]
22 | D1 = np.load(runpath1+'/analysis/mean.npy').all()
23 | param1 = np.load(runpath1+'/param.npy').all()
24 |
25 | runpath2 = path+'data/run%04i' % runfolder[1]
26 | D2 = np.load(runpath2+'/analysis/mean.npy').all()
27 | param2 = np.load(runpath2+'/param.npy').all()
28 |
29 | runpath3 = path+'data/run%04i' % runfolder[2]
30 | D3 = np.load(runpath3+'/analysis/mean.npy').all()
31 | param3 = np.load(runpath3+'/param.npy').all()
32 |
33 | runpath4 = path+'data/run%04i' % runfolder[3]
34 | D4 = np.load(runpath4+'/analysis/mean.npy').all()
35 | param4 = np.load(runpath4+'/param.npy').all()
36 |
37 | runpath5 = path+'data/run%04i' % runfolder[4]
38 | D5 = np.load(runpath5+'/analysis/mean.npy').all()
39 | param5 = np.load(runpath5+'/param.npy').all()
40 |
41 | um128,vm128,hm128 = grid_interpolation(D2['um'],D2['vm'],D2['hm'],param2,param1)
42 | um32,vm32,hm32 = grid_interpolation(D2['um'],D2['vm'],D2['hm'],param2,param3)
43 | um64,vm64,hm64 = grid_interpolation(D2['um'],D2['vm'],D2['hm'],param2,param4)
44 | um256,vm256,hm256 = grid_interpolation(D2['um'],D2['vm'],D2['hm'],param2,param5)
45 |
46 | ##
47 | # low resolution
48 | stitle = r'Taylor Diagram: $\overline{u}$, $\overline{v}$, $\overline{h}$'
49 |
50 | fig,ax = taylor_diag(hm128, D1['hm'], norm=True,label=r'$h$',color='C0',marker='o')
51 | taylor_diag(um128, D1['um'], norm=True,label=r'$u$',add=True,ax=ax,color='C0',marker='o')
52 | taylor_diag(vm128, D1['vm'], norm=True,label=r'$v$',add=True,ax=ax,color='C0',marker='o')
53 |
54 | # plus backscatter
55 | taylor_diag(hm32, D3['hm'], norm=True,label=r'$h$',add=True,ax=ax,color='C3')
56 | taylor_diag(um32, D3['um'], norm=True,label=r'$u$',add=True,ax=ax,color='C3')
57 | taylor_diag(vm32, D3['vm'], norm=True,label=r'$v$',add=True,ax=ax,color='C3')
58 |
59 | # plus backscatter
60 | taylor_diag(hm64, D4['hm'], norm=True,label=r'$h$',add=True,ax=ax,color='C1')
61 | taylor_diag(um64, D4['um'], norm=True,label=r'$u$',add=True,ax=ax,color='C1')
62 | taylor_diag(vm64, D4['vm'], norm=True,label=r'$v$',add=True,ax=ax,color='C1')
63 |
64 | # plus backscatter
65 | taylor_diag(hm256, D5['hm'], norm=True,label=r'$h$',add=True,ax=ax,color='C4')
66 | taylor_diag(um256, D5['um'], norm=True,label=r'$u$',add=True,ax=ax,color='C4')
67 | taylor_diag(vm256, D5['vm'], norm=True,label=r'$v$',add=True,ax=ax,color='C4',title=stitle)
68 |
69 | ax.scatter(-np.ones(3),-np.ones(3),5,'C3',marker='^',label=r'$\Delta x = 120$km')
70 | ax.scatter(-np.ones(3),-np.ones(3),5,'C1',marker='^',label=r'$\Delta x = 60$km')
71 | ax.scatter(-np.ones(3),-np.ones(3),5,'C0',marker='o',label=r'$\Delta x = 30$km')
72 | ax.scatter(-np.ones(3),-np.ones(3),5,'C4',marker='^',label=r'$\Delta x = 15$km')
73 | ax.scatter(-np.ones(3),-np.ones(3),5,'C2',marker='o',label=r'$\Delta x = 7.5$km')
74 |
75 | plt.legend(loc=1,scatterpoints=3)
76 |
77 | plt.tight_layout()
78 | plt.savefig(path+'compare/Taylor_uvh_convergence.png',dpi=150)
79 | plt.close(fig)
--------------------------------------------------------------------------------
/plot/last_timestep_plot.py:
--------------------------------------------------------------------------------
1 | ## PRODUCE FINAL PLOTS
2 | from __future__ import print_function
3 |
4 | path1 = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/data/'
5 | path2 = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
6 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
7 |
8 | import os; os.chdir(path2) # change working directory
9 | import numpy as np
10 | from scipy import sparse
11 | from scipy.integrate import cumtrapz
12 | import matplotlib.pyplot as plt
13 | import time as tictoc
14 | from netCDF4 import Dataset
15 | import glob
16 | from cmocean import cm
17 |
18 | plt.rcParams['mathtext.fontset'] = 'cm'
19 | plt.rcParams['mathtext.rm'] = 'serif'
20 |
21 | ## OPTIONS
22 | runfolders = [0,3,6]
23 | print('Creating final plots from run ' + str(runfolders))
24 |
25 | ## read data
26 | p = []
27 | z = []
28 |
29 | # import functions
30 | funpath = '/network/home/aopp/kloewer/git/swm/'
31 | exec(open(funpath+'swm_param.py').read())
32 | exec(open(funpath+'swm_operators.py').read())
33 |
34 | for i,r in enumerate(runfolders):
35 |
36 | path = path2 if i==1 else path1
37 | runpath = path+'run%04i' % r
38 |
39 | u = np.load(runpath+'/u_last.npy').flatten()
40 | v = np.load(runpath+'/v_last.npy').flatten()
41 | p.append(np.load(runpath+'/param.npy').all())
42 |
43 | # set param the current param dictionnary
44 | param = p[-1]
45 | param['output'] = 0
46 |
47 | # get operators
48 | set_grad_mat()
49 | set_interp_mat()
50 | set_coriolis()
51 |
52 | # rel vort calculation
53 | z.append(q2mat(Gvx.dot(v) - Guy.dot(u)))
54 | print((z[-1]**2).mean())
55 | expo = 0.5
56 | z[-1] = (np.sign(z[-1])*abs(z[-1]*1e5)**expo)
57 |
58 | z_max = np.percentile(abs(z[-1]),98.5)
59 | levs = np.linspace(-z_max,z_max,32)
60 |
61 | ##
62 |
63 | fig,axs = plt.subplots(1,3,figsize=(10,4.8),sharex=True,sharey=True)
64 | fig.tight_layout(rect=[0.03,.15,1,0.9])
65 | fig.subplots_adjust(wspace=0.03,hspace=0.03)
66 |
67 | pos = axs[0].get_position()
68 | pos2 = axs[-1].get_position()
69 | cax = fig.add_axes([pos.x0,0.1,pos2.x1-pos.x0,0.03])
70 |
71 | axs[0].contourf(p[0]['x_q']/1e3,p[0]['y_q']/1e3,z[0],levs,cmap=cm.balance,extend='both')
72 | axs[1].contourf(p[1]['x_q']/1e3,p[1]['y_q']/1e3,z[1],levs,cmap=cm.balance,extend='both')
73 | q0 = axs[2].contourf(p[2]['x_q']/1e3,p[2]['y_q']/1e3,z[2],levs,cmap=cm.balance,extend='both')
74 |
75 | tik0 = np.array([-3,-1.9,-1,-0.4,-0.1,0,0.1,0.4,1,1.9,3])
76 |
77 | cbar0 = fig.colorbar(q0,cax=cax,orientation='horizontal',ticks=np.sign(tik0)*abs(tik0)**expo)
78 | cbar0.set_label(r'[10$^{-5}$ s$^{-1}$]')
79 | cbar0.set_ticklabels(tik0)
80 |
81 | plt.suptitle(r'Snapshots of relative vorticity',x=0.201)
82 |
83 | axs[0].set_xlim(0,param['Lx']/1e3)
84 | axs[0].set_ylim(0,param['Ly']/1e3)
85 |
86 | axs[0].set_xticks([0,1000,2000,3000])
87 | axs[0].set_yticks([0,1000,2000,3000])
88 |
89 | axs[0].set_ylabel(r'$y$ [km]')
90 | axs[1].set_xlabel(r'$x$ [km]')
91 |
92 |
93 | axs[0].set_title(r'Low resolution, $\Delta x = $30km')
94 | axs[1].set_title(r'LR + moderate backscatter')
95 | axs[2].set_title(r'High resolution, $\Delta x = $7.5km')
96 |
97 | axs[0].set_title('a',loc='left',fontweight='bold')
98 | axs[1].set_title('b',loc='left',fontweight='bold')
99 | axs[2].set_title('c',loc='left',fontweight='bold')
100 |
101 | plt.savefig(outpath+'plots/relvort_snapshot.png',dpi=300)
102 | plt.close(fig)
103 |
--------------------------------------------------------------------------------
/calc/misc/trispec_plot.py:
--------------------------------------------------------------------------------
1 | ## TRISPEC PLOT
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 | import glob
10 | import matplotlib.pyplot as plt
11 | from cmocean import cm
12 |
13 | # OPTIONS
14 | runfolder = [3,10]
15 | var = 'h'
16 | print('Compare trispec plots from run ' + str(runfolder))
17 |
18 | runpath1 = path+'data/run%04i' % runfolder[0]
19 | D1 = np.load(runpath1+'/analysis/trispec_'+var+'.npy').all()
20 | param1 = np.load(runpath1+'/param.npy').all()
21 |
22 | runpath2 = path+'data/run%04i' % runfolder[1]
23 | D2 = np.load(runpath2+'/analysis/trispec_'+var+'.npy').all()
24 | param2 = np.load(runpath2+'/param.npy').all()
25 |
26 | ##
27 | Ro_max = param1['c_phase']/(param1['f_0'] - param1['beta']*param1['Ly']/2.)
28 | Ro_min = param1['c_phase']/(param1['f_0'] + param1['beta']*param1['Ly']/2.)
29 |
30 | # dispersion relation, divide omega and k by 2pi
31 | wrossby_max = lambda k: param1['beta']*k/(2*np.pi)/(2*(k/(2*np.pi))**2 + 1./(Ro_max)**2)/2./np.pi
32 | wrossby_min = lambda k: param1['beta']*k/(2*np.pi)/(2*(k/(2*np.pi))**2 + 1./(Ro_min)**2)/2./np.pi
33 |
34 | ## PLOTTING
35 | sd = 3600.*24. # from seconds to days for frequency axis
36 | kf = 1e3 # wavenumber factor for plotting
37 |
38 | fig,(ax1,ax2) = plt.subplots(1,2,sharex=True,sharey=True,figsize=(14,7))
39 | c1 = ax1.contourf(D1['k']*kf,D1['f']*sd,np.log10(D1['p']),np.linspace(0,9,51),cmap=cm.thermal,extend='both')
40 | c2 = ax2.contourf(D2['k']*kf,D2['f']*sd,np.log10(D2['p']),np.linspace(0,9,51),cmap=cm.thermal,extend='both')
41 |
42 | for D,ax,greyvalue in zip([D1,D2],[ax1,ax2],['0.7','0.3']):
43 |
44 | ax.plot(np.zeros(2),[D['f'][0]*sd,D['f'][-1]*sd],'w',lw=22)
45 |
46 | ax.plot(D['k']*kf,wrossby_min(D['k'])*sd,'c',label=r'$\omega_{Ro,min}(k)$',lw=1.5)
47 | ax.plot(D['k']*kf,wrossby_max(D['k'])*sd,'c--',label=r'$\omega_{Ro,max}(k)$',lw=1.5)
48 |
49 | ax.plot(1./Ro_min*kf*np.ones(2),[D['f'][0]*sd,D['f'][-1]*sd],greyvalue,label=r'$Ro_{min}$',lw=1.5)
50 | ax.plot(1./Ro_max*kf*np.ones(2),[D2['f'][0]*sd,D['f'][-1]*sd],greyvalue,label=r'$Ro_{max}$',linestyle='dashed',lw=1.5)
51 |
52 | ax.plot(-1./Ro_min*kf*np.ones(2),[D['f'][0]*sd,D['f'][-1]*sd],greyvalue,lw=1.5)
53 | ax.plot(-1./Ro_max*kf*np.ones(2),[D2['f'][0]*sd,D['f'][-1]*sd],greyvalue,linestyle='dashed',lw=1.5)
54 |
55 | ytick = np.array([200,50,20,15,10,8,7,6,5,4,3])
56 | ax.set_yticks(1./ytick)
57 | ax.set_yticklabels(ytick)
58 |
59 | xtick = np.array([40,10,5,3,2,1])*100
60 | ax.set_xticks(1./xtick)
61 | ax.set_xticklabels(xtick)
62 |
63 | ax.tick_params(axis='x', color='white')
64 | ax.tick_params(axis='y', color='white')
65 |
66 | ax.set_xticklabels(ax.xaxis.get_majorticklabels(), rotation=90)
67 |
68 | ax1.set_xlim(0,0.01)
69 | ax1.set_ylim(0,.5)
70 |
71 | ax1.legend(loc=1)
72 |
73 | ax1.set_xlabel(r'wavelength $\lambda = 1/\sqrt{k_x^2 + k_y^2}$ [km]')
74 | ax2.set_xlabel(r'$\lambda$ [km]')
75 | ax1.set_ylabel('period [days]')
76 |
77 | if var == 'h':
78 | varname = '$\eta$'
79 | elif var == 'u':
80 | varname = '$u$'
81 | elif var == 'v':
82 | varname = '$v$'
83 |
84 | ax1.set_title('3D power spectrum of '+varname+': Low resolution $\Delta x = 30$km')
85 | ax2.set_title('High resolution $\Delta x = 7.5$km')
86 | plt.tight_layout()
87 | plt.savefig(path+'/compare/trispec_'+var+'.png')
88 | plt.close(fig)
--------------------------------------------------------------------------------
/swm_rhs.py:
--------------------------------------------------------------------------------
1 | ## RIGHT HAND SIDE OF THE EQUATIONS
2 | def rhs(u,v,eta):
3 | """ Set of equations:
4 |
5 | u_t = qhv - p_x + Fx + Mx(u,v) - bottom_friction
6 | v_t = -qhu - p_y + My(u,v) - bottom_friction
7 | eta_t = -(uh)_x - (vh)_y
8 |
9 | with p = .5*(u**2 + v**2) + gh, the bernoulli potential
10 | and q = (v_x - u_y + f)/h the potential vorticity
11 |
12 | using the enstrophy and energy conserving scheme (Arakawa and Lamb, 1981) and
13 | a biharmonic lateral mixing term based on Shchepetkin and O'Brien (1996).
14 | """
15 |
16 | #TODO param[nu_B] is large, applying the biharmonic creates tiny values (as dx^4 is large)
17 | #TODO think about a way to avoid possibly involved rounding errors especially with single precision
18 | #TODO might be efficiently only possible for dx=dy
19 |
20 | h = eta + param['H']
21 |
22 | h_u = ITu.dot(h) # h on u-grid
23 | h_v = ITv.dot(h) # h on v-grid
24 | h_q = ITq.dot(h) # h on q-grid
25 |
26 | U = u*h_u # volume fluxes: U on u-grid
27 | V = v*h_v # and V on v-grid
28 |
29 | KE = IuT.dot(u**2) + IvT.dot(v**2) # kinetic energy without .5-factor
30 |
31 | q = (f_q + Gvx.dot(v) - Guy.dot(u)) / h_q # potential vorticity q
32 | p = .5*KE + param['g']*h # Bernoulli potential p
33 |
34 | ## BOTTOM FRICTION: quadratic drag
35 | sqrtKE = np.sqrt(KE)
36 | bfric_u = param['c_D']*ITu.dot(sqrtKE)*u/h_u
37 | bfric_v = param['c_D']*ITv.dot(sqrtKE)*v/h_v
38 |
39 | ## ADVECTION
40 | # Sadourny, 1975 enstrophy conserving scheme.
41 | # adv_u = Iqu.dot(q)*Ivu.dot(V)
42 | # adv_v = -Iqv.dot(q)*Iuv.dot(U)
43 |
44 | # Arakawa and Lamb, 1981
45 | adv_u, adv_v = ALadvection(q,U,V)
46 |
47 | ## LATERAL MIXING OPERATOR
48 | # simple bi-harmonic mixing
49 | # bidiff_u = param['nu_B']*LLu.dot(u)
50 | # bidiff_v = param['nu_B']*LLv.dot(v)
51 |
52 | # symmetric stress tensor S = (S11, S12, S12, -S11), store only S11, S12
53 | S = (Gux.dot(u) - Gvy.dot(v),G2vx.dot(v) + G2uy.dot(u))
54 | hS = (h*S[0],h_q*S[1])
55 |
56 | diff_u = (GTx*hS[0] + Gqy*hS[1]) / h_u
57 | diff_v = (Gqx*hS[1] - GTy*hS[0]) / h_v
58 |
59 | # biharmonic stress tensor R = (R11, R12, R12, -R11), store only R11, R12
60 | R = (Gux.dot(diff_u) - Gvy.dot(diff_v), G2vx.dot(diff_v) + G2uy.dot(diff_u))
61 | nuhR = (param['nu_B']*h*R[0],param['nu_B']*h_q*R[1])
62 |
63 | bidiff_u = (GTx.dot(nuhR[0]) + Gqy.dot(nuhR[1])) / h_u
64 | bidiff_v = (Gqx.dot(nuhR[1]) - GTy.dot(nuhR[0])) / h_v
65 |
66 | ## RIGHT-HAND SIDE: ADD TERMS
67 | rhs_u = adv_u - GTx.dot(p) + Fx/h_u - bidiff_u - bfric_u
68 | rhs_v = adv_v - GTy.dot(p) - bidiff_v - bfric_v
69 | rhs_eta = -(Gux.dot(U) + Gvy.dot(V))
70 |
71 | return rhs_u, rhs_v, rhs_eta
72 |
73 | def ALadvection(q,U,V):
74 | """ Arakawa and Lamb,1981 advection terms. See interpolation.py for further information. """
75 |
76 | AL1q = AL1.dot(q)
77 | AL2q = AL2.dot(q)
78 |
79 | adv_u = Seur.dot(ALeur.dot(q)*U) + Seul.dot(ALeul.dot(q)*U) +\
80 | Sau.dot(AL1q[indx_au]*V) + Sbu.dot(AL2q[indx_bu]*V) +\
81 | Scu.dot(AL2q[indx_cu]*V) + Sdu.dot(AL1q[indx_du]*V)
82 |
83 | adv_v = Spvu.dot(ALpvu.dot(q)*V) + Spvd.dot(ALpvd.dot(q)*V) -\
84 | Sav.dot(AL1q[indx_av]*U) - Sbv.dot(AL2q[indx_bv]*U) -\
85 | Scv.dot(AL2q[indx_cv]*U) - Sdv.dot(AL1q[indx_dv]*U)
86 |
87 | return adv_u, adv_v
88 |
89 |
--------------------------------------------------------------------------------
/calc/misc/cospec_plot.py:
--------------------------------------------------------------------------------
1 | ## COSPEC PLOT
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 | import glob
10 | import matplotlib.pyplot as plt
11 | from cmocean import cm
12 |
13 | # OPTIONS
14 | runfolder = [3,10]
15 | var = 'eke'
16 | print('Compare cospec plots from run ' + str(runfolder))
17 |
18 | #lat1 = '_1lat'
19 | lat1 = ''
20 |
21 | runpath1 = path+'data/run%04i' % runfolder[0]
22 | D1 = np.load(runpath1+'/analysis/cospec_'+var+lat1+'.npy').all()
23 | param1 = np.load(runpath1+'/param.npy').all()
24 |
25 | runpath2 = path+'data/run%04i' % runfolder[1]
26 | D2 = np.load(runpath2+'/analysis/cospec_'+var+lat1+'.npy').all()
27 | param2 = np.load(runpath2+'/param.npy').all()
28 |
29 | ##
30 | Ro_max = param1['c_phase']/(param1['f_0'] - param1['beta']*param1['Ly']/2.)
31 | Ro_min = param1['c_phase']/(param1['f_0'] + param1['beta']*param1['Ly']/2.)
32 |
33 | # dispersion relation, divide omega and k by 2pi
34 | wrossby_max = lambda k: -param1['beta']*k/(2*np.pi)/(2*(k/(2*np.pi))**2 + 1./(Ro_max)**2)/2./np.pi
35 | wrossby_min = lambda k: -param1['beta']*k/(2*np.pi)/(2*(k/(2*np.pi))**2 + 1./(Ro_min)**2)/2./np.pi
36 |
37 | ## PLOTTING
38 | sd = 3600.*24. # from seconds to days for frequency axis
39 | kf = 1e3 # wavenumber factor for plotting
40 |
41 | fig,(ax1,ax2) = plt.subplots(1,2,sharex=True,sharey=True,figsize=(14,7))
42 | c1 = ax1.contourf(D1['k']*kf,D1['f']*sd,np.log10(D1['p']),np.linspace(4,10,51),cmap=cm.thermal,extend='both')
43 | c2 = ax2.contourf(D2['k']*kf,D2['f']*sd,np.log10(D2['p']),np.linspace(4,10,51),cmap=cm.thermal,extend='both')
44 |
45 | for D,ax,greyvalue in zip([D1,D2],[ax1,ax2],['0.7','0.3']):
46 | ax.plot(np.zeros(2),[D['f'][0]*sd,D['f'][-1]*sd],'w',lw=22)
47 |
48 | ax.plot(D['k']*kf,wrossby_min(D['k'])*sd,'c',label=r'$\frac{1}{2\pi}\omega_{Ro,min}(\frac{k}{2\pi})$',lw=1.5)
49 | ax.plot(D['k']*kf,wrossby_max(D['k'])*sd,'c--',label=r'$\frac{1}{2\pi}\omega_{Ro,max}(\frac{k}{2\pi})$',lw=1.5)
50 |
51 | ax.plot(1./Ro_min*kf*np.ones(2),[D['f'][0]*sd,D['f'][-1]*sd],greyvalue,label=r'$Ro_{min}$',lw=1.5)
52 | ax.plot(1./Ro_max*kf*np.ones(2),[D2['f'][0]*sd,D['f'][-1]*sd],greyvalue,label=r'$Ro_{max}$',linestyle='dashed',lw=1.5)
53 |
54 | ax.plot(-1./Ro_min*kf*np.ones(2),[D['f'][0]*sd,D['f'][-1]*sd],greyvalue,lw=1.5)
55 | ax.plot(-1./Ro_max*kf*np.ones(2),[D2['f'][0]*sd,D['f'][-1]*sd],greyvalue,linestyle='dashed',lw=1.5)
56 |
57 | ytick = np.array([200,50,20,15,10,8,7,6,5,4,3])
58 | ax.set_yticks(1./ytick)
59 | ax.set_yticklabels(ytick)
60 |
61 | xtick = np.array([-2,-5,-10,-40,40,10,5,2])*100
62 | ax.set_xticks(1./xtick)
63 | ax.set_xticklabels(xtick)
64 |
65 | ax.tick_params(axis='x', color='white')
66 | ax.tick_params(axis='y', color='white')
67 |
68 | ax.set_xticklabels(ax.xaxis.get_majorticklabels(), rotation=90)
69 |
70 | ax1.set_xlim(-0.005,0.005)
71 | ax1.set_ylim(0,.34)
72 |
73 | ax1.legend(loc=1)
74 |
75 | ax1.set_xlabel(r'wavelength [km]')
76 | ax2.set_xlabel(r'wavelength [km]')
77 | ax1.set_ylabel('period [days]')
78 |
79 | if var == 'h':
80 | varname = '$\eta$'
81 | elif var == 'u':
82 | varname = '$u$'
83 | elif var == 'v':
84 | varname = '$v$'
85 | elif var == 'eke':
86 | varname = 'EKE'
87 |
88 | ax1.set_title('2D power spectrum of '+varname+': Low resolution $\Delta x = 30$km')
89 | ax2.set_title('High resolution $\Delta x = 7.5$km')
90 | plt.tight_layout()
91 | plt.savefig(path+'/compare/cospec_'+var+lat1+'.png')
92 | plt.close(fig)
93 |
94 |
95 |
--------------------------------------------------------------------------------
/calc/misc/tempautocorr_plot_bf.py:
--------------------------------------------------------------------------------
1 | ## TEMPAUTOCORR PLOT
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | import matplotlib.pyplot as plt
7 | from scipy.integrate import cumtrapz
8 |
9 | ## read data
10 |
11 | runpath1 = path+'data/run%04i' % 0
12 | D1 = np.load(runpath1+'/analysis/acfs.npy').all()
13 | param1 = np.load(runpath1+'/param.npy').all()
14 |
15 | runpath2 = path+'data/run%04i' % 6
16 | D2 = np.load(runpath2+'/analysis/acfs.npy').all()
17 | param2 = np.load(runpath2+'/param.npy').all()
18 |
19 | runpath3 = path+'data/run%04i' % 10
20 | D3 = np.load(runpath3+'/analysis/acfs.npy').all()
21 | param3 = np.load(runpath3+'/param.npy').all()
22 |
23 | runpath4 = path+'data/run%04i' % 14
24 | D4 = np.load(runpath4+'/analysis/acfs.npy').all()
25 | param4 = np.load(runpath4+'/param.npy').all()
26 |
27 | runpath5 = path+'data/run%04i' % 15
28 | D5 = np.load(runpath5+'/analysis/acfs.npy').all()
29 | param5 = np.load(runpath5+'/param.npy').all()
30 |
31 | # read without bottom friction data
32 |
33 | # runpath1 = path+'data/newold/run%04i' % 3
34 | # D1 = np.load(runpath1+'/analysis/acfs.npy').all()
35 | # param1 = np.load(runpath1+'/param.npy').all()
36 | #
37 | # runpath2 = path+'data/newold/run%04i' % 10
38 | # D2 = np.load(runpath2+'/analysis/acfs.npy').all()
39 | # param2 = np.load(runpath2+'/param.npy').all()
40 | #
41 | # runpath3 = path+'stoch/data/run%04i' % 13
42 | # D3 = np.load(runpath3+'/analysis/acfs.npy').all()
43 | # param3 = np.load(runpath3+'/param.npy').all()
44 | #
45 | # runpath4 = path+'stoch/data/run%04i' % 12
46 | # D4 = np.load(runpath4+'/analysis/acfs.npy').all()
47 | # param4 = np.load(runpath4+'/param.npy').all()
48 | #
49 | # runpath5 = path+'stoch/data/run%04i' % 14
50 | # D5 = np.load(runpath5+'/analysis/acfs.npy').all()
51 | # param5 = np.load(runpath5+'/param.npy').all()
52 |
53 | ## Plotting
54 |
55 | fig,axs = plt.subplots(2,3,sharex=True,sharey=True,figsize=(9,6))
56 | plt.tight_layout(rect=[0.05,0.02,1,0.96])
57 | fig.subplots_adjust(wspace=0.05,hspace=0.26)
58 |
59 | for i in range(3):
60 | for j in range(2):
61 | axs[j,i].plot(D1['time'],D1['acfs'][:,i,j],'C0',label=r'Low resolution, $\Delta x = $30km',lw=2)
62 | axs[j,i].plot(D2['time'],D2['acfs'][:,i,j],'C2',label=r'High resolution, $\Delta x = $7.5km',lw=2)
63 | axs[j,i].plot(D3['time'],D3['acfs'][:,i,j],'C3',label=r'LR + weak backscatter',lw=1,ls='--')
64 | axs[j,i].plot(D4['time'],D4['acfs'][:,i,j],'C1',label=r'LR + moderate backscatter',lw=1,ls='--')
65 | axs[j,i].plot(D5['time'],D5['acfs'][:,i,j],'C5',label=r'LR + strong backscatter',lw=1,ls='--')
66 | axs[j,i].plot([0,50],[0,0],'C7',alpha=.5)
67 |
68 | axs[0,0].set_xlim(0,49)
69 | axs[0,0].set_ylim(-0.9,1)
70 |
71 | axs[1,1].legend(bbox_to_anchor=(-1, 1.02, 3., .102), loc=3, fontsize=9, ncol=3, mode="expand", borderaxespad=0.)
72 |
73 | axs[0,0].set_title(r'Zonal velocity $u$',loc='left')
74 | axs[0,1].set_title(r'Meridional velocity $v$',loc='left')
75 | axs[0,2].set_title(r'Surface displacement $\eta$',loc='left')
76 |
77 | axs[1,0].set_xlabel('lag [days]')
78 | axs[1,1].set_xlabel('lag [days]')
79 | axs[1,2].set_xlabel('lag [days]')
80 |
81 | axs[0,0].set_ylabel('Autocorrelation \n Point A')
82 | axs[1,0].set_ylabel('Autocorrelation \n Point B')
83 |
84 | axs[0,0].set_yticks([-0.5,0,0.5,1])
85 |
86 | abc = 'abcdef'
87 | abci = 0
88 | for axcol in axs:
89 | for ax in axcol:
90 | plt.text(0.93,0.93,abc[abci],transform=ax.transAxes,fontweight='bold')
91 | abci += 1
92 |
93 | plt.savefig(path+'compare/autocorrelation_bf.pdf')
94 | plt.close(fig)
95 | #plt.show()
--------------------------------------------------------------------------------
/calc/floats/floats_plot.py:
--------------------------------------------------------------------------------
1 | ## FLOATS PLOT
2 | import numpy as np
3 | from netCDF4 import Dataset
4 | from scipy.interpolate import RegularGridInterpolator as RGI
5 | import matplotlib.pyplot as plt
6 | from cmocean import cm
7 |
8 | plt.rcParams['mathtext.fontset'] = 'cm'
9 | plt.rcParams['mathtext.rm'] = 'serif'
10 |
11 | path = '/home/mkloewer/python/swm/'
12 |
13 | # OPTIONS#
14 | runfolder = [3,10]
15 | print('Plotting floats from run ' + str(runfolder))
16 |
17 | ## LOAD DATA
18 | runpath1 = path+'data/newold/run%04i' % runfolder[0]
19 | param1 = np.load(runpath1+'/param.npy').all()
20 | D1 = np.load(runpath1+'/analysis/floats.npy').all()
21 |
22 | runpath2 = path+'data/newold/run%04i' % runfolder[1]
23 | param2 = np.load(runpath2+'/param.npy').all()
24 | D2 = np.load(runpath2+'/analysis/floats.npy').all()
25 |
26 | runpath3 = path+'stoch/data/run%04i' % 12
27 | param3 = np.load(runpath3+'/param.npy').all()
28 | D3 = np.load(runpath3+'/analysis/floats.npy').all()
29 |
30 | expo = 0.5 # non-linear colorbar exponent
31 |
32 | dx,dy = D1['xm'][1]-D1['xm'][0],D1['ym'][1]-D1['ym'][0]
33 | D1['H'] = (D1['H']/dx/dy*1e6)**expo
34 |
35 | dx,dy = D2['xm'][1]-D2['xm'][0],D2['ym'][1]-D2['ym'][0]
36 | D2['H'] = (D2['H']/dx/dy*1e6)**expo
37 |
38 | dx,dy = D1['xm'][1]-D1['xm'][0],D1['ym'][1]-D1['ym'][0]
39 | D3['H'] = (D3['H']/dx/dy*1e6)**expo
40 |
41 | tiks = np.array([0,1,5,10,20,30,40])
42 | levs = np.linspace(0,np.percentile(D1['H'],99),64)
43 |
44 | ## Plotting
45 | fig,axs = plt.subplots(2,3,sharex=True,sharey=True,figsize=(10,8))
46 | plt.tight_layout(rect=[0,.09,1,0.98])
47 | fig.subplots_adjust(wspace=0.03,hspace=0.03)
48 |
49 | pos1 = axs[-1,0].get_position()
50 | pos2 = axs[-1,-1].get_position()
51 | cax = fig.add_axes([pos1.x0,0.07,pos2.x1-pos1.x0,0.03])
52 |
53 | N = 30 # number of trajectories to plot
54 |
55 | for iD,D in enumerate([D1,D3,D2]):
56 | for i in range(min(D['X'].shape[1],N)): # max num of floats to display
57 | z = np.random.randint(0,250,1)[0]
58 | axs[0,iD].plot(D['X'][:,40+i],D['Y'][:,40+i],color=cm.haline(z))
59 |
60 | for i,D in enumerate([D1,D3,D2]):
61 | sx,sy = D['seedx'],D['seedy'] # unpack
62 | xm,ym,H = D['xm'],D['ym'],D['H']
63 | axs[1,i].add_patch(plt.Rectangle((sx[0],sy[0]),sx[1]-sx[0],sy[1]-sy[0],fc='none',alpha=1,ec='k',lw=1.5))
64 | q = axs[1,i].contourf(xm,ym,H.T,levs,extend='max',cmap=cm.thermal)
65 | axs[1,i].contour(xm,ym,H.T,[0],colors='w')
66 |
67 | cbar = plt.colorbar(q,cax=cax,orientation='horizontal',ticks=tiks**expo)
68 | cbar.set_ticklabels(tiks)
69 | cbar.set_label('[1/km$^2$]')
70 |
71 | axs[0,0].set_ylabel('Example float trajectories')
72 | axs[1,0].set_ylabel('Accumulated float density')
73 | axs[0,0].set_xlim(0,param1['Lx'])
74 | axs[0,0].set_ylim(0,param1['Ly'])
75 | axs[0,0].set_xticks([])
76 | axs[0,0].set_yticks([])
77 |
78 | axs[0,0].set_title(r'Low resolution, $\Delta x = $30km')
79 | axs[0,2].set_title(r'High resolution, $\Delta x = $7.5km')
80 | axs[0,1].set_title(r'LR + moderate backscatter')
81 |
82 | abc = 'abcdef'
83 | abcc = 'kkkwww'
84 | abci = 0
85 | for axcol in axs:
86 | for ax in axcol:
87 | plt.text(0.93,0.93,abc[abci],transform=ax.transAxes,fontweight='bold',color=abcc[abci])
88 | abci += 1
89 |
90 |
91 | axs[-1,0].set_xlabel(r'$x$')
92 | axs[-1,1].set_xlabel(r'$x$')
93 | axs[-1,2].set_xlabel(r'$x$')
94 |
95 | axs[0,2].set_ylabel(r'$y$')
96 | axs[0,2].yaxis.set_label_position('right')
97 |
98 | axs[1,2].set_ylabel(r'$y$')
99 | axs[1,2].yaxis.set_label_position('right')
100 |
101 | #plt.savefig(path+'compare/floats_3runs.png',dpi=150)
102 | #plt.close(fig)
103 | plt.show()
--------------------------------------------------------------------------------
/calc/floats/floats_plot_bf.py:
--------------------------------------------------------------------------------
1 | ## FLOATS PLOT
2 | import numpy as np
3 | from netCDF4 import Dataset
4 | from scipy.interpolate import RegularGridInterpolator as RGI
5 | import matplotlib.pyplot as plt
6 | from cmocean import cm
7 |
8 | plt.rcParams['mathtext.fontset'] = 'cm'
9 | plt.rcParams['mathtext.rm'] = 'serif'
10 |
11 | path = '/home/mkloewer/python/swm/'
12 |
13 | # OPTIONS#
14 | runfolder = [0,6,14]
15 | print('Plotting floats from run ' + str(runfolder))
16 |
17 | ## LOAD DATA
18 | runpath1 = path+'data/run%04i' % runfolder[0]
19 | param1 = np.load(runpath1+'/param.npy').all()
20 | D1 = np.load(runpath1+'/analysis/floats.npy').all()
21 |
22 | runpath2 = path+'data/run%04i' % runfolder[1]
23 | param2 = np.load(runpath2+'/param.npy').all()
24 | D2 = np.load(runpath2+'/analysis/floats.npy').all()
25 |
26 | runpath3 = path+'data/run%04i' % runfolder[2]
27 | param3 = np.load(runpath3+'/param.npy').all()
28 | D3 = np.load(runpath3+'/analysis/floats.npy').all()
29 |
30 | expo = 0.5 # non-linear colorbar exponent
31 |
32 | dx,dy = D1['xm'][1]-D1['xm'][0],D1['ym'][1]-D1['ym'][0]
33 | D1['H'] = (D1['H']/dx/dy*1e6)**expo
34 |
35 | dx,dy = D2['xm'][1]-D2['xm'][0],D2['ym'][1]-D2['ym'][0]
36 | D2['H'] = (D2['H']/dx/dy*1e6)**expo
37 |
38 | dx,dy = D1['xm'][1]-D1['xm'][0],D1['ym'][1]-D1['ym'][0]
39 | D3['H'] = (D3['H']/dx/dy*1e6)**expo
40 |
41 | tiks = np.array([0,1,5,10,20,30,40])#,50,60,70,80,100,120,140,160,180])
42 | levs = np.linspace(0,np.percentile(D1['H'],99),64)
43 |
44 | ## Plotting
45 | fig,axs = plt.subplots(2,3,sharex=True,sharey=True,figsize=(10,8))
46 | plt.tight_layout(rect=[0,.09,1,0.98])
47 | fig.subplots_adjust(wspace=0.03,hspace=0.03)
48 |
49 | pos1 = axs[-1,0].get_position()
50 | pos2 = axs[-1,-1].get_position()
51 | cax = fig.add_axes([pos1.x0,0.07,pos2.x1-pos1.x0,0.03])
52 |
53 | N = 30 # number of trajectories to plot
54 |
55 | for iD,D in enumerate([D1,D3,D2]):
56 | for i in range(min(D['X'].shape[1],N)): # max num of floats to display
57 | z = np.random.randint(0,250,1)[0]
58 | axs[0,iD].plot(D['X'][:,40+i],D['Y'][:,40+i],color=cm.haline(z))
59 |
60 | for i,D in enumerate([D1,D3,D2]):
61 | sx,sy = D['seedx'],D['seedy'] # unpack
62 | xm,ym,H = D['xm'],D['ym'],D['H']
63 | axs[1,i].add_patch(plt.Rectangle((sx[0],sy[0]),sx[1]-sx[0],sy[1]-sy[0],fc='none',alpha=1,ec='k',lw=1.5))
64 | q = axs[1,i].contourf(xm,ym,H.T,levs,extend='max',cmap=cm.thermal)
65 | axs[1,i].contour(xm,ym,H.T,[0],colors='w')
66 |
67 | cbar = plt.colorbar(q,cax=cax,orientation='horizontal',ticks=tiks**expo)
68 | cbar.set_ticklabels(tiks)
69 | cbar.set_label('[1/km$^2$]')
70 |
71 | axs[0,0].set_ylabel('Example float trajectories')
72 | axs[1,0].set_ylabel('Accumulated float density')
73 | axs[0,0].set_xlim(0,param1['Lx'])
74 | axs[0,0].set_ylim(0,param1['Ly'])
75 | axs[0,0].set_xticks([])
76 | axs[0,0].set_yticks([])
77 |
78 | axs[0,0].set_title(r'Low resolution, $\Delta x = $30km')
79 | axs[0,2].set_title(r'High resolution, $\Delta x = $7.5km')
80 | axs[0,1].set_title(r'LR + moderate backscatter')
81 |
82 | abc = 'abcdef'
83 | abcc = 'kkkwww'
84 | abci = 0
85 | for axcol in axs:
86 | for ax in axcol:
87 | plt.text(0.93,0.05,abc[abci],transform=ax.transAxes,fontweight='bold',color=abcc[abci])
88 | abci += 1
89 |
90 |
91 | axs[-1,0].set_xlabel(r'$x$')
92 | axs[-1,1].set_xlabel(r'$x$')
93 | axs[-1,2].set_xlabel(r'$x$')
94 |
95 | axs[0,2].set_ylabel(r'$y$')
96 | axs[0,2].yaxis.set_label_position('right')
97 |
98 | axs[1,2].set_ylabel(r'$y$')
99 | axs[1,2].yaxis.set_label_position('right')
100 |
101 | plt.savefig(path+'compare/floats_3runs_bf.png',dpi=150)
102 | plt.close(fig)
--------------------------------------------------------------------------------
/plot/Ro_hist_plot.py:
--------------------------------------------------------------------------------
1 | ## HISTOGRAM PLOTTING FOR REYNOLDS AND ROSSBY NUMBERS
2 | from __future__ import print_function
3 |
4 | path = '/network/home/aopp/kloewer/swm/paperplot/'
5 | path2 = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/'
6 | path3 = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
7 |
8 | import numpy as np
9 | import matplotlib.pyplot as plt
10 |
11 | plt.rcParams['mathtext.fontset'] = 'cm'
12 | plt.rcParams['mathtext.rm'] = 'serif'
13 |
14 | # OPTIONS
15 | runfolder = [0,6,0,2,4]
16 | print('Creating Ro histogram plot from run '+str(runfolder))
17 |
18 | ## read data
19 | runpath = path2+'data/run%04i' % runfolder[0]
20 | D1 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
21 |
22 | runpath = path2+'data/run%04i' % runfolder[1]
23 | D2 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
24 |
25 | runpath = path3+'run%04i' % runfolder[2]
26 | D3 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
27 | print(np.load(runpath+'/param.npy').all()['n_diss'])
28 |
29 | runpath = path3+'run%04i' % runfolder[3]
30 | D4 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
31 | print(np.load(runpath+'/param.npy').all()['n_diss'])
32 |
33 | runpath = path3+'run%04i' % runfolder[4]
34 | D5 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
35 | print(np.load(runpath+'/param.npy').all()['n_diss'])
36 |
37 | ## EXTEND HISTOGRAM WITH ZERO TO THE RIGHT
38 |
39 | for D in [D1,D2,D3,D4,D5]:
40 | D['Ro_mid'] = np.hstack((D['Ro_mid'],10**1.5))
41 | D['RoH'] = np.hstack((D['RoH'],0.))
42 |
43 | ## CDISS
44 | Ro = np.linspace(10**-3.5,10**1.5,10000)
45 | cd = lambda d: 1/(1+(Ro/d))
46 |
47 | ## PLOT
48 | fig,(ax1,ax2) = plt.subplots(2,1,figsize=(8,4.5),sharex=True)
49 |
50 | s = 1e6
51 |
52 | ax1.plot(D1['Ro_mid'],D1['RoH']/s,'C0',label=r'Low resolution, $\Delta x = $30km',lw=3)
53 | ax1.plot(D2['Ro_mid'],D2['RoH']/16/s,'C2',label=r'High resolution, $\Delta x = $7.5km',lw=3)
54 | ax1.plot(D3['Ro_mid'],D3['RoH']/s,'C1',label=r'LR + weak backscatter',ls='--')
55 | ax1.plot(D4['Ro_mid'],D4['RoH']/s,'C3',label=r'LR + moderate backscatter',ls='--')
56 | ax1.plot(D5['Ro_mid'],D5['RoH']/s,'C5',label=r'LR + strong backscatter',ls='--')
57 |
58 | ytikmax = 0.25
59 |
60 | ax1.axvline(np.log10(D1['Ro_mean']),0,ytikmax,c='C0',ls='-',lw=2)
61 | ax1.axvline(np.log10(D2['Ro_mean']),0,ytikmax,c='C2',ls='-',lw=2)
62 | ax1.axvline(np.log10(D3['Ro_mean']),0,ytikmax,c='C1',ls='--')
63 | ax1.axvline(np.log10(D4['Ro_mean']),0,ytikmax,c='C3',ls='--')
64 | ax1.axvline(np.log10(D5['Ro_mean']),0,ytikmax,c='C5',ls='--')
65 |
66 | ax1.text(np.log10(D1['Ro_mean'])-0.01,1.3,'mean($R_o$)',rotation=90,ha='right',color='k')
67 |
68 | ax2.plot(np.log10(Ro),cd(1.),'C1--',label=r'$c_{diss}$ for $R_{diss} = 1$, weak backscatter')
69 | ax2.plot(np.log10(Ro),cd(6.),'C3--',label=r'$c_{diss}$ for $R_{diss} = 6$, moderate backscatter')
70 | ax2.plot(np.log10(Ro),np.ones_like(Ro),'C5--',label=r'$c_{diss}$ for $R_{diss} = \infty$, strong backscatter')
71 |
72 | ax2.plot(np.ones(2)*np.log10(1),[-1,0.5],'C1')
73 | ax2.plot(np.ones(2)*np.log10(6),[-1,0.5],'C3')
74 | ax2.text(np.log10(1)-0.03,0.3,r'$R_{diss} = 1$',rotation=90,ha='right',color='k')
75 | ax2.text(np.log10(6)-0.03,0.3,r'$R_{diss} = 6$',rotation=90,ha='right',color='k')
76 | ax2.text(-2.9,0.6,r'$c_{diss} = (1 + \frac{R_o}{R_{diss}})^{-1}$', fontsize=15)
77 |
78 | ax2.legend(loc=3)
79 | ax1.legend(loc=1)
80 |
81 | ax1.set_xlim(-3,1)
82 | ax1.set_ylim(-0.1,3.5)
83 | ax2.set_ylim(-0.05,1.05)
84 |
85 | ax1.set_title('a',loc='left',fontweight='bold')
86 | ax1.set_title('Rossby number histogram')
87 |
88 | ax2.set_title('b',loc='left',fontweight='bold')
89 | ax2.set_title('Rossby number dissipation scaling')
90 |
91 | ax2.set_xlabel('log$_{10}(R_o)$')
92 | ax1.set_ylabel(r'$N$ $[10^6]$')
93 |
94 | plt.tight_layout()
95 | plt.savefig(path+'plots/Ro_hist.pdf')
96 | plt.close(fig)
97 |
--------------------------------------------------------------------------------
/calc/misc/spec_ens _calc.py:
--------------------------------------------------------------------------------
1 | ## COMPUTE ENSTROPHY SPECTRUM
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | import time as tictoc
8 | from netCDF4 import Dataset
9 | import glob
10 | import matplotlib.pyplot as plt
11 |
12 | exec(open(path+'swm_param.py').read())
13 | exec(open(path+'swm_operators.py').read())
14 | exec(open(path+'swm_rhs.py').read())
15 | exec(open(path+'swm_integration.py').read())
16 | exec(open(path+'swm_output.py').read())
17 |
18 | # OPTIONS
19 | runfolder = [2,3]
20 | print('Calculating EKE spectrogramms from run ' + str(runfolder))
21 |
22 | ##
23 | def ens_spec_avg(z,dx,dy):
24 | """ Computes a wavenumber-frequency plot for 3D (t,x,y) data via radial (k = sqrt(kx**2 + ky**2)) integration. TODO: correct normalisation, so that the integral in normal space corresponds to the integral in Fourier space.
25 | """
26 |
27 | nt,ny,nx = np.shape(z)
28 | kx = (1/(dx))*np.hstack((np.arange(0,(nx+1)/2.),np.arange(-nx/2.+1,0)))/float(nx)
29 | ky = (1/(dy))*np.hstack((np.arange(0,(ny+1)/2.),np.arange(-ny/2.+1,0)))/float(ny)
30 |
31 | kxx,kyy = np.meshgrid(kx,ky)
32 | # radial distance from kx,ky = 0
33 | kk = np.sqrt(kxx**2 + kyy**2)
34 |
35 | if nx >= ny: #kill negative wavenumbers
36 | k = kx[:int(nx/2)+1]
37 | else:
38 | k = ky[:int(ny/2)+1]
39 |
40 | dk = k[1] - k[0]
41 |
42 | # create radial coordinates, associated with k[i]
43 | # nearest point interpolation to get points within the -.5,.5 annulus
44 | rcoords = []
45 | for i in range(len(k)):
46 | rcoords.append(np.where((kk>(k[i]-.5*dk))*(kk<=(k[i]+.5*dk))))
47 |
48 | # 2D FFT average
49 |
50 | pz = np.empty((nt,ny,nx))
51 |
52 | for i in range(nt):
53 | pz[i,:,:] = abs(np.fft.fft2(z[i,:,:]))**2
54 | if i % 100 == 0:
55 | print(i)
56 |
57 | pz_avg = .5*pz.mean(axis=0)
58 |
59 | # mulitply by dk to have the corresponding integral
60 | ens_spec = np.zeros(len(k))
61 | for i in range(len(k)):
62 | ens_spec[i] = np.sum(pz_avg[rcoords[i][0],rcoords[i][1]])*dk
63 |
64 | return k[1:],ens_spec[1:] # eliminate zero wavenumber
65 |
66 |
67 | ## read data
68 | for r,i in zip(runfolder,range(len(runfolder))):
69 | runpath = path+'data/run%04i' % r
70 |
71 | if i == 0:
72 | u = np.load(runpath+'/u_sub.npy')
73 | v = np.load(runpath+'/v_sub.npy')
74 | #h = np.load(runpath+'/h_sub.npy')
75 | time = np.load(runpath+'/t_sub.npy')
76 | print('run %i read.' % r)
77 |
78 | else:
79 | u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))
80 | v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))
81 | #h = np.concatenate((h,np.load(runpath+'/h_sub.npy')))
82 | time = np.hstack((time,np.load(runpath+'/t_sub.npy')))
83 | print('run %i read.' % r)
84 |
85 | t = time / 3600. / 24. # in days
86 | tlen = len(time)
87 | dt = time[1] - time[0]
88 |
89 | ## read param
90 | global param
91 | param = np.load(runpath+'/param.npy').all()
92 | param['output'] = 0
93 |
94 | set_grad_mat()
95 | set_interp_mat()
96 |
97 | #reshape u,v
98 | u = u.reshape((tlen,param['Nu'])).T
99 | v = v.reshape((tlen,param['Nv'])).T
100 | z = (Gvx.dot(v) - Guy.dot(u)).T.reshape((tlen,param['ny']+1,param['nx']+1))
101 | del u,v
102 | ##
103 | k,p = ens_spec_avg(z,param['dx'],param['dy'])
104 |
105 | ##
106 | dic = dict()
107 | all_var2export = ['k','p']
108 |
109 | for v in all_var2export:
110 | exec('dic[v] ='+v)
111 |
112 | np.save(runpath+'/analysis/spec_ens.npy',dic)
113 |
114 | print('Everything stored.')
115 |
--------------------------------------------------------------------------------
/calc/power_inout_calc.py:
--------------------------------------------------------------------------------
1 | ## POWER INPUT EXIT CALCULATION
2 | from __future__ import print_function
3 |
4 | # path
5 | import os
6 | #path = os.path.dirname(os.getcwd()) + '/' # on level above
7 | path = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
8 | os.chdir(path) # change working directory
9 |
10 | import numpy as np
11 | from scipy import sparse
12 |
13 | # OPTIONS
14 | # several entries in the list concatenates the runs and stores the result in the last folder
15 | runfolder = [4]
16 | print('Calculating power in/out from run ' + str(runfolder))
17 |
18 | InPower_T = []
19 | ExPower_T = []
20 | BfricPower_T = []
21 |
22 | ## read data
23 | for r in runfolder: # calculate each run separately
24 | runpath = path+'run%04i' % r
25 |
26 | skip = 5*365
27 | u = np.load(runpath+'/u_sub.npy')[skip:,...]
28 | v = np.load(runpath+'/v_sub.npy')[skip:,...]
29 | eta = np.load(runpath+'/eta_sub.npy')[skip:,...]
30 | t = np.load(runpath+'/t_sub.npy')[skip:,...]
31 | print('run %i read.' % r)
32 |
33 | ## read param
34 | global param
35 | param = np.load(runpath+'/param.npy').all()
36 |
37 | # import functions
38 | funpath = '/network/home/aopp/kloewer/git/swm/'
39 | exec(open(funpath+'swm_param.py').read())
40 | exec(open(funpath+'swm_operators.py').read())
41 |
42 | set_grad_mat()
43 | set_interp_mat()
44 | set_coriolis()
45 | set_forcing()
46 |
47 | tlen = len(t)
48 | ## create ouputfolder
49 | try:
50 | os.mkdir(runpath+'/analysis')
51 | except:
52 | pass
53 |
54 | ## reshape u,v
55 | u = u.reshape((tlen,param['Nu'])).T
56 | v = v.reshape((tlen,param['Nv'])).T
57 | h = eta.reshape((tlen,param['NT'])).T + param['H']
58 | print('Reshape done.')
59 |
60 | h_q = ITq.dot(h)
61 | h_u = ITu.dot(h)
62 | h_v = ITv.dot(h)
63 | print('h_u, h_v, h_q done.')
64 |
65 | ## input
66 | # Fx is actually Fx/rho
67 | InPower = param['rho']*(u.T*Fx).mean(axis=0)
68 | print('Input Power done.')
69 |
70 | # Shchepetkin and O'Brien divergence of a tensor formulation
71 | hS = ((Gux.dot(u)-Gvy.dot(v))*h,(G2vx.dot(v) + G2uy.dot(u))*h_q)
72 | diff_u = (GTx.dot(hS[0]) + Gqy.dot(hS[1])) / h_u
73 | diff_v = (Gqx.dot(hS[1]) - GTy.dot(hS[0])) / h_v
74 |
75 | del hS, h_u, h_v
76 |
77 | # biharmonic stress tensor R = (R11, R12, R12, -R11), store only R11, R12
78 | hR = ((Gux.dot(diff_u) - Gvy.dot(diff_v))*h, (G2vx.dot(diff_v) + G2uy.dot(diff_u))*h_q)
79 |
80 | del h_q, diff_u, diff_v
81 |
82 | bidiff_u = (GTx.dot(hR[0]) + Gqy.dot(hR[1]))
83 | bidiff_v = (Gqx.dot(hR[1]) - GTy.dot(hR[0]))
84 |
85 | del hR
86 |
87 | print('Biharmonic dissipation term done.')
88 |
89 | ExPower_u = -param['nu_B']*param['rho']*(u*bidiff_u).mean(axis=1)
90 | ExPower_v = -param['nu_B']*param['rho']*(v*bidiff_v).mean(axis=1)
91 |
92 | del bidiff_u, bidiff_v
93 |
94 | print('Exit Power done.')
95 |
96 | BfricPower = -param['rho']*param['c_D']*((IuT.dot(u**2) + IvT.dot(v**2))**(3./2.)).mean(axis=1)
97 |
98 | # Interpolation
99 | InPower_T.append(IuT.dot(InPower))
100 | ExPower_T.append(IuT.dot(ExPower_u) + IvT.dot(ExPower_v))
101 | BfricPower_T.append(BfricPower)
102 |
103 | # Averaging over runs
104 | InPower_T = np.array(InPower_T).mean(axis=0)
105 | ExPower_T = np.array(ExPower_T).mean(axis=0)
106 | BfricPower_T = np.array(BfricPower_T).mean(axis=0)
107 |
108 | ## STORING
109 | dic = dict()
110 | all_var2export = ['InPower_T','ExPower_T','BfricPower_T']
111 | for v in all_var2export:
112 | exec('dic[v] ='+v)
113 |
114 | np.save(runpath+'/analysis/power_map.npy',dic)
115 | print('Everything stored.')
116 |
--------------------------------------------------------------------------------
/calc/mean_calc.py:
--------------------------------------------------------------------------------
1 | ## PRODUCE MEAN CALCULATIONS AND EXPORT AS .NPY
2 | from __future__ import print_function
3 |
4 | # path
5 | import os
6 | funpath = '/network/home/aopp/kloewer/git/swm/' # path for functions swm_operators.py etc
7 | path = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/' # path for data
8 | os.chdir(path)
9 |
10 | import numpy as np
11 | from scipy import sparse
12 |
13 | # OPTIONS
14 | runfolder = [5]
15 | print('Calculating means from run ' + str(runfolder))
16 |
17 | ## read data
18 | for r,i in zip(runfolder,range(len(runfolder))):
19 | runpath = path+'run%04i' % r
20 |
21 | if i == 0:
22 | skip = 5*365
23 | #skip = 0
24 | u = np.load(runpath+'/u_sub.npy')[skip:,...]
25 | v = np.load(runpath+'/v_sub.npy')[skip:,...]
26 | eta = np.load(runpath+'/eta_sub.npy')[skip:,...]
27 | t = np.load(runpath+'/t_sub.npy')[skip:,...]
28 | print('run %i read.' % r)
29 |
30 | else:
31 | # use [1:,...] to not have one time step double
32 | u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))[1:,...]
33 | v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))[1:,...]
34 | eta = np.concatenate((eta,np.load(runpath+'/eta_sub.npy')))[1:,...]
35 | t = np.hstack((t,np.load(runpath+'/t_sub.npy')))[1:,...]
36 | print('run %i read.' % r)
37 |
38 | ## read param
39 | global param
40 | param = np.load(runpath+'/param.npy').all()
41 |
42 | # import functions
43 |
44 | exec(open(funpath+'swm_param.py').read())
45 | exec(open(funpath+'swm_operators.py').read())
46 |
47 | set_grad_mat()
48 | set_interp_mat()
49 | set_lapl_mat()
50 | set_coriolis()
51 |
52 | tlen = len(t)
53 | ## create ouputfolder
54 | try:
55 | os.mkdir(runpath+'/analysis')
56 | except:
57 | pass
58 |
59 | ## reshape u,v
60 | u = u.reshape((tlen,param['Nu'])).T
61 | v = v.reshape((tlen,param['Nv'])).T
62 | eta = eta.reshape((tlen,param['NT'])).T
63 | print('Reshape done.')
64 |
65 | ## U,V,H mean
66 | # thickness-weighted averaging for u,v (Aiki, 2016)
67 | etam = eta.mean(axis=1) # temporal average
68 | um = (ITu.dot(eta + param['H'])*u).mean(axis=1) / ITu.dot(etam + param['H'])
69 | vm = (ITv.dot(eta + param['H'])*v).mean(axis=1) / ITv.dot(etam + param['H'])
70 | print('u,v,eta mean done.')
71 |
72 | # TOTAL KINETIC ENERGY
73 | ke = .5*param['rho']*((eta+param['H'])*(IuT.dot(u**2) + IvT.dot(v**2))).mean(axis=1)
74 | # TOTAL (PERTURBATION) POTENTIAL ENERGY
75 | pe = .5*param['rho']*param['g']*(eta**2).mean(axis=1)
76 | print('KE, PE done.')
77 |
78 | # MEAN KINETIC ENERGY
79 | mke = .5*param['rho']*(etam+param['H'])*(IuT.dot(um**2) + IvT.dot(vm**2))
80 | # Mean Potential Energy
81 | mpe = .5*param['g']*param['rho']*etam**2
82 | print('MKE, MPE done.')
83 |
84 | # Eddy potential energy
85 | epe = .5*param['rho']*param['g']*eta.var(axis=1)
86 |
87 | # Eddy kinetic energy
88 | uprime = ((u.T - um).T)
89 | vprime = ((v.T - vm).T)
90 | print('Prime anomalies done.')
91 |
92 | eke = .5*param['rho']*((eta+param['H'])*(IuT.dot(uprime**2) + IvT.dot(vprime**2))).mean(axis=1)
93 | print('EPE, EKE done.')
94 | del uprime,vprime
95 |
96 | # SPEED MEAN
97 | speedm = np.sqrt(IuT.dot(u**2) + IvT.dot(v**2)).mean(axis=1)
98 | print('Rel Vort, Speed done.')
99 |
100 | ## ENERGY TIME SERIES
101 | PEm = (.5*param['g']*param['rho']*eta**2).mean(axis=0)
102 | print('Potential Energy done.')
103 |
104 | KEm = .5*param['rho']*((eta+param['H'])*(IuT.dot(u**2) + IvT.dot(v**2))).mean(axis=0)
105 | print('Kinetic Energy done.')
106 |
107 | ## STORING
108 | dic = dict()
109 | all_var2export = ['um','vm','etam','ke','pe','mke','eke','mpe','epe','speedm']
110 | #all_var2export = ['t','PEm','KEm']
111 |
112 | for v in all_var2export:
113 | exec('dic[v] ='+v)
114 |
115 | np.save(runpath+'/analysis/mean.npy',dic)
116 | print('Everything stored.')
117 |
--------------------------------------------------------------------------------
/calc/mean_timeseries_calc.py:
--------------------------------------------------------------------------------
1 | ## PRODUCE MEAN CALCULATIONS AND EXPORT AS .NPY
2 | from __future__ import print_function
3 |
4 | # path
5 | import os
6 | funpath = '/network/home/aopp/kloewer/git/swm/'
7 | path = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
8 | os.chdir(path) # change working directory
9 |
10 | import numpy as np
11 | from scipy import sparse
12 |
13 | # OPTIONS
14 | runfolder = [5]
15 | print('Calculating timeseries from run ' + str(runfolder))
16 |
17 | ## read data
18 | for r,i in zip(runfolder,range(len(runfolder))):
19 | runpath = path+'run%04i' % r
20 |
21 | if i == 0:
22 | #skip = 5*365
23 | skip = 0
24 | u = np.load(runpath+'/u_sub.npy')[skip:,...]
25 | v = np.load(runpath+'/v_sub.npy')[skip:,...]
26 | eta = np.load(runpath+'/eta_sub.npy')[skip:,...]
27 | t = np.load(runpath+'/t_sub.npy')[skip:,...]
28 | print('run %i read.' % r)
29 |
30 | else:
31 | # use [1:,...] to not have one time step double
32 | u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))[1:,...]
33 | v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))[1:,...]
34 | eta = np.concatenate((eta,np.load(runpath+'/eta_sub.npy')))[1:,...]
35 | t = np.hstack((t,np.load(runpath+'/t_sub.npy')))[1:,...]
36 | print('run %i read.' % r)
37 |
38 | ## read param
39 | global param
40 | param = np.load(runpath+'/param.npy').all()
41 |
42 | # import functions
43 | exec(open(funpath+'swm_param.py').read())
44 | exec(open(funpath+'swm_operators.py').read())
45 |
46 | set_grad_mat()
47 | set_interp_mat()
48 | set_lapl_mat()
49 | set_coriolis()
50 |
51 | tlen = len(t)
52 | ## create ouputfolder
53 | try:
54 | os.mkdir(runpath+'/analysis')
55 | except:
56 | pass
57 |
58 | ## reshape u,v
59 | u = u.reshape((tlen,param['Nu'])).T
60 | v = v.reshape((tlen,param['Nv'])).T
61 | eta = eta.reshape((tlen,param['NT'])).T
62 | print('Reshape done.')
63 |
64 | ## U,V,H mean
65 | # thickness-weighted averaging for u,v (Aiki, 2016)
66 | #etam = eta.mean(axis=1) # temporal average
67 | #um = (ITu.dot(eta + param['H'])*u).mean(axis=1) / ITu.dot(etam + param['H'])
68 | #vm = (ITv.dot(eta + param['H'])*v).mean(axis=1) / ITv.dot(etam + param['H'])
69 | #print('u,v,eta mean done.')
70 |
71 | # TOTAL KINETIC ENERGY
72 | #ke = .5*param['rho']*((eta+param['H'])*(IuT.dot(u**2) + IvT.dot(v**2))).mean(axis=1)
73 | # TOTAL (PERTURBATION) POTENTIAL ENERGY
74 | #pe = .5*param['rho']*param['g']*(eta**2).mean(axis=1)
75 | #print('KE, PE done.')
76 |
77 | # MEAN KINETIC ENERGY
78 | #mke = .5*param['rho']*(etam+param['H'])*(IuT.dot(um**2) + IvT.dot(vm**2))
79 | # Mean Potential Energy
80 | #mpe = .5*param['g']*param['rho']*etam**2
81 | #print('MKE, MPE done.')
82 |
83 | # Eddy potential energy
84 | #epe = .5*param['rho']*param['g']*eta.var(axis=1)
85 |
86 | # Eddy kinetic energy
87 | #uprime = ((u.T - um).T)
88 | #vprime = ((v.T - vm).T)
89 | #print('Prime anomalies done.')
90 |
91 | #eke = .5*param['rho']*((eta+param['H'])*(IuT.dot(uprime**2) + IvT.dot(vprime**2))).mean(axis=1)
92 | #print('EPE, EKE done.')
93 | #del uprime,vprime
94 |
95 | # SPEED MEAN
96 | #speedm = np.sqrt(IuT.dot(u**2) + IvT.dot(v**2)).mean(axis=1)
97 | #print('Rel Vort, Speed done.')
98 |
99 | ## ENERGY TIME SERIES
100 | PEm = (.5*param['g']*param['rho']*eta**2).mean(axis=0)
101 | print('Potential Energy done.')
102 |
103 | KEm = .5*param['rho']*((eta+param['H'])*(IuT.dot(u**2) + IvT.dot(v**2))).mean(axis=0)
104 | print('Kinetic Energy done.')
105 |
106 | ## STORING
107 | dic = dict()
108 | #all_var2export = ['um','vm','etam','ke','pe','mke','eke','mpe','epe','speedm']
109 | all_var2export = ['t','PEm','KEm']
110 |
111 | for v in all_var2export:
112 | exec('dic[v] ='+v)
113 |
114 | np.save(runpath+'/analysis/mean_timeseries.npy',dic)
115 | print('Everything stored.')
116 |
--------------------------------------------------------------------------------
/calc/spec_calc.py:
--------------------------------------------------------------------------------
1 | ## COMPUTE EKE SPECTRUM
2 | from __future__ import print_function
3 |
4 | # path
5 | import os
6 | #path = os.path.dirname(os.getcwd()) + '/' # on level above
7 | path = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
8 | os.chdir(path) # change working directory
9 |
10 | import numpy as np
11 | from scipy import sparse
12 |
13 | # OPTIONS
14 | # several entries in the list concatenates the runs and stores the result in the last folder
15 | runfolder = [5]
16 | print('Calculating eke spectrum from run ' + str(runfolder))
17 |
18 | ##
19 | def eke_spec_avg(u,v,dx,dy):
20 | """ Computes a wavenumber-frequency plot for 3D (t,x,y) data via radial (k = sqrt(kx**2 + ky**2)) integration. TODO: correct normalisation, so that the integral in normal space corresponds to the integral in Fourier space.
21 | """
22 |
23 | nt,ny,nx = np.shape(u)
24 | kx = (1/(dx))*np.hstack((np.arange(0,(nx+1)/2.),np.arange(-nx/2.+1,0)))/float(nx)
25 | ky = (1/(dy))*np.hstack((np.arange(0,(ny+1)/2.),np.arange(-ny/2.+1,0)))/float(ny)
26 |
27 | kxx,kyy = np.meshgrid(kx,ky)
28 | # radial distance from kx,ky = 0
29 | kk = np.sqrt(kxx**2 + kyy**2)
30 |
31 | if nx >= ny: #kill negative wavenumbers
32 | k = kx[:int(nx/2)+1]
33 | else:
34 | k = ky[:int(ny/2)+1]
35 |
36 | dk = k[1] - k[0]
37 |
38 | # 2D FFT average
39 | p_eke = np.empty((nt,ny,nx))
40 | nxy2 = nx**2*ny**2
41 |
42 | for i in range(nt):
43 | pu = abs(np.fft.fft2(u[i,:,:]))**2/nxy2
44 | pv = abs(np.fft.fft2(v[i,:,:]))**2/nxy2
45 | p_eke[i,:,:] = pu+pv
46 | if ((i+1)/nt*100 % 5) < (i/nt*100 % 5):
47 | print(str(int((i+1)/nt*100.))+'%')
48 |
49 | p_eke_avg = .5*p_eke.mean(axis=0)
50 |
51 | # create radial coordinates, associated with k[i]
52 | rcoords = []
53 | for i in range(len(k)):
54 | rcoords.append(np.where(kk= ny: #kill negative wavenumbers
31 | k = kx[:int(nx/2)+1]
32 | else:
33 | k = ky[:int(ny/2)+1]
34 |
35 | f = f[:int(nt/2)+1] #kill negative frequencies
36 | dk = k[1] - k[0]
37 |
38 | # create radial coordinates, associated with k[i]
39 | # nearest point interpolation to get points within the -.5,.5 annulus
40 | rcoords = []
41 | for i in range(len(k)):
42 | rcoords.append(np.where((kk>(k[i]-.5*dk))*(kk<=(k[i]+.5*dk))))
43 |
44 | # 3D FFT
45 | p = np.fft.fftn(a)
46 | p = np.real(p * np.conj(p))
47 |
48 | # mulitply by dk to have the corresponding integral
49 | spec = np.zeros((len(k),len(f)))
50 | for i in range(len(k)):
51 | spec[i,:] = np.sum(p[:int(nt/2)+1,rcoords[i][0],rcoords[i][1]],axis=1)*dk
52 |
53 | return k,f,spec
54 |
55 | ## read data
56 | for r,i in zip(runfolder,range(len(runfolder))):
57 | runpath = path+'data/run%04i' % r
58 |
59 | if i == 0:
60 | #u = np.load(runpath+'/u_sub.npy')
61 | #v = np.load(runpath+'/v_sub.npy')
62 | h = np.load(runpath+'/h_sub.npy')
63 | time = np.load(runpath+'/t_sub.npy')
64 | print('run %i read.' % r)
65 |
66 | else:
67 | #u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))
68 | #v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))
69 | h = np.concatenate((h,np.load(runpath+'/h_sub.npy')))
70 | time = np.hstack((time,np.load(runpath+'/t_sub.npy')))
71 | print('run %i read.' % r)
72 |
73 | t = time / 3600. / 24. # in days
74 | tlen = len(time)
75 | dt = time[1] - time[0]
76 |
77 | ## read param
78 | global param
79 | param = np.load(runpath+'/param.npy').all()
80 |
81 | ##
82 | k,f,spec3d = trispec(h,dt,param['dx'],param['dy'])
83 |
84 |
85 | ## rossby radius
86 | Ro_min = param['c_phase']/f_T.max()
87 | Ro_max = param['c_phase']/f_T.min()
88 | # dispersion relation
89 | Ro_disp_min = param['beta']*k/(k**2 + 1./Ro_min**2)
90 | Ro_disp_max = param['beta']*k/(k**2 + 1./Ro_max**2)
91 |
92 |
93 | ## plotting 3D
94 | sd = 3600.*24.
95 |
96 | fig,ax = plt.subplots(1,1)
97 | c1 = ax.contourf(k[1:]*1e3,f[1:]*sd,np.log10(spec3d[1:,1:].T),64,cmap='viridis')
98 | ax.loglog()
99 |
100 | plt.colorbar(c1,ax=ax)
101 |
102 | ax.plot(Ro_min*np.ones(2)*1e3,[1./f[-1]/sd,1/f[1]/sd],'w')
103 | ax.plot(Ro_max*np.ones(2)*1e3,[1./f[-1]/sd,1/f[1]/sd],'w')
104 |
105 | ax.plot(1./k[-1]*np.ones(2)/1e3,[1./f_T.min()/3600./24.,1./f_T.min()/3600./24.],'k')
106 | ax.plot(1./k[-1]*np.ones(2)/1e3,[1./f_T.max()/3600./24.,1./f_T.max()/3600./24.],'k')
107 |
108 |
109 | ax.plot(1./k[1:]/1e3,1./Ro_disp_min[1:]/3600./24.,'k')
110 | ax.plot(1./k[1:]/1e3,1./Ro_disp_max[1:]/3600./24.,'k')
111 |
112 | ax.set_xlim(1./k[-1]/1e3,1./k[1]/1e3)
113 | ax.set_ylim(1./f[-1],1./f[1])
114 |
115 | ax.set_xlabel('wavelength [km]')
116 | ax.set_ylabel('period [days]')
117 | ax.set_title('3D power spectrum of $\eta$')
118 | plt.tight_layout()
119 | plt.show()
--------------------------------------------------------------------------------
/calc/misc/Re_hist_calc.py:
--------------------------------------------------------------------------------
1 | ## HISTOGRAM COMPUTATIONS FOR REYNOLDS AND ROSSBY NUMBERS
2 | from __future__ import print_function
3 |
4 | # path
5 | import os
6 | path = os.path.dirname(os.getcwd()) + '/' # on level above
7 | os.chdir(path) # change working directory
8 |
9 | import numpy as np
10 | from scipy import sparse
11 |
12 | # OPTIONS
13 | runfolder = [0]
14 | print('Calculating Reynolds histograms from run ' + str(runfolder))
15 |
16 | ReH = []
17 | Re_mean = []
18 | Re_median = []
19 |
20 | ## read data - calculate each run separately
21 | for r,i in zip(runfolder,range(len(runfolder))):
22 | runpath = path+'data/run%04i' % r
23 |
24 | skip = 5*365
25 | u = np.load(runpath+'/u_sub.npy')[skip:,...]
26 | v = np.load(runpath+'/v_sub.npy')[skip:,...]
27 | eta = np.load(runpath+'/eta_sub.npy')[skip:,...]
28 | t = np.load(runpath+'/t_sub.npy')[skip:,...]
29 | print('run %i read.' % r)
30 |
31 | ## read param
32 | global param
33 | param = np.load(runpath+'/param.npy').all()
34 |
35 | # import functions
36 | exec(open(path+'swm_param.py').read())
37 | exec(open(path+'swm_operators.py').read())
38 |
39 | set_grad_mat()
40 | set_interp_mat()
41 | set_coriolis()
42 |
43 | tlen = len(t)
44 | ## create ouputfolder
45 | try:
46 | os.mkdir(runpath+'/analysis')
47 | except:
48 | pass
49 |
50 | ## reshape u,v
51 | u = u.reshape((tlen,param['Nu'])).T
52 | v = v.reshape((tlen,param['Nv'])).T
53 | h = eta.reshape((tlen,param['NT'])).T + param['H']
54 | print('Reshape done.')
55 |
56 | ## COMPUTE REYNOLDS, ROSSBY
57 | u_T = IuT.dot(u)
58 | v_T = IvT.dot(v)
59 | print('u,v interpolation done.')
60 |
61 | #advective term
62 | adv_u = u_T*Gux.dot(u) + v_T*IqT.dot(Guy.dot(u))
63 | adv_v = u_T*IqT.dot(Gvx.dot(v)) + v_T*Gvy.dot(v)
64 | del u_T,v_T
65 | adv_term = np.sqrt(adv_u**2 + adv_v**2)
66 | del adv_u, adv_v
67 | print('Advection term done.')
68 |
69 | #diffusive term
70 | S = (Gux.dot(u)-Gvy.dot(v),G2vx.dot(v) + G2uy.dot(u))
71 | del u,v
72 | hS = (h*S[0],ITq.dot(h)*S[1])
73 | del S
74 | print('Stress tensor S done.')
75 |
76 | diff_u = (GTx.dot(hS[0]) + Gqy.dot(hS[1])) / ITu.dot(h)
77 | diff_v = (Gqx.dot(hS[1]) - GTy.dot(hS[0])) / ITv.dot(h)
78 | del hS
79 | print('Harmonic part done.')
80 |
81 | # biharmonic stress tensor R = (R11, R12, R12, -R11), store only R11, R12
82 | R = (Gux.dot(diff_u) - Gvy.dot(diff_v), G2vx.dot(diff_v) + G2uy.dot(diff_u))
83 | del diff_u, diff_v
84 | hR = (h*R[0],ITq.dot(h)*R[1])
85 | del R
86 | print('Stress tensor R done.')
87 |
88 | bidiff_u = param['nu_B']*(GTx.dot(hR[0]) + Gqy.dot(hR[1])) / ITu.dot(h)
89 | bidiff_v = param['nu_B']*(Gqx.dot(hR[1]) - GTy.dot(hR[0])) / ITv.dot(h)
90 | del h,hR
91 | print('Biharmonic part done.')
92 |
93 | diff_term = np.sqrt(IuT.dot(bidiff_u**2) + IvT.dot(bidiff_v**2))
94 | print('Diff term done.')
95 | del bidiff_u,bidiff_v
96 |
97 | # actual number
98 | Re = (adv_term / diff_term).flatten()
99 | print('Re computed.')
100 | del adv_term, diff_term
101 |
102 | Re_mean.append(Re.mean())
103 | Re_median.append(np.median(Re))
104 | Re = np.log10(Re)
105 |
106 | # histogram
107 | Re_min = -3. # in log scale
108 | Re_max = 5.
109 | N = 300
110 |
111 | ReH_temp,Re_edges = np.histogram(Re,np.linspace(Re_min,Re_max,N))
112 | print('Re histogram done.')
113 | del Re
114 |
115 | # store each run in a list
116 | ReH.append(ReH_temp)
117 |
118 | Re_mid = Re_edges[:-1] + np.diff(Re_edges)/2.
119 |
120 |
121 | ReH = np.array(ReH).sum(axis=0)
122 | Re_mean = np.array(Re_mean).mean()
123 | Re_median = np.median(np.array(Re_median)) #actually median of medians though...
124 |
125 | ## STORING in last
126 | dic = dict()
127 | all_var2export = ['ReH','Re_mid','Re_edges','Re_mean','Re_median']
128 |
129 | for vars in all_var2export:
130 | exec('dic[vars] ='+vars)
131 |
132 | np.save(runpath+'/analysis/Re_hist.npy',dic)
133 |
--------------------------------------------------------------------------------
/calc/misc/diss_vis.py:
--------------------------------------------------------------------------------
1 | ## UNDERSTANDING DISSIPATION
2 | from __future__ import print_function
3 | path = '/home/mkloewer/python/swm/'
4 | import os; os.chdir(path) # change working directory
5 | import numpy as np
6 | from scipy import sparse
7 | from scipy.integrate import cumtrapz
8 | import matplotlib.pyplot as plt
9 | import time as tictoc
10 | from netCDF4 import Dataset
11 | import glob
12 | from cmocean import cm
13 |
14 | # import functions
15 | exec(open(path+'swm_param.py').read())
16 | exec(open(path+'swm_operators.py').read())
17 | exec(open(path+'swm_output.py').read())
18 | exec(open(path+'stoch/swm_rhs.py').read())
19 |
20 | ## OPTIONS
21 | runfolder = [3,10]
22 |
23 | ## read data
24 | runpath = path+'data/run%04i' % runfolder[0]
25 | ncu = Dataset(runpath+'/u.nc')
26 | ncv = Dataset(runpath+'/v.nc')
27 | nch = Dataset(runpath+'/h.nc')
28 |
29 | u1 = ncu['u'][-1000,:,:].flatten()
30 | v1 = ncv['v'][-1000,:,:].flatten()
31 | h1 = nch['h'][-1000,:,:].flatten()
32 | print('netCDF data read.')
33 |
34 | # close netcdfs
35 | ncu.close()
36 | ncv.close()
37 | nch.close()
38 |
39 | param1 = np.load(runpath+'/param.npy').all()
40 | param1['output'] = 0
41 |
42 | ##
43 | runpath = path+'data/run%04i' % runfolder[1]
44 | ncu = Dataset(runpath+'/u.nc')
45 | ncv = Dataset(runpath+'/v.nc')
46 | nch = Dataset(runpath+'/h.nc')
47 |
48 | u2 = ncu['u'][-1,:,:].flatten()
49 | v2 = ncv['v'][-1,:,:].flatten()
50 | h2 = nch['h'][-1,:,:].flatten()
51 | print('netCDF data read.')
52 |
53 | # close netcdfs
54 | ncu.close()
55 | ncv.close()
56 | nch.close()
57 |
58 | param2 = np.load(runpath+'/param.npy').all()
59 | param2['output'] = 0
60 |
61 | ##
62 | global param
63 |
64 | def Q1(u,v,h):
65 |
66 | set_grad_mat()
67 | set_interp_mat()
68 | set_lapl_mat()
69 | set_coriolis()
70 |
71 | h_u = ITu.dot(h) # h on u-grid
72 | h_v = ITv.dot(h) # h on v-grid
73 | h_q = ITq.dot(h) # h on q-grid
74 |
75 | dudx = Gux.dot(u)
76 | dudy = Guy.dot(u)
77 | dvdx = Gvx.dot(v)
78 | dvdy = Gvy.dot(v)
79 |
80 | #diff_u, diff_v = mixing(u,v,h,h_q,h_u,h_v) # harmonic
81 | #bidiff_u, bidiff_v = mixing(diff_u,diff_v,h,h_q,h_u,h_v) # apply twice = biharmonic
82 |
83 | diss_e = (dudx*Gux.dot(Lu.dot(u)) + dvdy*Gvy.dot(Lv.dot(v)))
84 |
85 | return diss_e
86 |
87 | def Q2(u,v,h):
88 |
89 | set_grad_mat()
90 | set_interp_mat()
91 | set_lapl_mat()
92 | set_coriolis()
93 |
94 | h_u = ITu.dot(h) # h on u-grid
95 | h_v = ITv.dot(h) # h on v-grid
96 | h_q = ITq.dot(h) # h on q-grid
97 |
98 | dudx = Gux.dot(u)
99 | dudy = Guy.dot(u)
100 | dvdx = Gvx.dot(v)
101 | dvdy = Gvy.dot(v)
102 |
103 | diff_u, diff_v = mixing(u,v,h,h_q,h_u,h_v) # harmonic
104 | bidiff_u, bidiff_v = mixing(diff_u,diff_v,h,h_q,h_u,h_v) # apply twice = biharmonic
105 |
106 | #bidiff_u = LLu.dot(u)
107 | #bidiff_v = LLv.dot(v)
108 |
109 | #diss_e = param['B']*(dudx*Gux.dot(Lu.dot(u)) + dvdy*Gvy.dot(Lv.dot(v)))
110 |
111 | return IuT.dot(u*bidiff_u) + IvT.dot(v*bidiff_v)
112 |
113 | param = param2
114 | q = Q1(u2,v2,h2+param['H'])
115 | q2 = Q2(u2,v2,h2+param['H'])
116 |
117 | ## plotting
118 | fig,(ax1,ax2) = plt.subplots(1,2,sharex=True,sharey=True,figsize=(12,6))
119 | plt.tight_layout(rect=[0,0,1,0.95])
120 |
121 | pq = q*2e16*100
122 | pq2 = q2*2e16
123 |
124 | levs = np.linspace(-abs(pq2).max()*0.02,abs(pq2).max()*0.02,64)
125 |
126 | param = param2
127 | c = ax1.contourf(param2['x_T'],param2['y_T'],h2mat(pq),levs,extend='both',cmap='RdBu_r')
128 | c = ax2.contourf(param2['x_T'],param2['y_T'],h2mat(pq2),levs,extend='both',cmap='RdBu_r')
129 |
130 | ax1.set_xticks([])
131 | ax1.set_yticks([])
132 | ax1.set_xlabel('x')
133 | ax2.set_xlabel('x')
134 | ax1.set_ylabel('y')
135 |
136 | ax1.set_xlim(571e3,1824e3)
137 | ax1.set_ylim(1051e3,2131e3)
138 |
139 | ax1.set_title(r'$100*\nabla\mathbf{u} \cdot \nabla(\nabla^2\mathbf{u})$')
140 | ax2.set_title(r'$\mathbf{u} \cdot \nabla^4\mathbf{u}$')
141 |
142 | cbar = plt.colorbar(c,ax=(ax1,ax2),ticks=[-1,-0.5,0,0.5,1])
143 | cbar.set_label(r'[$2 \cdot 10^{-16}m^{-2}s^{-2}$]')
144 | plt.show()
--------------------------------------------------------------------------------
/calc/floats/floats_calc_meanflow.py:
--------------------------------------------------------------------------------
1 | ## LAGRANGIAN FLOATS
2 | import numpy as np
3 | from netCDF4 import Dataset
4 | from scipy.interpolate import RegularGridInterpolator as RGI
5 |
6 | path = '/home/mkloewer/python/swm/'
7 |
8 | # OPTIONS
9 | runfolder = [14]
10 | print('Calculating floats from run ' + str(runfolder))
11 |
12 | ## pad function for u,v
13 | def uv_pad(u,v):
14 | """ Pads u,v with kinematic and lateral boundary conditions. """
15 | bs = 0 # boundary speed (positive inwards)
16 | u = np.pad(u,((1,1),(1,1)),'constant',constant_values=((bs,-bs),(bs,-bs))) # kinematic bc
17 | v = np.pad(v,((1,1),(1,1)),'constant',constant_values=((bs,-bs),(bs,-bs)))
18 |
19 | return u,v
20 |
21 | runpath = path+'data/run%04i' % runfolder[0]
22 |
23 | D = np.load(runpath+'/analysis/mean.npy').all()
24 | param = np.load(runpath+'/param.npy').all()
25 |
26 | u = D['um'].reshape((param['ny'],param['nx']-1))
27 | v = D['vm'].reshape((param['ny']-1,param['nx']))
28 |
29 | dt = 6*3600.
30 |
31 | # renaming for convenience
32 | x_u = param['x_u']
33 | y_u = param['y_u']
34 |
35 | x_v = param['x_v']
36 | y_v = param['y_v']
37 |
38 | # pad x,y to include the boundary conditions
39 | # grid is not equidistant at the boundary however ...
40 | x_u = np.hstack((0.,x_u,param['Lx']))
41 | y_u = np.hstack((0.,y_u,param['Ly']))
42 |
43 | y_v = np.hstack((0,y_v,param['Ly']))
44 | x_v = np.hstack((0,x_v,param['Lx']))
45 |
46 | print('Grid read.')
47 |
48 | ## OPTIONS
49 | N = 10000 # number of floats
50 | ntime = 1460 # number of timesteps to integrate forward: equals one year
51 | R_chunk = 10
52 |
53 | # preallocate
54 | nbins = 254
55 | H = np.zeros((nbins,nbins))
56 |
57 | #exclude up to 30km from boundary
58 | Hrange = [[30e3,3810e3],[30e3,3810e3]]
59 |
60 | # edges of inital seeding region
61 | seedx = np.array([100,200])*1e3
62 | seedy = np.array([100,1920])*1e3
63 | def u2mat(u):
64 | return u.reshape((param['ny'],param['nx']-1))
65 |
66 | def v2mat(v):
67 | return v.reshape((param['ny']-1,param['nx']))
68 |
69 | # padding with boundary conditions
70 | u,v = uv_pad(u,v)
71 | print('Padding boundary conditions: done.')
72 |
73 | # Advect the floats
74 | Xa = np.empty((ntime,N,R_chunk)).astype(np.float64)
75 | Ya = np.empty_like(Xa)
76 |
77 | # preallocate
78 | X = np.empty((ntime,N)).astype(np.float64)
79 | Y = np.empty_like(X).astype(np.float64)
80 |
81 | for r in range(R_chunk):
82 | print(r)
83 |
84 | # set initial conditions
85 | X[0,:] = np.random.rand(N)*np.diff(seedx) + seedx[0]
86 | Y[0,:] = np.random.rand(N)*np.diff(seedy) + seedy[0]
87 |
88 | # interpolation function
89 | Iu = RGI((x_u,y_u),u.T,bounds_error=False,fill_value=0)
90 | Iv = RGI((x_v,y_v),v.T,bounds_error=False,fill_value=0)
91 |
92 | for i in range(ntime-1):
93 | # Following the ideas of the Crank-Nicolson method
94 | # However, as the RHS is discrete, Euler forward is used to estimate
95 | # the RHS of the next time step
96 |
97 | # old RHS
98 | dXdt1 = Iu((X[i,:],Y[i,:]))
99 | dYdt1 = Iv((X[i,:],Y[i,:]))
100 |
101 | # new RHS
102 | dXdt2 = Iu((X[i,:] + dt*dXdt1,Y[i,:] + dt*dYdt1))
103 | dYdt2 = Iv((X[i,:] + dt*dXdt1,Y[i,:] + dt*dYdt1))
104 |
105 | # average of old and new RHS
106 | X[i+1,:] = X[i,:] + 0.5*dt*(dXdt1+dXdt2)
107 | Y[i+1,:] = Y[i,:] + 0.5*dt*(dYdt1+dYdt2)
108 |
109 | Xa[:,:,r] = X
110 | Ya[:,:,r] = Y
111 |
112 | print('Advecting floats done.')
113 |
114 | # free memory
115 | del u,v
116 |
117 | # histogram do not count the grid cell at the boundary
118 | Hi,xe,ye = np.histogram2d(Xa.flatten(),Ya.flatten(),bins=nbins,range=Hrange)
119 | H += Hi
120 | print('Histogram computed.')
121 |
122 | # free memory
123 | del Xa,Ya
124 |
125 |
126 | print(H.sum())
127 |
128 | # mid points
129 | xm = xe[:-1] + (xe[1]-xe[0])/2.
130 | ym = ye[:-1] + (ye[1]-ye[0])/2.
131 |
132 | ## STORING
133 | dic = dict()
134 | all_var2export = ['X','Y','seedx','seedy','H','xe','ye','xm','ym']
135 |
136 | for vars in all_var2export:
137 | exec('dic[vars] ='+vars)
138 |
139 | np.save(runpath+'/analysis/floats_meanflow.npy',dic)
140 | print('Everything stored.')
141 |
--------------------------------------------------------------------------------
/plot/powermap_plot.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 |
3 | path = '/network/home/aopp/kloewer/strix/'
4 | dpath = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
5 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
6 |
7 | import os; os.chdir(path) # change working directory
8 | import numpy as np
9 | from scipy import sparse
10 | import matplotlib.pyplot as plt
11 | import time as tictoc
12 | from netCDF4 import Dataset
13 | import glob
14 | from matplotlib.colors import BoundaryNorm,LogNorm
15 | import cmocean
16 |
17 | plt.rcParams['mathtext.fontset'] = 'cm'
18 | plt.rcParams['mathtext.rm'] = 'serif'
19 |
20 | # OPTIONS
21 | runfolder = [0,6]
22 | print('Plots for run ' + str(runfolder))
23 |
24 | ## read data
25 |
26 | runpath1 = path+'run%04i' % runfolder[0]
27 | D1 = np.load(runpath1+'/analysis/power_map.npy').all()
28 | param1 = np.load(runpath1+'/param.npy').all()
29 |
30 | runpath2 = path+'run%04i' % runfolder[1]
31 | D2 = np.load(runpath2+'/analysis/power_map.npy').all()
32 | param2 = np.load(runpath2+'/param.npy').all()
33 |
34 | # functions
35 | def h2mat(h,param):
36 | return h.reshape((param['ny'],param['nx']))
37 |
38 | def u2mat(u,param):
39 | return u.reshape((param['ny'],param['nx']-1))
40 |
41 | def v2mat(v,param):
42 | return v.reshape((param['ny']-1,param['nx']))
43 |
44 | def q2mat(q,param):
45 | return q.reshape((param['ny']+1,param['nx']+1))
46 | ##
47 |
48 | m = [0]*6
49 | s = 1e3
50 |
51 | in1 = h2mat(D1['InPower_T'],param1)*s
52 | m[0] = in1.mean()
53 | in1 = np.sign(in1)*np.sqrt(abs(in1))
54 |
55 | ex1 = h2mat(D1['ExPower_T'],param1)*s
56 | m[2] = ex1.mean()
57 | ex1 = np.sign(ex1)*np.sqrt(abs(ex1))
58 |
59 | bf1 = h2mat(D1['BfricPower_T'],param1)*s
60 | m[1] = bf1.mean()
61 | bf1 = np.sign(bf1)*np.sqrt(abs(bf1))
62 |
63 | in2 = h2mat(D2['InPower_T'],param2)*s
64 | m[3] = in2.mean()
65 | in2 = np.sign(in2)*np.sqrt(abs(in2))
66 |
67 | ex2 = h2mat(D2['ExPower_T'],param2)*s
68 | m[5] = ex2.mean()
69 | ex2 = np.sign(ex2)*np.sqrt(abs(ex2))
70 |
71 | bf2 = h2mat(D2['BfricPower_T'],param2)*s
72 | m[4] = bf2.mean()
73 | bf2 = np.sign(bf2)*np.sqrt(abs(bf2))
74 |
75 | m = [np.round(mi,2) for mi in m]
76 |
77 | ## PLOTTING
78 |
79 | fig,axs = plt.subplots(2,3,figsize=(10,7),sharex=True,sharey=True)
80 |
81 | plt.tight_layout(rect=[0,.08,1,0.98])
82 | fig.subplots_adjust(wspace=0.03,hspace=0.03)
83 |
84 | pos = axs[-1,0].get_position()
85 | pos2 = axs[-1,-1].get_position()
86 | cax = fig.add_axes([pos.x0,0.08,pos2.x1-pos.x0,0.02])
87 |
88 | levs = np.linspace(-np.sqrt(90),np.sqrt(90),64)
89 | tik = np.array([-90,-60,-30,-10,-3,0,3,10,30,60,90])
90 | tik = np.sign(tik)*np.sqrt(abs(tik))
91 |
92 | q1 = axs[0,0].contourf(param1['x_T'],param1['y_T'],in1,levs,cmap=cmocean.cm.balance,extend='both')
93 | axs[0,2].contourf(param1['x_T'],param1['y_T'],ex1,levs,cmap=cmocean.cm.balance,extend='both')
94 | cbar = fig.colorbar(q1,cax=cax,orientation='horizontal',ticks=tik)
95 | cbar.set_label(r'Power [Wm$^{-2} \cdot 10^{-3}$]')
96 | cbar.set_ticklabels(np.round(tik**2*np.sign(tik)).astype(int))
97 |
98 |
99 | axs[1,0].contourf(param2['x_T'],param2['y_T'],in2,levs,cmap=cmocean.cm.balance,extend='both')
100 | axs[1,2].contourf(param2['x_T'],param2['y_T'],ex2,levs,cmap=cmocean.cm.balance,extend='both')
101 |
102 | axs[0,1].contourf(param1['x_T'],param1['y_T'],bf1,levs,cmap=cmocean.cm.balance,extend='both')
103 | axs[1,1].contourf(param2['x_T'],param2['y_T'],bf2,levs,cmap=cmocean.cm.balance,extend='both')
104 |
105 | axs[0,0].set_title('Wind forcing power',loc='left')
106 | axs[0,2].set_title('Biharmonic viscosity power',loc='left')
107 | axs[0,1].set_title('Bottom friction power',loc='left')
108 |
109 | abc = 'abcdef'
110 | abci = 0
111 | for axcol in axs:
112 | for ax in axcol:
113 | plt.text(0.93,0.93,abc[abci],transform=ax.transAxes,fontweight='bold')
114 | plt.text(0.97,0.88,"%.2f" % m[abci],transform=ax.transAxes,ha='right')
115 | abci += 1
116 |
117 | axs[0,0].set_xticks([])
118 | axs[0,0].set_yticks([])
119 |
120 | axs[0,0].set_ylabel(r'Low resolution, $\Delta x = $30km')
121 | axs[1,0].set_ylabel(r'High resolution, $\Delta x = $7.5km')
122 |
123 | axs[-1,0].set_xlabel(r'$x$')
124 | axs[-1,1].set_xlabel(r'$x$')
125 | axs[-1,2].set_xlabel(r'$x$')
126 |
127 | axs[0,2].set_ylabel(r'$y$')
128 | axs[0,2].yaxis.set_label_position('right')
129 |
130 | axs[1,2].set_ylabel(r'$y$')
131 | axs[1,2].yaxis.set_label_position('right')
132 |
133 | plt.savefig(outpath+'plots/power_maps.png',dpi=150)
134 | plt.close(fig)
135 |
--------------------------------------------------------------------------------
/plot/pv_gradient.py:
--------------------------------------------------------------------------------
1 | ## PLOT STREAMFUNCTION
2 | from __future__ import print_function
3 | #path = '/home/mkloewer/python/swm/'
4 | path = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/data/'
5 | path2 = '/home/kloewer/git/swm/'
6 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
7 |
8 | import numpy as np
9 | from scipy import sparse
10 | import matplotlib.pyplot as plt
11 | from cmocean import cm
12 |
13 | plt.rcParams['mathtext.fontset'] = 'cm'
14 | plt.rcParams['mathtext.rm'] = 'serif'
15 |
16 |
17 | # OPTIONS
18 | runfolder = [0,6,8]
19 | print('Compare mean plots from run ' + str(runfolder))
20 |
21 | ## read data
22 |
23 | runpath1 = path+'run%04i' % runfolder[0]
24 | D1 = np.load(runpath1+'/analysis/mean_pv.npy').all()
25 | param1 = np.load(runpath1+'/param.npy').all()
26 |
27 | runpath2 = path+'run%04i' % runfolder[1]
28 | D2 = np.load(runpath2+'/analysis/mean_pv.npy').all()
29 | param2 = np.load(runpath2+'/param.npy').all()
30 |
31 | runpath3 = path+'run%04i' % runfolder[2]
32 | D3 = np.load(runpath3+'/analysis/mean_pv.npy').all()
33 | param3 = np.load(runpath3+'/param.npy').all()
34 |
35 | def q2mat(q,param):
36 | return q.reshape((param['ny']+1,param['nx']+1))
37 |
38 | def u2mat(u,param):
39 | return u.reshape((param['ny'],param['nx']-1))
40 |
41 | def v2mat(v,param):
42 | return v.reshape((param['ny']-1,param['nx']))
43 |
44 | def fq(param):
45 | y_q = param['y_q']
46 | Ly = param['Ly']
47 |
48 | # subtract the regions mid-y so that phi_0 corresponds to a central latitude
49 | yy_q = np.array([y_q - Ly/2.]*(param['nx']+1)).T
50 |
51 | # globally available coriolis parameters (only f_q is actually needed though)
52 | f_q = param['f_0'] + param['beta']*yy_q.flatten()
53 |
54 | return f_q
55 |
56 |
57 | ## Plotting
58 | fig,axs = plt.subplots(2,3,sharex=True,sharey=True,figsize=(12,9))
59 | fig.tight_layout(rect=[0.02,.15,1.,0.98])
60 | fig.subplots_adjust(wspace=0.03,hspace=0.1)
61 |
62 | pos = axs[0,0].get_position()
63 | pos2 = axs[0,2].get_position()
64 | cax = fig.add_axes([pos.x0,0.12,pos2.x1-pos.x0,0.02])
65 | cax2 = fig.add_axes([pos.x0,0.05,pos2.x1-pos.x0,0.02])
66 |
67 | s = 1e3 # scaling factor m -> km
68 | n = 10
69 |
70 | levs = np.linspace(6e-8,2.2e-7,17)
71 | levs2 = np.linspace(-2e-8,2e-8,17)
72 |
73 | # PV mean
74 | q1 = axs[0,0].contourf(param1['x_q']/s,param1['y_q']/s,q2mat(D1['qm'],param1),levs,extend='both')
75 | axs[0,1].contourf(param3['x_q']/s,param3['y_q']/s,q2mat(D3['qm'],param3),levs,extend='both')
76 | axs[0,2].contourf(param2['x_q']/s,param2['y_q']/s,q2mat(D2['qm'],param2),levs,extend='both')
77 |
78 | q2 = axs[1,0].contourf(param1['x_q']/s,param1['y_q']/s,q2mat(D1['qm']-fq(param1)/param1['H'],param1),levs2,extend='both',cmap=cm.balance)
79 | axs[1,1].contourf(param3['x_q']/s,param3['y_q']/s,q2mat(D3['qm']-fq(param3)/param3['H'],param3),levs2,extend='both',cmap=cm.balance)
80 | axs[1,2].contourf(param2['x_q']/s,param2['y_q']/s,q2mat(D2['qm']-fq(param2)/param2['H'],param2),levs2,extend='both',cmap=cm.balance)
81 |
82 | # PV gradient
83 | #axs[1].quiver(param3['x_q'][::n]/s,param3['y_q'][::n]/s,v2mat(D3['dqm_dx'],param3)[::n,::n],u2mat(D3['dqm_dy'],param3)[::n,::n])
84 |
85 |
86 | fig.colorbar(q1,cax=cax,orientation='horizontal')
87 | cbar = fig.colorbar(q2,cax=cax2,orientation='horizontal')
88 | cbar.set_label(r'Potential Vorticity [m$^{-1}$s$^{-1}$]')
89 | axs[0,0].set_xticks([0,1000,2000,3000])
90 | axs[0,0].set_yticks([0,1000,2000,3000])
91 |
92 | axs[0,0].set_xlim(0,param1['Lx']/s)
93 | axs[0,0].set_ylim(0,param1['Ly']/s)
94 | axs[0,0].set_ylabel(r'$y$ [km]')
95 | axs[1,0].set_ylabel(r'$y$ [km]')
96 | axs[1,0].set_xlabel(r'$x$ [km]')
97 | axs[1,1].set_xlabel(r'$x$ [km]')#
98 | axs[1,2].set_xlabel(r'$x$ [km]')
99 |
100 | axs[0,0].set_title(r'PV, $\Delta x = $30km, no-slip')
101 | axs[0,1].set_title(r'PV, $\Delta x = $15km, free-slip')
102 | axs[0,2].set_title(r'PV, $\Delta x = $7.5km, no-slip')
103 |
104 | axs[1,0].set_title(r'PV - f/H, $\Delta x = $30km, no-slip')
105 | axs[1,1].set_title(r'PV - f/H, $\Delta x = $15km, free-slip')
106 | axs[1,2].set_title(r'PV - f/H, $\Delta x = $7.5km, no-slip')
107 |
108 | axs[0,0].set_title('a',fontweight='bold',loc='left')
109 | axs[0,1].set_title('b',fontweight='bold',loc='left')
110 | axs[0,2].set_title('c',fontweight='bold',loc='left')
111 |
112 | axs[1,0].set_title('d',fontweight='bold',loc='left')
113 | axs[1,1].set_title('e',fontweight='bold',loc='left')
114 | axs[1,2].set_title('f',fontweight='bold',loc='left')
115 |
116 | plt.savefig(outpath+'plots/pv_gradient.pdf')
117 | plt.close(fig)
118 |
--------------------------------------------------------------------------------
/plot/powermap_bs_crosssection.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 |
3 | path = '/network/home/aopp/kloewer/strix/'
4 | dpath = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
5 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
6 |
7 | import os; os.chdir(path) # change working directory
8 | import numpy as np
9 | from scipy import sparse
10 | import matplotlib.pyplot as plt
11 | import time as tictoc
12 | from netCDF4 import Dataset
13 | import glob
14 | from matplotlib.colors import BoundaryNorm,LogNorm
15 | import cmocean
16 |
17 | plt.rcParams['mathtext.fontset'] = 'cm'
18 | plt.rcParams['mathtext.rm'] = 'serif'
19 |
20 | # OPTIONS
21 | runfolder = [0,6,2]
22 | print('Plots for run ' + str(runfolder))
23 |
24 | ## read data
25 |
26 | runpath1 = path+'run%04i' % runfolder[0]
27 | D1 = np.load(runpath1+'/analysis/power_map.npy').all()
28 | param1 = np.load(runpath1+'/param.npy').all()
29 |
30 | runpath2 = path+'run%04i' % runfolder[1]
31 | D2 = np.load(runpath2+'/analysis/power_map.npy').all()
32 | param2 = np.load(runpath2+'/param.npy').all()
33 |
34 | runpath3 = dpath+'run%04i' % runfolder[2]
35 | D3 = np.load(runpath3+'/analysis/power_map.npy').all()
36 | param3 = np.load(runpath3+'/param.npy').all()
37 | print(param3['n_diss'])
38 |
39 | # functions
40 | def h2mat(h,param):
41 | return h.reshape((param['ny'],param['nx']))
42 |
43 | def u2mat(u,param):
44 | return u.reshape((param['ny'],param['nx']-1))
45 |
46 | def v2mat(v,param):
47 | return v.reshape((param['ny']-1,param['nx']))
48 |
49 | def q2mat(q,param):
50 | return q.reshape((param['ny']+1,param['nx']+1))
51 | ##
52 |
53 | m = [0]*(len(runfolder)*3)
54 | s = 1e3
55 |
56 | # LOW RESOLUTION RUN
57 | in1 = h2mat(D1['InPower_T'],param1)*s
58 | m[0] = in1.mean()
59 | in1 = np.sign(in1)*np.sqrt(abs(in1))
60 |
61 | bf1 = h2mat(D1['BfricPower_T'],param1)*s
62 | m[1] = bf1.mean()
63 | bf1 = np.sign(bf1)*np.sqrt(abs(bf1))
64 |
65 | ex1 = h2mat(D1['ExPower_T'],param1)*s
66 | m[2] = ex1.mean()
67 | #ex1 = np.sign(ex1)*np.sqrt(abs(ex1))
68 |
69 | # BACKSCATTER RUN
70 | in3 = h2mat(D3['InPower_T'],param3)*s
71 | m[3] = in3.mean()
72 | in3 = np.sign(in3)*np.sqrt(abs(in3))
73 |
74 | bf3 = h2mat(D3['BfricPower_T'],param3)*s
75 | m[4] = bf3.mean()
76 | bf3 = np.sign(bf3)*np.sqrt(abs(bf3))
77 |
78 | D3['ExPower_T'] += D3['BackPower_T']
79 |
80 | ex3 = h2mat(D3['ExPower_T'],param3)*s
81 | m[5] = ex3.mean()
82 | #ex3 = np.sign(ex3)*np.sqrt(abs(ex3))
83 |
84 | # bs = h2mat(D3['BackPower_T'],param3)*s
85 | # m[6] = bs.mean()
86 | # bs = np.sign(bs)*np.sqrt(abs(bs))
87 |
88 | # HIGH RESOLUTION RUN
89 | in2 = h2mat(D2['InPower_T'],param2)*s
90 | m[6] = in2.mean()
91 | in2 = np.sign(in2)*np.sqrt(abs(in2))
92 |
93 | bf2 = h2mat(D2['BfricPower_T'],param2)*s
94 | m[7] = bf2.mean()
95 | bf2 = np.sign(bf2)*np.sqrt(abs(bf2))
96 |
97 | ex2 = h2mat(D2['ExPower_T'],param2)*s
98 | m[8] = ex2.mean()
99 | #ex2 = np.sign(ex2)*np.sqrt(abs(ex2))
100 |
101 | mround = [np.round(mi,2) for mi in m]
102 |
103 | ## PLOTTING
104 |
105 | fig,(ax,ax2) = plt.subplots(2,1)
106 |
107 | s1 = slice(32,96,1) # for low resolution from y/4 to 3y/4
108 | s2 = slice(128,384,1) # for high resolution
109 |
110 | ax.plot((param1['x_T']-param1['dx']/2.)/1e3,ex1[s1,:].mean(axis=0),'C0',drawstyle='steps-post')
111 | ax.plot((param2['x_T']-param2['dx']/2.)/1e3,ex2[s2,:].mean(axis=0),'C2',drawstyle='steps-post')
112 | ax.plot((param3['x_T']-param3['dx']/2.)/1e3,ex3[s1,:].mean(axis=0),'C3',drawstyle='steps-post')
113 |
114 | ax2.plot((param1['x_T']-param1['dx']/2.)/1e3,ex1[s1,:].mean(axis=0),'C0',label='Low resolution, $\Delta x = 30$km',drawstyle='steps-post')
115 | ax2.plot((param2['x_T']-param2['dx']/2.)/1e3,ex2[s2,:].mean(axis=0),'C2',label='High resolution, $\Delta x = 7.5$km',drawstyle='steps-post')
116 | ax2.plot((param3['x_T']-param3['dx']/2.)/1e3,ex3[s1,:].mean(axis=0),'C3',label='LR + moderate backscatter',drawstyle='steps-post')
117 |
118 | ax.set_ylim(-20,20)
119 | ax.set_xlim(0,param1['Lx']/1e3)
120 |
121 | #ax2.set_ylim(-20,20)
122 | ax2.set_xlim(0,param1['Lx']/1e3/6)
123 |
124 |
125 | ax.set_title(r'Biharm. viscosity + backscatter power, $y=\frac{L_y}{4} \colon \frac{3L_y}{4}$@average')
126 | ax2.set_title('Zoom in in $x$, zoom out in y-axis')
127 | ax.set_title('(a)',loc='left')
128 | ax2.set_title('(b)',loc='left')
129 |
130 |
131 | ax.set_ylabel(r'mW/m$^2$')
132 | ax2.set_ylabel(r'mW/m$^2$')
133 | ax.set_xlabel('$x$ [km]')
134 | ax2.set_xlabel('$x$ [km]')
135 |
136 | ax2.legend(loc=4)
137 |
138 | plt.tight_layout()
139 | plt.savefig(outpath+'plots/power_maps_bs_crosssection.png',dpi=150)
140 | plt.close(fig)
141 |
--------------------------------------------------------------------------------
/calc/misc/c_diss_plot.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | path = '/home/mkloewer/python/swm/'
3 | import os; os.chdir(path) # change working directory
4 | import numpy as np
5 | from scipy import sparse
6 | import time as tictoc
7 | from netCDF4 import Dataset
8 | import glob
9 | import matplotlib.pyplot as plt
10 |
11 | # OPTIONS
12 | runfolder = [2,3]
13 |
14 | ## read data
15 | for r,i in zip(runfolder,range(len(runfolder))):
16 | runpath = path+'data/run%04i' % r
17 |
18 | if i == 0:
19 | u = np.load(runpath+'/u_sub.npy')
20 | v = np.load(runpath+'/v_sub.npy')
21 | h = np.load(runpath+'/h_sub.npy')
22 | time = np.load(runpath+'/t_sub.npy')
23 | print('run %i read.' % r)
24 |
25 | else:
26 | u = np.concatenate((u,np.load(runpath+'/u_sub.npy')))
27 | v = np.concatenate((v,np.load(runpath+'/v_sub.npy')))
28 | h = np.concatenate((h,np.load(runpath+'/h_sub.npy')))
29 | time = np.hstack((time,np.load(runpath+'/t_sub.npy')))
30 | print('run %i read.' % r)
31 |
32 | t = time / 3600. / 24. # in days
33 | ## read param
34 | global param
35 | param = np.load(runpath+'/param.npy').all()
36 | param['dat_type'] = np.float32
37 |
38 | # import functions
39 | exec(open(path+'swm_param.py').read())
40 | exec(open(path+'swm_operators.py').read())
41 | exec(open(path+'swm_output.py').read())
42 | param['output'] = 0
43 |
44 | set_grad_mat()
45 | set_interp_mat()
46 | set_lapl_mat()
47 | set_coriolis()
48 |
49 | tlen = len(time)
50 | ## create ouputfolder
51 | try:
52 | os.mkdir(runpath+'/analysis')
53 | except:
54 | pass
55 |
56 | ## reshape u,v
57 | u = u.reshape((tlen,param['Nu'])).T
58 | v = v.reshape((tlen,param['Nv'])).T
59 | h = h.reshape((tlen,param['NT'])).T
60 | print('Reshape done.')
61 |
62 | ##
63 | dudx = Gux.dot(u)
64 | dudy = Guy.dot(u)
65 | dvdx = Gvx.dot(v)
66 | dvdy = Gvy.dot(v)
67 |
68 | n = 2
69 |
70 | D = np.sqrt((dudx - dvdy)**2 + IqT.dot((dudy + dvdx)**2))
71 | Ro = (D.T/f_T)
72 | Rom = Ro.mean(axis=0)
73 | c = (1/(1+Ro)**n).mean(axis=0)
74 |
75 | # REYNOLDS, ROSSBY, EKMAN NUMBER MEAN
76 | u_T = IuT.dot(u)
77 | v_T = IvT.dot(v)
78 | print('u,v interpolation done.')
79 |
80 | #advective term
81 | adv_u = u_T*Gux.dot(u) + v_T*IqT.dot(Guy.dot(u))
82 | adv_v = u_T*IqT.dot(Gvx.dot(v)) + v_T*Gvy.dot(v)
83 | del u_T,v_T
84 | adv_term = np.sqrt(adv_u**2 + adv_v**2)
85 | del adv_u, adv_v
86 | print('Advection term done.')
87 |
88 | #coriolis term
89 | cor_term = (f_T*np.sqrt(IuT.dot(u**2) + IvT.dot(v**2)).T).T
90 | print('Coriolis term done.')
91 |
92 | Ro2 = adv_term / cor_term
93 | c2 = (1/(1+Ro2)**n).mean(axis=1)
94 | Ro2m = Ro2.mean(axis=1)
95 |
96 | ##
97 | levs1 = np.linspace(0,.2,21)
98 | levs2 = np.linspace(0.5,1,21)
99 |
100 | fig,axs = plt.subplots(2,3,sharex=True,sharey=True,figsize=(9,5.5))
101 | plt.tight_layout(rect=[-.02,-.03,1.12,.97],w_pad=0.1)
102 |
103 | axs[0,0].contourf(param['x_T'],param['y_T'],h2mat(Ro2m),levs1)
104 | axs[0,1].contourf(param['x_T'],param['y_T'],h2mat(Rom),levs1,extend='max')
105 | m1 = axs[0,2].contourf(param['x_T'],param['y_T'],h2mat(Ro[-1,:]),levs1,extend='max')
106 | plt.colorbar(m1,ax=(axs[0,0],axs[0,1],axs[0,2]),ticks=np.arange(0,.22,.04))
107 |
108 | axs[1,0].contourf(param['x_T'],param['y_T'],h2mat(c2),levs2)
109 | m21 = axs[1,0].contour(param['x_T'],param['y_T'],h2mat(c2),[0.8],linewidths=0.7)
110 | axs[1,1].contourf(param['x_T'],param['y_T'],h2mat(c),levs2)
111 | m2 = axs[1,2].contourf(param['x_T'],param['y_T'],h2mat(1/(1+Ro[-1,:])**n),levs2,extend='min')
112 | axs[1,2].contour(param['x_T'],param['y_T'],h2mat(1/(1+Ro[-1,:])**n),[0.8],linewidths=0.7)
113 | m22 = axs[1,1].contour(param['x_T'],param['y_T'],h2mat(c),[0.8],linewidths=0.7)
114 | plt.colorbar(m2,ax=(axs[1,0],axs[1,1],axs[1,2]),ticks=np.arange(0.5,1.05,.05))
115 | plt.clabel(m22, inline=1, fontsize=5,fmt='%.1f')
116 | plt.clabel(m21, inline=1, fontsize=5,fmt='%.1f')
117 |
118 | axs[0,0].set_xticks([])
119 | axs[0,0].set_yticks([])
120 |
121 | axs[0,0].set_title(r'$\overline{R_o} = \overline{\frac{|(\mathbf{u} \cdot \nabla)\mathbf{u}|}{|f\mathbf{u}|}}$')
122 | axs[0,1].set_title(r'$\overline{R_o^*} = \overline{\frac{|D|}{f}}$')
123 | axs[0,2].set_title(r'snapshot: $R_o^*$')
124 |
125 | axs[1,0].set_title(r'$(1+\overline{R_o})^{-2}$')
126 | axs[1,1].set_title(r'$(1+\overline{R_o}^*)^{-2}$')
127 | axs[1,2].set_title(r'$(1+R_o^*)^{-2}$')
128 |
129 | axs[0,0].set_ylabel('y')
130 | axs[1,0].set_ylabel('y')
131 | axs[1,0].set_xlabel('x')
132 | axs[1,1].set_xlabel('x')
133 |
134 | plt.savefig(path+'compare/Ro_scaling.png',dpi=150)
135 | plt.close(fig)
136 | #plt.show()
137 |
138 |
139 |
--------------------------------------------------------------------------------
/plot/Ro_hist_plot_balu.py:
--------------------------------------------------------------------------------
1 | ## HISTOGRAM PLOTTING FOR REYNOLDS AND ROSSBY NUMBERS
2 | from __future__ import print_function
3 |
4 | path = '/network/home/aopp/kloewer/swm/paperplot/'
5 | path2 = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/'
6 | path3 = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
7 | import numpy as np
8 | import matplotlib.pyplot as plt
9 |
10 | plt.rcParams['mathtext.fontset'] = 'cm'
11 | plt.rcParams['mathtext.rm'] = 'serif'
12 |
13 | # OPTIONS
14 | runfolder = [0,6,0,3,4]
15 | print('Creating Ro histogram plot from run '+str(runfolder))
16 |
17 | ## read data
18 | runpath = path2+'data/run%04i' % runfolder[0]
19 | D1 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
20 |
21 | runpath = path2+'data/run%04i' % runfolder[1]
22 | D2 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
23 |
24 | runpath = path3+'run%04i' % runfolder[2]
25 | D3 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
26 | print(np.load(runpath+'/param.npy').all()['n_diss'])
27 |
28 | runpath = path3+'run%04i' % runfolder[3]
29 | D4 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
30 | print(np.load(runpath+'/param.npy').all()['n_diss'])
31 |
32 | runpath = path3+'run%04i' % runfolder[4]
33 | D5 = np.load(runpath+'/analysis/Ro_defo_hist.npy').all()
34 | print(np.load(runpath+'/param.npy').all()['n_diss'])
35 |
36 | ## EXTEND HISTOGRAM WITH ZERO TO THE RIGHT
37 |
38 | for D in [D1,D2,D3,D4,D5]:
39 | D['Ro_mid'] = np.hstack((D['Ro_mid'],10**1.5))
40 | D['RoH'] = np.hstack((D['RoH'],0.))
41 |
42 | ## CDISS
43 | Ro = np.linspace(10**-3.5,10**1.5,10000)
44 | cd = lambda d: 1/(1+(Ro/d))
45 | cd2 = lambda d: (1 - np.minimum(np.exp(Ro - d),np.ones_like(Ro)))/(1-np.exp(-d))
46 |
47 | ## PLOT
48 | fig,(ax1,ax2,ax3) = plt.subplots(3,1,figsize=(8,6.5),sharex=True)
49 |
50 | s = 1e6
51 |
52 | ax1.plot(D1['Ro_mid'],D1['RoH']/s,'C0',label=r'Low resolution, $\Delta x = $30km',lw=3)
53 | ax1.plot(D2['Ro_mid'],D2['RoH']/16/s,'C2',label=r'High resolution, $\Delta x = $7.5km',lw=3)
54 | ax1.plot(D3['Ro_mid'],D3['RoH']/s,'C1',label=r'LR + weak backscatter',ls='--')
55 | ax1.plot(D4['Ro_mid'],D4['RoH']/s,'C3',label=r'LR + moderate backscatter',ls='--')
56 | ax1.plot(D5['Ro_mid'],D5['RoH']/s,'C5',label=r'LR + strong backscatter',ls='--')
57 |
58 | ytikmax = 0.25
59 |
60 | ax1.axvline(np.log10(D1['Ro_mean']),0,ytikmax,c='C0',ls='-',lw=2)
61 | ax1.axvline(np.log10(D2['Ro_mean']),0,ytikmax,c='C2',ls='-',lw=2)
62 | ax1.axvline(np.log10(D3['Ro_mean']),0,ytikmax,c='C1',ls='--')
63 | ax1.axvline(np.log10(D4['Ro_mean']),0,ytikmax,c='C3',ls='--')
64 | ax1.axvline(np.log10(D5['Ro_mean']),0,ytikmax,c='C5',ls='--')
65 |
66 | ax1.text(np.log10(D1['Ro_mean'])-0.01,1.3,'mean($R_o$)',rotation=90,ha='right',color='k')
67 |
68 | ax2.plot(np.log10(Ro),cd(1.),'C1--',label=r'$c_{diss}$ for $R_{diss} = 1$, weak backscatter')
69 | ax2.plot(np.log10(Ro),cd(8.),'C3--',label=r'$c_{diss}$ for $R_{diss} = 8$, moderate backscatter')
70 | ax2.plot(np.log10(Ro),cd(64.),'C5--',label=r'$c_{diss}$ for $R_{diss} = 64$, strong backscatter')
71 |
72 | ax3.plot(np.log10(Ro),cd(1.),'C1--',label='as in b')
73 | ax3.plot(np.log10(Ro),cd(8.),'C3--',label='as in b')
74 | ax3.plot(np.log10(Ro),cd(64.),'C5--',label='as in b')
75 |
76 | ax3.plot(np.log10(Ro),cd2(1.),'C0',label='$c_{diss}^*$ for $R_{diss} = 1$')
77 | ax3.plot(np.log10(Ro),cd2(8.),'C4',label='$c_{diss}^*$ for $R_{diss} = 8$')
78 | ax3.plot(np.log10(Ro),cd2(64),'C2',label='$c_{diss}^*$ for $R_{diss} = 64$')
79 |
80 | ax2.plot(np.ones(2)*np.log10(1),[-1,0.5],'C1')
81 | ax2.plot(np.ones(2)*np.log10(8),[-1,0.5],'C3')
82 | ax2.text(np.log10(1)-0.03,0.3,r'$R_{diss} = 1$',rotation=90,ha='right',color='k')
83 | ax2.text(np.log10(8)-0.03,0.3,r'$R_{diss} = 8$',rotation=90,ha='right',color='k')
84 | ax2.text(-2.9,0.6,r'$c_{diss} = (1 + \frac{R_o}{R_{diss}})^{-1}$', fontsize=15)
85 | ax3.text(-2.9,0.6,r'$c_{diss}^* \sim 1 - \exp(R_o - R_{diss})$', fontsize=15)
86 |
87 | ax3.legend(loc=3,ncol=2)
88 | ax2.legend(loc=3)
89 | ax1.legend(loc=1)
90 |
91 | ax1.set_xlim(-3,1)
92 | ax1.set_ylim(-0.1,3.5)
93 | ax2.set_ylim(-0.05,1.05)
94 | ax3.set_ylim(-0.05,1.05)
95 |
96 | ax1.set_title('a',loc='left',fontweight='bold')
97 | ax1.set_title('Rossby number histogram')
98 |
99 | ax2.set_title('b',loc='left',fontweight='bold')
100 | ax2.set_title('Rossby number dissipation scaling')
101 |
102 | ax3.set_title('c',loc='left',fontweight='bold')
103 | ax3.set_title('Rossby number dissipation scaling, exponential version')
104 |
105 | ax3.set_xlabel('log$_{10}(R_o)$')
106 | ax1.set_ylabel(r'$N$ $[10^6]$')
107 |
108 | plt.tight_layout()
109 | plt.savefig(path+'plots/Ro_hist_nadiga.pdf')
110 | plt.close(fig)
--------------------------------------------------------------------------------
/calc/power_inout_bs_calc.py:
--------------------------------------------------------------------------------
1 | ## POWER INPUT EXIT CALCULATION
2 | from __future__ import print_function
3 |
4 | # path
5 | import os
6 | path = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
7 | os.chdir(path) # change working directory
8 |
9 | import numpy as np
10 | from scipy import sparse
11 |
12 | # OPTIONS
13 | # several entries in the list concatenates the runs and stores the result in the last folder
14 | runfolder = [4]
15 | print('Calculating power in/out from run ' + str(runfolder))
16 |
17 | InPower_T = []
18 | ExPower_T = []
19 | BfricPower_T = []
20 | BackPower_T = []
21 |
22 | ## read data
23 | for r in runfolder: # calculate each run separately
24 | runpath = path+'run%04i' % r
25 |
26 | skip = 5*365
27 | u = np.load(runpath+'/u_sub.npy')[skip:,...]
28 | v = np.load(runpath+'/v_sub.npy')[skip:,...]
29 | eta = np.load(runpath+'/eta_sub.npy')[skip:,...]
30 | e = np.load(runpath+'/e_sub.npy')[skip:,...]
31 | t = np.load(runpath+'/t_sub.npy')[skip:,...]
32 | print('run %i read.' % r)
33 |
34 | ## read param
35 | global param
36 | param = np.load(runpath+'/param.npy').all()
37 |
38 | # import functions
39 | funpath = '/network/home/aopp/kloewer/git/swm/'
40 | exec(open(funpath+'swm_param.py').read())
41 | exec(open(funpath+'swm_operators.py').read())
42 |
43 | set_grad_mat()
44 | set_interp_mat()
45 | set_coriolis()
46 | set_forcing()
47 |
48 | tlen = len(t)
49 | ## create ouputfolder
50 | try:
51 | os.mkdir(runpath+'/analysis')
52 | except:
53 | pass
54 |
55 | ## reshape u,v
56 | u = u.reshape((tlen,param['Nu'])).T
57 | v = v.reshape((tlen,param['Nv'])).T
58 | h = eta.reshape((tlen,param['NT'])).T + param['H']
59 | e = e.reshape((tlen,param['NT'])).T
60 | print('Reshape done.')
61 |
62 | h_q = ITq.dot(h)
63 | h_u = ITu.dot(h)
64 | h_v = ITv.dot(h)
65 | print('h_u, h_v, h_q done.')
66 |
67 | ## input
68 | # Fx is actually Fx/rho
69 | InPower = param['rho']*(u.T*Fx).mean(axis=0)
70 | print('Input Power done.')
71 |
72 | # Shchepetkin and O'Brien divergence of a tensor formulation
73 | hS = ((Gux.dot(u)-Gvy.dot(v))*h,(G2vx.dot(v) + G2uy.dot(u))*h_q)
74 | diff_u = (GTx.dot(hS[0]) + Gqy.dot(hS[1])) / h_u
75 | diff_v = (Gqx.dot(hS[1]) - GTy.dot(hS[0])) / h_v
76 |
77 | # hS will be used for the backscatter term further down
78 |
79 | # biharmonic stress tensor R = (R11, R12, R12, -R11), store only R11, R12
80 | hR = ((Gux.dot(diff_u) - Gvy.dot(diff_v))*h, (G2vx.dot(diff_v) + G2uy.dot(diff_u))*h_q)
81 |
82 |
83 | del h_q, diff_u, diff_v
84 |
85 | # without the 1/h factor compared to the calculation in the rhs
86 | bidiff_u = (GTx.dot(hR[0]) + Gqy.dot(hR[1]))
87 | bidiff_v = (Gqx.dot(hR[1]) - GTy.dot(hR[0]))
88 |
89 | del hR
90 |
91 | ExPower_u = -param['nu_B']*param['rho']*(u*bidiff_u).mean(axis=1)
92 | ExPower_v = -param['nu_B']*param['rho']*(v*bidiff_v).mean(axis=1)
93 |
94 | del bidiff_u, bidiff_v
95 |
96 | print('Biharmonic dissipation term done.')
97 |
98 | BfricPower = -param['rho']*param['c_D']*((IuT.dot(u**2) + IvT.dot(v**2))**(3./2.)).mean(axis=1)
99 |
100 | print('Bottom friction dissipation term done.')
101 |
102 | # Backscatter term
103 | e_over_h = e/h
104 | nu_back = -param['c_back']*param['max_dxdy']*np.sqrt(2*e_over_h.clip(0,e_over_h.max()))
105 | del e_over_h, h, e
106 |
107 | nu_back_hS0 = nu_back*hS[0]
108 | nu_back_hS1 = ITq.dot(nu_back)*hS[1]
109 |
110 | del nu_back, hS
111 |
112 | # without the 1/h factor compared to the calculation in the rhs
113 | back_diff_u = (GTx.dot(nu_back_hS0) + Gqy.dot(nu_back_hS1))
114 | back_diff_v = (Gqx.dot(nu_back_hS1) - GTy.dot(nu_back_hS0))
115 |
116 | del nu_back_hS0, nu_back_hS1, h_u, h_v
117 |
118 | BackPower_u = param['rho']*(u*back_diff_u).mean(axis=1)
119 | BackPower_v = param['rho']*(v*back_diff_v).mean(axis=1)
120 |
121 | del back_diff_u, back_diff_v
122 |
123 | print('Backscatter term done.')
124 |
125 | # Interpolation
126 | InPower_T.append(IuT.dot(InPower))
127 | ExPower_T.append(IuT.dot(ExPower_u) + IvT.dot(ExPower_v))
128 | BfricPower_T.append(BfricPower)
129 | BackPower_T.append(IuT.dot(BackPower_u) + IvT.dot(BackPower_v))
130 |
131 | # Averaging over runs
132 | InPower_T = np.array(InPower_T).mean(axis=0)
133 | ExPower_T = np.array(ExPower_T).mean(axis=0)
134 | BfricPower_T = np.array(BfricPower_T).mean(axis=0)
135 | BackPower_T = np.array(BackPower_T).mean(axis=0)
136 |
137 | ## STORING
138 | dic = dict()
139 | all_var2export = ['InPower_T','ExPower_T','BfricPower_T','BackPower_T']
140 | for v in all_var2export:
141 | exec('dic[v] ='+v)
142 |
143 | np.save(runpath+'/analysis/power_map.npy',dic)
144 | print('Everything stored.')
145 |
--------------------------------------------------------------------------------
/calc/misc/Re_hist_calc_bs.py:
--------------------------------------------------------------------------------
1 | ## HISTOGRAM COMPUTATIONS FOR REYNOLDS AND ROSSBY NUMBERS
2 | from __future__ import print_function
3 |
4 | # path
5 | import os
6 | path = os.path.dirname(os.getcwd()) + '/' # on level above
7 | os.chdir(path) # change working directory
8 |
9 | import numpy as np
10 | from scipy import sparse
11 |
12 | # OPTIONS
13 | runfolder = [10]
14 | print('Calculating Reynolds histograms from run ' + str(runfolder))
15 |
16 | ReH = []
17 | Re_mean = []
18 | Re_median = []
19 |
20 | ## read data - calculate each run separately
21 | for r,i in zip(runfolder,range(len(runfolder))):
22 | runpath = path+'data/run%04i' % r
23 |
24 | skip = 5*365
25 | u = np.load(runpath+'/u_sub.npy')[skip:,...]
26 | v = np.load(runpath+'/v_sub.npy')[skip:,...]
27 | eta = np.load(runpath+'/eta_sub.npy')[skip:,...]
28 | e = np.load(runpath+'/e_sub.npy')[skip:,...]
29 | t = np.load(runpath+'/t_sub.npy')[skip:,...]
30 | print('run %i read.' % r)
31 |
32 | ## read param
33 | global param
34 | param = np.load(runpath+'/param.npy').all()
35 |
36 | # import functions
37 | exec(open(path+'swm_param.py').read())
38 | exec(open(path+'swm_operators.py').read())
39 |
40 | set_grad_mat()
41 | set_interp_mat()
42 | set_coriolis()
43 |
44 | tlen = len(t)
45 | ## create ouputfolder
46 | try:
47 | os.mkdir(runpath+'/analysis')
48 | except:
49 | pass
50 |
51 | ## reshape u,v
52 | u = u.reshape((tlen,param['Nu'])).T
53 | v = v.reshape((tlen,param['Nv'])).T
54 | h = eta.reshape((tlen,param['NT'])).T + param['H']
55 | e = e.reshape((tlen,param['NT'])).T
56 | print('Reshape done.')
57 |
58 | ## COMPUTE REYNOLDS, ROSSBY
59 | u_T = IuT.dot(u)
60 | v_T = IvT.dot(v)
61 | print('u,v interpolation done.')
62 |
63 | #advective term
64 | adv_u = u_T*Gux.dot(u) + v_T*IqT.dot(Guy.dot(u))
65 | adv_v = u_T*IqT.dot(Gvx.dot(v)) + v_T*Gvy.dot(v)
66 | del u_T,v_T
67 | adv_term = np.sqrt(adv_u**2 + adv_v**2)
68 | del adv_u, adv_v
69 | print('Advection term done.')
70 |
71 | #diffusive term
72 | S = (Gux.dot(u)-Gvy.dot(v),G2vx.dot(v) + G2uy.dot(u))
73 | del u,v
74 | hS = (h*S[0],ITq.dot(h)*S[1])
75 | del S
76 | print('Stress tensor S done.')
77 |
78 | diff_u = (GTx.dot(hS[0]) + Gqy.dot(hS[1])) / ITu.dot(h)
79 | diff_v = (Gqx.dot(hS[1]) - GTy.dot(hS[0])) / ITv.dot(h)
80 | print('Harmonic part done.')
81 |
82 | # biharmonic stress tensor R = (R11, R12, R12, -R11), store only R11, R12
83 | R = (Gux.dot(diff_u) - Gvy.dot(diff_v), G2vx.dot(diff_v) + G2uy.dot(diff_u))
84 | del diff_u, diff_v
85 | nuhR = (param['nu_B']*h*R[0],param['nu_B']*ITq.dot(h)*R[1])
86 | del R
87 | print('Stress tensor R done.')
88 |
89 | bidiff_u = (GTx.dot(nuhR[0]) + Gqy.dot(nuhR[1])) / ITu.dot(h)
90 | bidiff_v = (Gqx.dot(nuhR[1]) - GTy.dot(nuhR[0])) / ITv.dot(h)
91 |
92 | del nuhR
93 | print('Biharmonic part done.')
94 |
95 | # backscatter
96 | e_over_h = e/h
97 | nu_back = -param['c_back']*param['max_dxdy']*np.sqrt(2*e_over_h.clip(0,e_over_h.max()))
98 | del e_over_h,e
99 |
100 | nu_back_hS0 = nu_back*hS[0]
101 | nu_back_hS1 = ITq.dot(nu_back)*hS[1]
102 | print('nu_back calculated.')
103 | del nu_back
104 |
105 | back_diff_u = (GTx.dot(nu_back_hS0) + Gqy.dot(nu_back_hS1)) / ITu.dot(h)
106 | back_diff_v = (Gqx.dot(nu_back_hS1) - GTy.dot(nu_back_hS0)) / ITv.dot(h)
107 | del nu_back_hS0,nu_back_hS1
108 |
109 | diff_term = np.sqrt(IuT.dot((-bidiff_u + back_diff_u)**2) + IvT.dot((-bidiff_v + back_diff_v)**2))
110 | #diff_term = np.sqrt(IuT.dot(bidiff_u**2) + IvT.dot(bidiff_v**2))
111 | print('Diff term done.')
112 | del bidiff_u,bidiff_v,back_diff_u,back_diff_v
113 |
114 | # actual number
115 | Re = (adv_term / diff_term).flatten()
116 | print('Re computed.')
117 | del adv_term, diff_term
118 |
119 | Re_mean.append(Re.mean())
120 | Re_median.append(np.median(Re))
121 | Re = np.log10(Re)
122 |
123 | # histogram
124 | Re_min = -3. # in log scale
125 | Re_max = 5.
126 | N = 300
127 |
128 | ReH_temp,Re_edges = np.histogram(Re,np.linspace(Re_min,Re_max,N))
129 | print('Re histogram done.')
130 | del Re
131 |
132 | # store each run in a list
133 | ReH.append(ReH_temp)
134 |
135 | Re_mid = Re_edges[:-1] + np.diff(Re_edges)/2.
136 |
137 |
138 | ReH = np.array(ReH).sum(axis=0)
139 | Re_mean = np.array(Re_mean).mean()
140 | Re_median = np.median(np.array(Re_median)) #actually median of medians though...
141 |
142 | ## STORING in last
143 | dic = dict()
144 | all_var2export = ['ReH','Re_mid','Re_edges','Re_mean','Re_median']
145 |
146 | for vars in all_var2export:
147 | exec('dic[vars] ='+vars)
148 |
149 | np.save(runpath+'/analysis/Re_hist.npy',dic)
150 |
--------------------------------------------------------------------------------
/calc/misc/Re_hist_calc_bs_old.py:
--------------------------------------------------------------------------------
1 | ## HISTOGRAM COMPUTATIONS FOR REYNOLDS AND ROSSBY NUMBERS
2 | from __future__ import print_function
3 |
4 | # path
5 | import os
6 | path = '/home/mkloewer/python/swm/'
7 | #path = os.path.dirname(os.getcwd()) + '/' # on level above
8 | os.chdir(path) # change working directory
9 | import time as tictoc
10 |
11 | import numpy as np
12 | from scipy import sparse
13 |
14 | # OPTIONS
15 | runfolder = [14]
16 | print('Calculating Reynolds histograms from run ' + str(runfolder))
17 |
18 | ReH = []
19 | Re_mean = []
20 | Re_median = []
21 |
22 | ## read data - calculate each run separately
23 | for r,i in zip(runfolder,range(len(runfolder))):
24 | runpath = path+'stoch/data/run%04i' % r
25 |
26 | skip = 5*365
27 | u = np.load(runpath+'/u_sub.npy')[skip:,...]
28 | v = np.load(runpath+'/v_sub.npy')[skip:,...]
29 | eta = np.load(runpath+'/h_sub.npy')[skip:,...]
30 | e = np.load(runpath+'/e_sub.npy')[skip:,...]
31 | t = np.load(runpath+'/t_sub.npy')[skip:,...]
32 | print('run %i read.' % r)
33 |
34 | ## read param
35 | global param
36 | param = np.load(runpath+'/param.npy').all()
37 |
38 | # import functions
39 | exec(open(path+'swm_param.py').read())
40 | exec(open(path+'swm_operators.py').read())
41 | param['output'] = 0
42 |
43 | set_grad_mat()
44 | set_interp_mat()
45 | set_coriolis()
46 |
47 | tlen = len(t)
48 | ## create ouputfolder
49 | try:
50 | os.mkdir(runpath+'/analysis')
51 | except:
52 | pass
53 |
54 | ## reshape u,v
55 | u = u.reshape((tlen,param['Nu'])).T
56 | v = v.reshape((tlen,param['Nv'])).T
57 | h = eta.reshape((tlen,param['NT'])).T + param['H']
58 | e = e.reshape((tlen,param['NT'])).T
59 | print('Reshape done.')
60 |
61 | ## COMPUTE REYNOLDS, ROSSBY
62 | u_T = IuT.dot(u)
63 | v_T = IvT.dot(v)
64 | print('u,v interpolation done.')
65 |
66 | #advective term
67 | adv_u = u_T*Gux.dot(u) + v_T*IqT.dot(Guy.dot(u))
68 | adv_v = u_T*IqT.dot(Gvx.dot(v)) + v_T*Gvy.dot(v)
69 | del u_T,v_T
70 | adv_term = np.sqrt(adv_u**2 + adv_v**2)
71 | del adv_u, adv_v
72 | print('Advection term done.')
73 |
74 | #diffusive term
75 | S = (Gux.dot(u)-Gvy.dot(v),G2vx.dot(v) + G2uy.dot(u))
76 | del u,v
77 | hS = (h*S[0],ITq.dot(h)*S[1])
78 | del S
79 | print('Stress tensor S done.')
80 |
81 | diff_u = (GTx.dot(hS[0]) + Gqy.dot(hS[1])) / ITu.dot(h)
82 | diff_v = (Gqx.dot(hS[1]) - GTy.dot(hS[0])) / ITv.dot(h)
83 | print('Harmonic part done.')
84 |
85 | # biharmonic stress tensor R = (R11, R12, R12, -R11), store only R11, R12
86 | R = (Gux.dot(diff_u) - Gvy.dot(diff_v), G2vx.dot(diff_v) + G2uy.dot(diff_u))
87 | del diff_u, diff_v
88 | nuhR = (param['nu_B']*h*R[0],param['nu_B']*ITq.dot(h)*R[1])
89 | del R
90 | print('Stress tensor R done.')
91 |
92 | bidiff_u = (GTx.dot(nuhR[0]) + Gqy.dot(nuhR[1])) / ITu.dot(h)
93 | bidiff_v = (Gqx.dot(nuhR[1]) - GTy.dot(nuhR[0])) / ITv.dot(h)
94 |
95 | del nuhR
96 | print('Biharmonic part done.')
97 |
98 | # backscatter
99 | nu_back = -param['c_back']*param['max_dxdy']*np.sqrt(2*e.clip(0,e.max()))
100 | del e
101 |
102 | nu_back_hS0 = nu_back*hS[0]
103 | nu_back_hS1 = ITq.dot(nu_back)*hS[1]
104 | print('nu_back calculated.')
105 | del nu_back
106 |
107 | back_diff_u = (GTx.dot(nu_back_hS0) + Gqy.dot(nu_back_hS1)) / ITu.dot(h)
108 | back_diff_v = (Gqx.dot(nu_back_hS1) - GTy.dot(nu_back_hS0)) / ITv.dot(h)
109 | del nu_back_hS0,nu_back_hS1
110 |
111 | diff_term = np.sqrt(IuT.dot((bidiff_u + back_diff_u)**2) + IvT.dot((bidiff_v + back_diff_v)**2))
112 | #diff_term = np.sqrt(IuT.dot(bidiff_u**2) + IvT.dot(bidiff_v**2))
113 | print('Diff term done.')
114 | del bidiff_u,bidiff_v,back_diff_u,back_diff_v
115 |
116 | # actual number
117 | Re = (adv_term / diff_term).flatten()
118 | print('Re computed.')
119 | del adv_term, diff_term
120 |
121 | Re_mean.append(Re.mean())
122 | Re_median.append(np.median(Re))
123 | Re = np.log10(Re)
124 |
125 | # histogram
126 | Re_min = -3. # in log scale
127 | Re_max = 5.
128 | N = 300
129 |
130 | ReH_temp,Re_edges = np.histogram(Re,np.linspace(Re_min,Re_max,N))
131 | print('Re histogram done.')
132 | del Re
133 |
134 | # store each run in a list
135 | ReH.append(ReH_temp)
136 |
137 | Re_mid = Re_edges[:-1] + np.diff(Re_edges)/2.
138 |
139 |
140 | ReH = np.array(ReH).sum(axis=0)
141 | Re_mean = np.array(Re_mean).mean()
142 | Re_median = np.median(np.array(Re_median)) #actually median of medians though...
143 |
144 | ## STORING in last
145 | dic = dict()
146 | all_var2export = ['ReH','Re_mid','Re_edges','Re_mean','Re_median']
147 |
148 | for vars in all_var2export:
149 | exec('dic[vars] ='+vars)
150 |
151 | np.save(runpath+'/analysis/Re_hist.npy',dic)
152 |
--------------------------------------------------------------------------------
/plot/streamplot.py:
--------------------------------------------------------------------------------
1 | ## PLOT STREAMFUNCTION
2 | from __future__ import print_function
3 | #path = '/home/mkloewer/python/swm/'
4 | path = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/data/'
5 | path2 = '/home/kloewer/git/swm/'
6 | path3 = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
7 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
8 |
9 | import numpy as np
10 | from scipy import sparse
11 | import matplotlib.pyplot as plt
12 | from cmocean import cm
13 |
14 | plt.rcParams['mathtext.fontset'] = 'cm'
15 | plt.rcParams['mathtext.rm'] = 'serif'
16 |
17 |
18 | # OPTIONS
19 | runfolder = [0,6,3]
20 | print('Compare mean plots from run ' + str(runfolder))
21 |
22 | ## read data
23 |
24 | runpath1 = path+'run%04i' % runfolder[0]
25 | D1 = np.load(runpath1+'/analysis/mean.npy').all()
26 | param1 = np.load(runpath1+'/param.npy').all()
27 |
28 | runpath2 = path+'run%04i' % runfolder[1]
29 | D2 = np.load(runpath2+'/analysis/mean.npy').all()
30 | param2 = np.load(runpath2+'/param.npy').all()
31 |
32 | runpath3 = path3+'run%04i' % runfolder[2]
33 | D3 = np.load(runpath3+'/analysis/mean.npy').all()
34 | param3 = np.load(runpath3+'/param.npy').all()
35 | print(param3['n_diss'])
36 |
37 | ## CALCULATE
38 | u = [0]*3
39 | v = [0]*3
40 | speed = [0]*3
41 | xx = [0]*3
42 | yy = [0]*3
43 |
44 |
45 | global param
46 | param = np.load(runpath1+'/param.npy').all()
47 | exec(open(path2+'swm_operators.py').read())
48 | exec(open(path2+'swm_output.py').read())
49 | param['output'] = 0
50 | set_grad_mat()
51 | set_interp_mat()
52 |
53 | u[0] = h2mat(IuT.dot(D1['um']))
54 | v[0] = h2mat(IvT.dot(D1['vm']))
55 | speed[0] = np.sqrt(u[0]**2 + v[0]**2)
56 | xx[0],yy[0] = np.meshgrid(param['x_T'],param['y_T'])
57 |
58 | # next run
59 | param = np.load(runpath2+'/param.npy').all()
60 | exec(open(path2+'swm_operators.py').read())
61 | exec(open(path2+'swm_output.py').read())
62 | param['output'] = 0
63 | set_grad_mat()
64 | set_interp_mat()
65 |
66 | u[1] = h2mat(IuT.dot(D2['um']))
67 | v[1] = h2mat(IvT.dot(D2['vm']))
68 | speed[1] = np.sqrt(u[1]**2 + v[1]**2)
69 |
70 | xx[1],yy[1] = np.meshgrid(param['x_T'],param['y_T'])
71 |
72 | # next run
73 | param = np.load(runpath3+'/param.npy').all()
74 | exec(open(path2+'swm_operators.py').read())
75 | exec(open(path2+'swm_output.py').read())
76 | param['output'] = 0
77 | set_grad_mat()
78 | set_interp_mat()
79 |
80 | u[2] = h2mat(IuT.dot(D3['um']))
81 | v[2] = h2mat(IvT.dot(D3['vm']))
82 | speed[2] = np.sqrt(u[2]**2 + v[2]**2)
83 |
84 | xx[2],yy[2] = np.meshgrid(param['x_T'],param['y_T'])
85 |
86 | # line width
87 | lww = [4*np.sqrt(speed[0])/np.sqrt(speed[0].max())]
88 | lww.append(4*np.sqrt(speed[1])/np.sqrt(speed[0].max()))
89 | lww.append(4*np.sqrt(speed[2])/np.sqrt(speed[0].max()))
90 |
91 | # wind profile
92 | Fx = param['Fx0']*(np.cos(2*np.pi*(param['y_u']-param['Ly']/2)/param['Ly']) + 2*np.sin(np.pi*(param['y_u'] - param['Ly']/2)/param['Ly']))
93 |
94 | ## Plotting
95 | fig,axs = plt.subplots(1,3,sharex=True,sharey=True,figsize=(12,5))
96 | fig.tight_layout(rect=[0.02,.15,0.9,0.92])
97 | fig.subplots_adjust(wspace=0.03,hspace=0.03)
98 |
99 | pos = axs[0].get_position()
100 | pos2 = axs[2].get_position()
101 | cax = fig.add_axes([pos.x0,0.1,pos2.x1-pos.x0,0.03])
102 |
103 | s = 1e3 # scaling factor m -> km
104 |
105 | # wind profile
106 | wax = fig.add_axes([0.888,pos.y0,0.1,pos.y1-pos.y0])
107 | wax.set_ylim(0,param['Ly']/s)
108 | wax.set_yticks([0,1000,2000,3000])
109 | wax.set_yticklabels([])
110 | wax.plot(Fx,param['y_u']/s)
111 | wax.plot([0,0],[0,param['Ly']/s],'grey',lw=0.5)
112 | #wax.set_title('d',fontweight='bold',loc='left')
113 | wax.set_title(r'Wind stress $\tau$',loc='left')
114 |
115 |
116 | wax.set_xlabel('[Pa]')
117 | wax.set_xticks([-0.3,0,0.2])
118 | wax.set_xticklabels([-0.3,0,0.2])
119 |
120 | #plt.text(0, 1.1,r'Wind stress $\tau$',fontsize=13,ha='left',transform=wax.transAxes)
121 |
122 | for j,i in zip([0,2,1],range(3)):
123 | strm = axs[j].streamplot(xx[i]/s,yy[i]/s,u[i],v[i],color=speed[i],density=2.5,linewidth=lww[i],arrowstyle='->')
124 |
125 | cbar = fig.colorbar(strm.lines,cax=cax,orientation='horizontal')
126 | cbar.set_label('Speed [m/s]')
127 | axs[0].set_xticks([0,1000,2000,3000])
128 | axs[0].set_yticks([0,1000,2000,3000])
129 |
130 | axs[0].set_xlim(0,param['Lx']/s)
131 | axs[0].set_ylim(0,param['Ly']/s)
132 | axs[0].set_ylabel(r'$y$ [km]')
133 | axs[1].set_xlabel(r'$x$ [km]')
134 |
135 | axs[0].set_title(r'Low resolution, $\Delta x = $30km')
136 | axs[1].set_title(r'LR + moderate backscatter')
137 | axs[2].set_title(r'High resolution, $\Delta x = $7.5km')
138 |
139 | axs[0].set_title('a',fontweight='bold',loc='left')
140 | axs[1].set_title('b',fontweight='bold',loc='left')
141 | axs[2].set_title('c',fontweight='bold',loc='left')
142 |
143 | #plt.suptitle('Streamlines of mean circulation ($\overline{u},\overline{v}$)',x=0.186,y=0.98)
144 |
145 | #plt.text(0,1.1,'Streamlines of mean circulation ($\overline{u},\overline{v}$)',fontsize=13,ha='left',transform=axs[0].transAxes)
146 |
147 | #plt.suptitle(r'wind stress $\tau$',x=0.86,y=0.98)
148 | plt.savefig(outpath+'plots/streamplot.eps')
149 | plt.close(fig)
150 |
--------------------------------------------------------------------------------
/plot/energy_timeseries.py:
--------------------------------------------------------------------------------
1 | ## PLOT ENERGY AND ENSTROPY TIME SERIES
2 | from __future__ import print_function
3 |
4 | path1 = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
5 | path2 = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/data/'
6 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
7 |
8 | import os; os.chdir(path2) # change working directory
9 | import numpy as np
10 | import matplotlib.pyplot as plt
11 | import matplotlib.patches as patches
12 | import matplotlib.gridspec as gridspec
13 |
14 | plt.rcParams['mathtext.fontset'] = 'cm'
15 | plt.rcParams['mathtext.rm'] = 'serif'
16 |
17 | # OPTIONS
18 | runfolder = [0,6,0,3,8]
19 | print('Compare mean plots from run ' + str(runfolder))
20 |
21 | ## read data
22 |
23 | runpath1 = path2+'run%04i' % runfolder[0]
24 | D1 = np.load(runpath1+'/analysis/mean_timeseries.npy').all()
25 |
26 | runpath2 = path2+'run%04i' % runfolder[1]
27 | D2 = np.load(runpath2+'/analysis/mean_timeseries.npy').all()
28 |
29 | runpath3 = path1+'run%04i' % runfolder[2]
30 | D3 = np.load(runpath3+'/analysis/mean_timeseries.npy').all()
31 |
32 | runpath4 = path1+'run%04i' % runfolder[3]
33 | D4 = np.load(runpath4+'/analysis/mean_timeseries.npy').all()
34 |
35 | runpath5 = path1+'run%04i' % runfolder[4]
36 | D5 = np.load(runpath5+'/analysis/mean_timeseries.npy').all()
37 |
38 | for D in [D1,D3,D4,D5]: # from seconds to years
39 | D['t'] = D['t'] / 3600. / 24. / 365.
40 |
41 | # create new t2 time axis based on the knowledge that dt = 86260 seconds
42 | D2['t'] = (np.arange(len(D2['t']))*86260) / 3600. / 24. / 365.
43 |
44 | ##
45 |
46 | def running_mean(x, N):
47 | cumsum = np.cumsum(np.insert(x, 0, 0))
48 | return (cumsum[N:] - cumsum[:-N]) / N
49 |
50 | ## PLOTTING
51 |
52 | #fig,((ax1,ax3),(ax2,ax4)) = plt.subplots(2,2,sharex=True,sharey='row',figsize=(8,6))
53 |
54 | #fig = plt.figure(figsize=(8,6))parameteri
55 | #gs = gridspec.GridSpec(2, 2,width_ratios=[20,1])
56 |
57 | # fig = plt.figure(figsize=(8,3))
58 | # gs = gridspec.GridSpec(1, 2,width_ratios=[20,1])
59 |
60 | fig,ax1 = plt.subplots(1,1,figsize=(8,3))
61 |
62 | # ax1 = plt.subplot(gs[0])
63 | #ax2 = plt.subplot(gs[1,0])
64 |
65 | # ax3 = plt.subplot(gs[1])
66 | #ax4 = plt.subplot(gs[1,1])
67 |
68 | fig.tight_layout(rect=[0.02,0.03,1.01,0.95])
69 | # fig.subplots_adjust(wspace=0.03,hspace=0.15)
70 |
71 | #ax1.set_xticklabels([])
72 |
73 | # ax3.set_xticks([])
74 | # ax4.set_xticks([])
75 |
76 | # ax3.set_yticklabels([])
77 | # ax4.set_yticklabels([])
78 |
79 | ax1.set_xlim(0,30)
80 | # ax2.set_xlim(0,30)
81 | ax1.set_ylim(0,170)
82 | # ax3.set_ylim(0,170)
83 |
84 | # ax2.set_ylim(0,10)
85 | # ax4.set_ylim(0,10)
86 |
87 | # ax3.set_xlim(0,1)
88 | # ax4.set_xlim(0,1)
89 |
90 | KEmm = [0,]*5
91 | PEmm = [0,]*5
92 | for i,D in enumerate([D1,D2,D3,D4,D5]):
93 | KEmm[i] = D['KEm'][5*365:].mean()/1e3
94 | PEmm[i] = D['PEm'][5*365:].mean()/1e3
95 |
96 | # ax3.plot([0,1],np.ones(2)*KEmm[1],'C2',lw=3)
97 | # ax3.plot([0,1],np.ones(2)*KEmm[0],'C0',lw=3)
98 | # ax3.plot([0,1],np.ones(2)*KEmm[2],'C1',lw=1)
99 | # ax3.plot([0,1],np.ones(2)*KEmm[3],'C3',lw=1)
100 | # ax3.plot([0,1],np.ones(2)*KEmm[4],'C5',lw=1)
101 |
102 | # ax3.text(0.2,KEmm[1],"%i" % KEmm[1])
103 | # ax3.text(0.2,KEmm[0],"%i" % KEmm[0])
104 | # ax3.text(0.2,KEmm[2],"%i" % KEmm[2])
105 | # ax3.text(0.2,KEmm[3],"%i" % KEmm[3])
106 | # ax3.text(0.2,KEmm[4],"%i" % KEmm[4])
107 |
108 | # ax4.plot([0,1],np.ones(2)*PEmm[1],'C2',lw=3)
109 | # ax4.plot([0,1],np.ones(2)*PEmm[0],'C0',lw=3)
110 | # ax4.plot([0,1],np.ones(2)*PEmm[2],'C1',lw=1)
111 | # ax4.plot([0,1],np.ones(2)*PEmm[3],'C3',lw=1)
112 | # ax4.plot([0,1],np.ones(2)*PEmm[4],'C5',lw=1)
113 |
114 | # ax4.text(0.2,PEmm[1],"%.1f" % PEmm[1])
115 | # ax4.text(0.2,PEmm[0],"%.1f" % PEmm[0])
116 | # ax4.text(0.2,PEmm[2],"%.1f" % PEmm[2])
117 | # ax4.text(0.2,PEmm[3],"%.1f" % PEmm[3])
118 | # ax4.text(0.2,PEmm[4],"%.1f" % PEmm[4])
119 |
120 | #
121 | ax1.plot(D2['t'],D2['KEm']/1e3,'C2',label=r'High resolution, $\Delta x = $7.5km',lw=1.5)
122 | ax1.plot(D1['t'],D1['KEm']/1e3,'C0',label=r'Low resolution, $\Delta x = $30km',lw=1.5)
123 | ax1.plot(D3['t'],D3['KEm']/1e3,'C1',label=r'LR + weak backscatter',lw=1.5)
124 | ax1.plot(D4['t'],D4['KEm']/1e3,'C3',label=r'LR + moderate backscatter',lw=1.5)
125 | ax1.plot(D5['t'],D5['KEm']/1e3,'C5',label=r'LR + strong backscatter',lw=1.5)
126 |
127 | # monthly mean for potential energy
128 | m = 1
129 | for D in [D1,D2,D3,D4,D5]:
130 | #D['PEm'] = D['PEm'][:-(len(D['PEm']) % m)].reshape((-1,m)).mean(axis=1)
131 | #D['t'] = D['t'][:-(len(D['t']) % m)].reshape((-1,m)).mean(axis=1)
132 |
133 | D['PEm'] = running_mean(D['PEm'],m)
134 | D['t'] = running_mean(D['t'],m)
135 |
136 | # ax2.plot(D2['t'],D2['PEm']/1e3,'C2',lw=2)
137 | # ax2.plot(D1['t'],D1['PEm']/1e3,'C0',lw=2)
138 | # ax2.plot(D3['t'],D3['PEm']/1e3,'C1',lw=1)
139 | # ax2.plot(D4['t'],D4['PEm']/1e3,'C3',lw=1)
140 | # ax2.plot(D5['t'],D5['PEm']/1e3,'C5',lw=1,zorder=-1)
141 |
142 | ax1.add_patch(patches.Rectangle((0,0),5,ax1.get_ylim()[1],color='0.7'))
143 | # ax2.add_patch(patches.Rectangle((0,0),5,ax2.get_ylim()[1],color='grey',alpha=.3))
144 | #invisible bar for legend
145 | ax1.bar(0,0,color='0.7',label='spin-up')
146 |
147 | ax1.set_title('Kinetic energy',loc='left')
148 | #ax1.set_title('a',loc='left',fontweight='bold')
149 | ax1.set_ylabel(r'kJ m$^{-2}$')
150 | ax1.set_ylim(0,150)
151 |
152 | # ax2.set_title('Potential energy PE')
153 | # ax2.set_title('b',loc='left',fontweight='bold')
154 | # ax2.set_ylabel(r'kJm$^{-2}$')
155 | ax1.set_xlabel('time [years]')
156 | ax1.legend(loc=4,fontsize=8,ncol=3)
157 |
158 | #ax1.grid()
159 |
160 | # ax3.set_title('c',fontweight='bold')
161 | # ax4.set_title('d',fontweight='bold')
162 |
163 | # ax3.set_ylabel('mean(KE)')
164 | # ax3.yaxis.set_label_position('right')
165 |
166 | # ax4.set_ylabel('mean(PE)')
167 | # ax4.yaxis.set_label_position('right')
168 |
169 |
170 | plt.savefig(outpath + 'plots/energy_timeseries_ke.eps')
171 | plt.close(fig)
172 |
--------------------------------------------------------------------------------
/plot/powermap_plot_bs.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 |
3 | path = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/data/'
4 | dpath = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
5 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
6 |
7 | import os; os.chdir(path) # change working directory
8 | import numpy as np
9 | from scipy import sparse
10 | import matplotlib.pyplot as plt
11 | import time as tictoc
12 | from netCDF4 import Dataset
13 | import glob
14 | from matplotlib.colors import BoundaryNorm,LogNorm
15 | import cmocean
16 |
17 | plt.rcParams['mathtext.fontset'] = 'cm'
18 | plt.rcParams['mathtext.rm'] = 'serif'
19 |
20 | # OPTIONS
21 | runfolder = [0,6,3]
22 | print('Plots for run ' + str(runfolder))
23 |
24 | # read data
25 |
26 | runpath1 = path+'run%04i' % runfolder[0]
27 | D1 = np.load(runpath1+'/analysis/power_map.npy').all()
28 | param1 = np.load(runpath1+'/param.npy').all()
29 |
30 | runpath2 = path+'run%04i' % runfolder[1]
31 | D2 = np.load(runpath2+'/analysis/power_map.npy').all()
32 | param2 = np.load(runpath2+'/param.npy').all()
33 |
34 | runpath3 = dpath+'run%04i' % runfolder[2]
35 | D3 = np.load(runpath3+'/analysis/power_map.npy').all()
36 | param3 = np.load(runpath3+'/param.npy').all()
37 | print(param3['n_diss'])
38 |
39 | # functions
40 | def h2mat(h,param):
41 | return h.reshape((param['ny'],param['nx']))
42 |
43 | def u2mat(u,param):
44 | return u.reshape((param['ny'],param['nx']-1))
45 |
46 | def v2mat(v,param):
47 | return v.reshape((param['ny']-1,param['nx']))
48 |
49 | def q2mat(q,param):
50 | return q.reshape((param['ny']+1,param['nx']+1))
51 | #
52 |
53 | m = [0]*(len(runfolder)*3)
54 | s = 1e3
55 |
56 | expo = 1.
57 |
58 | # LOW RESOLUTION RUN
59 | in1 = h2mat(D1['InPower_T'],param1)*s
60 | m[0] = in1.mean()
61 | in1 = np.sign(in1)*abs(in1)**expo
62 |
63 | bf1 = h2mat(D1['BfricPower_T'],param1)*s
64 | m[1] = bf1.mean()
65 | bf1 = np.sign(bf1)*abs(bf1)**expo
66 |
67 | ex1 = h2mat(D1['ExPower_T'],param1)*s
68 | m[2] = ex1.mean()
69 | ex1 = np.sign(ex1)*abs(ex1)**expo
70 |
71 | # BACKSCATTER RUN
72 | in3 = h2mat(D3['InPower_T'],param3)*s
73 | m[3] = in3.mean()
74 | in3 = np.sign(in3)*abs(in3)**expo
75 |
76 | bf3 = h2mat(D3['BfricPower_T'],param3)*s
77 | m[4] = bf3.mean()
78 | bf3 = np.sign(bf3)*abs(bf3)**expo
79 |
80 | D3['ExPower_T'] += D3['BackPower_T']
81 |
82 | ex3 = h2mat(D3['ExPower_T'],param3)*s
83 | m[5] = ex3.mean()
84 | ex3 = np.sign(ex3)*abs(ex3)**expo
85 |
86 | # bs = h2mat(D3['BackPower_T'],param3)*s
87 | # m[6] = bs.mean()
88 | # bs = np.sign(bs)*np.sqrt(abs(bs))
89 |
90 | # HIGH RESOLUTION RUN
91 | in2 = h2mat(D2['InPower_T'],param2)*s
92 | m[6] = in2.mean()
93 | in2 = np.sign(in2)*abs(in2)**expo
94 |
95 | bf2 = h2mat(D2['BfricPower_T'],param2)*s
96 | m[7] = bf2.mean()
97 | bf2 = np.sign(bf2)*abs(bf2)**expo
98 |
99 | ex2 = h2mat(D2['ExPower_T'],param2)*s
100 | m[8] = ex2.mean()
101 | ex2 = np.sign(ex2)*abs(ex2)**expo
102 |
103 | mround = [np.round(mi,2) for mi in m]
104 |
105 | budget_closed = np.array(m).reshape((3,-1))
106 |
107 |
108 | ## PLOTTING
109 |
110 | fig,axs = plt.subplots(3,3,figsize=(8.8,9),sharex=True,sharey=True)
111 |
112 | plt.tight_layout(rect=[0,.07,1,0.97])
113 | fig.subplots_adjust(wspace=0.03,hspace=0.03)
114 |
115 | pos = axs[-1,0].get_position()
116 | pos2 = axs[-1,-1].get_position()
117 | cax = fig.add_axes([pos.x0,0.06,pos2.x1-pos.x0,0.02])
118 |
119 | levs = np.linspace(-75**expo,75**expo,31)
120 | tik = np.array([-75,-50,-25,0,25,50,75])
121 | tik = np.sign(tik)*abs(tik)**expo
122 |
123 | q1 = axs[0,0].contourf(param1['x_T'],param1['y_T'],in1,levs,cmap=cmocean.cm.balance,extend='both')
124 | cbar = fig.colorbar(q1,cax=cax,orientation='horizontal',ticks=tik)
125 | cbar.set_label(r'Power [Wm$^{-2} \cdot 10^{-3}$]')
126 | cbar.set_ticklabels(np.round(abs(tik)**expo*np.sign(tik)).astype(int))
127 |
128 | axs[1,0].contourf(param3['x_T'],param3['y_T'],in3,levs,cmap=cmocean.cm.balance,extend='both')
129 | axs[2,0].contourf(param2['x_T'],param2['y_T'],in2,levs,cmap=cmocean.cm.balance,extend='both')
130 |
131 | axs[0,2].contourf(param1['x_T'],param1['y_T'],ex1,levs,cmap=cmocean.cm.balance,extend='both')
132 | axs[1,2].contourf(param3['x_T'],param3['y_T'],ex3,levs,cmap=cmocean.cm.balance,extend='both')
133 | axs[2,2].contourf(param2['x_T'],param2['y_T'],ex2,levs,cmap=cmocean.cm.balance,extend='both')
134 |
135 | axs[0,1].contourf(param1['x_T'],param1['y_T'],bf1,levs,cmap=cmocean.cm.balance,extend='both')
136 | axs[1,1].contourf(param3['x_T'],param3['y_T'],bf3,levs,cmap=cmocean.cm.balance,extend='both')
137 | axs[2,1].contourf(param2['x_T'],param2['y_T'],bf2,levs,cmap=cmocean.cm.balance,extend='both')
138 |
139 | #axs[1,3].contourf(param3['x_T'],param3['y_T'],bs,levs,cmap=cmocean.cm.balance,extend='both')
140 |
141 |
142 | axs[0,0].set_title('Wind forcing power',loc='left')
143 | axs[0,1].set_title('Bottom friction power',loc='left')
144 | axs[0,2].set_title('Biharmonic viscosity\n+ backscatter power',loc='left')
145 | #axs[1,3].set_title('Backscatter power',loc='left')
146 |
147 | abc = 'abcdefghijkl'
148 | abci = 0
149 | for i,axcol in enumerate(axs):
150 | for j,ax in enumerate(axcol):
151 | # if not(i in [0,2] and j == 3):
152 | plt.text(0.93,0.93,abc[abci],transform=ax.transAxes,fontweight='bold')
153 | plt.text(0.965,0.87,"%.2f" % mround[abci],transform=ax.transAxes,ha='right')
154 | abci += 1
155 |
156 | axs[0,0].set_xticks([])
157 | axs[0,0].set_yticks([])
158 | axs[0,0].set_xlim(15e3,param1['Lx']-15e3)
159 | axs[0,0].set_ylim(15e3,param1['Ly']-15e3)
160 |
161 | axs[0,0].set_ylabel(r'Low resolution, $\Delta x = $30km',fontsize=11)
162 | axs[1,0].set_ylabel(r'LR + strong backscatter',fontsize=11)
163 | axs[2,0].set_ylabel(r'High resolution, $\Delta x = $7.5km',fontsize=11)
164 |
165 | axs[-1,0].set_xlabel(r'$x$')
166 | axs[-1,1].set_xlabel(r'$x$')
167 | axs[-1,2].set_xlabel(r'$x$')
168 | #axs[-1,3].set_xlabel(r'$x$')
169 |
170 | #axs[0,3].set_frame_on(False)
171 | #axs[2,3].set_frame_on(False)
172 |
173 | axs[0,2].set_ylabel(r'$y$')
174 | axs[0,2].yaxis.set_label_position('right')
175 |
176 | axs[1,2].set_ylabel(r'$y$')
177 | axs[1,2].yaxis.set_label_position('right')
178 |
179 | axs[2,2].set_ylabel(r'$y$')
180 | axs[2,2].yaxis.set_label_position('right')
181 |
182 | plt.savefig(outpath+'plots/power_maps_bs.png',dpi=300)
183 | plt.close(fig)
184 |
--------------------------------------------------------------------------------
/plot/energymap_plot.py:
--------------------------------------------------------------------------------
1 | ## PLOT ENERGY RESERVOIR MAPS
2 | from __future__ import print_function
3 |
4 | path1 = '/network/aopp/cirrus/pred/kloewer/swm_back_ronew/'
5 | path2 = '/network/aopp/cirrus/pred/kloewer/swm_bf_cntrl/data/'
6 | outpath = '/network/home/aopp/kloewer/swm/paperplot/'
7 |
8 | import numpy as np
9 | from scipy import sparse
10 | import matplotlib.pyplot as plt
11 | from cmocean import cm
12 |
13 | plt.rcParams['mathtext.fontset'] = 'cm'
14 | plt.rcParams['mathtext.rm'] = 'serif'
15 |
16 | # OPTIONS
17 | runfolder = [0,6,3]
18 | print('Compare mean plots from run ' + str(runfolder))
19 |
20 | ## read data
21 |
22 | runpath1 = path2+'run%04i' % runfolder[0]
23 | D1 = np.load(runpath1+'/analysis/mean.npy').all()
24 | param1 = np.load(runpath1+'/param.npy').all()
25 |
26 | runpath2 = path2+'run%04i' % runfolder[1]
27 | D2 = np.load(runpath2+'/analysis/mean.npy').all()
28 | param2 = np.load(runpath2+'/param.npy').all()
29 |
30 | runpath3 = path1+'run%04i' % runfolder[2]
31 | D3 = np.load(runpath3+'/analysis/mean.npy').all()
32 | param3 = np.load(runpath3+'/param.npy').all()
33 | print(param3['n_diss'])
34 |
35 | # functions
36 | def h2mat(h,param):
37 | return h.reshape((param['ny'],param['nx']))
38 |
39 | def u2mat(u,param):
40 | return u.reshape((param['ny'],param['nx']-1))
41 |
42 | def v2mat(v,param):
43 | return v.reshape((param['ny']-1,param['nx']))
44 |
45 | def q2mat(q,param):
46 | return q.reshape((param['ny']+1,param['nx']+1))
47 |
48 | ##
49 |
50 | expo = 1.
51 |
52 | mm = np.empty((3,4))
53 |
54 | mm[0,0] = D1['mke'].mean()
55 | mm[1,0] = D3['mke'].mean()
56 | mm[2,0] = D2['mke'].mean()
57 |
58 | mm[0,1] = D1['eke'].mean()
59 | mm[1,1] = D3['eke'].mean()
60 | mm[2,1] = D2['eke'].mean()
61 |
62 | mm[0,2] = D1['mpe'].mean()
63 | mm[1,2] = D3['mpe'].mean()
64 | mm[2,2] = D2['mpe'].mean()
65 |
66 | mm[0,3] = D1['epe'].mean()
67 | mm[1,3] = D3['epe'].mean()
68 | mm[2,3] = D2['epe'].mean()
69 |
70 | # total energy contribution
71 | rm = (mm.T / mm.sum(axis=1)).T
72 | rm = np.round(rm*100,1).flatten()
73 |
74 | for v in ['mke','eke']:
75 | D1[v] = (D1[v]/1e3)**expo
76 | D2[v] = (D2[v]/1e3)**expo
77 | D3[v] = (D3[v]/1e3)**expo
78 |
79 | for v in ['epe','mpe']:
80 | D1[v] = (D1[v]/1e3)**expo
81 | D2[v] = (D2[v]/1e3)**expo
82 | D3[v] = (D3[v]/1e3)**expo
83 |
84 | ## PLOTTING
85 | levs=[]
86 | for v in ['mke','eke','mpe','epe']:
87 | maxs = np.max((np.max(D1[v]),np.max(D2[v])))
88 | #mins = np.min((np.min(D1[v]),np.min(D2[v])))
89 | levs.append(np.linspace(0,maxs*0.95,32))
90 |
91 | fig,axs = plt.subplots(3,4,figsize=(12,9),sharex=True,sharey=True)
92 | plt.tight_layout(rect=[0,.08,1,0.98])
93 | fig.subplots_adjust(wspace=0.03,hspace=0.03)
94 | n = axs.shape[1]
95 | caxs = [0,]*n
96 | for i in range(n):
97 | pos = axs[-1,i].get_position()
98 | caxs[i] = fig.add_axes([pos.x0,0.06,pos.width,0.03])
99 |
100 | qaxs = np.empty_like(axs)
101 |
102 | tiks = [np.array([0,100,200,300,400]),np.array([0,100,200,300,400]),np.array([0,1,2,3,4,5]),np.array([0,2,4,6,8,10,12])]
103 | #tiks = [np.array([0,100,200,300,400]),np.array([0,100,200,300,400,500])*2,np.array([0,1,2,3,4,5,6])*2,np.array([0,10,20,30,40,50])]
104 |
105 |
106 | qaxs[0,0] = axs[0,0].contourf(param1['x_T'],param1['y_T'],h2mat(D1['mke'],param1),levs[0],cmap=cm.thermal,extend='max')
107 | cb1 = fig.colorbar(qaxs[0,0],cax=caxs[0],orientation='horizontal',ticks=tiks[0]**expo)
108 | cb1.set_ticklabels(tiks[0])
109 | cb1.set_label(r'[kJ m$^{-2}$]')
110 |
111 | qaxs[0,1] = axs[0,1].contourf(param1['x_T'],param1['y_T'],h2mat(D1['eke'],param1),levs[1],cmap=cm.thermal,extend='max')
112 | cb2 = fig.colorbar(qaxs[0,1],cax=caxs[1],orientation='horizontal',ticks=tiks[1]**expo)
113 | cb2.set_ticklabels(tiks[1].astype(np.int))
114 | cb2.set_label(r'[kJ m$^{-2}$]')
115 |
116 | qaxs[0,2] = axs[0,2].contourf(param1['x_T'],param1['y_T'],h2mat(D1['mpe'],param1),levs[2],cmap=cm.thermal,extend='max')
117 | cb3 = fig.colorbar(qaxs[0,2],cax=caxs[2],orientation='horizontal',ticks=tiks[2]**expo)
118 | cb3.set_ticklabels(tiks[2])
119 | cb3.set_label(r'[kJ m$^{-2}$]')
120 |
121 | qaxs[0,3] = axs[0,3].contourf(param1['x_T'],param1['y_T'],h2mat(D1['epe'],param1),levs[3],cmap=cm.thermal,extend='max')
122 | cb4 = fig.colorbar(qaxs[0,3],cax=caxs[3],orientation='horizontal',ticks=tiks[3]**expo)
123 | cb4.set_ticklabels(tiks[3])
124 | cb4.set_label(r'[kJ m$^{-2}$]')
125 |
126 | axs[1,0].contourf(param3['x_T'],param3['y_T'],h2mat(D3['mke'],param3),levs[0],cmap=cm.thermal,extend='max')
127 | axs[1,1].contourf(param3['x_T'],param3['y_T'],h2mat(D3['eke'],param3),levs[1],cmap=cm.thermal,extend='max')
128 | axs[1,2].contourf(param3['x_T'],param3['y_T'],h2mat(D3['mpe'],param3),levs[2],cmap=cm.thermal,extend='max')
129 | axs[1,3].contourf(param3['x_T'],param3['y_T'],h2mat(D3['epe'],param3),levs[3],cmap=cm.thermal,extend='max')
130 |
131 | axs[2,0].contourf(param2['x_T'],param2['y_T'],h2mat(D2['mke'],param2),levs[0],cmap=cm.thermal,extend='max')
132 | axs[2,1].contourf(param2['x_T'],param2['y_T'],h2mat(D2['eke'],param2),levs[1],cmap=cm.thermal,extend='max')
133 | axs[2,2].contourf(param2['x_T'],param2['y_T'],h2mat(D2['mpe'],param2),levs[2],cmap=cm.thermal,extend='max')
134 | axs[2,3].contourf(param2['x_T'],param2['y_T'],h2mat(D2['epe'],param2),levs[3],cmap=cm.thermal,extend='max')
135 |
136 | axs[0,0].set_title('MKE',loc='left')
137 | axs[0,1].set_title('EKE',loc='left')
138 | axs[0,2].set_title('MPE',loc='left')
139 | axs[0,3].set_title('EPE',loc='left')
140 |
141 | axs[0,0].set_xticks([])
142 | axs[0,0].set_yticks([])
143 |
144 | axs[0,0].set_xlim(15e3,param1['Lx']-15e3) # to avoid a tiny white frame
145 | axs[0,0].set_ylim(15e3,param1['Ly']-15e3)
146 |
147 | axs[0,0].set_ylabel(r'Low resolution, $\Delta x = $30km',fontsize=11)
148 | axs[1,0].set_ylabel(r'LR + moderate backscatter',fontsize=11)
149 | axs[2,0].set_ylabel(r'High resolution, $\Delta x = $7.5km',fontsize=11)
150 |
151 | abc = 'abcdefghijkl'
152 | abci = 0
153 | for axcol in axs:
154 | for ax in axcol:
155 | plt.text(0.93,0.93,abc[abci],transform=ax.transAxes,fontweight='bold',color='w')
156 | plt.text(0.97,0.04,"%.1f%%" % rm[abci],transform=ax.transAxes,fontweight='bold',color='w',ha='right')
157 | abci += 1
158 |
159 | axs[-1,0].set_xlabel(r'$x$')
160 | axs[-1,1].set_xlabel(r'$x$')
161 | axs[-1,2].set_xlabel(r'$x$')
162 | axs[-1,3].set_xlabel(r'$x$')
163 |
164 | axs[0,3].set_ylabel(r'$y$')
165 | axs[0,3].yaxis.set_label_position('right')
166 |
167 | axs[1,3].set_ylabel(r'$y$')
168 | axs[1,3].yaxis.set_label_position('right')
169 |
170 | axs[2,3].set_ylabel(r'$y$')
171 | axs[2,3].yaxis.set_label_position('right')
172 |
173 | plt.savefig(outpath+'plots/energymap.png',dpi=300)
174 | plt.close(fig)
175 |
--------------------------------------------------------------------------------
/swm_output.py:
--------------------------------------------------------------------------------
1 | ## OUTPUT FUNCTIONS
2 | # PART1: STORE DATA in netCDF4 file (output__nc_ini,output_nc,output_nc_fin)
3 | # PART2: STORE INFO in txt file (output_txt_ini, ...
4 | # PART3: STORE PARAMETERS IN .NPY FILE
5 |
6 | ## STORE DATA
7 | def output_nc_ini():
8 | """ Initialise the netCDF4 file."""
9 |
10 | param['output_j'] = 0 # output index
11 |
12 | # store files, dimensions and variables in dictionnaries
13 | ncu = dict()
14 | ncv = dict()
15 | nceta = dict()
16 |
17 | # creating the netcdf files
18 | ncformat = 'NETCDF4'
19 | ncu['file'] = Dataset(param['output_runpath']+'/u.nc','w',format=ncformat)
20 | ncv['file'] = Dataset(param['output_runpath']+'/v.nc','w',format=ncformat)
21 | nceta['file'] = Dataset(param['output_runpath']+'/eta.nc','w',format=ncformat)
22 |
23 | # write general attributes
24 | for ncfile in [ncu,ncv,nceta]:
25 | ncfile['file'].history = 'Created ' + tictoc.ctime(tictoc.time())
26 | ncfile['file'].description = 'Data from: Shallow-water model in double gyre configuration.'
27 | ncfile['file'].details = 'Cartesian coordinates, beta-plane approximation, Arakawa C-grid'
28 |
29 | # all param ints floats and strings as global attribute
30 | for key in param.keys():
31 | if (type(param[key]) is int) or (type(param[key]) is float) or (type(param[key]) is str):
32 | ncfile['file'].setncattr(key,param[key])
33 |
34 | # create dimensions
35 | ncu['xdim'] = ncu['file'].createDimension('x',param['nx']-1)
36 | ncu['ydim'] = ncu['file'].createDimension('y',param['ny'])
37 | #ncu['tdim'] = ncu['file'].createDimension('t',param['output_tlen'])
38 | ncu['tdim'] = ncu['file'].createDimension('t',None)
39 |
40 |
41 | ncv['xdim'] = ncv['file'].createDimension('x',param['nx'])
42 | ncv['ydim'] = ncv['file'].createDimension('y',param['ny']-1)
43 | ncv['tdim'] = ncv['file'].createDimension('t',None)
44 |
45 | nceta['xdim'] = nceta['file'].createDimension('x',param['nx'])
46 | nceta['ydim'] = nceta['file'].createDimension('y',param['ny'])
47 | nceta['tdim'] = nceta['file'].createDimension('t',None)
48 |
49 | # create variables
50 | p = 'f4' # 32-bit precision storing, or f8 for 64bit
51 | for ncfile,var in zip([ncu,ncv,nceta],['u','v','eta']):
52 | # store time as integers as measured in seconds and gets large
53 | ncfile['t'] = ncfile['file'].createVariable('t','i8',('t',),zlib=True,fletcher32=True)
54 | ncfile['x'] = ncfile['file'].createVariable('x','f8',('x',),zlib=True,fletcher32=True)
55 | ncfile['y'] = ncfile['file'].createVariable('y','f8',('y',),zlib=True,fletcher32=True)
56 | ncfile[var] = ncfile['file'].createVariable(var,p,('t','y','x'),zlib=True,fletcher32=True)
57 |
58 | # write units
59 | for ncfile in [ncu,ncv,nceta]:
60 | ncfile['t'].units = 's'
61 | ncfile['t'].long_name = 'time'
62 | ncfile['x'].units = 'm'
63 | ncfile['x'].long_name = 'x'
64 | ncfile['y'].units = 'm'
65 | ncfile['y'].long_name = 'y'
66 |
67 | ncu['u'].units = 'm/s'
68 | ncv['v'].units = 'm/s'
69 | nceta['eta'].units = 'm'
70 |
71 | # write dimensions
72 | for ncfile,var in zip([ncu,ncv,nceta],['u','v','T']):
73 | ncfile['x'][:] = param['x_'+var]
74 | ncfile['y'][:] = param['y_'+var]
75 |
76 | # make globally available
77 | global ncfiles
78 | ncfiles = [ncu,ncv,nceta]
79 |
80 | output_txt('Output will be stored in '+param['outputpath']+param['runfolder']+' every %i hours.' % (param['output_dt']/3600.))
81 |
82 |
83 | def output_nc(u,v,eta,t):
84 | """ Writes u,v,eta fields on every nth time step """
85 | # output index j
86 | j = param['output_j'] # for convenience
87 |
88 | for ncfile in ncfiles:
89 | ncfile['t'][j] = t
90 |
91 | #TODO issue, use unlimited time dimension or not?
92 | ncfiles[0]['u'][j,:,:] = u2mat(u)
93 | ncfiles[1]['v'][j,:,:] = v2mat(v)
94 | ncfiles[2]['eta'][j,:,:] = h2mat(eta)
95 |
96 | param['output_j'] += 1
97 |
98 | def output_nc_fin():
99 | """ Finalise the output netCDF4 file."""
100 |
101 | for ncfile in ncfiles:
102 | ncfile['file'].close()
103 |
104 | output_txt('All output written in '+param['runfolder']+'.')
105 |
106 | ## STORE INFO in TXT FILE
107 | def readable_secs(secs):
108 | """ Returns a human readable string representing seconds in terms of days, hours, minutes, seconds. """
109 |
110 | days = np.floor(secs/3600/24)
111 | hours = np.floor((secs/3600) % 24)
112 | minutes = np.floor((secs/60) % 60)
113 | seconds = np.floor(secs%3600%60)
114 |
115 | if days > 0:
116 | return ("%id, %ih" % (days,hours))
117 | elif hours > 0:
118 | return ("%ih, %imin" % (hours,minutes))
119 | elif minutes > 0:
120 | return ("%imin, %is" % (minutes,seconds))
121 | else:
122 | return ("%.2fs" % secs)
123 |
124 | def duration_est(tic):
125 | """ Saves an estimate for the total time the model integration will take in the output txt file. """
126 | time_togo = (tictoc.time()-tic) / (i+1) * param['Nt']
127 | str1 = 'Model integration will take approximately '+readable_secs(time_togo)+', '
128 | print(str1)
129 |
130 | if param['output']:
131 | str2 = 'and is hopefully done on '+tictoc.asctime(tictoc.localtime(tic + time_togo))
132 | output_txt(str1+str2)
133 | print(str2)
134 |
135 | def output_txt_ini():
136 | """ Initialise the output txt file for information about the run."""
137 | if param['output']:
138 | param['output_txtfile'] = open(param['output_runpath']+'/info.txt','w')
139 | s = ('Shallow water model run %i initialised on ' % param['run_id'])+tictoc.asctime()+'\n'
140 | param['output_txtfile'].write(s)
141 |
142 | def output_scripts():
143 | """Save all model scripts into a zip file."""
144 | if param['output']:
145 | zf = zipfile.ZipFile(param['output_runpath']+'/scripts.zip','w')
146 | all_scripts = glob.glob('swm_*.py')
147 | [zf.write(script) for script in all_scripts]
148 | zf.close()
149 | output_txt('All model scripts stored in a zipped file.')
150 |
151 | def output_txt(s,end='\n'):
152 | """ Write into the output txt file."""
153 | if param['output']:
154 | param['output_txtfile'].write(s+end)
155 | param['output_txtfile'].flush()
156 |
157 | def output_txt_fin():
158 | """ Finalise the output txt file."""
159 | if param['output']:
160 | param['output_txtfile'].close()
161 |
162 | ## STORE PARAMETERS
163 | def output_param():
164 | """ Stores the param dictionary in a .npy file """
165 | if param['output']:
166 | # filter out 'output_txtfile' as this is a unsaveable textwrapper
167 | dict_tmp = {key:param[key] for key in param.keys() if key != 'output_txtfile'}
168 | np.save(param['output_runpath']+'/param.npy',dict_tmp)
169 |
170 | # store also as a more readable .txt file for quick access on the parameters
171 | param_txtfile = open(param['output_runpath']+'/param.txt','w')
172 | for key in dict_tmp.keys():
173 | if not(key in ['x_T','y_T','x_u','y_u','x_v','y_v','x_q','y_q']):
174 | param_txtfile.write(key + 2*'\t' + str(dict_tmp[key]) + '\n')
175 |
176 | param_txtfile.close()
177 | output_txt('Param dictionary stored as txt and zip.\n')
178 |
--------------------------------------------------------------------------------
/calc/floats/floats_calc.py:
--------------------------------------------------------------------------------
1 | ## LAGRANGIAN FLOATS
2 | import numpy as np
3 | from netCDF4 import Dataset
4 | from scipy.interpolate import RegularGridInterpolator as RGI
5 |
6 | path = '/home/mkloewer/python/swm/'
7 |
8 | # OPTIONS
9 | runfolder = [2,3,4,5,6]
10 | print('Calculating floats from run ' + str(runfolder))
11 |
12 | ## pad function for u,v
13 | def uv_pad(u,v):
14 | """ Pads u,v with kinematic and lateral boundary conditions. """
15 | bs = 0 # boundary speed (positive inwards)
16 | u = np.pad(u,((0,0),(1,1),(1,1)),'constant',constant_values=((0,0),(bs,-bs),(bs,-bs))) # kinematic bc
17 | v = np.pad(v,((0,0),(1,1),(1,1)),'constant',constant_values=((0,0),(bs,-bs),(bs,-bs)))
18 |
19 | return u,v
20 |
21 | ## Reading data in blocks to save memory.
22 | def read_data(index_start):
23 | """ Based on the start index decide which datasets to load and do so."""
24 | index_end = index_start + 2*ntime
25 |
26 | file_length0 = np.hstack((0,file_length))
27 | file_length_each = np.hstack((file_length[0],np.diff(file_length)))
28 |
29 | start_crit = np.logical_and(index_start <= file_length,index_start > file_length0[:-1])
30 | end_crit = np.logical_and(index_end <= file_length,index_end > file_length0[:-1])
31 |
32 | data_to_read = np.logical_or(start_crit,end_crit)
33 |
34 | d = 0
35 | for r,rn in zip(np.array(runfolder)[data_to_read],np.arange(len(runfolder))[data_to_read]):
36 |
37 | # r is the run id
38 | # rn is the relative number of the run, starting with 0 for the first in runfolder
39 |
40 | runpath = path+'data/run%04i' % r
41 |
42 | if d == 0: # in case the first data set is read
43 |
44 | idx0 = index_start - file_length0[rn]
45 | idx1 = min(index_end - file_length0[rn],file_length_each[rn]+1)
46 |
47 | ncu = Dataset(runpath+'/u.nc')
48 | u = ncu.variables['u'][idx0:idx1,:,:]
49 | ncu.close()
50 |
51 | ncv = Dataset(runpath+'/v.nc')
52 | v = ncv.variables['v'][idx0:idx1,:,:]
53 | ncv.close()
54 |
55 | else: # concatenate second data set
56 | print('reading second file')
57 | idx0 = 1 # skip the first as this is a duplicate from the last step of previous file
58 | idx1 = index_end - file_length0[rn] + 1
59 |
60 | ncu = Dataset(runpath+'/u.nc')
61 | ncv = Dataset(runpath+'/v.nc')
62 |
63 | u = np.concatenate((u,ncu.variables['u'][idx0:idx1,:,:]))
64 | v = np.concatenate((v,ncv.variables['v'][idx0:idx1,:,:]))
65 |
66 | d = 1 # set to 1 to concatenate any further data set
67 |
68 | return u,v
69 |
70 | ## read grid
71 | file_length = np.empty(len(runfolder)).astype(np.int) # list to store the number of time steps in each file
72 |
73 | for i,r in enumerate(runfolder):
74 | runpath = path+'data/run%04i' % r
75 | ncu = Dataset(runpath+'/u.nc')
76 |
77 | if i == 0: time = ncu.variables['t'][:]
78 | else: time = np.hstack((time,ncu.variables['t'][:]))
79 |
80 | file_length[i] = len(time)
81 |
82 | dt = time[1]-time[0]
83 |
84 | # read spatial grid
85 | param = np.load(runpath+'/param.npy').all()
86 |
87 | # renaming for convenience
88 | x_u = param['x_u']
89 | y_u = param['y_u']
90 |
91 | x_v = param['x_v']
92 | y_v = param['y_v']
93 |
94 | # pad x,y to include the boundary conditions
95 | # grid is not equidistant at the boundary however ...
96 | x_u = np.hstack((0.,x_u,param['Lx']))
97 | y_u = np.hstack((0.,y_u,param['Ly']))
98 |
99 | y_v = np.hstack((0,y_v,param['Ly']))
100 | x_v = np.hstack((0,x_v,param['Lx']))
101 |
102 | print('Grid read.')
103 |
104 | ## OPTIONS
105 | N = 100 # number of floats
106 | ntime = 1460 # number of timesteps to integrate forward: equals one year
107 | R = 1000 # number of repetitions (from random start dates)
108 |
109 | # preallocate
110 | nbins = 254
111 | H = np.zeros((nbins,nbins))
112 |
113 | #exclude up to 30km from boundary
114 | Hrange = [[30e3,3810e3],[30e3,3810e3]]
115 |
116 | # edges of inital seeding region
117 | seedx = np.array([100,200])*1e3
118 | seedy = np.array([100,1920])*1e3
119 |
120 | all_startidxs = np.sort(np.random.randint(0,len(time)-ntime-2,R))
121 |
122 | ichunk = 0
123 | while all_startidxs.shape[0]: # delete from all_startidxs in every loop until empty
124 | ichunk += 1
125 |
126 | # indices for current chunk
127 | startidxs = all_startidxs[all_startidxs < (all_startidxs[0]+ntime)]
128 |
129 | # number of repetitions within chunk
130 | R_chunk = len(startidxs)
131 |
132 | # remove these dates from all_startidxs
133 | all_startidxs = all_startidxs[len(startidxs):]
134 |
135 | u,v = read_data(startidxs[0])
136 | print('Data chunk %i read.' % ichunk)
137 |
138 | # padding with boundary conditions
139 | u,v = uv_pad(u,v)
140 | print('Padding boundary conditions: done.')
141 |
142 | # Advect the floats
143 | Xa = np.empty((ntime,N,R_chunk)).astype(np.float64)
144 | Ya = np.empty_like(Xa)
145 |
146 | # preallocate
147 | X = np.empty((ntime,N)).astype(np.float64)
148 | Y = np.empty_like(X).astype(np.float64)
149 |
150 | for r in range(R_chunk):
151 | # relative index within dataset
152 | i_rel = startidxs[r] - startidxs[0]
153 |
154 | # set initial conditions
155 | X[0,:] = np.random.rand(N)*np.diff(seedx) + seedx[0]
156 | Y[0,:] = np.random.rand(N)*np.diff(seedy) + seedy[0]
157 |
158 | # old time step
159 | Iu1 = RGI((x_u,y_u),u[i_rel,:,:].T,bounds_error=False,fill_value=-1)
160 | Iv1 = RGI((x_v,y_v),v[i_rel,:,:].T,bounds_error=False,fill_value=-1)
161 |
162 | for i in range(ntime-1):
163 | # Following the ideas of the Crank-Nicolson method
164 | # However, as the RHS is discrete, Euler forward is used to estimate
165 | # the RHS of the next time step
166 |
167 | # next time step
168 | # fill_value means once they are out of the boundary floats stop moving
169 | Iu2 = RGI((x_u,y_u),u[i+i_rel+1,:,:].T,bounds_error=False,fill_value=0)
170 | Iv2 = RGI((x_v,y_v),v[i+i_rel+1,:,:].T,bounds_error=False,fill_value=0)
171 |
172 | # old RHS
173 | dXdt1 = Iu1((X[i,:],Y[i,:]))
174 | dYdt1 = Iv1((X[i,:],Y[i,:]))
175 |
176 | # new RHS based on new time step
177 | dXdt2 = Iu2((X[i,:] + dt*dXdt1,Y[i,:] + dt*dYdt1))
178 | dYdt2 = Iv2((X[i,:] + dt*dXdt1,Y[i,:] + dt*dYdt1))
179 |
180 | # average of old and new RHS
181 | X[i+1,:] = X[i,:] + 0.5*dt*(dXdt1+dXdt2)
182 | Y[i+1,:] = Y[i,:] + 0.5*dt*(dYdt1+dYdt2)
183 |
184 | # rename to avoid re-setting up of RGI functions
185 | Iu1 = Iu2 # next -> old
186 | Iv1 = Iv2
187 |
188 | Xa[:,:,r] = X
189 | Ya[:,:,r] = Y
190 |
191 | print('Advecting floats done.')
192 |
193 | # free memory
194 | del u,v
195 |
196 | # histogram do not count the grid cell at the boundary
197 | Hi,xe,ye = np.histogram2d(Xa.flatten(),Ya.flatten(),bins=nbins,range=Hrange)
198 | H += Hi
199 | print('Histogram computed.')
200 |
201 | # free memory
202 | del Xa,Ya
203 |
204 |
205 | print(H.sum())
206 |
207 | # mid points
208 | xm = xe[:-1] + (xe[1]-xe[0])/2.
209 | ym = ye[:-1] + (ye[1]-ye[0])/2.
210 |
211 | ## STORING
212 | dic = dict()
213 | all_var2export = ['X','Y','seedx','seedy','H','xe','ye','xm','ym']
214 |
215 | for vars in all_var2export:
216 | exec('dic[vars] ='+vars)
217 |
218 | np.save(runpath+'/analysis/floats.npy',dic)
219 | print('Everything stored.')
220 |
--------------------------------------------------------------------------------