properties_manager.F90 Source File


This file depends on

sourcefile~~properties_manager.f90~~EfferentGraph sourcefile~properties_manager.f90 properties_manager.F90 sourcefile~calculate.f90 calculate.F90 sourcefile~properties_manager.f90->sourcefile~calculate.f90 sourcefile~control.f90 control.F90 sourcefile~properties_manager.f90->sourcefile~control.f90 sourcefile~core.f90 core.F90 sourcefile~properties_manager.f90->sourcefile~core.f90 sourcefile~input.f90 input.F90 sourcefile~properties_manager.f90->sourcefile~input.f90 sourcefile~materials_manager.f90 materials_manager.F90 sourcefile~properties_manager.f90->sourcefile~materials_manager.f90 sourcefile~density_interface.f90 density_interface.F90 sourcefile~calculate.f90->sourcefile~density_interface.f90 sourcefile~gcc_interface.f90 gcc_interface.F90 sourcefile~calculate.f90->sourcefile~gcc_interface.f90 sourcefile~hcf_interface.f90 hcf_interface.F90 sourcefile~calculate.f90->sourcefile~hcf_interface.f90 sourcefile~heat_capacity_interface.f90 heat_capacity_interface.F90 sourcefile~calculate.f90->sourcefile~heat_capacity_interface.f90 sourcefile~linalg.f90 linalg.F90 sourcefile~calculate.f90->sourcefile~linalg.f90 sourcefile~specific_heat_interface.f90 specific_heat_interface.F90 sourcefile~calculate.f90->sourcefile~specific_heat_interface.f90 sourcefile~thermal_conductivity_interface.f90 thermal_conductivity_interface.F90 sourcefile~calculate.f90->sourcefile~thermal_conductivity_interface.f90 sourcefile~control.f90->sourcefile~core.f90 sourcefile~control.f90->sourcefile~input.f90 sourcefile~iteration.f90 iteration.F90 sourcefile~control.f90->sourcefile~iteration.f90 sourcefile~openmp.f90 openmp.F90 sourcefile~control.f90->sourcefile~openmp.f90 sourcefile~time.f90 time.F90 sourcefile~control.f90->sourcefile~time.f90 sourcefile~allocate.f90 allocate.F90 sourcefile~core.f90->sourcefile~allocate.f90 sourcefile~check_range.f90 check_range.F90 sourcefile~core.f90->sourcefile~check_range.f90 sourcefile~deallocate.f90 deallocate.F90 sourcefile~core.f90->sourcefile~deallocate.f90 sourcefile~error.f90 error.F90 sourcefile~core.f90->sourcefile~error.f90 sourcefile~fortran_utils.f90 fortran_utils.F90 sourcefile~core.f90->sourcefile~fortran_utils.f90 sourcefile~string_utils.f90 string_utils.F90 sourcefile~core.f90->sourcefile~string_utils.f90 sourcefile~types.f90 types.F90 sourcefile~core.f90->sourcefile~types.f90 sourcefile~unique.f90 unique.F90 sourcefile~core.f90->sourcefile~unique.f90 sourcefile~vtk.f90 vtk.F90 sourcefile~core.f90->sourcefile~vtk.f90 sourcefile~vtk_constants.f90 vtk_constants.F90 sourcefile~core.f90->sourcefile~vtk_constants.f90 sourcefile~input_interface.f90 input_interface.F90 sourcefile~input.f90->sourcefile~input_interface.f90 sourcefile~materials_manager.f90->sourcefile~calculate.f90 sourcefile~materials_manager.f90->sourcefile~input.f90 sourcefile~allocate.f90->sourcefile~error.f90 sourcefile~deallocate.f90->sourcefile~error.f90 sourcefile~density_interface.f90->sourcefile~core.f90 sourcefile~density_interface.f90->sourcefile~input.f90 sourcefile~memory_stats_wrapper.f90 memory_stats_wrapper.F90 sourcefile~fortran_utils.f90->sourcefile~memory_stats_wrapper.f90 sourcefile~signal_flag_wrapper.f90 signal_flag_wrapper.F90 sourcefile~fortran_utils.f90->sourcefile~signal_flag_wrapper.f90 sourcefile~system_info_wrapper.f90 system_info_wrapper.F90 sourcefile~fortran_utils.f90->sourcefile~system_info_wrapper.f90 sourcefile~gcc_interface.f90->sourcefile~core.f90 sourcefile~gcc_interface.f90->sourcefile~input.f90 sourcefile~hcf_interface.f90->sourcefile~core.f90 sourcefile~hcf_interface.f90->sourcefile~input.f90 sourcefile~heat_capacity_interface.f90->sourcefile~core.f90 sourcefile~heat_capacity_interface.f90->sourcefile~density_interface.f90 sourcefile~heat_capacity_interface.f90->sourcefile~input_interface.f90 sourcefile~input_interface.f90->sourcefile~core.f90 sourcefile~project_settings.f90 project_settings.F90 sourcefile~input_interface.f90->sourcefile~project_settings.f90 sourcefile~iteration.f90->sourcefile~calculate.f90 sourcefile~iteration.f90->sourcefile~input.f90 sourcefile~matrix_ops.f90 matrix_ops.F90 sourcefile~linalg.f90->sourcefile~matrix_ops.f90 sourcefile~matvec.f90 matvec.F90 sourcefile~linalg.f90->sourcefile~matvec.f90 sourcefile~vector_ops.f90 vector_ops.F90 sourcefile~linalg.f90->sourcefile~vector_ops.f90 sourcefile~openmp.f90->sourcefile~input.f90 sourcefile~specific_heat_interface.f90->sourcefile~core.f90 sourcefile~specific_heat_interface.f90->sourcefile~input.f90 sourcefile~string_utils.f90->sourcefile~allocate.f90 sourcefile~thermal_conductivity_interface.f90->sourcefile~core.f90 sourcefile~thermal_conductivity_interface.f90->sourcefile~input.f90 sourcefile~time.f90->sourcefile~core.f90 sourcefile~time.f90->sourcefile~input.f90 sourcefile~array.f90 array.F90 sourcefile~types.f90->sourcefile~array.f90 sourcefile~gauss.f90 gauss.F90 sourcefile~types.f90->sourcefile~gauss.f90 sourcefile~matrix.f90 matrix.F90 sourcefile~types.f90->sourcefile~matrix.f90 sourcefile~pointer.f90 pointer.F90 sourcefile~types.f90->sourcefile~pointer.f90 sourcefile~variable.f90 variable.F90 sourcefile~types.f90->sourcefile~variable.f90 sourcefile~vector.f90 vector.F90 sourcefile~types.f90->sourcefile~vector.f90 sourcefile~unique.f90->sourcefile~allocate.f90 sourcefile~vtk.f90->sourcefile~allocate.f90 sourcefile~vtk.f90->sourcefile~deallocate.f90 sourcefile~vtk.f90->sourcefile~types.f90 sourcefile~vtk.f90->sourcefile~unique.f90 sourcefile~vtk.f90->sourcefile~vtk_constants.f90 sourcefile~vtk_wrapper.f90 vtk_wrapper.F90 sourcefile~vtk.f90->sourcefile~vtk_wrapper.f90 sourcefile~vtu_wrapper.f90 vtu_wrapper.F90 sourcefile~vtk.f90->sourcefile~vtu_wrapper.f90 sourcefile~array.f90->sourcefile~allocate.f90 sourcefile~array.f90->sourcefile~deallocate.f90 sourcefile~matrix_coo.f90 matrix_coo.F90 sourcefile~matrix.f90->sourcefile~matrix_coo.f90 sourcefile~matrix_crs.f90 matrix_crs.F90 sourcefile~matrix.f90->sourcefile~matrix_crs.f90 sourcefile~matrix_dense.f90 matrix_dense.F90 sourcefile~matrix.f90->sourcefile~matrix_dense.f90 sourcefile~matrix_interface.f90 matrix_interface.F90 sourcefile~matrix.f90->sourcefile~matrix_interface.f90 sourcefile~matrix_ops.f90->sourcefile~core.f90 sourcefile~matvec.f90->sourcefile~core.f90 sourcefile~c_utils.f90 c_utils.F90 sourcefile~memory_stats_wrapper.f90->sourcefile~c_utils.f90 sourcefile~project_settings.f90->sourcefile~core.f90 sourcefile~signal_flag.f90 signal_flag.F90 sourcefile~signal_flag_wrapper.f90->sourcefile~signal_flag.f90 sourcefile~system_info_wrapper.f90->sourcefile~c_utils.f90 sourcefile~variable.f90->sourcefile~allocate.f90 sourcefile~c_utils.f90->sourcefile~signal_flag.f90 sourcefile~memory_stats.f90 memory_stats.F90 sourcefile~c_utils.f90->sourcefile~memory_stats.f90 sourcefile~system_info.f90 system_info.F90 sourcefile~c_utils.f90->sourcefile~system_info.f90 sourcefile~matrix_coo.f90->sourcefile~allocate.f90 sourcefile~matrix_coo.f90->sourcefile~deallocate.f90 sourcefile~matrix_coo.f90->sourcefile~matrix_interface.f90 sourcefile~matrix_crs.f90->sourcefile~allocate.f90 sourcefile~matrix_crs.f90->sourcefile~deallocate.f90 sourcefile~matrix_crs.f90->sourcefile~matrix_interface.f90 sourcefile~matrix_dense.f90->sourcefile~allocate.f90 sourcefile~matrix_dense.f90->sourcefile~deallocate.f90 sourcefile~matrix_dense.f90->sourcefile~matrix_interface.f90

