! SVN:$Id: ice_dyn_eap.F90 1134 2016-07-29 20:47:56Z eclare $ !======================================================================= ! ! Elastic-anisotropic sea ice dynamics model ! Computes ice velocity and deformation ! ! See: ! ! Wilchinsky, A.V. and D.L. Feltham (2006). Modelling the rheology of ! sea ice as a collection of diamond-shaped floes. ! Journal of Non-Newtonian Fluid Mechanics, 138(1), 22-32. ! ! Tsamados, M., D.L. Feltham, and A.V. Wilchinsky (2012). Impact on new ! anisotropic rheology on simulations of Arctic sea ice. JGR, in press. ! ! authors: Michel Tsamados, CPOM ! David Schroeder, CPOM module ice_dyn_eap use ice_kinds_mod use ice_blocks, only: nx_block, ny_block use ice_domain_size, only: max_blocks implicit none private public :: eap, init_eap, write_restart_eap, read_restart_eap ! Look-up table needed for calculating structure tensor integer (int_kind), parameter :: & nx_yield = 41, & ny_yield = 41, & na_yield = 21 real (kind=dbl_kind), dimension (nx_yield,ny_yield,na_yield) :: & s11r, s12r, s22r, s11s, s12s, s22s real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: & a11_1, a11_2, a11_3, a11_4, & ! components of a12_1, a12_2, a12_3, a12_4 ! structure tensor ! history real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks), public :: & e11 , & ! components of strain rate tensor (1/s) e12 , & e22 , & yieldstress11, & ! components of yield stress tensor (kg/s^2) yieldstress12, & yieldstress22, & s11 , & ! components of stress tensor (kg/s^2) s12 , & s22 , & a11 , & ! components of structure tensor () a12 !======================================================================= contains !======================================================================= ! ! Elastic-anisotropic-plastic dynamics driver ! based on subroutine evp subroutine eap (dt) #ifdef CICE_IN_NEMO ! Wind stress is set during this routine from the values supplied ! via NEMO (unless calc_strair is true). These values are supplied ! rotated on u grid and multiplied by aice. strairxT = 0 in this ! case so operations in evp_prep1 are pointless but carried out to ! minimise code changes. #endif use ice_atmo, only: Cdn_ocn use ice_boundary, only: ice_halo, ice_HaloMask, ice_HaloUpdate, & ice_HaloDestroy use ice_blocks, only: block, get_block use ice_constants, only: field_loc_center, field_loc_NEcorner, & field_type_scalar, field_type_vector, c0, p5 use ice_domain, only: nblocks, blocks_ice, halo_info, maskhalo_dyn use ice_dyn_shared, only: fcor_blk, ndte, dtei, a_min, m_min, & cosw, sinw, denom1, uvel_init, vvel_init, arlx1i, & evp_prep1, evp_prep2, stepu, evp_finish use ice_flux, only: rdg_conv, rdg_shear, prs_sig, strairxT, strairyT, & strairx, strairy, uocn, vocn, ss_tltx, ss_tlty, iceumask, fm, & strtltx, strtlty, strocnx, strocny, strintx, strinty, & strocnxT, strocnyT, strax, stray, & stressp_1, stressp_2, stressp_3, stressp_4, & stressm_1, stressm_2, stressm_3, stressm_4, & stress12_1, stress12_2, stress12_3, stress12_4 use ice_grid, only: tmask, umask, dxt, dyt, dxhy, dyhx, cxp, cyp, cxm, cym, & tarear, uarear, tinyarea, to_ugrid, t2ugrid_vector, u2tgrid_vector use ice_mechred, only: ice_strength use ice_state, only: aice, vice, vsno, uvel, vvel, divu, shear, & aice_init, aice0, aicen, vicen, strength ! use ice_timers, only: timer_dynamics, timer_bound, & ! ice_timer_start, ice_timer_stop, & ! timer_tmp1, timer_tmp2, timer_tmp3 use ice_timers, only: timer_dynamics, timer_bound, & ice_timer_start, ice_timer_stop #ifdef CICE_IN_NEMO use ice_atmo, only: calc_strair #endif real (kind=dbl_kind), intent(in) :: & dt ! time step ! local variables integer (kind=int_kind) :: & ksub , & ! subcycle step iblk , & ! block index ilo,ihi,jlo,jhi, & ! beginning and end of physical domain i, j integer (kind=int_kind), dimension(max_blocks) :: & icellt , & ! no. of cells where icetmask = 1 icellu ! no. of cells where iceumask = 1 integer (kind=int_kind), dimension (nx_block*ny_block, max_blocks) :: & indxti , & ! compressed index in i-direction indxtj , & ! compressed index in j-direction indxui , & ! compressed index in i-direction indxuj ! compressed index in j-direction real (kind=dbl_kind), dimension (nx_block,ny_block,max_blocks) :: & tmass , & ! total mass of ice and snow (kg/m^2) waterx , & ! for ocean stress calculation, x (m/s) watery , & ! for ocean stress calculation, y (m/s) forcex , & ! work array: combined atm stress and ocn tilt, x forcey , & ! work array: combined atm stress and ocn tilt, y aiu , & ! ice fraction on u-grid umass , & ! total mass of ice and snow (u grid) umassdti ! mass of U-cell/dte (kg/m^2 s) real (kind=dbl_kind), allocatable :: fld2(:,:,:,:) real (kind=dbl_kind), dimension(nx_block,ny_block,8):: & strtmp ! stress combinations for momentum equation integer (kind=int_kind), dimension (nx_block,ny_block,max_blocks) :: & icetmask, & ! ice extent mask (T-cell) halomask ! ice mask for halo update type (ice_halo) :: & halo_info_mask ! ghost cell update info for masked halo type (block) :: & this_block ! block information for current block call ice_timer_start(timer_dynamics) ! dynamics !----------------------------------------------------------------- ! Initialize !----------------------------------------------------------------- allocate(fld2(nx_block,ny_block,2,max_blocks)) ! This call is needed only if dt changes during runtime. ! call set_evp_parameters (dt) !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) do iblk = 1, nblocks do j = 1, ny_block do i = 1, nx_block rdg_conv (i,j,iblk) = c0 rdg_shear(i,j,iblk) = c0 divu (i,j,iblk) = c0 shear(i,j,iblk) = c0 prs_sig(i,j,iblk) = c0 e11(i,j,iblk) = c0 e12(i,j,iblk) = c0 e22(i,j,iblk) = c0 s11(i,j,iblk) = c0 s12(i,j,iblk) = c0 s22(i,j,iblk) = c0 yieldstress11(i,j,iblk) = c0 yieldstress12(i,j,iblk) = c0 yieldstress22(i,j,iblk) = c0 enddo enddo !----------------------------------------------------------------- ! preparation for dynamics !----------------------------------------------------------------- this_block = get_block(blocks_ice(iblk),iblk) ilo = this_block%ilo ihi = this_block%ihi jlo = this_block%jlo jhi = this_block%jhi call evp_prep1 (nx_block, ny_block, & ilo, ihi, jlo, jhi, & aice (:,:,iblk), vice (:,:,iblk), & vsno (:,:,iblk), tmask (:,:,iblk), & strairxT(:,:,iblk), strairyT(:,:,iblk), & strairx (:,:,iblk), strairy (:,:,iblk), & tmass (:,:,iblk), icetmask(:,:,iblk)) enddo ! iblk !$OMP END PARALLEL DO call ice_timer_start(timer_bound) call ice_HaloUpdate (icetmask, halo_info, & field_loc_center, field_type_scalar) call ice_timer_stop(timer_bound) !----------------------------------------------------------------- ! convert fields from T to U grid !----------------------------------------------------------------- call to_ugrid(tmass,umass) call to_ugrid(aice_init, aiu) #ifdef CICE_IN_NEMO !---------------------------------------------------------------- ! Set wind stress to values supplied via NEMO ! This wind stress is rotated on u grid and multiplied by aice !---------------------------------------------------------------- if (.not. calc_strair) then strairx(:,:,:) = strax(:,:,:) strairy(:,:,:) = stray(:,:,:) else #endif call t2ugrid_vector(strairx) call t2ugrid_vector(strairy) #ifdef CICE_IN_NEMO endif #endif !$OMP PARALLEL DO PRIVATE(iblk,i,j,ilo,ihi,jlo,jhi,this_block) do iblk = 1, nblocks !----------------------------------------------------------------- ! more preparation for dynamics !----------------------------------------------------------------- this_block = get_block(blocks_ice(iblk),iblk) ilo = this_block%ilo ihi = this_block%ihi jlo = this_block%jlo jhi = this_block%jhi call evp_prep2 (nx_block, ny_block, & ilo, ihi, jlo, jhi, & icellt(iblk), icellu(iblk), & indxti (:,iblk), indxtj (:,iblk), & indxui (:,iblk), indxuj (:,iblk), & aiu (:,:,iblk), umass (:,:,iblk), & umassdti (:,:,iblk), fcor_blk (:,:,iblk), & umask (:,:,iblk), & uocn (:,:,iblk), vocn (:,:,iblk), & strairx (:,:,iblk), strairy (:,:,iblk), & ss_tltx (:,:,iblk), ss_tlty (:,:,iblk), & icetmask (:,:,iblk), iceumask (:,:,iblk), & fm (:,:,iblk), dt, & strtltx (:,:,iblk), strtlty (:,:,iblk), & strocnx (:,:,iblk), strocny (:,:,iblk), & strintx (:,:,iblk), strinty (:,:,iblk), & waterx (:,:,iblk), watery (:,:,iblk), & forcex (:,:,iblk), forcey (:,:,iblk), & stressp_1 (:,:,iblk), stressp_2 (:,:,iblk), & stressp_3 (:,:,iblk), stressp_4 (:,:,iblk), & stressm_1 (:,:,iblk), stressm_2 (:,:,iblk), & stressm_3 (:,:,iblk), stressm_4 (:,:,iblk), & stress12_1(:,:,iblk), stress12_2(:,:,iblk), & stress12_3(:,:,iblk), stress12_4(:,:,iblk), & uvel_init (:,:,iblk), vvel_init (:,:,iblk), & uvel (:,:,iblk), vvel (:,:,iblk)) !----------------------------------------------------------------- ! Initialize structure tensor !----------------------------------------------------------------- do j = 1, ny_block do i = 1, nx_block if (icetmask(i,j,iblk)==0) then ! structure tensor a11_1(i,j,iblk) = p5 a11_2(i,j,iblk) = p5 a11_3(i,j,iblk) = p5 a11_4(i,j,iblk) = p5 a12_1(i,j,iblk) = c0 a12_2(i,j,iblk) = c0 a12_3(i,j,iblk) = c0 a12_4(i,j,iblk) = c0 endif ! icetmask enddo ! i enddo ! j !----------------------------------------------------------------- ! ice strength ! New strength used in Ukita Moritz rheology !----------------------------------------------------------------- call ice_strength (nx_block, ny_block, & ilo, ihi, jlo, jhi, & icellt(iblk), & indxti (:,iblk), & indxtj (:,iblk), & aice (:,:, iblk), & vice (:,:, iblk), & aice0 (:,:, iblk), & aicen (:,:,:,iblk), & vicen (:,:,:,iblk), & strength(:,:, iblk)) ! load velocity into array for boundary updates fld2(:,:,1,iblk) = uvel(:,:,iblk) fld2(:,:,2,iblk) = vvel(:,:,iblk) enddo ! iblk !$OMP END PARALLEL DO call ice_timer_start(timer_bound) call ice_HaloUpdate (strength, halo_info, & field_loc_center, field_type_scalar) ! velocities may have changed in evp_prep2 call ice_HaloUpdate (fld2, halo_info, & field_loc_NEcorner, field_type_vector) call ice_timer_stop(timer_bound) ! unload !$OMP PARALLEL DO PRIVATE(iblk) do iblk = 1, nblocks uvel(:,:,iblk) = fld2(:,:,1,iblk) vvel(:,:,iblk) = fld2(:,:,2,iblk) enddo !$OMP END PARALLEL DO if (maskhalo_dyn) then call ice_timer_start(timer_bound) halomask = 0 where (iceumask) halomask = 1 call ice_HaloUpdate (halomask, halo_info, & field_loc_center, field_type_scalar) call ice_timer_stop(timer_bound) call ice_HaloMask(halo_info_mask, halo_info, halomask) endif do ksub = 1,ndte ! subcycling !----------------------------------------------------------------- ! stress tensor equation, total surface stress !----------------------------------------------------------------- !$OMP PARALLEL DO PRIVATE(iblk,strtmp) do iblk = 1, nblocks ! call ice_timer_start(timer_tmp1) ! dynamics call stress_eap (nx_block, ny_block, & ksub, ndte, & icellt(iblk), & indxti (:,iblk), indxtj (:,iblk), & arlx1i, denom1, & uvel (:,:,iblk), vvel (:,:,iblk), & dxt (:,:,iblk), dyt (:,:,iblk), & dxhy (:,:,iblk), dyhx (:,:,iblk), & cxp (:,:,iblk), cyp (:,:,iblk), & cxm (:,:,iblk), cym (:,:,iblk), & tarear (:,:,iblk), strength (:,:,iblk), & a11 (:,:,iblk), a12 (:,:,iblk), & a11_1 (:,:,iblk), a11_2 (:,:,iblk), & a11_3 (:,:,iblk), a11_4 (:,:,iblk), & a12_1 (:,:,iblk), a12_2 (:,:,iblk), & a12_3 (:,:,iblk), a12_4 (:,:,iblk), & stressp_1 (:,:,iblk), stressp_2 (:,:,iblk), & stressp_3 (:,:,iblk), stressp_4 (:,:,iblk), & stressm_1 (:,:,iblk), stressm_2 (:,:,iblk), & stressm_3 (:,:,iblk), stressm_4 (:,:,iblk), & stress12_1(:,:,iblk), stress12_2(:,:,iblk), & stress12_3(:,:,iblk), stress12_4(:,:,iblk), & shear (:,:,iblk), divu (:,:,iblk), & e11 (:,:,iblk), e12 (:,:,iblk), & e22 (:,:,iblk), & s11 (:,:,iblk), s12 (:,:,iblk), & s22 (:,:,iblk), & yieldstress11 (:,:,iblk), & yieldstress12 (:,:,iblk), & yieldstress22 (:,:,iblk), & prs_sig (:,:,iblk), & rdg_conv (:,:,iblk), rdg_shear (:,:,iblk), & strtmp (:,:,:)) ! call ice_timer_stop(timer_tmp1) ! dynamics !----------------------------------------------------------------- ! momentum equation !----------------------------------------------------------------- call stepu (nx_block, ny_block, & icellu (iblk), Cdn_ocn (:,:,iblk), & indxui (:,iblk), indxuj (:,iblk), & aiu (:,:,iblk), strtmp (:,:,:), & uocn (:,:,iblk), vocn (:,:,iblk), & waterx (:,:,iblk), watery (:,:,iblk), & forcex (:,:,iblk), forcey (:,:,iblk), & umassdti (:,:,iblk), fm (:,:,iblk), & uarear (:,:,iblk), & strocnx (:,:,iblk), strocny (:,:,iblk), & strintx (:,:,iblk), strinty (:,:,iblk), & uvel_init(:,:,iblk), vvel_init(:,:,iblk),& uvel (:,:,iblk), vvel (:,:,iblk)) ! load velocity into array for boundary updates fld2(:,:,1,iblk) = uvel(:,:,iblk) fld2(:,:,2,iblk) = vvel(:,:,iblk) !----------------------------------------------------------------- ! evolution of structure tensor A !----------------------------------------------------------------- ! call ice_timer_start(timer_tmp3) ! dynamics if (mod(ksub,10) == 1) then ! only called every 10th timestep call stepa (nx_block, ny_block, & dtei, icellt (iblk), & indxti (:,iblk), indxtj (:,iblk), & a11 (:,:,iblk), a12 (:,:,iblk), & a11_1 (:,:,iblk), a11_2 (:,:,iblk), & a11_3 (:,:,iblk), a11_4 (:,:,iblk), & a12_1 (:,:,iblk), a12_2 (:,:,iblk), & a12_3 (:,:,iblk), a12_4 (:,:,iblk), & stressp_1(:,:,iblk), stressp_2(:,:,iblk), & stressp_3(:,:,iblk), stressp_4(:,:,iblk), & stressm_1(:,:,iblk), stressm_2(:,:,iblk), & stressm_3(:,:,iblk), stressm_4(:,:,iblk), & stress12_1(:,:,iblk), stress12_2(:,:,iblk), & stress12_3(:,:,iblk), stress12_4(:,:,iblk)) endif ! call ice_timer_stop(timer_tmp3) ! dynamics enddo !$OMP END PARALLEL DO call ice_timer_start(timer_bound) if (maskhalo_dyn) then call ice_HaloUpdate (fld2, halo_info_mask, & field_loc_NEcorner, field_type_vector) else call ice_HaloUpdate (fld2, halo_info, & field_loc_NEcorner, field_type_vector) endif call ice_timer_stop(timer_bound) ! unload !$OMP PARALLEL DO PRIVATE(iblk) do iblk = 1, nblocks uvel(:,:,iblk) = fld2(:,:,1,iblk) vvel(:,:,iblk) = fld2(:,:,2,iblk) enddo !$OMP END PARALLEL DO enddo ! subcycling deallocate(fld2) if (maskhalo_dyn) call ice_HaloDestroy(halo_info_mask) !----------------------------------------------------------------- ! ice-ocean stress !----------------------------------------------------------------- !$OMP PARALLEL DO PRIVATE(iblk) do iblk = 1, nblocks call evp_finish & (nx_block, ny_block, & icellu (iblk), Cdn_ocn (:,:,iblk), & indxui (:,iblk), indxuj (:,iblk), & uvel (:,:,iblk), vvel (:,:,iblk), & uocn (:,:,iblk), vocn (:,:,iblk), & aiu (:,:,iblk), fm (:,:,iblk), & strintx (:,:,iblk), strinty (:,:,iblk), & strairx (:,:,iblk), strairy (:,:,iblk), & strocnx (:,:,iblk), strocny (:,:,iblk), & strocnxT(:,:,iblk), strocnyT(:,:,iblk)) enddo !$OMP END PARALLEL DO call u2tgrid_vector(strocnxT) ! shift call u2tgrid_vector(strocnyT) call ice_timer_stop(timer_dynamics) ! dynamics end subroutine eap !======================================================================= ! Initialize parameters and variables needed for the eap dynamics ! (based on init_evp) subroutine init_eap (dt) use ice_blocks, only: nx_block, ny_block use ice_communicate, only: my_task, master_task use ice_constants, only: c0, c1, c2, c12, p5, pi, pih, piq use ice_domain, only: nblocks use ice_dyn_shared, only: init_evp use ice_exit, only: abort_ice use ice_restart_shared, only: runtype real (kind=dbl_kind), intent(in) :: & dt ! time step ! local variables integer (kind=int_kind) :: & i, j, k, & iblk ! block index real (kind=dbl_kind), parameter :: & eps6 = 1.0e-6_dbl_kind, & phi = pi/c12 ! diamond shaped floe smaller angle (default phi = 30 deg) integer (kind=int_kind) :: & ix, iy, ip, iz, n, ia integer (kind=int_kind), parameter :: & nz = 100 real (kind=dbl_kind) :: & ainit, xinit, yinit, pinit, zinit, & da, dx, dy, dp, dz, a1 call init_evp (dt) !$OMP PARALLEL DO PRIVATE(iblk,i,j) do iblk = 1, nblocks do j = 1, ny_block do i = 1, nx_block e11(i,j,iblk) = c0 e12(i,j,iblk) = c0 e22(i,j,iblk) = c0 s11(i,j,iblk) = c0 s12(i,j,iblk) = c0 s22(i,j,iblk) = c0 yieldstress11(i,j,iblk) = c0 yieldstress12(i,j,iblk) = c0 yieldstress22(i,j,iblk) = c0 a11_1 (i,j,iblk) = p5 a11_2 (i,j,iblk) = p5 a11_3 (i,j,iblk) = p5 a11_4 (i,j,iblk) = p5 a12_1 (i,j,iblk) = c0 a12_2 (i,j,iblk) = c0 a12_3 (i,j,iblk) = c0 a12_4 (i,j,iblk) = c0 enddo ! i enddo ! j enddo ! iblk !$OMP END PARALLEL DO !----------------------------------------------------------------- ! create lookup table for eap dynamics (see Appendix A1) !----------------------------------------------------------------- da = p5/real(na_yield-1,kind=dbl_kind) ainit = p5 - da dx = pi/real(nx_yield-1,kind=dbl_kind) xinit = pi + piq - dx dz = pi/real(nz,kind=dbl_kind) zinit = -pih dy = pi/real(ny_yield-1,kind=dbl_kind) yinit = -dy do ia=1,na_yield do ix=1,nx_yield do iy=1,ny_yield s11r(ix,iy,ia) = c0 s12r(ix,iy,ia) = c0 s22r(ix,iy,ia) = c0 s11s(ix,iy,ia) = c0 s12s(ix,iy,ia) = c0 s22s(ix,iy,ia) = c0 if (ia <= na_yield-1) then do iz=1,nz s11r(ix,iy,ia) = s11r(ix,iy,ia) + 1*w1(ainit+ia*da)* & exp(-w2(ainit+ia*da)*(zinit+iz*dz)*(zinit+iz*dz))* & s11kr(xinit+ix*dx,yinit+iy*dy,zinit+iz*dz,phi)*dz/sin(c2*phi) s12r(ix,iy,ia) = s12r(ix,iy,ia) + 1*w1(ainit+ia*da)* & exp(-w2(ainit+ia*da)*(zinit+iz*dz)*(zinit+iz*dz))* & s12kr(xinit+ix*dx,yinit+iy*dy,zinit+iz*dz,phi)*dz/sin(c2*phi) s22r(ix,iy,ia) = s22r(ix,iy,ia) + 1*w1(ainit+ia*da)* & exp(-w2(ainit+ia*da)*(zinit+iz*dz)*(zinit+iz*dz))* & s22kr(xinit+ix*dx,yinit+iy*dy,zinit+iz*dz,phi)*dz/sin(c2*phi) s11s(ix,iy,ia) = s11s(ix,iy,ia) + 1*w1(ainit+ia*da)* & exp(-w2(ainit+ia*da)*(zinit+iz*dz)*(zinit+iz*dz))* & s11ks(xinit+ix*dx,yinit+iy*dy,zinit+iz*dz,phi)*dz/sin(c2*phi) s12s(ix,iy,ia) = s12s(ix,iy,ia) + 1*w1(ainit+ia*da)* & exp(-w2(ainit+ia*da)*(zinit+iz*dz)*(zinit+iz*dz))* & s12ks(xinit+ix*dx,yinit+iy*dy,zinit+iz*dz,phi)*dz/sin(c2*phi) s22s(ix,iy,ia) = s22s(ix,iy,ia) + 1*w1(ainit+ia*da)* & exp(-w2(ainit+ia*da)*(zinit+iz*dz)*(zinit+iz*dz))* & s22ks(xinit+ix*dx,yinit+iy*dy,zinit+iz*dz,phi)*dz/sin(c2*phi) enddo if (abs(s11r(ix,iy,ia)) < eps6) s11r(ix,iy,ia) = c0 if (abs(s12r(ix,iy,ia)) < eps6) s12r(ix,iy,ia) = c0 if (abs(s22r(ix,iy,ia)) < eps6) s22r(ix,iy,ia) = c0 if (abs(s11s(ix,iy,ia)) < eps6) s11s(ix,iy,ia) = c0 if (abs(s12s(ix,iy,ia)) < eps6) s12s(ix,iy,ia) = c0 if (abs(s22s(ix,iy,ia)) < eps6) s22s(ix,iy,ia) = c0 else s11r(ix,iy,ia) = p5*s11kr(xinit+ix*dx,yinit+iy*dy,c0,phi)/sin(c2*phi) s12r(ix,iy,ia) = p5*s12kr(xinit+ix*dx,yinit+iy*dy,c0,phi)/sin(c2*phi) s22r(ix,iy,ia) = p5*s22kr(xinit+ix*dx,yinit+iy*dy,c0,phi)/sin(c2*phi) s11s(ix,iy,ia) = p5*s11ks(xinit+ix*dx,yinit+iy*dy,c0,phi)/sin(c2*phi) s12s(ix,iy,ia) = p5*s12ks(xinit+ix*dx,yinit+iy*dy,c0,phi)/sin(c2*phi) s22s(ix,iy,ia) = p5*s22ks(xinit+ix*dx,yinit+iy*dy,c0,phi)/sin(c2*phi) if (abs(s11r(ix,iy,ia)) < eps6) s11r(ix,iy,ia) = c0 if (abs(s12r(ix,iy,ia)) < eps6) s12r(ix,iy,ia) = c0 if (abs(s22r(ix,iy,ia)) < eps6) s22r(ix,iy,ia) = c0 if (abs(s11s(ix,iy,ia)) < eps6) s11s(ix,iy,ia) = c0 if (abs(s12s(ix,iy,ia)) < eps6) s12s(ix,iy,ia) = c0 if (abs(s22s(ix,iy,ia)) < eps6) s22s(ix,iy,ia) = c0 endif enddo enddo enddo end subroutine init_eap !======================================================================= ! Function : w1 (see Gaussian function psi in Tsamados et al 2013) FUNCTION w1(a) double precision, intent(in) :: a real (kind=dbl_kind) :: w1 w1 = - 223.87569446_dbl_kind & + 2361.2198663_dbl_kind*a & - 10606.56079975_dbl_kind*a*a & + 26315.50025642_dbl_kind*a*a*a & - 38948.30444297_dbl_kind*a*a*a*a & + 34397.72407466_dbl_kind*a*a*a*a*a & - 16789.98003081_dbl_kind*a*a*a*a*a*a & + 3495.82839237_dbl_kind*a*a*a*a*a*a*a end FUNCTION w1 !======================================================================= ! Function : w2 (see Gaussian function psi in Tsamados et al 2013) FUNCTION w2(a) double precision, intent(in) :: a real (kind=dbl_kind) :: w2 w2 = - 6670.68911883_dbl_kind & + 70222.33061536_dbl_kind*a & - 314871.71525448_dbl_kind*a*a & + 779570.02793492_dbl_kind*a*a*a & - 1151098.82436864_dbl_kind*a*a*a*a & + 1013896.59464498_dbl_kind*a*a*a*a*a & - 493379.44906738_dbl_kind*a*a*a*a*a*a & + 102356.551518_dbl_kind*a*a*a*a*a*a*a end FUNCTION w2 !======================================================================= ! Function : s11kr FUNCTION s11kr(x,y,z,phi) use ice_constants , only: p5, pi, pih, c0, c1, puny real (kind=dbl_kind), intent(in) :: & x,y,z,phi real (kind=dbl_kind) :: & s11kr, p real (kind=dbl_kind) :: & n1t2i11, n1t2i12, n1t2i21, n1t2i22, & n2t1i11, n2t1i12, n2t1i21, n2t1i22, & t1t2i11, t1t2i12, t1t2i21, t1t2i22, & t2t1i11, t2t1i12, t2t1i21, t2t1i22, & d11, d12, d22, & IIn1t2, IIn2t1, IIt1t2, & Hen1t2, Hen2t1 p = phi n1t2i11 = cos(z+pih-p) * cos(z+p) n1t2i12 = cos(z+pih-p) * sin(z+p) n1t2i21 = sin(z+pih-p) * cos(z+p) n1t2i22 = sin(z+pih-p) * sin(z+p) n2t1i11 = cos(z-pih+p) * cos(z-p) n2t1i12 = cos(z-pih+p) * sin(z-p) n2t1i21 = sin(z-pih+p) * cos(z-p) n2t1i22 = sin(z-pih+p) * sin(z-p) t1t2i11 = cos(z-p) * cos(z+p) t1t2i12 = cos(z-p) * sin(z+p) t1t2i21 = sin(z-p) * cos(z+p) t1t2i22 = sin(z-p) * sin(z+p) t2t1i11 = cos(z+p) * cos(z-p) t2t1i12 = cos(z+p) * sin(z-p) t2t1i21 = sin(z+p) * cos(z-p) t2t1i22 = sin(z+p) * sin(z-p) ! In expression of tensor d, with this formulatin d(x)=-d(x+pi) ! Solution, when diagonalizing always check sgn(a11-a22) if > then keep x else x=x-pi/2 d11 = cos(y)*cos(y)*(cos(x)+sin(x)*tan(y)*tan(y)) d12 = cos(y)*cos(y)*tan(y)*(-cos(x)+sin(x)) d22 = cos(y)*cos(y)*(sin(x)+cos(x)*tan(y)*tan(y)) IIn1t2 = n1t2i11 * d11 + (n1t2i12 + n1t2i21) * d12 + n1t2i22 * d22 IIn2t1 = n2t1i11 * d11 + (n2t1i12 + n2t1i21) * d12 + n2t1i22 * d22 IIt1t2 = t1t2i11 * d11 + (t1t2i12 + t1t2i21) * d12 + t1t2i22 * d22 if (-IIn1t2>=puny) then Hen1t2 = c1 else Hen1t2 = c0 endif if (-IIn2t1>=puny) then Hen2t1 = c1 else Hen2t1 = c0 endif s11kr = (- Hen1t2 * n1t2i11 - Hen2t1 * n2t1i11) end FUNCTION s11kr !======================================================================= ! Function : s12kr FUNCTION s12kr(x,y,z,phi) use ice_constants , only: p5, pi, pih, c0, c1, puny real (kind=dbl_kind), intent(in) :: & x,y,z,phi real (kind=dbl_kind) :: & s12kr, s12r0, s21r0, p real (kind=dbl_kind) :: & n1t2i11, n1t2i12, n1t2i21, n1t2i22, & n2t1i11, n2t1i12, n2t1i21, n2t1i22, & t1t2i11, t1t2i12, t1t2i21, t1t2i22, & t2t1i11, t2t1i12, t2t1i21, t2t1i22, & d11, d12, d22, & IIn1t2, IIn2t1, IIt1t2, & Hen1t2, Hen2t1 p = phi n1t2i11 = cos(z+pih-p) * cos(z+p) n1t2i12 = cos(z+pih-p) * sin(z+p) n1t2i21 = sin(z+pih-p) * cos(z+p) n1t2i22 = sin(z+pih-p) * sin(z+p) n2t1i11 = cos(z-pih+p) * cos(z-p) n2t1i12 = cos(z-pih+p) * sin(z-p) n2t1i21 = sin(z-pih+p) * cos(z-p) n2t1i22 = sin(z-pih+p) * sin(z-p) t1t2i11 = cos(z-p) * cos(z+p) t1t2i12 = cos(z-p) * sin(z+p) t1t2i21 = sin(z-p) * cos(z+p) t1t2i22 = sin(z-p) * sin(z+p) t2t1i11 = cos(z+p) * cos(z-p) t2t1i12 = cos(z+p) * sin(z-p) t2t1i21 = sin(z+p) * cos(z-p) t2t1i22 = sin(z+p) * sin(z-p) d11 = cos(y)*cos(y)*(cos(x)+sin(x)*tan(y)*tan(y)) d12 = cos(y)*cos(y)*tan(y)*(-cos(x)+sin(x)) d22 = cos(y)*cos(y)*(sin(x)+cos(x)*tan(y)*tan(y)) IIn1t2 = n1t2i11 * d11 + (n1t2i12 + n1t2i21) * d12 + n1t2i22 * d22 IIn2t1 = n2t1i11 * d11 + (n2t1i12 + n2t1i21) * d12 + n2t1i22 * d22 IIt1t2 = t1t2i11 * d11 + (t1t2i12 + t1t2i21) * d12 + t1t2i22 * d22 if (-IIn1t2>=puny) then Hen1t2 = c1 else Hen1t2 = c0 endif if (-IIn2t1>=puny) then Hen2t1 = c1 else Hen2t1 = c0 endif s12r0 = (- Hen1t2 * n1t2i12 - Hen2t1 * n2t1i12) s21r0 = (- Hen1t2 * n1t2i21 - Hen2t1 * n2t1i21) s12kr=p5*(s12r0+s21r0) end FUNCTION s12kr !======================================================================= ! Function : s22r FUNCTION s22kr(x,y,z,phi) use ice_constants , only: p5, pi, pih, c0, c1, puny real (kind=dbl_kind), intent(in) :: & x,y,z,phi real (kind=dbl_kind) :: & s22kr, p real (kind=dbl_kind) :: & n1t2i11, n1t2i12, n1t2i21, n1t2i22, & n2t1i11, n2t1i12, n2t1i21, n2t1i22, & t1t2i11, t1t2i12, t1t2i21, t1t2i22, & t2t1i11, t2t1i12, t2t1i21, t2t1i22, & d11, d12, d22, & IIn1t2, IIn2t1, IIt1t2, & Hen1t2, Hen2t1 p = phi n1t2i11 = cos(z+pih-p) * cos(z+p) n1t2i12 = cos(z+pih-p) * sin(z+p) n1t2i21 = sin(z+pih-p) * cos(z+p) n1t2i22 = sin(z+pih-p) * sin(z+p) n2t1i11 = cos(z-pih+p) * cos(z-p) n2t1i12 = cos(z-pih+p) * sin(z-p) n2t1i21 = sin(z-pih+p) * cos(z-p) n2t1i22 = sin(z-pih+p) * sin(z-p) t1t2i11 = cos(z-p) * cos(z+p) t1t2i12 = cos(z-p) * sin(z+p) t1t2i21 = sin(z-p) * cos(z+p) t1t2i22 = sin(z-p) * sin(z+p) t2t1i11 = cos(z+p) * cos(z-p) t2t1i12 = cos(z+p) * sin(z-p) t2t1i21 = sin(z+p) * cos(z-p) t2t1i22 = sin(z+p) * sin(z-p) d11 = cos(y)*cos(y)*(cos(x)+sin(x)*tan(y)*tan(y)) d12 = cos(y)*cos(y)*tan(y)*(-cos(x)+sin(x)) d22 = cos(y)*cos(y)*(sin(x)+cos(x)*tan(y)*tan(y)) IIn1t2 = n1t2i11 * d11 + (n1t2i12 + n1t2i21) * d12 + n1t2i22 * d22 IIn2t1 = n2t1i11 * d11 + (n2t1i12 + n2t1i21) * d12 + n2t1i22 * d22 IIt1t2 = t1t2i11 * d11 + (t1t2i12 + t1t2i21) * d12 + t1t2i22 * d22 if (-IIn1t2>=puny) then Hen1t2 = c1 else Hen1t2 = c0 endif if (-IIn2t1>=puny) then Hen2t1 = c1 else Hen2t1 = c0 endif s22kr = (- Hen1t2 * n1t2i22 - Hen2t1 * n2t1i22) end FUNCTION s22kr !======================================================================= ! Function : s11ks FUNCTION s11ks(x,y,z,phi) use ice_constants , only: p5, pi, pih, c0, c1, puny real (kind=dbl_kind), intent(in):: & x,y,z,phi real (kind=dbl_kind) :: & s11ks, p real (kind=dbl_kind) :: & n1t2i11, n1t2i12, n1t2i21, n1t2i22, & n2t1i11, n2t1i12, n2t1i21, n2t1i22, & t1t2i11, t1t2i12, t1t2i21, t1t2i22, & t2t1i11, t2t1i12, t2t1i21, t2t1i22, & d11, d12, d22, & IIn1t2, IIn2t1, IIt1t2, & Hen1t2, Hen2t1 p = phi n1t2i11 = cos(z+pih-p) * cos(z+p) n1t2i12 = cos(z+pih-p) * sin(z+p) n1t2i21 = sin(z+pih-p) * cos(z+p) n1t2i22 = sin(z+pih-p) * sin(z+p) n2t1i11 = cos(z-pih+p) * cos(z-p) n2t1i12 = cos(z-pih+p) * sin(z-p) n2t1i21 = sin(z-pih+p) * cos(z-p) n2t1i22 = sin(z-pih+p) * sin(z-p) t1t2i11 = cos(z-p) * cos(z+p) t1t2i12 = cos(z-p) * sin(z+p) t1t2i21 = sin(z-p) * cos(z+p) t1t2i22 = sin(z-p) * sin(z+p) t2t1i11 = cos(z+p) * cos(z-p) t2t1i12 = cos(z+p) * sin(z-p) t2t1i21 = sin(z+p) * cos(z-p) t2t1i22 = sin(z+p) * sin(z-p) d11 = cos(y)*cos(y)*(cos(x)+sin(x)*tan(y)*tan(y)) d12 = cos(y)*cos(y)*tan(y)*(-cos(x)+sin(x)) d22 = cos(y)*cos(y)*(sin(x)+cos(x)*tan(y)*tan(y)) IIn1t2 = n1t2i11 * d11 + (n1t2i12 + n1t2i21) * d12 + n1t2i22 * d22 IIn2t1 = n2t1i11 * d11 + (n2t1i12 + n2t1i21) * d12 + n2t1i22 * d22 IIt1t2 = t1t2i11 * d11 + (t1t2i12 + t1t2i21) * d12 + t1t2i22 * d22 if (-IIn1t2>=puny) then Hen1t2 = c1 else Hen1t2 = c0 endif if (-IIn2t1>=puny) then Hen2t1 = c1 else Hen2t1 = c0 endif s11ks = sign(c1,IIt1t2+puny)*(Hen1t2 * t1t2i11 + Hen2t1 * t2t1i11) end FUNCTION s11ks !======================================================================= ! Function : s12ks FUNCTION s12ks(x,y,z,phi) use ice_constants , only: p5, pi, pih, c0, c1, puny real (kind=dbl_kind), intent(in) :: & x,y,z,phi real (kind=dbl_kind) :: & s12ks,s12s0,s21s0,p real (kind=dbl_kind) :: & n1t2i11, n1t2i12, n1t2i21, n1t2i22, & n2t1i11, n2t1i12, n2t1i21, n2t1i22, & t1t2i11, t1t2i12, t1t2i21, t1t2i22, & t2t1i11, t2t1i12, t2t1i21, t2t1i22, & d11, d12, d22, & IIn1t2, IIn2t1, IIt1t2, & Hen1t2, Hen2t1 p =phi n1t2i11 = cos(z+pih-p) * cos(z+p) n1t2i12 = cos(z+pih-p) * sin(z+p) n1t2i21 = sin(z+pih-p) * cos(z+p) n1t2i22 = sin(z+pih-p) * sin(z+p) n2t1i11 = cos(z-pih+p) * cos(z-p) n2t1i12 = cos(z-pih+p) * sin(z-p) n2t1i21 = sin(z-pih+p) * cos(z-p) n2t1i22 = sin(z-pih+p) * sin(z-p) t1t2i11 = cos(z-p) * cos(z+p) t1t2i12 = cos(z-p) * sin(z+p) t1t2i21 = sin(z-p) * cos(z+p) t1t2i22 = sin(z-p) * sin(z+p) t2t1i11 = cos(z+p) * cos(z-p) t2t1i12 = cos(z+p) * sin(z-p) t2t1i21 = sin(z+p) * cos(z-p) t2t1i22 = sin(z+p) * sin(z-p) d11 = cos(y)*cos(y)*(cos(x)+sin(x)*tan(y)*tan(y)) d12 = cos(y)*cos(y)*tan(y)*(-cos(x)+sin(x)) d22 = cos(y)*cos(y)*(sin(x)+cos(x)*tan(y)*tan(y)) IIn1t2 = n1t2i11 * d11 + (n1t2i12 + n1t2i21) * d12 + n1t2i22 * d22 IIn2t1 = n2t1i11 * d11 + (n2t1i12 + n2t1i21) * d12 + n2t1i22 * d22 IIt1t2 = t1t2i11 * d11 + (t1t2i12 + t1t2i21) * d12 + t1t2i22 * d22 if (-IIn1t2>=puny) then Hen1t2 = c1 else Hen1t2 = c0 endif if (-IIn2t1>=puny) then Hen2t1 = c1 else Hen2t1 = c0 endif s12s0 = sign(c1,IIt1t2+puny)*(Hen1t2 * t1t2i12 + Hen2t1 * t2t1i12) s21s0 = sign(c1,IIt1t2+puny)*(Hen1t2 * t1t2i21 + Hen2t1 * t2t1i21) s12ks=p5*(s12s0+s21s0) end FUNCTION s12ks !======================================================================= ! Function : s22ks FUNCTION s22ks(x,y,z,phi) use ice_constants , only: p5, pi, pih, c0, c1, puny real (kind=dbl_kind), intent(in) :: & x,y,z,phi real (kind=dbl_kind) :: & s22ks,p real (kind=dbl_kind) :: & n1t2i11, n1t2i12, n1t2i21, n1t2i22, & n2t1i11, n2t1i12, n2t1i21, n2t1i22, & t1t2i11, t1t2i12, t1t2i21, t1t2i22, & t2t1i11, t2t1i12, t2t1i21, t2t1i22, & d11, d12, d22, & IIn1t2, IIn2t1, IIt1t2, & Hen1t2, Hen2t1 p = phi n1t2i11 = cos(z+pih-p) * cos(z+p) n1t2i12 = cos(z+pih-p) * sin(z+p) n1t2i21 = sin(z+pih-p) * cos(z+p) n1t2i22 = sin(z+pih-p) * sin(z+p) n2t1i11 = cos(z-pih+p) * cos(z-p) n2t1i12 = cos(z-pih+p) * sin(z-p) n2t1i21 = sin(z-pih+p) * cos(z-p) n2t1i22 = sin(z-pih+p) * sin(z-p) t1t2i11 = cos(z-p) * cos(z+p) t1t2i12 = cos(z-p) * sin(z+p) t1t2i21 = sin(z-p) * cos(z+p) t1t2i22 = sin(z-p) * sin(z+p) t2t1i11 = cos(z+p) * cos(z-p) t2t1i12 = cos(z+p) * sin(z-p) t2t1i21 = sin(z+p) * cos(z-p) t2t1i22 = sin(z+p) * sin(z-p) d11 = cos(y)*cos(y)*(cos(x)+sin(x)*tan(y)*tan(y)) d12 = cos(y)*cos(y)*tan(y)*(-cos(x)+sin(x)) d22 = cos(y)*cos(y)*(sin(x)+cos(x)*tan(y)*tan(y)) IIn1t2 = n1t2i11 * d11 + (n1t2i12 + n1t2i21) * d12 + n1t2i22 * d22 IIn2t1 = n2t1i11 * d11 + (n2t1i12 + n2t1i21) * d12 + n2t1i22 * d22 IIt1t2 = t1t2i11 * d11 + (t1t2i12 + t1t2i21) * d12 + t1t2i22 * d22 if (-IIn1t2>=puny) then Hen1t2 = c1 else Hen1t2 = c0 endif if (-IIn2t1>=puny) then Hen2t1 = c1 else Hen2t1 = c0 endif s22ks = sign(c1,IIt1t2+puny)*(Hen1t2 * t1t2i22 + Hen2t1 * t2t1i22) end FUNCTION s22ks !======================================================================= ! Computes the rates of strain and internal stress components for ! each of the four corners on each T-grid cell. ! Computes stress terms for the momentum equation ! (based on subroutine stress) subroutine stress_eap (nx_block, ny_block, & ksub, ndte, & icellt, & indxti, indxtj, & arlx1i, denom1, & uvel, vvel, & dxt, dyt, & dxhy, dyhx, & cxp, cyp, & cxm, cym, & tarear, strength, & a11, a12, & a11_1, a11_2, a11_3, a11_4, & a12_1, a12_2, a12_3, a12_4, & stressp_1, stressp_2, & stressp_3, stressp_4, & stressm_1, stressm_2, & stressm_3, stressm_4, & stress12_1, stress12_2, & stress12_3, stress12_4, & shear, divu, & e11, e12, & e22, & s11, s12, & s22, & yieldstress11, & yieldstress12, & yieldstress22, & prs_sig, & rdg_conv, rdg_shear, & strtmp) use ice_constants, only: c0, p027, p055, p111, p166, & p2, p222, p25, p333, p5, puny !echmod tmp ! use ice_timers, only: & ! ice_timer_start, ice_timer_stop, & ! timer_tmp1, timer_tmp2, timer_tmp3 integer (kind=int_kind), intent(in) :: & nx_block, ny_block, & ! block dimensions ksub , & ! subcycling step ndte , & ! number of subcycles icellt ! no. of cells where icetmask = 1 integer (kind=int_kind), dimension (nx_block*ny_block), & intent(in) :: & indxti , & ! compressed index in i-direction indxtj ! compressed index in j-direction real (kind=dbl_kind), intent(in) :: & arlx1i , & ! dte/2T (original) or 1/alpha1 (revised) denom1 ! constant for stress equation real (kind=dbl_kind), dimension (nx_block,ny_block), intent(in) :: & strength , & ! ice strength (N/m) uvel , & ! x-component of velocity (m/s) vvel , & ! y-component of velocity (m/s) dxt , & ! width of T-cell through the middle (m) dyt , & ! height of T-cell through the middle (m) dxhy , & ! 0.5*(HTE - HTE) dyhx , & ! 0.5*(HTN - HTN) cyp , & ! 1.5*HTE - 0.5*HTE cxp , & ! 1.5*HTN - 0.5*HTN cym , & ! 0.5*HTE - 1.5*HTE cxm , & ! 0.5*HTN - 1.5*HTN tarear ! 1/tarea real (kind=dbl_kind), dimension (nx_block,ny_block), & intent(inout) :: & stressp_1, stressp_2, stressp_3, stressp_4, & ! sigma11+sigma22 stressm_1, stressm_2, stressm_3, stressm_4, & ! sigma11-sigma22 stress12_1,stress12_2,stress12_3,stress12_4 ! sigma12 real (kind=dbl_kind), dimension (nx_block,ny_block), & intent(inout) :: & a11, a12, a11_1, a11_2, a11_3, a11_4, & ! structure tensor a12_1, a12_2, a12_3, a12_4 ! structure tensor real (kind=dbl_kind), dimension (nx_block,ny_block), & intent(inout) :: & prs_sig , & ! replacement pressure, for stress calc shear , & ! strain rate II component (1/s) divu , & ! strain rate I component, velocity divergence (1/s) e11 , & ! components of strain rate tensor (1/s) e12 , & ! e22 , & ! s11 , & ! components of stress tensor (kg/s^2) s12 , & ! s22 , & ! yieldstress11, & ! components of yield stress tensor (kg/s^2) yieldstress12, & yieldstress22, & rdg_conv , & ! convergence term for ridging (1/s) rdg_shear ! shear term for ridging (1/s) real (kind=dbl_kind), dimension(nx_block,ny_block,8), & intent(out) :: & strtmp ! stress combinations ! local variables integer (kind=int_kind) :: & i, j, ij real (kind=dbl_kind) :: & stressptmp_1, stressptmp_2, stressptmp_3, stressptmp_4, & ! sigma11+sigma22 stressmtmp_1, stressmtmp_2, stressmtmp_3, stressmtmp_4, & ! sigma11-sigma22 stress12tmp_1,stress12tmp_2,stress12tmp_3,stress12tmp_4 ! sigma12 real (kind=dbl_kind) :: & divune, divunw, divuse, divusw , & ! divergence tensionne, tensionnw, tensionse, tensionsw, & ! tension shearne, shearnw, shearse, shearsw , & ! shearing ssigpn, ssigps, ssigpe, ssigpw , & ssigmn, ssigms, ssigme, ssigmw , & ssig12n, ssig12s, ssig12e, ssig12w , & ssigp1, ssigp2, ssigm1, ssigm2, ssig121, ssig122, & csigpne, csigpnw, csigpse, csigpsw , & csigmne, csigmnw, csigmse, csigmsw , & csig12ne, csig12nw, csig12se, csig12sw , & str12ew, str12we, str12ns, str12sn , & strp_tmp, strm_tmp real (kind=dbl_kind) :: & alpharne, alpharnw, alpharsw, alpharse, & alphasne, alphasnw, alphassw, alphasse !----------------------------------------------------------------- ! Initialize !----------------------------------------------------------------- strtmp(:,:,:) = c0 !DIR$ CONCURRENT !Cray !cdir nodep !NEC !ocl novrec !Fujitsu do ij = 1, icellt i = indxti(ij) j = indxtj(ij) !----------------------------------------------------------------- ! strain rates ! NOTE these are actually strain rates * area (m^2/s) !----------------------------------------------------------------- ! divergence = e_11 + e_22 divune = cyp(i,j)*uvel(i ,j ) - dyt(i,j)*uvel(i-1,j ) & + cxp(i,j)*vvel(i ,j ) - dxt(i,j)*vvel(i ,j-1) divunw = cym(i,j)*uvel(i-1,j ) + dyt(i,j)*uvel(i ,j ) & + cxp(i,j)*vvel(i-1,j ) - dxt(i,j)*vvel(i-1,j-1) divusw = cym(i,j)*uvel(i-1,j-1) + dyt(i,j)*uvel(i ,j-1) & + cxm(i,j)*vvel(i-1,j-1) + dxt(i,j)*vvel(i-1,j ) divuse = cyp(i,j)*uvel(i ,j-1) - dyt(i,j)*uvel(i-1,j-1) & + cxm(i,j)*vvel(i ,j-1) + dxt(i,j)*vvel(i ,j ) ! tension strain rate = e_11 - e_22 tensionne = -cym(i,j)*uvel(i ,j ) - dyt(i,j)*uvel(i-1,j ) & + cxm(i,j)*vvel(i ,j ) + dxt(i,j)*vvel(i ,j-1) tensionnw = -cyp(i,j)*uvel(i-1,j ) + dyt(i,j)*uvel(i ,j ) & + cxm(i,j)*vvel(i-1,j ) + dxt(i,j)*vvel(i-1,j-1) tensionsw = -cyp(i,j)*uvel(i-1,j-1) + dyt(i,j)*uvel(i ,j-1) & + cxp(i,j)*vvel(i-1,j-1) - dxt(i,j)*vvel(i-1,j ) tensionse = -cym(i,j)*uvel(i ,j-1) - dyt(i,j)*uvel(i-1,j-1) & + cxp(i,j)*vvel(i ,j-1) - dxt(i,j)*vvel(i ,j ) ! shearing strain rate = e_12 shearne = -cym(i,j)*vvel(i ,j ) - dyt(i,j)*vvel(i-1,j ) & - cxm(i,j)*uvel(i ,j ) - dxt(i,j)*uvel(i ,j-1) shearnw = -cyp(i,j)*vvel(i-1,j ) + dyt(i,j)*vvel(i ,j ) & - cxm(i,j)*uvel(i-1,j ) - dxt(i,j)*uvel(i-1,j-1) shearsw = -cyp(i,j)*vvel(i-1,j-1) + dyt(i,j)*vvel(i ,j-1) & - cxp(i,j)*uvel(i-1,j-1) + dxt(i,j)*uvel(i-1,j ) shearse = -cym(i,j)*vvel(i ,j-1) - dyt(i,j)*vvel(i-1,j-1) & - cxp(i,j)*uvel(i ,j-1) + dxt(i,j)*uvel(i ,j ) !----------------------------------------------------------------- ! Stress updated depending on strain rate and structure tensor !----------------------------------------------------------------- ! call ice_timer_start(timer_tmp2) ! dynamics ! ne call update_stress_rdg (ksub, ndte, divune, tensionne, & shearne, a11_1(i,j), a12_1(i,j), & stressptmp_1, stressmtmp_1, & stress12tmp_1, strength(i,j), & alpharne, alphasne) ! nw call update_stress_rdg (ksub, ndte, divunw, tensionnw, & shearnw, a11_2(i,j), a12_2(i,j), & stressptmp_2, stressmtmp_2, & stress12tmp_2, strength(i,j), & alpharnw, alphasnw) ! sw call update_stress_rdg (ksub, ndte, divusw, tensionsw, & shearsw, a11_3(i,j), a12_3(i,j), & stressptmp_3, stressmtmp_3, & stress12tmp_3, strength(i,j), & alpharsw, alphassw) ! se call update_stress_rdg (ksub, ndte, divuse, tensionse, & shearse, a11_4(i,j), a12_4(i,j), & stressptmp_4, stressmtmp_4, & stress12tmp_4, strength(i,j), & alpharse, alphasse) ! call ice_timer_stop(timer_tmp2) ! dynamics !----------------------------------------------------------------- ! on last subcycle, save quantities for mechanical redistribution !----------------------------------------------------------------- if (ksub == ndte) then ! diagnostic only ! shear = sqrt(tension**2 + shearing**2) shear(i,j) = p25*tarear(i,j)*sqrt( & (tensionne + tensionnw + tensionse + tensionsw)**2 & + (shearne + shearnw + shearse + shearsw)**2) divu(i,j) = p25*(divune + divunw + divuse + divusw) * tarear(i,j) rdg_conv(i,j) = -min(p25*(alpharne + alpharnw & + alpharsw + alpharse),c0) * tarear(i,j) !rdg_shear=0 for computing closing_net in ridge_prep !rdg_shear(i,j) = p25*(alphasne + alphasnw & ! + alphassw + alphasse) * tarear(i,j) endif e11(i,j) = p5*p25*(divune + divunw + divuse + divusw + & tensionne + tensionnw + tensionse + tensionsw) * tarear(i,j) e12(i,j) = p5*p25*(shearne + shearnw + shearse + shearsw) * tarear(i,j) e22(i,j) = p5*p25*(divune + divunw + divuse + divusw - & tensionne - tensionnw - tensionse - tensionsw) * tarear(i,j) prs_sig(i,j) = strength(i,j) !----------------------------------------------------------------- ! elastic relaxation, see Eq. A12-A14 !----------------------------------------------------------------- stressp_1(i,j) = (stressp_1(i,j) + stressptmp_1*arlx1i) & * denom1 stressp_2(i,j) = (stressp_2(i,j) + stressptmp_2*arlx1i) & * denom1 stressp_3(i,j) = (stressp_3(i,j) + stressptmp_3*arlx1i) & * denom1 stressp_4(i,j) = (stressp_4(i,j) + stressptmp_4*arlx1i) & * denom1 stressm_1(i,j) = (stressm_1(i,j) + stressmtmp_1*arlx1i) & * denom1 stressm_2(i,j) = (stressm_2(i,j) + stressmtmp_2*arlx1i) & * denom1 stressm_3(i,j) = (stressm_3(i,j) + stressmtmp_3*arlx1i) & * denom1 stressm_4(i,j) = (stressm_4(i,j) + stressmtmp_4*arlx1i) & * denom1 stress12_1(i,j) = (stress12_1(i,j) + stress12tmp_1*arlx1i) & * denom1 stress12_2(i,j) = (stress12_2(i,j) + stress12tmp_2*arlx1i) & * denom1 stress12_3(i,j) = (stress12_3(i,j) + stress12tmp_3*arlx1i) & * denom1 stress12_4(i,j) = (stress12_4(i,j) + stress12tmp_4*arlx1i) & * denom1 s11(i,j) = p5 * p25 * (stressp_1(i,j) + stressp_2(i,j) & + stressp_3(i,j) + stressp_4(i,j) & + stressm_1(i,j) + stressm_2(i,j) & + stressm_3(i,j) + stressm_4(i,j)) s22(i,j) = p5 * p25 * (stressp_1(i,j) + stressp_2(i,j) & + stressp_3(i,j) + stressp_4(i,j) & - stressm_1(i,j) - stressm_2(i,j) & - stressm_3(i,j) - stressm_4(i,j)) s12(i,j) = p25 * (stress12_1(i,j) + stress12_2(i,j) & + stress12_3(i,j) + stress12_4(i,j)) yieldstress11(i,j) = p5 * p25 * (stressptmp_1 + stressptmp_2 & + stressptmp_3 + stressptmp_4 & + stressmtmp_1 + stressmtmp_2 & + stressmtmp_3 + stressmtmp_4) yieldstress22(i,j) = p5 * p25 * (stressptmp_1 + stressptmp_2 & + stressptmp_3 + stressptmp_4 & - stressmtmp_1 - stressmtmp_2 & - stressmtmp_3 - stressmtmp_4) yieldstress12(i,j) = p25 * (stress12tmp_1 + stress12tmp_2 & + stress12tmp_3 + stress12tmp_4) !----------------------------------------------------------------- ! Eliminate underflows. ! The following code is commented out because it is relatively ! expensive and most compilers include a flag that accomplishes ! the same thing more efficiently. This code is cheaper than ! handling underflows if the compiler lacks a flag; uncomment ! it in that case. The compiler flag is often described with the ! phrase "flush to zero". !----------------------------------------------------------------- ! stressp_1(i,j) = sign(max(abs(stressp_1(i,j)),puny),stressp_1(i,j)) ! stressp_2(i,j) = sign(max(abs(stressp_2(i,j)),puny),stressp_2(i,j)) ! stressp_3(i,j) = sign(max(abs(stressp_3(i,j)),puny),stressp_3(i,j)) ! stressp_4(i,j) = sign(max(abs(stressp_4(i,j)),puny),stressp_4(i,j)) ! stressm_1(i,j) = sign(max(abs(stressm_1(i,j)),puny),stressm_1(i,j)) ! stressm_2(i,j) = sign(max(abs(stressm_2(i,j)),puny),stressm_2(i,j)) ! stressm_3(i,j) = sign(max(abs(stressm_3(i,j)),puny),stressm_3(i,j)) ! stressm_4(i,j) = sign(max(abs(stressm_4(i,j)),puny),stressm_4(i,j)) ! stress12_1(i,j) = sign(max(abs(stress12_1(i,j)),puny),stress12_1(i,j)) ! stress12_2(i,j) = sign(max(abs(stress12_2(i,j)),puny),stress12_2(i,j)) ! stress12_3(i,j) = sign(max(abs(stress12_3(i,j)),puny),stress12_3(i,j)) ! stress12_4(i,j) = sign(max(abs(stress12_4(i,j)),puny),stress12_4(i,j)) !----------------------------------------------------------------- ! combinations of the stresses for the momentum equation ! kg/s^2 !----------------------------------------------------------------- ssigpn = stressp_1(i,j) + stressp_2(i,j) ssigps = stressp_3(i,j) + stressp_4(i,j) ssigpe = stressp_1(i,j) + stressp_4(i,j) ssigpw = stressp_2(i,j) + stressp_3(i,j) ssigp1 =(stressp_1(i,j) + stressp_3(i,j))*p055 ssigp2 =(stressp_2(i,j) + stressp_4(i,j))*p055 ssigmn = stressm_1(i,j) + stressm_2(i,j) ssigms = stressm_3(i,j) + stressm_4(i,j) ssigme = stressm_1(i,j) + stressm_4(i,j) ssigmw = stressm_2(i,j) + stressm_3(i,j) ssigm1 =(stressm_1(i,j) + stressm_3(i,j))*p055 ssigm2 =(stressm_2(i,j) + stressm_4(i,j))*p055 ssig12n = stress12_1(i,j) + stress12_2(i,j) ssig12s = stress12_3(i,j) + stress12_4(i,j) ssig12e = stress12_1(i,j) + stress12_4(i,j) ssig12w = stress12_2(i,j) + stress12_3(i,j) ssig121 =(stress12_1(i,j) + stress12_3(i,j))*p111 ssig122 =(stress12_2(i,j) + stress12_4(i,j))*p111 csigpne = p111*stressp_1(i,j) + ssigp2 + p027*stressp_3(i,j) csigpnw = p111*stressp_2(i,j) + ssigp1 + p027*stressp_4(i,j) csigpsw = p111*stressp_3(i,j) + ssigp2 + p027*stressp_1(i,j) csigpse = p111*stressp_4(i,j) + ssigp1 + p027*stressp_2(i,j) csigmne = p111*stressm_1(i,j) + ssigm2 + p027*stressm_3(i,j) csigmnw = p111*stressm_2(i,j) + ssigm1 + p027*stressm_4(i,j) csigmsw = p111*stressm_3(i,j) + ssigm2 + p027*stressm_1(i,j) csigmse = p111*stressm_4(i,j) + ssigm1 + p027*stressm_2(i,j) csig12ne = p222*stress12_1(i,j) + ssig122 & + p055*stress12_3(i,j) csig12nw = p222*stress12_2(i,j) + ssig121 & + p055*stress12_4(i,j) csig12sw = p222*stress12_3(i,j) + ssig122 & + p055*stress12_1(i,j) csig12se = p222*stress12_4(i,j) + ssig121 & + p055*stress12_2(i,j) str12ew = p5*dxt(i,j)*(p333*ssig12e + p166*ssig12w) str12we = p5*dxt(i,j)*(p333*ssig12w + p166*ssig12e) str12ns = p5*dyt(i,j)*(p333*ssig12n + p166*ssig12s) str12sn = p5*dyt(i,j)*(p333*ssig12s + p166*ssig12n) !----------------------------------------------------------------- ! for dF/dx (u momentum) !----------------------------------------------------------------- strp_tmp = p25*dyt(i,j)*(p333*ssigpn + p166*ssigps) strm_tmp = p25*dyt(i,j)*(p333*ssigmn + p166*ssigms) ! northeast (i,j) strtmp(i,j,1) = -strp_tmp - strm_tmp - str12ew & + dxhy(i,j)*(-csigpne + csigmne) + dyhx(i,j)*csig12ne ! northwest (i+1,j) strtmp(i,j,2) = strp_tmp + strm_tmp - str12we & + dxhy(i,j)*(-csigpnw + csigmnw) + dyhx(i,j)*csig12nw strp_tmp = p25*dyt(i,j)*(p333*ssigps + p166*ssigpn) strm_tmp = p25*dyt(i,j)*(p333*ssigms + p166*ssigmn) ! southeast (i,j+1) strtmp(i,j,3) = -strp_tmp - strm_tmp + str12ew & + dxhy(i,j)*(-csigpse + csigmse) + dyhx(i,j)*csig12se ! southwest (i+1,j+1) strtmp(i,j,4) = strp_tmp + strm_tmp + str12we & + dxhy(i,j)*(-csigpsw + csigmsw) + dyhx(i,j)*csig12sw !----------------------------------------------------------------- ! for dF/dy (v momentum) !----------------------------------------------------------------- strp_tmp = p25*dxt(i,j)*(p333*ssigpe + p166*ssigpw) strm_tmp = p25*dxt(i,j)*(p333*ssigme + p166*ssigmw) ! northeast (i,j) strtmp(i,j,5) = -strp_tmp + strm_tmp - str12ns & - dyhx(i,j)*(csigpne + csigmne) + dxhy(i,j)*csig12ne ! southeast (i,j+1) strtmp(i,j,6) = strp_tmp - strm_tmp - str12sn & - dyhx(i,j)*(csigpse + csigmse) + dxhy(i,j)*csig12se strp_tmp = p25*dxt(i,j)*(p333*ssigpw + p166*ssigpe) strm_tmp = p25*dxt(i,j)*(p333*ssigmw + p166*ssigme) ! northwest (i+1,j) strtmp(i,j,7) = -strp_tmp + strm_tmp + str12ns & - dyhx(i,j)*(csigpnw + csigmnw) + dxhy(i,j)*csig12nw ! southwest (i+1,j+1) strtmp(i,j,8) = strp_tmp - strm_tmp + str12sn & - dyhx(i,j)*(csigpsw + csigmsw) + dxhy(i,j)*csig12sw enddo ! ij end subroutine stress_eap !======================================================================= ! Updates the stress depending on values of strain rate and structure ! tensor and for ksub=ndte it computes closing and sliding rate subroutine update_stress_rdg (ksub, ndte, divu, tension, & shear, a11, a12, & stressp, stressm, & stress12, strength, & alphar, alphas) use ice_constants, only: c0, p025, p05, p1, p5, c1, c2, c12, puny, & pi, pih, pi2, piq integer (kind=int_kind), intent(in) :: & ksub, & ndte real (kind=dbl_kind), intent(in) :: & a11, a12, & divu, tension, shear, & strength real (kind=dbl_kind), intent(out) :: & stressp, stressm, stress12, & alphar, alphas ! local variables integer (kind=int_kind) :: & kx ,ky, ka real (kind=dbl_kind) :: & stemp11r, stemp12r, stemp22r, & stemp11s, stemp12s, stemp22s, & a22, Q11, Q12, Qd11, Qd12, & Q11Q11, Q11Q12, Q12Q12, & dtemp11, dtemp12, dtemp22, & fxinvdx, fyinvdy, fainvda, & mfxinvdx, mfyinvdy, mfainvda, & fff, ffm, fmm, mmm, mmf, mff, fmf, mfm, & rotstemp11r, rotstemp12r, rotstemp22r, & rotstemp11s, rotstemp12s, rotstemp22s, & sig11, sig12, sig22, & sgprm11, sgprm12, sgprm22, & invstressconviso, & gamma, alpha, x, y, dx, dy, da, & invdx, invdy, invda, invsin, & invleng, dtemp1, dtemp2, atempprime, a real (kind=dbl_kind), parameter :: & kfriction = 0.45_dbl_kind ! Factor to maintain the same stress as in EVP (see Section 3) ! Can be set to 1 otherwise invstressconviso = c1/(c1+kfriction*kfriction) invsin = c1/sin(pi2/c12) * invstressconviso ! compute eigenvalues, eigenvectors and angles for structure tensor, strain rates ! 1) structure tensor a22 = c1-a11 ! gamma: angle between general coordiantes and principal axis gamma = p5*atan2((c2*a12),(a11 - a22)) ! rotational tensor from general coordinates into principal axis Q11 = cos(gamma) Q12 = sin(gamma) Q11Q11 = Q11*Q11 Q11Q12 = Q11*Q12 Q12Q12 = Q12*Q12 ! rotation Q*atemp*Q^T atempprime = Q11Q11*a11 + c2*Q11Q12*a12 + Q12Q12*a22 ! make first principal value the largest atempprime = max(atempprime, c1 - atempprime) ! 2) strain rate dtemp11 = p5*(divu + tension) dtemp12 = shear*p5 dtemp22 = p5*(divu - tension) ! alpha: angle between general coordiantes and principal axis alpha = p5*atan2((c2*dtemp12),(dtemp11 - dtemp22)) ! y: angle between major principal axis of strain rate and structure tensor ! to make sure y between 0 and pi/2 if (alpha > gamma) alpha = alpha - pi if (alpha < gamma-pi) alpha = alpha + pi y = gamma - alpha !echmod require 0 <= y < (ny_yield-1)*dy = pi/2 ! y = mod(y+pi2, pih) !echmod require 0 <= y < (ny_yield-1)*dy = pi ! y = mod(y+pi2, pi) ! alpha = gamma - y ! rotate tensor (anticlockwise) from general coordinates into principal axis Qd11 = cos(alpha) Qd12 = sin(alpha) dtemp1 = Qd11*(Qd11*dtemp11 + c2*Qd12*dtemp12) + Qd12*Qd12*dtemp22 dtemp2 = Qd12*(Qd12*dtemp11 - c2*Qd11*dtemp12) + Qd11*Qd11*dtemp22 x = c0 ! In cos and sin values if ((ABS(dtemp1) > puny).or.(ABS(dtemp2) > puny)) then invleng = c1/sqrt(dtemp1*dtemp1 + dtemp2*dtemp2) dtemp1 = dtemp1*invleng dtemp2 = dtemp2*invleng x = atan2(dtemp2,dtemp1) endif !echmod to ensure the angle lies between pi/4 and 9 pi/4 if (x < piq) x = x + pi2 !echmod require 0 <= x < (nx_yield-1)*dx = 2 pi ! x = mod(x+pi2, pi2) ! Now calculate updated stress tensor dx = pi/real(nx_yield-1,kind=dbl_kind) dy = pi/real(ny_yield-1,kind=dbl_kind) da = p5/real(na_yield-1,kind=dbl_kind) invdx = c1/dx invdy = c1/dy invda = c1/da kx = int((x-piq-pi)*invdx) + 1 ky = int(y*invdy) + 1 ka = int((atempprime-p5)*invda) + 1 ! Determine sigma_r(A1,Zeta,y) and sigma_s (see Section A1) stemp11r = s11r(kx,ky,ka) stemp12r = s12r(kx,ky,ka) stemp22r = s22r(kx,ky,ka) stemp11s = s11s(kx,ky,ka) stemp12s = s12s(kx,ky,ka) stemp22s = s22s(kx,ky,ka) ! Calculate mean ice stress over a collection of floes (Equation 3) stressp = strength*(stemp11r + kfriction*stemp11s & + stemp22r + kfriction*stemp22s) * invsin stress12 = strength*(stemp12r + kfriction*stemp12s) * invsin stressm = strength*(stemp11r + kfriction*stemp11s & - stemp22r - kfriction*stemp22s) * invsin ! Back - rotation of the stress from principal axes into general coordinates ! Update stress sig11 = p5*(stressp + stressm) sig12 = stress12 sig22 = p5*(stressp - stressm) sgprm11 = Q11Q11*sig11 + Q12Q12*sig22 - c2*Q11Q12 *sig12 sgprm12 = Q11Q12*sig11 - Q11Q12*sig22 + (Q11Q11 - Q12Q12)*sig12 sgprm22 = Q12Q12*sig11 + Q11Q11*sig22 + c2*Q11Q12 *sig12 stressp = sgprm11 + sgprm22 stress12 = sgprm12 stressm = sgprm11 - sgprm22 ! Compute ridging and sliding functions in general coordinates (Equation 11) if (ksub == ndte) then rotstemp11r = Q11Q11*stemp11r - c2*Q11Q12* stemp12r & + Q12Q12*stemp22r rotstemp12r = Q11Q11*stemp12r + Q11Q12*(stemp11r-stemp22r) & - Q12Q12*stemp12r rotstemp22r = Q12Q12*stemp11r + c2*Q11Q12* stemp12r & + Q11Q11*stemp22r rotstemp11s = Q11Q11*stemp11s - c2*Q11Q12* stemp12s & + Q12Q12*stemp22s rotstemp12s = Q11Q11*stemp12s + Q11Q12*(stemp11s-stemp22s) & - Q12Q12*stemp12s rotstemp22s = Q12Q12*stemp11s + c2*Q11Q12* stemp12s & + Q11Q11*stemp22s alphar = rotstemp11r*dtemp11 + c2*rotstemp12r*dtemp12 & + rotstemp22r*dtemp22 alphas = rotstemp11s*dtemp11 + c2*rotstemp12s*dtemp12 & + rotstemp22s*dtemp22 endif end subroutine update_stress_rdg !======================================================================= ! Solves evolution equation for structure tensor (A19, A20) subroutine stepa (nx_block, ny_block, & dtei, icellt, & indxti, indxtj, & a11, a12, & a11_1, a11_2, a11_3, a11_4, & a12_1, a12_2, a12_3, a12_4, & stressp_1, stressp_2, & stressp_3, stressp_4, & stressm_1, stressm_2, & stressm_3, stressm_4, & stress12_1, stress12_2, & stress12_3, stress12_4) use ice_constants, only: p001, p2, p25, p5, c1 integer (kind=int_kind), intent(in) :: & nx_block, ny_block, & ! block dimensions icellt ! no. of cells where icetmask = 1 real (kind=dbl_kind), intent(in) :: & dtei ! 1/dte, where dte is subcycling timestep (1/s) integer (kind=int_kind), dimension (nx_block*ny_block), & intent(in) :: & indxti , & ! compressed index in i-direction indxtj ! compressed index in j-direction real (kind=dbl_kind), dimension (nx_block,ny_block), & intent(in) :: & ! ice stress tensor (kg/s^2) in each corner of T cell stressp_1, stressp_2, stressp_3, stressp_4, & ! sigma11+sigma22 stressm_1, stressm_2, stressm_3, stressm_4, & ! sigma11-sigma22 stress12_1, stress12_2, stress12_3, stress12_4 ! sigma12 real (kind=dbl_kind), dimension (nx_block,ny_block), & intent(inout) :: & ! structure tensor () in each corner of T cell a11, a12, a11_1, a11_2, a11_3, a11_4, & ! components of a12_1, a12_2, a12_3, a12_4 ! structure tensor () ! local variables integer (kind=int_kind) :: & i, j, ij real (kind=dbl_kind) :: & mresult11, mresult12, & dteikth, p5kth real (kind=dbl_kind), parameter :: & kth = p2*p001 dteikth = c1 / (dtei + kth) p5kth = p5 * kth do ij = 1, icellt i = indxti(ij) j = indxtj(ij) ! ne call calc_ffrac(1, stressp_1(i,j), stressm_1(i,j), & stress12_1(i,j), & a11_1(i,j), & mresult11) call calc_ffrac(2, stressp_1(i,j), stressm_1(i,j), & stress12_1(i,j), & a12_1(i,j), & mresult12) a11_1(i,j) = (a11_1(i,j)*dtei + p5kth - mresult11) * dteikth ! implicit a12_1(i,j) = (a12_1(i,j)*dtei - mresult12) * dteikth ! implicit ! nw call calc_ffrac(1, stressp_2(i,j), stressm_2(i,j), & stress12_2(i,j), & a11_2(i,j), & mresult11) call calc_ffrac(2, stressp_2(i,j), stressm_2(i,j), & stress12_2(i,j), & a12_2(i,j), & mresult12) a11_2(i,j) = (a11_2(i,j)*dtei + p5kth - mresult11) * dteikth ! implicit a12_2(i,j) = (a12_2(i,j)*dtei - mresult12) * dteikth ! implicit ! sw call calc_ffrac(1, stressp_3(i,j), stressm_3(i,j), & stress12_3(i,j), & a11_3(i,j), & mresult11) call calc_ffrac(2, stressp_3(i,j), stressm_3(i,j), & stress12_3(i,j), & a12_3(i,j), & mresult12) a11_3(i,j) = (a11_3(i,j)*dtei + p5kth - mresult11) * dteikth ! implicit a12_3(i,j) = (a12_3(i,j)*dtei - mresult12) * dteikth ! implicit ! se call calc_ffrac(1, stressp_4(i,j), stressm_4(i,j), & stress12_4(i,j), & a11_4(i,j), & mresult11) call calc_ffrac(2, stressp_4(i,j), stressm_4(i,j), & stress12_4(i,j), & a12_4(i,j), & mresult12) a11_4(i,j) = (a11_4(i,j)*dtei + p5kth - mresult11) * dteikth ! implicit a12_4(i,j) = (a12_4(i,j)*dtei - mresult12) * dteikth ! implicit ! average structure tensor a11(i,j) = p25*(a11_1(i,j) + a11_2(i,j) + a11_3(i,j) + a11_4(i,j)) a12(i,j) = p25*(a12_1(i,j) + a12_2(i,j) + a12_3(i,j) + a12_4(i,j)) enddo ! ij end subroutine stepa !======================================================================= ! computes term in evolution equation for structure tensor which determines ! the ice floe re-orientation due to fracture ! Eq. 7: Ffrac = -kf(A-S) or = 0 depending on sigma_1 and sigma_2 subroutine calc_ffrac (blockno, stressp, stressm, & stress12, & a1x, & mresult) use ice_constants, only: c0, p001, p1, p5, c2, c3 integer(kind=int_kind), intent(in) :: & blockno real (kind=dbl_kind), intent(in) :: & stressp, stressm, stress12, a1x real (kind=dbl_kind), intent(out) :: & mresult ! local variables real (kind=dbl_kind) :: & sigma11, sigma12, sigma22, & gamma, sigma_1, sigma_2, & Q11, Q12, Q11Q11, Q11Q12, Q12Q12 real (kind=dbl_kind), parameter :: & kfrac = p001, & threshold = c3*p1 sigma11 = p5*(stressp+stressm) sigma12 = stress12 sigma22 = p5*(stressp-stressm) gamma = p5*atan2((c2*sigma12),(sigma11-sigma22)) ! rotate tensor to get into sigma principal axis Q11 = cos(gamma) Q12 = sin(gamma) Q11Q11 = Q11*Q11 Q11Q12 = Q11*Q12 Q12Q12 = Q12*Q12 sigma_1 = Q11Q11*sigma11 + c2*Q11Q12*sigma12 & + Q12Q12*sigma22 ! S(1,1) sigma_2 = Q12Q12*sigma11 - c2*Q11Q12*sigma12 & + Q11Q11*sigma22 ! S(2,2) ! Pure divergence if ((sigma_1 >= c0).and.(sigma_2 >= c0)) then mresult = c0 ! Unconfined compression: cracking of blocks not along the axial splitting direction ! which leads to the loss of their shape, so we again model it through diffusion elseif ((sigma_1 >= c0).and.(sigma_2 < c0)) then if (blockno == 1) mresult = kfrac * (a1x - Q12Q12) if (blockno == 2) mresult = kfrac * (a1x + Q11Q12) ! Shear faulting elseif (sigma_2 == c0) then mresult = c0 elseif ((sigma_1 <= c0).and.(sigma_1/sigma_2 <= threshold)) then if (blockno == 1) mresult = kfrac * (a1x - Q12Q12) if (blockno == 2) mresult = kfrac * (a1x + Q11Q12) ! Horizontal spalling else mresult = c0 endif end subroutine calc_ffrac !======================================================================= !---! these subroutines write/read Fortran unformatted data files .. !======================================================================= ! Dumps all values needed for a restart subroutine write_restart_eap () use ice_fileunits, only: nu_diag, nu_dump_eap use ice_restart, only: write_restart_field ! local variables integer (kind=int_kind) :: & iyear, imonth, iday ! year, month, day character(len=char_len_long) :: filename logical (kind=log_kind) :: diag diag = .true. !----------------------------------------------------------------- ! structure tensor !----------------------------------------------------------------- call write_restart_field(nu_dump_eap,0,a11_1,'ruf8','a11_1',1,diag) call write_restart_field(nu_dump_eap,0,a11_3,'ruf8','a11_3',1,diag) call write_restart_field(nu_dump_eap,0,a11_2,'ruf8','a11_2',1,diag) call write_restart_field(nu_dump_eap,0,a11_4,'ruf8','a11_4',1,diag) call write_restart_field(nu_dump_eap,0,a12_1,'ruf8','a12_1',1,diag) call write_restart_field(nu_dump_eap,0,a12_3,'ruf8','a12_3',1,diag) call write_restart_field(nu_dump_eap,0,a12_2,'ruf8','a12_2',1,diag) call write_restart_field(nu_dump_eap,0,a12_4,'ruf8','a12_4',1,diag) end subroutine write_restart_eap !======================================================================= ! Reads all values needed for elastic anisotropic plastic dynamics restart subroutine read_restart_eap() use ice_blocks, only: nghost use ice_boundary, only: ice_HaloUpdate_stress use ice_communicate, only: my_task, master_task use ice_constants, only: c0, & field_loc_center, field_type_scalar use ice_domain, only: nblocks, halo_info use ice_fileunits, only: nu_diag, nu_restart_eap use ice_grid, only: grid_type use ice_restart, only: read_restart_field use ice_restart_shared, only: restart_format ! local variables integer (kind=int_kind) :: & i, j, iblk logical (kind=log_kind) :: & diag diag = .true. !----------------------------------------------------------------- ! Structure tensor must be read and scattered in pairs in order ! to properly match corner values across a tripole grid cut. !----------------------------------------------------------------- if (my_task == master_task) write(nu_diag,*) & 'structure tensor restart data' call read_restart_field(nu_restart_eap,0,a11_1,'ruf8', & 'a11_1',1,diag,field_loc_center,field_type_scalar) ! a11_1 call read_restart_field(nu_restart_eap,0,a11_3,'ruf8', & 'a11_3',1,diag,field_loc_center,field_type_scalar) ! a11_3 call read_restart_field(nu_restart_eap,0,a11_2,'ruf8', & 'a11_2',1,diag,field_loc_center,field_type_scalar) ! a11_2 call read_restart_field(nu_restart_eap,0,a11_4,'ruf8', & 'a11_4',1,diag,field_loc_center,field_type_scalar) ! a11_4 call read_restart_field(nu_restart_eap,0,a12_1,'ruf8', & 'a12_1',1,diag,field_loc_center,field_type_scalar) ! a12_1 call read_restart_field(nu_restart_eap,0,a12_3,'ruf8', & 'a12_3',1,diag,field_loc_center,field_type_scalar) ! a12_3 call read_restart_field(nu_restart_eap,0,a12_2,'ruf8', & 'a12_2',1,diag,field_loc_center,field_type_scalar) ! a12_2 call read_restart_field(nu_restart_eap,0,a12_4,'ruf8', & 'a12_4',1,diag,field_loc_center,field_type_scalar) ! a12_4 if (trim(grid_type) == 'tripole' .and. trim(restart_format) == 'pio') then call ice_HaloUpdate_stress(a11_1, a11_3, halo_info, & field_loc_center, field_type_scalar) call ice_HaloUpdate_stress(a11_3, a11_1, halo_info, & field_loc_center, field_type_scalar) call ice_HaloUpdate_stress(a11_2, a11_4, halo_info, & field_loc_center, field_type_scalar) call ice_HaloUpdate_stress(a11_4, a11_2, halo_info, & field_loc_center, field_type_scalar) call ice_HaloUpdate_stress(a12_1, a12_3, halo_info, & field_loc_center, field_type_scalar) call ice_HaloUpdate_stress(a12_3, a12_1, halo_info, & field_loc_center, field_type_scalar) call ice_HaloUpdate_stress(a12_2, a12_4, halo_info, & field_loc_center, field_type_scalar) call ice_HaloUpdate_stress(a12_4, a12_2, halo_info, & field_loc_center, field_type_scalar) endif !----------------------------------------------------------------- ! Ensure unused values in west and south ghost cells are 0 !----------------------------------------------------------------- !$OMP PARALLEL DO PRIVATE(iblk,i,j) do iblk = 1, nblocks do j = 1, nghost do i = 1, nx_block a11_1 (i,j,iblk) = c0 a11_2 (i,j,iblk) = c0 a11_3 (i,j,iblk) = c0 a11_4 (i,j,iblk) = c0 a12_1 (i,j,iblk) = c0 a12_2 (i,j,iblk) = c0 a12_3 (i,j,iblk) = c0 a12_4 (i,j,iblk) = c0 enddo enddo do j = 1, ny_block do i = 1, nghost a11_1 (i,j,iblk) = c0 a11_2 (i,j,iblk) = c0 a11_3 (i,j,iblk) = c0 a11_4 (i,j,iblk) = c0 a12_1 (i,j,iblk) = c0 a12_2 (i,j,iblk) = c0 a12_3 (i,j,iblk) = c0 a12_4 (i,j,iblk) = c0 enddo enddo enddo !$OMP END PARALLEL DO end subroutine read_restart_eap !======================================================================= end module ice_dyn_eap !=======================================================================