update_transport_properties Subroutine

public subroutine update_transport_properties(mesh, flow, params, Y, transport, T_state)

Uses

  • proc~~update_transport_properties~~UsesGraph proc~update_transport_properties mod_transport_properties::update_transport_properties iso_c_binding iso_c_binding proc~update_transport_properties->iso_c_binding module~mod_profiler mod_profiler proc~update_transport_properties->module~mod_profiler iso_fortran_env iso_fortran_env module~mod_profiler->iso_fortran_env module~mod_kinds mod_kinds module~mod_profiler->module~mod_kinds mpi_f08 mpi_f08 module~mod_profiler->mpi_f08 module~mod_kinds->iso_fortran_env

Evaluates physical properties for the entire domain.

If Cantera transport is enabled, it calls the C++ bridge to calculate mixture-averaged viscosity and diffusivity. Otherwise, it applies the uniform constant values defined in params. In both cases, transport%rho is the constant flow/projection density params%rho.

Arguments

Type IntentOptional Attributes Name
type(mesh_t), intent(in) :: mesh

The computational mesh.

type(flow_mpi_t), intent(inout) :: flow

MPI decomposition and halo metadata.

type(case_params_t), intent(in) :: params

Simulation parameters and background conditions.

real(kind=rk), intent(in), optional :: Y(:,:)
type(transport_properties_t), intent(inout) :: transport

The property container to update.

real(kind=rk), intent(in), optional :: T_state(:)

Calls

proc~~update_transport_properties~~CallsGraph proc~update_transport_properties mod_transport_properties::update_transport_properties interface~cantera_update_transport_c mod_transport_properties::cantera_update_transport_c proc~update_transport_properties->interface~cantera_update_transport_c proc~fatal_error mod_kinds::fatal_error proc~update_transport_properties->proc~fatal_error proc~flow_exchange_cell_matrix mod_mpi_flow::flow_exchange_cell_matrix proc~update_transport_properties->proc~flow_exchange_cell_matrix proc~flow_exchange_cell_scalar mod_mpi_flow::flow_exchange_cell_scalar proc~update_transport_properties->proc~flow_exchange_cell_scalar proc~profiler_start mod_profiler::profiler_start proc~update_transport_properties->proc~profiler_start proc~profiler_stop mod_profiler::profiler_stop proc~update_transport_properties->proc~profiler_stop proc~flow_exchange_cell_matrix->proc~fatal_error proc~flow_exchange_cell_matrix->proc~profiler_start proc~flow_exchange_cell_matrix->proc~profiler_stop mpi_irecv mpi_irecv proc~flow_exchange_cell_matrix->mpi_irecv mpi_isend mpi_isend proc~flow_exchange_cell_matrix->mpi_isend mpi_waitall mpi_waitall proc~flow_exchange_cell_matrix->mpi_waitall proc~check_mpi~2 mod_mpi_flow::check_mpi proc~flow_exchange_cell_matrix->proc~check_mpi~2 proc~flow_exchange_cell_scalar->proc~profiler_start proc~flow_exchange_cell_scalar->proc~profiler_stop proc~flow_exchange_cell_scalar->mpi_irecv proc~flow_exchange_cell_scalar->mpi_isend proc~flow_exchange_cell_scalar->mpi_waitall proc~flow_exchange_cell_scalar->proc~check_mpi~2 mpi_wtime mpi_wtime proc~profiler_start->mpi_wtime proc~find_or_create_timer mod_profiler::find_or_create_timer proc~profiler_start->proc~find_or_create_timer proc~profiler_stop->mpi_wtime proc~profiler_stop->proc~find_or_create_timer proc~record_edge mod_profiler::record_edge proc~profiler_stop->proc~record_edge proc~check_mpi~2->proc~fatal_error

Called by

proc~~update_transport_properties~~CalledByGraph proc~update_transport_properties mod_transport_properties::update_transport_properties program~lowmach_react_hex lowmach_react_hex program~lowmach_react_hex->proc~update_transport_properties

Source Code

   subroutine update_transport_properties(mesh, flow, params, Y, transport, T_state)
      use iso_c_binding, only : c_char
      use mod_profiler, only : profiler_start, profiler_stop
      type(mesh_t), intent(in) :: mesh
      type(flow_mpi_t), intent(inout) :: flow
      type(case_params_t), intent(in) :: params
      real(rk), intent(in), optional :: Y(:,:)
      type(transport_properties_t), intent(inout) :: transport
      real(rk), intent(in), optional :: T_state(:)
      integer :: c, k, i, n_len, nloc
      real(rk), allocatable :: T_arr(:), P_arr(:), Y_local(:,:), Y_pure(:,:)
      real(rk), allocatable :: mu_local(:), diff_local(:,:)
      character(kind=c_char, len=len(params%species_name(1))*params%nspecies) :: c_names_flat

      if (mesh%ncells /= size(transport%rho)) then
         call fatal_error('transport', 'transport field size does not match mesh')
      end if

      ! Constant density is assumed for the standard incompressible solver mode.
      ! This is not a Cantera density update; energy%rho_thermo is diagnostic only.
      transport%rho = params%rho
      
      if (params%enable_cantera_fluid .or. params%enable_cantera_species) then
         call profiler_start('Transport_Setup')

         ! Build owned-cell Temperature and thermodynamic-pressure arrays for the bridge call.
         nloc = flow%nlocal
         allocate(T_arr(nloc))
         allocate(P_arr(nloc))
         allocate(mu_local(nloc))
         allocate(diff_local(max(1, params%nspecies), nloc))
         if (present(T_state)) then
            if (size(T_state) < mesh%ncells) then
               call fatal_error('transport', 'T_state has incompatible size for Cantera transport update')
            end if
            do i = 1, nloc
               c = flow%first_cell + i - 1
               T_arr(i) = T_state(c)
            end do
         else
            T_arr = params%background_temp
         end if
         P_arr = params%background_press
         mu_local = zero
         diff_local = zero

         c_names_flat = ""
         n_len = len(params%species_name(1))
         do k = 1, params%nspecies
            c_names_flat((k-1)*n_len+1:k*n_len) = params%species_name(k)
         end do

         if (present(Y)) then
            allocate(Y_local(max(1, params%nspecies), nloc))
            do i = 1, nloc
               c = flow%first_cell + i - 1
               do k = 1, params%nspecies
                  Y_local(k, i) = Y(k, c)
               end do
            end do

            call profiler_stop('Transport_Setup')
            call profiler_start('Transport_Cantera_Call')
            call cantera_update_transport_c(nloc, T_arr, P_arr, params%nspecies, &
                                            Y_local, mu_local, diff_local, &
                                            c_names_flat, n_len)
            call profiler_stop('Transport_Cantera_Call')

            call profiler_start('Transport_Cleanup')
            deallocate(Y_local)
            call profiler_stop('Transport_Cleanup')
         else
            ! Case where species are not yet initialized: pass pure background gas (Y=1.0)
            allocate(Y_pure(max(1, params%nspecies), nloc))
            Y_pure = one
            call profiler_stop('Transport_Setup')
            call profiler_start('Transport_Cantera_Call')
            call cantera_update_transport_c(nloc, T_arr, P_arr, params%nspecies, &
                                            Y_pure, mu_local, diff_local, &
                                            c_names_flat, n_len)
            call profiler_stop('Transport_Cantera_Call')

            call profiler_start('Transport_Cleanup')
            deallocate(Y_pure)
            call profiler_stop('Transport_Cleanup')
         end if

         call profiler_start('Transport_Unpack')
         do i = 1, nloc
            c = flow%first_cell + i - 1
            transport%mu(c) = mu_local(i)
            do k = 1, params%nspecies
               transport%diffusivity(k, c) = diff_local(k, i)
            end do
         end do
         call profiler_stop('Transport_Unpack')

         call profiler_start('Transport_Exchange')

         ! Apply partial overrides (e.g., if viscosity is constant but diffusivity is dynamic)
         if (.not. params%enable_cantera_fluid) then
            transport%nu = params%nu
            transport%mu = params%rho * params%nu
         else
            do c = flow%first_cell, flow%last_cell
               transport%nu(c) = transport%mu(c) / transport%rho(c)
            end do
            call profiler_start('Transport_Exchange_Mu')
            call flow_exchange_cell_scalar(flow, transport%mu)
            call profiler_stop('Transport_Exchange_Mu')

            call profiler_start('Transport_Exchange_Nu')
            call flow_exchange_cell_scalar(flow, transport%nu)
            call profiler_stop('Transport_Exchange_Nu')
         end if

         if (.not. params%enable_cantera_species .and. params%nspecies > 0) then
            do k = 1, params%nspecies
               transport%diffusivity(k, :) = params%species_diffusivity(k)
            end do
         else if (params%nspecies > 0) then
            call profiler_start('Transport_Exchange_Diff')
            call flow_exchange_cell_matrix(flow, transport%diffusivity)
            call profiler_stop('Transport_Exchange_Diff')
         end if
         call profiler_stop('Transport_Exchange')
         
         call profiler_start('Transport_Cleanup')
         deallocate(T_arr)
         deallocate(P_arr)
         deallocate(mu_local)
         deallocate(diff_local)
         call profiler_stop('Transport_Cleanup')
      else
         ! Constant Fallback Mode
         transport%nu = params%nu
         transport%mu = params%rho * params%nu
         
         if (params%nspecies > 0) then
            do k = 1, params%nspecies
               transport%diffusivity(k, :) = params%species_diffusivity(k)
            end do
         end if
      end if
      
   
      ! Validation-control option: keep flow viscosity/nu constant unless
      ! variable viscosity is explicitly enabled. This still allows Cantera
      ! species diffusivity D_k to be used when species Cantera transport is on.
      if (.not. params%enable_variable_nu) then
         transport%mu = params%rho * params%nu
      end if

end subroutine update_transport_properties