Files dependent on this one

sourcefile~~properties_manager.f90~~AfferentGraph sourcefile~properties_manager.f90 properties_manager.F90 sourcefile~properties.f90 properties.F90 sourcefile~properties.f90->sourcefile~properties_manager.f90 sourcefile~ftdss.f90 ftdss.F90 sourcefile~ftdss.f90->sourcefile~properties.f90 sourcefile~hydraulic.f90 hydraulic.F90 sourcefile~ftdss.f90->sourcefile~hydraulic.f90 sourcefile~output.f90 output.F90 sourcefile~ftdss.f90->sourcefile~output.f90 sourcefile~thermal.f90 thermal.F90 sourcefile~ftdss.f90->sourcefile~thermal.f90 sourcefile~hydraulic_assemble.f90 hydraulic_assemble.F90 sourcefile~hydraulic_assemble.f90->sourcefile~properties.f90 sourcefile~hydraulic_interface.f90 hydraulic_interface.F90 sourcefile~hydraulic_interface.f90->sourcefile~properties.f90 sourcefile~hydraulic_interface.f90->sourcefile~hydraulic_assemble.f90 sourcefile~output_interface.f90 output_interface.F90 sourcefile~output_interface.f90->sourcefile~properties.f90 sourcefile~thermal_interface.f90 thermal_interface.F90 sourcefile~thermal_interface.f90->sourcefile~properties.f90 sourcefile~hydraulic.f90->sourcefile~hydraulic_interface.f90 sourcefile~hydraulic_crs.f90 hydraulic_crs.F90 sourcefile~hydraulic_crs.f90->sourcefile~hydraulic_interface.f90 sourcefile~output.f90->sourcefile~output_interface.f90 sourcefile~output_base.f90 output_base.F90 sourcefile~output_base.f90->sourcefile~output_interface.f90 sourcefile~output_observation.f90 output_observation.F90 sourcefile~output_observation.f90->sourcefile~output_interface.f90 sourcefile~output_overall_base.f90 output_overall_base.F90 sourcefile~output_overall_base.f90->sourcefile~output_interface.f90 sourcefile~output_overall_vtk.f90 output_overall_vtk.F90 sourcefile~output_overall_vtk.f90->sourcefile~output_interface.f90 sourcefile~output_overall_vtu.f90 output_overall_vtu.F90 sourcefile~output_overall_vtu.f90->sourcefile~output_interface.f90 sourcefile~output_system_logger.f90 output_system_logger.F90 sourcefile~output_system_logger.f90->sourcefile~output_interface.f90 sourcefile~thermal.f90->sourcefile~thermal_interface.f90 sourcefile~thermal_crs.f90 thermal_crs.F90 sourcefile~thermal_crs.f90->sourcefile~thermal_interface.f90

