diff --git a/env_compile_intel_linux.bash b/env_compile_intel_linux.bash index 64d9a376..05d665be 100755 --- a/env_compile_intel_linux.bash +++ b/env_compile_intel_linux.bash @@ -23,7 +23,7 @@ export NEXTSIMDIR=`pwd` # AeroBulk turbulent air-sea flux computation #-------------------------------------------- -l_aerobulk=true ; # Call AeroBulk to compute air-sea fluxes ? If true, give the appropriate value for "AEROBULK_DIR" in the arch CASE block... +l_aerobulk=false ; # Call AeroBulk to compute air-sea fluxes ? If true, give the appropriate value for "AEROBULK_DIR" in the arch CASE block... if ${l_aerobulk}; then export USE_AEROBULK=true # => then, later before launching neXtSIM, pick an algorithm by setting `ocean_bulk_formula=` of the `thermo` block in the config file @@ -74,7 +74,7 @@ NXTSM_DEP_DIR="/opt/nextsim_intel" ; # path to directory containing compiled BOO ###################################################################### # Host-specific adjustment of previously defined variables if needed # ###################################################################### -case `hostname | cut -d. -f2` in +case `hostname -f | cut -d. -f2` in "merlat" ) export LDFLAGS="-L${INTEL_COMP_DIR}/compiler/lib/intel64_lin -limf" ;; "ige-mcpc-36" ) NXTSM_DEP_DIR="/opt/nextsim_intel" @@ -105,16 +105,16 @@ case `hostname | cut -d. -f2` in # export LDFLAGS="-L${INTEL_COMP_DIR}/compiler/lib/intel64_lin -lifcore -lifport" ;; - "fram" ) NXTSM_DEP_DIR="/cluster/projects/nn9878k/brodeau/opt/nextsim_intel" - INTEL_VERSION="2018.1.163" - INTEL_ROOT="/cluster/software/ifort/${INTEL_VERSION}-GCC-6.4.0-2.28" - export INTEL_COMP_DIR="${INTEL_ROOT}/compilers_and_libraries_${INTEL_VERSION}/linux" - export MPI_DIR="/cluster/software/impi/${INTEL_VERSION}-iccifort-${INTEL_VERSION}-GCC-6.4.0-2.28/intel64" - export NETCDF_DIR="/cluster/software/netCDF/4.4.1.1-intel-2018a-HDF5-1.8.19" - export NETCDF_CXX_DIR="/cluster/software/netCDF-C++4/4.3.0-intel-2018a-HDF5-1.8.19" + "fram" ) NXTSM_DEP_DIR="/cluster/projects/nn9878k/guibou/nextsim_intel/opt/" + INTEL_VERSION="2022.1.0" + INTEL_ROOT="/cluster/software/intel-compilers/${INTEL_VERSION}" + export INTEL_COMP_DIR="/cluster/software/intel-compilers/${INTEL_VERSION}/compiler/latest/linux/" + export MPI_DIR="/cluster/software/impi/2021.6.0-intel-compilers-${INTEL_VERSION}/mpi/latest/" + export NETCDF_DIR="/cluster/software/netCDF/4.9.0-iimpi-2022a/" + export NETCDF_CXX_DIR="/cluster/software/netCDF/4.9.0-iimpi-2022a/" # - export AEROBULK_DIR="/cluster/projects/nn9878k/brodeau/src/aerobulk" - export OASIS_DIR="/cluster/projects/nn9878k/brodeau/src/oasis3-mct" + export AEROBULK_DIR="/cluster/projects/nn9878k/guibou/NANUK/aerobulk/" + export OASIS_DIR="/cluster/projects/nn9878k/guibou/NANUK/oa3-mct_iimpi2022a/" # export LDFLAGS="-L${INTEL_COMP_DIR}/compiler/lib/intel64_lin -lifcore -lifport" ;; diff --git a/model/finiteelement.cpp b/model/finiteelement.cpp index 70d77d87..47a30434 100644 --- a/model/finiteelement.cpp +++ b/model/finiteelement.cpp @@ -3957,7 +3957,12 @@ FiniteElement::update(std::vector const & UM_P) to_be_updated=false; // We need to make sure D_del_ci_ridge_myi is 0. where there's no ice. - D_del_ci_ridge_myi[cpt] = 0.; + D_del_ci_ridge_myi[cpt] = 0.; + D_del_ci_ridge_young[cpt] = 0.; + D_del_ci_ridge[cpt] = 0.; + + // This is a transfer term + D_del_vi_ridge_young[cpt] = 0.; // We update only elements where there's ice. Not strictly neccesary, but may improve performance. double const surface_old = M_surface[cpt]; @@ -4016,9 +4021,7 @@ FiniteElement::update(std::vector const & UM_P) // We get ridging when we cap D_del_ci_ridge_myi[cpt] = -M_conc_myi[cpt]; M_conc_myi[cpt] = std::min(M_conc_myi[cpt], 1.); // Ensure M_conc_myi doesn't exceed total ice conc - D_del_ci_ridge_myi[cpt] += M_conc_myi[cpt]; } - D_del_ci_ridge_myi[cpt]*=days_in_sec/dtime_step; // Change in myi concentration due to ridging [/day] } /*====================================================================== @@ -4053,6 +4056,8 @@ FiniteElement::update(std::vector const & UM_P) { if(M_conc_young[cpt]>0. ) { + D_del_ci_ridge_young[cpt] = -M_conc_young[cpt]; + D_del_vi_ridge_young[cpt] = -M_h_young[cpt]; new_conc_young = std::min(1.,std::max(1.-M_conc[cpt]-open_water_concentration,0.)); // Ridging @@ -4073,13 +4078,17 @@ FiniteElement::update(std::vector const & UM_P) M_ridge_ratio[cpt] = 1. - (1.-M_ridge_ratio[cpt])*M_thick[cpt]/(M_thick[cpt]+newice); M_thick[cpt] += newice; - M_conc[cpt] += del_c; - M_conc[cpt] = std::min(1.,std::max(M_conc[cpt],0.)); + // These two lines are not consistent with the rest of the function, as M_conc + // is redefined later on, accounting for del_c and the capping + //M_conc[cpt] += del_c; + //M_conc[cpt] = std::min(1.,std::max(M_conc[cpt],0.)); M_snow_thick[cpt] += newsnow; } M_conc_young[cpt] = new_conc_young; + D_del_vi_ridge_young[cpt] += M_h_young[cpt]; + D_del_ci_ridge_young[cpt] += M_conc_young[cpt]; } else { @@ -4090,6 +4099,8 @@ FiniteElement::update(std::vector const & UM_P) conc_young = M_conc_young[cpt]; } + // From now on, M_conc+del_c is only modified if ridging happens + D_del_ci_ridge[cpt] = -M_conc[cpt]-del_c; double new_conc=std::min(1.,std::max(1.-conc_young-open_water_concentration+del_c,0.)); if((new_conc+conc_young)>1.) @@ -4097,6 +4108,9 @@ FiniteElement::update(std::vector const & UM_P) M_conc[cpt]=new_conc; + // This is to make sure ridging does not create crazy thick ice. + // Howver, in practice this term mostly make sure that very low concentrations + // don't have crazy true ice thickness. Very visible at first time steps. double max_true_thickness = 50.; if(M_conc[cpt]>0.) { @@ -4121,15 +4135,26 @@ FiniteElement::update(std::vector const & UM_P) /* lower bounds */ M_conc[cpt] = ((M_conc[cpt]>0.)?(M_conc[cpt] ):(0.)) ; M_thick[cpt] = ((M_thick[cpt]>0.)?(M_thick[cpt] ):(0.)) ; + M_conc_myi[cpt] = ((M_conc_myi[cpt]>0.)?(M_conc_myi[cpt] ):(0.)) ; M_thick_myi[cpt] = ((M_thick_myi[cpt]>0.)?(M_thick_myi[cpt] ):(0.)) ; M_snow_thick[cpt] = ((M_snow_thick[cpt]>0.)?(M_snow_thick[cpt]):(0.)) ; - /* This del_ci_ridge only works for ridge_myi_and_fyi=false*/ - D_del_ci_ridge_myi[cpt] = -M_conc_myi[cpt]; - if (newice_type == 4 && use_young_ice_in_myi_reset == true) + + /*====================================================================== + * Finish budgeting ridging : + *====================================================================== + */ + D_del_ci_ridge[cpt] += M_conc[cpt]; + // Ridge MYI if needed + if (newice_type == 4 && use_young_ice_in_myi_reset == true) M_conc_myi[cpt] = std::max(0.,std::min(M_conc_myi[cpt],M_conc[cpt]+M_conc_young[cpt])); // Ensure M_conc_myi doesn't exceed total ice conc else M_conc_myi[cpt] = std::max(0.,std::min(M_conc_myi[cpt],M_conc[cpt])); // Ensure M_conc_myi doesn't exceed total ice conc - D_del_ci_ridge_myi[cpt]+=M_conc_myi[cpt]; + D_del_ci_ridge_myi[cpt] += M_conc_myi[cpt]; + + D_del_vi_ridge_young[cpt]*=days_in_sec/dtime_step; // Ice volume tranfered from young to old due to ridging [m/day] + D_del_ci_ridge_young[cpt]*=days_in_sec/dtime_step; // Change in young ice concentration due to ridging [/day] + D_del_ci_ridge_myi[cpt] *=days_in_sec/dtime_step; // Change in myi concentration due to ridging [/day] + D_del_ci_ridge[cpt] *=days_in_sec/dtime_step; // Change in 'old' ice concentration due to ridging [/day] }//loop over elements }//update @@ -5301,6 +5326,8 @@ FiniteElement::thermo(int dt) double const old_vol = M_thick[i]; double const old_snow_vol = M_snow_thick[i]; double const old_conc = M_conc[i]; + double const old_conc_myi = M_conc_myi[i]; // delta= -old + new + double const old_thick_myi = M_thick_myi[i]; double old_h_young = 0.; double old_hs_young = 0.; double old_conc_young=0.; @@ -5442,11 +5469,15 @@ FiniteElement::thermo(int dt) double mlt_vi_bot = mlt_hi_bot*old_conc; double del_vs_mlt = del_hs_mlt*old_conc; double snow2ice = del_hi_s2i*old_conc; - double del_vi_young = 0.; + double del_vi_bot_young = 0.; + double del_vi_young2old = 0.; + double del_ci_young2old = 0.; + double del_ci = 0.; + double del_ci_young = 0.; if ( M_ice_cat_type==setup::IceCategoryType::YOUNG_ICE ) { - del_vi_young+= del_hi_young*old_conc_young; - del_vi += del_hi_young*old_conc_young; + del_vi_bot_young+= del_hi_young*old_conc_young + del_hi_s2i_young*old_conc_young; //This is a temporary fix + del_vi += del_hi_young*old_conc_young + del_hi_s2i_young*old_conc_young; //Same mlt_vi_top += mlt_hi_top_young*old_conc_young; mlt_vi_bot += mlt_hi_bot_young*old_conc_young; snow2ice += del_hi_s2i_young*old_conc_young; @@ -5507,7 +5538,6 @@ FiniteElement::thermo(int dt) if ( M_h_young[i] < h_young_min*M_conc_young[i] ) { M_conc_young[i] = M_h_young[i]/h_young_min; - young_ice_growth =M_conc_young[i] - old_conc_young ; } else { @@ -5519,10 +5549,12 @@ FiniteElement::thermo(int dt) // - concentration reduction done somewhat arbitrarily double tmp = M_conc_young[i]*(h_young_max_sharp - h_young_min)/(hi - h_young_min);// new conc del_c = std::max(0., M_conc_young[i] - tmp);// added to old ice later + del_ci_young2old = del_c; M_conc_young[i] = tmp; // YI thickness drops to max value tmp = M_conc_young[i] * h_young_max_sharp;// new ice vol newice = std::max(0., M_h_young[i] - tmp);// added to old ice later + del_vi_young2old = newice; M_h_young[i] = tmp; // keep same absolute snow thickness tmp = M_conc_young[i] * hs;// new snow vol @@ -5767,7 +5799,14 @@ FiniteElement::thermo(int dt) FSD is updated after the routine is over (in updateFSD(), called from step()) */ #endif } - + // Budget sea ice area term: + del_ci = M_conc[i] - old_conc ; + if ( M_ice_cat_type==setup::IceCategoryType::YOUNG_ICE ) + // + del_ci_young2old be consistent with the change in young ice volume that does not + // include the loss of young ice due to transfer to old ice + { + del_ci_young = (M_conc_young[i] - old_conc_young) + del_ci_young2old ; + } #ifdef OASIS // ------------------------------------------------- //! 6.b) Merge of ice floe if FSD (Roach et al. 2018) @@ -5932,10 +5971,10 @@ FiniteElement::thermo(int dt) D_rain[i] = rain; // Ice volume melt rate per day per element area [m/day] - D_vice_melt[i] = del_vi*days_in_sec/ddt; + D_del_vi_tot[i] = del_vi*days_in_sec/ddt; - // Young Ice volume melt rate per day per element area [m/day] - D_del_vi_young[i] = del_vi_young*days_in_sec/ddt; + // Young Ice volume growth/melt rate per day per element area [m/day] + D_del_vi_bot_young[i] = del_vi_bot_young*days_in_sec/ddt; // Ice growth/melt rate [m/day] D_del_hi[i] = del_hi*days_in_sec/ddt; @@ -5944,16 +5983,28 @@ FiniteElement::thermo(int dt) D_del_hi_young[i] = del_hi_young*days_in_sec/ddt; // young ice volume per surface area rate [m/day] - D_newice[i] = newice_stored*days_in_sec/ddt; + D_del_vi_newfrazil[i] = newice_stored*days_in_sec/ddt; // top melt volume per surface area rate [m/day] - D_mlt_top[i] = mlt_vi_top*days_in_sec/ddt; + D_del_vi_mlt_top[i] = mlt_vi_top*days_in_sec/ddt; // top melt volume per surface area rate [m/day] - D_mlt_bot[i] = mlt_vi_bot*days_in_sec/ddt; + D_del_vi_mlt_bot[i] = mlt_vi_bot*days_in_sec/ddt; // ice from snow volume per surface area rate [m/day] - D_snow2ice[i] = snow2ice*days_in_sec/ddt; + D_del_vi_snow2ice[i] = snow2ice*days_in_sec/ddt; + + // Ice area change rate (thermo) per day per element area [m/day] + D_del_ci_thermo[i] = (del_ci+del_ci_young)*days_in_sec/ddt; + + // Young Ice area change rate (thermo) per day per element area [m/day] + D_del_ci_thermo_young[i] = del_ci_young*days_in_sec/ddt; + + // Young Ice area transfered to "old" category (thermo) per day per element area [m/day] + D_del_ci_young2old[i] = del_ci_young2old*days_in_sec/ddt; + + // Young Ice volume transfered to "old" category (thermo) per day per element area [m/day] + D_del_vi_young2old[i] = del_vi_young2old*days_in_sec/ddt; // sea ice albedo double sialb = old_conc * albedo[i]; @@ -5968,13 +6019,24 @@ FiniteElement::thermo(int dt) double del_ci_rplnt_myi =0.; double del_vi_mlt_myi =0.; double del_ci_mlt_myi =0.; - if (M_conc[i] < physical::cmin || M_thick[i] < M_conc[i]*physical::hmin) + double c_myi_max = M_conc[i]; + double v_myi_max = M_thick[i]; + if ( (M_ice_cat_type==setup::IceCategoryType::YOUNG_ICE) + && use_young_ice_in_myi_reset) + { + c_myi_max += M_conc_young[i]; + v_myi_max += M_h_young[i]; + } + // If there is not enough myi, set to 0 + if (c_myi_max < physical::cmin || v_myi_max < c_myi_max*physical::hmin) { + del_ci_mlt_myi = std::min(0.,-M_conc_myi[i]); + del_vi_mlt_myi = std::min(0.,-M_thick_myi[i]); + M_conc_myi[i] = 0.; + M_thick_myi[i] = 0.; M_fyi_fraction[i] = 0.; M_age_det[i] = 0.; M_age[i] = 0.; - M_thick_myi[i] = 0.; - M_conc_myi[i] = 0.; M_freeze_days[i] = 0.; // If there is no ice, the freeze counter for myi should be reset as no myi to tag M_freeze_onset[i] = 1.; // If there is no ice, set onset to 1 since there is no ice to update anyway } @@ -6058,16 +6120,6 @@ FiniteElement::thermo(int dt) // Now ensure that freeze and melt onsets are 0 or 1 M_freeze_onset[i] = std::round(M_freeze_onset[i]); - double old_conc_myi = M_conc_myi[i]; // delta= -old + new - double old_thick_myi = M_thick_myi[i]; - double c_myi_max = M_conc[i]; - double v_myi_max = M_thick[i]; - if ( (M_ice_cat_type==setup::IceCategoryType::YOUNG_ICE) - && use_young_ice_in_myi_reset) - { - c_myi_max += M_conc_young[i]; - v_myi_max += M_h_young[i]; - } if (reset_myi) // { @@ -6110,9 +6162,9 @@ FiniteElement::thermo(int dt) // Same logic for the volume //M_thick_myi[i] = std::max(0.,std::min(M_thick[i], M_thick_myi[i]*thick_loss_ratio)); // // Recompute effective change - del_ci_mlt_myi = M_conc_myi[i] - old_conc_myi; - del_vi_mlt_myi = M_thick_myi[i]- old_thick_myi; } + del_ci_mlt_myi = std::min(0.,M_conc_myi[i] - old_conc_myi); + del_vi_mlt_myi = std::min(0.,M_thick_myi[i] - old_thick_myi); } } // Tracers quantities to output @@ -7009,18 +7061,18 @@ FiniteElement::initModelVariables() M_variables_elt.push_back(&D_Qnosun); D_Qsw_ocean = ModelVariable(ModelVariable::variableID::D_Qsw_ocean);//! \param D_Qsw_ocean (double) SW flux out of the ocean [W/m2] M_variables_elt.push_back(&D_Qsw_ocean); - D_vice_melt = ModelVariable(ModelVariable::variableID::D_vice_melt);//! \param D_vice_melt (double) Ice volume formed/melted per element area [m/day] - M_variables_elt.push_back(&D_vice_melt); - D_del_vi_young = ModelVariable(ModelVariable::variableID::D_del_vi_young);//! \param D_del_vi_young (double) Young Ice volume formed/melted per element area [m/day] - M_variables_elt.push_back(&D_del_vi_young); - D_newice = ModelVariable(ModelVariable::variableID::D_newice);//! \param D_newice (double) Ice volume formed in open water per element area [m/day] - M_variables_elt.push_back(&D_newice); - D_mlt_top = ModelVariable(ModelVariable::variableID::D_mlt_top);//! \param D_mlt_top (double) Ice volume melted at top per element area [m/day] - M_variables_elt.push_back(&D_mlt_top); - D_mlt_bot = ModelVariable(ModelVariable::variableID::D_mlt_bot);//! \param D_mlt_bot (double) Ice volume melted at bottom per element area [m/day] - M_variables_elt.push_back(&D_mlt_bot); - D_snow2ice = ModelVariable(ModelVariable::variableID::D_snow2ice);//! \param D_snow2ice (double) Ice volume formed in from snow flooding per element area [m/day] - M_variables_elt.push_back(&D_snow2ice); + D_del_vi_tot = ModelVariable(ModelVariable::variableID::D_del_vi_tot);//! \param D_del_vi_tot (double) Ice volume formed/melted per element area [m/day] + M_variables_elt.push_back(&D_del_vi_tot); + D_del_vi_bot_young = ModelVariable(ModelVariable::variableID::D_del_vi_bot_young);//! \param D_del_vi_bot_young (double) Young Ice volume formed/melted per element area [m/day] + M_variables_elt.push_back(&D_del_vi_bot_young); + D_del_vi_newfrazil = ModelVariable(ModelVariable::variableID::D_del_vi_newfrazil);//! + M_variables_elt.push_back(&D_del_vi_newfrazil); + D_del_vi_mlt_top = ModelVariable(ModelVariable::variableID::D_del_vi_mlt_top);//! \param D_del_vi_mlt_top (double) Ice volume melted at top per element area [m/day] + M_variables_elt.push_back(&D_del_vi_mlt_top); + D_del_vi_mlt_bot = ModelVariable(ModelVariable::variableID::D_del_vi_mlt_bot);//! \param D_del_vi_mlt_bot (double) Ice volume melted at bottom per element area [m/day] + M_variables_elt.push_back(&D_del_vi_mlt_bot); + D_del_vi_snow2ice = ModelVariable(ModelVariable::variableID::D_del_vi_snow2ice);//! \param D_del_vi_snow2ice (double) Ice volume formed in from snow flooding per element area [m/day] + M_variables_elt.push_back(&D_del_vi_snow2ice); D_del_hi_young = ModelVariable(ModelVariable::variableID::D_del_hi_young);//! \param D_del_hi_young (double) Young growth/melt rate [m/day] M_variables_elt.push_back(&D_del_hi_young); D_del_hi = ModelVariable(ModelVariable::variableID::D_del_hi);//! \param D_del_hi (double) Ice growth/melt rate [m/day] @@ -7033,8 +7085,22 @@ FiniteElement::initModelVariables() M_variables_elt.push_back(&D_del_ci_rplnt_myi); D_del_vi_rplnt_myi = ModelVariable(ModelVariable::variableID::D_del_vi_rplnt_myi);//! \param D_del_vi_rplnt_myi (double) Ice growth/melt rate [m/day] M_variables_elt.push_back(&D_del_vi_rplnt_myi); - D_del_ci_ridge_myi = ModelVariable(ModelVariable::variableID::D_del_ci_ridge_myi);//! \param D_del_ci_ridge_myi (double) Ice growth/melt rate [m/day] + D_del_ci_ridge_myi = ModelVariable(ModelVariable::variableID::D_del_ci_ridge_myi);//! \param D_del_ci_ridge_myi (double) Ice surface ridged [/day] M_variables_elt.push_back(&D_del_ci_ridge_myi); + D_del_vi_ridge_young = ModelVariable(ModelVariable::variableID::D_del_vi_ridge_young);//! \param D_del_vi_ridge_young (double) Ice surf. ridged [/day] + M_variables_elt.push_back(&D_del_vi_ridge_young); + D_del_ci_ridge = ModelVariable(ModelVariable::variableID::D_del_ci_ridge);//! \param D_del_ci_ridge (double) Ice surface ridged [/day] + M_variables_elt.push_back(&D_del_ci_ridge); + D_del_ci_ridge_young = ModelVariable(ModelVariable::variableID::D_del_ci_ridge_young);//! \param D_del_ci_ridge_young (double) Ice surf. ridged [/day] + M_variables_elt.push_back(&D_del_ci_ridge_young); + D_del_ci_thermo = ModelVariable(ModelVariable::variableID::D_del_ci_thermo);//! \param D_del_ci_thermo (double) Ice surface area change (thermo) [/day] + M_variables_elt.push_back(&D_del_ci_thermo); + D_del_ci_thermo_young = ModelVariable(ModelVariable::variableID::D_del_ci_thermo_young);//! \param D_del_ci_thermo_young (double) Young ice area change (thermo) [/day] + M_variables_elt.push_back(&D_del_ci_thermo_young); + D_del_ci_young2old = ModelVariable(ModelVariable::variableID::D_del_ci_young2old);//! \param D_del_ci_young2old (double) Young ice area transferred to 'old' [/day] + M_variables_elt.push_back(&D_del_ci_young2old); + D_del_vi_young2old = ModelVariable(ModelVariable::variableID::D_del_vi_young2old);//! \param D_del_vi_young2old (double) Young ice volume transferred to 'old' [/day] + M_variables_elt.push_back(&D_del_vi_young2old); D_fwflux = ModelVariable(ModelVariable::variableID::D_fwflux);//! \param D_fwflux (double) Fresh-water flux at ocean surface [kg/m2/s] M_variables_elt.push_back(&D_fwflux); D_fwflux_ice = ModelVariable(ModelVariable::variableID::D_fwflux_ice);//! \param D_fwflux_ice (double) Fresh-water flux at ocean surface due to ice processes [kg/m2/s] @@ -8521,42 +8587,70 @@ FiniteElement::updateMeans(GridOutput& means, double time_factor) for (int i=0; idata_mesh[i] -= D_fwflux_ice[i]*time_factor; break; - case (GridOutput::variableID::del_vi_young): + case (GridOutput::variableID::dvi_bot_young): for (int i=0; idata_mesh[i] += D_del_vi_young[i]*time_factor; + it->data_mesh[i] += D_del_vi_bot_young[i]*time_factor; break; - case (GridOutput::variableID::vice_melt): + case (GridOutput::variableID::dvi_thermo): for (int i=0; idata_mesh[i] += D_vice_melt[i]*time_factor; + it->data_mesh[i] += D_del_vi_tot[i]*time_factor; break; - case (GridOutput::variableID::del_hi): + case (GridOutput::variableID::dhi): for (int i=0; idata_mesh[i] += D_del_hi[i]*time_factor; break; - case (GridOutput::variableID::del_hi_young): + case (GridOutput::variableID::dhi_young): for (int i=0; idata_mesh[i] += D_del_hi_young[i]*time_factor; break; - case (GridOutput::variableID::newice): + case (GridOutput::variableID::dvi_newfrazil): for (int i=0; idata_mesh[i] += D_newice[i]*time_factor; + it->data_mesh[i] += D_del_vi_newfrazil[i]*time_factor; break; - case (GridOutput::variableID::snow2ice): + case (GridOutput::variableID::dvi_snow2ice): for (int i=0; idata_mesh[i] += D_snow2ice[i]*time_factor; + it->data_mesh[i] += D_del_vi_snow2ice[i]*time_factor; break; - case (GridOutput::variableID::mlt_top): + case (GridOutput::variableID::dvi_mlt_top): for (int i=0; idata_mesh[i] += D_mlt_top[i]*time_factor; + it->data_mesh[i] += D_del_vi_mlt_top[i]*time_factor; break; - case (GridOutput::variableID::mlt_bot): + case (GridOutput::variableID::dvi_mlt_bot): for (int i=0; idata_mesh[i] += D_mlt_bot[i]*time_factor; + it->data_mesh[i] += D_del_vi_mlt_bot[i]*time_factor; break; case (GridOutput::variableID::wspeed): for (int i=0; idata_mesh[i] += this->windSpeedElement(i)*time_factor; break; + case (GridOutput::variableID::dci_thermo): + for (int i=0; idata_mesh[i] += D_del_ci_thermo[i]*time_factor; + break; + case (GridOutput::variableID::dci_thermo_young): + for (int i=0; idata_mesh[i] += D_del_ci_thermo_young[i]*time_factor; + break; + case (GridOutput::variableID::dci_ridge): + for (int i=0; idata_mesh[i] += D_del_ci_ridge[i]*time_factor; + break; + case (GridOutput::variableID::dci_ridge_young): + for (int i=0; idata_mesh[i] += D_del_ci_ridge_young[i]*time_factor; + break; + case (GridOutput::variableID::dvi_ridge_young): + for (int i=0; idata_mesh[i] += D_del_vi_ridge_young[i]*time_factor; + break; + case (GridOutput::variableID::dci_young2old): + for (int i=0; idata_mesh[i] += D_del_ci_young2old[i]*time_factor; + break; + case (GridOutput::variableID::dvi_young2old): + for (int i=0; idata_mesh[i] += D_del_vi_young2old[i]*time_factor; + break; case (GridOutput::variableID::mld): for (int i=0; idata_mesh[i] += M_mld[i]*time_factor; @@ -8779,14 +8873,14 @@ FiniteElement::initMoorings() ("divergence", GridOutput::variableID::divergence) // Primarily coupling variables, but perhaps useful for debugging ("taumod", GridOutput::variableID::taumod) - ("vice_melt", GridOutput::variableID::vice_melt) - ("del_vi_young", GridOutput::variableID::del_vi_young) - ("del_hi", GridOutput::variableID::del_hi) - ("del_hi_young", GridOutput::variableID::del_hi_young) - ("newice", GridOutput::variableID::newice) - ("mlt_bot", GridOutput::variableID::mlt_bot) - ("mlt_top", GridOutput::variableID::mlt_top) - ("snow2ice", GridOutput::variableID::snow2ice) + ("dhi", GridOutput::variableID::dhi) + ("dhi_young", GridOutput::variableID::dhi_young) + ("dvi_thermo", GridOutput::variableID::dvi_thermo) + ("dvi_bot_young", GridOutput::variableID::dvi_bot_young) + ("dvi_newfrazil", GridOutput::variableID::dvi_newfrazil) + ("dvi_mlt_bot", GridOutput::variableID::dvi_mlt_bot) + ("dvi_mlt_top", GridOutput::variableID::dvi_mlt_top) + ("dvi_snow2ice", GridOutput::variableID::dvi_snow2ice) ("fwflux", GridOutput::variableID::fwflux) ("fwflux_ice", GridOutput::variableID::fwflux_ice) ("QNoSw", GridOutput::variableID::QNoSw) @@ -8830,6 +8924,13 @@ FiniteElement::initMoorings() ("dci_rplnt_myi", GridOutput::variableID::dci_rplnt_myi) ("dvi_rplnt_myi", GridOutput::variableID::dvi_rplnt_myi) ("dci_ridge_myi", GridOutput::variableID::dci_ridge_myi) + ("dci_thermo", GridOutput::variableID::dci_thermo) + ("dci_thermo_young", GridOutput::variableID::dci_thermo_young) + ("dci_ridge", GridOutput::variableID::dci_ridge) + ("dci_ridge_young", GridOutput::variableID::dci_ridge_young) + ("dvi_ridge_young", GridOutput::variableID::dvi_ridge_young) + ("dci_young2old", GridOutput::variableID::dci_young2old) + ("dvi_young2old", GridOutput::variableID::dvi_young2old) ; std::vector names = vm["moorings.variables"].as>(); diff --git a/model/finiteelement.hpp b/model/finiteelement.hpp index 3306d9d1..5d857ec1 100644 --- a/model/finiteelement.hpp +++ b/model/finiteelement.hpp @@ -795,19 +795,19 @@ class FiniteElement ModelVariable D_Qnosun; // Non-solar heat loss from ocean [W/m2] ModelVariable D_Qsw_ocean; // SW flux out of the ocean [W/m2] ModelVariable D_Qassim; // flux from assim [W/m2] - ModelVariable D_vice_melt; // ice volume (/element_area) melted/formed [m/day] - ModelVariable D_del_vi_young; // young ice volume (/element_area) melted/formed [m/day] + ModelVariable D_del_vi_tot; // ice volume (/element_area) melted/formed [m/day] + ModelVariable D_del_vi_bot_young; // young ice volume (/element_area) melted/formed [m/day] ModelVariable D_del_hi; // ice growth/melt rate [m/sdat ModelVariable D_del_hi_young; // young ice growth/melt rate [m/day] - ModelVariable D_newice; // ice volume (/element_area) formed in open water [m/day] - ModelVariable D_mlt_top; // ice volume (/element_area) melted at top [m/day] - ModelVariable D_mlt_bot; // ice volume (/element_area) melted at bottom [m/day] + ModelVariable D_del_vi_newfrazil; // ice volume (/element_area) formed in open water [m/day] + ModelVariable D_del_vi_mlt_top; // ice volume (/element_area) melted at top [m/day] + ModelVariable D_del_vi_mlt_bot; // ice volume (/element_area) melted at bottom [m/day] ModelVariable D_del_vi_mlt_myi; //myi ice volume (/element_area) melted [m/day] ModelVariable D_del_vi_rplnt_myi; //myi ice vol change (/element_area) due to replenishment [./day] ModelVariable D_del_ci_rplnt_myi; //myi ice area change (/element_area) due to replenishment [./day] ModelVariable D_del_ci_mlt_myi; //myi ice area (/element_area) melted [m/day] ModelVariable D_del_ci_ridge_myi; //myi ice area change (/element_area) due to ridging [./day] - ModelVariable D_snow2ice; // ice volume (/element_area) melted at bottom [m/day] + ModelVariable D_del_vi_snow2ice; // ice volume (/element_area) melted at bottom [m/day] ModelVariable D_delS; // Salt flux to ocean ModelVariable D_fwflux; // Fresh-water flux at ocean surface [kg/m2/s] ModelVariable D_fwflux_ice; // Fresh-water flux at ocean surface due to ice processes [kg/m2/s] @@ -819,6 +819,13 @@ class FiniteElement ModelVariable D_rain; // Rain into the ocean [kg/m2/s] ModelVariable D_albedo; // surface albedo ModelVariable D_sialb; // sea ice albedo + ModelVariable D_del_vi_ridge_young; //young ice volume change (/element_area) due to ridging [m/day] + ModelVariable D_del_ci_ridge_young; //young ice area change (/element_area) due to ridging [./day] + ModelVariable D_del_ci_ridge; // ice area change (/element_area) due to ridging [./day] + ModelVariable D_del_ci_thermo; // ice area change (/element_area) due to thermo [./day] + ModelVariable D_del_ci_thermo_young; // young ice area change (/element_area) due to thermo [./day] + ModelVariable D_del_ci_young2old; // young ice area change (/element_area) transferred to 'old' [./day] + ModelVariable D_del_vi_young2old; // young ice volume change (/element_area) transferred to 'old' [m/day] // Temporary variables std::vector D_tau_w; // Ice-ocean drag [Pa] diff --git a/model/gridoutput.hpp b/model/gridoutput.hpp index b52d262d..ba1df7ac 100644 --- a/model/gridoutput.hpp +++ b/model/gridoutput.hpp @@ -170,24 +170,31 @@ class GridOutput rain = 107, evap = 108, d_crit = 109, - vice_melt = 110, - del_hi = 111, - del_hi_young = 112, - newice = 113, - snow2ice = 114, - mlt_top = 115, - mlt_bot = 116, - del_vi_young = 117, + dvi_thermo = 110, + dhi = 111, + dhi_young = 112, + dvi_newfrazil = 113, + dvi_snow2ice = 114, + dvi_mlt_top = 115, + dvi_mlt_bot = 116, + dvi_bot_young = 117, sigma_n = 118, sigma_s = 119, divergence = 120, albedo = 121, - dci_ridge_myi= 122, - dci_mlt_myi = 123, - dvi_mlt_myi = 124, - dci_rplnt_myi= 125, - dvi_rplnt_myi= 126, - sialb = 127, + dci_ridge_myi = 122, + dci_mlt_myi = 123, + dvi_mlt_myi = 124, + dci_rplnt_myi = 125, + dvi_rplnt_myi = 126, + sialb = 127, + dci_thermo = 128, + dci_thermo_young = 129, + dci_young2old = 130, + dci_ridge = 131, + dci_ridge_young = 132, + dvi_ridge_young = 133, + dvi_young2old = 134, // Forcing variables tair = 200, @@ -544,57 +551,57 @@ class GridOutput Units = "1"; cell_methods = "area: mean"; break; - case (variableID::del_vi_young): - name = "del_vi_young"; + case (variableID::dvi_bot_young): + name = "dvi_bot_young"; longName = "Young Ice Volume Melted or Formed per Day per Surface Area"; stdName = "young_ice_volume_melted_or_formed_per_day_per_surface_area"; Units = " m/day"; cell_methods = "area: mean"; break; - case (variableID::vice_melt): - name = "vice_melt"; + case (variableID::dvi_thermo): + name = "dvi_thermo"; longName = "Ice Volume Melted or Formed per Day per Surface Area"; stdName = "ice_volume_melted_or_formed_per_day_per_surface_area"; Units = " m/day"; cell_methods = "area: mean"; break; - case (variableID::del_hi): - name = "del_hi"; + case (variableID::dhi): + name = "dhi"; longName = "Growth-melt rate of (thick) ice"; stdName = "growth_melt_rate_of_thick_ice"; Units = " m/day"; cell_methods = "area: mean"; break; - case (variableID::del_hi_young): - name = "del_hi_young"; + case (variableID::dhi_young): + name = "dhi_young"; longName = "Growth-melt rate of young ice"; stdName = "growth_melt_rate_of_young_ice"; Units = " m/day"; cell_methods = "area: mean"; break; - case (variableID::newice): - name = "newice"; + case (variableID::dvi_newfrazil): + name = "dvi_newfrazil"; longName = "Ice formed in open water by supercooling"; stdName = "ice_formed_in_open_water_by_supercooling"; Units = " m/day"; cell_methods = "area: mean"; break; - case (variableID::mlt_bot): - name = "mlt_bot"; + case (variableID::dvi_mlt_bot): + name = "dvi_mlt_bot"; longName = "Ice melted at bottom"; stdName = "ice_melted_at_bottom"; Units = " m/day"; cell_methods = "area: mean"; break; - case (variableID::mlt_top): - name = "mlt_top"; + case (variableID::dvi_mlt_top): + name = "dvi_mlt_top"; longName = "Ice melted at top"; stdName = "ice_melted_at_top"; Units = " m/day"; cell_methods = "area: mean"; break; - case (variableID::snow2ice): - name = "snow2ice"; + case (variableID::dvi_snow2ice): + name = "dvi_snow2ice"; longName = "Ice formed from snow by flooding"; stdName = "ice_formed_from_snow_by_flooding"; Units = " m/day"; @@ -635,6 +642,55 @@ class GridOutput Units = " /day"; cell_methods = "area: mean"; break; + case (variableID::dci_ridge_young): + name = "dci_ridge_young"; + longName = "young ice area_change rate due to ridging"; + stdName = "young_ice_area_change_rate_due_to_ridging"; + Units = " /day"; + cell_methods = "area: mean"; + break; + case (variableID::dvi_ridge_young): + name = "dvi_ridge_young"; + longName = "young ice volume_change rate due to ridging"; + stdName = "young_ice_volume_change_rate_due_to_ridging"; + Units = "m/day"; + cell_methods = "area: mean"; + break; + case (variableID::dci_ridge): + name = "dci_ridge"; + longName = " ice area_change rate due to ridging"; + stdName = "ice_area_change_rate_due_to_ridging"; + Units = " /day"; + cell_methods = "area: mean"; + break; + case (variableID::dci_thermo): + name = "dci_thermo"; + longName = " ice area_change rate due to thermo"; + stdName = "ice_area_change_rate_due_to_thermo"; + Units = " /day"; + cell_methods = "area: mean"; + break; + case (variableID::dci_thermo_young): + name = "dci_thermo_young"; + longName = " young ice area change rate due to thermo"; + stdName = "young_ice_area_change_rate_due_to_thermo"; + Units = " /day"; + cell_methods = "area: mean"; + break; + case (variableID::dci_young2old): + name = "dci_young2old"; + longName = " young ice area transfer to old due to thermo"; + stdName = "young_ice_area_transfer_to_old_due_to_thermo"; + Units = " /day"; + cell_methods = "area: mean"; + break; + case (variableID::dvi_young2old): + name = "dvi_young2old"; + longName = " young ice volume transfer to old due to thermo"; + stdName = "young_ice_volume_transfer_to_old_due_to_thermo"; + Units = " /day"; + cell_methods = "area: mean"; + break; case (variableID::albedo): name = "albedo"; longName = "Surface albedo"; diff --git a/model/model_variable.cpp b/model/model_variable.cpp index 59a7c03c..7645e51f 100644 --- a/model/model_variable.cpp +++ b/model/model_variable.cpp @@ -559,18 +559,18 @@ ModelVariable::initElemental() M_exporting = false; break; - case (variableID::D_vice_melt): + case (variableID::D_del_vi_tot): // ice volume gain/loss by freezing/melt [m/day] - M_name = "D_vice_melt"; - M_export_name = "D_vice_melt"; + M_name = "D_del_vi_tot"; + M_export_name = "D_del_vi_tot"; M_prognostic = false; M_exporting = false; break; - case (variableID::D_del_vi_young): + case (variableID::D_del_vi_bot_young): // Young ice volume gain/loss by freezing/melt [m/day] - M_name = "D_del_vi_young"; - M_export_name = "D_del_vi_young"; + M_name = "D_del_vi_bot_young"; + M_export_name = "D_del_vi_bot_young"; M_prognostic = false; M_exporting = false; break; @@ -591,38 +591,91 @@ ModelVariable::initElemental() M_exporting = false; break; - case (variableID::D_newice): + case (variableID::D_del_vi_newfrazil): // ice growth in open water [m/day] - M_name = "D_newice"; - M_export_name = "D_newice"; + M_name = "D_del_vi_newfrazil"; + M_export_name = "D_del_vi_newfrazil"; M_prognostic = false; M_exporting = false; break; - case (variableID::D_mlt_bot): + case (variableID::D_del_vi_mlt_bot): // ice melt at bottom [m/day] - M_name = "D_mlt_bot"; - M_export_name = "D_mlt_bot"; + M_name = "D_del_vi_mlt_bot"; + M_export_name = "D_del_vi_mlt_bot"; M_prognostic = false; M_exporting = false; break; - case (variableID::D_mlt_top): + case (variableID::D_del_vi_mlt_top): // ice melt at top [m/day] - M_name = "D_mlt_top"; - M_export_name = "D_mlt_top"; + M_name = "D_del_vi_mlt_top"; + M_export_name = "D_del_vi_mlt_top"; M_prognostic = false; M_exporting = false; break; - case (variableID::D_snow2ice): + case (variableID::D_del_vi_snow2ice): // ice formed from snow by flooding [m/day] - M_name = "D_snow2ice"; - M_export_name = "D_snow2ice"; + M_name = "D_del_vi_snow2ice"; + M_export_name = "D_del_vi_snow2ice"; M_prognostic = false; M_exporting = false; break; + case (variableID::D_del_vi_young2old): + // Young ice volume transferred to old category [m/day] + M_name = "D_del_vi_young2old"; + M_export_name = "D_del_vi_young2old"; + M_prognostic = false; + M_exporting = false; + break; + + case (variableID::D_del_ci_young2old): + // Young ice volume transferred to old category [m/day] + M_name = "D_del_ci_young2old"; + M_export_name = "D_del_ci_young2old"; + M_prognostic = false; + M_exporting = false; + break; + + case (variableID::D_del_ci_thermo_young): + // Young ice area change due to thermo [m/day] + M_name = "D_del_ci_thermo_young"; + M_export_name = "D_del_ci_thermo_young"; + M_prognostic = false; + M_exporting = false; + break; + + case (variableID::D_del_ci_thermo): + // Ice area change due to thermo [m/day] + M_name = "D_del_ci_thermo"; + M_export_name = "D_del_ci_thermo"; + M_prognostic = false; + M_exporting = false; + break; + + case (variableID::D_del_ci_ridge): + M_name = "D_del_ci_ridge"; + M_export_name = "Ice_area_ridging_change_daily_rate"; + M_prognostic = false; + M_exporting = false; + break; + + case (variableID::D_del_ci_ridge_young): + M_name = "D_del_ci_ridge_young"; + M_export_name = "Young_ice_area_ridging_change_daily_rate"; + M_prognostic = false; + M_exporting = false; + break; + + case (variableID::D_del_vi_ridge_young): + M_name = "D_del_vi_ridge_young"; + M_export_name = "Young_ice_volume_ridging_change_daily_rate"; + M_prognostic = false; + M_exporting = false; + break; + case (variableID::D_brine): // Brine release - kg/m^2/s M_name = "D_brine"; diff --git a/model/model_variable.hpp b/model/model_variable.hpp index ca2ba123..0ee9e86b 100644 --- a/model/model_variable.hpp +++ b/model/model_variable.hpp @@ -108,22 +108,29 @@ class ModelVariable: public std::vector // inherit from std::vector