From edd992b7e7cf3222bb6b3591057a049e30c3eb1d Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Tue, 11 Aug 2020 13:48:29 +0100 Subject: [PATCH 01/46] averaged sw model with 3 different time-stepping methods: SSPRK3, RK2, Heun's. Default SSPRK3. --- averaged_sw_explicit.py | 321 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 averaged_sw_explicit.py diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py new file mode 100644 index 0000000..f8867e9 --- /dev/null +++ b/averaged_sw_explicit.py @@ -0,0 +1,321 @@ +#get command arguments +import argparse +parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') +parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') +parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') +parser.add_argument('--dumpt', type=float, default=6, help='Dump time in hours. Default 6.') +parser.add_argument('--dt', type=float, default=2, help='Timestep in hours. Default 2.') +parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') +parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') +parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') +parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') +parser.add_argument('--filter2', type=bool, default=False, help='Use a filter for cheby2') +parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') +parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') +parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'heuns', 'ssprk3'], help='Choose a time steeping method. Default SSPRK3.') +parser.add_argument('--filename', type=str, default='explicit') +args = parser.parse_known_args() +args = args[0] + +filter = args.filter +filter2 = args.filter2 +filter_val = args.filter_val +timestepping = args.timestepping + +#checking cheby parameters based on ref_level +ref_level = args.ref_level +eigs = [0.003465, 0.007274, 0.014955] #maximum frequency +from math import pi +min_time_period = 2*pi/eigs[ref_level-3] +hours = args.dt +dt = 60*60*hours +rho = args.rho #averaging window is rho*dt + +L = eigs[ref_level-3]*dt*rho +ppp = args.ppp #points per (minimum) time period + +# rho*dt/min_time_period = number of min_time_periods that fit in rho*dt +# we want at least ppp times this number of sample points +from math import ceil +Mbar = ceil(ppp*rho*dt*eigs[ref_level-3]/2/pi) +print(args) + +if args.get_Mbar: + print("Mbar="+str(Mbar)) + import sys; sys.exit() + +from cheby_exp import * +from firedrake import * +import numpy as np + +from firedrake.petsc import PETSc +print = PETSc.Sys.Print +assert Mbar==COMM_WORLD.size, str(Mbar)+' '+str(COMM_WORLD.size) +print('averaging window', rho*dt, 'sample width', rho*dt/Mbar) +print('Mbar', Mbar, 'samples per min time period', min_time_period/(rho*dt/Mbar)) + +#ensemble communicator +ensemble = Ensemble(COMM_WORLD, 1) + +#some domain, parameters and FS setup +R0 = 6371220. +H = Constant(5960.) + +mesh = IcosahedralSphereMesh(radius=R0, + refinement_level=ref_level, degree=3, + comm = ensemble.comm) +cx = SpatialCoordinate(mesh) +mesh.init_cell_orientations(cx) + +cx, cy, cz = SpatialCoordinate(mesh) + +outward_normals = CellNormal(mesh) +perp = lambda u: cross(outward_normals, u) + +V1 = FunctionSpace(mesh, "BDM", 2) +V2 = FunctionSpace(mesh, "DG", 1) +W = MixedFunctionSpace((V1, V2)) + +u, eta = TrialFunctions(W) +v, phi = TestFunctions(W) + +Omega = Constant(7.292e-5) # rotation rate +f = 2*Omega*cz/Constant(R0) # Coriolis parameter +g = Constant(9.8) # Gravitational constant +b = Function(V2, name="Topography") +c = sqrt(g*H) + +#Set up the exponential operator +operator_in = Function(W) +u_in, eta_in = split(operator_in) + +#D = eta + b + +u, eta = TrialFunctions(W) +v, phi = TestFunctions(W) + +F = ( + - inner(f*perp(u_in),v)*dx + +g*eta_in*div(v)*dx + - H*div(u_in)*phi*dx +) + +a = inner(v,u)*dx + phi*eta*dx + +operator_out = Function(W) + +params = { + 'ksp_type': 'preonly', + 'pc_type': 'fieldsplit', + 'fieldsplit_0_ksp_type':'cg', + 'fieldsplit_0_pc_type':'bjacobi', + 'fieldsplit_0_sub_pc_type':'ilu', + 'fieldsplit_1_ksp_type':'preonly', + 'fieldsplit_1_pc_type':'bjacobi', + 'fieldsplit_1_sub_pc_type':'ilu' +} + +Prob = LinearVariationalProblem(a, F, operator_out) +OperatorSolver = LinearVariationalSolver(Prob, solver_parameters=params) + +ncheb = 10000 + +cheby = cheby_exp(OperatorSolver, operator_in, operator_out, + ncheb, tol=1.0e-8, L=L, filter=filter, filter_val=filter_val) + +cheby2 = cheby_exp(OperatorSolver, operator_in, operator_out, + ncheb, tol=1.0e-8, L=L, filter=filter2, filter_val=filter_val) + +#solvers for slow part +USlow_in = Function(W) #value at previous timestep +USlow_out = Function(W) #value at RK stage + +u0, eta0 = split(USlow_in) + +#RHS for Forward Euler step +gradperp = lambda f: perp(grad(f)) +n = FacetNormal(mesh) +Upwind = 0.5 * (sign(dot(u0, n)) + 1) +both = lambda u: 2*avg(u) +K = 0.5*inner(u0, u0) +uup = 0.5 * (dot(u0, n) + abs(dot(u0, n))) + +dT = Constant(dt) + +vector_invariant = True +if vector_invariant: + L = ( + dT*inner(perp(grad(inner(v, perp(u0)))), u0)*dx + - dT*inner(both(perp(n)*inner(v, perp(u0))), + both(Upwind*u0))*dS + + dT*div(v)*K*dx + + dT*inner(grad(phi), u0*(eta0-b))*dx + - dT*jump(phi)*(uup('+')*(eta0('+')-b('+')) + - uup('-')*(eta0('-') - b('-')))*dS + ) +else: + L = ( + dT*inner(div(outer(u0, v)), u0)*dx + - dT*inner(both(inner(n, u0)*v), both(Upwind*u0))*dS + + dT*inner(grad(phi), u0*(eta0-b))*dx + - dT*jump(phi)*(uup('+')*(eta0('+')-b('+')) + - uup('-')*(eta0('-') - b('-')))*dS + ) + +#with topography, D = H + eta - b + +SlowProb = LinearVariationalProblem(a, L, USlow_out) +SlowSolver = LinearVariationalSolver(SlowProb, + solver_parameters = params) + +t = 0. +tmax = 60.*60.*args.tmax +dumpt = args.dumpt*60.*60. +tdump = 0. + +svals = np.arange(0.5, Mbar)/Mbar #tvals goes from -rho*dt/2 to rho*dt/2 +weights = np.exp(-1.0/svals/(1.0-svals)) +weights = weights/np.sum(weights) +print(weights) +svals -= 0.5 + +rank = ensemble.ensemble_comm.rank +expt = rho*dt*svals[rank] +wt = weights[rank] +print(wt,"weight",expt) + +x = SpatialCoordinate(mesh) + +u_0 = 20.0 # maximum amplitude of the zonal wind [m/s] +u_max = Constant(u_0) +u_expr = as_vector([-u_max*x[1]/R0, u_max*x[0]/R0, 0.0]) +eta_expr = - ((R0 * Omega * u_max + u_max*u_max/2.0)*(x[2]*x[2]/(R0*R0)))/g +un = Function(V1, name="Velocity").project(u_expr) +etan = Function(V2, name="Elevation").project(eta_expr) + +# Topography +rl = pi/9.0 +lambda_x = atan_2(x[1]/R0, x[0]/R0) +lambda_c = -pi/2.0 +phi_x = asin(x[2]/R0) +phi_c = pi/6.0 +minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +bexpr = 2000.0*(1 - sqrt(minarg)/rl) +b.interpolate(bexpr) + +un1 = Function(V1) +etan1 = Function(V1) + +U = Function(W) +DU = Function(W) +U1 = Function(W) +U2 = Function(W) +V = Function(W) + +U_u, U_eta = U.split() +U_u.assign(un) +U_eta.assign(etan) + +name = args.filename +if rank==0: + file_sw = File(name+'.pvd', comm=ensemble.comm) + file_sw.write(un, etan, b) + +nonlinear = args.nonlinear + +print ('tmax', tmax, 'dt', dt) +while t < tmax + 0.5*dt: + print(t) + t += dt + tdump += dt + + if timestepping == 'ssprk3': + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Step forward U1 + DU.assign(U + U1) + cheby2.apply(DU, U1, dt) + + #Average the nonlinearity + cheby.apply(U1, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U2) + #Advance U + DU.assign(U1 + U2) + cheby2.apply(DU, U2, -dt/2) + cheby2.apply(U, U1, dt/2) + U2.assign(0.75*U1 + 0.25*U2) + + #Average the nonlinearity + cheby.apply(U2, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Advance U + DU.assign(U2 + U1) + cheby2.apply(DU, U2, dt/2) + cheby2.apply(U, U1, dt) + U.assign(1/3*U1 + 2/3*U2) + elif timestepping == 'rk2': + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + #Step forward V + V.assign(U + 0.5*V) + + #transform forwards to U^{n+1/2} + cheby2.apply(V, DU, dt/2) + + #Average the nonlinearity + cheby.apply(DU, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + #Advance U + cheby2.apply(U, DU, dt/2) + V.assign(DU + V) + + #transform forwards to next timestep + cheby2.apply(V, U, dt/2) + elif timestepping == 'heuns': + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Step forward U1 + U1.assign(U + U1) + + #Average the nonlinearity + cheby2.apply(U1, DU, dt) + cheby.apply(DU, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U2) + #Advance U + cheby2.apply(U, DU, dt) + U2.assign(DU + U2) + + #transform forwards to next timestep + cheby2.apply(U1, U, dt) + U.assign(0.5*U + 0.5*U2) + + if rank == 0: + if tdump > dumpt - dt*0.5: + un.assign(U_u) + etan.assign(U_eta) + file_sw.write(un, etan, b) + tdump -= dumpt From ea7f6bca41b86784ae0207b18eefd721315e27bd Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Tue, 8 Sep 2020 15:40:31 +0100 Subject: [PATCH 02/46] Added leapfrog. Blew up at around 30 hours --- averaged_sw_explicit.py | 165 +++++++++++++++++++++++++++------------- 1 file changed, 113 insertions(+), 52 deletions(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index f8867e9..8e6442d 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -9,10 +9,11 @@ parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') -parser.add_argument('--filter2', type=bool, default=False, help='Use a filter for cheby2') +parser.add_argument('--filter2', type=bool, default=True, help='Use a filter for cheby2') parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') -parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'heuns', 'ssprk3'], help='Choose a time steeping method. Default SSPRK3.') +parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') +parser.add_argument('--asselin', type=float, default=0.15, help='Asselin Filter coefficient. Default 0.15.') parser.add_argument('--filename', type=str, default='explicit') args = parser.parse_known_args() args = args[0] @@ -21,6 +22,7 @@ filter2 = args.filter2 filter_val = args.filter_val timestepping = args.timestepping +asselin = args.asselin #checking cheby parameters based on ref_level ref_level = args.ref_level @@ -229,8 +231,11 @@ t += dt tdump += dt - if timestepping == 'ssprk3': - #Average the nonlinearity + if t == dt and timestepping == 'leapfrog': + U_old = Function(W) + U_new = Function(W) + + #First time step using SSPRK3 cheby.apply(U, USlow_in, expt) SlowSolver.solve() cheby.apply(USlow_out, DU, -expt) @@ -262,56 +267,112 @@ DU.assign(U2 + U1) cheby2.apply(DU, U2, dt/2) cheby2.apply(U, U1, dt) - U.assign(1/3*U1 + 2/3*U2) - elif timestepping == 'rk2': - #Average the nonlinearity - cheby.apply(U, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, V) - #Step forward V - V.assign(U + 0.5*V) - - #transform forwards to U^{n+1/2} - cheby2.apply(V, DU, dt/2) - - #Average the nonlinearity - cheby.apply(DU, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, V) - #Advance U - cheby2.apply(U, DU, dt/2) - V.assign(DU + V) - - #transform forwards to next timestep - cheby2.apply(V, U, dt/2) - elif timestepping == 'heuns': - #Average the nonlinearity - cheby.apply(U, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U1) - #Step forward U1 - U1.assign(U + U1) - - #Average the nonlinearity - cheby2.apply(U1, DU, dt) - cheby.apply(DU, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U2) - #Advance U - cheby2.apply(U, DU, dt) - U2.assign(DU + U2) #transform forwards to next timestep - cheby2.apply(U1, U, dt) - U.assign(0.5*U + 0.5*U2) + U_old.assign(U) + U.assign(1/3*U1 + 2/3*U2) + else: + if timestepping == 'leapfrog': + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + #Step forward V + cheby2.apply(U_old, DU, dt) + V.assign(DU + 2*V) + cheby2.apply(V, U_new, dt) + #Average the nonlinearity + cheby2.apply(U_old, U1, dt) + cheby2.apply(U_new, U2, -dt) + V.assign((U1+U2)*0.5 - U) + #Advance U + U_old.assign(U + asselin*V) + U.assign(U_new) + elif timestepping == 'ssprk3': + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Step forward U1 + DU.assign(U + U1) + cheby2.apply(DU, U1, dt) + + #Average the nonlinearity + cheby.apply(U1, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U2) + #Advance U + DU.assign(U1 + U2) + cheby2.apply(DU, U2, -dt/2) + cheby2.apply(U, U1, dt/2) + U2.assign(0.75*U1 + 0.25*U2) + + #Average the nonlinearity + cheby.apply(U2, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Advance U + DU.assign(U2 + U1) + cheby2.apply(DU, U2, dt/2) + cheby2.apply(U, U1, dt) + U.assign(1/3*U1 + 2/3*U2) + elif timestepping == 'rk2': + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + #Step forward V + V.assign(U + 0.5*V) + + #transform forwards to U^{n+1/2} + cheby2.apply(V, DU, dt/2) + + #Average the nonlinearity + cheby.apply(DU, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + #Advance U + cheby2.apply(U, DU, dt/2) + V.assign(DU + V) + + #transform forwards to next timestep + cheby2.apply(V, U, dt/2) + elif timestepping == 'heuns': + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Step forward U1 + U1.assign(U + U1) + + #Average the nonlinearity + cheby2.apply(U1, DU, dt) + cheby.apply(DU, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U2) + #Advance U + cheby2.apply(U, DU, dt) + U2.assign(DU + U2) + + #transform forwards to next timestep + cheby2.apply(U1, U, dt) + U.assign(0.5*U + 0.5*U2) if rank == 0: if tdump > dumpt - dt*0.5: From 1a28280e44470fe3d7cf9c0dbbc9ce5619362975 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Tue, 22 Sep 2020 13:45:57 +0100 Subject: [PATCH 03/46] tidied up averaged_sw_explicit.py and added leapfrog to timestepping options --- averaged_sw_explicit.py | 150 ++++------------------------------------ timestepping_methods.py | 116 +++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 135 deletions(-) create mode 100644 timestepping_methods.py diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index 8e6442d..78d86e7 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -1,3 +1,4 @@ + #get command arguments import argparse parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') @@ -13,7 +14,7 @@ parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') -parser.add_argument('--asselin', type=float, default=0.15, help='Asselin Filter coefficient. Default 0.15.') +parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') parser.add_argument('--filename', type=str, default='explicit') args = parser.parse_known_args() args = args[0] @@ -214,6 +215,8 @@ U2 = Function(W) V = Function(W) +from timestepping_methods import * + U_u, U_eta = U.split() U_u.assign(un) U_eta.assign(etan) @@ -231,148 +234,25 @@ t += dt tdump += dt - if t == dt and timestepping == 'leapfrog': + if t < dt*1.5 and timestepping == 'leapfrog': U_old = Function(W) U_new = Function(W) - - #First time step using SSPRK3 - cheby.apply(U, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U1) - #Step forward U1 - DU.assign(U + U1) - cheby2.apply(DU, U1, dt) - - #Average the nonlinearity - cheby.apply(U1, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U2) - #Advance U - DU.assign(U1 + U2) - cheby2.apply(DU, U2, -dt/2) - cheby2.apply(U, U1, dt/2) - U2.assign(0.75*U1 + 0.25*U2) - - #Average the nonlinearity - cheby.apply(U2, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U1) - #Advance U - DU.assign(U2 + U1) - cheby2.apply(DU, U2, dt/2) - cheby2.apply(U, U1, dt) - - #transform forwards to next timestep U_old.assign(U) - U.assign(1/3*U1 + 2/3*U2) + rk2(U, USlow_in, USlow_out, DU, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) else: if timestepping == 'leapfrog': - #Average the nonlinearity - cheby.apply(U, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, V) - #Step forward V - cheby2.apply(U_old, DU, dt) - V.assign(DU + 2*V) - cheby2.apply(V, U_new, dt) - #Average the nonlinearity - cheby2.apply(U_old, U1, dt) - cheby2.apply(U_new, U2, -dt) - V.assign((U1+U2)*0.5 - U) - #Advance U - U_old.assign(U + asselin*V) - U.assign(U_new) + leapfrog(U, USlow_in, USlow_out, U_old, U_new, DU, U1, U2, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt, asselin) elif timestepping == 'ssprk3': - #Average the nonlinearity - cheby.apply(U, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U1) - #Step forward U1 - DU.assign(U + U1) - cheby2.apply(DU, U1, dt) - - #Average the nonlinearity - cheby.apply(U1, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U2) - #Advance U - DU.assign(U1 + U2) - cheby2.apply(DU, U2, -dt/2) - cheby2.apply(U, U1, dt/2) - U2.assign(0.75*U1 + 0.25*U2) - - #Average the nonlinearity - cheby.apply(U2, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U1) - #Advance U - DU.assign(U2 + U1) - cheby2.apply(DU, U2, dt/2) - cheby2.apply(U, U1, dt) - U.assign(1/3*U1 + 2/3*U2) + ssprk3(U, USlow_in, USlow_out, DU, U1, U2, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) elif timestepping == 'rk2': - #Average the nonlinearity - cheby.apply(U, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, V) - #Step forward V - V.assign(U + 0.5*V) - - #transform forwards to U^{n+1/2} - cheby2.apply(V, DU, dt/2) - - #Average the nonlinearity - cheby.apply(DU, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, V) - #Advance U - cheby2.apply(U, DU, dt/2) - V.assign(DU + V) - - #transform forwards to next timestep - cheby2.apply(V, U, dt/2) + rk2(U, USlow_in, USlow_out, DU, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) elif timestepping == 'heuns': - #Average the nonlinearity - cheby.apply(U, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U1) - #Step forward U1 - U1.assign(U + U1) - - #Average the nonlinearity - cheby2.apply(U1, DU, dt) - cheby.apply(DU, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, U2) - #Advance U - cheby2.apply(U, DU, dt) - U2.assign(DU + U2) - - #transform forwards to next timestep - cheby2.apply(U1, U, dt) - U.assign(0.5*U + 0.5*U2) + heuns(U, USlow_in, USlow_out, DU, U1, U2, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) if rank == 0: if tdump > dumpt - dt*0.5: diff --git a/timestepping_methods.py b/timestepping_methods.py new file mode 100644 index 0000000..f2f63bb --- /dev/null +++ b/timestepping_methods.py @@ -0,0 +1,116 @@ +#timestepping options for averaged_sw_explicit.py +#rk2/heuns/ssprk3/leapfrog + +from firedrake import Function + +def rk2(U, USlow_in, USlow_out, DU, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt): + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + #Step forward V + V.assign(U + 0.5*V) + + #transform forwards to U^{n+1/2} + cheby2.apply(V, DU, dt/2) + + #Average the nonlinearity + cheby.apply(DU, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + #Advance U + cheby2.apply(U, DU, dt/2) + V.assign(DU + V) + + #transform forwards to next timestep + cheby2.apply(V, U, dt/2) + + +def heuns(U, USlow_in, USlow_out, DU, U1, U2, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt): + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Step forward U1 + U1.assign(U + U1) + + #Average the nonlinearity + cheby2.apply(U1, DU, dt) + cheby.apply(DU, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U2) + #Step forward U2 + cheby2.apply(U, DU, dt) + U2.assign(DU + U2) + + #transform forwards to next timestep + cheby2.apply(U1, U, dt) + U.assign(0.5*U + 0.5*U2) + + +def ssprk3(U, USlow_in, USlow_out, DU, U1, U2, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt): + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Step forward U1 + DU.assign(U + U1) + cheby2.apply(DU, U1, dt) + + #Average the nonlinearity + cheby.apply(U1, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U2) + #Step forward U2 + DU.assign(U1 + U2) + cheby2.apply(DU, U2, -dt/2) + cheby2.apply(U, U1, dt/2) + U2.assign(0.75*U1 + 0.25*U2) + + #Average the nonlinearity + cheby.apply(U2, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Advance U + DU.assign(U2 + U1) + cheby2.apply(DU, U2, dt/2) + cheby2.apply(U, U1, dt) + U.assign(1/3*U1 + 2/3*U2) + + +def leapfrog(U, USlow_in, USlow_out, U_old, U_new, DU, U1, U2, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt, asselin): + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + #Step forward V + cheby2.apply(U_old, DU, dt) + V.assign(DU + 2*V) + cheby2.apply(V, U_new, dt) + #Asselin filter + cheby2.apply(U_old, U1, dt) + cheby2.apply(U_new, U2, -dt) + V.assign((U1+U2)*0.5 - U) + U_old.assign(U + asselin*V) + #Advance U + U.assign(U_new) From 9671e95ffab0897d9002106993beaaef73f4ff05 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Tue, 29 Sep 2020 15:21:24 +0100 Subject: [PATCH 04/46] adding rk4 - got UFL error --- averaged_sw_explicit.py | 6 +++- timestepping_methods.py | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index 78d86e7..944cdf7 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -13,7 +13,7 @@ parser.add_argument('--filter2', type=bool, default=True, help='Use a filter for cheby2') parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') -parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') +parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') parser.add_argument('--filename', type=str, default='explicit') args = parser.parse_known_args() @@ -213,6 +213,7 @@ DU = Function(W) U1 = Function(W) U2 = Function(W) +U3 = Function(W) V = Function(W) from timestepping_methods import * @@ -250,6 +251,9 @@ elif timestepping == 'rk2': rk2(U, USlow_in, USlow_out, DU, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + elif timestepping == 'rk4': + rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) elif timestepping == 'heuns': heuns(U, USlow_in, USlow_out, DU, U1, U2, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) diff --git a/timestepping_methods.py b/timestepping_methods.py index f2f63bb..aade2b2 100644 --- a/timestepping_methods.py +++ b/timestepping_methods.py @@ -31,6 +31,73 @@ def rk2(U, USlow_in, USlow_out, DU, V, W, cheby2.apply(V, U, dt/2) +def rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt): + #Average the nonlinearity + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U1) + #Step forward U1 + U1.assign(U + 0.5*U1) + + #Average the nonlinearity + cheby2.apply(U1, DU, dt/2) + cheby.apply(DU, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U2) + #Step forward U2 + cheby2.apply(U, DU, dt/2) + U2.assign(DU + 0.5*U2) + + #Average the nonlinearity + cheby.apply(U2, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U3) + #Step forward U1 + cheby2.apply(U, DU, dt/2) + U3.assign(DU + U3) + + #Average the nonlinearity + cheby2.apply(U1, DU, dt/2) + cheby.apply(DU, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + cheby2.apply(V, U1, dt/2) + + cheby.apply(U2, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + cheby2.apply(V, U2, dt/2) + + cheby2.apply(U3, DU, dt/2) + cheby.apply(DU, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, U3) + + cheby.apply(U, USlow_in, expt) + SlowSolver.solve() + cheby.apply(USlow_out, DU, -expt) + DU *= wt + ensemble.allreduce(DU, V) + cheby2.apply(V, DU, dt) + + cheby2.apply(U, V, dt) + + U.assign(V + DU/6 + U1/3 + U2/3 + U3/6) + + def heuns(U, USlow_in, USlow_out, DU, U1, U2, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt): #Average the nonlinearity From d20b4f615d433c69ff52beb37491cd34ad9a33a4 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Tue, 29 Sep 2020 15:35:52 +0100 Subject: [PATCH 05/46] fixed the UFL error --- timestepping_methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/timestepping_methods.py b/timestepping_methods.py index aade2b2..e1afb6f 100644 --- a/timestepping_methods.py +++ b/timestepping_methods.py @@ -95,7 +95,7 @@ def rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V, W, cheby2.apply(U, V, dt) - U.assign(V + DU/6 + U1/3 + U2/3 + U3/6) + U.assign(V + 1/6*DU + 1/3*U1 + 1/3*U2 + 1/6*U3) def heuns(U, USlow_in, USlow_out, DU, U1, U2, W, From 36a9680d08e7093da533faa115f8bdba6f73b082 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Fri, 2 Oct 2020 11:52:33 +0100 Subject: [PATCH 06/46] tidied up rk4 which works now --- averaged_sw_explicit.py | 5 ++++- timestepping_methods.py | 41 +++++++++++------------------------------ 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index 944cdf7..3accce4 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -214,6 +214,9 @@ U1 = Function(W) U2 = Function(W) U3 = Function(W) +V1 = Function(W) +V2 = Function(W) +V3 = Function(W) V = Function(W) from timestepping_methods import * @@ -252,7 +255,7 @@ rk2(U, USlow_in, USlow_out, DU, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) elif timestepping == 'rk4': - rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V, W, + rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V1, V2, V3, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) elif timestepping == 'heuns': heuns(U, USlow_in, USlow_out, DU, U1, U2, W, diff --git a/timestepping_methods.py b/timestepping_methods.py index e1afb6f..8fce36c 100644 --- a/timestepping_methods.py +++ b/timestepping_methods.py @@ -31,16 +31,16 @@ def rk2(U, USlow_in, USlow_out, DU, V, W, cheby2.apply(V, U, dt/2) -def rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V, W, +def rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V1, V2, V3, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt): #Average the nonlinearity cheby.apply(U, USlow_in, expt) SlowSolver.solve() cheby.apply(USlow_out, DU, -expt) DU *= wt - ensemble.allreduce(DU, U1) + ensemble.allreduce(DU, V1) #Step forward U1 - U1.assign(U + 0.5*U1) + U1.assign(U + 0.5*V1) #Average the nonlinearity cheby2.apply(U1, DU, dt/2) @@ -48,36 +48,23 @@ def rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V, W, SlowSolver.solve() cheby.apply(USlow_out, DU, -expt) DU *= wt - ensemble.allreduce(DU, U2) + ensemble.allreduce(DU, V2) #Step forward U2 - cheby2.apply(U, DU, dt/2) - U2.assign(DU + 0.5*U2) + cheby2.apply(U, V, dt/2) + U2.assign(V + 0.5*V2) #Average the nonlinearity cheby.apply(U2, USlow_in, expt) SlowSolver.solve() cheby.apply(USlow_out, DU, -expt) DU *= wt - ensemble.allreduce(DU, U3) + ensemble.allreduce(DU, V3) #Step forward U1 - cheby2.apply(U, DU, dt/2) - U3.assign(DU + U3) + U3.assign(V + V3) #Average the nonlinearity - cheby2.apply(U1, DU, dt/2) - cheby.apply(DU, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, V) - cheby2.apply(V, U1, dt/2) - - cheby.apply(U2, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, V) - cheby2.apply(V, U2, dt/2) + cheby2.apply(V2, U1, dt/2) + cheby2.apply(V3, U2, dt/2) cheby2.apply(U3, DU, dt/2) cheby.apply(DU, USlow_in, expt) @@ -86,13 +73,7 @@ def rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V, W, DU *= wt ensemble.allreduce(DU, U3) - cheby.apply(U, USlow_in, expt) - SlowSolver.solve() - cheby.apply(USlow_out, DU, -expt) - DU *= wt - ensemble.allreduce(DU, V) - cheby2.apply(V, DU, dt) - + cheby2.apply(V1, DU, dt) cheby2.apply(U, V, dt) U.assign(V + 1/6*DU + 1/3*U1 + 1/3*U2 + 1/6*U3) From 10f1686c193fa64fc7b48c080636090a7eefa39a Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Thu, 8 Oct 2020 16:51:38 +0100 Subject: [PATCH 07/46] added a new file which compares the averaged solutions and the serial solution --- averaged_sw_diff.py | 367 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 averaged_sw_diff.py diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py new file mode 100644 index 0000000..c15b317 --- /dev/null +++ b/averaged_sw_diff.py @@ -0,0 +1,367 @@ +from cheby_exp import * +from firedrake import * +from firedrake.petsc import PETSc +from math import pi +from math import ceil +from timestepping_methods import * +import numpy as np +import argparse + +#get command arguments +parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') +parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') +parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') +parser.add_argument('--dumpt', type=float, default=6, help='Dump time in hours. Default 6.') +parser.add_argument('--dt', type=float, default=2, help='Timestep in hours. Default 2.') +parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') +parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') +parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') +parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') +parser.add_argument('--filter2', type=bool, default=True, help='Use a filter for cheby2') +parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') +parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') +parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') +parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') +parser.add_argument('--filename', type=str, default='explicit') +args = parser.parse_known_args() +args = args[0] +filter = args.filter +filter2 = args.filter2 +filter_val = args.filter_val +timestepping = args.timestepping +asselin = args.asselin +ref_level = args.ref_level + +#ensemble communicator +ensemble = Ensemble(COMM_WORLD, 1) + +#parameters +R0 = 6371220. +R = Constant(R0) +H = Constant(5960.) +Omega = Constant(7.292e-5) # rotation rate +g = Constant(9.8) # Gravitational constant +mesh = IcosahedralSphereMesh(radius=R0, + refinement_level=ref_level, degree=3, + comm = ensemble.comm) +x = SpatialCoordinate(mesh) +global_normal = as_vector([x[0], x[1], x[2]]) +mesh.init_cell_orientations(global_normal) +outward_normals = CellNormal(mesh) +perp = lambda u: cross(outward_normals, u) +V1 = FunctionSpace(mesh, "BDM", 2) +V2 = FunctionSpace(mesh, "DG", 1) +W = MixedFunctionSpace((V1, V2)) +f_expr = 2 * Omega * x[2] / R +Vf = FunctionSpace(mesh, "CG", 3) +f = Function(Vf).interpolate(f_expr) # Coriolis frequency +u_0 = 20.0 # maximum amplitude of the zonal wind [m/s] +u_max = Constant(u_0) +u_expr = as_vector([-u_max*x[1]/R, u_max*x[0]/R, 0.0]) +h_expr = H-((R*Omega*u_max+u_max*u_max/2.0)*(x[2]*x[2]/(R*R)))/g +eta_expr = h_expr - H +un = Function(V1, name="Velocity").project(u_expr) +etan = Function(V2, name="Elevation").project(eta_expr) +hn = Function(V2).interpolate(h_expr) +urn = Function(V1).assign(un) + +#topography (D = H + eta - b) +rl = pi/9.0 +lambda_x = atan_2(x[1]/R0, x[0]/R0) +lambda_c = -pi/2.0 +phi_x = asin(x[2]/R0) +phi_c = pi/6.0 +minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +bexpr = 2000.0*(1 - sqrt(minarg)/rl) +b = Function(V2, name="Topography") +b.interpolate(bexpr) +hn -= b + +#checking cheby parameters based on ref_level +eigs = [0.003465, 0.007274, 0.014955] #maximum frequency +min_time_period = 2*pi/eigs[ref_level-3] +hours = args.dt +dt = 60*60*hours +rho = args.rho #averaging window is rho*dt +L = eigs[ref_level-3]*dt*rho +ppp = args.ppp #points per (minimum) time period + #rho*dt/min_time_period = number of min_time_periods that fit in rho*dt + # we want at least ppp times this number of sample points +Mbar = ceil(ppp*rho*dt*eigs[ref_level-3]/2/pi) +if args.get_Mbar: + print("Mbar="+str(Mbar)) + import sys; sys.exit() + +svals = np.arange(0.5, Mbar)/Mbar #tvals goes from -rho*dt/2 to rho*dt/2 +weights = np.exp(-1.0/svals/(1.0-svals)) +weights = weights/np.sum(weights) +print(weights) +svals -= 0.5 + +#parameters for timestepping +t = 0. +tmax = 60.*60.*args.tmax +dumpt = args.dumpt*60.*60. +tdump = 0. + + + +#print out settings +print = PETSc.Sys.Print +assert Mbar==COMM_WORLD.size, str(Mbar)+' '+str(COMM_WORLD.size) +print('averaging window', rho*dt, 'sample width', rho*dt/Mbar) +print('Mbar', Mbar, 'samples per min time period', min_time_period/(rho*dt/Mbar)) +print(args) + +############################################################################## +# Set up the exponential operator +############################################################################## +operator_in = Function(W) +u_in, eta_in = split(operator_in) +u, eta = TrialFunctions(W) +v, phi = TestFunctions(W) + +F = ( + - inner(f*perp(u_in),v)*dx + +g*eta_in*div(v)*dx + - H*div(u_in)*phi*dx +) + +a = inner(v,u)*dx + phi*eta*dx + +operator_out = Function(W) + +params = { + 'ksp_type': 'preonly', + 'pc_type': 'fieldsplit', + 'fieldsplit_0_ksp_type':'cg', + 'fieldsplit_0_pc_type':'bjacobi', + 'fieldsplit_0_sub_pc_type':'ilu', + 'fieldsplit_1_ksp_type':'preonly', + 'fieldsplit_1_pc_type':'bjacobi', + 'fieldsplit_1_sub_pc_type':'ilu' +} + +Prob = LinearVariationalProblem(a, F, operator_out) +OperatorSolver = LinearVariationalSolver(Prob, solver_parameters=params) + +ncheb = 10000 + +cheby = cheby_exp(OperatorSolver, operator_in, operator_out, + ncheb, tol=1.0e-8, L=L, filter=filter, filter_val=filter_val) + +cheby2 = cheby_exp(OperatorSolver, operator_in, operator_out, + ncheb, tol=1.0e-8, L=L, filter=filter2, filter_val=filter_val) + +############################################################################## +# Set up solvers for the slow part +############################################################################## +USlow_in = Function(W) #value at previous timestep +USlow_out = Function(W) #value at RK stage +u0, eta0 = split(USlow_in) + +#RHS for Forward Euler step +gradperp = lambda f: perp(grad(f)) +n = FacetNormal(mesh) +Upwind = 0.5 * (sign(dot(u0, n)) + 1) +both = lambda u: 2*avg(u) +K = 0.5*inner(u0, u0) +uup = 0.5 * (dot(u0, n) + abs(dot(u0, n))) + +dT = Constant(dt) + +vector_invariant = True +if vector_invariant: + L = ( + dT*inner(perp(grad(inner(v, perp(u0)))), u0)*dx + - dT*inner(both(perp(n)*inner(v, perp(u0))), + both(Upwind*u0))*dS + + dT*div(v)*K*dx + + dT*inner(grad(phi), u0*(eta0-b))*dx + - dT*jump(phi)*(uup('+')*(eta0('+')-b('+')) + - uup('-')*(eta0('-') - b('-')))*dS + ) +else: + L = ( + dT*inner(div(outer(u0, v)), u0)*dx + - dT*inner(both(inner(n, u0)*v), both(Upwind*u0))*dS + + dT*inner(grad(phi), u0*(eta0-b))*dx + - dT*jump(phi)*(uup('+')*(eta0('+')-b('+')) + - uup('-')*(eta0('-') - b('-')))*dS + ) + +SlowProb = LinearVariationalProblem(a, L, USlow_out) +SlowSolver = LinearVariationalSolver(SlowProb, + solver_parameters = params) + +############################################################################## +# Set up depth advection solver (DG upwinded scheme) +############################################################################## +up = Function(V1) +hp = Function(V2) +hps = Function(V2) +h = TrialFunction(V2) +phi = TestFunction(V2) +hh = 0.5 * (hn + h) +uh = 0.5 * (urn + up) +n = FacetNormal(mesh) +uup = 0.5 * (dot(uh, n) + abs(dot(uh, n))) +Heqn = ((h - hn)*phi*dx - dt*inner(grad(phi), uh*hh)*dx + + dt*jump(phi)*(uup('+')*hh('+')-uup('-')*hh('-'))*dS) +Hproblem = LinearVariationalProblem(lhs(Heqn), rhs(Heqn), hps) +lu_params = {'ksp_type': 'preonly', + 'pc_type': 'lu', + 'pc_factor_mat_solver_type': 'mumps'} +Hsolver = LinearVariationalSolver(Hproblem, + solver_parameters=lu_params, + options_prefix="H-advection") + +############################################################################## +# Velocity advection (Natale et. al (2016) extended to SWE) +############################################################################## +ups = Function(V1) +u = TrialFunction(V1) +v = TestFunction(V1) +hh = 0.5 * (hn + hp) +ubar = 0.5 * (urn + up) +uup = 0.5 * (dot(ubar, n) + abs(dot(ubar, n))) +uh = 0.5 * (urn + u) +Upwind = 0.5 * (sign(dot(ubar, n)) + 1) +K = 0.5 * (inner(0.5 * (urn + up), 0.5 * (urn + up))) +both = lambda u: 2*avg(u) +outward_normals = CellNormal(mesh) +perp = lambda arg: cross(outward_normals, arg) +Ueqn = (inner(u - urn, v)*dx + dt*inner(perp(uh)*f, v)*dx + - dt*inner(perp(grad(inner(v, perp(ubar)))), uh)*dx + + dt*inner(both(perp(n)*inner(v, perp(ubar))), + both(Upwind*uh))*dS + - dt*div(v)*(g*(hh + b) + K)*dx) +Uproblem = LinearVariationalProblem(lhs(Ueqn), rhs(Ueqn), ups) +Usolver = LinearVariationalSolver(Uproblem, + solver_parameters=lu_params, + options_prefix="U-advection") + +############################################################################## +# Linear solver for incremental updates +############################################################################## +HU = Function(W) +deltaU, deltaH = HU.split() +w, phi = TestFunctions(W) +du, dh = TrialFunctions(W) +alpha = 0.5 +HUlhs = (inner(w, du + alpha*dt*f*perp(du))*dx + - alpha*dt*div(w)*g*dh*dx + + phi*(dh + alpha*dt*H*div(du))*dx) +HUrhs = -inner(w, up - ups)*dx - phi*(hp - hps)*dx +HUproblem = LinearVariationalProblem(HUlhs, HUrhs, HU) +params = {'ksp_type': 'preonly', + 'mat_type': 'aij', + 'pc_type': 'lu', + 'pc_factor_mat_solver_type': 'mumps'} +HUsolver = LinearVariationalSolver(HUproblem, + solver_parameters=params, + options_prefix="impl-solve") + +############################################################################## +# Time loop +############################################################################## +U = Function(W) +DU = Function(W) +U1 = Function(W) +U2 = Function(W) +U3 = Function(W) +X1 = Function(W) +X2 = Function(W) +X3 = Function(W) +V = Function(W) + +U_u, U_eta = U.split() +U_u.assign(un) +U_eta.assign(etan) + +k_max = 4 # Maximum number of Picard iterations +u_out = Function(V1, name="Velocity").assign(urn) +eta_out = Function(V2, name="Elevation").assign(hn + b - H) +u_diff = Function(V1, name="Velocity Difference").assign(un - u_out) +eta_diff = Function(V2, name="Elevation Difference").assign(etan - eta_out) + +#set weights +rank = ensemble.ensemble_comm.rank +expt = rho*dt*svals[rank] +wt = weights[rank] +print(wt,"weight",expt) + +#write out initial fields +name = args.filename +if rank==0: + file_sw = File(name+'_avg.pvd', comm=ensemble.comm) + file_r = File(name+'_serial.pvd', comm=ensemble.comm) + file_d = File(name+'_diff.pvd', comm=ensemble.comm) + file_sw.write(un, etan, b) + file_r.write(u_out, eta_out, b) + file_d.write(u_diff, eta_diff, b) + +#start time loop +print ('tmax', tmax, 'dt', dt) +while t < tmax + 0.5*dt: + print(t) + t += dt + tdump += dt + + if t < dt*1.5 and timestepping == 'leapfrog': + U_old = Function(W) + U_new = Function(W) + U_old.assign(U) + rk2(U, USlow_in, USlow_out, DU, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + else: + if timestepping == 'leapfrog': + leapfrog(U, USlow_in, USlow_out, U_old, U_new, DU, U1, U2, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt, asselin) + elif timestepping == 'ssprk3': + ssprk3(U, USlow_in, USlow_out, DU, U1, U2, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + elif timestepping == 'rk2': + rk2(U, USlow_in, USlow_out, DU, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + elif timestepping == 'rk4': + rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, X1, X2, X3, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + elif timestepping == 'heuns': + heuns(U, USlow_in, USlow_out, DU, U1, U2, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + + if rank == 0: + #run the serial solver + up.assign(urn) + hp.assign(hn) + + #start picard cycle + for i in range(k_max): + #advect to get candidates + Hsolver.solve() + Usolver.solve() + + #linear solve for updates + HUsolver.solve() + + #increment updates + up += deltaU + hp += deltaH + + #update fields for next time step + urn.assign(up) + hn.assign(hp) + + #dump + if tdump > dumpt - dt*0.5: + un.assign(U_u) + etan.assign(U_eta) + file_sw.write(un, etan, b) + u_out.assign(urn) + eta_out.assign(hn + b - H) + file_r.write(u_out, eta_out, b) + u_diff.assign(un - u_out) + eta_diff.assign(etan - eta_out) + file_d.write(u_diff, eta_diff, b) + tdump -= dumpt From 5a5b41872ce61615314784a7b345e901daed257f Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Thu, 26 Nov 2020 14:12:19 +0000 Subject: [PATCH 08/46] started adding dumbcheckpoint --- averaged_sw_explicit.py | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index 3accce4..96396fe 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -1,4 +1,3 @@ - #get command arguments import argparse parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') @@ -10,7 +9,7 @@ parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') -parser.add_argument('--filter2', type=bool, default=True, help='Use a filter for cheby2') +parser.add_argument('--filter2', type=bool, default=False, help='Use a filter for cheby2') parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') @@ -214,9 +213,9 @@ U1 = Function(W) U2 = Function(W) U3 = Function(W) -V1 = Function(W) -V2 = Function(W) -V3 = Function(W) +W1 = Function(W) +W2 = Function(W) +W3 = Function(W) V = Function(W) from timestepping_methods import * @@ -255,7 +254,7 @@ rk2(U, USlow_in, USlow_out, DU, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) elif timestepping == 'rk4': - rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V1, V2, V3, V, W, + rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, W1, W2, W3, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) elif timestepping == 'heuns': heuns(U, USlow_in, USlow_out, DU, U1, U2, W, @@ -266,4 +265,31 @@ un.assign(U_u) etan.assign(U_eta) file_sw.write(un, etan, b) + print("dumped at t =", t) tdump -= dumpt + +valf = assemble(etan*dx) + +print("create checkpointing file at rank =", rank) +chk = DumbCheckpoint("dump_explicit", mode=FILE_CREATE) +chk.store(un) +chk.store(etan) +chk.store(b) +chk.close() + +und = Function(V1) +etand = Function(V2) +bd = Function(V2) + +chk = DumbCheckpoint("dump_explicit", mode=FILE_READ) +chk.load(und, name="Velocity") +chk.load(etand, name="Elevation") +chk.load(bd, name="Topography") + +valg = assemble(etand*dx) + +print("valf = ", valf) +print("valg = ", valg) +assert(valf == valg) + +chk.close() From 0840ee89a0a5f383755bab0c25badc1e8e36d029 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 9 Dec 2020 11:02:06 +0000 Subject: [PATCH 09/46] tidy up --- averaged_sw_explicit.py | 176 +++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 93 deletions(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index 96396fe..25753be 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -1,5 +1,13 @@ -#get command arguments +from cheby_exp import * +from firedrake import * +from firedrake.petsc import PETSc +from math import pi +from math import ceil +from timestepping_methods import * +import numpy as np import argparse + +#get command arguments parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') @@ -17,82 +25,98 @@ parser.add_argument('--filename', type=str, default='explicit') args = parser.parse_known_args() args = args[0] - filter = args.filter filter2 = args.filter2 filter_val = args.filter_val timestepping = args.timestepping asselin = args.asselin +ref_level = args.ref_level + +#ensemble communicator +ensemble = Ensemble(COMM_WORLD, 1) + +#parameters +R0 = 6371220. +H = Constant(5960.) +Omega = Constant(7.292e-5) # rotation rate +g = Constant(9.8) # Gravitational constant +mesh = IcosahedralSphereMesh(radius=R0, + refinement_level=ref_level, degree=3, + comm = ensemble.comm) +x = SpatialCoordinate(mesh) +global_normal = as_vector([x[0], x[1], x[2]]) +mesh.init_cell_orientations(global_normal) +outward_normals = CellNormal(mesh) +perp = lambda u: cross(outward_normals, u) +V1 = FunctionSpace(mesh, "BDM", 2) +V2 = FunctionSpace(mesh, "DG", 1) +W = MixedFunctionSpace((V1, V2)) +f = 2*Omega*x[2]/Constant(R0) # Coriolis parameter +u_0 = 20.0 # maximum amplitude of the zonal wind [m/s] +u_max = Constant(u_0) +u_expr = as_vector([-u_max*x[1]/R0, u_max*x[0]/R0, 0.0]) +eta_expr = - ((R0 * Omega * u_max + u_max*u_max/2.0)*(x[2]*x[2]/(R0*R0)))/g +un = Function(V1, name="Velocity").project(u_expr) +etan = Function(V2, name="Elevation").project(eta_expr) + +#topography (D = H + eta - b) +rl = pi/9.0 +lambda_x = atan_2(x[1]/R0, x[0]/R0) +lambda_c = -pi/2.0 +phi_x = asin(x[2]/R0) +phi_c = pi/6.0 +minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +bexpr = 2000.0*(1 - sqrt(minarg)/rl) +b = Function(V2, name="Topography") +b.interpolate(bexpr) #checking cheby parameters based on ref_level -ref_level = args.ref_level eigs = [0.003465, 0.007274, 0.014955] #maximum frequency -from math import pi min_time_period = 2*pi/eigs[ref_level-3] hours = args.dt dt = 60*60*hours rho = args.rho #averaging window is rho*dt - L = eigs[ref_level-3]*dt*rho ppp = args.ppp #points per (minimum) time period - -# rho*dt/min_time_period = number of min_time_periods that fit in rho*dt -# we want at least ppp times this number of sample points -from math import ceil + #rho*dt/min_time_period = number of min_time_periods that fit in rho*dt + #we want at least ppp times this number of sample points Mbar = ceil(ppp*rho*dt*eigs[ref_level-3]/2/pi) print(args) - if args.get_Mbar: print("Mbar="+str(Mbar)) import sys; sys.exit() -from cheby_exp import * -from firedrake import * -import numpy as np +#set svals +svals = np.arange(0.5, Mbar)/Mbar #tvals goes from -rho*dt/2 to rho*dt/2 +weights = np.exp(-1.0/svals/(1.0-svals)) +weights = weights/np.sum(weights) +print(weights) +svals -= 0.5 -from firedrake.petsc import PETSc +#set weights +rank = ensemble.ensemble_comm.rank +expt = rho*dt*svals[rank] +wt = weights[rank] +print(wt,"weight",expt) + +#parameters for timestepping +t = 0. +tmax = 60.*60.*args.tmax +dumpt = args.dumpt*60.*60. +tdump = 0. + +#dump settings print = PETSc.Sys.Print assert Mbar==COMM_WORLD.size, str(Mbar)+' '+str(COMM_WORLD.size) print('averaging window', rho*dt, 'sample width', rho*dt/Mbar) print('Mbar', Mbar, 'samples per min time period', min_time_period/(rho*dt/Mbar)) -#ensemble communicator -ensemble = Ensemble(COMM_WORLD, 1) - -#some domain, parameters and FS setup -R0 = 6371220. -H = Constant(5960.) - -mesh = IcosahedralSphereMesh(radius=R0, - refinement_level=ref_level, degree=3, - comm = ensemble.comm) -cx = SpatialCoordinate(mesh) -mesh.init_cell_orientations(cx) - -cx, cy, cz = SpatialCoordinate(mesh) - -outward_normals = CellNormal(mesh) -perp = lambda u: cross(outward_normals, u) - -V1 = FunctionSpace(mesh, "BDM", 2) -V2 = FunctionSpace(mesh, "DG", 1) -W = MixedFunctionSpace((V1, V2)) - -u, eta = TrialFunctions(W) -v, phi = TestFunctions(W) - -Omega = Constant(7.292e-5) # rotation rate -f = 2*Omega*cz/Constant(R0) # Coriolis parameter -g = Constant(9.8) # Gravitational constant -b = Function(V2, name="Topography") -c = sqrt(g*H) -#Set up the exponential operator +############################################################################## +# Set up the exponential operator +############################################################################## operator_in = Function(W) u_in, eta_in = split(operator_in) - -#D = eta + b - u, eta = TrialFunctions(W) v, phi = TestFunctions(W) @@ -128,10 +152,12 @@ cheby2 = cheby_exp(OperatorSolver, operator_in, operator_out, ncheb, tol=1.0e-8, L=L, filter=filter2, filter_val=filter_val) -#solvers for slow part + +############################################################################## +# Set up solvers for the slow part +############################################################################## USlow_in = Function(W) #value at previous timestep USlow_out = Function(W) #value at RK stage - u0, eta0 = split(USlow_in) #RHS for Forward Euler step @@ -164,50 +190,14 @@ - uup('-')*(eta0('-') - b('-')))*dS ) -#with topography, D = H + eta - b - SlowProb = LinearVariationalProblem(a, L, USlow_out) SlowSolver = LinearVariationalSolver(SlowProb, solver_parameters = params) -t = 0. -tmax = 60.*60.*args.tmax -dumpt = args.dumpt*60.*60. -tdump = 0. - -svals = np.arange(0.5, Mbar)/Mbar #tvals goes from -rho*dt/2 to rho*dt/2 -weights = np.exp(-1.0/svals/(1.0-svals)) -weights = weights/np.sum(weights) -print(weights) -svals -= 0.5 - -rank = ensemble.ensemble_comm.rank -expt = rho*dt*svals[rank] -wt = weights[rank] -print(wt,"weight",expt) - -x = SpatialCoordinate(mesh) - -u_0 = 20.0 # maximum amplitude of the zonal wind [m/s] -u_max = Constant(u_0) -u_expr = as_vector([-u_max*x[1]/R0, u_max*x[0]/R0, 0.0]) -eta_expr = - ((R0 * Omega * u_max + u_max*u_max/2.0)*(x[2]*x[2]/(R0*R0)))/g -un = Function(V1, name="Velocity").project(u_expr) -etan = Function(V2, name="Elevation").project(eta_expr) - -# Topography -rl = pi/9.0 -lambda_x = atan_2(x[1]/R0, x[0]/R0) -lambda_c = -pi/2.0 -phi_x = asin(x[2]/R0) -phi_c = pi/6.0 -minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) -bexpr = 2000.0*(1 - sqrt(minarg)/rl) -b.interpolate(bexpr) - -un1 = Function(V1) -etan1 = Function(V1) +############################################################################## +# Time loop +############################################################################## U = Function(W) DU = Function(W) U1 = Function(W) @@ -218,19 +208,17 @@ W3 = Function(W) V = Function(W) -from timestepping_methods import * - U_u, U_eta = U.split() U_u.assign(un) U_eta.assign(etan) +#write out initial fields name = args.filename if rank==0: file_sw = File(name+'.pvd', comm=ensemble.comm) file_sw.write(un, etan, b) -nonlinear = args.nonlinear - +#start time loop print ('tmax', tmax, 'dt', dt) while t < tmax + 0.5*dt: print(t) @@ -260,6 +248,7 @@ heuns(U, USlow_in, USlow_out, DU, U1, U2, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + #dump if rank == 0: if tdump > dumpt - dt*0.5: un.assign(U_u) @@ -268,6 +257,7 @@ print("dumped at t =", t) tdump -= dumpt +#check if dumbcheckpoint is working valf = assemble(etan*dx) print("create checkpointing file at rank =", rank) From 0d8507118bbf30b75115c8006928c4a240328ae0 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 9 Dec 2020 11:10:04 +0000 Subject: [PATCH 10/46] some comments --- averaged_sw_explicit.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index 25753be..d11f623 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -70,7 +70,7 @@ b = Function(V2, name="Topography") b.interpolate(bexpr) -#checking cheby parameters based on ref_level +#set Mbar eigs = [0.003465, 0.007274, 0.014955] #maximum frequency min_time_period = 2*pi/eigs[ref_level-3] hours = args.dt @@ -115,6 +115,8 @@ ############################################################################## # Set up the exponential operator ############################################################################## + +#apply the exponential of an operator using chebyshev approximation operator_in = Function(W) u_in, eta_in = split(operator_in) u, eta = TrialFunctions(W) From 11fe79aefba23ee01f16feb69de87027d05ef88b Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 16 Dec 2020 12:46:38 +0000 Subject: [PATCH 11/46] added subcycling for the serial solver and norm calculations --- averaged_sw_diff.py | 83 ++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index c15b317..355116a 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -58,10 +58,11 @@ u_0 = 20.0 # maximum amplitude of the zonal wind [m/s] u_max = Constant(u_0) u_expr = as_vector([-u_max*x[1]/R, u_max*x[0]/R, 0.0]) -h_expr = H-((R*Omega*u_max+u_max*u_max/2.0)*(x[2]*x[2]/(R*R)))/g -eta_expr = h_expr - H +eta_expr = -((R*Omega*u_max+u_max*u_max/2.0)*(x[2]*x[2]/(R*R)))/g +h_expr = eta_expr + H + un = Function(V1, name="Velocity").project(u_expr) -etan = Function(V2, name="Elevation").project(eta_expr) +etan = Function(V2, name="Elevation").interpolate(eta_expr) hn = Function(V2).interpolate(h_expr) urn = Function(V1).assign(un) @@ -104,8 +105,6 @@ dumpt = args.dumpt*60.*60. tdump = 0. - - #print out settings print = PETSc.Sys.Print assert Mbar==COMM_WORLD.size, str(Mbar)+' '+str(COMM_WORLD.size) @@ -197,6 +196,7 @@ ############################################################################## # Set up depth advection solver (DG upwinded scheme) ############################################################################## +dts = 900 up = Function(V1) hp = Function(V2) hps = Function(V2) @@ -206,8 +206,8 @@ uh = 0.5 * (urn + up) n = FacetNormal(mesh) uup = 0.5 * (dot(uh, n) + abs(dot(uh, n))) -Heqn = ((h - hn)*phi*dx - dt*inner(grad(phi), uh*hh)*dx - + dt*jump(phi)*(uup('+')*hh('+')-uup('-')*hh('-'))*dS) +Heqn = ((h - hn)*phi*dx - dts*inner(grad(phi), uh*hh)*dx + + dts*jump(phi)*(uup('+')*hh('+')-uup('-')*hh('-'))*dS) Hproblem = LinearVariationalProblem(lhs(Heqn), rhs(Heqn), hps) lu_params = {'ksp_type': 'preonly', 'pc_type': 'lu', @@ -231,11 +231,11 @@ both = lambda u: 2*avg(u) outward_normals = CellNormal(mesh) perp = lambda arg: cross(outward_normals, arg) -Ueqn = (inner(u - urn, v)*dx + dt*inner(perp(uh)*f, v)*dx - - dt*inner(perp(grad(inner(v, perp(ubar)))), uh)*dx - + dt*inner(both(perp(n)*inner(v, perp(ubar))), +Ueqn = (inner(u - urn, v)*dx + dts*inner(perp(uh)*f, v)*dx + - dts*inner(perp(grad(inner(v, perp(ubar)))), uh)*dx + + dts*inner(both(perp(n)*inner(v, perp(ubar))), both(Upwind*uh))*dS - - dt*div(v)*(g*(hh + b) + K)*dx) + - dts*div(v)*(g*(hh + b) + K)*dx) Uproblem = LinearVariationalProblem(lhs(Ueqn), rhs(Ueqn), ups) Usolver = LinearVariationalSolver(Uproblem, solver_parameters=lu_params, @@ -249,9 +249,9 @@ w, phi = TestFunctions(W) du, dh = TrialFunctions(W) alpha = 0.5 -HUlhs = (inner(w, du + alpha*dt*f*perp(du))*dx - - alpha*dt*div(w)*g*dh*dx - + phi*(dh + alpha*dt*H*div(du))*dx) +HUlhs = (inner(w, du + alpha*dts*f*perp(du))*dx + - alpha*dts*div(w)*g*dh*dx + + phi*(dh + alpha*dts*H*div(du))*dx) HUrhs = -inner(w, up - ups)*dx - phi*(hp - hps)*dx HUproblem = LinearVariationalProblem(HUlhs, HUrhs, HU) params = {'ksp_type': 'preonly', @@ -280,6 +280,8 @@ U_eta.assign(etan) k_max = 4 # Maximum number of Picard iterations +iter_max = int(dt/dts) +print("dt, dts, iter_max =", dt, dts, iter_max) u_out = Function(V1, name="Velocity").assign(urn) eta_out = Function(V2, name="Elevation").assign(hn + b - H) u_diff = Function(V1, name="Velocity Difference").assign(un - u_out) @@ -300,9 +302,14 @@ file_sw.write(un, etan, b) file_r.write(u_out, eta_out, b) file_d.write(u_diff, eta_diff, b) + area = assemble(1*dx(domain=f.ufl_domain())) + print('area', area) + u_norm = errornorm(un, u_out)/area + eta_norm = errornorm(etan, eta_out)/area + print('u_norm', u_norm, 'eta_norm', eta_norm) #start time loop -print ('tmax', tmax, 'dt', dt) +print('tmax', tmax, 'dt', dt) while t < tmax + 0.5*dt: print(t) t += dt @@ -332,36 +339,48 @@ expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) if rank == 0: - #run the serial solver - up.assign(urn) - hp.assign(hn) + #run the serial solver + + for iter in range(iter_max): + print(iter) + up.assign(urn) + hp.assign(hn) - #start picard cycle - for i in range(k_max): - #advect to get candidates - Hsolver.solve() - Usolver.solve() + #start picard cycle + for i in range(k_max): + #advect to get candidates + Hsolver.solve() + Usolver.solve() - #linear solve for updates - HUsolver.solve() + #linear solve for updates + HUsolver.solve() - #increment updates - up += deltaU - hp += deltaH + #increment updates + up += deltaU + hp += deltaH - #update fields for next time step - urn.assign(up) - hn.assign(hp) + #update fields for next time step + urn.assign(up) + hn.assign(hp) - #dump + #dumping if tdump > dumpt - dt*0.5: + #dump averaged results un.assign(U_u) etan.assign(U_eta) file_sw.write(un, etan, b) + #dump non averaged results u_out.assign(urn) eta_out.assign(hn + b - H) file_r.write(u_out, eta_out, b) + #dump differences u_diff.assign(un - u_out) eta_diff.assign(etan - eta_out) file_d.write(u_diff, eta_diff, b) + #calculate l2 norm + u_norm = errornorm(un, u_out)/area + eta_norm = errornorm(etan, eta_out)/area + print('u_norm', u_norm, 'eta_norm', eta_norm) + #update dumpt + print("dumped at t =", t) tdump -= dumpt From 77cd34f54e710138e4a733ff590c659dd38e9d55 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Thu, 21 Jan 2021 14:25:03 +0000 Subject: [PATCH 12/46] started williamson 6 test case --- averaged_sw_williamson6.py | 416 +++++++++++++++++++++++++++++++++++++ 1 file changed, 416 insertions(+) create mode 100644 averaged_sw_williamson6.py diff --git a/averaged_sw_williamson6.py b/averaged_sw_williamson6.py new file mode 100644 index 0000000..d239e73 --- /dev/null +++ b/averaged_sw_williamson6.py @@ -0,0 +1,416 @@ +from cheby_exp import * +from firedrake import * +from firedrake.petsc import PETSc +from math import pi +from math import ceil +from timestepping_methods import * +import numpy as np +import argparse + +#get command arguments +parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') +parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') +parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') +parser.add_argument('--dumpt', type=float, default=6, help='Dump time in hours. Default 6.') +parser.add_argument('--dt', type=float, default=2, help='Timestep in hours. Default 2.') +parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') +parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') +parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') +parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') +parser.add_argument('--filter2', type=bool, default=True, help='Use a filter for cheby2') +parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') +parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') +parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') +parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') +parser.add_argument('--filename', type=str, default='sw_rossby') +args = parser.parse_known_args() +args = args[0] +filter = args.filter +filter2 = args.filter2 +filter_val = args.filter_val +timestepping = args.timestepping +asselin = args.asselin +ref_level = args.ref_level +print(args) + +#ensemble communicator +ensemble = Ensemble(COMM_WORLD, 1) + +#parameters +R0 = 6371220. +R = Constant(R0) +H = Constant(8000.) +Omega = Constant(7.292e-5) # rotation rate +g = Constant(9.8) # Gravitational constant +mesh = IcosahedralSphereMesh(radius=R0, + refinement_level=ref_level, degree=3, + comm = ensemble.comm) +x = SpatialCoordinate(mesh) +global_normal = as_vector([x[0], x[1], x[2]]) +mesh.init_cell_orientations(global_normal) +outward_normals = CellNormal(mesh) +perp = lambda u: cross(outward_normals, u) +V1 = FunctionSpace(mesh, "BDM", 2) +V2 = FunctionSpace(mesh, "DG", 1) +W = MixedFunctionSpace((V1, V2)) + +#coriolis +f_expr = 2 * Omega * x[2] / R +Vf = FunctionSpace(mesh, "CG", 3) +f = Function(Vf).interpolate(f_expr) # Coriolis frequency + +#u, h and eta +omega = 7.848e-6 # note lower-case, not the same as Omega +K = 7.848e-6 + +unsafe = x[2]/sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]) +safe = Min(Max(unsafe, -1.0), 1.0) # avoid silly roundoff errors +theta = asin(safe) # latitude +lamda = atan_2(x[1], x[0]) # longitude + +u_zonal = R*omega*cos(theta) + R*K*(cos(theta)**3)*(4*sin(theta)**2 - cos(theta)**2)*cos(4*lamda) +u_merid = -R*K*4*(cos(theta)**3)*sin(theta)*sin(4*lamda) + +cartesian_u_expr = -u_zonal*sin(lamda) - u_merid*sin(theta)*cos(lamda) +cartesian_v_expr = u_zonal*cos(lamda) - u_merid*sin(theta)*sin(lamda) +cartesian_w_expr = u_merid*cos(theta) + +u_expr = as_vector((cartesian_u_expr, cartesian_v_expr, cartesian_w_expr)) + +def Atheta(theta): + return 0.5*omega*(2*Omega + omega)*cos(theta)**2 + 0.25*(K**2)*(cos(theta)**8)*(5*cos(theta)**2 + 26 - 32/(cos(theta)**2)) + + +def Btheta(theta): + return (2*(Omega + omega)*K/30)*(cos(theta)**4)*(26 - 25*cos(theta)**2) + + +def Ctheta(theta): + return 0.25*(K**2)*(cos(theta)**8)*(5*cos(theta)**2 - 6) + +eta_expr = (R**2)*(Atheta(theta) + Btheta(theta)*cos(4*lamda) + Ctheta(theta)*cos(8*lamda))/g +h_expr = eta_expr + H + +un = Function(V1, name="Velocity").project(u_expr, form_compiler_parameters={'quadrature_degree': 8}) +etan = Function(V2, name="Elevation").interpolate(eta_expr) +hn = Function(V2).interpolate(h_expr) +urn = Function(V1).assign(un) + +#topography (D = H + eta - b) +rl = pi/9.0 +lambda_x = atan_2(x[1]/R0, x[0]/R0) +lambda_c = -pi/2.0 +phi_x = asin(x[2]/R0) +phi_c = pi/6.0 +minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +bexpr = 2000.0*(1 - sqrt(minarg)/rl) +b = Function(V2, name="Topography") +#b.interpolate(bexpr) +hn -= b + +#checking cheby parameters based on ref_level +eigs = [0.003465, 0.007274, 0.014955] #maximum frequency +min_time_period = 2*pi/eigs[ref_level-3] +hours = args.dt +dt = 60*60*hours +rho = args.rho #averaging window is rho*dt +L = eigs[ref_level-3]*dt*rho +ppp = args.ppp #points per (minimum) time period + #rho*dt/min_time_period = number of min_time_periods that fit in rho*dt + # we want at least ppp times this number of sample points +Mbar = ceil(ppp*rho*dt*eigs[ref_level-3]/2/pi) +if args.get_Mbar: + print("Mbar="+str(Mbar)) + import sys; sys.exit() + +svals = np.arange(0.5, Mbar)/Mbar #tvals goes from -rho*dt/2 to rho*dt/2 +weights = np.exp(-1.0/svals/(1.0-svals)) +weights = weights/np.sum(weights) +print(weights) +svals -= 0.5 + +#parameters for timestepping +t = 0. +tmax = 60.*60.*args.tmax +dumpt = args.dumpt*60.*60. +tdump = 0. + +#print out settings +print = PETSc.Sys.Print +assert Mbar==COMM_WORLD.size, str(Mbar)+' '+str(COMM_WORLD.size) +print('averaging window', rho*dt, 'sample width', rho*dt/Mbar) +print('Mbar', Mbar, 'samples per min time period', min_time_period/(rho*dt/Mbar)) +print(args) + +############################################################################## +# Set up the exponential operator +############################################################################## +operator_in = Function(W) +u_in, eta_in = split(operator_in) +u, eta = TrialFunctions(W) +v, phi = TestFunctions(W) + +F = ( + - inner(f*perp(u_in),v)*dx + +g*eta_in*div(v)*dx + - H*div(u_in)*phi*dx +) + +a = inner(v,u)*dx + phi*eta*dx + +operator_out = Function(W) + +params = { + 'ksp_type': 'preonly', + 'pc_type': 'fieldsplit', + 'fieldsplit_0_ksp_type':'cg', + 'fieldsplit_0_pc_type':'bjacobi', + 'fieldsplit_0_sub_pc_type':'ilu', + 'fieldsplit_1_ksp_type':'preonly', + 'fieldsplit_1_pc_type':'bjacobi', + 'fieldsplit_1_sub_pc_type':'ilu' +} + +Prob = LinearVariationalProblem(a, F, operator_out) +OperatorSolver = LinearVariationalSolver(Prob, solver_parameters=params) + +ncheb = 10000 + +cheby = cheby_exp(OperatorSolver, operator_in, operator_out, + ncheb, tol=1.0e-8, L=L, filter=filter, filter_val=filter_val) + +cheby2 = cheby_exp(OperatorSolver, operator_in, operator_out, + ncheb, tol=1.0e-8, L=L, filter=filter2, filter_val=filter_val) + +############################################################################## +# Set up solvers for the slow part +############################################################################## +USlow_in = Function(W) #value at previous timestep +USlow_out = Function(W) #value at RK stage +u0, eta0 = split(USlow_in) + +#RHS for Forward Euler step +gradperp = lambda f: perp(grad(f)) +n = FacetNormal(mesh) +Upwind = 0.5 * (sign(dot(u0, n)) + 1) +both = lambda u: 2*avg(u) +K = 0.5*inner(u0, u0) +uup = 0.5 * (dot(u0, n) + abs(dot(u0, n))) + +dT = Constant(dt) + +vector_invariant = True +if vector_invariant: + L = ( + dT*inner(perp(grad(inner(v, perp(u0)))), u0)*dx + - dT*inner(both(perp(n)*inner(v, perp(u0))), + both(Upwind*u0))*dS + + dT*div(v)*K*dx + + dT*inner(grad(phi), u0*(eta0-b))*dx + - dT*jump(phi)*(uup('+')*(eta0('+')-b('+')) + - uup('-')*(eta0('-') - b('-')))*dS + ) +else: + L = ( + dT*inner(div(outer(u0, v)), u0)*dx + - dT*inner(both(inner(n, u0)*v), both(Upwind*u0))*dS + + dT*inner(grad(phi), u0*(eta0-b))*dx + - dT*jump(phi)*(uup('+')*(eta0('+')-b('+')) + - uup('-')*(eta0('-') - b('-')))*dS + ) + +SlowProb = LinearVariationalProblem(a, L, USlow_out) +SlowSolver = LinearVariationalSolver(SlowProb, + solver_parameters = params) + +############################################################################## +# Set up depth advection solver (DG upwinded scheme) +############################################################################## +dts = 360 +up = Function(V1) +hp = Function(V2) +hps = Function(V2) +h = TrialFunction(V2) +phi = TestFunction(V2) +hh = 0.5 * (hn + h) +uh = 0.5 * (urn + up) +n = FacetNormal(mesh) +uup = 0.5 * (dot(uh, n) + abs(dot(uh, n))) +Heqn = ((h - hn)*phi*dx - dts*inner(grad(phi), uh*hh)*dx + + dts*jump(phi)*(uup('+')*hh('+')-uup('-')*hh('-'))*dS) +Hproblem = LinearVariationalProblem(lhs(Heqn), rhs(Heqn), hps) +lu_params = {'ksp_type': 'preonly', + 'pc_type': 'lu', + 'pc_factor_mat_solver_type': 'mumps'} +Hsolver = LinearVariationalSolver(Hproblem, + solver_parameters=lu_params, + options_prefix="H-advection") + +############################################################################## +# Velocity advection (Natale et. al (2016) extended to SWE) +############################################################################## +ups = Function(V1) +u = TrialFunction(V1) +v = TestFunction(V1) +hh = 0.5 * (hn + hp) +ubar = 0.5 * (urn + up) +uup = 0.5 * (dot(ubar, n) + abs(dot(ubar, n))) +uh = 0.5 * (urn + u) +Upwind = 0.5 * (sign(dot(ubar, n)) + 1) +K = 0.5 * (inner(0.5 * (urn + up), 0.5 * (urn + up))) +both = lambda u: 2*avg(u) +outward_normals = CellNormal(mesh) +perp = lambda arg: cross(outward_normals, arg) +Ueqn = (inner(u - urn, v)*dx + dts*inner(perp(uh)*f, v)*dx + - dts*inner(perp(grad(inner(v, perp(ubar)))), uh)*dx + + dts*inner(both(perp(n)*inner(v, perp(ubar))), + both(Upwind*uh))*dS + - dts*div(v)*(g*(hh + b) + K)*dx) +Uproblem = LinearVariationalProblem(lhs(Ueqn), rhs(Ueqn), ups) +Usolver = LinearVariationalSolver(Uproblem, + solver_parameters=lu_params, + options_prefix="U-advection") + +############################################################################## +# Linear solver for incremental updates +############################################################################## +HU = Function(W) +deltaU, deltaH = HU.split() +w, phi = TestFunctions(W) +du, dh = TrialFunctions(W) +alpha = 0.5 +HUlhs = (inner(w, du + alpha*dts*f*perp(du))*dx + - alpha*dts*div(w)*g*dh*dx + + phi*(dh + alpha*dts*H*div(du))*dx) +HUrhs = -inner(w, up - ups)*dx - phi*(hp - hps)*dx +HUproblem = LinearVariationalProblem(HUlhs, HUrhs, HU) +params = {'ksp_type': 'preonly', + 'mat_type': 'aij', + 'pc_type': 'lu', + 'pc_factor_mat_solver_type': 'mumps'} +HUsolver = LinearVariationalSolver(HUproblem, + solver_parameters=params, + options_prefix="impl-solve") + +############################################################################## +# Time loop +############################################################################## +U = Function(W) +DU = Function(W) +U1 = Function(W) +U2 = Function(W) +U3 = Function(W) +X1 = Function(W) +X2 = Function(W) +X3 = Function(W) +V = Function(W) + +U_u, U_eta = U.split() +U_u.assign(un) +U_eta.assign(etan) + +k_max = 4 # Maximum number of Picard iterations +iter_max = int(dt/dts) +print("dt, dts, iter_max =", dt, dts, iter_max) +u_out = Function(V1, name="Velocity").assign(urn) +eta_out = Function(V2, name="Elevation").assign(hn + b - H) +u_diff = Function(V1, name="Velocity Difference").assign(un - u_out) +eta_diff = Function(V2, name="Elevation Difference").assign(etan - eta_out) + +#set weights +rank = ensemble.ensemble_comm.rank +expt = rho*dt*svals[rank] +wt = weights[rank] +print(wt,"weight",expt) + +#write out initial fields +name = args.filename +if rank==0: + file_sw = File(name+'_avg.pvd', comm=ensemble.comm) + file_r = File(name+'_serial.pvd', comm=ensemble.comm) + file_d = File(name+'_diff.pvd', comm=ensemble.comm) + file_sw.write(un, etan, b) + file_r.write(u_out, eta_out, b) + file_d.write(u_diff, eta_diff, b) + area = assemble(1*dx(domain=f.ufl_domain())) + print('area', area) + u_norm = errornorm(un, u_out)/area + eta_norm = errornorm(etan, eta_out)/area + print('u_norm', u_norm, 'eta_norm', eta_norm) + +#start time loop +print('tmax', tmax, 'dt', dt) +while t < tmax + 0.5*dt: + print(t) + t += dt + tdump += dt + + if t < dt*1.5 and timestepping == 'leapfrog': + U_old = Function(W) + U_new = Function(W) + U_old.assign(U) + rk2(U, USlow_in, USlow_out, DU, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + else: + if timestepping == 'leapfrog': + leapfrog(U, USlow_in, USlow_out, U_old, U_new, DU, U1, U2, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt, asselin) + elif timestepping == 'ssprk3': + ssprk3(U, USlow_in, USlow_out, DU, U1, U2, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + elif timestepping == 'rk2': + rk2(U, USlow_in, USlow_out, DU, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + elif timestepping == 'rk4': + rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, X1, X2, X3, V, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + elif timestepping == 'heuns': + heuns(U, USlow_in, USlow_out, DU, U1, U2, W, + expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + + if rank == 0: + #run the serial solver + + for iter in range(iter_max): + print(iter) + up.assign(urn) + hp.assign(hn) + + #start picard cycle + for i in range(k_max): + #advect to get candidates + Hsolver.solve() + Usolver.solve() + + #linear solve for updates + HUsolver.solve() + + #increment updates + up += deltaU + hp += deltaH + + #update fields for next time step + urn.assign(up) + hn.assign(hp) + + #dumping + if tdump > dumpt - dt*0.5: + #dump averaged results + un.assign(U_u) + etan.assign(U_eta) + file_sw.write(un, etan, b) + #dump non averaged results + u_out.assign(urn) + eta_out.assign(hn + b - H) + file_r.write(u_out, eta_out, b) + #dump differences + u_diff.assign(un - u_out) + eta_diff.assign(etan - eta_out) + file_d.write(u_diff, eta_diff, b) + #calculate l2 norm + u_norm = errornorm(un, u_out)/area + eta_norm = errornorm(etan, eta_out)/area + print('u_norm', u_norm, 'eta_norm', eta_norm) + #update dumpt + print("dumped at t =", t) + tdump -= dumpt From dc3b0aba3b409bdd33e3e5a5c265b8fdb5f48b8e Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Thu, 28 Jan 2021 14:04:30 +0000 Subject: [PATCH 13/46] williamson 6 test case is now working --- averaged_sw_williamson6.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/averaged_sw_williamson6.py b/averaged_sw_williamson6.py index d239e73..5b7106b 100644 --- a/averaged_sw_williamson6.py +++ b/averaged_sw_williamson6.py @@ -17,12 +17,12 @@ parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') -parser.add_argument('--filter2', type=bool, default=True, help='Use a filter for cheby2') +parser.add_argument('--filter2', type=bool, default=False, help='Use a filter for cheby2') parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') -parser.add_argument('--filename', type=str, default='sw_rossby') +parser.add_argument('--filename', type=str, default='sw_rossby_triangle') args = parser.parse_known_args() args = args[0] filter = args.filter @@ -43,7 +43,7 @@ Omega = Constant(7.292e-5) # rotation rate g = Constant(9.8) # Gravitational constant mesh = IcosahedralSphereMesh(radius=R0, - refinement_level=ref_level, degree=3, + refinement_level=ref_level, comm = ensemble.comm) x = SpatialCoordinate(mesh) global_normal = as_vector([x[0], x[1], x[2]]) @@ -226,7 +226,7 @@ def Ctheta(theta): ############################################################################## # Set up depth advection solver (DG upwinded scheme) ############################################################################## -dts = 360 +dts = 900 up = Function(V1) hp = Function(V2) hps = Function(V2) From 7f87845ab7c29bf7917accccf24c51762f87129a Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Thu, 11 Feb 2021 14:19:29 +0000 Subject: [PATCH 14/46] initialise coefficients --- cheby_exp.py | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/cheby_exp.py b/cheby_exp.py index 7e78bf0..c6d0305 100644 --- a/cheby_exp.py +++ b/cheby_exp.py @@ -18,7 +18,7 @@ def __init__(self, operator_solver, operator_in, operator_out, operator_in: the input to operator_solver operator_out: the output to operator_solver ncheb: number of Chebyshev polynomials to approximate exp - tol: tolerance to compress Chebyshev expansion by + tol: tolerance to compress Chebyshev expansion by (removes terms from the high degree end until total L^1 norm of removed terms > tol) L: approximate exp on range [-L*i, L*i] @@ -42,8 +42,41 @@ def __init__(self, operator_solver, operator_in, operator_out, self.ChebCoeffs = FourierCoeffs[:ncheb+2] self.ChebCoeffs[0] = self.ChebCoeffs[0]/2 self.ChebCoeffs[-1] = self.ChebCoeffs[-1]/2 - + + #initialise T0 + A = 0 + Tnm1 = 1.0 + Tn = A/(L*1j) + nc = 10000 + fvals0 = self.ChebCoeffs[0]*Tnm1 + self.ChebCoeffs[1]*Tn + + for i in range(2,nc+1): + Tnm2 = Tnm1 + Tnm1 = Tn + Tn = 2*A*Tnm1/(L*1j) - Tnm2 + fvals0 += self.ChebCoeffs[i]*Tn + + print("fvals0 before initialisation", fvals0) + + for i in range(len(self.ChebCoeffs)): + self.ChebCoeffs[i] = self.ChebCoeffs[i]/fvals0 + + #check if fvals0 = 1 + Tnm1 = 1.0 + Tn = A/(L*1j) + nc = 10000 + fvals0 = self.ChebCoeffs[0]*Tnm1 + self.ChebCoeffs[1]*Tn + + for i in range(2,nc+1): + Tnm2 = Tnm1 + Tnm1 = Tn + Tn = 2*A*Tnm1/(L*1j) - Tnm2 + fvals0 += self.ChebCoeffs[i]*Tn + + print("fvals0 after initialisation", fvals0) + #cheby compression + print("ncheb before compression", ncheb) nrm = 0. Compressed = False while nrm + abs(self.ChebCoeffs[ncheb+1]) < tol: @@ -51,8 +84,11 @@ def __init__(self, operator_solver, operator_in, operator_out, ncheb -= 1 Compressed = True assert Compressed + print("ncheb after compression", ncheb) +# ncheb = 100 self.ncheb = ncheb + print("ncheb is set to", ncheb) self.L = L FS = operator_in.function_space() @@ -64,7 +100,7 @@ def __init__(self, operator_solver, operator_in, operator_out, self.T_i = Function(FS) self.dy = Function(FS) - + def apply(self, x, y, t): L = self.L #initially Tm1 contains T_0(A)x From 0d16c21fbd814ab7f05138c3805c319c3fd296f8 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Thu, 25 Feb 2021 15:43:29 +0000 Subject: [PATCH 15/46] print out norms every tnorm --- averaged_sw_diff.py | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 355116a..68bb790 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -16,8 +16,8 @@ parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') -parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') -parser.add_argument('--filter2', type=bool, default=True, help='Use a filter for cheby2') +parser.add_argument('--filter', type=bool, default=False, help='Use a filter in the averaging exponential') +parser.add_argument('--filter2', type=bool, default=False, help='Use a filter for cheby2') parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') @@ -31,6 +31,7 @@ timestepping = args.timestepping asselin = args.asselin ref_level = args.ref_level +print(args) #ensemble communicator ensemble = Ensemble(COMM_WORLD, 1) @@ -103,7 +104,9 @@ t = 0. tmax = 60.*60.*args.tmax dumpt = args.dumpt*60.*60. +normt = 24.*60.*60. tdump = 0. +tnorm = 0. #print out settings print = PETSc.Sys.Print @@ -196,7 +199,7 @@ ############################################################################## # Set up depth advection solver (DG upwinded scheme) ############################################################################## -dts = 900 +dts = 180 up = Function(V1) hp = Function(V2) hps = Function(V2) @@ -291,9 +294,12 @@ rank = ensemble.ensemble_comm.rank expt = rho*dt*svals[rank] wt = weights[rank] -print(wt,"weight",expt) +print(wt, "weight", expt) +print("svals", svals) #write out initial fields +u_norm = [] +eta_norm = [] name = args.filename if rank==0: file_sw = File(name+'_avg.pvd', comm=ensemble.comm) @@ -304,9 +310,13 @@ file_d.write(u_diff, eta_diff, b) area = assemble(1*dx(domain=f.ufl_domain())) print('area', area) - u_norm = errornorm(un, u_out)/area - eta_norm = errornorm(etan, eta_out)/area - print('u_norm', u_norm, 'eta_norm', eta_norm) + unorm = errornorm(un, u_out)/norm(u_out) + etanorm = errornorm(etan, eta_out)/norm(eta_out) + print('u_norm', unorm, 'eta_norm', etanorm) + u_norm.append(unorm) + eta_norm.append(etanorm) + print('u_norm =', u_norm) + print('eta_norm =', eta_norm) #start time loop print('tmax', tmax, 'dt', dt) @@ -314,6 +324,7 @@ print(t) t += dt tdump += dt + tnorm += dt if t < dt*1.5 and timestepping == 'leapfrog': U_old = Function(W) @@ -378,9 +389,16 @@ eta_diff.assign(etan - eta_out) file_d.write(u_diff, eta_diff, b) #calculate l2 norm - u_norm = errornorm(un, u_out)/area - eta_norm = errornorm(etan, eta_out)/area - print('u_norm', u_norm, 'eta_norm', eta_norm) + unorm = errornorm(un, u_out)/norm(u_out) + etanorm = errornorm(etan, eta_out)/norm(eta_out) + print('u_norm', unorm, 'eta_norm', etanorm) #update dumpt print("dumped at t =", t) tdump -= dumpt + + if tnorm > normt - dt*0.5: + u_norm.append(unorm) + eta_norm.append(etanorm) + print('u_norm =', u_norm) + print('eta_norm =', eta_norm) + tnorm -= normt From a79c2b0f9ec6e2ab7504c5cb21d127cea8da2e88 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Mon, 8 Mar 2021 11:56:12 +0000 Subject: [PATCH 16/46] dump lat-lon plots --- averaged_sw_diff.py | 41 +++++++++++++++++++++++++++++++++++++++++ timestepping_methods.py | 2 -- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 68bb790..c6a33ca 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -4,6 +4,7 @@ from math import pi from math import ceil from timestepping_methods import * +from latlon import * import numpy as np import argparse @@ -318,6 +319,42 @@ print('u_norm =', u_norm) print('eta_norm =', eta_norm) + mesh_ll = get_latlon_mesh(mesh) + file_avg_ll = File(name+'_avg_latlon.pvd', comm=ensemble.comm) + file_serial_ll = File(name+'_serial_latlon.pvd', comm=ensemble.comm) + file_diff_ll = File(name+'_diff_latlon.pvd', comm=ensemble.comm) + field_un = Function( + functionspaceimpl.WithGeometry( + un.function_space(), mesh_ll), + val=un.topological) + field_etan = Function( + functionspaceimpl.WithGeometry( + etan.function_space(), mesh_ll), + val=etan.topological) + field_b = Function( + functionspaceimpl.WithGeometry( + b.function_space(), mesh_ll), + val=b.topological) + field_uout = Function( + functionspaceimpl.WithGeometry( + u_out.function_space(), mesh_ll), + val=u_out.topological) + field_etaout = Function( + functionspaceimpl.WithGeometry( + eta_out.function_space(), mesh_ll), + val=eta_out.topological) + field_udiff = Function( + functionspaceimpl.WithGeometry( + u_diff.function_space(), mesh_ll), + val=u_diff.topological) + field_etadiff = Function( + functionspaceimpl.WithGeometry( + eta_diff.function_space(), mesh_ll), + val=eta_diff.topological) + file_avg_ll.write(field_un, field_etan, field_b) + file_serial_ll.write(field_uout, field_etaout, field_b) + file_diff_ll.write(field_udiff, field_etadiff, field_b) + #start time loop print('tmax', tmax, 'dt', dt) while t < tmax + 0.5*dt: @@ -380,14 +417,17 @@ un.assign(U_u) etan.assign(U_eta) file_sw.write(un, etan, b) + file_avg_ll.write(field_un, field_etan, field_b) #dump non averaged results u_out.assign(urn) eta_out.assign(hn + b - H) file_r.write(u_out, eta_out, b) + file_serial_ll.write(field_uout, field_etaout, field_b) #dump differences u_diff.assign(un - u_out) eta_diff.assign(etan - eta_out) file_d.write(u_diff, eta_diff, b) + file_diff_ll.write(field_udiff, field_etadiff, field_b) #calculate l2 norm unorm = errornorm(un, u_out)/norm(u_out) etanorm = errornorm(etan, eta_out)/norm(eta_out) @@ -402,3 +442,4 @@ print('u_norm =', u_norm) print('eta_norm =', eta_norm) tnorm -= normt + diff --git a/timestepping_methods.py b/timestepping_methods.py index 8fce36c..a6e8509 100644 --- a/timestepping_methods.py +++ b/timestepping_methods.py @@ -1,8 +1,6 @@ #timestepping options for averaged_sw_explicit.py #rk2/heuns/ssprk3/leapfrog -from firedrake import Function - def rk2(U, USlow_in, USlow_out, DU, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt): #Average the nonlinearity From 7ffaaa91cd1c10d1764fe0603337aed8996fb83d Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Thu, 18 Mar 2021 12:41:01 +0000 Subject: [PATCH 17/46] added checkpointing --- averaged_sw_diff.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index c6a33ca..6633616 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -11,7 +11,7 @@ #get command arguments parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') -parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') +parser.add_argument('--tmax', type=float, default=1200, help='Final time in hours. Default 24x50=1200.') parser.add_argument('--dumpt', type=float, default=6, help='Dump time in hours. Default 6.') parser.add_argument('--dt', type=float, default=2, help='Timestep in hours. Default 2.') parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') @@ -355,6 +355,13 @@ file_serial_ll.write(field_uout, field_etaout, field_b) file_diff_ll.write(field_udiff, field_etadiff, field_b) + #create checkpointing file + print("create checkpointing file at rank =", rank) + chk = DumbCheckpoint("dump_explicit", mode=FILE_CREATE, comm = ensemble.comm) + chk.store(un) + chk.store(etan) + chk.store(b) + #start time loop print('tmax', tmax, 'dt', dt) while t < tmax + 0.5*dt: @@ -435,6 +442,10 @@ #update dumpt print("dumped at t =", t) tdump -= dumpt + #checkpointing + chk.store(un) + chk.store(etan) + chk.store(b) if tnorm > normt - dt*0.5: u_norm.append(unorm) @@ -443,3 +454,24 @@ print('eta_norm =', eta_norm) tnorm -= normt +if rank == 0: + chk.close() + + #check if dumbcheckpoint is working + und = Function(V1) + etand = Function(V2) + bd = Function(V2) + + chkfile = DumbCheckpoint("dump_explicit", mode=FILE_READ, comm = ensemble.comm) + chkfile.load(und, name="Velocity") + chkfile.load(etand, name="Elevation") + chkfile.load(bd, name="Topography") + + valf = assemble(etan*dx) + valg = assemble(etand*dx) + + print("valf = ", valf) + print("valg = ", valg) + assert(valf == valg) + + chkfile.close() From 447299487cddd1692e076961a1cece34ce5b64ca Mon Sep 17 00:00:00 2001 From: Colin Cotter Date: Thu, 18 Mar 2021 13:45:35 +0000 Subject: [PATCH 18/46] playing with the growth factor of the exp --- check_cheb.py | 54 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/check_cheb.py b/check_cheb.py index 375696e..249b3a3 100644 --- a/check_cheb.py +++ b/check_cheb.py @@ -13,7 +13,7 @@ #approximating exp(ix) on interval [-L,L] #by \sum_i a_i T_i(ix) -fvals = exp(pi*1j*x) +fvals = exp(1j*x) thetas = concatenate((flipud(t1), -t1[1:-1])) valsUnitDisc = concatenate((flipud(fvals), fvals[1:-1])) FourierCoeffs = fftpack.fft(valsUnitDisc)/n @@ -29,25 +29,39 @@ for i in range(nf): fvals0 += ChebCoeffs[i]*cos(i*thetas) -pyplot.plot(thetas,real(fvals0),'.') -pyplot.plot(thetas,real(valsUnitDisc),'-k') -pyplot.show() +#pyplot.plot(thetas,real(fvals0),'.') +#pyplot.plot(thetas,real(valsUnitDisc),'-k') +#pyplot.show() -pyplot.plot(thetas,imag(fvals0),'.') -pyplot.plot(thetas,imag(valsUnitDisc),'-k') -pyplot.show() +#pyplot.plot(thetas,imag(fvals0),'.') +#pyplot.plot(thetas,imag(valsUnitDisc),'-k') +#pyplot.show() #Compute Forward transform using iterative formula -fvals0 = 0*fvals +nc = 500 #initialise T0 +A = 0.*1j +Tnm1 = 1.0+0.0j +Tn = A/(L*1j) +f0 = ChebCoeffs[0]*Tnm1 + ChebCoeffs[1]*Tn +for i in range(2,nc+1): + Tnm2 = Tnm1 + Tnm1 = Tn + Tn = 2*A*Tnm1/(L*1j) - Tnm2 -A = 1j*x + f0 += ChebCoeffs[i]*Tn + +print(f0) +ChebCoeffs /= f0 + +fvals0 = 0*fvals +x2 = arange(-L,L,L*0.001) +A = 1j*x2 Tnm1 = 1.0 Tn = A/(L*1j) -nc = 500 fvals0 = ChebCoeffs[0]*Tnm1 + ChebCoeffs[1]*Tn for i in range(2,nc+1): @@ -56,13 +70,16 @@ Tn = 2*A*Tnm1/(L*1j) - Tnm2 fvals0 += ChebCoeffs[i]*Tn - -pyplot.plot(x,real(fvals),'.') -pyplot.plot(x,real(fvals0),'-k') -pyplot.show() - -pyplot.plot(x,imag(fvals),'.') -pyplot.plot(x,imag(fvals0),'-k') + +print(absolute(fvals0).max()) + +#pyplot.plot(x,real(fvals),'-b') +pyplot.plot(x2,real(fvals0),'.r') +pyplot.plot(x2,sqrt(real(fvals0)**2 + imag(fvals0)**2),'--b') +pyplot.plot(x,cos(x),'--r') +#pyplot.plot(x,imag(fvals),'-g') +pyplot.plot(x2,imag(fvals0),'.k') +pyplot.plot(x,sin(x),'--k') pyplot.show() A = 0.1*array([[0,-1],[1,0]]) @@ -88,6 +105,3 @@ y += real(ChebCoeffs[i]*T_r + ChebCoeffs[i]*T_i) -print(exp(A)) -print(dot(exp(A),v)) -print(y) From 0b5f39284c295ca4152dbf98b56120e928dfc54d Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Fri, 19 Mar 2021 00:47:57 +0000 Subject: [PATCH 19/46] dump only the latlon plots. initialise fvals after compression. --- averaged_sw_diff.py | 61 ++++++++++++++++------------------------- cheby_exp.py | 33 ++++++++++------------ latlon.py | 59 +++++++++++++++++++++++++++++++++++++++ timestepping_methods.py | 2 +- 4 files changed, 98 insertions(+), 57 deletions(-) create mode 100644 latlon.py diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 6633616..4e9e68d 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -12,7 +12,7 @@ parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') parser.add_argument('--tmax', type=float, default=1200, help='Final time in hours. Default 24x50=1200.') -parser.add_argument('--dumpt', type=float, default=6, help='Dump time in hours. Default 6.') +parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 6.') parser.add_argument('--dt', type=float, default=2, help='Timestep in hours. Default 2.') parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') @@ -298,17 +298,11 @@ print(wt, "weight", expt) print("svals", svals) -#write out initial fields u_norm = [] eta_norm = [] name = args.filename if rank==0: - file_sw = File(name+'_avg.pvd', comm=ensemble.comm) - file_r = File(name+'_serial.pvd', comm=ensemble.comm) - file_d = File(name+'_diff.pvd', comm=ensemble.comm) - file_sw.write(un, etan, b) - file_r.write(u_out, eta_out, b) - file_d.write(u_diff, eta_diff, b) + #calculate norm at the initial state area = assemble(1*dx(domain=f.ufl_domain())) print('area', area) unorm = errornorm(un, u_out)/norm(u_out) @@ -319,41 +313,35 @@ print('u_norm =', u_norm) print('eta_norm =', eta_norm) + #write out initial fields mesh_ll = get_latlon_mesh(mesh) - file_avg_ll = File(name+'_avg_latlon.pvd', comm=ensemble.comm) - file_serial_ll = File(name+'_serial_latlon.pvd', comm=ensemble.comm) - file_diff_ll = File(name+'_diff_latlon.pvd', comm=ensemble.comm) + file_sw = File(name+'_avg.pvd', comm=ensemble.comm) + file_r = File(name+'_serial.pvd', comm=ensemble.comm) + file_d = File(name+'_diff.pvd', comm=ensemble.comm) field_un = Function( - functionspaceimpl.WithGeometry( - un.function_space(), mesh_ll), + functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), val=un.topological) field_etan = Function( - functionspaceimpl.WithGeometry( - etan.function_space(), mesh_ll), + functionspaceimpl.WithGeometry(etan.function_space(), mesh_ll), val=etan.topological) field_b = Function( - functionspaceimpl.WithGeometry( - b.function_space(), mesh_ll), + functionspaceimpl.WithGeometry(b.function_space(), mesh_ll), val=b.topological) field_uout = Function( - functionspaceimpl.WithGeometry( - u_out.function_space(), mesh_ll), + functionspaceimpl.WithGeometry(u_out.function_space(), mesh_ll), val=u_out.topological) field_etaout = Function( - functionspaceimpl.WithGeometry( - eta_out.function_space(), mesh_ll), + functionspaceimpl.WithGeometry(eta_out.function_space(), mesh_ll), val=eta_out.topological) field_udiff = Function( - functionspaceimpl.WithGeometry( - u_diff.function_space(), mesh_ll), + functionspaceimpl.WithGeometry(u_diff.function_space(), mesh_ll), val=u_diff.topological) field_etadiff = Function( - functionspaceimpl.WithGeometry( - eta_diff.function_space(), mesh_ll), + functionspaceimpl.WithGeometry(eta_diff.function_space(), mesh_ll), val=eta_diff.topological) - file_avg_ll.write(field_un, field_etan, field_b) - file_serial_ll.write(field_uout, field_etaout, field_b) - file_diff_ll.write(field_udiff, field_etadiff, field_b) + file_sw.write(field_un, field_etan, field_b) + file_r.write(field_uout, field_etaout, field_b) + file_d.write(field_udiff, field_etadiff, field_b) #create checkpointing file print("create checkpointing file at rank =", rank) @@ -423,18 +411,19 @@ #dump averaged results un.assign(U_u) etan.assign(U_eta) - file_sw.write(un, etan, b) - file_avg_ll.write(field_un, field_etan, field_b) + file_sw.write(field_un, field_etan, field_b) #dump non averaged results u_out.assign(urn) eta_out.assign(hn + b - H) - file_r.write(u_out, eta_out, b) - file_serial_ll.write(field_uout, field_etaout, field_b) + file_r.write(field_uout, field_etaout, field_b) #dump differences u_diff.assign(un - u_out) eta_diff.assign(etan - eta_out) - file_d.write(u_diff, eta_diff, b) - file_diff_ll.write(field_udiff, field_etadiff, field_b) + file_d.write(field_udiff, field_etadiff, field_b) + #checkpointing + chk.store(un) + chk.store(etan) + chk.store(b) #calculate l2 norm unorm = errornorm(un, u_out)/norm(u_out) etanorm = errornorm(etan, eta_out)/norm(eta_out) @@ -442,10 +431,6 @@ #update dumpt print("dumped at t =", t) tdump -= dumpt - #checkpointing - chk.store(un) - chk.store(etan) - chk.store(b) if tnorm > normt - dt*0.5: u_norm.append(unorm) diff --git a/cheby_exp.py b/cheby_exp.py index c6d0305..c54d6e3 100644 --- a/cheby_exp.py +++ b/cheby_exp.py @@ -43,14 +43,26 @@ def __init__(self, operator_solver, operator_in, operator_out, self.ChebCoeffs[0] = self.ChebCoeffs[0]/2 self.ChebCoeffs[-1] = self.ChebCoeffs[-1]/2 + #cheby compression + print("ncheb before compression", ncheb) + nrm = 0. + Compressed = False + while nrm + abs(self.ChebCoeffs[ncheb+1]) < tol: + nrm += abs(self.ChebCoeffs[ncheb+1]) + ncheb -= 1 + Compressed = True + assert Compressed + print("ncheb after compression", ncheb) + self.ncheb = ncheb + print("ncheb is set to", ncheb) + #initialise T0 A = 0 Tnm1 = 1.0 Tn = A/(L*1j) - nc = 10000 fvals0 = self.ChebCoeffs[0]*Tnm1 + self.ChebCoeffs[1]*Tn - for i in range(2,nc+1): + for i in range(2,ncheb+1): Tnm2 = Tnm1 Tnm1 = Tn Tn = 2*A*Tnm1/(L*1j) - Tnm2 @@ -64,10 +76,9 @@ def __init__(self, operator_solver, operator_in, operator_out, #check if fvals0 = 1 Tnm1 = 1.0 Tn = A/(L*1j) - nc = 10000 fvals0 = self.ChebCoeffs[0]*Tnm1 + self.ChebCoeffs[1]*Tn - for i in range(2,nc+1): + for i in range(2,ncheb+1): Tnm2 = Tnm1 Tnm1 = Tn Tn = 2*A*Tnm1/(L*1j) - Tnm2 @@ -75,20 +86,6 @@ def __init__(self, operator_solver, operator_in, operator_out, print("fvals0 after initialisation", fvals0) - #cheby compression - print("ncheb before compression", ncheb) - nrm = 0. - Compressed = False - while nrm + abs(self.ChebCoeffs[ncheb+1]) < tol: - nrm += abs(self.ChebCoeffs[ncheb+1]) - ncheb -= 1 - Compressed = True - assert Compressed - print("ncheb after compression", ncheb) - -# ncheb = 100 - self.ncheb = ncheb - print("ncheb is set to", ncheb) self.L = L FS = operator_in.function_space() diff --git a/latlon.py b/latlon.py new file mode 100644 index 0000000..883f61a --- /dev/null +++ b/latlon.py @@ -0,0 +1,59 @@ +from firedrake import * +import numpy as np + +def get_latlon_mesh(mesh): + coords_orig = mesh.coordinates + coords_fs = coords_orig.function_space() + + if coords_fs.extruded: + cell = mesh._base_mesh.ufl_cell().cellname() + DG1_hori_elt = FiniteElement("DG", cell, 1, variant="equispaced") + DG1_vert_elt = FiniteElement("DG", interval, 1, variant="equispaced") + DG1_elt = TensorProductElement(DG1_hori_elt, DG1_vert_elt) + else: + cell = mesh.ufl_cell().cellname() + DG1_elt = FiniteElement("DG", cell, 1, variant="equispaced") + vec_DG1 = VectorFunctionSpace(mesh, DG1_elt) + coords_dg = Function(vec_DG1).interpolate(coords_orig) + coords_latlon = Function(vec_DG1) + shapes = {"nDOFs": vec_DG1.finat_element.space_dimension(), 'dim': 3} + + radius = np.min(np.sqrt(coords_dg.dat.data[:, 0]**2 + coords_dg.dat.data[:, 1]**2 + coords_dg.dat.data[:, 2]**2)) + # lat-lon 'x' = atan2(y, x) + coords_latlon.dat.data[:, 0] = np.arctan2(coords_dg.dat.data[:, 1], coords_dg.dat.data[:, 0]) + # lat-lon 'y' = asin(z/sqrt(x^2 + y^2 + z^2)) + coords_latlon.dat.data[:, 1] = np.arcsin(coords_dg.dat.data[:, 2]/np.sqrt(coords_dg.dat.data[:, 0]**2 + coords_dg.dat.data[:, 1]**2 + coords_dg.dat.data[:, 2]**2)) + # our vertical coordinate is radius - the minimum radius + coords_latlon.dat.data[:, 2] = np.sqrt(coords_dg.dat.data[:, 0]**2 + coords_dg.dat.data[:, 1]**2 + coords_dg.dat.data[:, 2]**2) - radius + +# We need to ensure that all points in a cell are on the same side of the branch cut in longitude coords +# This kernel amends the longitude coords so that all longitudes in one cell are close together + kernel = op2.Kernel(""" +#define PI 3.141592653589793 +#define TWO_PI 6.283185307179586 +void splat_coords(double *coords) {{ + double max_diff = 0.0; + double diff = 0.0; + + for (int i=0; i<{nDOFs}; i++) {{ + for (int j=0; j<{nDOFs}; j++) {{ + diff = coords[i*{dim}] - coords[j*{dim}]; + if (fabs(diff) > max_diff) {{ + max_diff = diff; + }} + }} + }} + + if (max_diff > PI) {{ + for (int i=0; i<{nDOFs}; i++) {{ + if (coords[i*{dim}] < 0) {{ + coords[i*{dim}] += TWO_PI; + }} + }} + }} +}} +""".format(**shapes), "splat_coords") + + op2.par_loop(kernel, coords_latlon.cell_set, + coords_latlon.dat(op2.RW, coords_latlon.cell_node_map())) + return Mesh(coords_latlon) diff --git a/timestepping_methods.py b/timestepping_methods.py index a6e8509..fb04f92 100644 --- a/timestepping_methods.py +++ b/timestepping_methods.py @@ -1,5 +1,5 @@ #timestepping options for averaged_sw_explicit.py -#rk2/heuns/ssprk3/leapfrog +#rk2/rk4/heuns/ssprk3/leapfrog def rk2(U, USlow_in, USlow_out, DU, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt): From 477065b8fd1647d8ad9c0b98f8b2322efd6d8022 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Tue, 23 Mar 2021 13:05:27 +0000 Subject: [PATCH 20/46] dump PV and use HDiv norm for u. --- averaged_sw_diff.py | 89 +++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 27 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 4e9e68d..9f48a68 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -12,18 +12,18 @@ parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') parser.add_argument('--tmax', type=float, default=1200, help='Final time in hours. Default 24x50=1200.') -parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 6.') -parser.add_argument('--dt', type=float, default=2, help='Timestep in hours. Default 2.') +parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') +parser.add_argument('--dt', type=float, default=1, help='Timestep in hours. Default 1.') parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') -parser.add_argument('--filter', type=bool, default=False, help='Use a filter in the averaging exponential') +parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') parser.add_argument('--filter2', type=bool, default=False, help='Use a filter for cheby2') parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') -parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') +parser.add_argument('--timestepping', type=str, default='rk4', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') -parser.add_argument('--filename', type=str, default='explicit') +parser.add_argument('--filename', type=str, default='control_lev3') args = parser.parse_known_args() args = args[0] filter = args.filter @@ -298,20 +298,41 @@ print(wt, "weight", expt) print("svals", svals) -u_norm = [] eta_norm = [] +u_norm_Hdiv = [] +u_norm_L2 = [] name = args.filename if rank==0: - #calculate norm at the initial state - area = assemble(1*dx(domain=f.ufl_domain())) - print('area', area) - unorm = errornorm(un, u_out)/norm(u_out) + #calculate norms at the initial state etanorm = errornorm(etan, eta_out)/norm(eta_out) - print('u_norm', unorm, 'eta_norm', etanorm) - u_norm.append(unorm) + unorm_Hdiv = errornorm(un, u_out, norm_type="Hdiv")/norm(u_out, norm_type="Hdiv") + unorm_L2 = errornorm(un, u_out)/norm(u_out) + print('etanorm', etanorm, 'unorm_Hdiv', unorm_Hdiv, 'unorm_L2', unorm_L2) eta_norm.append(etanorm) - print('u_norm =', u_norm) - print('eta_norm =', eta_norm) + u_norm_Hdiv.append(unorm_Hdiv) + u_norm_L2.append(unorm_L2) + print('etanorm =', eta_norm) + print('unorm_Hdiv =', u_norm_Hdiv) + print('unorm_L2 =', u_norm_L2) + + #setup PV solver + PV = Function(Vf, name="PotentialVorticity") + gamma = TestFunction(Vf) + q = TrialFunction(Vf) + D = etan + H - b + a = q*gamma*D*dx + L = (- inner(perp(grad(gamma)), un))*dx + gamma*f*dx + PVproblem = LinearVariationalProblem(a, L, PV) + PVsolver = LinearVariationalSolver(PVproblem, solver_parameters={"ksp_type": "cg"}) + PVsolver.solve() + PVout = Function(Vf, name="PotentialVorticity") + Dout = eta_out + H - b + a = q*gamma*Dout*dx + L = (- inner(perp(grad(gamma)), u_out))*dx + gamma*f*dx + PVoutproblem = LinearVariationalProblem(a, L, PVout) + PVoutsolver = LinearVariationalSolver(PVoutproblem, solver_parameters={"ksp_type": "cg"}) + PVoutsolver.solve() + PVdiff = Function(Vf, name="PV Difference").assign(PV- PVout) #write out initial fields mesh_ll = get_latlon_mesh(mesh) @@ -324,6 +345,9 @@ field_etan = Function( functionspaceimpl.WithGeometry(etan.function_space(), mesh_ll), val=etan.topological) + field_PV = Function( + functionspaceimpl.WithGeometry(PV.function_space(), mesh_ll), + val=PV.topological) field_b = Function( functionspaceimpl.WithGeometry(b.function_space(), mesh_ll), val=b.topological) @@ -333,15 +357,21 @@ field_etaout = Function( functionspaceimpl.WithGeometry(eta_out.function_space(), mesh_ll), val=eta_out.topological) + field_PVout = Function( + functionspaceimpl.WithGeometry(PVout.function_space(), mesh_ll), + val=PVout.topological) field_udiff = Function( functionspaceimpl.WithGeometry(u_diff.function_space(), mesh_ll), val=u_diff.topological) field_etadiff = Function( functionspaceimpl.WithGeometry(eta_diff.function_space(), mesh_ll), val=eta_diff.topological) - file_sw.write(field_un, field_etan, field_b) - file_r.write(field_uout, field_etaout, field_b) - file_d.write(field_udiff, field_etadiff, field_b) + field_PVdiff = Function( + functionspaceimpl.WithGeometry(PVdiff.function_space(), mesh_ll), + val=PVdiff.topological) + file_sw.write(field_un, field_etan, field_PV, field_b) + file_r.write(field_uout, field_etaout, field_PVout, field_b) + file_d.write(field_udiff, field_etadiff, field_PVdiff, field_b) #create checkpointing file print("create checkpointing file at rank =", rank) @@ -385,7 +415,6 @@ #run the serial solver for iter in range(iter_max): - print(iter) up.assign(urn) hp.assign(hn) @@ -411,32 +440,38 @@ #dump averaged results un.assign(U_u) etan.assign(U_eta) - file_sw.write(field_un, field_etan, field_b) + PVsolver.solve() + file_sw.write(field_un, field_etan, field_PV, field_b) #dump non averaged results u_out.assign(urn) eta_out.assign(hn + b - H) - file_r.write(field_uout, field_etaout, field_b) + PVoutsolver.solve() + file_r.write(field_uout, field_etaout, field_PVout, field_b) #dump differences u_diff.assign(un - u_out) eta_diff.assign(etan - eta_out) - file_d.write(field_udiff, field_etadiff, field_b) + PVdiff.assign(PV- PVout) + file_d.write(field_udiff, field_etadiff, field_PVdiff, field_b) #checkpointing chk.store(un) chk.store(etan) chk.store(b) - #calculate l2 norm - unorm = errornorm(un, u_out)/norm(u_out) + #calculate norms etanorm = errornorm(etan, eta_out)/norm(eta_out) - print('u_norm', unorm, 'eta_norm', etanorm) + unorm_Hdiv = errornorm(un, u_out, norm_type="Hdiv")/norm(u_out, norm_type="Hdiv") + unorm_L2 = errornorm(un, u_out)/norm(u_out) + print('etanorm', etanorm, 'unorm_Hdiv', unorm_Hdiv, 'unorm_L2', unorm_L2) #update dumpt print("dumped at t =", t) tdump -= dumpt if tnorm > normt - dt*0.5: - u_norm.append(unorm) eta_norm.append(etanorm) - print('u_norm =', u_norm) - print('eta_norm =', eta_norm) + u_norm_Hdiv.append(unorm_Hdiv) + u_norm_L2.append(unorm_L2) + print('etanorm =', eta_norm) + print('unorm_Hdiv =', u_norm_Hdiv) + print('unorm_L2 =', u_norm_L2) tnorm -= normt if rank == 0: From fd978e7e9b8337b31b6b34b1bee3371933d9f91b Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Tue, 6 Apr 2021 00:22:27 +0100 Subject: [PATCH 21/46] added pickup option --- averaged_sw_diff.py | 88 +++++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 31 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 9f48a68..f807be9 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -23,7 +23,8 @@ parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') parser.add_argument('--timestepping', type=str, default='rk4', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') -parser.add_argument('--filename', type=str, default='control_lev3') +parser.add_argument('--filename', type=str, default='control') +parser.add_argument('--pickup', type=bool, default=False, help='Pickup the result from the checkpoint.') args = parser.parse_known_args() args = args[0] filter = args.filter @@ -63,11 +64,6 @@ eta_expr = -((R*Omega*u_max+u_max*u_max/2.0)*(x[2]*x[2]/(R*R)))/g h_expr = eta_expr + H -un = Function(V1, name="Velocity").project(u_expr) -etan = Function(V2, name="Elevation").interpolate(eta_expr) -hn = Function(V2).interpolate(h_expr) -urn = Function(V1).assign(un) - #topography (D = H + eta - b) rl = pi/9.0 lambda_x = atan_2(x[1]/R0, x[0]/R0) @@ -78,7 +74,6 @@ bexpr = 2000.0*(1 - sqrt(minarg)/rl) b = Function(V2, name="Topography") b.interpolate(bexpr) -hn -= b #checking cheby parameters based on ref_level eigs = [0.003465, 0.007274, 0.014955] #maximum frequency @@ -116,6 +111,27 @@ print('Mbar', Mbar, 'samples per min time period', min_time_period/(rho*dt/Mbar)) print(args) +#pickup the result +if args.pickup: + chkfile = DumbCheckpoint(name, mode=FILE_READ, comm = ensemble.comm) + un = Function(V1, name="Velocity") + etan = Function(V2, name="Elevation") + urn = Function(V1, name="VelocityR") + hn = Function(V2, name="Depth") + chkfile.load(un, name="Velocity") + chkfile.load(etan, name="Elevation") + chkfile.load(urn, name="VelocityR") + chkfile.load(hn, name="Depth") + t = chkfile.read_attribute("/", "time") + tdump = chkfile.read_attribute("/", "tdump") + tnorm = chkfile.read_attribute("/", "tnorm") +else: + un = Function(V1, name="Velocity").project(u_expr) + etan = Function(V2, name="Elevation").interpolate(eta_expr) + urn = Function(V1, name="VelocityR").assign(un) + hn = Function(V2, name="Depth").interpolate(h_expr) + hn -= b + ############################################################################## # Set up the exponential operator ############################################################################## @@ -369,16 +385,14 @@ field_PVdiff = Function( functionspaceimpl.WithGeometry(PVdiff.function_space(), mesh_ll), val=PVdiff.topological) - file_sw.write(field_un, field_etan, field_PV, field_b) - file_r.write(field_uout, field_etaout, field_PVout, field_b) - file_d.write(field_udiff, field_etadiff, field_PVdiff, field_b) + if not args.pickup: + file_sw.write(field_un, field_etan, field_PV, field_b) + file_r.write(field_uout, field_etaout, field_PVout, field_b) + file_d.write(field_udiff, field_etadiff, field_PVdiff, field_b) #create checkpointing file print("create checkpointing file at rank =", rank) - chk = DumbCheckpoint("dump_explicit", mode=FILE_CREATE, comm = ensemble.comm) - chk.store(un) - chk.store(etan) - chk.store(b) + chk = DumbCheckpoint(name, mode=FILE_CREATE, comm = ensemble.comm) #start time loop print('tmax', tmax, 'dt', dt) @@ -436,6 +450,14 @@ hn.assign(hp) #dumping + if tnorm > normt - dt*0.5: + eta_norm.append(etanorm) + u_norm_Hdiv.append(unorm_Hdiv) + u_norm_L2.append(unorm_L2) + print('etanorm =', eta_norm) + print('unorm_Hdiv =', u_norm_Hdiv) + print('unorm_L2 =', u_norm_L2) + tnorm -= normt if tdump > dumpt - dt*0.5: #dump averaged results un.assign(U_u) @@ -452,10 +474,6 @@ eta_diff.assign(etan - eta_out) PVdiff.assign(PV- PVout) file_d.write(field_udiff, field_etadiff, field_PVdiff, field_b) - #checkpointing - chk.store(un) - chk.store(etan) - chk.store(b) #calculate norms etanorm = errornorm(etan, eta_out)/norm(eta_out) unorm_Hdiv = errornorm(un, u_out, norm_type="Hdiv")/norm(u_out, norm_type="Hdiv") @@ -464,15 +482,14 @@ #update dumpt print("dumped at t =", t) tdump -= dumpt - - if tnorm > normt - dt*0.5: - eta_norm.append(etanorm) - u_norm_Hdiv.append(unorm_Hdiv) - u_norm_L2.append(unorm_L2) - print('etanorm =', eta_norm) - print('unorm_Hdiv =', u_norm_Hdiv) - print('unorm_L2 =', u_norm_L2) - tnorm -= normt + #checkpointing + chk.store(un) + chk.store(etan) + chk.store(urn) + chk.store(hn) + chk.write_attribute("/", "time", t) + chk.write_attribute("/", "tdump", tdump) + chk.write_attribute("/", "tnorm", tnorm) if rank == 0: chk.close() @@ -480,18 +497,27 @@ #check if dumbcheckpoint is working und = Function(V1) etand = Function(V2) - bd = Function(V2) + urnd = Function(V1) + hnd = Function(V2) - chkfile = DumbCheckpoint("dump_explicit", mode=FILE_READ, comm = ensemble.comm) + chkfile = DumbCheckpoint(name, mode=FILE_READ, comm = ensemble.comm) chkfile.load(und, name="Velocity") chkfile.load(etand, name="Elevation") - chkfile.load(bd, name="Topography") - + chkfile.load(urnd, name="VelocityR") + chkfile.load(hnd, name="Depth") + t = chkfile.read_attribute("/", "time") + tdump = chkfile.read_attribute("/", "tdump") + tnorm = chkfile.read_attribute("/", "tnorm") valf = assemble(etan*dx) valg = assemble(etand*dx) + valh = assemble(hn*dx) + vald = assemble(hnd*dx) print("valf = ", valf) print("valg = ", valg) assert(valf == valg) + print("valh = ", valh) + print("vald = ", vald) + assert(valh == vald) chkfile.close() From e2b9542b64727bf0f07e647b61e802ff732b4a8a Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 7 Apr 2021 11:43:54 +0100 Subject: [PATCH 22/46] use store_true instead of bool --- averaged_sw_diff.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index f807be9..503056d 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -17,14 +17,14 @@ parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') -parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') -parser.add_argument('--filter2', type=bool, default=False, help='Use a filter for cheby2') +parser.add_argument('--filter', action='store_true', help='Use a filter in the averaging exponential') +parser.add_argument('--filter2', action='store_true', help='Use a filter for cheby2') parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') parser.add_argument('--timestepping', type=str, default='rk4', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') parser.add_argument('--filename', type=str, default='control') -parser.add_argument('--pickup', type=bool, default=False, help='Pickup the result from the checkpoint.') +parser.add_argument('--pickup', action='store_true', help='Pickup the result from the checkpoint.') args = parser.parse_known_args() args = args[0] filter = args.filter @@ -33,6 +33,7 @@ timestepping = args.timestepping asselin = args.asselin ref_level = args.ref_level +filename = args.filename print(args) #ensemble communicator @@ -113,7 +114,7 @@ #pickup the result if args.pickup: - chkfile = DumbCheckpoint(name, mode=FILE_READ, comm = ensemble.comm) + chkfile = DumbCheckpoint(filename, mode=FILE_READ, comm = ensemble.comm) un = Function(V1, name="Velocity") etan = Function(V2, name="Elevation") urn = Function(V1, name="VelocityR") @@ -317,7 +318,6 @@ eta_norm = [] u_norm_Hdiv = [] u_norm_L2 = [] -name = args.filename if rank==0: #calculate norms at the initial state etanorm = errornorm(etan, eta_out)/norm(eta_out) @@ -352,9 +352,9 @@ #write out initial fields mesh_ll = get_latlon_mesh(mesh) - file_sw = File(name+'_avg.pvd', comm=ensemble.comm) - file_r = File(name+'_serial.pvd', comm=ensemble.comm) - file_d = File(name+'_diff.pvd', comm=ensemble.comm) + file_sw = File(filename+'_avg.pvd', comm=ensemble.comm) + file_r = File(filename+'_serial.pvd', comm=ensemble.comm) + file_d = File(filename+'_diff.pvd', comm=ensemble.comm) field_un = Function( functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), val=un.topological) @@ -392,7 +392,7 @@ #create checkpointing file print("create checkpointing file at rank =", rank) - chk = DumbCheckpoint(name, mode=FILE_CREATE, comm = ensemble.comm) + chk = DumbCheckpoint(filename, mode=FILE_CREATE, comm = ensemble.comm) #start time loop print('tmax', tmax, 'dt', dt) From 7ed133ea622ca98f28135107a6ea6d8480de9ba0 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 7 Apr 2021 23:24:33 +0100 Subject: [PATCH 23/46] add option --pickupfrom --- averaged_sw_diff.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 503056d..37dac48 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -25,6 +25,7 @@ parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') parser.add_argument('--filename', type=str, default='control') parser.add_argument('--pickup', action='store_true', help='Pickup the result from the checkpoint.') +parser.add_argument('--pickupfrom', type=str, default='chkpt') args = parser.parse_known_args() args = args[0] filter = args.filter @@ -114,7 +115,7 @@ #pickup the result if args.pickup: - chkfile = DumbCheckpoint(filename, mode=FILE_READ, comm = ensemble.comm) + chkfile = DumbCheckpoint(args.pickupfrom, mode=FILE_READ, comm = ensemble.comm) un = Function(V1, name="Velocity") etan = Function(V2, name="Elevation") urn = Function(V1, name="VelocityR") @@ -500,7 +501,7 @@ urnd = Function(V1) hnd = Function(V2) - chkfile = DumbCheckpoint(name, mode=FILE_READ, comm = ensemble.comm) + chkfile = DumbCheckpoint(filename, mode=FILE_READ, comm = ensemble.comm) chkfile.load(und, name="Velocity") chkfile.load(etand, name="Elevation") chkfile.load(urnd, name="VelocityR") From 593047a42ae79fa9bad93e07998cf29bcb1bf4b1 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Fri, 9 Apr 2021 01:12:58 +0100 Subject: [PATCH 24/46] fix dumping norms in case pickup=True --- averaged_sw_diff.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 37dac48..4878125 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -325,12 +325,13 @@ unorm_Hdiv = errornorm(un, u_out, norm_type="Hdiv")/norm(u_out, norm_type="Hdiv") unorm_L2 = errornorm(un, u_out)/norm(u_out) print('etanorm', etanorm, 'unorm_Hdiv', unorm_Hdiv, 'unorm_L2', unorm_L2) - eta_norm.append(etanorm) - u_norm_Hdiv.append(unorm_Hdiv) - u_norm_L2.append(unorm_L2) print('etanorm =', eta_norm) print('unorm_Hdiv =', u_norm_Hdiv) print('unorm_L2 =', u_norm_L2) + if not args.pickup: + eta_norm.append(etanorm) + u_norm_Hdiv.append(unorm_Hdiv) + u_norm_L2.append(unorm_L2) #setup PV solver PV = Function(Vf, name="PotentialVorticity") From 584ce451f393c3c5ae42b09af78a8d9f02bbd2f3 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Sat, 10 Apr 2021 14:51:48 +0100 Subject: [PATCH 25/46] add filter to cut off frequency --- averaged_sw_diff.py | 8 +++++++- cheby_exp.py | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 4878125..087768a 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -20,6 +20,7 @@ parser.add_argument('--filter', action='store_true', help='Use a filter in the averaging exponential') parser.add_argument('--filter2', action='store_true', help='Use a filter for cheby2') parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') +parser.add_argument('--filter_freq', action='store_true', help='Cut-off frequency for filter') parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') parser.add_argument('--timestepping', type=str, default='rk4', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') @@ -31,12 +32,17 @@ filter = args.filter filter2 = args.filter2 filter_val = args.filter_val +filter_freq = args.filter_freq timestepping = args.timestepping asselin = args.asselin ref_level = args.ref_level filename = args.filename print(args) +if filter_freq and filter: + print("To many filters are on") + import sys; sys.exit() + #ensemble communicator ensemble = Ensemble(COMM_WORLD, 1) @@ -169,7 +175,7 @@ ncheb = 10000 cheby = cheby_exp(OperatorSolver, operator_in, operator_out, - ncheb, tol=1.0e-8, L=L, filter=filter, filter_val=filter_val) + ncheb, tol=1.0e-8, L=L, filter=filter, filter_val=filter_val, filter_freq=filter_freq) cheby2 = cheby_exp(OperatorSolver, operator_in, operator_out, ncheb, tol=1.0e-8, L=L, filter=filter2, filter_val=filter_val) diff --git a/cheby_exp.py b/cheby_exp.py index c54d6e3..ac57e3e 100644 --- a/cheby_exp.py +++ b/cheby_exp.py @@ -7,7 +7,7 @@ class cheby_exp(object): def __init__(self, operator_solver, operator_in, operator_out, - ncheb, tol, L, filter=False, filter_val=0.75): + ncheb, tol, L, filter=False, filter_val=0.75, filter_freq=False): """ Class to apply the exponential of an operator using chebyshev approximation @@ -33,8 +33,17 @@ def __init__(self, operator_solver, operator_in, operator_out, x = L*np.cos(t1) fvals = np.exp(1j*x) - if filter: - fvals /= (1 + (x/filter_val/L)**2)**4 + #Set cut-off frequency + eigs = [0.003465, 0.007274, 0.014955] #maximum frequency + fL = eigs[0]*60*60 + + print("L =", L) + if filter_freq: + print("filter_freq is on. L =", fL) + fvals /= (1 + (x/fL)**2)**4 + elif filter: + print("filter is on. L =", filter_val*L) + fvals /= (1 + (x/(filter_val*L))**2)**4 valsUnitDisc = np.concatenate((np.flipud(fvals), fvals[1:-1])) FourierCoeffs = fftpack.fft(valsUnitDisc)/ncheb From 622d8442f6e8d75148159ed1b1f829f0c9abeb64 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 14 Apr 2021 01:40:36 +0100 Subject: [PATCH 26/46] checkpoint every time step --- averaged_sw_diff.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 087768a..2afdc1e 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -490,14 +490,15 @@ #update dumpt print("dumped at t =", t) tdump -= dumpt - #checkpointing - chk.store(un) - chk.store(etan) - chk.store(urn) - chk.store(hn) - chk.write_attribute("/", "time", t) - chk.write_attribute("/", "tdump", tdump) - chk.write_attribute("/", "tnorm", tnorm) + + #checkpointing + chk.store(un) + chk.store(etan) + chk.store(urn) + chk.store(hn) + chk.write_attribute("/", "time", t) + chk.write_attribute("/", "tdump", tdump) + chk.write_attribute("/", "tnorm", tnorm) if rank == 0: chk.close() From f09d6f456473522eb476c7e085076b51fc0e647c Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Sat, 17 Apr 2021 02:06:26 +0100 Subject: [PATCH 27/46] fix checkpointing --- averaged_sw_diff.py | 78 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 18 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 2afdc1e..e0bf77c 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -133,6 +133,15 @@ t = chkfile.read_attribute("/", "time") tdump = chkfile.read_attribute("/", "tdump") tnorm = chkfile.read_attribute("/", "tnorm") + eta_norm_ar = chkfile.read_attribute("/", "eta_norm") + u_norm_Hdiv_ar = chkfile.read_attribute("/", "u_norm_Hdiv") + u_norm_L2_ar = chkfile.read_attribute("/", "u_norm_L2") + eta_norm = eta_norm_ar.tolist() + u_norm_Hdiv = u_norm_Hdiv_ar.tolist() + u_norm_L2 = u_norm_L2_ar.tolist() + print("eta_norm = ", eta_norm) + print("u_norm_Hdiv = ", u_norm_Hdiv) + print("u_norm_L2 = ", u_norm_L2) else: un = Function(V1, name="Velocity").project(u_expr) etan = Function(V2, name="Elevation").interpolate(eta_expr) @@ -322,22 +331,25 @@ print(wt, "weight", expt) print("svals", svals) -eta_norm = [] -u_norm_Hdiv = [] -u_norm_L2 = [] +etanorm = 0. +unorm_Hdiv = 0. +unorm_L2 = 0. if rank==0: #calculate norms at the initial state etanorm = errornorm(etan, eta_out)/norm(eta_out) unorm_Hdiv = errornorm(un, u_out, norm_type="Hdiv")/norm(u_out, norm_type="Hdiv") unorm_L2 = errornorm(un, u_out)/norm(u_out) print('etanorm', etanorm, 'unorm_Hdiv', unorm_Hdiv, 'unorm_L2', unorm_L2) - print('etanorm =', eta_norm) - print('unorm_Hdiv =', u_norm_Hdiv) - print('unorm_L2 =', u_norm_L2) if not args.pickup: + eta_norm = [] + u_norm_Hdiv = [] + u_norm_L2 = [] eta_norm.append(etanorm) u_norm_Hdiv.append(unorm_Hdiv) u_norm_L2.append(unorm_L2) + print('etanorm =', eta_norm) + print('unorm_Hdiv =', u_norm_Hdiv) + print('unorm_L2 =', u_norm_L2) #setup PV solver PV = Function(Vf, name="PotentialVorticity") @@ -360,9 +372,9 @@ #write out initial fields mesh_ll = get_latlon_mesh(mesh) - file_sw = File(filename+'_avg.pvd', comm=ensemble.comm) - file_r = File(filename+'_serial.pvd', comm=ensemble.comm) - file_d = File(filename+'_diff.pvd', comm=ensemble.comm) + file_sw = File(filename+'_avg.pvd', comm=ensemble.comm, mode="a") + file_r = File(filename+'_serial.pvd', comm=ensemble.comm, mode="a") + file_d = File(filename+'_diff.pvd', comm=ensemble.comm, mode="a") field_un = Function( functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), val=un.topological) @@ -404,7 +416,7 @@ #start time loop print('tmax', tmax, 'dt', dt) -while t < tmax + 0.5*dt: +while t < tmax - 0.5*dt: print(t) t += dt tdump += dt @@ -458,14 +470,6 @@ hn.assign(hp) #dumping - if tnorm > normt - dt*0.5: - eta_norm.append(etanorm) - u_norm_Hdiv.append(unorm_Hdiv) - u_norm_L2.append(unorm_L2) - print('etanorm =', eta_norm) - print('unorm_Hdiv =', u_norm_Hdiv) - print('unorm_L2 =', u_norm_L2) - tnorm -= normt if tdump > dumpt - dt*0.5: #dump averaged results un.assign(U_u) @@ -491,6 +495,31 @@ print("dumped at t =", t) tdump -= dumpt + if tnorm > normt - dt*0.5: + eta_norm.append(etanorm) + u_norm_Hdiv.append(unorm_Hdiv) + u_norm_L2.append(unorm_L2) + print('etanorm =', eta_norm) + print('unorm_Hdiv =', u_norm_Hdiv) + print('unorm_L2 =', u_norm_L2) + tnorm -= normt + + elif tnorm > normt - dt*0.5: + un.assign(U_u) + etan.assign(U_eta) + u_out.assign(urn) + eta_out.assign(hn + b - H) + etanorm = errornorm(etan, eta_out)/norm(eta_out) + unorm_Hdiv = errornorm(un, u_out, norm_type="Hdiv")/norm(u_out, norm_type="Hdiv") + unorm_L2 = errornorm(un, u_out)/norm(u_out) + eta_norm.append(etanorm) + u_norm_Hdiv.append(unorm_Hdiv) + u_norm_L2.append(unorm_L2) + print('etanorm =', eta_norm) + print('unorm_Hdiv =', u_norm_Hdiv) + print('unorm_L2 =', u_norm_L2) + tnorm -= normt + #checkpointing chk.store(un) chk.store(etan) @@ -499,6 +528,9 @@ chk.write_attribute("/", "time", t) chk.write_attribute("/", "tdump", tdump) chk.write_attribute("/", "tnorm", tnorm) + chk.write_attribute("/", "eta_norm", eta_norm) + chk.write_attribute("/", "u_norm_Hdiv", u_norm_Hdiv) + chk.write_attribute("/", "u_norm_L2", u_norm_L2) if rank == 0: chk.close() @@ -517,11 +549,21 @@ t = chkfile.read_attribute("/", "time") tdump = chkfile.read_attribute("/", "tdump") tnorm = chkfile.read_attribute("/", "tnorm") + eta_norm = chkfile.read_attribute("/", "eta_norm") + u_norm_Hdiv = chkfile.read_attribute("/", "u_norm_Hdiv") + u_norm_L2 = chkfile.read_attribute("/", "u_norm_L2") valf = assemble(etan*dx) valg = assemble(etand*dx) valh = assemble(hn*dx) vald = assemble(hnd*dx) + print("t = ", t) + print("tdump = ", tdump) + print("tnorm = ", tnorm) + print("eta_norm = ", eta_norm) + print("u_norm_Hdiv = ", u_norm_Hdiv) + print("u_norm_L2 = ", u_norm_L2) + print("valf = ", valf) print("valg = ", valg) assert(valf == valg) From 38c6c5c08b9e2e84185d5d30a5216f773ba75b79 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Sun, 18 Apr 2021 14:17:23 +0100 Subject: [PATCH 28/46] dumbcheckpoint now working --- averaged_sw_diff.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index e0bf77c..b02c30a 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -26,7 +26,6 @@ parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') parser.add_argument('--filename', type=str, default='control') parser.add_argument('--pickup', action='store_true', help='Pickup the result from the checkpoint.') -parser.add_argument('--pickupfrom', type=str, default='chkpt') args = parser.parse_known_args() args = args[0] filter = args.filter @@ -121,7 +120,7 @@ #pickup the result if args.pickup: - chkfile = DumbCheckpoint(args.pickupfrom, mode=FILE_READ, comm = ensemble.comm) + chkfile = DumbCheckpoint(filename, mode=FILE_READ, comm = ensemble.comm) un = Function(V1, name="Velocity") etan = Function(V2, name="Elevation") urn = Function(V1, name="VelocityR") From 801a7d385fc1f70f3f6ee15e056388daf39dcb5f Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Fri, 7 May 2021 09:54:30 +0000 Subject: [PATCH 29/46] activate space parallelisation --- averaged_sw_diff.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index b02c30a..6a7d91e 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -11,6 +11,7 @@ #get command arguments parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') +parser.add_argument('--space_parallel', type=int, default=1, help='Default 1.') parser.add_argument('--tmax', type=float, default=1200, help='Final time in hours. Default 24x50=1200.') parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') parser.add_argument('--dt', type=float, default=1, help='Timestep in hours. Default 1.') @@ -36,6 +37,7 @@ asselin = args.asselin ref_level = args.ref_level filename = args.filename +space_parallel = args.space_parallel print(args) if filter_freq and filter: @@ -43,7 +45,7 @@ import sys; sys.exit() #ensemble communicator -ensemble = Ensemble(COMM_WORLD, 1) +ensemble = Ensemble(COMM_WORLD, space_parallel) #parameters R0 = 6371220. @@ -113,7 +115,7 @@ #print out settings print = PETSc.Sys.Print -assert Mbar==COMM_WORLD.size, str(Mbar)+' '+str(COMM_WORLD.size) +assert Mbar*space_parallel==COMM_WORLD.size, str(Mbar)+' '+str(COMM_WORLD.size) print('averaging window', rho*dt, 'sample width', rho*dt/Mbar) print('Mbar', Mbar, 'samples per min time period', min_time_period/(rho*dt/Mbar)) print(args) @@ -141,6 +143,7 @@ print("eta_norm = ", eta_norm) print("u_norm_Hdiv = ", u_norm_Hdiv) print("u_norm_L2 = ", u_norm_L2) + chkfile.close() else: un = Function(V1, name="Velocity").project(u_expr) etan = Function(V2, name="Elevation").interpolate(eta_expr) @@ -563,6 +566,13 @@ print("u_norm_Hdiv = ", u_norm_Hdiv) print("u_norm_L2 = ", u_norm_L2) + ud_out = Function(V1).assign(urnd) + etad_out = Function(V2).assign(hnd + b - H) + etanorm = errornorm(etand, etad_out)/norm(etad_out) + unorm_Hdiv = errornorm(und, ud_out, norm_type="Hdiv")/norm(ud_out, norm_type="Hdiv") + unorm_L2 = errornorm(und, ud_out)/norm(ud_out) + print('etanorm', etanorm, 'unorm_Hdiv', unorm_Hdiv, 'unorm_L2', unorm_L2) + print("valf = ", valf) print("valg = ", valg) assert(valf == valg) From 0b22f7b60e028c1ac68f56852220e139b22380da Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Fri, 7 May 2021 09:55:12 +0000 Subject: [PATCH 30/46] removed 1 cheby for faster calculation --- timestepping_methods.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/timestepping_methods.py b/timestepping_methods.py index fb04f92..4449447 100644 --- a/timestepping_methods.py +++ b/timestepping_methods.py @@ -61,8 +61,8 @@ def rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V1, V2, V3, V, W, U3.assign(V + V3) #Average the nonlinearity - cheby2.apply(V2, U1, dt/2) - cheby2.apply(V3, U2, dt/2) + U1.assign(V2 + V3) + cheby2.apply(U1, U2, dt/2) cheby2.apply(U3, DU, dt/2) cheby.apply(DU, USlow_in, expt) @@ -71,10 +71,10 @@ def rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, V1, V2, V3, V, W, DU *= wt ensemble.allreduce(DU, U3) - cheby2.apply(V1, DU, dt) + cheby2.apply(V1, U1, dt) cheby2.apply(U, V, dt) - U.assign(V + 1/6*DU + 1/3*U1 + 1/3*U2 + 1/6*U3) + U.assign(V + 1/6*U1 + 1/3*U2 + 1/6*U3) def heuns(U, USlow_in, USlow_out, DU, U1, U2, W, From 5af64c80cacb43c0758c7f8d8ba25f6782fb7bb5 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Sun, 9 May 2021 00:52:27 +0100 Subject: [PATCH 31/46] added normt into arguments --- averaged_sw_diff.py | 45 ++++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index 6a7d91e..c4d578c 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -14,6 +14,7 @@ parser.add_argument('--space_parallel', type=int, default=1, help='Default 1.') parser.add_argument('--tmax', type=float, default=1200, help='Final time in hours. Default 24x50=1200.') parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') +parser.add_argument('--normt', type=float, default=24, help='Collect norms every normt (in hours). Default 24.') parser.add_argument('--dt', type=float, default=1, help='Timestep in hours. Default 1.') parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') @@ -109,7 +110,7 @@ t = 0. tmax = 60.*60.*args.tmax dumpt = args.dumpt*60.*60. -normt = 24.*60.*60. +normt = args.normt*60.*60. tdump = 0. tnorm = 0. @@ -471,16 +472,22 @@ urn.assign(up) hn.assign(hp) - #dumping + #calculate norms + un.assign(U_u) + etan.assign(U_eta) + u_out.assign(urn) + eta_out.assign(hn + b - H) + etanorm = errornorm(etan, eta_out)/norm(eta_out) + unorm_Hdiv = errornorm(un, u_out, norm_type="Hdiv")/norm(u_out, norm_type="Hdiv") + unorm_L2 = errornorm(un, u_out)/norm(u_out) + print('etanorm', etanorm, 'unorm_Hdiv', unorm_Hdiv, 'unorm_L2', unorm_L2) + + #dumping results if tdump > dumpt - dt*0.5: #dump averaged results - un.assign(U_u) - etan.assign(U_eta) PVsolver.solve() file_sw.write(field_un, field_etan, field_PV, field_b) #dump non averaged results - u_out.assign(urn) - eta_out.assign(hn + b - H) PVoutsolver.solve() file_r.write(field_uout, field_etaout, field_PVout, field_b) #dump differences @@ -488,32 +495,12 @@ eta_diff.assign(etan - eta_out) PVdiff.assign(PV- PVout) file_d.write(field_udiff, field_etadiff, field_PVdiff, field_b) - #calculate norms - etanorm = errornorm(etan, eta_out)/norm(eta_out) - unorm_Hdiv = errornorm(un, u_out, norm_type="Hdiv")/norm(u_out, norm_type="Hdiv") - unorm_L2 = errornorm(un, u_out)/norm(u_out) - print('etanorm', etanorm, 'unorm_Hdiv', unorm_Hdiv, 'unorm_L2', unorm_L2) #update dumpt print("dumped at t =", t) tdump -= dumpt - if tnorm > normt - dt*0.5: - eta_norm.append(etanorm) - u_norm_Hdiv.append(unorm_Hdiv) - u_norm_L2.append(unorm_L2) - print('etanorm =', eta_norm) - print('unorm_Hdiv =', u_norm_Hdiv) - print('unorm_L2 =', u_norm_L2) - tnorm -= normt - - elif tnorm > normt - dt*0.5: - un.assign(U_u) - etan.assign(U_eta) - u_out.assign(urn) - eta_out.assign(hn + b - H) - etanorm = errornorm(etan, eta_out)/norm(eta_out) - unorm_Hdiv = errornorm(un, u_out, norm_type="Hdiv")/norm(u_out, norm_type="Hdiv") - unorm_L2 = errornorm(un, u_out)/norm(u_out) + #append norms to array every normt + if tnorm > normt - dt*0.5: eta_norm.append(etanorm) u_norm_Hdiv.append(unorm_Hdiv) u_norm_L2.append(unorm_L2) @@ -522,7 +509,7 @@ print('unorm_L2 =', u_norm_L2) tnorm -= normt - #checkpointing + #checkpointing every time step chk.store(un) chk.store(etan) chk.store(urn) From e945d782cbad2294a1d50e074ce16e3ff8c12ec3 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Mon, 17 May 2021 11:18:14 +0100 Subject: [PATCH 32/46] made dts a variable and set the default value to 90s --- averaged_sw_diff.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index c4d578c..a7189a6 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -15,7 +15,8 @@ parser.add_argument('--tmax', type=float, default=1200, help='Final time in hours. Default 24x50=1200.') parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') parser.add_argument('--normt', type=float, default=24, help='Collect norms every normt (in hours). Default 24.') -parser.add_argument('--dt', type=float, default=1, help='Timestep in hours. Default 1.') +parser.add_argument('--dt', type=float, default=1, help='Timestep for the averaged model in hours. Default 1.') +parser.add_argument('--dts', type=float, default=0.025, help='Timestep for the standard model in hours. Default 0.025.') parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') @@ -90,6 +91,7 @@ min_time_period = 2*pi/eigs[ref_level-3] hours = args.dt dt = 60*60*hours +dts = 60*60*args.dts rho = args.rho #averaging window is rho*dt L = eigs[ref_level-3]*dt*rho ppp = args.ppp #points per (minimum) time period @@ -236,7 +238,6 @@ ############################################################################## # Set up depth advection solver (DG upwinded scheme) ############################################################################## -dts = 180 up = Function(V1) hp = Function(V2) hps = Function(V2) @@ -418,7 +419,7 @@ chk = DumbCheckpoint(filename, mode=FILE_CREATE, comm = ensemble.comm) #start time loop -print('tmax', tmax, 'dt', dt) +print('tmax', tmax, 'dt', dt, 'dts', dts) while t < tmax - 0.5*dt: print(t) t += dt From 52ce35852f1a80b084ed3c41901c1e108ffdb3e3 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 19 May 2021 11:22:26 +0000 Subject: [PATCH 33/46] checkpoint only at the end of the program --- averaged_sw_diff.py | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/averaged_sw_diff.py b/averaged_sw_diff.py index a7189a6..26cd049 100644 --- a/averaged_sw_diff.py +++ b/averaged_sw_diff.py @@ -10,13 +10,13 @@ #get command arguments parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') -parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') -parser.add_argument('--space_parallel', type=int, default=1, help='Default 1.') +parser.add_argument('--ref_level', type=int, default=4, help='Refinement level of icosahedral grid. Default 4.') +parser.add_argument('--space_parallel', type=int, default=4, help='Default 4.') parser.add_argument('--tmax', type=float, default=1200, help='Final time in hours. Default 24x50=1200.') parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') -parser.add_argument('--normt', type=float, default=24, help='Collect norms every normt (in hours). Default 24.') -parser.add_argument('--dt', type=float, default=1, help='Timestep for the averaged model in hours. Default 1.') -parser.add_argument('--dts', type=float, default=0.025, help='Timestep for the standard model in hours. Default 0.025.') +parser.add_argument('--normt', type=float, default=6, help='Collect norms every normt (in hours). Default 6.') +parser.add_argument('--dt', type=float, default=0.5, help='Timestep for the averaged model in hours. Default 0.5.') +parser.add_argument('--dts', type=float, default=0.0125, help='Timestep for the standard model in hours. Default 0.0125.') parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') @@ -24,7 +24,7 @@ parser.add_argument('--filter2', action='store_true', help='Use a filter for cheby2') parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') parser.add_argument('--filter_freq', action='store_true', help='Cut-off frequency for filter') -parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') +parser.add_argument('--ppp', type=float, default=4, help='Points per time-period for averaging.') parser.add_argument('--timestepping', type=str, default='rk4', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') parser.add_argument('--filename', type=str, default='control') @@ -510,19 +510,18 @@ print('unorm_L2 =', u_norm_L2) tnorm -= normt - #checkpointing every time step - chk.store(un) - chk.store(etan) - chk.store(urn) - chk.store(hn) - chk.write_attribute("/", "time", t) - chk.write_attribute("/", "tdump", tdump) - chk.write_attribute("/", "tnorm", tnorm) - chk.write_attribute("/", "eta_norm", eta_norm) - chk.write_attribute("/", "u_norm_Hdiv", u_norm_Hdiv) - chk.write_attribute("/", "u_norm_L2", u_norm_L2) - if rank == 0: + #checkpointing every time step + chk.store(un) + chk.store(etan) + chk.store(urn) + chk.store(hn) + chk.write_attribute("/", "time", t) + chk.write_attribute("/", "tdump", tdump) + chk.write_attribute("/", "tnorm", tnorm) + chk.write_attribute("/", "eta_norm", eta_norm) + chk.write_attribute("/", "u_norm_Hdiv", u_norm_Hdiv) + chk.write_attribute("/", "u_norm_L2", u_norm_L2) chk.close() #check if dumbcheckpoint is working From e0587fc3e70638377ee05c4076580d452de0c48d Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 26 May 2021 22:39:10 +0100 Subject: [PATCH 34/46] Code to calculate just the averaged solution --- averaged_sw_explicit.py | 189 +++++++++++++++++++++++----------------- 1 file changed, 109 insertions(+), 80 deletions(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index d11f623..b75cd14 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -4,39 +4,41 @@ from math import pi from math import ceil from timestepping_methods import * +from latlon import * import numpy as np import argparse #get command arguments parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') -parser.add_argument('--ref_level', type=int, default=3, help='Refinement level of icosahedral grid. Default 3.') -parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') -parser.add_argument('--dumpt', type=float, default=6, help='Dump time in hours. Default 6.') -parser.add_argument('--dt', type=float, default=2, help='Timestep in hours. Default 2.') +parser.add_argument('--ref_level', type=int, default=4, help='Refinement level of icosahedral grid. Default 4.') +parser.add_argument('--space_parallel', type=int, default=4, help='Default 4.') +parser.add_argument('--tmax', type=float, default=1200, help='Final time in hours. Default 24x50=1200.') +parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') +parser.add_argument('--checkt', type=float, default=6, help='Create checkpointing file every checkt hours. Default 6.') +parser.add_argument('--dt', type=float, default=0.5, help='Timestep for the averaged model in hours. Default 0.5.') parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') -parser.add_argument('--linear', action='store_false', dest='nonlinear', help='Run linear model if present, otherwise run nonlinear model') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') -parser.add_argument('--filter', type=bool, default=True, help='Use a filter in the averaging exponential') -parser.add_argument('--filter2', type=bool, default=False, help='Use a filter for cheby2') -parser.add_argument('--filter_val', type=float, default=0.75, help='Cut-off for filter') -parser.add_argument('--ppp', type=float, default=3, help='Points per time-period for averaging.') -parser.add_argument('--timestepping', type=str, default='ssprk3', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default SSPRK3.') -parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient. Default 0.3.') -parser.add_argument('--filename', type=str, default='explicit') +parser.add_argument('--ppp', type=float, default=4, help='Points per time-period for averaging.') +parser.add_argument('--timestepping', type=str, default='rk4', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default rk4.') +parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient for leapfrog. Default 0.3.') +parser.add_argument('--filename', type=str, default='control') +parser.add_argument('--pickup', action='store_true', help='Pickup the result from the checkpoint.') +parser.add_argument('--pickup_from', type=str, default='standard') args = parser.parse_known_args() args = args[0] -filter = args.filter -filter2 = args.filter2 -filter_val = args.filter_val timestepping = args.timestepping asselin = args.asselin ref_level = args.ref_level +filename = args.filename +space_parallel = args.space_parallel +print(args) #ensemble communicator -ensemble = Ensemble(COMM_WORLD, 1) +ensemble = Ensemble(COMM_WORLD, space_parallel) #parameters R0 = 6371220. +R = Constant(R0) H = Constant(5960.) Omega = Constant(7.292e-5) # rotation rate g = Constant(9.8) # Gravitational constant @@ -51,13 +53,13 @@ V1 = FunctionSpace(mesh, "BDM", 2) V2 = FunctionSpace(mesh, "DG", 1) W = MixedFunctionSpace((V1, V2)) -f = 2*Omega*x[2]/Constant(R0) # Coriolis parameter +f_expr = 2 * Omega * x[2] / R +Vf = FunctionSpace(mesh, "CG", 3) +f = Function(Vf).interpolate(f_expr) # Coriolis frequency u_0 = 20.0 # maximum amplitude of the zonal wind [m/s] u_max = Constant(u_0) -u_expr = as_vector([-u_max*x[1]/R0, u_max*x[0]/R0, 0.0]) -eta_expr = - ((R0 * Omega * u_max + u_max*u_max/2.0)*(x[2]*x[2]/(R0*R0)))/g -un = Function(V1, name="Velocity").project(u_expr) -etan = Function(V2, name="Elevation").project(eta_expr) +u_expr = as_vector([-u_max*x[1]/R, u_max*x[0]/R, 0.0]) +eta_expr = -((R*Omega*u_max+u_max*u_max/2.0)*(x[2]*x[2]/(R*R)))/g #topography (D = H + eta - b) rl = pi/9.0 @@ -70,53 +72,98 @@ b = Function(V2, name="Topography") b.interpolate(bexpr) -#set Mbar +#checking cheby parameters based on ref_level eigs = [0.003465, 0.007274, 0.014955] #maximum frequency min_time_period = 2*pi/eigs[ref_level-3] hours = args.dt dt = 60*60*hours +dts = args.dts rho = args.rho #averaging window is rho*dt L = eigs[ref_level-3]*dt*rho ppp = args.ppp #points per (minimum) time period #rho*dt/min_time_period = number of min_time_periods that fit in rho*dt - #we want at least ppp times this number of sample points + # we want at least ppp times this number of sample points Mbar = ceil(ppp*rho*dt*eigs[ref_level-3]/2/pi) -print(args) if args.get_Mbar: print("Mbar="+str(Mbar)) import sys; sys.exit() -#set svals svals = np.arange(0.5, Mbar)/Mbar #tvals goes from -rho*dt/2 to rho*dt/2 weights = np.exp(-1.0/svals/(1.0-svals)) weights = weights/np.sum(weights) print(weights) svals -= 0.5 -#set weights -rank = ensemble.ensemble_comm.rank -expt = rho*dt*svals[rank] -wt = weights[rank] -print(wt,"weight",expt) - #parameters for timestepping t = 0. tmax = 60.*60.*args.tmax dumpt = args.dumpt*60.*60. +checkt = args.checkt*60.*60. tdump = 0. +tcheck = 0. -#dump settings +#print out settings print = PETSc.Sys.Print -assert Mbar==COMM_WORLD.size, str(Mbar)+' '+str(COMM_WORLD.size) +assert Mbar*space_parallel==COMM_WORLD.size, str(Mbar)+' '+str(COMM_WORLD.size) print('averaging window', rho*dt, 'sample width', rho*dt/Mbar) print('Mbar', Mbar, 'samples per min time period', min_time_period/(rho*dt/Mbar)) +print(args) + +#pickup the result +if args.pickup: + chkfile = DumbCheckpoint(args.pickup_from, mode=FILE_READ, comm = ensemble.comm) + un = Function(V1, name="Velocity") + etan = Function(V2, name="Elevation") + chkfile.load(un, name="Velocity") + chkfile.load(etan, name="Elevation") + t = chkfile.read_attribute("/", "time") + tdump = chkfile.read_attribute("/", "tdump") + tcheck = chkfile.read_attribute("/", "tcheck") + chkfile.close() +else: + un = Function(V1, name="Velocity").project(u_expr) + etan = Function(V2, name="Elevation").interpolate(eta_expr) +#set weights +rank = ensemble.ensemble_comm.rank +expt = rho*dt*svals[rank] +wt = weights[rank] +print(wt, "weight", expt) +print("svals", svals) + +if rank==0: + #setup PV solver + PV = Function(Vf, name="PotentialVorticity") + gamma = TestFunction(Vf) + q = TrialFunction(Vf) + D = etan + H - b + a = q*gamma*D*dx + L = (- inner(perp(grad(gamma)), un))*dx + gamma*f*dx + PVproblem = LinearVariationalProblem(a, L, PV) + PVsolver = LinearVariationalSolver(PVproblem, solver_parameters={"ksp_type": "cg"}) + PVsolver.solve() + + #write out initial fields + mesh_ll = get_latlon_mesh(mesh) + file_sw = File(filename+'_avg.pvd', comm=ensemble.comm, mode="a") + field_un = Function( + functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), + val=un.topological) + field_etan = Function( + functionspaceimpl.WithGeometry(etan.function_space(), mesh_ll), + val=etan.topological) + field_PV = Function( + functionspaceimpl.WithGeometry(PV.function_space(), mesh_ll), + val=PV.topological) + field_b = Function( + functionspaceimpl.WithGeometry(b.function_space(), mesh_ll), + val=b.topological) + if not args.pickup: + file_sw.write(field_un, field_etan, field_PV, field_b) ############################################################################## # Set up the exponential operator ############################################################################## - -#apply the exponential of an operator using chebyshev approximation operator_in = Function(W) u_in, eta_in = split(operator_in) u, eta = TrialFunctions(W) @@ -149,12 +196,11 @@ ncheb = 10000 cheby = cheby_exp(OperatorSolver, operator_in, operator_out, - ncheb, tol=1.0e-8, L=L, filter=filter, filter_val=filter_val) + ncheb, tol=1.0e-8, L=L, filter=filter, filter_val=filter_val, filter_freq=filter_freq) cheby2 = cheby_exp(OperatorSolver, operator_in, operator_out, ncheb, tol=1.0e-8, L=L, filter=filter2, filter_val=filter_val) - ############################################################################## # Set up solvers for the slow part ############################################################################## @@ -196,7 +242,6 @@ SlowSolver = LinearVariationalSolver(SlowProb, solver_parameters = params) - ############################################################################## # Time loop ############################################################################## @@ -205,27 +250,22 @@ U1 = Function(W) U2 = Function(W) U3 = Function(W) -W1 = Function(W) -W2 = Function(W) -W3 = Function(W) +X1 = Function(W) +X2 = Function(W) +X3 = Function(W) V = Function(W) U_u, U_eta = U.split() U_u.assign(un) U_eta.assign(etan) -#write out initial fields -name = args.filename -if rank==0: - file_sw = File(name+'.pvd', comm=ensemble.comm) - file_sw.write(un, etan, b) - #start time loop -print ('tmax', tmax, 'dt', dt) -while t < tmax + 0.5*dt: +print('tmax', tmax, 'dt', dt) +while t < tmax - 0.5*dt: print(t) t += dt tdump += dt + tcheck += dt if t < dt*1.5 and timestepping == 'leapfrog': U_old = Function(W) @@ -244,44 +284,33 @@ rk2(U, USlow_in, USlow_out, DU, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) elif timestepping == 'rk4': - rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, W1, W2, W3, V, W, + rk4(U, USlow_in, USlow_out, DU, U1, U2, U3, X1, X2, X3, V, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) elif timestepping == 'heuns': heuns(U, USlow_in, USlow_out, DU, U1, U2, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) - #dump if rank == 0: + #dumping results if tdump > dumpt - dt*0.5: - un.assign(U_u) - etan.assign(U_eta) - file_sw.write(un, etan, b) + #dump averaged results + PVsolver.solve() + file_sw.write(field_un, field_etan, field_PV, field_b) + #update dumpt print("dumped at t =", t) tdump -= dumpt -#check if dumbcheckpoint is working -valf = assemble(etan*dx) - -print("create checkpointing file at rank =", rank) -chk = DumbCheckpoint("dump_explicit", mode=FILE_CREATE) -chk.store(un) -chk.store(etan) -chk.store(b) -chk.close() - -und = Function(V1) -etand = Function(V2) -bd = Function(V2) - -chk = DumbCheckpoint("dump_explicit", mode=FILE_READ) -chk.load(und, name="Velocity") -chk.load(etand, name="Elevation") -chk.load(bd, name="Topography") - -valg = assemble(etand*dx) - -print("valf = ", valf) -print("valg = ", valg) -assert(valf == valg) - -chk.close() + #create checkpointing file every tcheck hours + if tcheck > checkt - dt*0.5: + print("checkpointing at t =", t) + thours = int(t/3600) + chk = DumbCheckpoint(filename+"_"+str(thours)+"h", mode=FILE_CREATE) + chk.store(un) + chk.store(etan) + chk.write_attribute("/", "time", t) + chk.write_attribute("/", "tdump", tdump) + chk.write_attribute("/", "tcheck", tcheck) + chk.close() + tcheck -= checkt + +print("Completed calculation at t =", t) From c92e52aac92ee616382d96f01acb37d2e4267f0d Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 26 May 2021 23:49:45 +0100 Subject: [PATCH 35/46] non-averaged sw model for comparison --- standard_sw.py | 234 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 standard_sw.py diff --git a/standard_sw.py b/standard_sw.py new file mode 100644 index 0000000..a792198 --- /dev/null +++ b/standard_sw.py @@ -0,0 +1,234 @@ +from firedrake import * +from math import pi +from math import ceil +from latlon import * +import numpy as np +import argparse + +#get command arguments +parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') +parser.add_argument('--ref_level', type=int, default=4, help='Refinement level of icosahedral grid. Default 4.') +parser.add_argument('--tmax', type=float, default=120, help='Final time in hours. Default 24x5=120.') +parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') +parser.add_argument('--checkt', type=float, default=6, help='Create checkpointing file every checkt hours. Default 6.') +parser.add_argument('--dt', type=float, default=45, help='Timestep for the standard model in seconds. Default 45.') +parser.add_argument('--filename', type=str, default='standard') +parser.add_argument('--pickup', action='store_true', help='Pickup the result from the checkpoint.') +parser.add_argument('--pickup_from', type=str, default='standard') +args = parser.parse_known_args() +args = args[0] +ref_level = args.ref_level +filename = args.filename +dt = args.dt +print(args) + +#parameters +R0 = 6371220. +R = Constant(R0) +H = Constant(5960.) +Omega = Constant(7.292e-5) # rotation rate +g = Constant(9.8) # Gravitational constant +mesh = IcosahedralSphereMesh(radius=R0, + refinement_level=ref_level, degree=3) +x = SpatialCoordinate(mesh) +global_normal = as_vector([x[0], x[1], x[2]]) +mesh.init_cell_orientations(global_normal) +outward_normals = CellNormal(mesh) +perp = lambda u: cross(outward_normals, u) +V1 = FunctionSpace(mesh, "BDM", 2) +V2 = FunctionSpace(mesh, "DG", 1) +W = MixedFunctionSpace((V1, V2)) +f_expr = 2 * Omega * x[2] / R +Vf = FunctionSpace(mesh, "CG", 3) +f = Function(Vf).interpolate(f_expr) # Coriolis frequency +u_0 = 20.0 # maximum amplitude of the zonal wind [m/s] +u_max = Constant(u_0) +u_expr = as_vector([-u_max*x[1]/R, u_max*x[0]/R, 0.0]) +h_expr = H-((R*Omega*u_max+u_max*u_max/2.0)*(x[2]*x[2]/(R*R)))/g + +#topography (D = H + eta - b) +rl = pi/9.0 +lambda_x = atan_2(x[1]/R0, x[0]/R0) +lambda_c = -pi/2.0 +phi_x = asin(x[2]/R0) +phi_c = pi/6.0 +minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +bexpr = 2000.0*(1 - sqrt(minarg)/rl) +b = Function(V2, name="Topography") +b.interpolate(bexpr) + +#parameters for timestepping +t = 0. +tmax = 60.*60.*args.tmax +dumpt = args.dumpt*60.*60. +checkt = args.checkt*60.*60. +tdump = 0. +tcheck = 0. +k_max = 4 # Maximum number of Picard iterations + +#pickup the result +if args.pickup: + chkfile = DumbCheckpoint(args.pickup_from, mode=FILE_READ) + un = Function(V1, name="Velocity") + hn = Function(V2, name="Depth") + chkfile.load(un, name="Velocity") + chkfile.load(hn, name="Depth") + etan = Function(V2, name="Elevation").assign(hn + b - H) + t = chkfile.read_attribute("/", "time") + tdump = chkfile.read_attribute("/", "tdump") + tcheck = chkfile.read_attribute("/", "tcheck") + chkfile.close() +else: + un = Function(V1, name="Velocity").project(u_expr) + hn = Function(V2, name="Depth").interpolate(h_expr) + hn -= b + etan = Function(V2, name="Elevation").assign(hn + b - H) + +#setup PV solver +PV = Function(Vf, name="PotentialVorticity") +gamma = TestFunction(Vf) +q = TrialFunction(Vf) +D = hn +a = q*gamma*D*dx +L = (- inner(perp(grad(gamma)), un))*dx + gamma*f*dx +PVproblem = LinearVariationalProblem(a, L, PV) +PVsolver = LinearVariationalSolver(PVproblem, solver_parameters={"ksp_type": "cg"}) +PVsolver.solve() + +#write out initial fields +mesh_ll = get_latlon_mesh(mesh) +file_sw = File(filename+'_sw.pvd', mode="a") +field_un = Function( + functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), + val=un.topological) +field_etan = Function( + functionspaceimpl.WithGeometry(etan.function_space(), mesh_ll), + val=etan.topological) +field_PV = Function( + functionspaceimpl.WithGeometry(PV.function_space(), mesh_ll), + val=PV.topological) +field_b = Function( + functionspaceimpl.WithGeometry(b.function_space(), mesh_ll), + val=b.topological) +if not args.pickup: + file_sw.write(field_un, field_etan, field_PV, field_b) + +############################################################################## +# Set up solvers +############################################################################## +# Set up depth advection solver (DG upwinded scheme) +up = Function(V1) +hp = Function(V2) +hpt = Function(V2) +h = TrialFunction(V2) +phi = TestFunction(V2) +hh = 0.5 * (hn + h) +uh = 0.5 * (un + up) +n = FacetNormal(mesh) +uup = 0.5 * (dot(uh, n) + abs(dot(uh, n))) +Heqn = ((h - hn)*phi*dx - dt*inner(grad(phi), uh*hh)*dx + + dt*jump(phi)*(uup('+')*hh('+')-uup('-')*hh('-'))*dS) +Hproblem = LinearVariationalProblem(lhs(Heqn), rhs(Heqn), hpt) +lu_params = {'ksp_type': 'preonly', + 'pc_type': 'lu', + 'pc_factor_mat_solver_type': 'mumps'} +Hsolver = LinearVariationalSolver(Hproblem, + solver_parameters=lu_params, + options_prefix="H-advection") + +# Velocity advection (Natale et. al (2016) extended to SWE) +upt = Function(V1) +u = TrialFunction(V1) +v = TestFunction(V1) +hh = 0.5 * (hn + hp) +ubar = 0.5 * (un + up) +uup = 0.5 * (dot(ubar, n) + abs(dot(ubar, n))) +uh = 0.5 * (un + u) +Upwind = 0.5 * (sign(dot(ubar, n)) + 1) +K = 0.5 * (inner(0.5 * (un + up), 0.5 * (un + up))) +both = lambda u: 2*avg(u) +outward_normals = CellNormal(mesh) +perp = lambda arg: cross(outward_normals, arg) +Ueqn = (inner(u - un, v)*dx + dt*inner(perp(uh)*f, v)*dx + - dt*inner(perp(grad(inner(v, perp(ubar)))), uh)*dx + + dt*inner(both(perp(n)*inner(v, perp(ubar))), + both(Upwind*uh))*dS + - dt*div(v)*(g*(hh + b) + K)*dx) +Uproblem = LinearVariationalProblem(lhs(Ueqn), rhs(Ueqn), upt) +Usolver = LinearVariationalSolver(Uproblem, + solver_parameters=lu_params, + options_prefix="U-advection") + +# Linear solver for incremental updates +HU = Function(W) +deltaU, deltaH = HU.split() +w, phi = TestFunctions(W) +du, dh = TrialFunctions(W) +alpha = 0.5 +HUlhs = (inner(w, du + alpha*dt*f*perp(du))*dx + - alpha*dt*div(w)*g*dh*dx + + phi*(dh + alpha*dt*H*div(du))*dx) +HUrhs = -inner(w, up - upt)*dx - phi*(hp - hpt)*dx +HUproblem = LinearVariationalProblem(HUlhs, HUrhs, HU) +params = {'ksp_type': 'preonly', + 'mat_type': 'aij', + 'pc_type': 'lu', + 'pc_factor_mat_solver_type': 'mumps'} +HUsolver = LinearVariationalSolver(HUproblem, + solver_parameters=params, + options_prefix="impl-solve") + +############################################################################## +# Time loop +############################################################################## +#start time loop +print('tmax', tmax, 'dt', dt) +while t < tmax - 0.5*dt: + print(t) + t += dt + tdump += dt + tcheck += dt + + up.assign(un) + hp.assign(hn) + + #start picard cycle + for i in range(k_max): + #advect to get candidates + Hsolver.solve() + Usolver.solve() + + #linear solve for updates + HUsolver.solve() + + #increment updates + up += deltaU + hp += deltaH + + #update fields for next time step + un.assign(up) + hn.assign(hp) + + #dumping results + if tdump > dumpt - dt*0.5: + #dump results + PVsolver.solve() + file_sw.write(field_un, field_etan, field_PV, field_b) + #update dumpt + print("dumped at t =", t) + tdump -= dumpt + + #create checkpointing file every tcheck hours + if tcheck > checkt - dt*0.5: + print("checkpointing at t =", t) + thours = int(t/3600) + chk = DumbCheckpoint(filename+"_"+str(thours)+"h", mode=FILE_CREATE) + chk.store(un) + chk.store(hn) + chk.write_attribute("/", "time", t) + chk.write_attribute("/", "tdump", tdump) + chk.write_attribute("/", "tcheck", tcheck) + chk.close() + tcheck -= checkt + +print("Completed calculation at t =", t) From 7b50ff6016c7ea601fef7a21cdf752858e52fa6a Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Thu, 27 May 2021 00:09:17 +0100 Subject: [PATCH 36/46] fixed some bugs --- averaged_sw_explicit.py | 79 ++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index b75cd14..c9ecbeb 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -77,7 +77,6 @@ min_time_period = 2*pi/eigs[ref_level-3] hours = args.dt dt = 60*60*hours -dts = args.dts rho = args.rho #averaging window is rho*dt L = eigs[ref_level-3]*dt*rho ppp = args.ppp #points per (minimum) time period @@ -124,43 +123,6 @@ un = Function(V1, name="Velocity").project(u_expr) etan = Function(V2, name="Elevation").interpolate(eta_expr) -#set weights -rank = ensemble.ensemble_comm.rank -expt = rho*dt*svals[rank] -wt = weights[rank] -print(wt, "weight", expt) -print("svals", svals) - -if rank==0: - #setup PV solver - PV = Function(Vf, name="PotentialVorticity") - gamma = TestFunction(Vf) - q = TrialFunction(Vf) - D = etan + H - b - a = q*gamma*D*dx - L = (- inner(perp(grad(gamma)), un))*dx + gamma*f*dx - PVproblem = LinearVariationalProblem(a, L, PV) - PVsolver = LinearVariationalSolver(PVproblem, solver_parameters={"ksp_type": "cg"}) - PVsolver.solve() - - #write out initial fields - mesh_ll = get_latlon_mesh(mesh) - file_sw = File(filename+'_avg.pvd', comm=ensemble.comm, mode="a") - field_un = Function( - functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), - val=un.topological) - field_etan = Function( - functionspaceimpl.WithGeometry(etan.function_space(), mesh_ll), - val=etan.topological) - field_PV = Function( - functionspaceimpl.WithGeometry(PV.function_space(), mesh_ll), - val=PV.topological) - field_b = Function( - functionspaceimpl.WithGeometry(b.function_space(), mesh_ll), - val=b.topological) - if not args.pickup: - file_sw.write(field_un, field_etan, field_PV, field_b) - ############################################################################## # Set up the exponential operator ############################################################################## @@ -196,10 +158,10 @@ ncheb = 10000 cheby = cheby_exp(OperatorSolver, operator_in, operator_out, - ncheb, tol=1.0e-8, L=L, filter=filter, filter_val=filter_val, filter_freq=filter_freq) + ncheb, tol=1.0e-8, L=L) cheby2 = cheby_exp(OperatorSolver, operator_in, operator_out, - ncheb, tol=1.0e-8, L=L, filter=filter2, filter_val=filter_val) + ncheb, tol=1.0e-8, L=L) ############################################################################## # Set up solvers for the slow part @@ -259,6 +221,43 @@ U_u.assign(un) U_eta.assign(etan) +#set weights +rank = ensemble.ensemble_comm.rank +expt = rho*dt*svals[rank] +wt = weights[rank] +print(wt, "weight", expt) +print("svals", svals) + +if rank==0: + #setup PV solver + PV = Function(Vf, name="PotentialVorticity") + gamma = TestFunction(Vf) + q = TrialFunction(Vf) + D = etan + H - b + a = q*gamma*D*dx + L = (- inner(perp(grad(gamma)), un))*dx + gamma*f*dx + PVproblem = LinearVariationalProblem(a, L, PV) + PVsolver = LinearVariationalSolver(PVproblem, solver_parameters={"ksp_type": "cg"}) + PVsolver.solve() + + #write out initial fields + mesh_ll = get_latlon_mesh(mesh) + file_sw = File(filename+'_avg.pvd', comm=ensemble.comm, mode="a") + field_un = Function( + functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), + val=un.topological) + field_etan = Function( + functionspaceimpl.WithGeometry(etan.function_space(), mesh_ll), + val=etan.topological) + field_PV = Function( + functionspaceimpl.WithGeometry(PV.function_space(), mesh_ll), + val=PV.topological) + field_b = Function( + functionspaceimpl.WithGeometry(b.function_space(), mesh_ll), + val=b.topological) + if not args.pickup: + file_sw.write(field_un, field_etan, field_PV, field_b) + #start time loop print('tmax', tmax, 'dt', dt) while t < tmax - 0.5*dt: From 7ae99b9ee6d5e3312e581b63ef87a9301855fe23 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Wed, 9 Jun 2021 23:29:59 +0100 Subject: [PATCH 37/46] stand alone codes are ready to go --- averaged_sw_explicit.py | 34 +++++++++++++++++++++++++--------- standard_sw.py | 30 +++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index c9ecbeb..3e5aca9 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -12,7 +12,7 @@ parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') parser.add_argument('--ref_level', type=int, default=4, help='Refinement level of icosahedral grid. Default 4.') parser.add_argument('--space_parallel', type=int, default=4, help='Default 4.') -parser.add_argument('--tmax', type=float, default=1200, help='Final time in hours. Default 24x50=1200.') +parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') parser.add_argument('--checkt', type=float, default=6, help='Create checkpointing file every checkt hours. Default 6.') parser.add_argument('--dt', type=float, default=0.5, help='Timestep for the averaged model in hours. Default 0.5.') @@ -21,9 +21,9 @@ parser.add_argument('--ppp', type=float, default=4, help='Points per time-period for averaging.') parser.add_argument('--timestepping', type=str, default='rk4', choices=['rk2', 'rk4', 'heuns', 'ssprk3', 'leapfrog'], help='Choose a time steeping method. Default rk4.') parser.add_argument('--asselin', type=float, default=0.3, help='Asselin Filter coefficient for leapfrog. Default 0.3.') -parser.add_argument('--filename', type=str, default='control') +parser.add_argument('--filename', type=str, default='explicit') parser.add_argument('--pickup', action='store_true', help='Pickup the result from the checkpoint.') -parser.add_argument('--pickup_from', type=str, default='standard') +parser.add_argument('--pickup_from', type=str, default='explicit') args = parser.parse_known_args() args = args[0] timestepping = args.timestepping @@ -110,7 +110,7 @@ #pickup the result if args.pickup: - chkfile = DumbCheckpoint(args.pickup_from, mode=FILE_READ, comm = ensemble.comm) + chkfile = DumbCheckpoint(args.pickup_from, mode=FILE_READ, comm=ensemble.comm) un = Function(V1, name="Velocity") etan = Function(V2, name="Elevation") chkfile.load(un, name="Velocity") @@ -123,6 +123,13 @@ un = Function(V1, name="Velocity").project(u_expr) etan = Function(V2, name="Elevation").interpolate(eta_expr) +#calculate norms for debug +uini = Function(V1, name="Velocity0").project(u_expr) +etaini = Function(V2, name="Elevation0").interpolate(eta_expr) +etanorm = errornorm(etan, etaini)/norm(etaini) +unorm = errornorm(un, uini, norm_type="Hdiv")/norm(uini, norm_type="Hdiv") +print('etanorm', etanorm, 'unorm', unorm) + ############################################################################## # Set up the exponential operator ############################################################################## @@ -242,7 +249,7 @@ #write out initial fields mesh_ll = get_latlon_mesh(mesh) - file_sw = File(filename+'_avg.pvd', comm=ensemble.comm, mode="a") + file_sw = File(filename+'.pvd', comm=ensemble.comm, mode="a") field_un = Function( functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), val=un.topological) @@ -289,7 +296,11 @@ heuns(U, USlow_in, USlow_out, DU, U1, U2, W, expt, ensemble, cheby, cheby2, SlowSolver, wt, dt) + if rank == 0: + un.assign(U_u) + etan.assign(U_eta) + #dumping results if tdump > dumpt - dt*0.5: #dump averaged results @@ -301,15 +312,20 @@ #create checkpointing file every tcheck hours if tcheck > checkt - dt*0.5: - print("checkpointing at t =", t) thours = int(t/3600) - chk = DumbCheckpoint(filename+"_"+str(thours)+"h", mode=FILE_CREATE) + chk = DumbCheckpoint(filename+"_"+str(thours)+"h", mode=FILE_CREATE, comm = ensemble.comm) + tcheck -= checkt chk.store(un) chk.store(etan) chk.write_attribute("/", "time", t) chk.write_attribute("/", "tdump", tdump) chk.write_attribute("/", "tcheck", tcheck) chk.close() - tcheck -= checkt + print("checkpointed at t =", t) + + #calculate norms for debug + etanorm = errornorm(etan, etaini)/norm(etaini) + unorm = errornorm(un, uini, norm_type="Hdiv")/norm(uini, norm_type="Hdiv") + print('etanorm', etanorm, 'unorm', unorm) -print("Completed calculation at t =", t) +print("Completed calculation at t = ", t/3600, "hours") diff --git a/standard_sw.py b/standard_sw.py index a792198..50a5139 100644 --- a/standard_sw.py +++ b/standard_sw.py @@ -2,13 +2,15 @@ from math import pi from math import ceil from latlon import * +from firedrake.petsc import PETSc import numpy as np import argparse +print = PETSc.Sys.Print #get command arguments parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') parser.add_argument('--ref_level', type=int, default=4, help='Refinement level of icosahedral grid. Default 4.') -parser.add_argument('--tmax', type=float, default=120, help='Final time in hours. Default 24x5=120.') +parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') parser.add_argument('--checkt', type=float, default=6, help='Create checkpointing file every checkt hours. Default 6.') parser.add_argument('--dt', type=float, default=45, help='Timestep for the standard model in seconds. Default 45.') @@ -44,7 +46,8 @@ u_0 = 20.0 # maximum amplitude of the zonal wind [m/s] u_max = Constant(u_0) u_expr = as_vector([-u_max*x[1]/R, u_max*x[0]/R, 0.0]) -h_expr = H-((R*Omega*u_max+u_max*u_max/2.0)*(x[2]*x[2]/(R*R)))/g +eta_expr = -((R*Omega*u_max+u_max*u_max/2.0)*(x[2]*x[2]/(R*R)))/g +h_expr = eta_expr + H #topography (D = H + eta - b) rl = pi/9.0 @@ -80,9 +83,16 @@ chkfile.close() else: un = Function(V1, name="Velocity").project(u_expr) + etan = Function(V2, name="Elevation").interpolate(eta_expr) hn = Function(V2, name="Depth").interpolate(h_expr) hn -= b - etan = Function(V2, name="Elevation").assign(hn + b - H) + +#calculate norms for debug +uini = Function(V1, name="Velocity0").project(u_expr) +etaini = Function(V2, name="Elevation0").interpolate(eta_expr) +etanorm = errornorm(etan, etaini)/norm(etaini) +unorm = errornorm(un, uini, norm_type="Hdiv")/norm(uini, norm_type="Hdiv") +print('etanorm', etanorm, 'unorm', unorm) #setup PV solver PV = Function(Vf, name="PotentialVorticity") @@ -97,7 +107,7 @@ #write out initial fields mesh_ll = get_latlon_mesh(mesh) -file_sw = File(filename+'_sw.pvd', mode="a") +file_sw = File(filename+'.pvd', mode="a") field_un = Function( functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), val=un.topological) @@ -208,6 +218,7 @@ #update fields for next time step un.assign(up) hn.assign(hp) + etan.assign(hn + b - H) #dumping results if tdump > dumpt - dt*0.5: @@ -220,15 +231,20 @@ #create checkpointing file every tcheck hours if tcheck > checkt - dt*0.5: - print("checkpointing at t =", t) thours = int(t/3600) chk = DumbCheckpoint(filename+"_"+str(thours)+"h", mode=FILE_CREATE) + tcheck -= checkt chk.store(un) chk.store(hn) chk.write_attribute("/", "time", t) chk.write_attribute("/", "tdump", tdump) chk.write_attribute("/", "tcheck", tcheck) chk.close() - tcheck -= checkt + print("checkpointed at t =", t) + + #calculate norms for debug + etanorm = errornorm(etan, etaini)/norm(etaini) + unorm = errornorm(un, uini, norm_type="Hdiv")/norm(uini, norm_type="Hdiv") + print('etanorm', etanorm, 'unorm', unorm) -print("Completed calculation at t =", t) +print("Completed calculation at t = ", t/3600, "hours") From 6dc0d0ea697519a12be1a2ddd94ff594f08a59f2 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Thu, 1 Jul 2021 13:22:17 +0100 Subject: [PATCH 38/46] changing SlowSolver from linear to nonlinear --- averaged_sw_imp.py | 55 ++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/averaged_sw_imp.py b/averaged_sw_imp.py index 04ce2a9..e1110f0 100644 --- a/averaged_sw_imp.py +++ b/averaged_sw_imp.py @@ -1,4 +1,4 @@ -#Use implicit midpoint with fixed point on advection velocity +#Use implicit midpoint with fixed point on advection velocity #get command arguments import argparse @@ -27,7 +27,7 @@ ref_level = args.ref_level eigs = [0.003465, 0.007274, 0.014955] #maximum frequency from math import pi -min_time_period = 2*pi/eigs[ref_level-3] +min_time_period = 2*pi/eigs[ref_level-3] hours = args.dt dt = 60*60*hours rho = args.rho #averaging window is rho*dt @@ -72,7 +72,7 @@ outward_normals = CellNormal(mesh) perp = lambda u: cross(outward_normals, u) - + V1 = FunctionSpace(mesh, "BDM", 2) V2 = FunctionSpace(mesh, "DG", 1) W = MixedFunctionSpace((V1, V2)) @@ -130,50 +130,43 @@ Unl = Function(W) #outer loop for slow solver u0, eta0 = split(USlow_in) -u1, eta1 = TrialFunctions(W) -unl, etanl = split(Unl) +u1, eta1 = split(USlow_out) uh = theta*u1 + (1-theta)*u0 etah = theta*eta1 + (1-theta)*eta0 #RHS for Forward Euler step gradperp = lambda f: perp(grad(f)) n = FacetNormal(mesh) -Upwind = 0.5 * (sign(dot(unl, n)) + 1) +Upwind = 0.5 * (sign(dot(uh, n)) + 1) both = lambda u: 2*avg(u) -K = 0.5*inner(unl, u0) -uup = 0.5 * (dot(unl, n) + abs(dot(unl, n))) +K = 0.5*inner(uh, u0) +uup = 0.5 * (dot(uh, n) + abs(dot(uh, n))) ncycles = args.ncycles dT = Constant(dt/ncycles) eqn = ( inner(v, u1-u0)*dx + phi*(eta1-eta0)*dx - + dT*inner(perp(grad(inner(v, perp(unl)))), uh)*dx - - dT*inner(both(perp(n)*inner(v, perp(unl))), + + dT*inner(perp(grad(inner(v, perp(uh)))), uh)*dx + - dT*inner(both(perp(n)*inner(v, perp(uh))), both(Upwind*uh))*dS + dT*div(v)*K*dx - + dT*inner(grad(phi), unl*(etah-b))*dx + + dT*inner(grad(phi), uh*(etah-b))*dx - dT*jump(phi)*(uup('+')*(etah('+')-b('+')) - uup('-')*(etah('-') - b('-')))*dS ) #with topography, D = H + eta - b - -impparams = { - 'ksp_type': 'preonly', - 'pc_type': 'fieldsplit', - 'fieldsplit_0_ksp_type':'cg', - 'fieldsplit_0_pc_type':'bjacobi', - 'fieldsplit_0_sub_pc_type':'ilu', - 'fieldsplit_1_ksp_type':'cg', - 'fieldsplit_1_pc_type':'bjacobi', - 'fieldsplit_1_sub_pc_type':'ilu' +params = { + "ksp_type": "preonly", + "mat_type":"aij", + "pc_type": "lu", + "pc_factor_mat_solver_type": "mumps" } -SlowProb = LinearVariationalProblem(lhs(eqn), rhs(eqn), USlow_out, - constant_jacobian=False) -SlowSolver = LinearVariationalSolver(SlowProb, - solver_parameters = impparams) +SlowProb = NonlinearVariationalProblem(eqn, USlow_out) +SlowSolver = NonlinearVariationalSolver(SlowProb, + solver_parameters = params) t = 0. tmax = 60.*60.*args.tmax @@ -244,17 +237,16 @@ # U_{n+1} = \exp(tL)(U_n + \int \rho\exp(-sL)\Delta\Phi(\exp(sL)U_n))ds #apply forward transformation and put result in V, storing copy in eU - cheby.apply(U, eU, expt) + cheby2.apply(U, V, dt) + cheby.apply(V, eU, expt) V.assign(eU) - + #apply forward slow step to V #using semi-implicit stepping for i in range(ncycles): USlow_in.assign(V) - Unl.assign(V) - SlowSolver.solve() - Unl.assign(0.5*(V + USlow_out)) + USlow_out.assign(V) SlowSolver.solve() V.assign(USlow_out) #compute difference from initial value @@ -267,7 +259,8 @@ #average into V ensemble.allreduce(DU, V) - U += V + cheby2.apply(V, eU, -dt) + U += eU V.assign(U) From ca81349f73274e2e5f36f491e4c8e5ba5867cb1d Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Fri, 30 Jul 2021 08:11:52 +0000 Subject: [PATCH 39/46] calculate norms from .h5 files from averaged_sw_explicit and standard_sw --- calculate_norm.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 calculate_norm.py diff --git a/calculate_norm.py b/calculate_norm.py new file mode 100644 index 0000000..fef08e5 --- /dev/null +++ b/calculate_norm.py @@ -0,0 +1,105 @@ +from firedrake import * +import numpy as np +import argparse +from firedrake.petsc import PETSc +print = PETSc.Sys.Print + +#get command arguments +parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') +parser.add_argument('--file0', type=str, default='standard0') +parser.add_argument('--file1', type=str, default='standard1') +args = parser.parse_known_args() +args = args[0] +print(args) + +# parameters +REF_LEVEL = 5 +HOURS = [6, 12, 18, 24] + +#parameters +R0 = 6371220. +R = Constant(R0) +H = Constant(5960.) +Omega = Constant(7.292e-5) # rotation rate +g = Constant(9.8) # Gravitational constant +mesh = IcosahedralSphereMesh(radius=R0, + refinement_level=REF_LEVEL, degree=3) +x = SpatialCoordinate(mesh) +global_normal = as_vector([x[0], x[1], x[2]]) +mesh.init_cell_orientations(global_normal) +outward_normals = CellNormal(mesh) +perp = lambda u: cross(outward_normals, u) +V1 = FunctionSpace(mesh, "BDM", 2) +V2 = FunctionSpace(mesh, "DG", 1) +W = MixedFunctionSpace((V1, V2)) +f_expr = 2 * Omega * x[2] / R +Vf = FunctionSpace(mesh, "CG", 3) +f = Function(Vf).interpolate(f_expr) # Coriolis frequency +u_0 = 20.0 # maximum amplitude of the zonal wind [m/s] +u_max = Constant(u_0) +u_expr = as_vector([-u_max*x[1]/R, u_max*x[0]/R, 0.0]) +eta_expr = -((R*Omega*u_max+u_max*u_max/2.0)*(x[2]*x[2]/(R*R)))/g +h_expr = eta_expr + H + +#calculate norms for debug +uini = Function(V1, name="Velocity0").project(u_expr) +etaini = Function(V2, name="Elevation0").interpolate(eta_expr) +etaavg = 0 +uavg = 0 +etastd = 0 +ustd = 0 + +#topography (D = H + eta - b) +rl = pi/9.0 +lambda_x = atan_2(x[1]/R0, x[0]/R0) +lambda_c = -pi/2.0 +phi_x = asin(x[2]/R0) +phi_c = pi/6.0 +minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +bexpr = 2000.0*(1 - sqrt(minarg)/rl) +b = Function(V2, name="Topography") +b.interpolate(bexpr) + +print('calculate normalised norms in '+str(args.file0)+" with respect to "+str(args.file1)+" at hours", HOURS) +eta_norm = [] +u_norm_Hdiv = [] +u_norm_L2 = [] +for hour in HOURS: + t = int(hour) + + #read data from file0 + chkfile0 = DumbCheckpoint(args.file0+"_"+str(t)+"h", mode=FILE_READ) + u0 = Function(V1, name="Velocity") + eta0 = Function(V2, name="Elevation") + chkfile0.load(u0, name="Velocity") + chkfile0.load(eta0, name="Elevation") + chkfile0.close() + uavg = errornorm(u0, uini, norm_type="Hdiv")/norm(uini, norm_type="Hdiv") + etaavg = errornorm(eta0, etaini)/norm(etaini) + print('etaavg', etaavg, 'uavg', uavg) + + #read data from file1 + chkfile1 = DumbCheckpoint(args.file1+"_"+str(t)+"h", mode=FILE_READ) + u1 = Function(V1, name="VelocityR") + h1 = Function(V2, name="DepthR") + chkfile1.load(u1, name="Velocity") + chkfile1.load(h1, name="Depth") + eta1 = Function(V2, name="ElevationR").assign(h1 + b - H) + chkfile1.close() + ustd = errornorm(u1, uini, norm_type="Hdiv")/norm(uini, norm_type="Hdiv") + etastd = errornorm(eta1, etaini)/norm(etaini) + print('etastd', etastd, 'ustd', ustd) + + #calculate norms + etanorm = errornorm(eta0, eta1)/norm(eta1) + unorm_Hdiv = errornorm(u0, u1, norm_type="Hdiv")/norm(u1, norm_type="Hdiv") + unorm_L2 = errornorm(u0, u1)/norm(u1) + + #append norms in array + eta_norm.append(etanorm) + u_norm_Hdiv.append(unorm_Hdiv) + u_norm_L2.append(unorm_L2) + +print('etanorm =', eta_norm) +print('unorm_Hdiv =', u_norm_Hdiv) +print('unorm_L2 =', u_norm_L2) From 75fcbba532d9485cd1544794eb462cb024f01c66 Mon Sep 17 00:00:00 2001 From: Hiroe Yamazaki Date: Fri, 30 Jul 2021 08:14:35 +0000 Subject: [PATCH 40/46] use .assign to be compatible with the latest firedrake --- cheby_exp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cheby_exp.py b/cheby_exp.py index ac57e3e..16e8d26 100644 --- a/cheby_exp.py +++ b/cheby_exp.py @@ -132,7 +132,7 @@ def apply(self, x, y, t): self.dy.assign(self.T_i) Coeff.assign(np.imag(self.ChebCoeffs[1])) - self.dy *= -Coeff + self.dy.assign(-Coeff*self.dy) y += self.dy for i in range(2, self.ncheb+1): @@ -161,5 +161,5 @@ def apply(self, x, y, t): self.dy.assign(self.T_i) Coeff.assign(imag(self.ChebCoeffs[i])) - self.dy *= -Coeff + self.dy.assign(-Coeff*self.dy) y += self.dy From 794f1da55f03e0be5419a9d2a7ea82b48f923bc9 Mon Sep 17 00:00:00 2001 From: hyamazak Date: Tue, 23 May 2023 13:06:43 +0100 Subject: [PATCH 41/46] update the file to be compatible with the latest firedrake --- averaged_sw.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/averaged_sw.py b/averaged_sw.py index 7def4bb..4ea7b53 100644 --- a/averaged_sw.py +++ b/averaged_sw.py @@ -58,15 +58,17 @@ R0 = 6371220. H = Constant(5960.) +mesh_degree = 3 mesh = IcosahedralSphereMesh(radius=R0, - refinement_level=ref_level, degree=3, + refinement_level=ref_level, degree=mesh_degree, comm = ensemble.comm) cx = SpatialCoordinate(mesh) mesh.init_cell_orientations(cx) cx, cy, cz = SpatialCoordinate(mesh) -outward_normals = CellNormal(mesh) +outward_normals = interpolate(CellNormal(mesh),VectorFunctionSpace(mesh,"DG",mesh_degree)) + perp = lambda u: cross(outward_normals, u) V1 = FunctionSpace(mesh, "BDM", 2) @@ -199,7 +201,7 @@ lambda_c = -pi/2.0 phi_x = asin(x[2]/R0) phi_c = pi/6.0 -minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +minarg = min_value(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) bexpr = 2000.0*(1 - sqrt(minarg)/rl) b.interpolate(bexpr) @@ -211,7 +213,7 @@ DU = Function(W) V = Function(W) -U_u, U_eta = U.split() +U_u, U_eta = U.subfunctions U_u.assign(un) U_eta.assign(etan) From e11d23af22264bbaf43ac841bb4f39dd73399917 Mon Sep 17 00:00:00 2001 From: hyamazak Date: Thu, 15 Jun 2023 11:31:00 +0100 Subject: [PATCH 42/46] standard model now runs with the latest firedrake --- standard_sw.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/standard_sw.py b/standard_sw.py index 50a5139..b9db14d 100644 --- a/standard_sw.py +++ b/standard_sw.py @@ -30,12 +30,13 @@ H = Constant(5960.) Omega = Constant(7.292e-5) # rotation rate g = Constant(9.8) # Gravitational constant +mesh_degree = 3 mesh = IcosahedralSphereMesh(radius=R0, - refinement_level=ref_level, degree=3) + refinement_level=ref_level, degree=mesh_degree) x = SpatialCoordinate(mesh) global_normal = as_vector([x[0], x[1], x[2]]) mesh.init_cell_orientations(global_normal) -outward_normals = CellNormal(mesh) +outward_normals = interpolate(CellNormal(mesh),VectorFunctionSpace(mesh,"DG",mesh_degree)) perp = lambda u: cross(outward_normals, u) V1 = FunctionSpace(mesh, "BDM", 2) V2 = FunctionSpace(mesh, "DG", 1) @@ -55,7 +56,7 @@ lambda_c = -pi/2.0 phi_x = asin(x[2]/R0) phi_c = pi/6.0 -minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +minarg = min_value(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) bexpr = 2000.0*(1 - sqrt(minarg)/rl) b = Function(V2, name="Topography") b.interpolate(bexpr) @@ -107,18 +108,20 @@ #write out initial fields mesh_ll = get_latlon_mesh(mesh) +global_normal = as_vector([0, 0, 1]) +mesh_ll.init_cell_orientations(global_normal) file_sw = File(filename+'.pvd', mode="a") field_un = Function( - functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), + functionspaceimpl.WithGeometry.create(un.function_space(), mesh_ll), val=un.topological) field_etan = Function( - functionspaceimpl.WithGeometry(etan.function_space(), mesh_ll), + functionspaceimpl.WithGeometry.create(etan.function_space(), mesh_ll), val=etan.topological) field_PV = Function( - functionspaceimpl.WithGeometry(PV.function_space(), mesh_ll), + functionspaceimpl.WithGeometry.create(PV.function_space(), mesh_ll), val=PV.topological) field_b = Function( - functionspaceimpl.WithGeometry(b.function_space(), mesh_ll), + functionspaceimpl.WithGeometry.create(b.function_space(), mesh_ll), val=b.topological) if not args.pickup: file_sw.write(field_un, field_etan, field_PV, field_b) @@ -157,7 +160,7 @@ Upwind = 0.5 * (sign(dot(ubar, n)) + 1) K = 0.5 * (inner(0.5 * (un + up), 0.5 * (un + up))) both = lambda u: 2*avg(u) -outward_normals = CellNormal(mesh) +#outward_normals = CellNormal(mesh) perp = lambda arg: cross(outward_normals, arg) Ueqn = (inner(u - un, v)*dx + dt*inner(perp(uh)*f, v)*dx - dt*inner(perp(grad(inner(v, perp(ubar)))), uh)*dx From 624dbb48aab8521c1ea464cb557d59d8ae0b661a Mon Sep 17 00:00:00 2001 From: hyamazak Date: Fri, 16 Jun 2023 03:47:42 +0100 Subject: [PATCH 43/46] averaged code runs now too --- averaged_sw_explicit.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index 3e5aca9..73c241f 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -42,13 +42,14 @@ H = Constant(5960.) Omega = Constant(7.292e-5) # rotation rate g = Constant(9.8) # Gravitational constant +mesh_degree = 3 mesh = IcosahedralSphereMesh(radius=R0, - refinement_level=ref_level, degree=3, + refinement_level=ref_level, degree=mesh_degree, comm = ensemble.comm) x = SpatialCoordinate(mesh) global_normal = as_vector([x[0], x[1], x[2]]) mesh.init_cell_orientations(global_normal) -outward_normals = CellNormal(mesh) +outward_normals = interpolate(CellNormal(mesh),VectorFunctionSpace(mesh,"DG",mesh_degree)) perp = lambda u: cross(outward_normals, u) V1 = FunctionSpace(mesh, "BDM", 2) V2 = FunctionSpace(mesh, "DG", 1) @@ -67,7 +68,7 @@ lambda_c = -pi/2.0 phi_x = asin(x[2]/R0) phi_c = pi/6.0 -minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +minarg = min_value(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) bexpr = 2000.0*(1 - sqrt(minarg)/rl) b = Function(V2, name="Topography") b.interpolate(bexpr) @@ -224,7 +225,7 @@ X3 = Function(W) V = Function(W) -U_u, U_eta = U.split() +U_u, U_eta = U.subfunctions U_u.assign(un) U_eta.assign(etan) @@ -249,18 +250,20 @@ #write out initial fields mesh_ll = get_latlon_mesh(mesh) + global_normal = as_vector([0, 0, 1]) + mesh_ll.init_cell_orientations(global_normal) file_sw = File(filename+'.pvd', comm=ensemble.comm, mode="a") field_un = Function( - functionspaceimpl.WithGeometry(un.function_space(), mesh_ll), + functionspaceimpl.WithGeometry.create(un.function_space(), mesh_ll), val=un.topological) field_etan = Function( - functionspaceimpl.WithGeometry(etan.function_space(), mesh_ll), + functionspaceimpl.WithGeometry.create(etan.function_space(), mesh_ll), val=etan.topological) field_PV = Function( - functionspaceimpl.WithGeometry(PV.function_space(), mesh_ll), + functionspaceimpl.WithGeometry.create(PV.function_space(), mesh_ll), val=PV.topological) field_b = Function( - functionspaceimpl.WithGeometry(b.function_space(), mesh_ll), + functionspaceimpl.WithGeometry.create(b.function_space(), mesh_ll), val=b.topological) if not args.pickup: file_sw.write(field_un, field_etan, field_PV, field_b) From df106ec9f05b97f288e52df7e3e816ce9ae4e864 Mon Sep 17 00:00:00 2001 From: hyamazak Date: Mon, 26 Jun 2023 13:04:18 +0100 Subject: [PATCH 44/46] updated files with parameters which were used in the paper --- averaged_sw_explicit.py | 4 ++-- calculate_norm.py | 6 +++--- standard_sw.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/averaged_sw_explicit.py b/averaged_sw_explicit.py index 73c241f..7950389 100644 --- a/averaged_sw_explicit.py +++ b/averaged_sw_explicit.py @@ -10,12 +10,12 @@ #get command arguments parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') -parser.add_argument('--ref_level', type=int, default=4, help='Refinement level of icosahedral grid. Default 4.') +parser.add_argument('--ref_level', type=int, default=5, help='Refinement level of icosahedral grid. Default 4.') parser.add_argument('--space_parallel', type=int, default=4, help='Default 4.') parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') parser.add_argument('--checkt', type=float, default=6, help='Create checkpointing file every checkt hours. Default 6.') -parser.add_argument('--dt', type=float, default=0.5, help='Timestep for the averaged model in hours. Default 0.5.') +parser.add_argument('--dt', type=float, default=0.25, help='Timestep for the averaged model in hours. Default 0.5.') parser.add_argument('--rho', type=float, default=1, help='Averaging window width as a multiple of dt. Default 1.') parser.add_argument('--Mbar', action='store_true', dest='get_Mbar', help='Compute suitable Mbar, print it and exit.') parser.add_argument('--ppp', type=float, default=4, help='Points per time-period for averaging.') diff --git a/calculate_norm.py b/calculate_norm.py index fef08e5..46f1277 100644 --- a/calculate_norm.py +++ b/calculate_norm.py @@ -6,8 +6,8 @@ #get command arguments parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') -parser.add_argument('--file0', type=str, default='standard0') -parser.add_argument('--file1', type=str, default='standard1') +parser.add_argument('--file0', type=str, default='explicit') +parser.add_argument('--file1', type=str, default='standard') args = parser.parse_known_args() args = args[0] print(args) @@ -55,7 +55,7 @@ lambda_c = -pi/2.0 phi_x = asin(x[2]/R0) phi_c = pi/6.0 -minarg = Min(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) +minarg = min_value(pow(rl, 2), pow(phi_x - phi_c, 2) + pow(lambda_x - lambda_c, 2)) bexpr = 2000.0*(1 - sqrt(minarg)/rl) b = Function(V2, name="Topography") b.interpolate(bexpr) diff --git a/standard_sw.py b/standard_sw.py index b9db14d..f59c284 100644 --- a/standard_sw.py +++ b/standard_sw.py @@ -9,11 +9,11 @@ #get command arguments parser = argparse.ArgumentParser(description='Williamson 5 testcase for averaged propagator.') -parser.add_argument('--ref_level', type=int, default=4, help='Refinement level of icosahedral grid. Default 4.') +parser.add_argument('--ref_level', type=int, default=5, help='Refinement level of icosahedral grid. Default 4.') parser.add_argument('--tmax', type=float, default=360, help='Final time in hours. Default 24x15=360.') parser.add_argument('--dumpt', type=float, default=24, help='Dump time in hours. Default 24.') parser.add_argument('--checkt', type=float, default=6, help='Create checkpointing file every checkt hours. Default 6.') -parser.add_argument('--dt', type=float, default=45, help='Timestep for the standard model in seconds. Default 45.') +parser.add_argument('--dt', type=float, default=22.5, help='Timestep for the standard model in seconds. Default 45.') parser.add_argument('--filename', type=str, default='standard') parser.add_argument('--pickup', action='store_true', help='Pickup the result from the checkpoint.') parser.add_argument('--pickup_from', type=str, default='standard') From 9661d3420e80b2b227c54546ad2006d68f49020a Mon Sep 17 00:00:00 2001 From: hyamazak Date: Tue, 27 Jun 2023 10:58:15 +0100 Subject: [PATCH 45/46] data files and scripts which were used to produce figures in the qjrms paper --- qjrms/data_lev5_dt0125.py | 271 ++++++++++++++++++++++++++++++++++++++ qjrms/data_lev5_dt025.py | 266 +++++++++++++++++++++++++++++++++++++ qjrms/data_lev5_dt0375.py | 126 ++++++++++++++++++ qjrms/plot_compare_dt.py | 210 +++++++++++++++++++++++++++++ qjrms/plot_lev5_dt025.py | 225 +++++++++++++++++++++++++++++++ 5 files changed, 1098 insertions(+) create mode 100644 qjrms/data_lev5_dt0125.py create mode 100644 qjrms/data_lev5_dt025.py create mode 100644 qjrms/data_lev5_dt0375.py create mode 100644 qjrms/plot_compare_dt.py create mode 100644 qjrms/plot_lev5_dt025.py diff --git a/qjrms/data_lev5_dt0125.py b/qjrms/data_lev5_dt0125.py new file mode 100644 index 0000000..6eb3af6 --- /dev/null +++ b/qjrms/data_lev5_dt0125.py @@ -0,0 +1,271 @@ +# peddle plots data for lev5_dt0125 + +def input_lev5_dt0125(etadict, udict, ppp, dts=45): + if ppp == 4: + # norms dumped every 0.25 day + + if dts == 45: + + print("dts == 45") + + # AW0.125 + etadict[0.125] = [1.6981642614427758e-05, 2.1003336658600135e-05] + udict[0.125] = [2.7689764322279938e-05, 3.122130548584667e-05] + + # AW0.15 + etadict[0.15] = [1.8695171275859983e-05, 2.2867321990678613e-05] + udict[0.15] = [3.441931893390227e-05, 3.8031290607508193e-05] + + # AW0.175 + etadict[0.175] = [2.0970616766434567e-05, 2.5299606622985727e-05] + udict[0.175] = [4.283923145132894e-05, 4.6705979783495636e-05] + + # AW0.2 + etadict[0.2] = [2.3579789914953545e-05, 2.8013997937390043e-05] + udict[0.2] = [5.198235131574744e-05, 5.6230175116296154e-05] + + # AW0.225 + etadict[0.225] = [2.661268747775121e-05, 3.112229679310489e-05] + udict[0.225] = [6.222224415268136e-05, 6.698882384585599e-05] + + # AW0.25 + etadict[0.25] = [3.0074213493207613e-05, 3.464178191702469e-05] + udict[0.25] = [7.348167176260643e-05, 7.893810107131359e-05] + + # AW0.3 + etadict[0.3] = [3.8072823320292053e-05, 4.273685405881847e-05] + udict[0.3] = [9.83190954187474e-05, 0.00010570803428689003] + + # AW0.35 + etadict[0.35] = [4.7209884364913035e-05, 5.198115701084791e-05] + udict[0.35] = [0.00012551674667853906, 0.00013557408646377195] + + # AW0.4 + etadict[0.4] = [5.733977065337065e-05, 6.225271720239979e-05] + udict[0.4] = [0.00015484975497150733, 0.0001683250527799476] + + # AW0.45 + etadict[0.45] = [6.83780752161118e-05, 7.348332573024231e-05] + udict[0.45] = [0.00018624905140430118, 0.00020389546619398207] + + # AW0.5 + etadict[0.5] = [8.030229573308488e-05, 8.566263335509212e-05] + udict[0.5] = [0.00021981550450696672, 0.00024238750089176027] + + # AW0.6 + etadict[0.6] = [0.00010679413319161268, 0.00011289120869042123] + udict[0.6] = [0.00029401806359428755, 0.0003286389478378706] + + # AW0.7 + etadict[0.7] = [0.00013680751901234164, 0.0001439784943618706] + udict[0.7] = [0.000378261603867781, 0.00042766735226009437] + + # AW0.8 + etadict[0.8] = [0.00017032391082603328, 0.00017892187664149558] + udict[0.8] = [0.00047257057207957404, 0.0005392681503837394] + + # AW0.9 + etadict[0.9] = [0.00020728283979520065, 0.00021765508903120678] + udict[0.9] = [0.0005764002884430113, 0.0006627116401107882] + + elif dts == 22.5: + + # AW0.1 + etadict[0.1] = [9.366463393959579e-06, 1.1354079146008386e-05, 2.072964310549257e-05, 5.9894578513515636e-05] + udict[0.1] = [1.7573968591559225e-05, 1.9402723726451677e-05, 2.8906507654333715e-05, 6.533076420875647e-05] + + # AW0.10625 + etadict[0.10625] = [9.338078959380886e-06, 1.0651856121586863e-05, 1.6899724915689978e-05, 4.186009865769183e-05] + udict[0.10625] = [1.825085086575451e-05, 1.950698688385012e-05, 2.5471383438889686e-05, 4.7389896933321265e-05] + + # AW0.1125 + etadict[0.1125] = [9.374240878498704e-06, 1.0199769709022165e-05, 1.4215840348522517e-05, 2.9252862033239736e-05] + udict[0.1125] = [1.908929010676017e-05, 1.996660674063706e-05, 2.3595244909845215e-05, 3.565265814591811e-05] + + # AW0.11875 + etadict[0.11875] = [9.865395868875837e-06, 1.0209089526480852e-05, 1.1968515191028366e-05, 1.6591262318022678e-05] + udict[0.11875] = [2.1878142663525775e-05, 2.249536962419403e-05, 2.414216903367326e-05, 2.7264293085291983e-05] + + # AW0.125 + etadict[0.125] = [1.0170584991455671e-05, 1.0442086452378304e-05, 1.1824356702194843e-05, 1.4589274061579014e-05] + udict[0.125] = [2.334031692792787e-05, 2.396399931255729e-05, 2.5380547285833332e-05, 2.7366901809677266e-05] + + # AW0.13125 + etadict[0.13125] = [1.0546310728951425e-05, 1.0808443115405702e-05, 1.2042699200946456e-05, 1.404473124921183e-05] + udict[0.13125] = [2.4952292805510182e-05, 2.5635373518109086e-05, 2.702733849556582e-05, 2.8688262049485773e-05] + + # AW0.1375 + etadict[0.1375] = [1.0988520348187241e-05, 1.1279233191729586e-05, 1.247700329446077e-05, 1.4214267201264232e-05] + udict[0.1375] = [2.6703912770347585e-05, 2.7479018770436955e-05, 2.8944811013957464e-05, 3.059805588809706e-05] + + # AW0.14375 + etadict[0.14375] = [1.1488770071312919e-05, 1.1825838536375784e-05, 1.3033148554058195e-05, 1.469654282043801e-05] + udict[0.14375] = [2.8582481927507373e-05, 2.946838437314016e-05, 3.105175619223444e-05, 3.2807098432088245e-05] + + # AW0.15 + etadict[0.15] = [1.2116123391897576e-05, 1.251089191411541e-05, 1.3748604822934126e-05, 1.542481567432057e-05] + udict[0.15] = [3.065789872276964e-05, 3.1694266766585694e-05, 3.3446394974764285e-05, 3.5368714546616914e-05] + + # AW0.175 + etadict[0.175] = [1.4780223100149392e-05, 1.5382028830838242e-05, 1.6746226600555565e-05, 1.849250950087603e-05] + udict[0.175] = [3.9576940057076746e-05, 4.1169991018926425e-05, 4.3572409984812635e-05, 4.618019827489252e-05] + + # AW0.2 + etadict[0.2] = [1.779683199488831e-05, 1.8555318072253365e-05, 2.00431294065245e-05, 2.1874615622490178e-05] + udict[0.2] = [4.909105418837714e-05, 5.129207691910051e-05, 5.442454903105406e-05, 5.7819949806438974e-05] + + # AW0.225 + etadict[0.225] = [2.1228379631043507e-05, 2.2121057980324938e-05, 2.374948812683963e-05, 2.5680622993385004e-05] + udict[0.225] = [5.9628003815664966e-05, 6.253047479154892e-05, 6.651545269004442e-05, 7.083552682793006e-05] + + # AW0.25 + etadict[0.25] = [2.506752220281647e-05, 2.6088674892665145e-05, 2.7882729882300844e-05, 2.9933865533783276e-05] + udict[0.25] = [7.112915463298665e-05, 7.487125175762697e-05, 7.986650496969999e-05, 8.527934301394256e-05] + + # AW0.3 + etadict[0.3] = [3.3729567870978534e-05, 3.5021048801885265e-05, 3.722265926061975e-05, 3.9572145353469705e-05] + udict[0.3] = [9.633174101970866e-05, 0.0001022378203508984, 0.00010975494799189639, 0.00011787895735067089] + + # AW0.35 + etadict[0.35] = [4.341044603967669e-05, 4.5010243606166934e-05, 4.771311658944147e-05, 5.04479227627931e-05] + udict[0.35] = [0.00012379389654712037, 0.0001325448263793947, 0.00014324372306310688, 0.00015475593785402458] + + # AW0.4 + etadict[0.4] = [5.399168965181975e-05, 5.594845820789957e-05, 5.923943726236224e-05, 6.24282878348927e-05] + udict[0.4] = [0.00015333209342995074, 0.00016564784516368494, 0.00018020191112832836, 0.00019578930444751283] + + # AW0.45 + etadict[0.45] = [6.54102789427128e-05, 6.777954143011987e-05, 7.174142584797578e-05, 7.543468272856465e-05] + udict[0.45] = [0.0001848981016735193, 0.0002015132266685986, 0.00022059887923775998, 0.0002409456796046905] + + # AW0.5 + etadict[0.5] = [7.765946441092074e-05, 8.050209892087074e-05, 8.52165548705934e-05, 8.94571332101822e-05] + udict[0.5] = [0.00021860462498403296, 0.000240259867539728, 0.0002645591589028287, 0.00029034554859892926] + + # AW0.6 + etadict[0.6] = [0.00010467562741702667, 0.00010866686789542422, 0.00011513641759030366, 0.00012059554961582457] + udict[0.6] = [0.0002930323823801102, 0.00032693175690616196, 0.00036368926644641164, 0.0004023456336066794] + + # AW0.7 + etadict[0.7] = [0.00013508892017494108, 0.00014051599200128154, 0.00014908447019983405, 0.00015587550022874507] + udict[0.7] = [0.0003774491344036863, 0.00042628949608930386, 0.00047816471203202356, 0.0005322738376963181] + + # AW0.8 + etadict[0.8] = [0.0001689148391163473, 0.0001760739834979462, 0.0001871004996465363, 0.00019531120543173804] + udict[0.8] = [0.00047189330024722766, 0.0005381482282576008, 0.0006077784675346472, 0.0006798714870804358] + + # AW0.9 + etadict[0.9] = [0.00020611613802836432, 0.00021530041621838517, 0.00022915415999485704, 0.00023885565789313713] + udict[0.9] = [0.0005758294575106701, 0.0006617935140271031, 0.00075182833732428, 0.0008444174949152699] + + # AW1 + etadict[1.0] = [0.00024661340519005644, 0.00025810559342249675, 0.00027515820070039365, 0.00028639323386373547] + udict[1.0] = [0.0006885334849204903, 0.0007963511713901604, 0.0009094509515442013, 0.00102503419080779] + + + elif dts == 10: + + # AW0.075 + etadict[0.075] = [2.3383738528966856e-05, 0.014475065775711884] + udict[0.075] = [6.162886020298819e-05, 0.026083363523280646] + + # AW0.0875 + etadict[0.0875] = [3.0686143418727067e-05, 0.03052817436957221] + udict[0.0875] = [5.6794475811310307e-05, 0.0657779506524491] + + # AW0.1 + etadict[0.1] = [8.272421659782072e-06, 1.0081297816171733e-05, 1.962499109674541e-05, 5.930053678283839e-05] + udict[0.1] = [1.6912925638578102e-05, 1.852230642687692e-05, 2.7957583804679086e-05, 6.475717040635701e-05] + + # AW0.10625 + etadict[0.10625] = [8.183689940150197e-06, 9.19163433831813e-06, 1.5446315245662183e-05, 4.09620128939831e-05] + udict[0.10625] = [1.7582092956924305e-05, 1.8578296130091945e-05, 2.4329352200564463e-05, 4.656074687960793e-05] + + # AW0.1125 + etadict[0.1125] = [8.165894732395508e-06, 8.561122545278078e-06, 1.2350761994146121e-05, 2.7886109507145973e-05] + udict[0.1125] = [1.8417946846844097e-05, 1.9005794338772264e-05, 2.2289385199239804e-05, 3.449290653050823e-05] + + # AW0.11875 + etadict[0.11875] = [8.578034121530008e-06, 8.290089551763608e-06, 9.316001108806635e-06, 1.3673962913600173e-05] + udict[0.11875] = [2.1218919254872993e-05, 2.1516055062984793e-05, 2.2684534323892333e-05, 2.5542254682479113e-05] + + # AW0.125 + etadict[0.125] = [8.861402986415471e-06, 8.445796992467736e-06, 8.951649069197335e-06, 1.0942184188880984e-05] + udict[0.125] = [2.26907301628355e-05, 2.2989999272062838e-05, 2.3916799359902993e-05, 2.5563718021130165e-05] + + # AW0.13125 + etadict[0.13125] = [9.225396136892378e-06, 8.766780417888777e-06, 9.057903100234352e-06, 9.962200035803235e-06] + udict[0.13125] = [2.4314284678523587e-05, 2.467256261673584e-05, 2.5579833933927488e-05, 2.68878216277115e-05] + + # AW0.1375 + etadict[0.1375] = [9.664502725276416e-06, 9.215860155166366e-06, 9.450060926173707e-06, 9.950043772603212e-06] + udict[0.1375] = [2.6078603381257762e-05, 2.6530637761124793e-05, 2.7523621958550973e-05, 2.8834745673402455e-05] + + # AW0.14375 + etadict[0.14375] = [1.016816962435833e-05, 9.7556650217192e-06, 9.999853332512177e-06, 1.0380604328939949e-05] + udict[0.14375] = [2.7970328976790824e-05, 2.853586699624967e-05, 2.9660241209257396e-05, 3.109046790676766e-05] + + # AW0.15 + etadict[0.15] = [1.0809515713391131e-05, 1.0449456133308178e-05, 1.0733297648564357e-05, 1.1120378866086363e-05] + udict[0.15] = [3.0058985843285298e-05, 3.07772867548848e-05, 3.208403505295586e-05, 3.370053216435626e-05] + + # AW0.1625 + etadict[0.1625] = [1.3534083837454687e-05, 1.3373601206864583e-05, 1.3826225282153363e-05, 1.429460341382495e-05] + udict[0.1625] = [3.9026346615028944e-05, 4.031294260106729e-05, 4.2315074309707785e-05, 4.467469136318679e-05] + + # AW0.175 + etadict[0.175] = [1.3534083837454687e-05, 1.3373601206864583e-05, 1.3826225282153363e-05, 1.429460341382495e-05] + udict[0.175] = [3.9026346615028944e-05, 4.031294260106729e-05, 4.2315074309707785e-05, 4.467469136318679e-05] + + # AW0.2 + etadict[0.2] = [1.662033460601124e-05, 1.6616524723557775e-05, 1.722862910716829e-05, 1.780041783179933e-05] + udict[0.2] = [4.857828084131165e-05, 5.0482427708938676e-05, 5.3245845681138225e-05, 5.643316897997446e-05] + + # AW0.225 + etadict[0.225] = [2.011926401027963e-05, 2.0252954931347e-05, 2.1037516815048194e-05, 2.172680659574343e-05] + udict[0.225] = [5.9147104346582225e-05, 6.176140649787924e-05, 6.540151403392936e-05, 6.954465017180678e-05] + + # AW0.25 + etadict[0.25] = [2.4021613587207857e-05, 2.4290900833939124e-05, 2.5270573966894026e-05, 2.6096831968408824e-05] + udict[0.25] = [7.067566516446663e-05, 7.413785746700785e-05, 7.88079422112147e-05, 8.406967150238145e-05] + + # AW0.3 + etadict[0.3] = [3.279540988563222e-05, 3.335963298906349e-05, 3.4801225657702716e-05, 3.595615332151521e-05] + udict[0.3] = [9.592365732549323e-05, 0.00010156640385939285, 0.00010878986067143964, 0.00011680484974742778] + + # AW0.35 + etadict[0.35] = [4.2571092364245134e-05, 4.3477517618701676e-05, 4.5470584129928045e-05, 4.703784647692701e-05] + udict[0.35] = [0.00012342316773539683, 0.00013192822593190037, 0.00014235923481144142, 0.00015379692145652517] + + # AW0.4 + etadict[0.4] = [5.323485609901108e-05, 5.4537900644162293e-05, 5.7167439596640105e-05, 5.9214158702680804e-05] + udict[0.4] = [0.0001529937642777872, 0.00016508215913321422, 0.0001793914423707526, 0.00019493448522633737] + + # AW0.45 + etadict[0.45] = [6.472631243944558e-05, 6.648462274337002e-05, 6.983217354898414e-05, 7.240813873886258e-05] + udict[0.45] = [0.00018458861004526223, 0.00020099541348744964, 0.00021985768526435216, 0.0002401871752763583] + + # AW0.5 + etadict[0.5] = [7.704040349058261e-05, 7.931597268733693e-05, 8.346175778930112e-05, 8.66098675871236e-05] + udict[0.5] = [0.00021832119505192025, 0.00023978704772520992, 0.00026388291182004596, 0.00028967633373918765] + + # AW0.6 + etadict[0.6] = [0.00010416662253819254, 0.00010767626752352099, 0.00011366252334390949, 0.00011807899240159988] + udict[0.6] = [0.0002927943353365242, 0.00032653984000340043, 0.0003631294524618366, 0.0004018341415538591] + + # AW0.7 + etadict[0.7] = [0.00013466833304918773, 0.00013969100018099338, 0.00014785190156918837, 0.00015364912350309396] + udict[0.7] = [0.00037724871882803253, 0.00042596583137959873, 0.00047770290679888423, 0.0005318928744605742] + + # AW0.8 + etadict[0.8] = [0.00016856528843100577, 0.00017538639025084244, 0.000186070413359456, 0.00019333364006937035] + udict[0.8] = [0.0004717237067794361, 0.0005378805417322342, 0.000607397015329718, 0.0006795961390485136] + + # AW0.9 + etadict[0.9] = [0.00020582373206677287, 0.00021472546333813376, 0.000228291475531923, 0.00023708809655680776] + udict[0.9] = [0.0005756849200778193, 0.000661571021981174, 0.0007515118107239634, 0.0008442265987373026] + + # AW1 + etadict[1.0] = [0.0002463671245684956, 0.0002576225094509902, 0.00027443288940607956, 0.00028480125292143987] + udict[1.0] = [0.0006884093376880977, 0.0007961649840352896, 0.0009091866405515607, 0.0010249106255206322] + diff --git a/qjrms/data_lev5_dt025.py b/qjrms/data_lev5_dt025.py new file mode 100644 index 0000000..8f97137 --- /dev/null +++ b/qjrms/data_lev5_dt025.py @@ -0,0 +1,266 @@ +# peddle plots data for lev5_dt025 + +def input_lev5_dt025(etadict, udict, ppp, dts=45): + if ppp == 4: + # norms dumped every 0.25 day + + if dts == 45: + # AW0.25 + etadict[0.25] = [0.00019172505002870938, 0.00019197835413556745, 0.0001897347686963432, 0.00018679114403504505, 0.00018464439237177676, 0.00018539885968004886, 0.00019005484824206675, 0.0002011105430246463, 0.00021866938759237172, 0.00024402044894614291, 0.00029678435668739666, 0.000387895142621664] + udict[0.25] = [0.0002352164740786885, 0.00023825054501631495, 0.00024159915059955518, 0.00024356099949871866, 0.0002466136565916857, 0.00025059602872036225, 0.0002538920123726709, 0.0002617831996482438, 0.00028731483481026773, 0.0003104237828542605, 0.0003533129224085153, 0.0004355690907149478] + + # AW0.3 + etadict[0.3] = [0.00015594586318949864, 0.000156440778547122, 0.00015547944062973616, 0.0001543057304599513, 0.00015340030629222058, 0.00015408630073726116, 0.0001557976236425181, 0.00016255808854879358, 0.00016857062997111823, 0.00017015135628677526, 0.0001732269136467181, 0.00017626489939620652] + udict[0.3] = [0.00019754990633230713, 0.0002015523419928365, 0.00020596841636402012, 0.00021036191025248328, 0.00021595740883470873, 0.0002200460249114379, 0.00022192370326457937, 0.00022524803701969555, 0.00024362876177382153, 0.0002401415239153689, 0.00024541797181132314, 0.00025344994711149816] + + # AW0.35 + etadict[0.35] = [0.00012397739999069039, 0.00012593256118586597, 0.00012686837537172302, 0.00012810532517048155, 0.00012934481023651207, 0.00013169338173114485, 0.00013456001170682278, 0.0001453098122920706, 0.00015088463859255706, 0.00015350586975159474, 0.00015590462972343318, 0.00015686326129572402] + udict[0.35] = [0.0001811188139314193, 0.00018869665816691108, 0.00019716346870530998, 0.00020587405254634674, 0.00021601840340962065, 0.00022296765705379746, 0.00022601518563646476, 0.0002304255331569725, 0.00025639851741533, 0.0002506849313941693, 0.0002571118319982582, 0.00026583281763002106] + + # AW0.4 + etadict[0.4] = [9.931512705219623e-05, 0.00010236156974622044, 0.00010551893997383321, 0.00010958389957201217, 0.00011354050794537177, 0.00011800189887996694, 0.00012253434015093868, 0.00013896164343995716, 0.00014439707171859636, 0.00014874817153626968, 0.00015169888905026925, 0.00015306572980719127] + udict[0.4] = [0.00018009755978091804, 0.00019210556938050203, 0.0002058693930843092, 0.00022008896141334408, 0.00023571193236452228, 0.000246180578324369, 0.0002504812204127059, 0.00025630557835949633, 0.000290735313786566, 0.0002834975184617693, 0.00029232527875568907, 0.0003034494507550408] + + # AW0.45 + etadict[0.45] = [8.672797698081236e-05, 9.093132344367659e-05, 9.624604381961226e-05, 0.00010278740499617236, 0.00010948567758034829, 0.00011592890515826524, 0.00012198816190450162, 0.00014428592914370354, 0.00014900022585376287, 0.00015467495532811326, 0.00015791660804632604, 0.00015989425090608028] + udict[0.45] = [0.00019393022750488495, 0.00021116169802076797, 0.00023062017023302148, 0.000250667851864537, 0.00027186038728285717, 0.0002859098496412918, 0.0002913134181997814, 0.00029849905894971493, 0.0003410047413769202, 0.00033224654379448624, 0.0003435396581846239, 0.00035708344891678006] + + # AW0.5 + etadict[0.5] = [8.649406470200451e-05, 9.16066800013381e-05, 9.84832310845584e-05, 0.00010662254071267354, 0.00011571001968411365, 0.00012372153423482058, 0.00013093915760049597, 0.00015858341303237058, 0.0001618240736576734, 0.00016844413737832753, 0.0001717216858916528, 0.0001744303446031785] + udict[0.5] = [0.0002195065458275644, 0.00024232298266543893, 0.0002675833373197193, 0.00029356302210433995, 0.00032031254582254786, 0.00033799266895654365, 0.00034443349391056067, 0.00035301321000831326, 0.0004032918519568362, 0.00039305363306448075, 0.00040690256649427526, 0.0004229425442858994] + + # AW0.6 + etadict[0.6] = [0.00010724075545176787, 0.00011336164995532104, 0.00012203594171463803, 0.00013166517974445133, 0.00014496281001934416, 0.00015545489938071605, 0.00016441127767303438, 0.00020200273238494344, 0.0002002284626475138, 0.00020830203976425498, 0.00021125414575623767, 0.00021579576004998854] + udict[0.6] = [0.0002910480858739002, 0.00032615697990650915, 0.0003639698812786003, 0.0004028277572697323, 0.0004414454237373189, 0.00046707264014904284, 0.00047578233194386205, 0.00048759426818653217, 0.0005535642495474443, 0.0005405409407216015, 0.0005600640074543189, 0.0005816402512807639] + + # AW0.7 + etadict[0.7] = [0.00013700814673713087, 0.0001441907226298451, 0.00015460703028849997, 0.00016534597992848247, 0.00018349241282981303, 0.0001966696915773672, 0.000207445496684216, 0.0002558335356775167, 0.0002466089429225144, 0.00025612569736028205, 0.00025847383398647586, 0.00026546738848047015] + udict[0.7] = [0.0003768763067201173, 0.00042656854864912364, 0.0004792103149890396, 0.0005332210340310838, 0.0005854752746762066, 0.0006204839825670099, 0.0006320232284555833, 0.0006479452565584794, 0.0007305926282475765, 0.0007150760846857852, 0.000741237380638112, 0.0007692454145972663] + + # AW0.8 + etadict[0.8] = [0.00017035955866877197, 0.00017896809118908544, 0.00019154492370306088, 0.00020350072612968065, 0.00022756987527545693, 0.00024394359609849038, 0.0002568869343488713, 0.0003176031320683236, 0.0002987753687463076, 0.0003098334154652501, 0.00031135372550464984, 0.0003214590348050285] + udict[0.8] = [0.0004723047451333888, 0.0005391366009807364, 0.0006093034764997757, 0.0006810703747586221, 0.0007488991250007805, 0.0007948685685435655, 0.0008098834762326243, 0.0008308812799362146, 0.0009314183067715524, 0.000913749791018054, 0.0009475431345537389, 0.00098289402361623] + + # AW0.9 + etadict[0.9] = [0.0002072039700603294, 0.00021758703523781184, 0.00023273633676709236, 0.0002459917074531703, 0.00027703858153245946, 0.0002971051762422088, 0.00031258534644016886, 0.00038722687112230017, 0.00035691510832889855, 0.00036960545386431414, 0.00037009634836894105, 0.00038394242614014603] + udict[0.9] = [0.0005764116994431321, 0.000662815906766576, 0.0007532650400405178, 0.0008454036866942104, 0.000930658685242764, 0.0009891529075327146, 0.0010082967927638692, 0.0010353344501673092, 0.0011549782259655853, 0.0011355310115793748, 0.0011779064132643824, 0.0012214722752642308] + + # AW1 + etadict[1.0] = [0.00024748243543621225, 0.000259967858614627, 0.00027810006648965984, 0.0002927134609000639, 0.00033178449552837507, 0.00035602553755130506, 0.000374420285810741, 0.0004645777008325223, 0.0004211520932470046, 0.0004355753572649929, 0.00043486733412767553, 0.00045304811547618515] + udict[1.0] = [0.0006889296716806969, 0.000797124397772081, 0.0009105776063466077, 0.0010256439278499385, 0.0011300515586001982, 0.0012025898810844177, 0.0012265146253179235, 0.0012605487762849012, 0.0014004830780315583, 0.0013796443430766315, 0.0014314989873249044, 0.0014841038748596236] + + # AW1.5 + etadict[1.5] = [0.0004948644762504552, 0.0005220179009514453, 0.0005607798786789145, 0.0005814926588375447] + udict[1.5] = [0.0013615586680117999, 0.0016061552517632003, 0.0018729654755083238, 0.002138528469064926] + + # AW2 + etadict[2.0] = [0.0008068669918901613, 0.0008537376009026272, 0.0009205488360225369, 0.0009406444037092065] + udict[2.0] = [0.0021734190192496277, 0.002588037641604009, 0.0030610982727968445, 0.0035280620098710035] + + # AW2.5 + etadict[2.5] = [0.0011696010399132545] + udict[2.5] = [0.003080555206821207] + + # AW3 + etadict[3.0] = [0.0015718586936727056] + udict[3.0] = [0.00404982178884965] + + # AW4 + etadict[4.0] = [0.0024589170551881415] + udict[4.0] = [0.006074163627379366] + + elif dts == 22.5: + + # AW0.25 + etadict[0.25] = [0.00019089525457024936, 0.00019054178987282865, 0.0001873700242147273, 0.00018308488660323757, 0.0001799940210567588, 0.00017949393301530211, 0.00018298772153442955, 0.0001922235381099472, 0.00020879275760322653, 0.0002339012860672028, 0.0002874979584288238, 0.0003806309926567247, 0.0005487526072106459, 0.0008569847827365109, 0.0014215426390173495, 0.0024292428456551005, 0.004239398210271925, 0.0074636315488140394, 0.012891668943424693, 0.021483552811442288] + udict[0.25] = [0.00023459282000944866, 0.00023684543323454688, 0.00023941483384703262, 0.00024068507763667904, 0.00024245344576722755, 0.0002454413493166093, 0.0002474849878365266, 0.0002545108423385313, 0.00027756751887254806, 0.0003011457120777048, 0.00034391846003352643, 0.0004264024943234161, 0.0005889772046444654, 0.0008913820444718173, 0.001411096941983047, 0.0023370280075787524, 0.004059769395448219, 0.007136210137430151, 0.012468645211862155, 0.02124829807233449] + + # AW0.3 + etadict[0.3] = [0.00015486745802661573, 0.00015446601032130912, 0.00015224518541931867, 0.00014917291254741433, 0.0001471008692224306, 0.0001461080532902558, 0.00014608509472425942, 0.00014968339658839609, 0.0001534900135396921, 0.00015300392110851143, 0.00015434202970083293, 0.0001573823909878029, 0.00016299071213083868, 0.00017344564355499263, 0.0001956132588782172, 0.00023437659142208216, 0.0003022295719988502, 0.00041336753672986535, 0.0005732114743572542, 0.000777827419896309] + udict[0.3] = [0.00019668301606605743, 0.00019969200400017528, 0.0002030795304248079, 0.0002066976610660315, 0.00021064663198148983, 0.00021346583178068448, 0.0002136916789493553, 0.0002159493797165944, 0.00022996025494449913, 0.0002260901661450568, 0.00022979993480323383, 0.00023506663154426337, 0.00024185318669941116, 0.0002514127528945791, 0.00026905954525880744, 0.00029718266060718354, 0.00035466871935883724, 0.00044396089691029167, 0.000586166523218453, 0.0007916678286528909] + + # AW0.35 + etadict[0.35] = [0.0001225147323296931, 0.00012320478208716691, 0.00012245600702753218, 0.00012106596523657889, 0.00012098255777086803, 0.00012125270860313561, 0.00012194362307697167, 0.00012859596456712017, 0.00013128144017675504, 0.00013141542214242907, 0.0001315041391083229, 0.00013224121194215614, 0.00013291590706363107, 0.00013372855094342218, 0.00013580851134027485, 0.00013960511500005825, 0.00014409962344577148, 0.000148361663165403, 0.0001515698873656978, 0.00015115060015209617] + udict[0.35] = [0.00018002513961556208, 0.0001865022494753412, 0.00019380618714094497, 0.00020180618333046549, 0.0002101407568102654, 0.00021578498425270143, 0.00021709452192734136, 0.0002206710180744468, 0.00024140267851343244, 0.00023536823764605495, 0.00024022876063461437, 0.0002460020829312764, 0.00025277322828300955, 0.00025920345118157903, 0.0002676581522090481, 0.00027381768842008866, 0.00028597574583998043, 0.0002905193329984006, 0.0002992716793553816, 0.00030820047843193514] + + # AW0.4 + etadict[0.4] = [9.735866786721902e-05, 9.866730787270947e-05, 9.965987790483489e-05, 0.00010027523228390093, 0.00010296617322371279, 0.00010507603222834764, 0.00010713033545253981, 0.0001190109729480383, 0.0001209932774419298, 0.00012277496868427095, 0.0001231425081944016, 0.00012443074251891026, 0.00012475231507303022, 0.0001255879402527792, 0.00012748365407900468, 0.00013333113884383542, 0.00013850675928939415, 0.00014406043529370294, 0.00014656392996562008, 0.0001437600745252633] + udict[0.4] = [0.00017885151483094654, 0.00018975691995905107, 0.00020234572414457573, 0.00021601840749289913, 0.00022982655367004105, 0.00023908392978192524, 0.0002417239825092347, 0.00024707214203473264, 0.0002757792295659278, 0.0002683883161972543, 0.0002758057463161745, 0.00028414577106610167, 0.0002942338530876783, 0.0003036414712836826, 0.00031503298620091984, 0.00032378154004361555, 0.00033970010334378765, 0.00034624287729332725, 0.00035746686024202244, 0.0003687247702491804] + + # AW0.45 + etadict[0.45] = [8.435211282185606e-05, 8.641563770703833e-05, 8.925113748488138e-05, 9.17324785327517e-05, 9.753413152430407e-05, 0.00010161772048873116, 0.00010514841319925245, 0.00012292808097783898, 0.00012381332849133002, 0.00012702561267807576, 0.0001275738601183581, 0.00012968119144951998, 0.00012947515849965873, 0.00013039893610161055, 0.00013244263875035592, 0.0001409330775370273, 0.0001470226084346855, 0.00015434499620697355, 0.0001571855633341763, 0.0001528802795407842] + udict[0.45] = [0.00019265455766323552, 0.0002088657995900435, 0.0002272242078462682, 0.00024690588095459823, 0.00026635866921098574, 0.0002793293051286207, 0.0002832229265282608, 0.00029029513661770227, 0.00032682564061967064, 0.00031809165978925356, 0.0003281335541684367, 0.0003391056448755107, 0.00035268021138737166, 0.0003651624309459597, 0.00037985681615206263, 0.00039132133277644104, 0.00041127523572461806, 0.00042013508618914775, 0.0004344676073602198, 0.0004487463171752674] + + # AW0.5 + etadict[0.5] = [8.400043011508558e-05, 8.68287825325141e-05, 9.11897693289439e-05, 9.501535634588432e-05, 0.00010366560829083295, 0.00010946936086866694, 0.0001142646165080974, 0.00013748939422938007, 0.00013672142079996862, 0.00014103036600054126, 0.00014161425030072972, 0.00014464232658667042, 0.00014367746896909767, 0.00014459971102522915, 0.00014682700051644375, 0.00015796343385262275, 0.0001645734442437878, 0.00017331113118132895, 0.000176605442645465, 0.00017092947320906425] + udict[0.5] = [0.00021829292984490626, 0.0002402007690224856, 0.0002644656742566249, 0.00029023368863014486, 0.000315338106357129, 0.0003320659799991585, 0.00033715970453752046, 0.0003459533044572042, 0.0003901446201673761, 0.0003800896093121592, 0.0003928245950508902, 0.00040649761026432494, 0.0004237392156139494, 0.00043941387851974153, 0.00045770059019358987, 0.0004719550484612801, 0.0004960461786539353, 0.0005073424133368977, 0.0005250755254589663, 0.0005426081084708354] + + # AW0.55 + etadict[0.55] = [9.239816580570293e-05, 9.585922060089891e-05, 0.00010135015961335138, 0.00010604892634600844, 0.00011717076272827707, 0.00012442849705118834, 0.00013028071762194828, 0.0001585177048063533, 0.0001555324925236932, 0.00016073988852777308, 0.00016126296427163638, 0.00016528807573079832, 0.0001633616324307891, 0.00016421283307659418, 0.00016661891056771633, 0.0001804116971948058, 0.00018721642615776422, 0.00019712750781224138, 0.00020092478542195122, 0.00019390148454964687] + udict[0.55] = [0.0002517220452720026, 0.000279644802631283, 0.0003100627428643844, 0.0003421603096588997, 0.0003731037603026075, 0.0003937609429814913, 0.00040008261058468487, 0.0004106833453747982, 0.0004626053449862295, 0.0004512582130456669, 0.00046683404830964514, 0.0004833521247114887, 0.0005045277763002942, 0.0005235991629198723, 0.0005457990889550747, 0.0005630186499630723, 0.000591403178229954, 0.000605322588279463, 0.0006267691302279753, 0.0006478296572908417] + + # AW0.6 + etadict[0.6] = [0.00010510616840872629, 0.00010916729327893143, 0.00011563814106545126, 0.00012101498913686453, 0.0001345282135888479, 0.00014316796164162086, 0.0001500164439284261, 0.00018325242659365042, 0.00017749311976528363, 0.00018354052337866711, 0.0001839377634831886, 0.00018906824995879067, 0.00018596488508207764, 0.00018668806942403272, 0.00018925597181760327, 0.00020583990725822125, 0.00021256136536330287, 0.00022349999609434646, 0.0002278257278978705, 0.00021938414903964134] + udict[0.6] = [0.00029003893699008394, 0.00032444011723010865, 0.00036145628430423805, 0.00040033297708835043, 0.00043747544177965116, 0.0004623542489258573, 0.0004699957364943311, 0.0004825619555005804, 0.0005424341704186616, 0.0005298374490782298, 0.0005484596273448503, 0.0005680116551320657, 0.000593450359351688, 0.0006161801061613255, 0.0006426366287474913, 0.000663043323772151, 0.0006959108008846255, 0.0007126975470181164, 0.0007381780089478466, 0.0007630594401362882] + + # AW0.65 + etadict[0.65] = [0.00011969014025764945, 0.00012440745270458938, 0.00013188568495908244, 0.0001379115586639382, 0.0001539651767685967, 0.00016404920173084136, 0.00017192837179008593, 0.00021042108580313564, 0.00020133716456822973, 0.0002082313119238352, 0.00020844838668183043, 0.00021482321740944917, 0.0002103096054503601, 0.0002108482717519437, 0.00021355662182233752, 0.00023315477735939475, 0.00023952892012045276, 0.0002513846829982388, 0.00025626112167905895, 0.0002462821571671596] + udict[0.65] = [0.00033171740215674116, 0.00037317314522880953, 0.00041736286017842486, 0.0004635890969457927, 0.0005073752843168739, 0.0005368307871337467, 0.0005459193110388681, 0.0005606500974077537, 0.0006287595312012195, 0.0006149668254944191, 0.0006368681905131409, 0.0006596632403733283, 0.0006897240199272151, 0.0007164016176525342, 0.0007474695742952764, 0.0007713030711269491, 0.0008088543302337853, 0.0008287908061445789, 0.0008586255534572887, 0.0008876265966140832] + + # AW0.7 + etadict[0.7] = [0.00013528096898302773, 0.00014073499787826008, 0.00014930644561680088, 0.00015601507403755735, 0.0001748315029262725, 0.00018646865362282236, 0.00019544895948893815, 0.0002395765585418913, 0.000226636450603623, 0.00023439209285870376, 0.000234376670256367, 0.00024213286783452656, 0.00023598256729402876, 0.00023628190704787114, 0.00023909077263900124, 0.0002619323956084678, 0.00026774508655922095, 0.0002804231154467478, 0.00028587349288457253, 0.00027421071249736974] + udict[0.7] = [0.0003760528222930637, 0.0004251879830816003, 0.00047719140881974685, 0.0005313869084685468, 0.0005822956953487391, 0.000616706203971728, 0.0006273838331891254, 0.0006444830425174732, 0.0007211441201094862, 0.0007062209044228322, 0.0007316391471862965, 0.0007578951141365059, 0.0007929359128047241, 0.0008238538801448779, 0.0008598829853258863, 0.0008874042098082438, 0.0009298284442260402, 0.0009532032768724525, 0.0009877081820269234, 0.0010211282032393232] + + # AW0.8 + etadict[0.8] = [0.00016894772837441625, 0.0001761194863940882, 0.0001871594724435891, 0.00019530423335098395, 0.00022039876943634267, 0.00023549396102235838, 0.0002469214359073283, 0.0003035176739655828, 0.00028136748083156606, 0.0002909102660371908, 0.00029027241510411677, 0.0003012447500944555, 0.0002911110740735712, 0.0002907648788725489, 0.00029368605208052764, 0.00032380038568352874, 0.0003277940538944166, 0.0003417977964696545, 0.00034848476421354735, 0.0003330495991023017] + udict[0.8] = [0.0004716253913574639, 0.000538016169397229, 0.0006076683529889641, 0.000679745010035239, 0.0007463277592947288, 0.0007918125686590564, 0.0008061178949764294, 0.0008286265188429123, 0.0009233339670385539, 0.0009063749961507994, 0.0009395475239775895, 0.0009733713140168811, 0.0010194571979265238, 0.0010597408699745095, 0.001106741769978978, 0.0011423739382390807, 0.0011951026605467605, 0.0012263128422204679, 0.0012710776575134677, 0.0013142124840527685] + + # AW0.9 + etadict[0.9] = [0.00020603710694890923, 0.00021522988871058597, 0.00022910062244988012, 0.00023874773250965095, 0.00027109444589231763, 0.00029009829947912333, 0.00030430457921364144, 0.0003749772863390287, 0.0003418006465161907, 0.00035320097039937004, 0.00035174301826115264, 0.00036650148842992154, 0.00035149299624963326, 0.0003502946182885271, 0.00035320930878890883, 0.000391627232579431, 0.00039297527995698804, 0.0004078897486288345, 0.0004159443886896163, 0.00039625907327916896] + udict[0.9] = [0.0005758419790643911, 0.0006618973546122419, 0.0007519286695637666, 0.000844472285662807, 0.0009285597737979656, 0.000986657178438998, 0.00100520441045189, 0.0010340170968212816, 0.001148002133084035, 0.0011293463634755193, 0.001171198227573016, 0.0012134283769598807, 0.0012719481434737983, 0.0013227389249419097, 0.0013820673831187351, 0.001426761573910282, 0.0014904944033317163, 0.0015308636920662799, 0.0015870662469735833, 0.0016410473731440541] + + # AW1 + etadict[1.0] = [0.0002465077825649911, 0.0002580063913572198, 0.00027507368829133595, 0.0002862605494824938, 0.0003268420138127172, 0.00035019718145032905, 0.00036752336925113116, 0.0004538543618733323, 0.0004080411047615862, 0.00042137831663594183, 0.0004189257113076624, 0.00043801765530125436, 0.00041729882199528133, 0.0004150607471777714, 0.0004178892057766536, 0.0004656829058739566, 0.0004635984543380572, 0.0004790404782025154, 0.0004886022624529476, 0.0004643079294847304] + udict[1.0] = [0.000688444703603655, 0.000796364077600347, 0.0009094757180283031, 0.0010250198502876522, 0.0011283233520766223, 0.0012005338846198174, 0.0012239464729765454, 0.001259966529450577, 0.001394411354589604, 0.0013744218510164188, 0.0014258317995124294, 0.001477266744058962, 0.0015495439942292244, 0.0016119321387287459, 0.0016848910935132026, 0.0017395212057120875, 0.0018149481004542808, 0.0018658369904382464, 0.0019345980022841983, 0.002000504201840423] + + # AW1.5 + etadict[1.5] = [0.0004944160589213959, 0.0005211464377925122, 0.0005594490618106062, 0.0005773136898120602] + udict[1.5] = [0.0013613141112754096, 0.0016058176590490047, 0.0018724884003496795, 0.0021387143493108445] + + # AW2 + etadict[2.0] = [0.00080662295026701, 0.0008532747216407442, 0.0009198518201430308, 0.0009372941936944963] + udict[2.0] = [0.0021732846084255913, 0.002587855431844976, 0.003060847304399614, 0.003528547754726256] + + # AW2.5 + etadict[2.5] = [0.0011694513695500637, 0.001238703155586606, 0.0013377737787137246, 0.0013421849711870337] + udict[2.5] = [0.003080484453992819, 0.003683021659171546, 0.004395123526996382, 0.005099452000122994] + + # AW3 + etadict[3.0] = [0.0015717606205259012, 0.0016643340240719696, 0.0017976322923969163, 0.001774192554594024] + udict[3.0] = [0.004049792123547585, 0.0048447708655605624, 0.005809172084705945, 0.006769336732863047] + + # AW4 + etadict[4.0] = [0.002458871012742821, 0.0025942278130149828, 0.0027945120743497675, 0.0026713942154345167] + udict[4.0] = [0.0060741795374788105, 0.007230552037210138, 0.008681310328001597, 0.010158888435980989] + + # AW5 + etadict[5.0] = [0.003406604316056958, 0.0035743934576828065, 0.0038341608005189533, 0.0035605665228714972] + udict[5.0] = [0.008095159798591368, 0.009551194760125642, 0.011409337941485784, 0.013354836683569725] + + # AW6 + etadict[6.0] = [0.004361103207718568, 0.004549447574513272, 0.004860346100943508, 0.00439973314431454] + udict[6.0] = [0.01001027425304973, 0.011702838573859111, 0.013867095076488523, 0.016197507208314522] + + # AW7 + etadict[7.0] = [0.005276329521929487, 0.005473363230565641, 0.0058300750935708695, 0.005162535749949409] + udict[7.0] = [0.01174376568968075, 0.013633252886060104, 0.016011733935347258, 0.01863814778884177] + + # AW8 + etadict[8.0] = [0.006121489052999652, 0.006314129357324369, 0.006715594396814507, 0.005836117330142164] + udict[8.0] = [0.013248367634802216, 0.015322474435914177, 0.01784696941533442, 0.02069016681335039] + + # AW9 + etadict[9.0] = [0.006883471822124988, 0.007055484673469818, 0.007504550111364294, 0.00641845480965171] + udict[9.0] = [0.014511765636084214, 0.016772088363527483, 0.01939918212001251, 0.022395116399817026] + + # AW10 + etadict[10.0] = [0.0075632875384578505, 0.007694145443822945, 0.008196771071888006, 0.006914639744218031] + udict[10.0] = [0.015554354867746046, 0.01799772974035212, 0.020703871927554063, 0.023802867997974653] + + elif dts == 10: + + # AW0.25 + etadict[0.25] = [0.00019075550850932707, 0.00019028048773325553, 0.0001869683472375965, 0.00018247897422313535, 0.00017927944566418293, 0.00017862511583062452, 0.00018196652699114288, 0.00019084469773422363, 0.00020722405192806294, 0.00023232866883604112, 0.00028608520340569365, 0.00037953598565440875, 0.0005478612759864074, 0.000856349239218586, 0.0014211405539836263, 0.002428978043925917, 0.00423921014425452, 0.00746350654087622, 0.012891594335515497, 0.021483504383244253] + udict[0.25] = [0.0002344969842194864, 0.00023660059828600237, 0.00023904307549582808, 0.00024023675717912158, 0.00024181862665710344, 0.00024468326860352336, 0.0002465819632273748, 0.0002535329477786623, 0.00027596364780712766, 0.0002997381322968507, 0.00034251922842700724, 0.0004250838700250785, 0.0005879919993648725, 0.000890666776328187, 0.0014105766284986268, 0.002336663241713199, 0.00405948799307341, 0.007136045441439411, 0.012468540373805513, 0.021248232304012342] + + # AW0.3 + etadict[0.3] = [0.00015467224235807272, 0.00015408626165837373, 0.00015165522283804516, 0.00014825495787035398, 0.00014603815043519352, 0.00014480621831488677, 0.00014451431784957708, 0.00014741015584249757, 0.00015075006512081069, 0.0001499289723471659, 0.00015100745906344523, 0.00015407979711993757, 0.00015918581522997416, 0.0001695497558509022, 0.0001919885786454655, 0.0002311743807310715, 0.00029921330698720556, 0.00041089660681239954, 0.0005713070692283174, 0.0007764809122709356] + udict[0.3] = [0.00019653318056079498, 0.00019934259969215312, 0.00020255174156505028, 0.00020608143235950694, 0.00020976139603896252, 0.00021240187931177254, 0.00021239961782544076, 0.00021456464991761136, 0.0002274355763802693, 0.0002236461796289898, 0.0002271262181444474, 0.00023198882975709317, 0.00023882497283357526, 0.0002482140474492272, 0.00026591516903101865, 0.0002938910352685029, 0.0003511443592694178, 0.0004413332848375734, 0.0005840206712851006, 0.0007898062652644983] + + # AW0.35 + etadict[0.35] = [0.00012223032307693215, 0.00012265153465122224, 0.00012159890167081025, 0.00011970497983711758, 0.00011945255526423149, 0.00011939015109861986, 0.00011969927543927692, 0.00012532883621878995, 0.00012733192871615718, 0.00012700108505441104, 0.0001266708435375767, 0.00012740061789809693, 0.00012713908279376166, 0.0001274657673267004, 0.0001293124195074528, 0.0001329349548368546, 0.00013613533883091188, 0.00013965788823840715, 0.0001424299114617463, 0.00014243626792295952] + udict[0.35] = [0.00017981467302161195, 0.0001860657351749172, 0.00019315705385079885, 0.00020108082957971075, 0.00020909146608142113, 0.00021453614772774958, 0.00021558115458945358, 0.00021911522304520243, 0.00023842494312215196, 0.00023248397380858067, 0.00023709430331035484, 0.00024238682892297104, 0.00024921201586731973, 0.00025538355075482443, 0.00026381164552477667, 0.00026942199460873174, 0.00028053931073062716, 0.0002855704341512, 0.0002940772344219085, 0.000302261561962561] + + # AW0.4 + etadict[0.4] = [9.695230012539394e-05, 9.7880709724102e-05, 9.84553145047023e-05, 9.83435321342855e-05, 0.00010088771921847186, 0.00010258428338307476, 0.00010415738944019605, 0.0001147886835306782, 0.00011588149521442909, 0.000117137131435113, 0.00011697061792542795, 0.00011829060876145704, 0.0001173704912140161, 0.00011757988501462843, 0.0001191775272012409, 0.0001249684561936633, 0.0001284900809558843, 0.00013320276127651488, 0.00013511092799373535, 0.00013271289202116548] + udict[0.4] = [0.0001785922839009304, 0.000189268752684673, 0.000201634209210307, 0.00021526017369014768, 0.00022872041799096036, 0.00023778146545777267, 0.00024015140638452, 0.00024552853372006035, 0.00027266324373771233, 0.00026539050679918124, 0.000272570188567955, 0.00028042520506553866, 0.0002905972310733642, 0.0002997592385345967, 0.0003111660809535718, 0.0003193530438776779, 0.0003341862216315663, 0.00034128222822595543, 0.0003522513181607449, 0.00036274206267374097] + + # AW0.45 + etadict[0.45] = [8.383137084572909e-05, 8.54146085431053e-05, 8.774519433853754e-05, 8.930550013409008e-05, 9.505703737530837e-05, 9.87026473892923e-05, 0.00010171167871708885, 0.0001181853787166893, 0.00011804078934204461, 0.00012072895422313174, 0.00012067748920102185, 0.00012287383593000283, 0.0001212203756606789, 0.00012143959883404764, 0.00012316806372793154, 0.00013177270052406776, 0.00013601377209040947, 0.0001425064192176642, 0.00014471617375924056, 0.00014081781320472755] + udict[0.45] = [0.00019237457705696228, 0.00020837237460070453, 0.00022651564288421995, 0.0002461822005909875, 0.00026528375607131135, 0.00027807120659381753, 0.0002817066659951273, 0.0002888787840158426, 0.00032377064937957423, 0.00031517802858617097, 0.00032499942403355417, 0.00033550076822255715, 0.00034917303453217816, 0.00036142442488321184, 0.00037616476336483354, 0.0003870762255223813, 0.00040594053464825355, 0.00041538964260798934, 0.0004294644155520233, 0.0004429819235842859] + + # AW0.5 + etadict[0.5] = [8.343246455123903e-05, 8.574112303092507e-05, 8.957394504160119e-05, 9.238131198525067e-05, 0.00010109452824659496, 0.000106478782450309, 0.00011076176843837011, 0.00013269639579048265, 0.00013084468176046337, 0.00013465528657756226, 0.0001346203591284716, 0.00013778399474443428, 0.00013528567948731393, 0.00013547975677042634, 0.00013740112471371485, 0.0001487643099817244, 0.00015342824392843132, 0.00016134451281208596, 0.0001640164638862031, 0.00015876950466888409] + udict[0.5] = [0.00021801630910311316, 0.00023973272134705215, 0.0002637984123948442, 0.000289577621575423, 0.00031433629190573387, 0.0003308959299627593, 0.00033574991055146874, 0.0003447077683824996, 0.0003872396739350591, 0.00037734602390090613, 0.0003898770339772469, 0.00040309910231726883, 0.0004204420551279946, 0.0004358988721032061, 0.000454254664337789, 0.0004679702189396299, 0.0004909839784842453, 0.0005028896843476995, 0.0005203614753905057, 0.0005371446635415579] + + # AW0.55 + etadict[0.55] = [9.184754276171448e-05, 9.480277282395008e-05, 9.978522604777583e-05, 0.0001034442573993417, 0.00011470864670179064, 0.00012157571736964871, 0.00012694310407256835, 0.00015391163566032097, 0.00014984600593328671, 0.00015458327646267761, 0.00015449331922403302, 0.00015868515933191646, 0.00015521010484029804, 0.00015533891992463092, 0.00015746086719977702, 0.00017153676698114357, 0.0001763482869540254, 0.00018543623281874833, 0.00018863654090636522, 0.000182082764564045] + udict[0.55] = [0.00025146093677973176, 0.00027921359717783284, 0.0003094495308106327, 0.00034157982964016934, 0.0003721857845384262, 0.00039268899684423577, 0.0003987901884207545, 0.000409613050390648, 0.00045987720336797527, 0.0004487082845900882, 0.00046409517947830384, 0.0004801829634870539, 0.0005014595235993158, 0.0005203246389822809, 0.0005426126911734693, 0.0005593082759656023, 0.0005866350769696053, 0.0006011780712344799, 0.0006223593305705168, 0.0006426835186913124] + + # AW0.6 + etadict[0.6] = [0.00010459745719584187, 0.0001081868534082571, 0.00011418334930411073, 0.00011853086093962717, 0.00013224212516520624, 0.00014052028701293318, 0.00014691570070081116, 0.00017890580534879938, 0.0001720975030368215, 0.00017770288856665901, 0.00017750300421659474, 0.00018282180001107857, 0.00017818522343688214, 0.00017820369005236772, 0.00018051511914983173, 0.00019741275862189092, 0.00020211847288032994, 0.00021222993568875123, 0.00021598926777711053, 0.00020806616981687754] + udict[0.6] = [0.00028979737143732074, 0.0003240471814985038, 0.00036089773157713025, 0.0003998255908576854, 0.0004366393505915333, 0.00046137735681043624, 0.0004688165589279621, 0.00048165753566985426, 0.0005398843584955243, 0.0005274801735964443, 0.0005459272277392359, 0.0005650696161718631, 0.0005906071219417994, 0.0006131413337558845, 0.0006397027268777878, 0.0006595999084313178, 0.0006914324270360428, 0.0007088548930221997, 0.0007340661301036057, 0.0007582241489816981] + + # AW0.65 + etadict[0.65] = [0.00011922612333668693, 0.00012350883284406564, 0.00013054891338831314, 0.00013556513858963432, 0.00015186219657043701, 0.0001616125493446312, 0.00016907073478003755, 0.00020634272876929744, 0.00019625485179995014, 0.00020273498816564557, 0.00020237482894047102, 0.0002089539353754011, 0.0002029357349705481, 0.00020279191149858537, 0.00020527477007895785, 0.0002252075653347755, 0.00022955675314963221, 0.00024058242241961267, 0.00024492461373715305, 0.00023551718218139253] + udict[0.65] = [0.0003314957334174864, 0.00037281629788510747, 0.0004168554767022673, 0.00046314914028914087, 0.0005066151849317877, 0.0005359419504160726, 0.000544844764476112, 0.0005598983965952194, 0.0006263805105761655, 0.0006127926227367607, 0.0006345316614551058, 0.0006569375697135349, 0.0006870942265174094, 0.000713586423516598, 0.0007447744074356133, 0.0007681120063054146, 0.0008046522771893212, 0.0008252360129902329, 0.000854797870910544, 0.0008830878433261736] + + # AW0.7 + etadict[0.7] = [0.00013485854473066996, 0.00013991326795621464, 0.00014808121400697834, 0.00015380180216275426, 0.0001729017647706471, 0.00018423150472465276, 0.00019282181482233808, 0.00023575619468340066, 0.00022186461587028647, 0.00022923357730700878, 0.00022866249184842595, 0.00023663526900945936, 0.0002290156458738415, 0.00022865672608366266, 0.00023127249687324684, 0.0002544652362874113, 0.0002582529786580991, 0.00027010021222370183, 0.0002750486786517812, 0.00026401187095811556] + udict[0.7] = [0.00037584993945763434, 0.00042486404409917765, 0.0004767306412179393, 0.0005310080490960387, 0.000581604751580591, 0.0006158974983991028, 0.0006264042369870191, 0.0006438699404829569, 0.0007189249213550944, 0.0007042170398009332, 0.0007294847597818239, 0.0007553713818802787, 0.0007905049179828437, 0.0008212469981511666, 0.0008574098729039305, 0.0008844474763749365, 0.0009258851698974058, 0.000949918435363862, 0.00098414713917041, 0.0010168677505365729] + + # AW0.8 + etadict[0.8] = [0.00016859702182943018, 0.00017543258090600456, 0.00018613170137718097, 0.00019333140978444938, 0.00021877783539933404, 0.0002336129441951928, 0.00024470788482967496, 0.0003001669056216627, 0.00027718433117670876, 0.0002863932924957234, 0.00028524589343718865, 0.0002964490288140258, 0.000284932461636343, 0.00028398039358797897, 0.0002867774183664258, 0.0003172663456326213, 0.0003192573531636616, 0.00033243568352671435, 0.0003386852614896919, 0.00032399076999324914] + udict[0.8] = [0.00047145505349206724, 0.0005377485076766615, 0.0006072875356557945, 0.0006794705519576535, 0.0007457558005654889, 0.0007911419389207616, 0.0008053012402737598, 0.000828251863211763, 0.0009213999350271521, 0.0009046730412208119, 0.0009377161304007435, 0.0009712088871926974, 0.0010173803703412536, 0.001057505578011094, 0.0011046642187194729, 0.0011398343044870779, 0.0011916244352105122, 0.0012235144999994173, 0.001267997993486055, 0.0013104546478271842] + + # AW0.9 + etadict[0.9] = [0.0002057443741290196, 0.00021465473246885632, 0.00022823822052667772, 0.00023698125949499606, 0.000269733658107118, 0.0002885176998475541, 0.0003024418691761343, 0.00037202985238141373, 0.0003381483556623032, 0.0003492641683651207, 0.00034734421310133007, 0.00036233597178896227, 0.0003460453049733338, 0.00034429608040667645, 0.0003471576658001087, 0.0003859624875123529, 0.0003853538540083638, 0.0003994578791488526, 0.00040713683643466063, 0.0003883111054741528] + udict[0.9] = [0.0005756975322584559, 0.00066167486100456, 0.0007516123517311759, 0.0008442816096817676, 0.0009280842523136143, 0.0009860987254918176, 0.0010045192598385183, 0.0010338354308991819, 0.001146309059650748, 0.0011278974447951476, 0.0011696378553418955, 0.0012115727926647487, 0.0012701704455884224, 0.0013208180102326269, 0.0013803239605235237, 0.0014245739203859614, 0.0014874133414347669, 0.0015284820993291261, 0.0015844001926606497, 0.0016377217119539886] + + # AW1 + etadict[1.0] = [0.0002462615095927441, 0.0002575229228889978, 0.0002743480549636519, 0.0002846684070437557, 0.0003256974400373494, 0.0003488666132894151, 0.0003659539929939778, 0.00045124617370211734, 0.0004048551293191489, 0.00041795304118673695, 0.00041508501181472616, 0.00043440350345660267, 0.0004125103764060768, 0.0004097763626685839, 0.0004126222598975333, 0.00046080586779019664, 0.000456826756392541, 0.00047148200613602556, 0.0004807249622507283, 0.0004574099563880565] + udict[1.0] = [0.0006883207953869788, 0.0007961778206466464, 0.0009092113742572904, 0.001024896222068802, 0.0011279258340927878, 0.001200066391286624, 0.0012233671448046038, 0.0012599407141000946, 0.0013929203069677218, 0.0013731834235767412, 0.0014244972195403, 0.001475670067093331, 0.0015480170986037095, 0.0016102752174775952, 0.0016834278137507915, 0.001737628817680415, 0.0018122036522772098, 0.001863809252106644, 0.001932284359384059, 0.001997547012170488] + + # AW1.5 + etadict[1.5] = [0.0004943001583269142, 0.000520924303750505, 0.0005591169584817984, 0.0005762384433811702] + udict[1.5] = [0.0013612501529181513, 0.0016057319366452412, 0.0018723686862437148, 0.002138775087701487] + + # AW2 + etadict[2.0] = [0.000806559093032144, 0.0008531545065002386, 0.0009196736035709384, 0.0009364143891798927] + udict[2.0] = [0.0021732490445340075, 0.002587808289517647, 0.003060782694209345, 0.003528680818286671] + + # AW2.5 + etadict[2.5] = [0.0011694119134887547, 0.0012386288228031738, 0.0013376644073925597, 0.0013413773131614518] + udict[2.5] = [0.0030804655893087985, 0.0036829920172781858, 0.004395083567888816, 0.005099621143605352] + + # AW3 + etadict[3.0] = [0.0015717346471584457, 0.001664283987050717, 0.0017975590140842097, 0.0017734081720882362] + udict[3.0] = [0.004049784142118397, 0.00484475064025152, 0.0058091451738200486, 0.0067695288433221226] + + # AW4 + etadict[4.0] = [0.0024588587530285926, 0.0025942014114423563, 0.0027944735665192534, 0.002670601530046808] + udict[4.0] = [0.00607418370658846, 0.007230541211007026, 0.008681296233126072, 0.010159112738140148] + + # AW5 + etadict[5.0] = [0.003406598462703586, 0.003574377631610394, 0.003834137709767406, 0.003559746497083284] + udict[5.0] = [0.008095170258729599, 0.009551188299158216, 0.011409329734482542, 0.013355084796769685] + + # AW6 + etadict[6.0] = [0.004361100865210791, 0.004549437512629054, 0.004860331352226306, 0.004398891680557741] + udict[6.0] = [0.01001028932090048, 0.011702834579484636, 0.013867090221042667, 0.016197773035343983] + + # AW7 + etadict[7.0] = [0.005276329403754867, 0.0054733568663750945, 0.005830065654939318, 0.005161683162285115] + udict[7.0] = [0.011743784835573388, 0.013633250531169061, 0.016011731362027784, 0.01863842637240092] + + # AW8 + etadict[8.0] = [0.006121490359056911, 0.006314125372192127, 0.006715588318385644, 0.005835261878091111] + udict[8.0] = [0.013248390394007457, 0.015322473166078834, 0.017846968401480097, 0.020690453856774513] + + # AW9 + etadict[9.0] = [0.006883473950065505, 0.007055482120688352, 0.007504545994541926, 0.006417603152134284] + udict[9.0] = [0.014511791346492766, 0.016772087759757068, 0.01939918210182068, 0.022395408045714958] + + # AW10 + etadict[10.0] = [0.007563290065444042, 0.00769414371302699, 0.00819676803681379, 0.006913797472505049] + udict[10.0] = [0.015554382672490962, 0.01799772952670675, 0.020703872524559786, 0.023803160976491333] diff --git a/qjrms/data_lev5_dt0375.py b/qjrms/data_lev5_dt0375.py new file mode 100644 index 0000000..9a0298f --- /dev/null +++ b/qjrms/data_lev5_dt0375.py @@ -0,0 +1,126 @@ +# peddle plots data for lev5_dt0375 + +def input_lev5_dt0375(etadict, udict, ppp, dts=45): + if ppp == 4: + # norms dumped every 0.25 day + + if dts == 22.5: + + # AW0.375 + etadict[0.375] = [0.0002764668621849686, 0.0003023548847734355, 0.00031330744288794775, 0.0003211613260047293] + udict[0.375] = [0.00036065475086278023, 0.000385203534511741, 0.0003973900542040997, 0.00040668959691644396] + + # AW0.4125 + etadict[0.4125] = [0.00024295125457962267, 0.0002675897153312497, 0.00027715478474604847, 0.00028268620963743744] + udict[0.4125] = [0.00032921669103865155, 0.00035447796452342317, 0.0003679072966651552, 0.0003782028975484377] + + # AW0.45 + etadict[0.45] = [0.00021705602264140704, 0.00023994585010858903, 0.00024903572496854347, 0.0002542729065495491] + udict[0.45] = [0.0003095606471221197, 0.00033594425810508035, 0.0003524296364224106, 0.00036667245188924105] + + # AW0.4875 + etadict[0.4875] = [0.00019643519778602433, 0.00021700107947011712, 0.00022574126927882686, 0.00023101401551628816] + udict[0.4875] = [0.0002995452050282037, 0.00032747942301477917, 0.0003479408328839486, 0.000367178211170296] + + # AW0.525 + etadict[0.525] = [0.0001796267218826777, 0.00019759747971534464, 0.00020602815949989024, 0.00021137406727763622] + udict[0.525] = [0.00029792603538442294, 0.0003280893695857168, 0.00035320146224005817, 0.0003780094055014392] + + # AW0.5625 + etadict[0.5625] = [0.0001661504662202764, 0.00018157661870095887, 0.00018982739012478653, 0.00019529391646582546] + udict[0.5625] = [0.00030399123291961067, 0.0003372207787369675, 0.00036751766199434274, 0.00039824489234316265] + + # AW0.6 + etadict[0.6] = [0.00015628391720596985, 0.00016943288648364188, 0.00017772484488993488, 0.00018343204752984025] + udict[0.6] = [0.0003171244618903795, 0.0003542538367078116, 0.0003901357154264304, 0.0004269938118179022] + + # AW0.6375 + etadict[0.6375] = [0.00015057947215279486, 0.00016183750295740466, 0.00017040911846206094, 0.00017648225193121856] + udict[0.6375] = [0.0003365328957962195, 0.0003782819345210976, 0.0004200340123677045, 0.0004631578687509413] + + # AW0.675 + etadict[0.675] = [0.00014934650784075693, 0.0001591659331139501, 0.00016821134839921422, 0.00017472862723607203] + udict[0.675] = [0.0003612410942718111, 0.0004081979451026498, 0.0004560444950064276, 0.0005055502546715767] + + # AW0.7125 + etadict[0.7125] = [0.00015236623800948527, 0.0001612270592600451, 0.0001708839372483343, 0.0001778738099407952] + udict[0.7125] = [0.0003902233365783387, 0.0004428770700061947, 0.0004970456766754519, 0.0005530795915784146] + + # AW0.75 + etadict[0.75] = [0.00015896611591199668, 0.0001673291696037965, 0.00017769920999389333, 0.00018516900078154025] + udict[0.75] = [0.00042255385647296036, 0.00048133011832148935, 0.0005420799456578253, 0.0006048437821811413] + + # AW0.825 + etadict[0.825] = [0.00017963128227777716, 0.00018811252088772414, 0.00020017124250969843, 0.00020862046660097297] + udict[0.825] = [0.0004944861928530654, 0.0005666527746912619, 0.0006414962983905907, 0.0007185336764244586] + + # AW0.9 + etadict[0.9] = [0.0002061412183397661, 0.00021568278879262613, 0.00022975175846708034, 0.00023924956300152715] + udict[0.9] = [0.0005733174467903793, 0.0006602686267997933, 0.0007506198471852471, 0.0008432211923890386] + + # AW0.975 + etadict[0.975] = [0.0002358678755480445, 0.0002469407185256142, 0.000263296976271812, 0.0002739185329452016] + udict[0.975] = [0.0006574201833818061, 0.0007604279909242868, 0.0008677846142319988, 0.0009773391974974095] + + elif dts == 10: + + # AW0.375 + etadict[0.375] = [0.00027650159606670095, 0.00030210808113065367, 0.0003128818086574182, 0.0003204697848134698] + udict[0.375] = [0.0003606791193651364, 0.0003850078726478931, 0.000397005322809595, 0.00040623395177133296] + + # AW0.4125 + etadict[0.4125] = [0.000242961475403071, 0.00026729506098841513, 0.00027665370369559287, 0.0002818599734487687] + udict[0.4125] = [0.00032921578237872447, 0.00035424863827123197, 0.0003674728078322617, 0.00037770057535862697] + + # AW0.45 + etadict[0.45] = [0.00021703332883940763, 0.0002395957946827902, 0.0002484517598800143, 0.0002533016929161275] + udict[0.45] = [0.00030952961345772647, 0.00033568106555571326, 0.0003519520439043436, 0.0003661401211876713] + + # AW0.4875 + etadict[0.4875] = [0.00019637218714922583, 0.00021658874484634027, 0.00022506643034514892, 0.00022988199228044794] + udict[0.4875] = [0.0002994819567157518, 0.00032718587308590654, 0.00034743083916350363, 0.00036663304047262113] + + # AW0.525 + etadict[0.525] = [0.00017951752864751698, 0.00019711713073887824, 0.0002052554940506727, 0.0002100647076407857] + udict[0.525] = [0.0002978318187557272, 0.0003277726437788226, 0.00035267308400260063, 0.00037746877643375724] + + # AW0.5625 + etadict[0.5625] = [0.0001659913827298096, 0.00018102544056927968, 0.00018895430663123282, 0.0001937968489493955] + udict[0.5625] = [0.0003038702991873141, 0.0003368904417965483, 0.00036698589227653425, 0.0003977241700889247] + + # AW0.6 + etadict[0.6] = [0.00015607466793817823, 0.00016881405235011221, 0.00017675796627263747, 0.00018175241570221457] + udict[0.6] = [0.00031698296144909904, 0.000353919751006107, 0.00038961374224722627, 0.00042650441322448444] + + # AW0.6375 + etadict[0.6375] = [0.00015032473911363934, 0.0001611630226949325, 0.00016936806467918088, 0.00017464788624983765] + udict[0.6375] = [0.00033637747359580684, 0.0003779524287436601, 0.00041953145394541864, 0.00046270664396513513] + + # AW0.675 + etadict[0.675] = [0.00014905608970652083, 0.00015845619358329283, 0.00016712709840512326, 0.0001727877982476562] + udict[0.675] = [0.00036107775136929443, 0.00040787892081856726, 0.0004555670734605503, 0.0005051400753713179] + + # AW0.7125 + etadict[0.7125] = [0.0001520528555598505, 0.00016050590816855224, 0.00016979112861677023, 0.00017588280415077335] + udict[0.7125] = [0.0003900568788249539, 0.00044257208555780066, 0.0004965959822560578, 0.0005527105776756642] + + # AW0.75 + etadict[0.75] = [0.0001586421337977229, 0.00016661758696216454, 0.00017662726648699927, 0.00018317741866522526] + udict[0.75] = [0.00042238783519978187, 0.0004810409379390843, 0.000541658464543972, 0.0006045144491721423] + + # AW0.825 + etadict[0.825] = [0.0001793125423075679, 0.00018745748927627174, 0.0001991913156732257, 0.00020671828954194] + udict[0.825] = [0.0004943277025190604, 0.0005663962563558012, 0.0006411284638302982, 0.0007182766665292911] + + # AW0.9 + etadict[0.9] = [0.0002058456573880613, 0.0002151003021559511, 0.0002288828968591213, 0.00023747964982175784] + udict[0.9] = [0.0005731709991120326, 0.0006600428947536359, 0.0007502994183408467, 0.0008430262917632789] + + # AW0.975 + etadict[0.975] = [0.00023560130795611053, 0.0002464280415529899, 0.00026253274949383836, 0.0002722797103620505] + udict[0.975] = [0.0006572872760419834, 0.0007602298323566737, 0.0008675050335882126, 0.0009771970250859942] + + # AW1.05 + etadict[1.05] = [0.00026750803012079677, 0.0002801503162859563, 0.0002988152377983499, 0.0003097487310469405] + udict[1.05] = [0.0007460151727225463, 0.0008662009770843192, 0.0009919967361278902, 0.001120058022901152] + diff --git a/qjrms/plot_compare_dt.py b/qjrms/plot_compare_dt.py new file mode 100644 index 0000000..27f5bd7 --- /dev/null +++ b/qjrms/plot_compare_dt.py @@ -0,0 +1,210 @@ +import numpy as np +import matplotlib.pyplot as plt +import data_lev5_dt025 +import data_lev5_dt0125 +import data_lev5_dt0375 +from data_lev5_dt025 import * +from data_lev5_dt0125 import * +from data_lev5_dt0375 import * + +# standard model results +eta_1350s = [0.00186908343558815, 0.0029236867056528708, 0.004092992645657903, 0.004259656570998618] +u_1350s = [0.0020939275941023795, 0.0032455969161292696, 0.004584794354643949, 0.006699830988348994] + +eta_900s = [0.0011678662042723888, 0.0017860061124668875, 0.002234454669789315, 0.00274443210083982] +u_900s = [0.0012973803949937785, 0.0019736018123054943, 0.0024921658929822365, 0.003069718801010646] + +eta_450s = [0.000482154999575752, 0.0007650883758127529, 0.0010018594716208551, 0.001313043595896499] +u_450s = [0.0005315923730401088, 0.0008401858482484554, 0.0011048694866359933, 0.0012381093634108319] + +# parameters +PPP = 4 +DTS = 22.5 +DAY_MAX = 1.0 +DAYS_TO_PLOT = [1.0] +AVERAGING_WINDOW_MAX0 = 1.0 +AVERAGING_WINDOW_MAX1 = 1.0 +AVERAGING_WINDOW_MAX2 = 1.0 +LOGLOG = True +LINEWIDTH = 1 +DRAW_ZOOM = False +AVERAGING_WINDOW_ZOOM = 1.0 + +# set days and averaging window +DAY_INT = 0.25 +DAYS = [] +imax = int(DAY_MAX/DAY_INT) +i = 1 +while i <= imax: + DAYS.append(i*DAY_INT) + i += 1 + +AVERAGING_WINDOW_ALL0 = [0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.8, 0.9, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 7.5, 10.0, 12.5, 15, 17.5, 20] +AVERAGING_WINDOW0 = [] +for k in AVERAGING_WINDOW_ALL0: + if k <= AVERAGING_WINDOW_MAX0: + AVERAGING_WINDOW0.append(k) + +AVERAGING_WINDOW_ALL1 = [0.1, 0.10625, 0.1125, 0.11875, 0.125, 0.13125, 0.1375, 0.14375, 0.15, 0.175, 0.2, 0.225, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 7.5, 10.0, 12.5, 15, 17.5, 20] +AVERAGING_WINDOW1 = [] +for k in AVERAGING_WINDOW_ALL1: + if k <= AVERAGING_WINDOW_MAX1: + AVERAGING_WINDOW1.append(k) + +AVERAGING_WINDOW_ALL2 = [0.375, 0.4125, 0.45, 0.4875, 0.525, 0.5625, 0.6, 0.6375, 0.675, 0.7125, 0.75, 0.825, 0.9, 0.975, 1.05] +AVERAGING_WINDOW2 = [] +for k in AVERAGING_WINDOW_ALL2: + if k <= AVERAGING_WINDOW_MAX2: + AVERAGING_WINDOW2.append(k) + +# input data +etadict0 = {} +udict0 = {} +input_lev5_dt025(etadict0, udict0, ppp=PPP, dts=DTS) +DT0 = 900 + +etadict1 = {} +udict1 = {} +input_lev5_dt0125(etadict1, udict1, ppp=PPP, dts=DTS) +DT1 = 450 + +etadict2 = {} +udict2 = {} +input_lev5_dt0375(etadict2, udict2, ppp=PPP, dts=DTS) +DT2 = 1350 + +# sort data by day +etanorm0 = {} +unorm0 = {} +i = 0 +for day in DAYS: + etanorm0[day] = [] + unorm0[day] = [] + for key in AVERAGING_WINDOW0: + etanorm0[day].append(etadict0[key][i]) + unorm0[day].append(udict0[key][i]) + i += 1 + +etanorm1 = {} +unorm1 = {} +i = 0 +for day in DAYS: + etanorm1[day] = [] + unorm1[day] = [] + for key in AVERAGING_WINDOW1: + etanorm1[day].append(etadict1[key][i]) + unorm1[day].append(udict1[key][i]) + i += 1 + +etanorm2 = {} +unorm2 = {} +i = 0 +for day in DAYS: + etanorm2[day] = [] + unorm2[day] = [] + for key in AVERAGING_WINDOW2: + etanorm2[day].append(etadict2[key][i]) + unorm2[day].append(udict2[key][i]) + i += 1 + +etanorm_900s = {} +unorm_900s = {} +i = 0 +for day in DAYS: + etanorm_900s[day] = [] + unorm_900s[day] = [] + for key in AVERAGING_WINDOW0: + etanorm_900s[day].append(eta_900s[i]) + unorm_900s[day].append(u_900s[i]) + i += 1 + +etanorm_1350s = {} +unorm_1350s = {} +i = 0 +for day in DAYS: + etanorm_1350s[day] = [] + unorm_1350s[day] = [] + for key in AVERAGING_WINDOW2: + etanorm_1350s[day].append(eta_1350s[i]) + unorm_1350s[day].append(u_1350s[i]) + i += 1 + +etanorm_450s = {} +unorm_450s = {} +i = 0 +for day in DAYS: + etanorm_450s[day] = [] + unorm_450s[day] = [] + for key in AVERAGING_WINDOW1: + etanorm_450s[day].append(eta_450s[i]) + unorm_450s[day].append(u_450s[i]) + i += 1 + +################################## +# PLOTTONG ENTIRE FIGURE # +################################## +markers = ["+", "s", "o", "v", "^", "<", ">", "1", "2", "3"] +colors = ["black", "red", "blue", "green", "magenta", "yellow", "black", "cyan"] + +plt.figure(num=1,figsize=(8,7)) + +i = 0 +for day in DAYS_TO_PLOT: + if LOGLOG: + plt.loglog(AVERAGING_WINDOW2, unorm_1350s[day], color=colors[i], linestyle="dotted", linewidth=LINEWIDTH, label = r'dt = '+str(DT2)+' s (standard)') + plt.loglog(AVERAGING_WINDOW0, unorm_900s[day], color=colors[i], linestyle="solid", linewidth=LINEWIDTH, label = r'dt = '+str(DT0)+' s (standard)') + plt.loglog(AVERAGING_WINDOW1, unorm_450s[day], color=colors[i], linestyle="dashed", linewidth=LINEWIDTH, label = r'dt = '+str(DT1)+' s (standard)') + plt.loglog(AVERAGING_WINDOW2, unorm2[day], marker=markers[4], color=colors[i], markersize=3, linestyle="dotted", linewidth=LINEWIDTH, label = r'dt = '+str(DT2)+' s (averaged)') + plt.loglog(AVERAGING_WINDOW0, unorm0[day], marker=markers[4], color=colors[i], markersize=3, linestyle="solid", linewidth=LINEWIDTH, label = r'dt = '+str(DT0)+' s (averaged)') + plt.loglog(AVERAGING_WINDOW1, unorm1[day], marker=markers[4], color=colors[i], markersize=3, linestyle="dashed", linewidth=LINEWIDTH, label = r'dt = '+str(DT1)+' s (averaged)') + else: + plt.plot(AVERAGING_WINDOW2, unorm2[day], marker=markers[0], color=colors[i], markersize=5, linestyle="dotted", linewidth=LINEWIDTH, label = r'dt = '+str(DT2)+' s') + plt.plot(AVERAGING_WINDOW0, unorm0[day], marker=markers[0], color=colors[i], markersize=5, linestyle="solid", linewidth=LINEWIDTH, label = r'dt = '+str(DT0)+' s') + plt.plot(AVERAGING_WINDOW1, unorm1[day], marker=markers[0], color=colors[i], markersize=5, linestyle="dashed", linewidth=LINEWIDTH, label = r'dt = '+str(DT1)+' s') + plt.plot(AVERAGING_WINDOW2, unorm_1350s[day], color=colors[i], linestyle="dotted", linewidth=LINEWIDTH, label = r'dt = '+str(DT2)+' s') + plt.plot(AVERAGING_WINDOW0, unorm_900s[day], color=colors[i], linestyle="solid", linewidth=LINEWIDTH, label = r'dt = '+str(DT0)+' s') + plt.plot(AVERAGING_WINDOW1, unorm_450s[day], color=colors[i], linestyle="dashed", linewidth=LINEWIDTH, label = r'dt = '+str(DT1)+' s') + i += 1 + +plt.title('Error in $u$ at day 1', fontsize=18) +plt.legend(prop={'size':10}, loc="lower right") + +plt.xlabel(r'Averaging Window $T$ (hour)', fontsize=18) +plt.ylabel(r'Normalised error', fontsize=18) +plt.ylim(1.e-5,1.e-2) +plt.yscale('log') + + +plt.savefig('lev5_dt_compare_u.eps') +plt.show() + +plt.figure(num=2,figsize=(8,7)) + +i = 0 +for day in DAYS_TO_PLOT: + if LOGLOG: + plt.loglog(AVERAGING_WINDOW2, etanorm_1350s[day], color=colors[i], linestyle="dotted", linewidth=LINEWIDTH, label = r'dt = '+str(DT2)+' s (standard)') + plt.loglog(AVERAGING_WINDOW0, etanorm_900s[day], color=colors[i], linestyle="solid", linewidth=LINEWIDTH, label = r'dt = '+str(DT0)+' s (standard)') + plt.loglog(AVERAGING_WINDOW1, etanorm_450s[day], color=colors[i], linestyle="dashed", linewidth=LINEWIDTH, label = r'dt = '+str(DT1)+' s (standard)') + plt.loglog(AVERAGING_WINDOW2, etanorm2[day], marker=markers[0], color=colors[i], markersize=5, linestyle="dotted", linewidth=LINEWIDTH, label = r'dt = '+str(DT2)+' s (averaged)') + plt.loglog(AVERAGING_WINDOW0, etanorm0[day], marker=markers[0], color=colors[i], markersize=5, linestyle="solid", linewidth=LINEWIDTH, label = r'dt = '+str(DT0)+' s (averaged)') + plt.loglog(AVERAGING_WINDOW1, etanorm1[day], marker=markers[0], color=colors[i], markersize=5, linestyle="dashed", linewidth=LINEWIDTH, label = r'dt = '+str(DT1)+' s (averaged)') + else: + plt.plot(AVERAGING_WINDOW2, etanorm2[day], marker=markers[0], color=colors[i], markersize=5, linestyle="dotted", linewidth=LINEWIDTH, label = r'dt = '+str(DT2)+' s') + plt.plot(AVERAGING_WINDOW0, etanorm0[day], marker=markers[0], color=colors[i], markersize=5, linestyle="solid", linewidth=LINEWIDTH, label = r'dt = '+str(DT0)+' s') + plt.plot(AVERAGING_WINDOW1, etanorm1[day], marker=markers[0], color=colors[i], markersize=5, linestyle="dashed", linewidth=LINEWIDTH, label = r'dt = '+str(DT1)+' s') + plt.plot(AVERAGING_WINDOW2, etanorm_1350s[day], color=colors[i], linestyle="dotted", linewidth=LINEWIDTH, label = r'dt = '+str(DT2)+' s') + plt.plot(AVERAGING_WINDOW0, etanorm_900s[day], color=colors[i], linestyle="solid", linewidth=LINEWIDTH, label = r'dt = '+str(DT0)+' s') + plt.plot(AVERAGING_WINDOW1, etanorm_450s[day], color=colors[i], linestyle="dashed", linewidth=LINEWIDTH, label = r'dt = '+str(DT1)+' s') + i += 1 + +plt.title('Error in $\eta$ at day 1', fontsize=18) +plt.legend(prop={'size':10}, loc="lower right") + +plt.xlabel(r'Averaging Window $T$ (hour)', fontsize=18) +plt.ylabel(r'Normalised error', fontsize=18) +plt.ylim(1.e-5,1.e-2) +plt.yscale('log') + +plt.savefig('lev5_dt_compare_eta.eps') +plt.show() diff --git a/qjrms/plot_lev5_dt025.py b/qjrms/plot_lev5_dt025.py new file mode 100644 index 0000000..95087b4 --- /dev/null +++ b/qjrms/plot_lev5_dt025.py @@ -0,0 +1,225 @@ +import numpy as np +import matplotlib.pyplot as plt +import data_lev5_dt025 +from data_lev5_dt025 import * + +# shared parameters +PPP = 4 +DTS = 22.5 +DAY_INT = 0.25 +LOGLOG = True + +# set parameters +DAY_MAX0 = 1 +DAYS_TO_PLOT0 = [1] +AVERAGING_WINDOW_MAX0 = 10 + +DAY_MAX1 = 1 +DAYS_TO_PLOT1 = [1] +AVERAGING_WINDOW_MAX1 = 2 + +DAY_MAX2 = 5 +DAYS_TO_PLOT2 = [5,4,3,2] +AVERAGING_WINDOW_MAX2 = 1 + +# set days +DAYS0 = [] +imax0 = int(DAY_MAX0/DAY_INT) +i = 1 +while i <= imax0: + DAYS0.append(i*DAY_INT) + i += 1 + +DAYS1 = [] +imax1 = int(DAY_MAX1/DAY_INT) +i = 1 +while i <= imax1: + DAYS1.append(i*DAY_INT) + i += 1 + +DAYS2 = [] +imax2 = int(DAY_MAX2/DAY_INT) +i = 1 +while i <= imax2: + DAYS2.append(i*DAY_INT) + i += 1 + +# set averaging window +AVERAGING_WINDOW_ALL = [0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.8, 0.9, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0] +AVERAGING_WINDOW0 = [] +for k in AVERAGING_WINDOW_ALL: + if k <= AVERAGING_WINDOW_MAX0: + AVERAGING_WINDOW0.append(k) + +AVERAGING_WINDOW1 = [] +for k in AVERAGING_WINDOW_ALL: + if k <= AVERAGING_WINDOW_MAX1: + AVERAGING_WINDOW1.append(k) + +AVERAGING_WINDOW2 = [] +for k in AVERAGING_WINDOW_ALL: + if k <= AVERAGING_WINDOW_MAX2: + AVERAGING_WINDOW2.append(k) + +# input data +etadict0 = {} +udict0 = {} +input_lev5_dt025(etadict0, udict0, ppp=PPP, dts=DTS) + +etadict1 = {} +udict1 = {} +input_lev5_dt025(etadict1, udict1, ppp=PPP, dts=DTS) + +etadict2 = {} +udict2 = {} +input_lev5_dt025(etadict2, udict2, ppp=PPP, dts=DTS) + +# sort data by day +etanorm0 = {} +unorm0 = {} +i = 0 +for day in DAYS0: + etanorm0[day] = [] + unorm0[day] = [] + for key in AVERAGING_WINDOW0: + etanorm0[day].append(etadict0[key][i]) + unorm0[day].append(udict0[key][i]) + i += 1 + +etanorm1 = {} +unorm1 = {} +i = 0 +for day in DAYS1: + etanorm1[day] = [] + unorm1[day] = [] + for key in AVERAGING_WINDOW1: + etanorm1[day].append(etadict1[key][i]) + unorm1[day].append(udict1[key][i]) + i += 1 + +etanorm2 = {} +unorm2 = {} +i = 0 +for day in DAYS2: + etanorm2[day] = [] + unorm2[day] = [] + for key in AVERAGING_WINDOW2: + etanorm2[day].append(etadict2[key][i]) + unorm2[day].append(udict2[key][i]) + i += 1 + +################################## +# PLOTTONG ENTIRE FIGURE # +################################## +markers = ["+", "s", "o", "v", "^", "<", ">", "1", "2", "3"] +colors = ["black", "red", "blue", "green", "magenta", "darkorange", "brown", "yellowgreen", "purple"] + +plt.figure(num=1,figsize=(8,6)) + +i = 0 +for day in DAYS_TO_PLOT0: + if LOGLOG: + plt.loglog(AVERAGING_WINDOW0, unorm0[day], color=colors[i], linewidth=1., marker=markers[4], markersize=3, markeredgecolor=colors[i], label = r'$u$') + plt.loglog(AVERAGING_WINDOW0, etanorm0[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, markeredgecolor=colors[i], label = r'$\eta$') + else: + plt.plot(AVERAGING_WINDOW0, unorm0[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day '+str(day)) + plt.plot(AVERAGING_WINDOW0, etanorm0[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day '+str(day)) + i += 1 + +plt.title('Error at day 1', fontsize=18) +plt.legend(prop={'size':13}, loc="lower right") + +plt.xlabel(r'Averaging Window $T$ (hour)', fontsize=18) +plt.ylabel(r'Normalised error', fontsize=18) +plt.ylim(1.e-5,1.e-1) + +plt.savefig('lev5_dt025.eps') +plt.show() + +# plt.figure(num=2,figsize=(8,6)) + +# i = 0 +# for day in DAYS_TO_PLOT0: +# if LOGLOG: +# plt.loglog(AVERAGING_WINDOW0, etanorm0[day], color=colors[i], linewidth=1., marker=markers[4], markersize=3, markeredgecolor=colors[i], label = r'day = '+str(day)) +# else: +# plt.plot(AVERAGING_WINDOW0, etanorm0[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, markeredgecolor=colors[i], label = r'day = '+str(day)) +# i += 1 + +# plt.title('Error in $\eta$', fontsize=18) +# plt.legend(prop={'size':12}, loc="lower right") + +# plt.xlabel(r'Averaging Window', fontsize=18) +# plt.ylabel(r'Normalised error', fontsize=18) +# plt.ylim(1.e-5,1.e-1) + +# plt.savefig('lev5_dt025_eta_day025.eps') +# plt.show() + +plt.figure(num=3,figsize=(6,6)) + +i = 4 +for day in DAYS_TO_PLOT2: + if LOGLOG: + plt.loglog(AVERAGING_WINDOW2, unorm2[day], color=colors[i], linewidth=1., marker=markers[4], markersize=3, markeredgecolor=colors[i], label = r'day '+str(day)) + else: + plt.plot(AVERAGING_WINDOW2, unorm2[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day '+str(day)) + i -= 1 + +# for day in DAYS_TO_PLOT1: +# if LOGLOG: +# plt.loglog(AVERAGING_WINDOW1, unorm1[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day = '+str(day)) +# else: +# plt.plot(AVERAGING_WINDOW1, unorm1[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day = '+str(day)) +# i -= 1 + +for day in DAYS_TO_PLOT0: + if LOGLOG: + plt.loglog(AVERAGING_WINDOW0, unorm0[day], color=colors[i], linewidth=1., marker=markers[4], markersize=3, markeredgecolor=colors[i], label = r'day '+str(day)) + else: + plt.plot(AVERAGING_WINDOW0, unorm0[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day '+str(day)) + +plt.title('Error in $u$', fontsize=18) +plt.legend(prop={'size':13}, loc="lower left") + +plt.xlabel(r'Averaging Window $T$ (hour)', fontsize=18) +plt.ylabel(r'Normalised error', fontsize=18) +plt.xlim(1.e-1,1.e0) +plt.ylim(1.e-5,1.e-1) + +plt.savefig('lev5_dt025_u.eps') +plt.show() + +plt.figure(num=4,figsize=(6,6)) + +i = 4 +for day in DAYS_TO_PLOT2: + if LOGLOG: + plt.loglog(AVERAGING_WINDOW2, etanorm2[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, markeredgecolor=colors[i], label = r'day '+str(day)) + else: + plt.plot(AVERAGING_WINDOW2, etanorm2[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day '+str(day)) + i -= 1 + +# for day in DAYS_TO_PLOT1: +# if LOGLOG: +# plt.loglog(AVERAGING_WINDOW1, etanorm1[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day = '+str(day)) +# else: +# plt.plot(AVERAGING_WINDOW1, etanorm1[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day = '+str(day)) +# i -= 1 + +for day in DAYS_TO_PLOT0: + if LOGLOG: + plt.loglog(AVERAGING_WINDOW0, etanorm0[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, markeredgecolor=colors[i], label = r'day '+str(day)) + else: + plt.plot(AVERAGING_WINDOW0, etanorm0[day], color=colors[i], linewidth=1., marker=markers[0], markersize=5, label = r'day '+str(day)) + +plt.title('Error in $\eta$', fontsize=18) +plt.legend(prop={'size':13}, loc="lower left") + +plt.xlabel(r'Averaging Window $T$ (hour)', fontsize=18) +plt.ylabel(r'Normalised error', fontsize=18) +plt.xlim(1.e-1,1.e0) +plt.ylim(1.e-5,1.e-1) + +plt.savefig('lev5_dt025_eta.eps') +plt.show() From 7694acd34a7c6372037ba44076554803d5b6edec Mon Sep 17 00:00:00 2001 From: Colin Cotter Date: Tue, 27 Jun 2023 11:12:54 +0100 Subject: [PATCH 46/46] added a readme --- README.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 README.txt diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..ef630d8 --- /dev/null +++ b/README.txt @@ -0,0 +1,6 @@ +The version used to produce results for the qjrms paper. + +averaged_sw_explicit.py: the averaged model +standard_sw.py: the standard model +calculate_norm.py: compare the .h5 files produced by the above models and calculate norms +qjrms/ directory: contains data files and scripts which were used to produce figures 4-6 of the paper