Source Code

module properties_properties_manager
    use, intrinsic :: iso_fortran_env, only: int32, real64
    use :: module_core, only:type_state
    use :: module_input, only:type_input
    use :: module_calculate, only:abst_gcc, abst_wrf, abst_den, abst_sph, abst_vhc, abst_thc, abst_hcf
    use :: module_control
    use :: properties_material_manager, only:type_material_manager

    implicit none
    private
    public :: type_properties_manager
    public :: type_phase_property

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Helper Derived Type to Hold Pointers for a Specific Region
    !-------------------------------------------------------------------------------------------------------------------------------
    ! Note: This type holds pointers to various material property classes
    type :: type_material_pointers
        class(abst_thc), pointer :: thc => null()
        class(abst_vhc), pointer :: vhc => null()
        class(abst_gcc), pointer :: gcc => null()
        class(abst_wrf), pointer :: wrf => null()
        class(abst_den), pointer :: den => null()
        class(abst_hcf), pointer :: hcf => null()
    end type type_material_pointers

    type :: type_phase_property
        real(real64) :: solid
        real(real64) :: water
        real(real64) :: ice
        real(real64) :: gas
    end type type_phase_property

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Main Derived Type with Generic Type-Bound Procedures
    !-------------------------------------------------------------------------------------------------------------------------------
    type :: type_properties_manager
        type(type_material_manager) :: materials
    contains
        procedure, public :: initialize => initialize_properties_manager

        ! --- Public Generic Interfaces (API remains unchanged) ---
        generic, public :: calc_thc => calculate_thc_scalar, calculate_thc_array
        generic, public :: calc_vhc => calculate_vhc_scalar, calculate_vhc_array
        generic, public :: calc_qw => calculate_qw_scalar, calculate_qw_array
        generic, public :: calc_water_content => calculate_water_content, calculate_water_content_array
        generic, public :: calc_dQw_dT => calculate_dQw_dT, calculate_dQw_dT_array
        generic, public :: calc_thermal => calc_thermal_properties_scalar, calc_thermal_properties_array
        generic, public :: calc_hcf => calculate_hcf_scalar, calculate_hcf_array
        generic, public :: calc_hydraulic => calc_hydraulic_properties_scalar, calc_hydraulic_properties_array

        ! --- Wrapper Procedures (Public facing) ---
        procedure, private, pass(self) :: calculate_thc_scalar
        procedure, private, pass(self) :: calculate_thc_array
        procedure, private, pass(self) :: calculate_vhc_scalar
        procedure, private, pass(self) :: calculate_vhc_array
        procedure, private, pass(self) :: calculate_qw_scalar
        procedure, private, pass(self) :: calculate_qw_array
        procedure, private, pass(self) :: calc_thermal_properties_scalar
        procedure, private, pass(self) :: calc_thermal_properties_array
        procedure, private, pass(self) :: calculate_hcf_scalar
        procedure, private, pass(self) :: calculate_hcf_array
        procedure, private, pass(self) :: calc_hydraulic_properties_scalar
        procedure, private, pass(self) :: calc_hydraulic_properties_array

        ! --- Implementation Procedures (Private, do the actual work) ---
        procedure, private, pass(self) :: calculate_thc_impl_scalar
        procedure, private, pass(self) :: calculate_thc_impl_array
        procedure, private, pass(self) :: calculate_vhc_impl_scalar
        procedure, private, pass(self) :: calculate_vhc_impl_array
        procedure, private, pass(self) :: calc_thermal_properties_impl_scalar
        procedure, private, pass(self) :: calc_thermal_properties_impl_array
        procedure, private, pass(self) :: calculate_hcf_impl_scalar
        procedure, private, pass(self) :: calculate_hcf_impl_array
        procedure, private, pass(self) :: calc_hydraulic_properties_impl_scalar
        procedure, private, pass(self) :: calc_hydraulic_properties_impl_array

        procedure, private, nopass :: calculate_water_content
        procedure, private, nopass :: calculate_water_content_array
        procedure, private, nopass :: calculate_dQw_dT
        procedure, private, nopass :: calculate_dQw_dT_array

        procedure, public, pass(self) :: get_phase_dens
        procedure, public, pass(self) :: get_phase_vhcs
        procedure, public, pass(self) :: get_phase_thcs
        procedure, public, pass(self) :: get_phase_sphs

        procedure, private, pass(self) :: get_pointers_for_region
    end type type_properties_manager

contains

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Initialization
    !-------------------------------------------------------------------------------------------------------------------------------
    subroutine initialize_properties_manager(self, input, ierr)
        implicit none
        class(type_properties_manager), intent(inout) :: self
        type(type_input), intent(in) :: input
        integer(int32), intent(inout) :: ierr

        call self%materials%initialize(input, ierr)
        if (ierr /= 0) then
            print *, "Error: Failed to initialize materials manager."
        end if
    end subroutine initialize_properties_manager

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Helper: Get all necessary pointers for a given region
    !-------------------------------------------------------------------------------------------------------------------------------
    ! Note: 指定された領域IDのポインタを一括で取得するヘルパー
    subroutine get_pointers_for_region(self, target_id, material_id, ptrs)
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: target_id
        integer(int32), intent(in) :: material_id
        type(type_material_pointers), intent(inout) :: ptrs

        select case (target_id)
        case (calc_thermal)
            ptrs%thc => self%materials%get_thc(material_id)
            ptrs%vhc => self%materials%get_vhc(material_id)
            ptrs%gcc => self%materials%get_gcc(material_id)
            ptrs%wrf => self%materials%get_wrf(material_id)
            ptrs%den => self%materials%get_den(material_id)

#ifdef USE_DEBUG
            if (.not. (associated(ptrs%thc) .and. associated(ptrs%vhc) .and. &
                       associated(ptrs%gcc) .and. associated(ptrs%wrf) .and. associated(ptrs%den))) then
                stop "Error: Failed to associate one or more material pointers."
            end if
