diff --git a/testcases/moving_cyclone/make_testcase.py b/testcases/moving_cyclone/make_testcase.py new file mode 100644 index 0000000..2f9d947 --- /dev/null +++ b/testcases/moving_cyclone/make_testcase.py @@ -0,0 +1,441 @@ +from netCDF4 import Dataset +import math +import os +import netCDF4 +import matplotlib +import matplotlib.pyplot as plt +from matplotlib.patches import Polygon +from matplotlib.collections import PatchCollection +import numpy as np +import matplotlib.cm as cmm +from mpl_toolkits.axes_grid1 import make_axes_locatable + +lx = 512000.0 +ly = 512000.0 + +#------------------------------------------------------------------------------- + +def create_grid_quad(gridfileOut, dc): + + mpas_tools_dir = os.environ['MPAS_TOOLS_DIR'] + + dx = dc + dy = dc + + nx = int(lx / dx) + ny = int(ly / dy) + + vertexDegree = 4 + + fileGrid = Dataset("grid_in.nc","w",format="NETCDF3_CLASSIC") + + fileGrid.on_a_sphere = "NO" + + nCells = nx * ny + nVertices = (nx+1) * (ny+1) + + fileGrid.createDimension("nCells", nCells) + fileGrid.createDimension("nVertices", nVertices) + fileGrid.createDimension("vertexDegree", vertexDegree) + + xCell = np.zeros(nCells) + yCell = np.zeros(nCells) + zCell = np.zeros(nCells) + + for j in range(0,ny): + for i in range(0,nx): + iCell = i + j * nx + xCell[iCell] = (float(i) + 0.5) * dc + yCell[iCell] = (float(j) + 0.5) * dc + + xVertex = np.zeros(nVertices) + yVertex = np.zeros(nVertices) + zVertex = np.zeros(nVertices) + cellsOnVertex = np.zeros((nVertices,vertexDegree),dtype="i") + + for j in range(0,ny+1): + for i in range(0,nx+1): + iVertex = i + j * (nx+1) + xVertex[iVertex] = float(i) * dc + yVertex[iVertex] = float(j) * dc + + ic = i - 1 ; jc = j - 1 + iCell = ic + jc * nx + if (ic >= 0 and jc >= 0): + cellsOnVertex[iVertex,0] = iCell + else: + cellsOnVertex[iVertex,0] = -1 + + ic = i ; jc = j - 1 + iCell = ic + jc * nx + if (ic < nx and jc >= 0): + cellsOnVertex[iVertex,1] = iCell + else: + cellsOnVertex[iVertex,1] = -1 + + ic = i ; jc = j + iCell = ic + jc * nx + if (ic < nx and jc < ny): + cellsOnVertex[iVertex,2] = iCell + else: + cellsOnVertex[iVertex,2] = -1 + + ic = i - 1 ; jc = j + iCell = ic + jc * nx + if (ic >= 0 and jc < ny): + cellsOnVertex[iVertex,3] = iCell + else: + cellsOnVertex[iVertex,3] = -1 + + var = fileGrid.createVariable("xCell","d",dimensions=["nCells"]) + var[:] = xCell[:] + var = fileGrid.createVariable("yCell","d",dimensions=["nCells"]) + var[:] = yCell[:] + var = fileGrid.createVariable("zCell","d",dimensions=["nCells"]) + var[:] = zCell[:] + + var = fileGrid.createVariable("xVertex","d",dimensions=["nVertices"]) + var[:] = xVertex[:] + var = fileGrid.createVariable("yVertex","d",dimensions=["nVertices"]) + var[:] = yVertex[:] + var = fileGrid.createVariable("zVertex","d",dimensions=["nVertices"]) + var[:] = zVertex[:] + + cellsOnVertex[:] = cellsOnVertex[:] + 1 + var = fileGrid.createVariable("cellsOnVertex","i",dimensions=["nVertices","vertexDegree"]) + var[:] = cellsOnVertex[:] + + fileGrid.close() + + os.system("%s/mesh_tools/mesh_conversion_tools/MpasMeshConverter.x grid_in.nc %s" %(mpas_tools_dir,gridfileOut)) + +#------------------------------------------------------------------------------- + +def create_grid_hex(gridfileOut, dc): + + mpas_tools_dir = os.environ['MPAS_TOOLS_DIR'] + + dx = dc + dy = dc * math.sqrt(0.75) + + nx = int(lx / dx) + if (nx % 2 != 0): + nx += 1 + ny = int(ly / dy) + if (ny % 2 != 0): + ny += 1 + + fileout = open("namelist.input","w") + + line = "&periodic_grid\n" + fileout.write(line) + + line = " nx = %i,\n" %(nx+2) + fileout.write(line) + + line = " ny = %i,\n" %(ny+2) + fileout.write(line) + + line = " dc = %f,\n" %(dc) + fileout.write(line) + + line = " nVertLevels = 1,\n" + fileout.write(line) + + line = " nTracers = 1,\n" + fileout.write(line) + + line = " nproc = 1,\n" + fileout.write(line) + + line = "/\n" + fileout.write(line) + + fileout.close() + + os.system("rm grid.nc") + os.system("%s/mesh_tools/periodic_hex/periodic_grid" %(mpas_tools_dir)) + os.system("python %s/mesh_tools/periodic_hex/mark_periodic_boundaries_for_culling.py -f grid.nc" %(mpas_tools_dir)) + os.system("%s/mesh_tools/mesh_conversion_tools/MpasCellCuller.x grid.nc %s" %(mpas_tools_dir,gridfileOut)) + +#------------------------------------------------------------------------------- + +def create_forcing(gridFilename, forcingFilename, forcingPlotFilename): + + fileGrid = Dataset(gridFilename, "r") + + nCells = len(fileGrid.dimensions["nCells"]) + + nEdgesOnCell = fileGrid.variables["nEdgesOnCell"][:] + verticesOnCell = fileGrid.variables["verticesOnCell"][:] + verticesOnCell[:] = verticesOnCell[:] - 1 + + xCell = fileGrid.variables["xCell"][:] + yCell = fileGrid.variables["yCell"][:] + + xVertex = fileGrid.variables["xVertex"][:] + yVertex = fileGrid.variables["yVertex"][:] + + fileGrid.close() + + + simulationDurationInDays = 4 + hoursInDay = 24 + + nTimes = hoursInDay * simulationDurationInDays + + uAirVelocity = np.zeros((nTimes,nCells)) + vAirVelocity = np.zeros((nTimes,nCells)) + airSpeed = np.zeros((nTimes,nCells)) + + uOceanVelocity = np.zeros((nTimes,nCells)) + vOceanVelocity = np.zeros((nTimes,nCells)) + oceanSpeed = np.zeros((nTimes,nCells)) + + xtimes = [] + + vOceanMax = 0.01 + vAirMax = 30.0 / math.e + + alpha = math.radians(-90.0-18.0) + salpha = math.sin(alpha) + calpha = math.cos(alpha) + + year = 1 + month = 1 + day = 1 + hour = 0 + minute = 0 + second = 0 + + for iTime in range(0,nTimes): + for iCell in range(0,nCells): + + time = float(iTime) # hours + + mx = 0.5*lx + 0.1*lx * (time / 24.0) + my = 0.5*ly + 0.1*ly * (time / 24.0) + r = math.sqrt(math.pow((mx - xCell[iCell]), 2) + + math.pow((my - yCell[iCell]), 2)) + s = (math.e / 100.0) * math.exp(-(r / (100.0 * 1000.0))) + + uAirVelocity[iTime,iCell] = s * vAirMax * ( calpha * (xCell[iCell]-mx) + salpha * (yCell[iCell]-my)) * 0.001 + vAirVelocity[iTime,iCell] = s * vAirMax * (-salpha * (xCell[iCell]-mx) + calpha * (yCell[iCell]-my)) * 0.001 + airSpeed[iTime,iCell] = math.sqrt(math.pow(uAirVelocity[iTime,iCell],2) + + math.pow(vAirVelocity[iTime,iCell],2)) + + uOceanVelocity[iTime,iCell] = vOceanMax * ( (2.0*yCell[iCell] - lx) / lx) + vOceanVelocity[iTime,iCell] = vOceanMax * (-(2.0*xCell[iCell] - ly) / ly) + oceanSpeed[iTime,iCell] = math.sqrt(math.pow(uOceanVelocity[iTime,iCell],2) + + math.pow(vOceanVelocity[iTime,iCell],2)) + + timeStr = "%4.4i-%2.2i-%2.2i_%2.2i:%2.2i:%2.2i" %(year,month,day,hour,minute,second) + xtimes.append(timeStr) + + hour += 1 + if hour > 23: + hour = 0 + day += 1 + + + fileForcing = Dataset(forcingFilename, "w", format="NETCDF3_CLASSIC") + + fileForcing.createDimension("nCells", nCells) + fileForcing.createDimension("StrLen", 64) + fileForcing.createDimension("Time", None) + + var = fileForcing.createVariable("xtime", "c", dimensions=["Time","StrLen"]) + for iTime in range(0,nTimes): + var[iTime,0:19] = netCDF4.stringtochar(np.array(xtimes[iTime], 'S19')) + var[iTime,19:] = " "*45 + + var = fileForcing.createVariable("uAirVelocity","d",dimensions=["Time","nCells"]) + var[:] = uAirVelocity[:] + + var = fileForcing.createVariable("vAirVelocity","d",dimensions=["Time","nCells"]) + var[:] = vAirVelocity[:] + + var = fileForcing.createVariable("uOceanVelocity","d",dimensions=["Time","nCells"]) + var[:] = uOceanVelocity[:] + + var = fileForcing.createVariable("vOceanVelocity","d",dimensions=["Time","nCells"]) + var[:] = vOceanVelocity[:] + + fileForcing.close() + + + cm = 1/2.54 # centimeters in inches + plt.rc('font', family="Times New Roman") + plt.rc('mathtext',fontset="stix") + SMALL_SIZE = 8 + MEDIUM_SIZE = 8 + BIGGER_SIZE = 8 + plt.rc('font', size=SMALL_SIZE) # controls default text sizes + plt.rc('axes', titlesize=SMALL_SIZE) # fontsize of the axes title + plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels + plt.rc('xtick', labelsize=SMALL_SIZE) # fontsize of the tick labels + plt.rc('ytick', labelsize=SMALL_SIZE) # fontsize of the tick labels + plt.rc('legend', fontsize=SMALL_SIZE) # legend fontsize + plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title + + patches = [] + for iCell in range(0,nCells): + vertices = [] + for iVertexOnCell in range(0,nEdgesOnCell[iCell]): + iVertex = verticesOnCell[iCell,iVertexOnCell] + vertices.append((xVertex[iVertex]*0.001,yVertex[iVertex]*0.001)) + patches.append(Polygon(vertices,True)) + + stride = 10 + + cmap = matplotlib.cm.viridis + + fig, axes = plt.subplots(2, 2, figsize=(15*cm,13*cm)) + + iTime = int(nTimes / 2) + + # u air velocity + pc1 = PatchCollection(patches, cmap=cmap) + pc1.set_array(uAirVelocity[iTime,:]) + axes[0,0].add_collection(pc1) + + divider = make_axes_locatable(axes[0,0]) + cax = divider.append_axes('right', size='5%', pad=0.05) + fig.colorbar(pc1, cax=cax, orientation='vertical') + + axes[0,0].set_aspect("equal") + axes[0,0].set_xlabel("x (km)") + axes[0,0].set_ylabel("y (km)") + axes[0,0].set_title("u air velocity (m/s)") + axes[0,0].set_xlim((np.amin(xVertex)*0.001,np.amax(xVertex)*0.001)) + axes[0,0].set_ylim((np.amin(yVertex)*0.001,np.amax(yVertex)*0.001)) + + # v air velocity + pc2 = PatchCollection(patches, cmap=cmap) + pc2.set_array(vAirVelocity[iTime,:]) + axes[0,1].add_collection(pc2) + + divider = make_axes_locatable(axes[0,1]) + cax = divider.append_axes('right', size='5%', pad=0.05) + fig.colorbar(pc2, cax=cax, orientation='vertical') + + axes[0,1].set_aspect("equal") + axes[0,1].set_xlabel("x (km)") + axes[0,1].set_ylabel("y (km)") + axes[0,1].set_title("v air velocity (m/s)") + axes[0,1].set_xlim((np.amin(xVertex)*0.001,np.amax(xVertex)*0.001)) + axes[0,1].set_ylim((np.amin(yVertex)*0.001,np.amax(yVertex)*0.001)) + + # air velocity + pc3 = PatchCollection(patches, cmap=cmap) + pc3.set_array(airSpeed[iTime,:]) + axes[1,0].add_collection(pc3) + axes[1,0].quiver(xCell[::stride]*0.001, yCell[::stride]*0.001, uAirVelocity[iTime,::stride], vAirVelocity[iTime,::stride]) + + divider = make_axes_locatable(axes[1,0]) + cax = divider.append_axes('right', size='5%', pad=0.05) + fig.colorbar(pc3, cax=cax, orientation='vertical') + + axes[1,0].set_aspect("equal") + axes[1,0].set_xlabel("x (km)") + axes[1,0].set_ylabel("y (km)") + axes[1,0].set_title("Air velocity (m/s)") + axes[1,0].set_xlim((np.amin(xVertex)*0.001,np.amax(xVertex)*0.001)) + axes[1,0].set_ylim((np.amin(yVertex)*0.001,np.amax(yVertex)*0.001)) + + # ocean velocity + pc4 = PatchCollection(patches, cmap=cmap) + pc4.set_array(oceanSpeed[iTime,:]) + axes[1,1].add_collection(pc4) + axes[1,1].quiver(xCell[::stride]*0.001, yCell[::stride]*0.001, uOceanVelocity[iTime,::stride], vOceanVelocity[iTime,::stride]) + + divider = make_axes_locatable(axes[1,1]) + cax = divider.append_axes('right', size='5%', pad=0.05) + fig.colorbar(pc4, cax=cax, orientation='vertical') + + axes[1,1].set_aspect("equal") + axes[1,1].set_xlabel("x (km)") + axes[1,1].set_ylabel("y (km)") + axes[1,1].set_title("Ocean velocity (m/s)") + axes[1,1].set_xlim((np.amin(xVertex)*0.001,np.amax(xVertex)*0.001)) + axes[1,1].set_ylim((np.amin(yVertex)*0.001,np.amax(yVertex)*0.001)) + + plt.tight_layout() + plt.savefig(forcingPlotFilename,dpi=300) + +#------------------------------------------------------------------------------- + +def create_ic(gridFilename, icFilename): + + nCategories = 5 + + fileGrid = Dataset(gridFilename, "r") + + nCells = len(fileGrid.dimensions["nCells"]) + nVertices = len(fileGrid.dimensions["nVertices"]) + + xCell = fileGrid.variables["xCell"][:] + yCell = fileGrid.variables["yCell"][:] + + fileGrid.close() + + iceAreaCategory = np.zeros((nCells,nCategories,1)) + iceVolumeCategory = np.zeros((nCells,nCategories,1)) + + for iCell in range(0,nCells): + iceAreaCategory[iCell,0,0] = 1.0 + iceVolumeCategory[iCell,0,0] = 0.3 + 0.005 * (math.sin(6e-5*xCell[iCell]) + math.sin(3e-5*yCell[iCell])) + + fVertex = 1.46e-4 + + fileIC = Dataset(icFilename,"w",format="NETCDF3_CLASSIC") + + fileIC.createDimension("nCells",nCells) + fileIC.createDimension("nVertices",nVertices) + fileIC.createDimension("nCategories",nCategories) + fileIC.createDimension("ONE",1) + + var = fileIC.createVariable("iceAreaCategory","d",dimensions=["nCells","nCategories","ONE"]) + var[:] = iceAreaCategory[:] + + var = fileIC.createVariable("iceVolumeCategory","d",dimensions=["nCells","nCategories","ONE"]) + var[:] = iceVolumeCategory[:] + + var = fileIC.createVariable("fVertex","d",dimensions=["nVertices"]) + var[:] = fVertex + + fileIC.close() + +#------------------------------------------------------------------------------- + +def make_testcase(): + + create_grid_quad("grid_moving_cyclone_quad_8km.nc", 8000.0) + create_grid_quad("grid_moving_cyclone_quad_4km.nc", 4000.0) + create_grid_quad("grid_moving_cyclone_quad_2km.nc", 2000.0) + + create_forcing("grid_moving_cyclone_quad_8km.nc", "forcing_moving_cyclone_quad_8km.nc", "forcing_moving_cyclone_quad_8km.png") + create_forcing("grid_moving_cyclone_quad_4km.nc", "forcing_moving_cyclone_quad_4km.nc", "forcing_moving_cyclone_quad_4km.png") + create_forcing("grid_moving_cyclone_quad_2km.nc", "forcing_moving_cyclone_quad_2km.nc", "forcing_moving_cyclone_quad_2km.png") + + create_ic("grid_moving_cyclone_quad_8km.nc", "ic_moving_cyclone_quad_8km.nc") + create_ic("grid_moving_cyclone_quad_4km.nc", "ic_moving_cyclone_quad_4km.nc") + create_ic("grid_moving_cyclone_quad_2km.nc", "ic_moving_cyclone_quad_2km.nc") + + create_grid_hex("grid_moving_cyclone_hex_8km.nc", 8000.0) + create_grid_hex("grid_moving_cyclone_hex_4km.nc", 4000.0) + create_grid_hex("grid_moving_cyclone_hex_2km.nc", 2000.0) + + create_forcing("grid_moving_cyclone_hex_8km.nc", "forcing_moving_cyclone_hex_8km.nc", "forcing_moving_cyclone_hex_8km.png") + create_forcing("grid_moving_cyclone_hex_4km.nc", "forcing_moving_cyclone_hex_4km.nc", "forcing_moving_cyclone_hex_4km.png") + create_forcing("grid_moving_cyclone_hex_2km.nc", "forcing_moving_cyclone_hex_2km.nc", "forcing_moving_cyclone_hex_2km.png") + + create_ic("grid_moving_cyclone_hex_8km.nc", "ic_moving_cyclone_hex_8km.nc") + create_ic("grid_moving_cyclone_hex_4km.nc", "ic_moving_cyclone_hex_4km.nc") + create_ic("grid_moving_cyclone_hex_2km.nc", "ic_moving_cyclone_hex_2km.nc") + +#------------------------------------------------------------------------------- + +if __name__ == "__main__": + + make_testcase() diff --git a/testcases/moving_cyclone/namelist.seaice b/testcases/moving_cyclone/namelist.seaice new file mode 100644 index 0000000..0d7dfc4 --- /dev/null +++ b/testcases/moving_cyclone/namelist.seaice @@ -0,0 +1,512 @@ +&seaice_model + config_dt = 120.0 + config_calendar_type = 'gregorian_noleap' + config_start_time = '0001-01-01_00:00:00' + config_stop_time = 'none' + config_run_duration = '00-00-02_00:00:00' + config_num_halos = 3 +/ +&io + config_pio_num_iotasks = 0 + config_pio_stride = 1 + config_write_output_on_startup = false + config_test_case_diag = false + config_test_case_diag_type = 'none' + config_full_abort_write = true +/ +&decomposition + config_block_decomp_file_prefix = 'graphs/graph.info.part.' + config_number_of_blocks = 0 + config_explicit_proc_decomp = false + config_proc_decomp_file_prefix = 'graphs/graph.info.part.' + config_use_halo_exch = true + config_aggregate_halo_exch = false + config_reuse_halo_exch = false + config_load_balance_timers = false +/ +&restart + config_do_restart = false + config_restart_timestamp_name = 'restart_timestamp' + config_do_restart_hbrine = false + config_do_restart_zsalinity = false + config_do_restart_bgc = false + config_do_restart_snow_density = false + config_do_restart_snow_grain_radius = false +/ +&dimensions + config_nCategories = 5 + config_nIceLayers = 7 + config_nSnowLayers = 1 +/ +&initialize + config_earth_radius = 6371229.0 + config_initial_condition_type = 'none' + config_initial_ice_area = 1.0 + config_initial_ice_volume = 0.8 + config_initial_snow_volume = 0.0 + config_initial_latitude_north = -70.0 + config_initial_latitude_south = 60.0 + config_initial_velocity_type = 'none' + config_initial_uvelocity = 0.0 + config_initial_vvelocity = 0.0 + config_calculate_coriolis = false +/ +&use_sections + config_use_dynamics = true + config_use_velocity_solver = true + config_use_advection = true + config_use_forcing = true + config_use_column_package = true + config_use_prescribed_ice = false + config_use_prescribed_ice_forcing = false +/ +&forcing + config_atmospheric_forcing_type = 'hourly_velocities' + config_forcing_start_time = '0001-01-01_00:00:00' + config_forcing_cycle_start = '0001-01-01_00:00:00' + config_forcing_cycle_duration = '00-00-04_00:00:00' + config_forcing_precipitation_units = 'mm_per_sec' + config_forcing_sst_type = 'hourly_velocities' + config_update_ocean_fluxes = false + config_include_pond_freshwater_feedback = false +/ +&testing + config_use_test_ice_shelf = false + config_testing_system_test = false +/ +&velocity_solver + config_dynamics_subcycle_number = 1 + config_rotate_cartesian_grid = false + config_include_metric_terms = false + config_elastic_subcycle_number = 120 + config_strain_scheme = 'variational' + config_constitutive_relation_type = 'evp' + config_stress_divergence_scheme = 'variational' + config_variational_basis = 'wachspress' + config_variational_denominator_type = 'original' + config_wachspress_integration_type = 'dunavant' + config_wachspress_integration_order = 8 + config_average_variational_strain = false + config_calc_velocity_masks = true + config_use_air_stress = true + config_use_ocean_stress = true + config_use_surface_tilt = true + config_geostrophic_surface_tilt = true + config_ocean_stress_type = 'quadratic' + config_use_special_boundaries_velocity = false + config_use_special_boundaries_velocity_masks = false +/ +&advection + config_advection_type = 'incremental_remap' + config_monotonic = true + config_conservation_check = false + config_monotonicity_check = false + config_recover_tracer_means_check = false +/ +&column_package + config_use_column_shortwave = false + config_use_column_vertical_thermodynamics = false + config_use_column_biogeochemistry = false + config_use_column_itd_thermodynamics = false + config_use_column_ridging = true + config_use_column_snow_tracers = false +/ +&column_tracers + config_use_ice_age = true + config_use_first_year_ice = true + config_use_level_ice = true + config_use_cesm_meltponds = false + config_use_level_meltponds = true + config_use_topo_meltponds = false + config_use_aerosols = false + config_use_effective_snow_density = false + config_use_snow_grain_radius = false + config_use_special_boundaries_tracers = false +/ +&biogeochemistry + config_use_brine = false + config_use_vertical_zsalinity = false + config_use_vertical_biochemistry = false + config_use_shortwave_bioabsorption = false + config_use_vertical_tracers = false + config_use_skeletal_biochemistry = false + config_use_nitrate = false + config_use_carbon = false + config_use_chlorophyll = false + config_use_ammonium = false + config_use_silicate = false + config_use_DMS = false + config_use_nonreactive = false + config_use_humics = false + config_use_DON = false + config_use_iron = false + config_use_modal_aerosols = false + config_use_zaerosols = false + config_skeletal_bgc_flux_type = 'Jin2006' + config_scale_initial_vertical_bgc = false + config_biogrid_bottom_molecular_sublayer = 0.006 + config_biogrid_top_molecular_sublayer = 0.006 + config_bio_gravity_drainage_length_scale = 0.024 + config_zsalinity_molecular_sublayer = 0.0 + config_zsalinity_gravity_drainage_scale = 0.028 + config_snow_porosity_at_ice_surface = -0.3 + config_new_ice_fraction_biotracer = 0.80 + config_fraction_biotracer_in_frazil = 0.80 + config_ratio_Si_to_N_diatoms = 1.80 + config_ratio_Si_to_N_small_plankton = 0.00 + config_ratio_Si_to_N_phaeocystis = 0.00 + config_ratio_S_to_N_diatoms = 0.03 + config_ratio_S_to_N_small_plankton = 0.03 + config_ratio_S_to_N_phaeocystis = 0.03 + config_ratio_Fe_to_C_diatoms = 0.0033 + config_ratio_Fe_to_C_small_plankton = 0.0033 + config_ratio_Fe_to_C_phaeocystis = 0.1 + config_ratio_Fe_to_N_diatoms = 0.023 + config_ratio_Fe_to_N_small_plankton = 0.023 + config_ratio_Fe_to_N_phaeocystis = 0.7 + config_ratio_Fe_to_DON = 0.023 + config_ratio_Fe_to_DOC_saccharids = 0.1 + config_ratio_Fe_to_DOC_lipids = 0.033 + config_respiration_fraction_of_growth = 0.05 + config_rapid_mobile_to_stationary_time = 5200.0 + config_long_mobile_to_stationary_time = 173000.0 + config_algal_maximum_velocity = 0.0000000111 + config_ratio_Fe_to_dust = 0.035 + config_solubility_of_Fe_in_dust = 0.005 + config_chla_absorptivity_of_diatoms = 0.03 + config_chla_absorptivity_of_small_plankton = 0.01 + config_chla_absorptivity_of_phaeocystis = 0.05 + config_light_attenuation_diatoms = 0.8 + config_light_attenuation_small_plankton = 0.67 + config_light_attenuation_phaeocystis = 0.67 + config_light_inhibition_diatoms = 0.018 + config_light_inhibition_small_plankton = 0.0025 + config_light_inhibition_phaeocystis = 0.01 + config_maximum_growth_rate_diatoms = 1.44 + config_maximum_growth_rate_small_plankton = 0.851 + config_maximum_growth_rate_phaeocystis = 0.851 + config_temperature_growth_diatoms = 0.06 + config_temperature_growth_small_plankton = 0.06 + config_temperature_growth_phaeocystis = 0.06 + config_grazed_fraction_diatoms = 0.0 + config_grazed_fraction_small_plankton = 0.1 + config_grazed_fraction_phaeocystis = 0.1 + config_mortality_diatoms = 0.007 + config_mortality_small_plankton = 0.007 + config_mortality_phaeocystis = 0.007 + config_temperature_mortality_diatoms = 0.03 + config_temperature_mortality_small_plankton = 0.03 + config_temperature_mortality_phaeocystis = 0.03 + config_exudation_diatoms = 0.0 + config_exudation_small_plankton = 0.0 + config_exudation_phaeocystis = 0.0 + config_nitrate_saturation_diatoms = 1.0 + config_nitrate_saturation_small_plankton = 1.0 + config_nitrate_saturation_phaeocystis = 1.0 + config_ammonium_saturation_diatoms = 0.3 + config_ammonium_saturation_small_plankton = 0.3 + config_ammonium_saturation_phaeocystis = 0.3 + config_silicate_saturation_diatoms = 4.0 + config_silicate_saturation_small_plankton = 0.0 + config_silicate_saturation_phaeocystis = 0.0 + config_iron_saturation_diatoms = 1.0 + config_iron_saturation_small_plankton = 0.2 + config_iron_saturation_phaeocystis = 0.1 + config_fraction_spilled_to_DON = 0.6 + config_degredation_of_DON = 0.03 + config_fraction_DON_ammonium = 0.25 + config_fraction_loss_to_saccharids = 0.4 + config_fraction_loss_to_lipids = 0.4 + config_fraction_exudation_to_saccharids = 1.0 + config_fraction_exudation_to_lipids = 1.0 + config_remineralization_saccharids = 0.03 + config_remineralization_lipids = 0.03 + config_maximum_brine_temperature = 0.0 + config_salinity_dependence_of_growth = 1.0 + config_minimum_optical_depth = 0.1 + config_slopped_grazing_fraction = 0.5 + config_excreted_fraction = 0.5 + config_fraction_mortality_to_ammonium = 0.5 + config_fraction_iron_remineralized = 0.3 + config_nitrification_rate = 0.0 + config_desorption_loss_particulate_iron = 3065.0 + config_maximum_loss_fraction = 0.9 + config_maximum_ratio_iron_to_saccharids = 0.2 + config_respiration_loss_to_DMSPd = 0.75 + config_DMSP_to_DMS_conversion_fraction = 0.5 + config_DMSP_to_DMS_conversion_time = 3.0 + config_DMS_oxidation_time = 10.0 + config_mobility_type_diatoms = 0.0 + config_mobility_type_small_plankton = 0.5 + config_mobility_type_phaeocystis = 0.5 + config_mobility_type_nitrate = -1.0 + config_mobility_type_ammonium = 1.0 + config_mobility_type_silicate = -1.0 + config_mobility_type_DMSPp = 0.5 + config_mobility_type_DMSPd = -1.0 + config_mobility_type_humics = 1.0 + config_mobility_type_saccharids = 0.5 + config_mobility_type_lipids = 0.5 + config_mobility_type_inorganic_carbon = -1.0 + config_mobility_type_proteins = 0.5 + config_mobility_type_dissolved_iron = 0.5 + config_mobility_type_particulate_iron = 0.5 + config_mobility_type_black_carbon1 = 1.0 + config_mobility_type_black_carbon2 = 1.0 + config_mobility_type_dust1 = 1.0 + config_mobility_type_dust2 = 1.0 + config_mobility_type_dust3 = 1.0 + config_mobility_type_dust4 = 1.0 + config_ratio_C_to_N_diatoms = 7.0 + config_ratio_C_to_N_small_plankton = 7.0 + config_ratio_C_to_N_phaeocystis = 7.0 + config_ratio_chla_to_N_diatoms = 2.1 + config_ratio_chla_to_N_small_plankton = 1.1 + config_ratio_chla_to_N_phaeocystis = 0.84 + config_scales_absorption_diatoms = 2.0 + config_scales_absorption_small_plankton = 4.0 + config_scales_absorption_phaeocystis = 5.0 + config_ratio_C_to_N_proteins = 7.0 +/ +&shortwave + config_shortwave_type = 'dEdd' + config_albedo_type = 'ccsm3' + config_use_snicar_ad = false + config_visible_ice_albedo = 0.78 + config_infrared_ice_albedo = 0.36 + config_visible_snow_albedo = 0.98 + config_infrared_snow_albedo = 0.70 + config_variable_albedo_thickness_limit = 0.3 + config_ice_shortwave_tuning_parameter = 0.0 + config_pond_shortwave_tuning_parameter = 0.0 + config_snow_shortwave_tuning_parameter = 1.5 + config_temp_change_snow_grain_radius_change = 1.5 + config_max_melting_snow_grain_radius = 1500.0 + config_algae_absorption_coefficient = 0.6 +/ +&snow + config_snow_redistribution_scheme = 'none' + config_fallen_snow_radius = 54.526 + config_use_snow_liquid_ponds = false + config_new_snow_density = 100.0 + config_max_snow_density = 450.0 + config_minimum_wind_compaction = 10.0 + config_wind_compaction_factor = 27.3 + config_max_dry_snow_radius = 1800.0 +/ +&meltponds + config_snow_to_ice_transition_depth = 0.0 + config_pond_refreezing_type = 'hlid' + config_pond_flushing_timescale = 1.0e-3 + config_min_meltwater_retained_fraction = 0.15 + config_max_meltwater_retained_fraction = 1.0 + config_pond_depth_to_fraction_ratio = 0.8 + config_snow_on_pond_ice_tapering_parameter = 0.03 + config_critical_pond_ice_thickness = 0.01 +/ +&thermodynamics + config_thermodynamics_type = 'mushy' + config_heat_conductivity_type = 'bubbly' + config_rapid_mode_channel_radius = 0.5e-3 + config_rapid_model_critical_Ra = 10.0 + config_rapid_mode_aspect_ratio = 1.0 + config_slow_mode_drainage_strength = -5.0e-8 + config_slow_mode_critical_porosity = 0.05 + config_congelation_ice_porosity = 0.85 +/ +&itd + config_itd_conversion_type = 'linear remap' + config_category_bounds_type = 'original' +/ +&ridging + config_ice_strength_formulation = 'Hibler79' + config_ridging_participation_function = 'exponential' + config_ridging_redistribution_function = 'exponential' + config_ridiging_efolding_scale = 3.0 + config_ratio_ridging_work_to_PE = 17.0 +/ +&atmosphere + config_atmos_boundary_method = 'ccsm3' + config_calc_surface_stresses = true + config_calc_surface_temperature = true + config_use_form_drag = false + config_use_high_frequency_coupling = false + config_boundary_layer_iteration_number = 5 +/ +&ocean + config_use_ocean_mixed_layer = true + config_min_friction_velocity = 0.0005 + config_ocean_heat_transfer_type = 'constant' + config_sea_freezing_temperature_type = 'mushy' + config_ocean_surface_type = 'free' + config_couple_biogeochemistry_fields = false + config_use_data_icebergs = false +/ +&diagnostics + config_check_state = false +/ +&AM_highFrequencyOutput + config_AM_highFrequencyOutput_enable = false + config_AM_highFrequencyOutput_compute_interval = 'output_interval' + config_AM_highFrequencyOutput_output_stream = 'highFrequencyOutput' + config_AM_highFrequencyOutput_compute_on_startup = true + config_AM_highFrequencyOutput_write_on_startup = true +/ +&AM_temperatures + config_AM_temperatures_enable = false + config_AM_temperatures_compute_interval = 'dt' + config_AM_temperatures_output_stream = 'none' + config_AM_temperatures_compute_on_startup = false + config_AM_temperatures_write_on_startup = false +/ +&AM_regionalStatistics + config_AM_regionalStatistics_enable = false + config_AM_regionalStatistics_compute_interval = 'output_interval' + config_AM_regionalStatistics_output_stream = 'regionalStatisticsOutput' + config_AM_regionalStatistics_compute_on_startup = false + config_AM_regionalStatistics_write_on_startup = false + config_AM_regionalStatistics_ice_extent_limit = 0.15 +/ +&AM_ridgingDiagnostics + config_AM_ridgingDiagnostics_enable = false + config_AM_ridgingDiagnostics_compute_interval = 'dt' + config_AM_ridgingDiagnostics_output_stream = 'none' + config_AM_ridgingDiagnostics_compute_on_startup = false + config_AM_ridgingDiagnostics_write_on_startup = false +/ +&AM_conservationCheck + config_AM_conservationCheck_enable = false + config_AM_conservationCheck_compute_interval = 'dt' + config_AM_conservationCheck_output_stream = 'conservationCheckOutput' + config_AM_conservationCheck_compute_on_startup = false + config_AM_conservationCheck_write_on_startup = false + config_AM_conservationCheck_write_to_logfile = true +/ +&AM_geographicalVectors + config_AM_geographicalVectors_enable = false + config_AM_geographicalVectors_compute_interval = 'dt' + config_AM_geographicalVectors_output_stream = 'none' + config_AM_geographicalVectors_compute_on_startup = false + config_AM_geographicalVectors_write_on_startup = false +/ +&AM_loadBalance + config_AM_loadBalance_enable = false + config_AM_loadBalance_compute_interval = 'output_interval' + config_AM_loadBalance_output_stream = 'loadBalanceOutput' + config_AM_loadBalance_compute_on_startup = false + config_AM_loadBalance_write_on_startup = false + config_AM_loadBalance_nProcs = 32 +/ +&AM_maximumIcePresence + config_AM_maximumIcePresence_enable = false + config_AM_maximumIcePresence_compute_interval = 'dt' + config_AM_maximumIcePresence_output_stream = 'maximumIcePresenceOutput' + config_AM_maximumIcePresence_compute_on_startup = false + config_AM_maximumIcePresence_write_on_startup = false + config_AM_maximumIcePresence_start_time = '0000-00-00_00:00:00' +/ +&AM_miscellaneous + config_AM_miscellaneous_enable = false + config_AM_miscellaneous_compute_interval = 'dt' + config_AM_miscellaneous_output_stream = 'none' + config_AM_miscellaneous_compute_on_startup = false + config_AM_miscellaneous_write_on_startup = false +/ +&AM_areaVariables + config_AM_areaVariables_enable = false + config_AM_areaVariables_compute_interval = 'dt' + config_AM_areaVariables_output_stream = 'none' + config_AM_areaVariables_compute_on_startup = false + config_AM_areaVariables_write_on_startup = false +/ +&AM_pondDiagnostics + config_AM_pondDiagnostics_enable = false + config_AM_pondDiagnostics_compute_interval = 'dt' + config_AM_pondDiagnostics_output_stream = 'none' + config_AM_pondDiagnostics_compute_on_startup = false + config_AM_pondDiagnostics_write_on_startup = false +/ +&AM_unitConversion + config_AM_unitConversion_enable = true + config_AM_unitConversion_compute_interval = 'dt' + config_AM_unitConversion_output_stream = 'none' + config_AM_unitConversion_compute_on_startup = false + config_AM_unitConversion_write_on_startup = false +/ +&AM_pointwiseStats + config_AM_pointwiseStats_enable = false + config_AM_pointwiseStats_compute_interval = 'dt' + config_AM_pointwiseStats_output_stream = 'pointwiseStatsOutput' + config_AM_pointwiseStats_compute_on_startup = false + config_AM_pointwiseStats_write_on_startup = false +/ +&AM_iceShelves + config_AM_iceShelves_enable = false + config_AM_iceShelves_compute_interval = 'output_interval' + config_AM_iceShelves_output_stream = 'iceShelvesOutput' + config_AM_iceShelves_compute_on_startup = true + config_AM_iceShelves_write_on_startup = true +/ +&AM_icePresent + config_AM_icePresent_enable = false + config_AM_icePresent_compute_interval = 'dt' + config_AM_icePresent_output_stream = 'none' + config_AM_icePresent_compute_on_startup = false + config_AM_icePresent_write_on_startup = false +/ +&AM_timeSeriesStatsDaily + config_AM_timeSeriesStatsDaily_enable = false + config_AM_timeSeriesStatsDaily_compute_on_startup = false + config_AM_timeSeriesStatsDaily_write_on_startup = false + config_AM_timeSeriesStatsDaily_compute_interval = 'dt' + config_AM_timeSeriesStatsDaily_output_stream = 'timeSeriesStatsDailyOutput' + config_AM_timeSeriesStatsDaily_restart_stream = 'timeSeriesStatsDailyRestart' + config_AM_timeSeriesStatsDaily_operation = 'avg' + config_AM_timeSeriesStatsDaily_reference_times = 'initial_time' + config_AM_timeSeriesStatsDaily_duration_intervals = 'repeat_interval' + config_AM_timeSeriesStatsDaily_repeat_intervals = 'reset_interval' + config_AM_timeSeriesStatsDaily_reset_intervals = '00-00-01_00:00:00' + config_AM_timeSeriesStatsDaily_backward_output_offset = '00-00-01_00:00:00' +/ +&AM_timeSeriesStatsMonthly + config_AM_timeSeriesStatsMonthly_enable = true + config_AM_timeSeriesStatsMonthly_compute_on_startup = false + config_AM_timeSeriesStatsMonthly_write_on_startup = false + config_AM_timeSeriesStatsMonthly_compute_interval = 'dt' + config_AM_timeSeriesStatsMonthly_output_stream = 'timeSeriesStatsMonthlyOutput' + config_AM_timeSeriesStatsMonthly_restart_stream = 'timeSeriesStatsMonthlyRestart' + config_AM_timeSeriesStatsMonthly_operation = 'avg' + config_AM_timeSeriesStatsMonthly_reference_times = 'initial_time' + config_AM_timeSeriesStatsMonthly_duration_intervals = 'repeat_interval' + config_AM_timeSeriesStatsMonthly_repeat_intervals = 'reset_interval' + config_AM_timeSeriesStatsMonthly_reset_intervals = '00-01-00_00:00:00' + config_AM_timeSeriesStatsMonthly_backward_output_offset = '00-01-00_00:00:00' +/ +&AM_timeSeriesStatsClimatology + config_AM_timeSeriesStatsClimatology_enable = false + config_AM_timeSeriesStatsClimatology_compute_on_startup = false + config_AM_timeSeriesStatsClimatology_write_on_startup = false + config_AM_timeSeriesStatsClimatology_compute_interval = '00-00-00_01:00:00' + config_AM_timeSeriesStatsClimatology_output_stream = 'timeSeriesStatsClimatologyOutput' + config_AM_timeSeriesStatsClimatology_restart_stream = 'timeSeriesStatsClimatologyRestart' + config_AM_timeSeriesStatsClimatology_operation = 'avg' + config_AM_timeSeriesStatsClimatology_reference_times = '00-03-01_00:00:00;00-06-01_00:00:00;00-09-01_00:00:00;00-12-01_00:00:00' + config_AM_timeSeriesStatsClimatology_duration_intervals = '00-03-00_00:00:00;00-03-00_00:00:00;00-03-00_00:00:00;00-03-00_00:00:00' + config_AM_timeSeriesStatsClimatology_repeat_intervals = '01-00-00_00:00:00;01-00-00_00:00:00;01-00-00_00:00:00;01-00-00_00:00:00' + config_AM_timeSeriesStatsClimatology_reset_intervals = '1000-00-00_00:00:00;1000-00-00_00:00:00;1000-00-00_00:00:00;1000-00-00_00:00:00' + config_AM_timeSeriesStatsClimatology_backward_output_offset = '00-03-00_00:00:00' +/ +&AM_timeSeriesStatsCustom + config_AM_timeSeriesStatsCustom_enable = false + config_AM_timeSeriesStatsCustom_compute_on_startup = false + config_AM_timeSeriesStatsCustom_write_on_startup = false + config_AM_timeSeriesStatsCustom_compute_interval = '00-00-00_01:00:00' + config_AM_timeSeriesStatsCustom_output_stream = 'timeSeriesStatsCustomOutput' + config_AM_timeSeriesStatsCustom_restart_stream = 'timeSeriesStatsCustomRestart' + config_AM_timeSeriesStatsCustom_operation = 'avg' + config_AM_timeSeriesStatsCustom_reference_times = 'initial_time' + config_AM_timeSeriesStatsCustom_duration_intervals = 'repeat_interval' + config_AM_timeSeriesStatsCustom_repeat_intervals = 'reset_interval' + config_AM_timeSeriesStatsCustom_reset_intervals = '00-00-07_00:00:00' + config_AM_timeSeriesStatsCustom_backward_output_offset = '00-00-01_00:00:00' +/ diff --git a/testcases/moving_cyclone/plot_testcase.py b/testcases/moving_cyclone/plot_testcase.py new file mode 100644 index 0000000..3303512 --- /dev/null +++ b/testcases/moving_cyclone/plot_testcase.py @@ -0,0 +1,186 @@ +from netCDF4 import Dataset +import matplotlib +import matplotlib.pyplot as plt +from matplotlib.patches import Polygon +from matplotlib.collections import PatchCollection +import numpy as np +import matplotlib.cm as mcm +from mpl_toolkits.axes_grid1 import make_axes_locatable +import cmocean + +#------------------------------------------------------------------------------- + +def plot_testcase(gridType,resolution): + + filenameIn = "output_%s_%s/output.0001.nc" %(gridType,resolution) + fileIn = Dataset(filenameIn,"r") + + nCells = len(fileIn.dimensions["nCells"]) + nVertices = len(fileIn.dimensions["nVertices"]) + vertexDegree = len(fileIn.dimensions["vertexDegree"]) + + nEdgesOnCell = fileIn.variables["nEdgesOnCell"][:] + + verticesOnCell = fileIn.variables["verticesOnCell"][:] + verticesOnCell[:] = verticesOnCell[:] - 1 + + cellsOnVertex = fileIn.variables["cellsOnVertex"][:] + cellsOnVertex[:] = cellsOnVertex[:] - 1 + + interiorVertex = fileIn.variables["interiorVertex"][:] + + xCell = fileIn.variables["xCell"][:] + yCell = fileIn.variables["yCell"][:] + + xVertex = fileIn.variables["xVertex"][:] + yVertex = fileIn.variables["yVertex"][:] + + xMin = np.amin(xVertex) + xMax = np.amax(xVertex) + yMin = np.amin(yVertex) + yMax = np.amax(yVertex) + + iceAreaCell = fileIn.variables["iceAreaCell"][:] + iceVolumeCell = fileIn.variables["iceVolumeCell"][:] + shear = fileIn.variables["shear"][:] + uVelocity = fileIn.variables["uVelocity"][:] + vVelocity = fileIn.variables["vVelocity"][:] + + speed = np.sqrt(np.add(np.power(uVelocity,2),np.power(vVelocity,2))) + + fileIn.close() + + + cmap = mcm.viridis + + + + patchesCells = [] + for iCell in range(0,nCells): + vertices = [] + for iVertexOnCell in range(0,nEdgesOnCell[iCell]): + iVertex = verticesOnCell[iCell,iVertexOnCell] + vertices.append((xVertex[iVertex]*0.001,yVertex[iVertex]*0.001)) + patchesCells.append(Polygon(vertices,True)) + + patchesVertices = [] + verticesIndex = [] + for iVertex in range(0,nVertices): + if (interiorVertex[-1,iVertex]): + verticesIndex.append(iVertex) + vertices = [] + for iCellOnVertex in range(0,vertexDegree): + iCell = cellsOnVertex[iVertex,iCellOnVertex] + vertices.append((xCell[iCell]*0.001,yCell[iCell]*0.001)) + patchesVertices.append(Polygon(vertices,True)) + + + + cm = 1/2.54 # centimeters in inches + plt.rc('font',family="Times New Roman") + plt.rc('mathtext',fontset="stix") + SMALL_SIZE = 8 + MEDIUM_SIZE = 8 + BIGGER_SIZE = 8 + plt.rc('font', size=SMALL_SIZE) # controls default text sizes + plt.rc('axes', titlesize=SMALL_SIZE) # fontsize of the axes title + plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels + plt.rc('xtick', labelsize=SMALL_SIZE) # fontsize of the tick labels + plt.rc('ytick', labelsize=SMALL_SIZE) # fontsize of the tick labels + plt.rc('legend', fontsize=SMALL_SIZE) # legend fontsize + plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title + + stride = 10 + + fig, axes = plt.subplots(2,2,figsize=(15*cm,13*cm)) + + # velocity + pc1 = PatchCollection(patchesVertices, cmap=cmap) + pc1.set_array(speed[-1,verticesIndex]) + pc1.set_clim([0.0,None]) + axes[0,0].add_collection(pc1) + axes[0,0].quiver(xVertex[::stride]*0.001, yVertex[::stride]*0.001, uVelocity[-1,::stride], vVelocity[-1,::stride]) + + divider = make_axes_locatable(axes[0,0]) + cax = divider.append_axes('right', size='5%', pad=0.05) + fig.colorbar(pc1, cax=cax, orientation='vertical') + + # shear + norm = matplotlib.colors.LogNorm(vmin=1e-8,vmax=1e-4) + #norm = matplotlib.colors.LogNorm() + pc2 = PatchCollection(patchesCells, cmap="Greys", norm=norm) + shear[:] /= (100.0 * 86400.0) # % per day to s^-1 + #shear = np.where(shear < 1e-8, 1e-8, shear) + pc2.set_array(shear[-1,:]) + #pc2.set_clim([0.0,None]) + axes[0,1].add_collection(pc2) + + divider = make_axes_locatable(axes[0,1]) + cax = divider.append_axes('right', size='5%', pad=0.05) + fig.colorbar(pc2, cax=cax, orientation='vertical') + + # ice concentration + norm = matplotlib.colors.Normalize(vmin=0.75,vmax=1.0) + pc3 = PatchCollection(patchesCells, cmap=cmocean.cm.ice, norm=norm) + pc3.set_array(iceAreaCell[-1,:]) + axes[1,0].add_collection(pc3) + + divider = make_axes_locatable(axes[1,0]) + cax = divider.append_axes('right', size='5%', pad=0.05) + fig.colorbar(pc3, cax=cax, orientation='vertical') + + # ice volume + pc4 = PatchCollection(patchesCells, cmap=cmap) + pc4.set_array(iceVolumeCell[-1,:]) + axes[1,1].add_collection(pc4) + + divider = make_axes_locatable(axes[1,1]) + cax = divider.append_axes('right', size='5%', pad=0.05) + fig.colorbar(pc4, cax=cax, orientation='vertical') + + + + + axes[0,0].set_xlim((xMin*0.001,xMax*0.001)) + axes[0,0].set_ylim((yMin*0.001,yMax*0.001)) + axes[0,0].set_title("Velocity (m/s)") + axes[0,0].set_aspect("equal") + axes[0,0].set_xlabel("x (km)") + axes[0,0].set_ylabel("y (km)") + + axes[0,1].set_xlim((xMin*0.001,xMax*0.001)) + axes[0,1].set_ylim((yMin*0.001,yMax*0.001)) + axes[0,1].set_title("Shear (s^-1)") + axes[0,1].set_aspect("equal") + axes[0,1].set_xlabel("x (km)") + axes[0,1].set_ylabel("y (km)") + + axes[1,0].set_xlim((xMin*0.001,xMax*0.001)) + axes[1,0].set_ylim((yMin*0.001,yMax*0.001)) + axes[1,0].set_title("Concentration (-)") + axes[1,0].set_aspect("equal") + axes[1,0].set_xlabel("x (km)") + axes[1,0].set_ylabel("y (km)") + + axes[1,1].set_xlim((xMin*0.001,xMax*0.001)) + axes[1,1].set_ylim((yMin*0.001,yMax*0.001)) + axes[1,1].set_title("Thickness (m)") + axes[1,1].set_aspect("equal") + axes[1,1].set_xlabel("x (km)") + axes[1,1].set_ylabel("y (km)") + + plt.tight_layout() + plt.savefig("moving_cyclone_%s_%s.png" %(gridType,resolution),dpi=300) + +#------------------------------------------------------------------------------- + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description='') + + parser.add_argument('-m', dest='gridType', choices=["quad","hex"], help='') + parser.add_argument('-r', dest='resolution', choices=["2km","4km","8km"], help='') + + args = parser.parse_args() + + plot_testcase(args.gridType,args.resolution) diff --git a/testcases/moving_cyclone/run_model.py b/testcases/moving_cyclone/run_model.py new file mode 100644 index 0000000..3d60164 --- /dev/null +++ b/testcases/moving_cyclone/run_model.py @@ -0,0 +1,41 @@ +import os + +#------------------------------------------------------------------------------- + +def run_model(): + + MPAS_SEAICE_EXECUTABLE = os.environ.get('MPAS_SEAICE_EXECUTABLE') + MPAS_SEAICE_TESTCASES_RUN_COMMAND = os.environ.get('MPAS_SEAICE_TESTCASES_RUN_COMMAND') + if (MPAS_SEAICE_TESTCASES_RUN_COMMAND is None): + MPAS_SEAICE_TESTCASES_RUN_COMMAND = "" + + gridTypes = ["quad","hex"] + resolutions = ["4km"] + + for gridType in gridTypes: + + print("gridType: ", gridType) + + for resolution in resolutions: + + print(" Resolution: ", resolution) + + os.system("rm -rf output_%s_%s" %(gridType, resolution)) + + os.system("rm grid.nc") + os.system("rm forcing.nc") + os.system("rm ic.nc") + + os.system("ln -s grid_moving_cyclone_%s_%s.nc grid.nc" %(gridType,resolution)) + os.system("ln -s forcing_moving_cyclone_%s_%s.nc forcing.nc" %(gridType,resolution)) + os.system("ln -s ic_moving_cyclone_%s_%s.nc ic.nc" %(gridType,resolution)) + + os.system("%s %s" %(MPAS_SEAICE_TESTCASES_RUN_COMMAND, MPAS_SEAICE_EXECUTABLE)) + + os.system("mv output output_%s_%s" %(gridType,resolution)) + +#------------------------------------------------------------------------------- + +if __name__ == "__main__": + + run_model() diff --git a/testcases/moving_cyclone/run_testcase.py b/testcases/moving_cyclone/run_testcase.py new file mode 100644 index 0000000..7d3b937 --- /dev/null +++ b/testcases/moving_cyclone/run_testcase.py @@ -0,0 +1,10 @@ +from make_testcase import make_testcase +from run_model import run_model +from plot_testcase import plot_testcase + +make_testcase() + +run_model() + +plot_testcase("quad","4km") +plot_testcase("hex","4km") diff --git a/testcases/moving_cyclone/streams.seaice b/testcases/moving_cyclone/streams.seaice new file mode 100644 index 0000000..2c5eca7 --- /dev/null +++ b/testcases/moving_cyclone/streams.seaice @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +