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.
| Type | Intent | Optional | 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(:) |
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