#endif
        case (calc_hydraulic)
            ptrs%den => self%materials%get_den(material_id)
            ptrs%hcf => self%materials%get_hcf(material_id)

#ifdef USE_DEBUG
            if (.not. (associated(ptrs%gcc) .and. associated(ptrs%wrf) .and. &
                       associated(ptrs%den) .and. associated(ptrs%hcf))) then
                stop "Error: Failed to associate one or more material pointers."
            end if
#endif
        end select
    end subroutine get_pointers_for_region

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Helper: Calculate common properties (water content)
    !-------------------------------------------------------------------------------------------------------------------------------
    pure elemental subroutine calculate_water_content(ptrs, state)
        implicit none
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: state

        state%density_water = ptrs%den%material2
        state%density_ice = ptrs%den%material3
        state%water_content = ptrs%wrf%calc(-ptrs%gcc%calc(state))
    end subroutine calculate_water_content

    pure subroutine calculate_water_content_array(ptrs, states)
        implicit none
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: states(:)

        call calculate_water_content(ptrs, states(:))

    end subroutine calculate_water_content_array

    pure elemental subroutine calculate_dQw_dT(ptrs, state)
        implicit none
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: state

        state%density_water = ptrs%den%material2
        state%density_ice = ptrs%den%material3
        state%dQw_dT = ptrs%wrf%deriv(-ptrs%gcc%calc(state)) * ptrs%gcc%deriv(state)

    end subroutine calculate_dQw_dT

    pure subroutine calculate_dQw_dT_array(ptrs, states)
        implicit none
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: states(:)

        call calculate_dQw_dT(ptrs, states(:))

    end subroutine calculate_dQw_dT_array

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Thermal Conductivity (THC)
    !-------------------------------------------------------------------------------------------------------------------------------
    ! --- Wrapper ---
    function calculate_thc_scalar(self, material_id, state) result(val)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: state
        real(real64) :: val

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_thermal, material_id, ptrs)
        val = self%calculate_thc_impl_scalar(ptrs, state)
    end function calculate_thc_scalar

    ! --- Implementation ---
    function calculate_thc_impl_scalar(self, ptrs, state) result(val)
        implicit none
        class(type_properties_manager), intent(in) :: self
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: state
        real(real64) :: val

        call self%calculate_water_content(ptrs, state)
        val = ptrs%thc%calc(state)
    end function calculate_thc_impl_scalar

    ! --- Wrapper (Array) ---
    function calculate_thc_array(self, material_id, states) result(vals)
        implicit none
        class(type_properties_manager), intent(in) :: self
        type(type_state), intent(inout) :: states(:)
        integer(int32), intent(in) :: material_id
        real(real64) :: vals(size(states))

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_thermal, material_id, ptrs)
        vals = self%calculate_thc_impl_array(ptrs, states)
    end function calculate_thc_array

    ! --- Implementation (Array) ---
    function calculate_thc_impl_array(self, ptrs, states) result(vals)
        implicit none
        class(type_properties_manager), intent(in) :: self
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: states(:)
        real(real64) :: vals(size(states))

        integer(int32) :: i

        call self%calc_water_content(ptrs, states)
        do i = 1, size(states)
            vals(i) = self%calculate_thc_impl_scalar(ptrs, states(i))
        end do
    end function calculate_thc_impl_array

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Volumetric Heat Capacity (VHC) Implementation
    !-------------------------------------------------------------------------------------------------------------------------------
    ! --- Wrapper ---
    function calculate_vhc_scalar(self, material_id, state) result(val)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: state
        real(real64) :: val

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_thermal, material_id, ptrs)
        val = self%calculate_vhc_impl_scalar(ptrs, state)
    end function calculate_vhc_scalar

    ! --- Implementation ---
    function calculate_vhc_impl_scalar(self, ptrs, state) result(val)
        implicit none
        class(type_properties_manager), intent(in) :: self
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: state
        real(real64) :: val

        call self%calculate_water_content(ptrs, state)
        call self%calculate_dQw_dT(ptrs, state)
        val = ptrs%vhc%calc(state)
    end function calculate_vhc_impl_scalar

    ! --- Wrapper (Array) ---
    function calculate_vhc_array(self, material_id, states) result(vals)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: states(:)
        real(real64) :: vals(size(states))

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_thermal, material_id, ptrs)
        vals = self%calculate_vhc_impl_array(ptrs, states)
    end function calculate_vhc_array

    ! --- Implementation (Array) ---
    function calculate_vhc_impl_array(self, ptrs, states) result(vals)
        implicit none
        class(type_properties_manager), intent(in) :: self
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: states(:)
        real(real64) :: vals(size(states))

        integer(int32) :: i

        call self%calc_water_content(ptrs, states)
        call self%calc_dQw_dT(ptrs, states)
        do i = 1, size(states)
            vals(i) = self%calculate_vhc_impl_scalar(ptrs, states(i))
        end do
    end function calculate_vhc_impl_array

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Water Content (qw) Implementation
    !-------------------------------------------------------------------------------------------------------------------------------
    ! --- Wrapper ---
    function calculate_qw_scalar(self, material_id, state) result(val)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: state
        real(real64) :: val

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_thermal, material_id, ptrs)
        call self%calc_water_content(ptrs, state)
        val = state%water_content
    end function calculate_qw_scalar

    ! --- Wrapper (Array) ---
    function calculate_qw_array(self, material_id, states) result(vals)
        implicit none
        class(type_properties_manager), intent(in) :: self
        type(type_state), intent(inout) :: states(:)
        integer(int32), intent(in) :: material_id
        real(real64) :: vals(size(states))

        type(type_material_pointers) :: ptrs
        integer(int32) :: i

        call self%get_pointers_for_region(calc_thermal, material_id, ptrs)
        call self%calc_water_content(ptrs, states)
        do i = 1, size(states)
            vals(i) = states(i)%water_content
        end do
    end function calculate_qw_array

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Thermal Properties Calculation
    !-------------------------------------------------------------------------------------------------------------------------------
    ! --- Wrapper ---
    subroutine calc_thermal_properties_scalar(self, material_id, state, thc, vhc)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: state
        real(real64), intent(inout) :: thc
        real(real64), intent(inout) :: vhc

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_thermal, material_id, ptrs)
        call self%calc_thermal_properties_impl_scalar(state, ptrs, thc, vhc)
    end subroutine calc_thermal_properties_scalar

    ! --- Implementation ---
    subroutine calc_thermal_properties_impl_scalar(self, state, ptrs, thc, vhc)
        class(type_properties_manager), intent(in) :: self
        type(type_state), intent(inout) :: state
        type(type_material_pointers), intent(in) :: ptrs
        real(real64), intent(inout) :: thc
        real(real64), intent(inout) :: vhc

        call self%calculate_water_content(ptrs, state)
        call self%calculate_dQw_dT(ptrs, state)

        thc = ptrs%thc%calc(state)
        vhc = ptrs%vhc%calc(state=state)

    end subroutine calc_thermal_properties_impl_scalar

    ! --- Wrapper (Array) ---
    subroutine calc_thermal_properties_array(self, material_id, states, thcs, vhcs)
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: states(:)
        real(real64), intent(inout) :: thcs(size(states))
        real(real64), intent(inout) :: vhcs(size(states))

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_thermal, material_id, ptrs)
        call self%calc_thermal_properties_impl_array(ptrs, states, thcs, vhcs)

    end subroutine calc_thermal_properties_array

    ! --- Implementation (Array) ---
    subroutine calc_thermal_properties_impl_array(self, ptrs, states, thcs, vhcs)
        class(type_properties_manager), intent(in) :: self
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: states(:)
        real(real64), intent(inout) :: thcs(size(states))
        real(real64), intent(inout) :: vhcs(size(states))

        integer(int32) :: i

        call self%calc_water_content(ptrs, states)
        call self%calc_dQw_dT(ptrs, states)

        do i = 1, size(states)
            thcs(i) = self%calculate_thc_impl_scalar(ptrs, states(i))
            vhcs(i) = self%calculate_vhc_impl_scalar(ptrs, states(i))
        end do
    end subroutine calc_thermal_properties_impl_array

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Hydraulic Conductivity (HCF) Implementation
    !-------------------------------------------------------------------------------------------------------------------------------
    ! --- Wrapper ---
    function calculate_hcf_scalar(self, material_id, state) result(val)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: state
        real(real64) :: val

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_hydraulic, material_id, ptrs)
        val = self%calculate_hcf_impl_scalar(ptrs, state)
    end function calculate_hcf_scalar

    ! --- Implementation ---
    function calculate_hcf_impl_scalar(self, ptrs, state) result(val)
        implicit none
        class(type_properties_manager), intent(in) :: self
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: state
        real(real64) :: val

        call self%calc_water_content(ptrs, state)
        state%ice_content = state%porosity - state%water_content

        val = ptrs%hcf%calc_kflh(state)
    end function calculate_hcf_impl_scalar

    ! --- Wrapper (Array) ---
    function calculate_hcf_array(self, material_id, states) result(vals)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: states(:)
        real(real64) :: vals(size(states))

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_hydraulic, material_id, ptrs)

        vals = self%calculate_hcf_impl_array(ptrs, states)
    end function calculate_hcf_array

    ! --- Implementation (Array) ---
    function calculate_hcf_impl_array(self, ptrs, states) result(vals)
        implicit none
        class(type_properties_manager), intent(in) :: self
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: states(:)
        real(real64) :: vals(size(states))

        integer(int32) :: i

        ! 1. 水分量を配列全体に対して一度に計算
        call self%calc_water_content(ptrs, states)

        ! 2. ループ内で各点の氷含有量を計算し、HCFを求める
        do i = 1, size(states)
            states(i)%ice_content = states(i)%porosity - states(i)%water_content
            vals(i) = self%calculate_hcf_impl_scalar(ptrs, states(i))
        end do
    end function calculate_hcf_impl_array

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Hydraulic Properties Calculation
    !-------------------------------------------------------------------------------------------------------------------------------
    ! --- Wrapper ---
    subroutine calc_hydraulic_properties_scalar(self, material_id, state, kflh)
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: state
        real(real64), intent(inout) :: kflh

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_hydraulic, material_id, ptrs)
        call self%calc_hydraulic_properties_impl_scalar(state, ptrs, kflh)
    end subroutine calc_hydraulic_properties_scalar

    ! --- Implementation ---
    subroutine calc_hydraulic_properties_impl_scalar(self, state, ptrs, kflh)
        class(type_properties_manager), intent(in) :: self
        type(type_state), intent(inout) :: state
        type(type_material_pointers), intent(in) :: ptrs
        real(real64), intent(inout) :: kflh

        kflh = ptrs%hcf%calc_kflh(state)
        state%density_water = ptrs%den%material2
        state%density_ice = ptrs%den%material3

    end subroutine calc_hydraulic_properties_impl_scalar

    ! --- Wrapper (Array) ---
    subroutine calc_hydraulic_properties_array(self, material_id, states, kflhs)
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_state), intent(inout) :: states(:)
        real(real64), intent(inout) :: kflhs(size(states))

        type(type_material_pointers) :: ptrs

        call self%get_pointers_for_region(calc_hydraulic, material_id, ptrs)
        call self%calc_hydraulic_properties_impl_array(ptrs, states, kflhs)

    end subroutine calc_hydraulic_properties_array

    ! --- Implementation (Array) ---
    subroutine calc_hydraulic_properties_impl_array(self, ptrs, states, kflhs)
        class(type_properties_manager), intent(in) :: self
        type(type_material_pointers), intent(in) :: ptrs
        type(type_state), intent(inout) :: states(:)
        real(real64), intent(inout) :: kflhs(size(states))

        integer(int32) :: i

        do i = 1, size(states)
            kflhs(i) = ptrs%hcf%calc_kflh(states(i))
            states(i)%density_water = ptrs%den%material2
            states(i)%density_ice = ptrs%den%material3
        end do
    end subroutine calc_hydraulic_properties_impl_array

    !-------------------------------------------------------------------------------------------------------------------------------
    ! Get Phase Property
    !-------------------------------------------------------------------------------------------------------------------------------
    function get_phase_dens(self, material_id) result(phase_property)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_phase_property) :: phase_property

        class(abst_den), pointer :: den_ptr => null()

        den_ptr => self%materials%get_den(material_id)

