diff --git a/assimilation_code/modules/utilities/netcdf_utilities_mod.f90 b/assimilation_code/modules/utilities/netcdf_utilities_mod.f90 index 74301bd6f4..22c819a37b 100644 --- a/assimilation_code/modules/utilities/netcdf_utilities_mod.f90 +++ b/assimilation_code/modules/utilities/netcdf_utilities_mod.f90 @@ -2415,7 +2415,7 @@ function nc_create_file(filename, context) character(len=*), parameter :: routine = 'nc_create_file' integer :: ret, ncid, oldmode -ret = nf90_create(filename, NF90_CLOBBER, ncid) +ret = nf90_create(filename, ior(NF90_CLOBBER,NF90_64BIT_OFFSET), ncid) call nc_check(ret, routine, 'create '//trim(filename)//' read/write', context) call add_fh_to_list(ncid, filename) diff --git a/assimilation_code/programs/model_mod_check/model_mod_check.f90 b/assimilation_code/programs/model_mod_check/model_mod_check.f90 index ee4eea51a0..f56c7617a1 100644 --- a/assimilation_code/programs/model_mod_check/model_mod_check.f90 +++ b/assimilation_code/programs/model_mod_check/model_mod_check.f90 @@ -416,7 +416,7 @@ subroutine check_meta_data( iloc ) kind_index=qty_index, & kind_string=qty_string) -write(string1,'("index ",i11," is i,j,k",3(1x,i4)," and is in domain ",i2)') & +write(string1,'("index ",i11," is i,j,k",3(1x,i10)," and is in domain ",i2)') & iloc, ix, iy, iz, dom_id write(string2,'("is quantity ", I4,", ",A)') var_type, trim(qty_string)//' at location' call write_location(0,loc,charstring=string3) @@ -556,9 +556,12 @@ subroutine check_all_meta_data() kind_string=qty_string) ! CLM has (potentially many) columns and needs i7 ish precision - write(string1,'(i11,1x,''i,j,k'',3(1x,i7),'' domain '',i2)') & +! write(string1,'(i11,1x,''i,j,k'',3(1x,i7),'' domain '',i2)') & +! iloc, ix, iy, iz, dom_id + ! EL: integer to short for the new I/O method + ! Change to long int to avoid problems + write(string1,'(i21,1x,''i,j,k'',3(1x,i21),'' domain '',i2)') & iloc, ix, iy, iz, dom_id - call get_state_meta_data(iloc, loc, var_type) metadata_qty_string = trim(get_name_for_quantity(var_type)) diff --git a/models/MITgcm_ocean/expand_netcdf.f90 b/models/MITgcm_ocean/expand_netcdf.f90 new file mode 100644 index 0000000000..f463b82df0 --- /dev/null +++ b/models/MITgcm_ocean/expand_netcdf.f90 @@ -0,0 +1,149 @@ +! Uncompress a netcdf fil +program expand_netcdf + +use netcdf_utilities_mod, only: nc_open_file_readonly, nc_get_dimension_size, & + nc_define_dimension, nc_create_file, & + nc_get_variable, nc_close_file, nc_put_variable, & + nc_define_real_variable, nc_end_define_mode, & + nc_add_attribute_to_variable + +use types_mod, only : r4, MISSING_R4 + +use utilities_mod, only : initialize_utilities, finalize_utilities + +use netcdf + +implicit none + +integer :: ncid, ncid_comp, dimid(1), dimlen, ret +integer :: Nx,Ny,Nz +integer :: nvars ! total number of variables in compressed file +integer :: id, n, c! loop variables +integer :: i,j,k, ncomp3d, ncomp2d +character(len=NF90_MAX_NAME) :: varname +real(r4), allocatable :: vals3d(:,:,:), vals2d(:,:), vals_comp(:) +integer, allocatable :: Xcomp_ind(:), Ycomp_ind(:), Zcomp_ind(:) + +call initialize_utilities('expand_netcdf') + +ncid_comp = nc_open_file_readonly('compressed.nc') +ncid = nc_create_file('expanded.nc') + +! get the Nx,Ny,Nz +Nx = nc_get_dimension_size(ncid_comp, 'XC') +Ny = nc_get_dimension_size(ncid_comp, 'YC') +Nz = nc_get_dimension_size(ncid_comp, 'ZC') + +! define Nx,Ny,Nz in the expanded file +call nc_define_dimension(ncid, 'X', Nx) +call nc_define_dimension(ncid, 'Y', Ny) +call nc_define_dimension(ncid, 'Z', Nz) + +! get the compressed size +ncomp2d = nc_get_dimension_size(ncid_comp, 'comp2d') +ncomp3d = nc_get_dimension_size(ncid_comp, 'comp3d') + +allocate(vals_comp(ncomp3d)) +allocate(vals2d(Nx,Ny), vals3d(Nx,Ny,Nz)) + +! read in +allocate(Xcomp_ind(ncomp3d), Ycomp_ind(ncomp3d), Zcomp_ind(ncomp3d)) +call nc_get_variable(ncid_comp, 'Ycomp_ind', Ycomp_ind) +call nc_get_variable(ncid_comp, 'Xcomp_ind', Xcomp_ind) +call nc_get_variable(ncid_comp, 'Zcomp_ind', Zcomp_ind) + + +! get the number of variables +ret = nf90_inquire(ncid_comp, nVariables=nvars) + +! define variables +do id = 1, nvars + ret = nf90_inquire_variable(ncid_comp, id, varname, dimids=dimid) + + ! is a it a compressed state variable? + if (var_of_interest(varname)) then + + ! inquire dimention length (2d or 3d) + ret = nf90_inquire_dimension(ncid_comp, dimid(1), len=dimlen) + + ! define expanded variable + if (dimlen == ncomp3d) then + call nc_define_real_variable(ncid, varname, (/'X','Y','Z'/)) + else + call nc_define_real_variable(ncid, varname, (/'X','Y'/)) + endif + + call nc_add_attribute_to_variable(ncid, varname, 'missing_value', MISSING_R4) + + endif +enddo + +call nc_end_define_mode(ncid) + +! write variables +do id = 1, nvars + ret = nf90_inquire_variable(ncid_comp, id, varname, dimids=dimid) + + ! is a it a compressed state variable? + if (var_of_interest(varname)) then + + ! inquire dimention length (2d or 3d) + ret = nf90_inquire_dimension(ncid_comp, dimid(1), len=dimlen) + + ! read in compressed variable + if (dimlen == ncomp3d) then + call nc_get_variable(ncid_comp, varname, vals_comp) + vals3d = MISSING_R4 + else + call nc_get_variable(ncid_comp, varname, vals_comp(1:ncomp2d)) + vals2d = MISSING_R4 + endif + + ! expand + c = 1 + do n = 1, ncomp3d + i = Xcomp_ind(n) + j = Ycomp_ind(n) + k = Zcomp_ind(n) + if (k == 1 .and. dimlen == ncomp2d) then + vals2d(i,j) = vals_comp(c) + c = c + 1 + else + vals3d(i,j,k) = vals_comp(n) + endif + enddo + + ! write expanded variable + if (dimlen == ncomp3d) then + call nc_put_variable(ncid, varname, vals3d) + else + call nc_put_variable(ncid, varname, vals2d) + endif + + endif +enddo + +call nc_close_file(ncid_comp) +call nc_close_file(ncid) + +call finalize_utilities('expand_netcdf') + +contains + + ! logical to ignore compression variables + function var_of_interest(varname) + character(len=*), intent(in) :: varname + logical :: var_of_interest + + select case (varname) + case ('XGcomp', 'XCcomp', 'YGcomp', 'YCcomp', 'ZCcomp', 'Xcomp_ind', 'Ycomp_ind', 'Zcomp_ind') + var_of_interest = .false. + case ('XC', 'YC', 'ZC', 'XG', 'YG') + var_of_interest = .false. + case default + var_of_interest = .true. + end select + + end function var_of_interest + +end program expand_netcdf diff --git a/models/MITgcm_ocean/model_mod.f90 b/models/MITgcm_ocean/model_mod.f90 index cc331593f5..3e4d763a1d 100644 --- a/models/MITgcm_ocean/model_mod.f90 +++ b/models/MITgcm_ocean/model_mod.f90 @@ -20,7 +20,7 @@ module model_mod get_close_state, get_close_obs, set_location, & VERTISHEIGHT, get_location, is_vertical, & convert_vertical_obs, convert_vertical_state - +! EL use only nc_check was here, deleted for now for testing use utilities_mod, only : error_handler, E_ERR, E_WARN, E_MSG, & logfileunit, get_unit, nc_check, do_output, to_upper, & find_namelist_in_file, check_namelist_read, & @@ -54,7 +54,10 @@ module model_mod get_index_start, get_index_end, & get_dart_vector_index, get_num_variables, & get_domain_size, & - get_io_clamping_minval + get_io_clamping_minval, get_kind_index + +use netcdf_utilities_mod, only : nc_open_file_readonly, nc_get_variable, & + nc_get_dimension_size, nc_close_file use netcdf @@ -253,9 +256,12 @@ module model_mod ! standard MITgcm namelist and filled in here. integer :: Nx=-1, Ny=-1, Nz=-1 ! grid counts for each field +integer :: comp3d=-1 ! size of commpressed variables ! locations of cell centers (C) and edges (G) for each axis. real(r8), allocatable :: XC(:), XG(:), YC(:), YG(:), ZC(:), ZG(:) +real(r4), allocatable :: XC_sq(:), YC_sq(:), XG_sq(:), YG_sq(:) +real(r8), allocatable :: ZC_sq(:) real(r8) :: ocean_dynamics_timestep = 900.0_r4 integer :: timestepcount = 0 @@ -275,7 +281,6 @@ module model_mod integer, parameter :: NUM_STATE_TABLE_COLUMNS = 5 character(len=vtablenamelength) :: mitgcm_variables(NUM_STATE_TABLE_COLUMNS, MAX_STATE_VARIABLES ) = ' ' - character(len=256) :: model_shape_file = ' ' integer :: assimilation_period_days = 7 integer :: assimilation_period_seconds = 0 @@ -290,8 +295,9 @@ module model_mod logical :: go_to_dart = .false. logical :: do_bgc = .false. logical :: log_transform = .false. +logical :: compress = .false. -namelist /trans_mitdart_nml/ go_to_dart, do_bgc, log_transform +namelist /trans_mitdart_nml/ go_to_dart, do_bgc, log_transform, compress ! /pkg/mdsio/mdsio_write_meta.F writes the .meta files type MIT_meta_type @@ -325,6 +331,7 @@ subroutine static_init_model() integer :: i, iunit, io integer :: ss, dd +integer :: ncid ! for reading compressed coordinates ! The Plan: ! @@ -526,13 +533,35 @@ subroutine static_init_model() domain_id = add_domain(model_shape_file, nvars, & var_names, quantity_list, clamp_vals, update_list ) +if (compress) then ! read in compressed coordinates + + ncid = nc_open_file_readonly(model_shape_file) + comp3d = nc_get_dimension_size(ncid, 'comp3d', 'static_init_model', model_shape_file) + + allocate(XC_sq(comp3d)) + allocate(YC_sq(comp3d)) + allocate(ZC_sq(comp3d)) ! ZC is r8 + + allocate(XG_sq(comp3d)) + allocate(YG_sq(comp3d)) + + call nc_get_variable(ncid, 'XCcomp', XC_sq) + call nc_get_variable(ncid, 'YCcomp', YC_sq) + call nc_get_variable(ncid, 'ZCcomp', ZC_sq) + + call nc_get_variable(ncid, 'XGcomp', XG_sq) + call nc_get_variable(ncid, 'YGcomp', YG_sq) + + call nc_close_file(ncid) + +endif + model_size = get_domain_size(domain_id) if (do_output()) write(*,*) 'model_size = ', model_size end subroutine static_init_model - function get_model_size() !------------------------------------------------------------------ ! @@ -952,6 +981,84 @@ function lon_dist(lon1, lon2) end function lon_dist +function get_compressed_dart_vector_index(iloc, jloc, kloc, dom_id, var_id) +!======================================================================= +! + +! returns the dart vector index for the compressed state + +integer, intent(in) :: iloc, jloc, kloc +integer, intent(in) :: dom_id, var_id +integer(i8) :: get_compressed_dart_vector_index + +real(r4) :: lon, lat +real(r8) :: depth +integer :: i ! loop counter +logical :: lon_found, lat_found, depth_found +integer :: qty + +integer(i8) :: offset +logical :: is_2d + +offset = get_index_start(dom_id, var_id) + +lon = XC(iloc) !lon +lat = YC(jloc) !lat +depth = ZC(kloc) !depth + +qty = get_kind_index(dom_id, var_id) +if (qty == QTY_U_CURRENT_COMPONENT) lon = XG(iloc) +if (qty == QTY_V_CURRENT_COMPONENT) lat = YG(jloc) + +is_2d = .false. + +if (qty == QTY_SEA_SURFACE_HEIGHT .or. qty == QTY_SURFACE_CHLOROPHYLL ) then + depth = ZC(1) + is_2d = .true. +endif + +get_compressed_dart_vector_index = -1 + +! Find the index in the compressed state +! HK you could read in {X,Y,Z}comp_ind if you did not want to do this search +do i=1, comp3d + lon_found = .false. + lat_found = .false. + depth_found = .false. + + if (qty == QTY_U_CURRENT_COMPONENT) then + if ( XG_sq(i) == lon ) then + lon_found = .true. + endif + else + if ( XC_sq(i) == lon ) then + lon_found = .true. + endif + endif + + if (qty == QTY_V_CURRENT_COMPONENT) then + if (YG_sq(i) == lat) then + lat_found = .true. + endif + else + if ( YC_sq(i) == lat ) then + lat_found = .true. + endif + endif + + if ( ZC_sq(i) == depth ) then + depth_found = .true. + endif + + if (lon_found .and. lat_found .and. depth_found )then + get_compressed_dart_vector_index = offset + i - 1 + return + endif +enddo + +end function get_compressed_dart_vector_index + + function get_val(lon_index, lat_index, level, var_id, state_handle,ens_size, masked) !======================================================================= ! @@ -969,24 +1076,28 @@ function get_val(lon_index, lat_index, level, var_id, state_handle,ens_size, mas if ( .not. module_initialized ) call static_init_model -state_index = get_dart_vector_index(lon_index, lat_index, level, domain_id, var_id) -get_val = get_state(state_index,state_handle) +masked = .false. -! Masked returns false if the value is masked -! A grid variable is assumed to be masked if its value is FVAL. -! Just to maintain legacy, we also assume that A grid variable is assumed -! to be masked if its value is exactly 0. -! See discussion in lat_lon_interpolate. +if (compress) then -! MEG CAUTION: THE ABOVE STATEMENT IS INCORRECT -! trans_mitdart already looks for 0.0 and makes them FVAL -! So, in the condition below we don't need to check for zeros -! The only mask is FVAL -masked = .false. -do i=1,ens_size -! if(get_val(i) == FVAL .or. get_val(i) == 0.0_r8 ) masked = .true. - if(get_val(i) == FVAL) masked = .true. -enddo + state_index = get_compressed_dart_vector_index(lon_index, lat_index, level, domain_id, var_id) + + if (state_index .ne. -1) then + get_val = get_state(state_index,state_handle) + else + masked = .true. + endif + +else + + state_index = get_dart_vector_index(lon_index, lat_index, level, domain_id, var_id) + get_val = get_state(state_index,state_handle) + + do i=1,ens_size ! HK this is checking the whole ensemble, can you have different masks for each ensemble member? + if(get_val(i) == FVAL) masked = .true. + enddo + +endif end function get_val @@ -1077,16 +1188,28 @@ subroutine get_state_meta_data(index_in, location, qty) call get_model_variable_indices(index_in, iloc, jloc, kloc, kind_index = qty) -lon = XC(iloc) -lat = YC(jloc) -depth = ZC(kloc) +if (compress) then ! all variables ae 1D + lon = XC_sq(iloc) + lat = YC_sq(iloc) + depth = ZC_sq(iloc) + ! Acounting for variables those on staggered grids + if (qty == QTY_U_CURRENT_COMPONENT) lon = XG_sq(iloc) + if (qty == QTY_V_CURRENT_COMPONENT) lat = YG_sq(iloc) +else + + lon = XC(iloc) + lat = YC(jloc) + depth = ZC(kloc) + + ! Acounting for variables those on staggered grids + if (qty == QTY_U_CURRENT_COMPONENT) lon = XG(iloc) + if (qty == QTY_V_CURRENT_COMPONENT) lat = YG(jloc) + +endif -! Acounting for surface variables and those on staggered grids ! MEG: check chl's depth here if (qty == QTY_SEA_SURFACE_HEIGHT .or. & qty == QTY_SURFACE_CHLOROPHYLL) depth = 0.0_r8 -if (qty == QTY_U_CURRENT_COMPONENT) lon = XG(iloc) -if (qty == QTY_V_CURRENT_COMPONENT) lat = YG(jloc) location = set_location(lon, lat, depth, VERTISHEIGHT) @@ -1295,6 +1418,8 @@ end subroutine nc_write_model_atts !------------------------------------------------------------------ ! Create an ensemble of states from a single state. +! Note if you perturb a compressed state, this will not be bitwise +! with perturbing a non-compressed state. subroutine pert_model_copies(state_ens_handle, ens_size, pert_amp, interf_provided) type(ensemble_type), intent(inout) :: state_ens_handle diff --git a/models/MITgcm_ocean/model_mod.nml b/models/MITgcm_ocean/model_mod.nml index ef64b88caa..03b81505ae 100644 --- a/models/MITgcm_ocean/model_mod.nml +++ b/models/MITgcm_ocean/model_mod.nml @@ -2,5 +2,6 @@ assimilation_period_days = 7 assimilation_period_seconds = 0 model_perturbation_amplitude = 0.2 + model_shape_file = 'mem01_reduced.nc' / diff --git a/models/MITgcm_ocean/readme.rst b/models/MITgcm_ocean/readme.rst index d63e56fea0..c6b7dc3dfd 100644 --- a/models/MITgcm_ocean/readme.rst +++ b/models/MITgcm_ocean/readme.rst @@ -34,8 +34,14 @@ can be set in the ``&trans_mitdart_nml`` namelist in ``input.nml``. &trans_mitdart_nml do_bgc = .false. ! change to .true. if doing bio-geo-chemistry log_transform = .false. ! change to .true. if using log_transform + compress = .false. ! change to .true. to compress the state vector / +``compress = .true.`` can be used to generate netcdf files for use with DART which has missing values (land) removed. +For some datasets this reduces the state vector size significantly. For example, the state vector size is +reduced by approximately 90% for the Red Sea. The program ``expand_netcdf`` can be used to uncompress the netcdf +file to view the data in a convenient form. + .. Warning:: diff --git a/models/MITgcm_ocean/trans_mitdart_mod.f90 b/models/MITgcm_ocean/trans_mitdart_mod.f90 index 15861b8164..2a7838e567 100644 --- a/models/MITgcm_ocean/trans_mitdart_mod.f90 +++ b/models/MITgcm_ocean/trans_mitdart_mod.f90 @@ -9,6 +9,7 @@ module trans_mitdart_mod use utilities_mod, only: initialize_utilities, register_module, & get_unit, find_namelist_in_file, file_exist, & check_namelist_read +use netcdf_utilities_mod, only : nc_get_variable, nc_get_dimension_size use netcdf implicit none @@ -20,9 +21,16 @@ module trans_mitdart_mod integer :: io, iunit logical :: do_bgc = .false. -logical :: log_transform = .false. +logical :: log_transform = .false. +logical :: compress = .false. +! set compress = .true. remove missing values from state +logical :: output_chl_data = .false. +! CHL.data is not written to mit .data files by default -namelist /trans_mitdart_nml/ do_bgc, log_transform +namelist /trans_mitdart_nml/ do_bgc, log_transform, compress + +real(r4), parameter :: FVAL=-999.0_r4 ! may put this as a namelist option +real(r4), parameter :: binary_fill=0.0_r4 !------------------------------------------------------------------ ! @@ -43,7 +51,7 @@ module trans_mitdart_mod integer :: recl3d integer :: recl2d -!-- Gridding parameters variable declarations +!-- Gridding parameters variable declarations logical :: usingCartesianGrid, usingCylindricalGrid, & usingSphericalPolarGrid, usingCurvilinearGrid, & deepAtmosphere @@ -71,14 +79,37 @@ module trans_mitdart_mod ! standard MITgcm namelist and filled in here. integer :: Nx=-1, Ny=-1, Nz=-1 ! grid counts for each field +integer :: ncomp2=-1, ncomp3=-1 ! length of compressed dim ! locations of cell centers (C) and edges (G) for each axis. real(r8), allocatable :: XC(:), XG(:), YC(:), YG(:), ZC(:), ZG(:) +real(r8), allocatable :: XCcomp(:), XGcomp(:), YCcomp(:), YGcomp(:), ZCcomp(:), ZGcomp(:) +integer, allocatable :: Xcomp_ind(:), Ycomp_ind(:), Zcomp_ind(:) !HK are the staggered grids compressed the same? + +! 3D variables, 3 grids: +! +! XC, YC, ZC 1 PSAL, PTMP, NO3, PO4, O2, PHY, ALK, DIC, DOP, DON, FET +! XC, YC, ZG 2 UVEL +! XC, YG, ZC 3 VVEL + +! 2D variables, 1 grid: +! +! YC, XC ETA, CHL private public :: static_init_trans, mit2dart, dart2mit +interface write_compressed + module procedure write_compressed_2d + module procedure write_compressed_3d +end interface write_compressed + +interface read_compressed + module procedure read_compressed_2d + module procedure read_compressed_3d +end interface read_compressed + contains !================================================================== @@ -100,7 +131,6 @@ subroutine static_init_trans() read(iunit, nml = trans_mitdart_nml, iostat = io) call check_namelist_read(iunit, io, 'trans_mitdart_nml') - ! Grid-related variables are in PARM04 delX(:) = 0.0_r4 delY(:) = 0.0_r4 @@ -196,13 +226,6 @@ subroutine static_init_trans() recl3d = Nx*Ny*Nz*4 recl2d = Nx*Ny*4 -! MEG Better have that as inout namelist parameter -! Are we also doing bgc on top of physics? -! If we found nitrate then the rest of the binaries (for the -! remaining 9 variables) should be also there. -! TODO may also enhance this functionality -! if (file_exist('NO3.data')) do_bgc = .true. - end subroutine static_init_trans !------------------------------------------------------------------ @@ -210,11 +233,15 @@ end subroutine static_init_trans subroutine mit2dart() -integer :: ncid, iunit +integer :: ncid ! for the dimensions and coordinate variables integer :: XGDimID, XCDimID, YGDimID, YCDimID, ZGDimID, ZCDimID integer :: XGVarID, XCVarID, YGVarID, YCVarID, ZGVarID, ZCVarID +integer :: comp2ID, comp3ID ! compressed dim +integer :: XGcompVarID, XCcompVarID, YGcompVarID, YCcompVarID, ZGcompVarID, ZCcompVarID +integer :: XindID, YindID, ZindID +integer :: all_dimids(7) ! store the 7 dimension ids that are used ! for the prognostic variables integer :: SVarID, TVarID, UVarID, VVarID, EtaVarID @@ -224,27 +251,31 @@ subroutine mit2dart() ! diagnostic variable integer :: chl_varid -real(r4), allocatable :: data_3d(:,:,:), data_2d(:,:) - -real(r4) :: FVAL - if (.not. module_initialized) call static_init_trans -FVAL=-999.0_r4 - -allocate(data_3d(Nx,Ny,Nz)) -allocate(data_2d(Nx,Ny)) - call check(nf90_create(path="OUTPUT.nc",cmode=or(nf90_clobber,nf90_64bit_offset),ncid=ncid)) ! Define the new dimensions IDs - -call check(nf90_def_dim(ncid=ncid, name="XG", len = Nx, dimid = XGDimID)) + call check(nf90_def_dim(ncid=ncid, name="XC", len = Nx, dimid = XCDimID)) -call check(nf90_def_dim(ncid=ncid, name="YG", len = Ny, dimid = YGDimID)) call check(nf90_def_dim(ncid=ncid, name="YC", len = Ny, dimid = YCDimID)) call check(nf90_def_dim(ncid=ncid, name="ZC", len = Nz, dimid = ZCDimID)) - + +call check(nf90_def_dim(ncid=ncid, name="XG", len = Nx, dimid = XGDimID)) +call check(nf90_def_dim(ncid=ncid, name="YG", len = Ny, dimid = YGDimID)) + +if (compress) then + ncomp2 = get_compressed_size_2d() + ncomp3 = get_compressed_size_3d() + call check(nf90_def_dim(ncid=ncid, name="comp2d", len = ncomp2, dimid = comp2ID)) + call check(nf90_def_dim(ncid=ncid, name="comp3d", len = ncomp3, dimid = comp3ID)) +else + comp2ID = -1 + comp3ID = -1 +endif + +all_dimids = (/XCDimID, YCDimID, ZCDimID, XGDimID, YGDimID, comp2ID, comp3ID/) + ! Create the (empty) Coordinate Variables and the Attributes ! U Grid Longitudes @@ -290,142 +321,80 @@ subroutine mit2dart() call check(nf90_put_att(ncid, ZCVarID, "axis", "Z")) call check(nf90_put_att(ncid, ZCVarID, "standard_name", "depth")) +! Compressed grid variables +if (compress) then + call check(nf90_def_var(ncid,name="XGcomp",xtype=nf90_real,dimids=comp3ID,varid=XGcompVarID)) + call check(nf90_def_var(ncid,name="XCcomp",xtype=nf90_real,dimids=comp3ID,varid=XCcompVarID)) + call check(nf90_def_var(ncid,name="YGcomp",xtype=nf90_real,dimids=comp3ID,varid=YGcompVarID)) + call check(nf90_def_var(ncid,name="YCcomp",xtype=nf90_real,dimids=comp3ID,varid=YCcompVarID)) + call check(nf90_def_var(ncid,name="ZCcomp",xtype=nf90_double,dimids=comp3ID,varid=ZCcompVarID)) + call check(nf90_def_var(ncid,name="Xcomp_ind",xtype=nf90_int,dimids=comp3ID,varid=XindID)) + call check(nf90_def_var(ncid,name="Ycomp_ind",xtype=nf90_int,dimids=comp3ID,varid=YindID)) + call check(nf90_def_var(ncid,name="Zcomp_ind",xtype=nf90_int,dimids=comp3ID,varid=ZindID)) +endif + +! The size of these variables will depend on the compression ! Create the (empty) Prognostic Variables and the Attributes -call check(nf90_def_var(ncid=ncid, name="PSAL", xtype=nf90_real, & - dimids = (/XCDimID,YCDimID,ZCDimID/),varid=SVarID)) -call check(nf90_put_att(ncid, SVarID, "long_name", "potential salinity")) -call check(nf90_put_att(ncid, SVarID, "missing_value", FVAL)) -call check(nf90_put_att(ncid, SVarID, "_FillValue", FVAL)) -call check(nf90_put_att(ncid, SVarID, "units", "psu")) -call check(nf90_put_att(ncid, SVarID, "units_long_name", "practical salinity units")) - -call check(nf90_def_var(ncid=ncid, name="PTMP", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=TVarID)) -call check(nf90_put_att(ncid, TVarID, "long_name", "Potential Temperature")) -call check(nf90_put_att(ncid, TVarID, "missing_value", FVAL)) -call check(nf90_put_att(ncid, TVarID, "_FillValue", FVAL)) -call check(nf90_put_att(ncid, TVarID, "units", "C")) -call check(nf90_put_att(ncid, TVarID, "units_long_name", "degrees celsius")) - -call check(nf90_def_var(ncid=ncid, name="UVEL", xtype=nf90_real, & - dimids=(/XGDimID,YCDimID,ZCDimID/),varid=UVarID)) -call check(nf90_put_att(ncid, UVarID, "long_name", "Zonal Velocity")) -call check(nf90_put_att(ncid, UVarID, "mssing_value", FVAL)) -call check(nf90_put_att(ncid, UVarID, "_FillValue", FVAL)) -call check(nf90_put_att(ncid, UVarID, "units", "m/s")) -call check(nf90_put_att(ncid, UVarID, "units_long_name", "meters per second")) - -call check(nf90_def_var(ncid=ncid, name="VVEL", xtype=nf90_real, & - dimids=(/XCDimID,YGDimID,ZCDimID/),varid=VVarID)) -call check(nf90_put_att(ncid, VVarID, "long_name", "Meridional Velocity")) -call check(nf90_put_att(ncid, VVarID, "missing_value", FVAL)) -call check(nf90_put_att(ncid, VVarID, "_FillValue", FVAL)) -call check(nf90_put_att(ncid, VVarID, "units", "m/s")) -call check(nf90_put_att(ncid, VVarID, "units_long_name", "meters per second")) - -call check(nf90_def_var(ncid=ncid, name="ETA", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID/),varid=EtaVarID)) -call check(nf90_put_att(ncid, EtaVarID, "long_name", "sea surface height")) -call check(nf90_put_att(ncid, EtaVarID, "missing_value", FVAL)) -call check(nf90_put_att(ncid, EtaVarID, "_FillValue", FVAL)) -call check(nf90_put_att(ncid, EtaVarID, "units", "m")) -call check(nf90_put_att(ncid, EtaVarID, "units_long_name", "meters")) - -!> Add BLING data: +SVarID = define_variable(ncid,"PSAL", nf90_real, all_dimids) +call add_attributes_to_variable(ncid, SVarID, "potential salinity", "psu", "practical salinity units") + +TVarID = define_variable(ncid,"PTMP", nf90_real, all_dimids) +call add_attributes_to_variable(ncid, TVarID, "Potential Temperature", "C", "degrees celsius") + +UVarID = define_variable(ncid,"UVEL", nf90_real, all_dimids) +call add_attributes_to_variable(ncid, UVarID, "Zonal Velocity", "m/s", "meters per second") + +VVarID = define_variable(ncid,"VVEL", nf90_real, all_dimids) +call add_attributes_to_variable(ncid, VVarID, "Meridional Velocity", "m/s", "meters per second") + +EtaVarID = define_variable_2d(ncid,"ETA", nf90_real, all_dimids) +call add_attributes_to_variable(ncid, EtaVarID, "sea surface height", "m", "meters") + +! Create the BLING netcdf variables: if (do_bgc) then ! 1. BLING tracer: nitrate NO3 - call check(nf90_def_var(ncid=ncid, name="NO3", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=no3_varid)) - call check(nf90_put_att(ncid, no3_varid, "long_name" , "Nitrate")) - call check(nf90_put_att(ncid, no3_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, no3_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, no3_varid, "units" , "mol N/m3")) - call check(nf90_put_att(ncid, no3_varid, "units_long_name", "moles Nitrogen per cubic meters")) - + no3_varid = define_variable(ncid,"NO3", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, no3_varid, "Nitrate", "mol N/m3", "moles Nitrogen per cubic meters") + ! 2. BLING tracer: phosphate PO4 - call check(nf90_def_var(ncid=ncid, name="PO4", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=po4_varid)) - call check(nf90_put_att(ncid, po4_varid, "long_name" , "Phosphate")) - call check(nf90_put_att(ncid, po4_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, po4_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, po4_varid, "units" , "mol P/m3")) - call check(nf90_put_att(ncid, po4_varid, "units_long_name", "moles Phosphorus per cubic meters")) - + po4_varid = define_variable(ncid,"PO4", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, po4_varid, "Phosphate", "mol P/m3", "moles Phosphorus per cubic meters") + ! 3. BLING tracer: oxygen O2 - call check(nf90_def_var(ncid=ncid, name="O2", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=o2_varid)) - call check(nf90_put_att(ncid, o2_varid, "long_name" , "Dissolved Oxygen")) - call check(nf90_put_att(ncid, o2_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, o2_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, o2_varid, "units" , "mol O/m3")) - call check(nf90_put_att(ncid, o2_varid, "units_long_name", "moles Oxygen per cubic meters")) - + o2_varid = define_variable(ncid,"O2", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, o2_varid, "Dissolved Oxygen", "mol O/m3", "moles Oxygen per cubic meters") + ! 4. BLING tracer: phytoplankton PHY - call check(nf90_def_var(ncid=ncid, name="PHY", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=phy_varid)) - call check(nf90_put_att(ncid, phy_varid, "long_name" , "Phytoplankton Biomass")) - call check(nf90_put_att(ncid, phy_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, phy_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, phy_varid, "units" , "mol C/m3")) - call check(nf90_put_att(ncid, phy_varid, "units_long_name", "moles Carbon per cubic meters")) + phy_varid = define_variable(ncid,"PHY", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, phy_varid, "Phytoplankton Biomass", "mol C/m3", "moles Carbon per cubic meters") ! 5. BLING tracer: alkalinity ALK - call check(nf90_def_var(ncid=ncid, name="ALK", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=alk_varid)) - call check(nf90_put_att(ncid, alk_varid, "long_name" , "Alkalinity")) - call check(nf90_put_att(ncid, alk_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, alk_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, alk_varid, "units" , "mol eq/m3")) - call check(nf90_put_att(ncid, alk_varid, "units_long_name", "moles equivalent per cubic meters")) - + alk_varid = define_variable(ncid,"ALK", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, alk_varid, "Alkalinity", "mol eq/m3", "moles equivalent per cubic meters") + ! 6. BLING tracer: dissolved inorganic carbon DIC - call check(nf90_def_var(ncid=ncid, name="DIC", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=dic_varid)) - call check(nf90_put_att(ncid, dic_varid, "long_name" , "Dissolved Inorganic Carbon")) - call check(nf90_put_att(ncid, dic_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, dic_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, dic_varid, "units" , "mol C/m3")) - call check(nf90_put_att(ncid, dic_varid, "units_long_name", "moles Carbon per cubic meters")) - - ! 7. BLING tracer: dissolved organic phosphorus DOP - call check(nf90_def_var(ncid=ncid, name="DOP", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=dop_varid)) - call check(nf90_put_att(ncid, dop_varid, "long_name" , "Dissolved Organic Phosphorus")) - call check(nf90_put_att(ncid, dop_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, dop_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, dop_varid, "units" , "mol P/m3")) - call check(nf90_put_att(ncid, dop_varid, "units_long_name", "moles Phosphorus per cubic meters")) + dic_varid = define_variable(ncid,"DIC", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, dic_varid, "Dissolved Inorganic Carbon", "mol C/m3", "moles Carbon per cubic meters") + + ! 7. BLING tracer: dissolved organic phosphorus DOP + dop_varid = define_variable(ncid,"DOP", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, dop_varid, "Dissolved Organic Phosphorus", "mol P/m3", "moles Phosphorus per cubic meters") ! 8. BLING tracer: dissolved organic nitrogen DON - call check(nf90_def_var(ncid=ncid, name="DON", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=don_varid)) - call check(nf90_put_att(ncid, don_varid, "long_name" , "Dissolved Organic Nitrogen")) - call check(nf90_put_att(ncid, don_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, don_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, don_varid, "units" , "mol N/m3")) - call check(nf90_put_att(ncid, don_varid, "units_long_name", "moles Nitrogen per cubic meters")) + don_varid = define_variable(ncid,"DON", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, don_varid, "Dissolved Organic Nitrogen", "mol N/m3", "moles Nitrogen per cubic meters") ! 9. BLING tracer: dissolved inorganic iron FET - call check(nf90_def_var(ncid=ncid, name="FET", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID,ZCDimID/),varid=fet_varid)) - call check(nf90_put_att(ncid, fet_varid, "long_name" , "Dissolved Inorganic Iron")) - call check(nf90_put_att(ncid, fet_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, fet_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, fet_varid, "units" , "mol Fe/m3")) - call check(nf90_put_att(ncid, fet_varid, "units_long_name", "moles Iron per cubic meters")) - + fet_varid = define_variable(ncid,"FET", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, fet_varid, "Dissolved Inorganic Iron", "mol Fe/m3", "moles Iron per cubic meters") + ! 10. BLING tracer: Surface Chlorophyl CHL - call check(nf90_def_var(ncid=ncid, name="CHL", xtype=nf90_real, & - dimids=(/XCDimID,YCDimID/),varid=chl_varid)) - call check(nf90_put_att(ncid, chl_varid, "long_name" , "Surface Chlorophyll")) - call check(nf90_put_att(ncid, chl_varid, "missing_value" , FVAL)) - call check(nf90_put_att(ncid, chl_varid, "_FillValue" , FVAL)) - call check(nf90_put_att(ncid, chl_varid, "units" , "mg/m3")) - call check(nf90_put_att(ncid, chl_varid, "units_long_name", "milligram per cubic meters")) -endif + chl_varid = define_variable_2d(ncid,"CHL", nf90_real, all_dimids) + call add_attributes_to_variable(ncid, chl_varid, "Surface Chlorophyll", "mg/m3", "milligram per cubic meters" ) +endif ! Finished with dimension/variable definitions, must end 'define' mode to fill. @@ -439,125 +408,49 @@ subroutine mit2dart() call check(nf90_put_var(ncid, YCVarID, YC )) call check(nf90_put_var(ncid, ZCVarID, ZC )) -! Fill the data - -iunit = get_unit() -open(iunit, file='PSAL.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') -read(iunit,rec=1)data_3d -close(iunit) -where (data_3d == 0.0_r4) data_3d = FVAL -call check(nf90_put_var(ncid,SVarID,data_3d,start=(/1,1,1/))) - -open(iunit, file='PTMP.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') -read(iunit,rec=1)data_3d -close(iunit) -where (data_3d == 0.0_r4) data_3d = FVAL -call check(nf90_put_var(ncid,TVarID,data_3d,start=(/1,1,1/))) - -open(iunit, file='UVEL.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') -read(iunit,rec=1)data_3d -close(iunit) -where (data_3d == 0.0_r4) data_3d = FVAL -call check(nf90_put_var(ncid,UVarID,data_3d,start=(/1,1,1/))) - -open(iunit, file='VVEL.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') -read(iunit,rec=1)data_3d -close(iunit) -where (data_3d == 0.0_r4) data_3d = FVAL -call check(nf90_put_var(ncid,VVarID,data_3d,start=(/1,1,1/))) - -open(iunit, file='ETA.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl2d, convert='BIG_ENDIAN') -read(iunit,rec=1)data_2d -close(iunit) -where (data_2d == 0.0_r4) data_2d = FVAL -call check(nf90_put_var(ncid,EtaVarID,data_2d,start=(/1,1/))) +if (compress) then + allocate(XCcomp(ncomp3)) + allocate(XGcomp(ncomp3)) + allocate(YCcomp(ncomp3)) + allocate(YGcomp(ncomp3)) + allocate(ZCcomp(ncomp3)) + allocate(ZGcomp(ncomp3)) + allocate(Xcomp_ind(ncomp3)) + allocate(Ycomp_ind(ncomp3)) + allocate(Zcomp_ind(ncomp3)) + call fill_compressed_coords() + call check(nf90_put_var(ncid, XGcompVarID, XGcomp )) + call check(nf90_put_var(ncid, XCcompVarID, XCcomp )) + call check(nf90_put_var(ncid, YGcompVarID, YGcomp )) + call check(nf90_put_var(ncid, YCcompVarID, YCcomp )) + call check(nf90_put_var(ncid, ZCcompVarID, ZCcomp )) + call check(nf90_put_var(ncid, XindID, Xcomp_ind )) + call check(nf90_put_var(ncid, YindID, Ycomp_ind )) + call check(nf90_put_var(ncid, ZindID, Zcomp_ind )) +endif -if (do_bgc) then - open(iunit, file='NO3.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_3d - close(iunit) - call fill_var_md(data_3d, FVAL) - call check(nf90_put_var(ncid,no3_varid,data_3d,start=(/1,1,1/))) - - open(iunit, file='PO4.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_3d - close(iunit) - call fill_var_md(data_3d, FVAL) - call check(nf90_put_var(ncid,po4_varid,data_3d,start=(/1,1,1/))) - - open(iunit, file='O2.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_3d - close(iunit) - call fill_var_md(data_3d, FVAL) - call check(nf90_put_var(ncid,o2_varid,data_3d,start=(/1,1,1/))) - - open(iunit, file='PHY.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_3d - close(iunit) - call fill_var_md(data_3d, FVAL) - call check(nf90_put_var(ncid,phy_varid,data_3d,start=(/1,1,1/))) - - open(iunit, file='ALK.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_3d - close(iunit) - call fill_var_md(data_3d, FVAL) - call check(nf90_put_var(ncid,alk_varid,data_3d,start=(/1,1,1/))) - - open(iunit, file='DIC.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_3d - close(iunit) - call fill_var_md(data_3d, FVAL) - call check(nf90_put_var(ncid,dic_varid,data_3d,start=(/1,1,1/))) - - open(iunit, file='DOP.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_3d - close(iunit) - call fill_var_md(data_3d, FVAL) - call check(nf90_put_var(ncid,dop_varid,data_3d,start=(/1,1,1/))) - - open(iunit, file='DON.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_3d - close(iunit) - call fill_var_md(data_3d, FVAL) - call check(nf90_put_var(ncid,don_varid,data_3d,start=(/1,1,1/))) - - open(iunit, file='FET.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_3d - close(iunit) - call fill_var_md(data_3d, FVAL) - call check(nf90_put_var(ncid,fet_varid,data_3d,start=(/1,1,1/))) - - open(iunit, file='CHL.data', form='UNFORMATTED', status='OLD', & - access='DIRECT', recl=recl2d, convert='BIG_ENDIAN') - read(iunit,rec=1)data_2d - close(iunit) - where (data_2d == 0.0_r4) - data_2d = FVAL - elsewhere - data_2d = log10(data_2d) - endwhere - call check(nf90_put_var(ncid,chl_varid,data_2d,start=(/1,1/))) +! Fill the netcdf variables +call from_mit_to_netcdf_3d('PSAL.data', ncid, SVarID) +call from_mit_to_netcdf_3d('PTMP.data', ncid, TVarID) +call from_mit_to_netcdf_3d('UVEL.data', ncid, UVarID) +call from_mit_to_netcdf_3d('VVEL.data', ncid, VVarID) +call from_mit_to_netcdf_2d('ETA.data', ncid, EtaVarID) + +if (do_bgc) then + call from_mit_to_netcdf_tracer_3d('NO3.data', ncid, no3_varid) + call from_mit_to_netcdf_tracer_3d('PO4.data', ncid, po4_varid) + call from_mit_to_netcdf_tracer_3d('O2.data', ncid, o2_varid) + call from_mit_to_netcdf_tracer_3d('PHY.data', ncid, phy_varid) + call from_mit_to_netcdf_tracer_3d('ALK.data', ncid, alk_varid) + call from_mit_to_netcdf_tracer_3d('DIC.data', ncid, dic_varid) + call from_mit_to_netcdf_tracer_3d('DOP.data', ncid, dop_varid) + call from_mit_to_netcdf_tracer_3d('DON.data', ncid, don_varid) + call from_mit_to_netcdf_tracer_3d('FET.data', ncid, fet_varid) + call from_mit_to_netcdf_tracer_2d('CHL.data', ncid, chl_varid) endif call check(nf90_close(ncid)) -deallocate(data_3d) -deallocate(data_2d) - end subroutine mit2dart !------------------------------------------------------------------ @@ -565,238 +458,640 @@ end subroutine mit2dart subroutine dart2mit() -integer :: ncid, varid, iunit -real(r4), allocatable :: data_3d(:,:,:),data_2d(:,:) -real(r4) :: FVAL - -allocate(data_3d(Nx,Ny,Nz)) -allocate(data_2d(Nx,Ny)) +integer :: ncid if (.not. module_initialized) call static_init_trans -iunit = get_unit() call check(nf90_open("INPUT.nc",NF90_NOWRITE,ncid)) +if (compress) then + ncomp3 = nc_get_dimension_size(ncid,'comp3d') + ncomp2 = nc_get_dimension_size(ncid,'comp2d') + allocate(Xcomp_ind(ncomp3)) + allocate(Ycomp_ind(ncomp3)) + allocate(Zcomp_ind(ncomp3)) + call nc_get_variable(ncid, 'Xcomp_ind', Xcomp_ind) + call nc_get_variable(ncid, 'Ycomp_ind', Ycomp_ind) + call nc_get_variable(ncid, 'Zcomp_ind', Zcomp_ind) +endif + !Fill the data -call check( NF90_INQ_VARID(ncid,'PSAL',varid) ) -call check( NF90_GET_VAR(ncid,varid,data_3d)) -call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) -where (data_3d == FVAL) data_3d = 0.0_r4 +call from_netcdf_to_mit_3d(ncid, 'PSAL') +call from_netcdf_to_mit_3d(ncid, 'PTMP') +call from_netcdf_to_mit_3d(ncid, 'UVEL') +call from_netcdf_to_mit_3d(ncid, 'VVEL') +call from_netcdf_to_mit_2d(ncid, 'ETA') + + +if (do_bgc) then + call from_netcdf_to_mit_tracer(ncid, 'NO3') + call from_netcdf_to_mit_tracer(ncid, 'PO4') + call from_netcdf_to_mit_tracer(ncid, 'O2') + call from_netcdf_to_mit_tracer(ncid, 'PHY') + call from_netcdf_to_mit_tracer(ncid, 'ALK') + call from_netcdf_to_mit_tracer(ncid, 'DIC') + call from_netcdf_to_mit_tracer(ncid, 'DOP') + call from_netcdf_to_mit_tracer(ncid, 'DON') + call from_netcdf_to_mit_tracer(ncid, 'FET') + if (output_chl_data) call from_netcdf_to_mit_tracer_chl(ncid, 'CHL') +endif -open(iunit, file='PSAL.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') -write(iunit,rec=1)data_3d -close(iunit) +call check( NF90_CLOSE(ncid) ) -call check( NF90_INQ_VARID(ncid,'PTMP',varid) ) -call check( NF90_GET_VAR(ncid,varid,data_3d)) -call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) -where (data_3d == FVAL) data_3d = 0.0_r4 +if (compress) deallocate(Xcomp_ind, Ycomp_ind, Zcomp_ind) -open(iunit, file='PTMP.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') -write(iunit,rec=1)data_3d -close(iunit) +end subroutine dart2mit -call check( NF90_INQ_VARID(ncid,'UVEL',varid) ) -call check( NF90_GET_VAR(ncid,varid,data_3d)) -call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) -where (data_3d == FVAL) data_3d = 0.0_r4 +!=============================================================================== +!> Subroutine that checks error status on NC file +!> Check the error status of the netcdf command -open(iunit, file='UVEL.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') -write(iunit,rec=1)data_3d -close(iunit) +subroutine check(status) + +integer, intent (in) :: status + +if(status /= nf90_noerr) then + print *, trim(nf90_strerror(status)) + stop "Stopped" +end if + +end subroutine check + +!=============================================================================== +! 3D variable +function define_variable(ncid, name, nc_type, all_dimids) result(varid) + +integer, intent(in) :: ncid +character(len=*), intent(in) :: name ! variable name +integer, intent(in) :: nc_type +integer, intent(in) :: all_dimids(7) ! possible dimension ids +integer :: varid ! netcdf variable id + +integer :: dimids(3) + +if (compress) then + call check(nf90_def_var(ncid=ncid, name=name, xtype=nc_type, & + dimids=all_dimids(7),varid=varid)) +else + dimids = which_dims(name, all_dimids) + call check(nf90_def_var(ncid=ncid, name=name, xtype=nc_type, & + dimids=dimids, varid=varid)) +endif + +end function define_variable + +!------------------------------------------------------------------ +! For the non-compressed variables, X,Y,Z dimesnions vary +! depending on the variable +function which_dims(name, all_dimids) result(dimids) + +character(len=*), intent(in) :: name ! variable name +integer, intent(in) :: all_dimids(7) +integer :: dimids(3) +! 3D variables, 3 grids: +! XC, YC, ZC 1 PSAL, PTMP, NO3, PO4, O2, PHY, ALK, DIC, DOP, DON, FET +! XG, YC, ZC 2 UVEL +! XC, YG, ZC 3 VVEL + +if (name=='UVEL') then + dimids = (/all_dimids(4),all_dimids(2),all_dimids(3)/) + return +endif +if (name=='VVEL') then + dimids = (/all_dimids(1),all_dimids(5),all_dimids(3)/) + return +endif + +dimids = (/all_dimids(1),all_dimids(2),all_dimids(3)/) + +end function + +!------------------------------------------------------------------ +! 2D variable +function define_variable_2d(ncid, name, nc_type, all_dimids) result(varid) + +integer, intent(in) :: ncid +character(len=*), intent(in) :: name ! variable name +integer, intent(in) :: nc_type +integer, intent(in) :: all_dimids(7) +integer :: varid ! netcdf variable id + +! 2D variables, 1 grid: +! YC, XC 1 ETA, CHL -call check( NF90_INQ_VARID(ncid,'VVEL',varid) ) -call check( NF90_GET_VAR(ncid,varid,data_3d)) -call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) -where (data_3d == FVAL) data_3d = 0.0_r4 +if (compress) then + call check(nf90_def_var(ncid=ncid, name=name, xtype=nc_type, & + dimids = (/all_dimids(6)/),varid=varid)) +else + call check(nf90_def_var(ncid=ncid, name=name, xtype=nc_type, & + dimids = (/all_dimids(1),all_dimids(2)/),varid=varid)) +endif + +end function define_variable_2d + +!------------------------------------------------------------------ +subroutine add_attributes_to_variable(ncid, varid, long_name, units, units_long_name) -open(iunit, file='VVEL.data', form="UNFORMATTED", status='UNKNOWN', & +integer, intent(in) :: ncid, varid ! which file, which variable +character(len=*), intent(in) :: long_name, units, units_long_name + +call check(nf90_put_att(ncid, varid, "long_name" , long_name)) +call check(nf90_put_att(ncid, varid, "missing_value" , FVAL)) +call check(nf90_put_att(ncid, varid, "_FillValue" , FVAL)) +call check(nf90_put_att(ncid, varid, "units" , units)) +call check(nf90_put_att(ncid, varid, "units_long_name", units_long_name)) + +end subroutine + +!------------------------------------------------------------------ +subroutine from_mit_to_netcdf_3d(mitfile, ncid, varid) + +character(len=*), intent(in) :: mitfile +integer, intent(in) :: ncid, varid ! which file, which variable + +integer :: iunit +real(r4) :: var_data(Nx,Ny,Nz) + +iunit = get_unit() +! HK are the mit files big endian by default? +open(iunit, file=mitfile, form='UNFORMATTED', status='OLD', & access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') -write(iunit,rec=1)data_3d +read(iunit,rec=1) var_data close(iunit) -call check( NF90_INQ_VARID(ncid,'ETA',varid) ) -call check( NF90_GET_VAR(ncid,varid,data_2d)) -call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) -where (data_2d == FVAL) data_2d = 0.0_r4 +where (var_data == binary_fill) var_data = FVAL !HK do we also need a check for nans here? -open(iunit, file='ETA.data', form="UNFORMATTED", status='UNKNOWN', & +if (compress) then + call write_compressed(ncid, varid, var_data) +else + call check(nf90_put_var(ncid,varid,var_data)) +endif + +end subroutine from_mit_to_netcdf_3d + +!------------------------------------------------------------------ +subroutine from_mit_to_netcdf_2d(mitfile, ncid, varid) + +character(len=*), intent(in) :: mitfile +integer, intent(in) :: ncid, varid ! which file, which variable + +integer :: iunit +real(r4) :: var_data(Nx,Ny) + +iunit = get_unit() +! HK are the mit files big endian by default? +open(iunit, file=mitfile, form='UNFORMATTED', status='OLD', & access='DIRECT', recl=recl2d, convert='BIG_ENDIAN') -write(iunit,rec=1)data_2d +read(iunit,rec=1) var_data close(iunit) -if (do_bgc) then - call check( NF90_INQ_VARID(ncid,'NO3',varid) ) - call check( NF90_GET_VAR(ncid,varid,data_3d)) - call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) - call fill_var_dm(data_3d, FVAL) - - open(iunit, file='NO3.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - write(iunit,rec=1)data_3d - close(iunit) - - call check( NF90_INQ_VARID(ncid,'PO4',varid) ) - call check( NF90_GET_VAR(ncid,varid,data_3d)) - call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) - call fill_var_dm(data_3d, FVAL) - - open(iunit, file='PO4.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - write(iunit,rec=1)data_3d - close(iunit) - - call check( NF90_INQ_VARID(ncid,'O2',varid) ) - call check( NF90_GET_VAR(ncid,varid,data_3d)) - call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) - call fill_var_dm(data_3d, FVAL) - - open(iunit, file='O2.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - write(iunit,rec=1)data_3d - close(iunit) - - call check( NF90_INQ_VARID(ncid,'PHY',varid) ) - call check( NF90_GET_VAR(ncid,varid,data_3d)) - call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) - call fill_var_dm(data_3d, FVAL) - - open(iunit, file='PHY.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - write(iunit,rec=1)data_3d - close(iunit) - - call check( NF90_INQ_VARID(ncid,'ALK',varid) ) - call check( NF90_GET_VAR(ncid,varid,data_3d)) - call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) - call fill_var_dm(data_3d, FVAL) - - open(iunit, file='ALK.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - write(iunit,rec=1)data_3d - close(iunit) - - call check( NF90_INQ_VARID(ncid,'DIC',varid) ) - call check( NF90_GET_VAR(ncid,varid,data_3d)) - call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) - call fill_var_dm(data_3d, FVAL) - - open(iunit, file='DIC.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - write(iunit,rec=1)data_3d - close(iunit) - - call check( NF90_INQ_VARID(ncid,'DOP',varid) ) - call check( NF90_GET_VAR(ncid,varid,data_3d)) - call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) - call fill_var_dm(data_3d, FVAL) - - open(iunit, file='DOP.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - write(iunit,rec=1)data_3d - close(iunit) - - call check( NF90_INQ_VARID(ncid,'DON',varid) ) - call check( NF90_GET_VAR(ncid,varid,data_3d)) - call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) - call fill_var_dm(data_3d, FVAL) - - open(iunit, file='DON.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - write(iunit,rec=1)data_3d - close(iunit) - - call check( NF90_INQ_VARID(ncid,'FET',varid) ) - call check( NF90_GET_VAR(ncid,varid,data_3d)) - call check( nf90_get_att(ncid,varid,"_FillValue",FVAL)) - call fill_var_dm(data_3d, FVAL) - - open(iunit, file='FET.data', form="UNFORMATTED", status='UNKNOWN', & - access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') - write(iunit,rec=1)data_3d - close(iunit) +where (var_data == binary_fill) var_data = FVAL !HK do we also need a check for nans here? + +if (compress) then + call write_compressed(ncid, varid, var_data) +else + call check(nf90_put_var(ncid,varid,var_data)) endif -call check( NF90_CLOSE(ncid) ) +end subroutine from_mit_to_netcdf_2d -deallocate(data_3d) -deallocate(data_2d) -end subroutine dart2mit +!------------------------------------------------------------------ +subroutine from_mit_to_netcdf_tracer_3d(mitfile, ncid, varid) -!=============================================================================== -!> Subroutine that checks error status on NC file -!> Check the error status of the netcdf command +character(len=*), intent(in) :: mitfile +integer, intent(in) :: ncid, varid ! which file, which variable -subroutine check(status) +integer :: iunit +real(r4) :: var_data(Nx,Ny,Nz) +real(r4) :: low_conc -integer, intent (in) :: status +low_conc = 1.0e-12 -if(status /= nf90_noerr) then - print *, trim(nf90_strerror(status)) - stop "Stopped" -end if +iunit = get_unit() +! HK are the mit files big endian by default? +open(iunit, file=mitfile, form='UNFORMATTED', status='OLD', & + access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') +read(iunit,rec=1) var_data +close(iunit) -end subroutine check +! CHL is treated differently - HK CHL is 2d so you will not enter this +if (mitfile=='CHL.data') then + where (var_data == binary_fill) + var_data = FVAL + elsewhere + var_data = log10(var_data) + endwhere +else + ! Make sure the tracer concentration is positive + where(var_data < binary_fill) var_data = low_conc + + if (log_transform) then + where (var_data == binary_fill) + var_data = FVAL + elsewhere + var_data = log(var_data) + endwhere + else + where (var_data == binary_fill) var_data = FVAL + endif +endif +if (compress) then + call write_compressed(ncid, varid, var_data) +else + call check(nf90_put_var(ncid,varid,var_data)) +endif -!=============================================================================== -!> Check the tracer variables after reading from the binaries -!> Make sure they are non-negative -!> Do the transform if requested -!> md: mit2dart; dm: dart2mit +end subroutine from_mit_to_netcdf_tracer_3d -subroutine fill_var_md(var, fillval) +!------------------------------------------------------------------ +subroutine from_mit_to_netcdf_tracer_2d(mitfile, ncid, varid) -real(r4), intent(inout) :: var(:, :, :) -real(r4), intent(in) :: fillval +character(len=*), intent(in) :: mitfile +integer, intent(in) :: ncid, varid ! which file, which variable +integer :: iunit +real(r4) :: var_data(Nx,Ny) real(r4) :: low_conc -if (.not. module_initialized) call static_init_trans - low_conc = 1.0e-12 -! Make sure the tracer concentration is positive -where(var < 0.0_r4) var = low_conc +iunit = get_unit() +! HK are the mit files big endian by default? +open(iunit, file=mitfile, form='UNFORMATTED', status='OLD', & + access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') +read(iunit,rec=1) var_data +close(iunit) -if (log_transform) then - where (var == 0.0_r4) - var = fillval +! CHL is treated differently +if (mitfile=='CHL.data') then + where (var_data == binary_fill) + var_data = FVAL elsewhere - var = log(var) + var_data = log10(var_data) endwhere else - where (var == 0.0_r4) var = fillval + ! Make sure the tracer concentration is positive + where(var_data < binary_fill) var_data = low_conc + + if (log_transform) then + where (var_data == binary_fill) + var_data = FVAL + elsewhere + var_data = log(var_data) + endwhere + else + where (var_data == binary_fill) var_data = FVAL + endif endif -end subroutine +if (compress) then + call write_compressed(ncid, varid, var_data) +else + call check(nf90_put_var(ncid,varid,var_data)) +endif + +end subroutine from_mit_to_netcdf_tracer_2d !------------------------------------------------------------------ +subroutine from_netcdf_to_mit_2d(ncid, name) -subroutine fill_var_dm(var, fillval) +integer, intent(in) :: ncid ! which file, +character(len=*), intent(in) :: name ! which variable -real(r4), intent(inout) :: var(:, :, :) -real(r4), intent(in) :: fillval +integer :: iunit +real(r4) :: var(Nx,Ny) +integer :: varid +real(r4) :: local_fval -if (.not. module_initialized) call static_init_trans +call check( NF90_INQ_VARID(ncid,name,varid) ) +call check( nf90_get_att(ncid,varid,"_FillValue",local_fval)) +! initialize var to netcdf fill value +var(:,:) = local_fval + +if (compress) then + call read_compressed(ncid, varid, var) +else + call check(nf90_get_var(ncid,varid,var)) +endif + +where (var == local_fval) var = binary_fill + +iunit = get_unit() +open(iunit, file=trim(name)//'.data', form="UNFORMATTED", status='UNKNOWN', & + access='DIRECT', recl=recl2d, convert='BIG_ENDIAN') +write(iunit,rec=1)var +close(iunit) + +end subroutine from_netcdf_to_mit_2d + +!------------------------------------------------------------------ +subroutine from_netcdf_to_mit_3d(ncid, name) + +integer, intent(in) :: ncid ! which file, +character(len=*), intent(in) :: name ! which variable + +integer :: iunit +real(r4) :: var(Nx,Ny,Nz) +integer :: varid +real(r4) :: local_fval + +call check( NF90_INQ_VARID(ncid,name,varid) ) +call check( nf90_get_att(ncid,varid,"_FillValue",local_fval)) +! initialize var to netcdf fill value +var(:,:,:) = local_fval + +if (compress) then + call read_compressed(ncid, varid, var) +else + call check(nf90_get_var(ncid,varid,var)) +endif + +where (var == local_fval) var = binary_fill + +iunit = get_unit() +open(iunit, file=trim(name)//'.data', form="UNFORMATTED", status='UNKNOWN', & + access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') +write(iunit,rec=1)var +close(iunit) + +end subroutine from_netcdf_to_mit_3d + + +!------------------------------------------------------------------ +subroutine from_netcdf_to_mit_tracer(ncid, name) + +integer, intent(in) :: ncid ! which file +character(len=*), intent(in) :: name ! which variable + +integer :: iunit +real(r4) :: var(Nx,Ny,Nz) +integer :: varid +real(r4) :: local_fval + +call check( NF90_INQ_VARID(ncid,name,varid) ) +call check( nf90_get_att(ncid,varid,"_FillValue",local_fval)) +! initialize var to netcdf fill value +var(:,:,:) = local_fval + +if (compress) then + call read_compressed(ncid, varid, var) +else + call check(nf90_get_var(ncid,varid,var)) +endif if (log_transform) then - where (var == fillval) - var = 0.0_r4 + where (var == local_fval) + var = binary_fill elsewhere var = exp(var) endwhere else - where (var == fillval) var = 0.0_r4 + where (var == local_fval) var = binary_fill endif -end subroutine +iunit = get_unit() +open(iunit, file=trim(name)//'.data', form="UNFORMATTED", status='UNKNOWN', & + access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') +write(iunit,rec=1)var +close(iunit) + +end subroutine from_netcdf_to_mit_tracer + +!------------------------------------------------------------------ +subroutine from_netcdf_to_mit_tracer_chl(ncid, name) + +integer, intent(in) :: ncid ! which file +character(len=*), intent(in) :: name ! which variable + +integer :: iunit +real(r4) :: var(Nx,Ny) +integer :: varid +real(r4) :: local_fval + +call check( NF90_INQ_VARID(ncid,name,varid) ) +call check( nf90_get_att(ncid,varid,"_FillValue",local_fval)) +! initialize var to netcdf fill value +var(:,:) = local_fval + +if (compress) then + call read_compressed(ncid, varid, var) +else + call check(nf90_get_var(ncid,varid,var)) +endif + +where (var == local_fval) + var = binary_fill +elsewhere + var = 10**(var) +endwhere + + +iunit = get_unit() +open(iunit, file=trim(name)//'.data', form="UNFORMATTED", status='UNKNOWN', & + access='DIRECT', recl=recl2d, convert='BIG_ENDIAN') +write(iunit,rec=1)var +close(iunit) + +end subroutine from_netcdf_to_mit_tracer_chl + + +!------------------------------------------------------------------ +! Assumes all 3D variables are masked in the +! same location +function get_compressed_size_3d() result(n3) + +integer :: n3 +integer :: iunit +real(r4) :: var3d(NX,NY,NZ) +integer :: i,j,k + +iunit = get_unit() +open(iunit, file='PSAL.data', form='UNFORMATTED', status='OLD', & + access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') +read(iunit,rec=1) var3d +close(iunit) + +n3 = 0 + +! Get compressed size +do i=1,NX + do j=1,NY + do k=1,NZ + if (var3d(i,j,k) /= binary_fill) then !HK also NaN? + n3 = n3 + 1 + endif + enddo + enddo +enddo + +end function get_compressed_size_3d + +!------------------------------------------------------------------ +! Assumes all 2D variables are masked in the +! same location +function get_compressed_size_2d() result(n2) + +integer :: n2 +integer :: iunit +real(r4) :: var2d(NX,NY) +integer :: i,j + +iunit = get_unit() +open(iunit, file='ETA.data', form='UNFORMATTED', status='OLD', & + access='DIRECT', recl=recl2d, convert='BIG_ENDIAN') +read(iunit,rec=1) var2d +close(iunit) + +n2 = 0 + +! Get compressed size +do i=1,NX + do j=1,NY + if (var2d(i,j) /= binary_fill) then !HK also NaN? + n2 = n2 + 1 + endif + enddo +enddo + +end function get_compressed_size_2d !------------------------------------------------------------------ +subroutine fill_compressed_coords() + +!XG,etc read from PARAM04 in static_init_trans +real(r4) :: var3d(NX,NY,NZ) +integer :: n, i, j, k + +iunit = get_unit() +open(iunit, file='PSAL.data', form='UNFORMATTED', status='OLD', & + access='DIRECT', recl=recl3d, convert='BIG_ENDIAN') +read(iunit,rec=1) var3d +close(iunit) + +n = 1 + +do k=1,NZ ! k first so 2d is first + do i=1,NX + do j=1,NY + if (var3d(i,j,k) /= binary_fill) then !HK also NaN? + XCcomp(n) = XC(i) + YCcomp(n) = YC(j) + ZCcomp(n) = ZC(k) + XGcomp(n) = XG(i) + YGcomp(n) = YG(j) + ZGcomp(n) = ZG(k) + + Xcomp_ind(n) = i ! Assuming grids are compressed the same + Ycomp_ind(n) = j + Zcomp_ind(n) = k + + n = n + 1 + endif + enddo + enddo +enddo + +end subroutine fill_compressed_coords + +!------------------------------------------------------------------ +subroutine write_compressed_2d(ncid, varid, var_data) + +integer, intent(in) :: ncid, varid +real(r4), intent(in) :: var_data(Nx,Ny) + +real(r4) :: comp_var(ncomp2) +integer :: n +integer :: i,j ! loop variables + +n = 1 +do i = 1, NX + do j = 1, NY + if (var_data(i,j) /= FVAL) then + comp_var(n) = var_data(i,j) + n = n + 1 + endif + enddo +enddo + +call check(nf90_put_var(ncid,varid,comp_var)) + +end subroutine write_compressed_2d + +!------------------------------------------------------------------ +subroutine write_compressed_3d(ncid, varid, var_data) + +integer, intent(in) :: ncid, varid +real(r4), intent(in) :: var_data(Nx,Ny,Nz) + +real(r4) :: comp_var(ncomp3) +integer :: n +integer :: i,j,k ! loop variables + +n = 1 +do k = 1 , NZ !k first so 2d is first + do i = 1, NX + do j = 1, NY + if (var_data(i,j,k) /= FVAL) then + comp_var(n) = var_data(i,j,k) + n = n + 1 + endif + enddo + enddo +enddo + +call check(nf90_put_var(ncid,varid,comp_var)) + +end subroutine write_compressed_3d + +!------------------------------------------------------------------ +subroutine read_compressed_2d(ncid, varid, var) + +integer, intent(in) :: ncid, varid +real(r4), intent(inout) :: var(NX,NY) + +real(r4) :: comp_var(ncomp2) +integer :: n ! loop variable +integer :: i,j,k ! x,y,z +integer :: c + +c = 1 + +call check(nf90_get_var(ncid,varid,comp_var)) + +do n = 1, ncomp3 + i = Xcomp_ind(n) + j = Ycomp_ind(n) + k = Zcomp_ind(n) + if (k == 1 ) then + var(i,j) = comp_var(c) + c = c + 1 + endif +enddo + +end subroutine read_compressed_2d + +!------------------------------------------------------------------ +subroutine read_compressed_3d(ncid, varid, var) + +integer, intent(in) :: ncid, varid +real(r4), intent(inout) :: var(NX,NY,NZ) + +real(r4) :: comp_var(ncomp3) +integer :: n ! loop variable +integer :: i,j,k ! x,y,k + +call check(nf90_get_var(ncid,varid,comp_var)) + +do n = 1, ncomp3 + i = Xcomp_ind(n) + j = Ycomp_ind(n) + k = Zcomp_ind(n) + var(i,j,k) = comp_var(n) +enddo + +end subroutine read_compressed_3d end module trans_mitdart_mod diff --git a/models/MITgcm_ocean/work/input.nml b/models/MITgcm_ocean/work/input.nml index 9bc7844826..6d16a79f88 100644 --- a/models/MITgcm_ocean/work/input.nml +++ b/models/MITgcm_ocean/work/input.nml @@ -451,7 +451,7 @@ # quantity_of_interest = 'QTY_DENSITY' &model_mod_check_nml - input_state_files = 'OUTPUT.nc' + input_state_files = 'mem01_reduced.nc' output_state_files = 'check_me' verbose = .TRUE. test1thru = 0 diff --git a/models/MITgcm_ocean/work/quickbuild.sh b/models/MITgcm_ocean/work/quickbuild.sh index 80731cfd82..1254788940 100755 --- a/models/MITgcm_ocean/work/quickbuild.sh +++ b/models/MITgcm_ocean/work/quickbuild.sh @@ -34,6 +34,7 @@ model_serial_programs=( dart_to_mit mit_to_dart create_ocean_obs +expand_netcdf ) arguments "$@"