configure_ocean_ddiff Subroutine

private subroutine configure_ocean_ddiff(cfg, ocean_state, compute_rank, ierr)

Copy the &ocean_ddiff_nml knobs onto ocean_state%vmix – every field, no dead-config gaps. Like convection, double diffusion adds no new slot (it rides the unconditionally-allocated vmix and the already-mirrored vmix%eos); vmix%ddiff_enable IS the latch. Folded into vmix_split_kd_heat_salt, so it needs the interior closure pipeline (use_closure) and thermodynamics (it reads T/S and the EOS alpha/beta). enable=.false. => bit-identical.

Arguments

Type IntentOptional Attributes Name
type(config_t), intent(in) :: cfg
type(ocean_state_t), intent(inout) :: ocean_state
integer, intent(in) :: compute_rank
integer, intent(out), optional :: ierr

Non-zero on a double-diffusion configuration conflict when present; absent behaves as today (error stop).


Calls

proc~~configure_ocean_ddiff~~CallsGraph proc~configure_ocean_ddiff configure_ocean_ddiff info info proc~configure_ocean_ddiff->info proc~fail fail proc~configure_ocean_ddiff->proc~fail to_string to_string proc~configure_ocean_ddiff->to_string error error proc~fail->error proc~error_ring_push error_ring_push proc~fail->proc~error_ring_push

Called by

proc~~configure_ocean_ddiff~~CalledByGraph proc~configure_ocean_ddiff configure_ocean_ddiff proc~configure_ocean_lateral configure_ocean_lateral proc~configure_ocean_lateral->proc~configure_ocean_ddiff proc~engine_setup engine_setup proc~engine_setup->proc~configure_ocean_lateral proc~complete_ocean_create complete_ocean_create proc~complete_ocean_create->proc~engine_setup proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_setup proc~driver_validate driver_validate proc~driver_validate->proc~engine_setup proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean proc~rdb_ocean_create_finalize rdb_ocean_create_finalize proc~rdb_ocean_create_finalize->proc~complete_ocean_create proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~complete_ocean_create

Source Code

   subroutine configure_ocean_ddiff(cfg, ocean_state, compute_rank, ierr)
      !! Copy the `&ocean_ddiff_nml` knobs onto `ocean_state%vmix` -- every
      !! field, no dead-config gaps.  Like convection, double diffusion adds
      !! no new slot (it rides the unconditionally-allocated `vmix` and the
      !! already-mirrored `vmix%eos`); `vmix%ddiff_enable` IS the latch.
      !! Folded into `vmix_split_kd_heat_salt`, so it needs the interior
      !! closure pipeline (`use_closure`) and thermodynamics (it reads T/S
      !! and the EOS alpha/beta).  `enable=.false.` => bit-identical.
      type(config_t), intent(in) :: cfg
      type(ocean_state_t), intent(inout) :: ocean_state
      integer, intent(in) :: compute_rank
      integer, intent(out), optional :: ierr
         !! Non-zero on a double-diffusion configuration conflict when
         !! present; absent behaves as today (`error stop`).

      associate (vmix => ocean_state%vmix, dcfg => cfg%ocean%ddiff)
         ! `ddiff_enable` is flipped LAST, only once every validation
         ! below has passed (P0.1 review F9 — `configure_ocean_porous` is
         ! the pattern): setting it up front left a half-configured slot
         ! flagged enabled on any of this routine's failure returns.
         if (.not. dcfg%enable) then
            vmix%ddiff_enable = .false.
            if (present(ierr)) ierr = OCEAN_STATUS_OK
            return
         end if

         vmix%ddiff_strat_param_max = dcfg%strat_param_max
         vmix%ddiff_kappa_s = dcfg%kappa_ddiff_s
         vmix%ddiff_exp1 = dcfg%ddiff_exp1
         vmix%ddiff_exp2 = dcfg%ddiff_exp2
         vmix%ddiff_param1 = dcfg%param1
         vmix%ddiff_param2 = dcfg%param2
         vmix%ddiff_param3 = dcfg%param3
         vmix%ddiff_mol_diff = dcfg%mol_diff
         vmix%ddiff_use_k90 = dcfg%use_k90

         ! Validation.
         if (.not. cfg%ocean%vmix%use_closure) then
            call fail("ocean_ddiff_nml: enable=.true. requires "// &
                      "ocean_vmix_nml use_closure=.true. (double diffusion "// &
                      "folds into the interior closure's heat/salt split)", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if
         if (.not. cfg%ocean%thermo%enable_thermodynamics) then
            call fail("ocean_ddiff_nml: enable=.true. requires "// &
                      "active thermodynamics (double diffusion reads T/S "// &
                      "and the EOS alpha/beta)", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if
         if (dcfg%strat_param_max <= 1.0_wp) then
            call fail("ocean_ddiff_nml: strat_param_max must be > 1 "// &
                      "(the fingering form divides by strat_param_max - 1)", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if
         if (dcfg%kappa_ddiff_s < 0.0_wp .or. dcfg%mol_diff < 0.0_wp) then
            call fail("ocean_ddiff_nml: kappa_ddiff_s and mol_diff must be >= 0", ierr, OCEAN_STATUS_ERR_SETUP)
            return
         end if

         if (compute_rank == 0) then
            call logger%info("Double diffusion: enabled (Rrho_max="// &
                             to_string(dcfg%strat_param_max)//"  K_f="// &
                             to_string(dcfg%kappa_ddiff_s)//" m^2/s  "// &
                             "conv="//trim(merge("K90 ", "MC76", dcfg%use_k90))//")")
         end if
         vmix%ddiff_enable = .true.
      end associate
      if (present(ierr)) ierr = OCEAN_STATUS_OK
   end subroutine configure_ocean_ddiff