#ifdef USE_DEBUG
        if (.not. associated(den_ptr)) then
            print *, "Error in get_phase_property: Failed to get density pointer for material_id =", material_id
            stop "FATAL ERROR: DENSITY POINTER NOT FOUND"
        end if
#endif

        phase_property%solid = den_ptr%material1
        phase_property%water = den_ptr%material2
        phase_property%ice = den_ptr%material3
        phase_property%gas = den_ptr%material4

    end function get_phase_dens

    function get_phase_sphs(self, material_id) result(phase_property)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_phase_property) :: phase_property

        class(abst_sph), pointer :: sph_ptr => null()

        sph_ptr => self%materials%get_sph(material_id)

#ifdef USE_DEBUG
        if (.not. associated(sph_ptr)) then
            print *, "Error in get_phase_property: Failed to get specific heat pointer for material_id =", material_id
            stop "FATAL ERROR: SPECIFIC HEAT POINTER NOT FOUND"
        end if
#endif

        phase_property%solid = sph_ptr%material1
        phase_property%water = sph_ptr%material2
        phase_property%ice = sph_ptr%material3
        phase_property%gas = sph_ptr%material4

    end function get_phase_sphs

    function get_phase_vhcs(self, material_id) result(phase_property)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_phase_property) :: phase_property

        class(abst_vhc), pointer :: vhc_ptr => null()

        vhc_ptr => self%materials%get_vhc(material_id)

