This subroutine calculates new, consistent estimates of TKE and kappa.
1220 integer,
intent(in) :: nz
1221 real,
dimension(nz+1),
intent(in) :: N2
1222 real,
dimension(nz+1),
intent(in) :: S2
1223 real,
dimension(nz+1),
intent(in) :: kappa_in
1225 real,
dimension(nz+1),
intent(in) :: dz_Int
1227 real,
dimension(nz+1),
intent(in) :: I_L2_bdry
1229 real,
dimension(nz),
intent(in) :: Idz
1230 real,
intent(in) :: f2
1231 type(Kappa_shear_CS),
pointer :: CS
1232 type(verticalGrid_type),
intent(in) :: GV
1233 type(unit_scale_type),
intent(in) :: US
1234 real,
dimension(nz+1),
intent(inout) :: K_Q
1237 real,
dimension(nz+1),
intent(out) :: tke
1239 real,
dimension(nz+1),
intent(out) :: kappa
1241 real,
dimension(nz+1),
optional, &
1242 intent(out) :: kappa_src
1243 real,
dimension(nz+1),
optional, &
1244 intent(out) :: local_src
1249 real,
dimension(nz) :: &
1252 real,
dimension(nz+1) :: &
1273 real :: cQcomp, cKcomp
1287 real :: eden1, eden2, I_eden, ome
1288 real :: diffusive_src
1296 real :: decay_term_k
1297 real :: decay_term_Q
1307 real,
parameter :: roundoff = 1.0e-16
1310 logical :: tke_noflux_bottom_BC = .false.
1311 logical :: tke_noflux_top_BC = .false.
1312 logical :: do_Newton
1313 logical :: abort_Newton
1315 logical :: was_Newton
1316 logical :: within_tolerance
1318 integer :: ks_src, ke_src
1319 integer :: ks_kappa, ke_kappa, ke_tke
1320 integer :: ks_kappa_prev, ke_kappa_prev
1321 integer :: itt, k, k2
1324 logical,
parameter :: debug_soln = .false.
1325 real :: K_err_lin, Q_err_lin, TKE_src_norm
1326 real,
dimension(nz+1) :: &
1331 c_n2 = cs%C_N**2 ; c_s2 = cs%C_S**2
1332 q0 = cs%TKE_bg ; kappa0 = cs%kappa_0
1333 tke_min = max(cs%TKE_bg, 1.0e-20*us%m_to_Z**2*us%T_to_s**2)
1334 ri_crit = cs%Rino_crit
1335 ilambda2 = 1.0 / cs%lambda**2
1336 kappa_trunc = cs%kappa_trunc
1337 do_newton = .false. ; abort_newton = .false.
1338 tol_err = cs%kappa_tol_err
1341 ks_kappa = 2 ; ke_kappa = nz ; ks_kappa_prev = 2 ; ke_kappa_prev = nz
1343 ke_src = 0 ; ks_src = nz+1
1345 if (n2(k) < ri_crit * s2(k))
then
1349 k_src(k) = (2.0 * cs%Shearmix_rate * sqrt(s2(k))) * &
1350 ((ri_crit*s2(k) - n2(k)) / (ri_crit*s2(k) + cs%FRi_curvature*n2(k)))
1352 if (ks_src > k) ks_src = k
1359 if (ks_src > ke_src)
then
1361 kappa(k) = 0.0 ; k_q(k) = 0.0 ; tke(k) = tke_min
1363 if (
present(kappa_src))
then ;
do k=1,nz+1 ; kappa_src(k) = 0.0 ;
enddo ;
endif
1364 if (
present(local_src))
then ;
do k=1,nz+1 ; local_src(k) = 0.0 ;
enddo ;
endif
1369 kappa(k) = kappa_in(k)
1371 tke_decay(k) = sqrt(c_n2*n2(k) + c_s2*s2(k))
1372 if ((kappa(k) > 0.0) .and. (k_q(k) > 0.0))
then
1373 tke(k) = kappa(k) / k_q(k)
1379 kappa(1) = 0.0 ; kappa(nz+1) = 0.0
1384 eden2 = kappa0 * idz(nz)
1385 if (tke_noflux_bottom_bc)
then
1386 eden1 = dz_int(nz+1)*tke_decay(nz+1)
1387 i_eden = 1.0 / (eden2 + eden1)
1388 e1(nz+1) = eden2 * i_eden ; ome = eden1 * i_eden
1390 e1(nz+1) = 0.0 ; ome = 1.0
1393 eden1 = dz_int(k)*tke_decay(k) + ome * eden2
1394 eden2 = kappa0 * idz(k-1)
1395 i_eden = 1.0 / (eden2 + eden1)
1396 e1(k) = eden2 * i_eden ; ome = eden1 * i_eden
1402 do itt=1,cs%max_RiNo_it
1408 if (debug_soln)
then ;
do k=1,nz+1 ; kappa_prev(k) = kappa(k) ; tke_prev(k) = tke(k) ;
enddo ;
endif
1410 if (.not.do_newton)
then
1416 ke_tke = max(ke_kappa,ke_kappa_prev)+1
1418 do k=1,min(ke_tke,nz)
1419 aq(k) = (0.5*(kappa(k)+kappa(k+1)) + kappa0) * idz(k)
1422 if (tke_noflux_top_bc)
then
1423 tke_src = kappa0*s2(1) + q0 * tke_decay(1)
1424 bqd1 = dz_int(1) * tke_decay(1)
1425 bq = 1.0 / (bqd1 + aq(1))
1426 tke(1) = bq * (dz_int(1)*tke_src)
1427 cq(2) = aq(1) * bq ; cqcomp = bqd1 * bq
1429 tke(1) = q0 ; cq(2) = 0.0 ; cqcomp = 1.0
1433 tke_src = (kappa(k) + kappa0)*s2(k) + q0*tke_decay(k)
1434 bqd1 = dz_int(k)*(tke_decay(k) + n2(k)*k_q(k)) + cqcomp*aq(k-1)
1435 bq = 1.0 / (bqd1 + aq(k))
1436 tke(k) = bq * (dz_int(k)*tke_src + aq(k-1)*tke(k-1))
1437 cq(k+1) = aq(k) * bq ; cqcomp = bqd1 * bq
1439 if ((ke_tke == nz+1) .and. .not.(tke_noflux_bottom_bc))
then
1444 tke_src = kappa0*s2(k) + q0*tke_decay(k)
1447 bq = 1.0 / (dz_int(k)*tke_decay(k) + cqcomp*aq(k-1))
1448 tke(k) = max(tke_min, bq * (dz_int(k)*tke_src + aq(k-1)*tke(k-1)))
1449 dq(k) = tke(k) + dq(k)
1451 bq = 1.0 / ((dz_int(k)*tke_decay(k) + cqcomp*aq(k-1)) + aq(k))
1452 cq(k+1) = aq(k) * bq
1455 tke(k) = max((bq * (dz_int(k)*tke_src + aq(k-1)*tke(k-1)) + &
1456 cq(k+1)*(tke(k+1) - e1(k+1)*tke(k))) / (1.0 - cq(k+1)*e1(k+1)), tke_min)
1457 dq(k) = tke(k) + dq(k)
1462 dq(k) = e1(k)*dq(k-1)
1463 tke(k) = max(tke(k) + dq(k), tke_min)
1464 if (abs(dq(k)) < roundoff*tke(k))
exit
1467 if (dq(k2) == 0.0)
exit
1473 tke(k) = max(tke(k) + cq(k+1)*tke(k+1), tke_min)
1474 dq(k) = tke(k) + dq(k)
1481 ke_kappa_prev = ke_kappa ; ks_kappa_prev = ks_kappa
1484 ck(2) = 0.0 ; ckcomp = 1.0
1485 if (itt == 1)
then ;
dO k=2,nz
1486 i_ld2(k) = (n2(k)*ilambda2 + f2) / tke(k) + i_l2_bdry(k)
1491 i_ld2(k) = (n2(k)*ilambda2 + f2) / tke(k) + i_l2_bdry(k)
1492 bkd1 = dz_int(k)*i_ld2(k) + ckcomp*idz(k-1)
1493 bk = 1.0 / (bkd1 + idz(k))
1495 kappa(k) = bk * (idz(k-1)*kappa(k-1) + dz_int(k) * k_src(k))
1496 ck(k+1) = idz(k) * bk ; ckcomp = bkd1 * bk
1499 if (kappa(k) < ckcomp*kappa_trunc)
then
1501 if (k > ke_src)
then ; ke_kappa = k-1 ; k_q(k) = 0.0 ;
exit ;
endif
1502 elseif (kappa(k) < 2.0*ckcomp*kappa_trunc)
then
1503 kappa(k) = 2.0 * (kappa(k) - ckcomp*kappa_trunc)
1506 k_q(ke_kappa) = kappa(ke_kappa) / tke(ke_kappa)
1507 dk(ke_kappa) = dk(ke_kappa) + kappa(ke_kappa)
1508 do k=ke_kappa+2,ke_kappa_prev
1509 dk(k) = -kappa(k) ; kappa(k) = 0.0 ; k_q(k) = 0.0
1511 do k=ke_kappa-1,2,-1
1512 kappa(k) = kappa(k) + ck(k+1)*kappa(k+1)
1514 if (kappa(k) <= kappa_trunc)
then
1516 if (k < ks_src)
then ; ks_kappa = k+1 ; k_q(k) = 0.0 ;
exit ;
endif
1517 elseif (kappa(k) < 2.0*kappa_trunc)
then
1518 kappa(k) = 2.0 * (kappa(k) - kappa_trunc)
1521 dk(k) = dk(k) + kappa(k)
1522 k_q(k) = kappa(k) / tke(k)
1524 do k=ks_kappa_prev,ks_kappa-2 ; kappa(k) = 0.0 ; k_q(k) = 0.0 ;
enddo
1529 ks_kappa_prev = ks_kappa ; ke_kappa_prev = ke_kappa ; ke_kappa = nz
1531 dk(1) = 0.0 ; ck(2) = 0.0 ; ckcomp = 1.0 ; dkdq(1) = 0.0
1532 aq(1) = (0.5*(kappa(1)+kappa(2))+kappa0) * idz(1)
1533 dqdz(1) = 0.5*(tke(1) - tke(2))*idz(1)
1534 if (tke_noflux_top_bc)
then
1535 tke_src = dz_int(1) * (kappa0*s2(1) - (tke(1) - q0)*tke_decay(1)) - &
1536 aq(1) * (tke(1) - tke(2))
1538 bq = 1.0 / (aq(1) + dz_int(1)*tke_decay(1))
1540 cqcomp = (dz_int(1)*tke_decay(1)) * bq
1541 dqmdk(2) = -dqdz(1) * bq
1542 dq(1) = bq * tke_src
1544 dq(1) = 0.0 ; cq(2) = 0.0 ; cqcomp = 1.0 ; dqmdk(2) = 0.0
1548 i_ld2(k) = (n2(k)*ilambda2 + f2) * i_q + i_l2_bdry(k)
1550 kap_src = dz_int(k) * (k_src(k) - i_ld2(k)*kappa(k)) + &
1551 idz(k-1)*(kappa(k-1)-kappa(k)) - idz(k)*(kappa(k)-kappa(k+1))
1555 decay_term_k = -idz(k-1)*dqmdk(k)*dkdq(k-1) + dz_int(k)*i_ld2(k)
1556 if (decay_term_k < 0.0)
then ; abort_newton = .true. ;
exit ;
endif
1557 bk = 1.0 / (idz(k) + idz(k-1)*ckcomp + decay_term_k)
1559 ck(k+1) = bk * idz(k)
1560 ckcomp = bk * (idz(k-1)*ckcomp + decay_term_k)
1561 if (cs%dKdQ_iteration_bug)
then
1562 dkdq(k) = bk * (idz(k-1)*dkdq(k-1)*cq(k) + &
1563 us%m_to_Z*(n2(k)*ilambda2 + f2) * i_q**2 * kappa(k) )
1565 dkdq(k) = bk * (idz(k-1)*dkdq(k-1)*cq(k) + &
1566 dz_int(k)*(n2(k)*ilambda2 + f2) * i_q**2 * kappa(k) )
1568 dk(k) = bk * (kap_src + idz(k-1)*dk(k-1) + idz(k-1)*dkdq(k-1)*dq(k-1))
1571 if (dk(k) <= ckcomp*(kappa_trunc - kappa(k)))
then
1572 dk(k) = -ckcomp*kappa(k)
1574 elseif (dk(k) < ckcomp*(2.0*kappa_trunc - kappa(k)))
then
1575 dk(k) = 2.0 * dk(k) - ckcomp*(2.0*kappa_trunc - kappa(k))
1579 aq(k) = (0.5*(kappa(k)+kappa(k+1))+kappa0) * idz(k)
1580 dqdz(k) = 0.5*(tke(k) - tke(k+1))*idz(k)
1581 tke_src = dz_int(k) * (((kappa(k) + kappa0)*s2(k) - kappa(k)*n2(k)) - &
1582 (tke(k) - q0)*tke_decay(k)) - &
1583 (aq(k) * (tke(k) - tke(k+1)) - aq(k-1) * (tke(k-1) - tke(k)))
1584 v1 = aq(k-1) + dqdz(k-1)*dkdq(k-1)
1585 v2 = (v1*dqmdk(k) + dqdz(k-1)*ck(k)) + &
1586 ((dqdz(k-1) - dqdz(k)) + dz_int(k)*(s2(k) - n2(k)))
1590 decay_term_q = dz_int(k)*tke_decay(k) - dqdz(k-1)*dkdq(k-1)*cq(k) - v2*dkdq(k)
1591 if (decay_term_q < 0.0)
then ; abort_newton = .true. ;
exit ;
endif
1592 bq = 1.0 / (aq(k) + (cqcomp*aq(k-1) + decay_term_q))
1594 cq(k+1) = aq(k) * bq
1595 cqcomp = (cqcomp*aq(k-1) + decay_term_q) * bq
1596 dqmdk(k+1) = (v2 * ck(k+1) - dqdz(k)) * bq
1599 dq(k) = max(bq * ((v1 * dq(k-1) + dqdz(k-1)*dk(k-1)) + &
1600 (v2 * dk(k) + tke_src)), cqcomp*(-0.5*tke(k)))
1603 if ((itt > 1) .and. (k > ke_src) .and. (dk(k) == 0.0) .and. &
1604 ((kappa(k) + kappa(k+1)) == 0.0))
then
1606 ke_kappa = k-1 ;
exit
1609 if ((ke_kappa == nz) .and. (.not. abort_newton))
then
1610 dk(nz+1) = 0.0 ; dkdq(nz+1) = 0.0
1611 if (tke_noflux_bottom_bc)
then
1613 tke_src = dz_int(k) * (kappa0*s2(k) - (tke(k) - q0)*tke_decay(k)) + &
1614 aq(k-1) * (tke(k-1) - tke(k))
1616 v1 = aq(k-1) + dqdz(k-1)*dkdq(k-1)
1617 decay_term_q = max(0.0, dz_int(k)*tke_decay(k) - dqdz(k-1)*dkdq(k-1)*cq(k))
1618 if (decay_term_q < 0.0)
then
1619 abort_newton = .true.
1621 bq = 1.0 / (aq(k) + (cqcomp*aq(k-1) + decay_term_q))
1623 dq(k) = max(bq * ((v1 * dq(k-1) + dqdz(k-1)*dk(k-1)) + tke_src), -0.5*tke(k))
1624 tke(k) = max(tke(k) + dq(k), tke_min)
1629 elseif (.not. abort_newton)
then
1631 dq(ke_kappa+1) = dq(ke_kappa+1) / (1.0 - cq(ke_kappa+2)*e1(ke_kappa+2))
1632 tke(ke_kappa+1) = max(tke(ke_kappa+1) + dq(ke_kappa+1), tke_min)
1633 do k=ke_kappa+2,nz+1
1634 if (debug_soln .and. (k < nz+1))
then
1636 aq(k) = (0.5*(kappa(k)+kappa(k+1))+kappa0) * idz(k)
1643 dq(k) = max(e1(k)*dq(k-1),-0.5*tke(k))
1644 tke(k) = max(tke(k) + dq(k), tke_min)
1645 if (abs(dq(k)) < roundoff*tke(k))
exit
1647 if (debug_soln)
then ;
do k2=k+1,nz+1 ; dq(k2) = 0.0 ; dk(k2) = 0.0 ;
enddo ;
endif
1649 if (.not. abort_newton)
then
1652 dq(k) = max(dq(k) + (cq(k+1)*dq(k+1) + dqmdk(k+1) * dk(k+1)), -0.5*tke(k))
1653 tke(k) = max(tke(k) + dq(k), tke_min)
1654 dk(k) = dk(k) + (ck(k+1)*dk(k+1) + dkdq(k) * dq(k))
1656 if (dk(k) <= kappa_trunc - kappa(k))
then
1659 if ((k < ks_src) .and. (k+1 > ks_kappa)) ks_kappa = k+1
1660 elseif (dk(k) < 2.0*kappa_trunc - kappa(k))
then
1661 dk(k) = 2.0*dk(k) - (2.0*kappa_trunc - kappa(k))
1662 kappa(k) = max(kappa(k) + dk(k), 0.0)
1663 if (k<=ks_kappa) ks_kappa = 2
1665 kappa(k) = kappa(k) + dk(k)
1666 if (k<=ks_kappa) ks_kappa = 2
1669 dq(1) = max(dq(1) + cq(2)*dq(2) + dqmdk(2) * dk(2), tke_min - tke(1))
1670 tke(1) = max(tke(1) + dq(1), tke_min)
1676 if (debug_soln)
then ;
do k=2,nz
1683 i_ld2_debug(k) = (n2(k)*ilambda2 + f2) * i_q + i_l2_bdry(k)
1685 kap_src = dz_int(k) * (k_src(k) - i_ld2(k)*kappa_prev(k)) + &
1686 (idz(k-1)*(kappa_prev(k-1)-kappa_prev(k)) - &
1687 idz(k)*(kappa_prev(k)-kappa_prev(k+1)))
1688 k_err_lin = -idz(k-1)*(dk(k-1)-dk(k)) + idz(k)*(dk(k)-dk(k+1)) + &
1689 dz_int(k)*i_ld2_debug(k)*dk(k) - kap_src - &
1690 dz_int(k)*(n2(k)*ilambda2 + f2)*i_q**2*kappa_prev(k) * dq(k)
1692 tke_src = dz_int(k) * ((kappa_prev(k) + kappa0)*s2(k) - &
1693 kappa_prev(k)*n2(k) - (tke_prev(k) - q0)*tke_decay(k)) - &
1694 (aq(k) * (tke_prev(k) - tke_prev(k+1)) - aq(k-1) * (tke_prev(k-1) - tke_prev(k)))
1695 q_err_lin = tke_src + (aq(k-1) * (dq(k-1)-dq(k)) - aq(k) * (dq(k)-dq(k+1))) - &
1696 0.5*(tke_prev(k)-tke_prev(k+1))*idz(k) * (dk(k) + dk(k+1)) - &
1697 0.5*(tke_prev(k)-tke_prev(k-1))*idz(k-1)* (dk(k-1) + dk(k)) + &
1698 dz_int(k) * (dk(k) * (s2(k) - n2(k)) - dq(k)*tke_decay(k))
1704 if ((tol_err < newton_err) .and. (.not.abort_newton))
then
1706 newton_test = newton_err ;
if (do_newton) newton_test = 2.0*newton_err
1707 was_newton = do_newton
1708 within_tolerance = .true. ; do_newton = .true.
1709 do k=min(ks_kappa,ks_kappa_prev),max(ke_kappa,ke_kappa_prev)
1710 kappa_mean = kappa0 + (kappa(k) - 0.5*dk(k))
1711 if (abs(dk(k)) > newton_test * kappa_mean)
then
1712 if (do_newton) abort_newton = .true.
1713 within_tolerance = .false. ; do_newton = .false. ;
exit
1714 elseif (abs(dk(k)) > tol_err * kappa_mean)
then
1715 within_tolerance = .false. ;
if (.not.do_newton)
exit
1717 if (abs(dq(k)) > newton_test*(tke(k) - 0.5*dq(k)))
then
1718 if (do_newton) abort_newton = .true.
1719 do_newton = .false. ;
if (.not.within_tolerance)
exit
1724 within_tolerance = .true.
1725 do k=min(ks_kappa,ks_kappa_prev),max(ke_kappa,ke_kappa_prev)
1726 if (abs(dk(k)) > tol_err * (kappa0 + (kappa(k) - 0.5*dk(k))))
then
1727 within_tolerance = .false. ;
exit
1732 if (abort_newton)
then
1733 do_newton = .false. ; abort_newton = .false.
1735 newton_err = 0.5*newton_err
1737 do k=2,nz ; k_q(k) = kappa(k) / max(tke(k), tke_min) ;
enddo
1740 if (within_tolerance)
exit
1745 do k=1,ks_kappa-1 ; k_q(k) = 0.0 ;
enddo
1746 do k=ks_kappa,ke_kappa ; k_q(k) = kappa(k) / tke(k) ;
enddo
1747 do k=ke_kappa+1,nz+1 ; k_q(k) = 0.0 ;
enddo
1750 if (
present(local_src))
then
1751 local_src(1) = 0.0 ; local_src(nz+1) = 0.0
1753 diffusive_src = idz(k-1)*(kappa(k-1)-kappa(k)) + idz(k)*(kappa(k+1)-kappa(k))
1754 chg_by_k0 = kappa0 * ((idz(k-1)+idz(k)) / dz_int(k) + i_ld2(k))
1755 if (diffusive_src <= 0.0)
then
1756 local_src(k) = k_src(k) + chg_by_k0
1758 local_src(k) = (k_src(k) + chg_by_k0) + diffusive_src / dz_int(k)
1762 if (
present(kappa_src))
then
1763 kappa_src(1) = 0.0 ; kappa_src(nz+1) = 0.0
1765 kappa_src(k) = k_src(k)