#ifdef USE_DEBUG
        if (.not. associated(vhc_ptr)) then
            print *, "Error in get_phase_property: Failed to get volumetric heat capacity pointer for material_id =", material_id
            stop "FATAL ERROR: VOLUMETRIC HEAT CAPACITY POINTER NOT FOUND"
        end if
#endif

        phase_property%solid = vhc_ptr%material1
        phase_property%water = vhc_ptr%material2
        phase_property%ice = vhc_ptr%material3
        phase_property%gas = vhc_ptr%material4

    end function get_phase_vhcs

    function get_phase_thcs(self, material_id) result(phase_property)
        implicit none
        class(type_properties_manager), intent(in) :: self
        integer(int32), intent(in) :: material_id
        type(type_phase_property) :: phase_property

        class(abst_thc), pointer :: thc_ptr => null()

        thc_ptr => self%materials%get_thc(material_id)

#ifdef USE_DEBUG
        if (.not. associated(thc_ptr)) then
            print *, "Error in get_phase_property: Failed to get thermal heat capacity pointer for material_id =", material_id
            stop "FATAL ERROR: THERMAL HEAT CAPACITY POINTER NOT FOUND"
        end if
#endif

        phase_property%solid = thc_ptr%material1
        phase_property%water = thc_ptr%material2
        phase_property%ice = thc_ptr%material3
        phase_property%gas = thc_ptr%material4

    end function get_phase_thcs

end module properties_properties_manager