Я пытаюсь построить структуру вложенного типа с помощью следующего объявления:
TYPE T_ORCH_DISCR
REAL(r_std), ALLOCATABLE, DIMENSION (:,:) :: simp !
REAL(r_std), ALLOCATABLE, DIMENSION (:,:,:) :: disc !
CONTAINS
PROCEDURE :: initialize
END TYPE T_ORCH_DISCR
t_orch_discr
инициализация:
SUBROUTINE initialize(this, kjpindex, argsec, discrdim)
CLASS(T_ORCH_DISCR), INTENT(inout) :: this
INTEGER(i_std), INTENT(in) :: kjpindex
INTEGER(i_std), INTENT(in) :: argsec
INTEGER(i_std), INTENT(in), OPTIONAL :: discrdim
INTEGER(i_std) :: ier
has_discretization = .FALSE.
IF (PRESENT(discrdim)) THEN
has_discretization = discrdim
ENDIF
IF (.NOT. has_discretization) THEN
ALLOCATE (this%simp(kjpindex,argsec),stat=ier)
ELSE
ALLOCATE (this%disc(kjpindex,argsec,discrdim),stat=ier)
ENDIF
END SUBROUTINE initialize
Будет выделено либо simp
, либо disc
, но они не будут распределены одновременно.
И
TYPE T_MC_HYDRO
TYPE(T_ORCH_DISCR) :: mc_layh
TYPE(T_ORCH_DISCR) :: mcl_layh
TYPE(T_ORCH_DISCR) :: soilmoist
CONTAINS
PROCEDURE :: initialize
END TYPE T_MC_HYDRO
t_mc_hydro
инициализация:
SUBROUTINE initialize(this, kjpindex, nslm, nstm, nvm)
CLASS(T_MC_HYDRO), INTENT(inout) :: this
INTEGER(i_std), INTENT(in) :: kjpindex
INTEGER(i_std), INTENT(in) :: nslm
INTEGER(i_std), INTENT(in), OPTIONAL :: nstm
INTEGER(i_std), INTENT(in), OPTIONAL :: nvm
INTEGER(i_std) :: ier
has_discretization = .FALSE.
IF (PRESENT(nvm) .AND. PRESENT(nstm)) THEN
has_discretization = .TRUE.
ENDIF
IF (has_discretization) THEN
CALL this%mc_layh%initialize(kjpindex, nslm, nstm)
CALL this%mcl_layh%initialize(kjpindex, nslm, nstm)
CALL this%soilmoist%initialize(kjpindex, nslm, nvm)
ELSE
CALL this%mc_layh%initialize(kjpindex, nslm)
CALL this%mcl_layh%initialize(kjpindex, nslm)
CALL this%soilmoist%initialize(kjpindex, nslm)
ENDIF
END SUBROUTINE initialize
Объявлен в глобальной области видимости модуля где-то еще:
TYPE(T_MC_HYDRO), SAVE :: t_mc_hydrol
Намерение сделать t_mc_hydrol
постоянным, когда модуль выходит из области видимости. Но текущий код не дает такого эффекта. Я изо всех сил пытаюсь понять лучший подход.
Обновление
Для воспроизведения вопроса:
Основная программа:
PROGRAM unittests
USE types_tests
IMPLICIT NONE
TYPE(T_MC_HYDRO), SAVE :: torch_test
INTEGER(i_std), PARAMETER :: kjpindex=20, nslm=10
CALL torch_test%initialize(kjpindex, nslm)
CALL types_tests_init(torch_test)
CALL types_tests_main(torch_test)
END PROGRAM unittests
Промежуточный модуль, использованный в исходном коде:
MODULE types_tests
USE ioipsl_para
USE type_moisture_content_hydro
IMPLICIT NONE
CONTAINS
SUBROUTINE types_tests_init(torch_test)
TYPE(T_MC_HYDRO), INTENT(out) :: torch_test
torch_test%mc_layh%simp = 22.0
torch_test%mcl_layh%simp = 23.0
END SUBROUTINE types_tests_init
SUBROUTINE types_tests_main(torch_test)
TYPE(T_MC_HYDRO), INTENT(out) :: torch_test
INTEGER(i_std) :: ji, jl
DO ji=1, 20 ! kjpindex ! 20
DO jl=1, 10 ! nslm
torch_test%mc_layh%simp(ji,jl) = 25.0 !! <--- code fails here
torch_test%mcl_layh%simp(ji,jl) = 24.0
ENDDO
ENDDO
END SUBROUTINE types_tests_main
END MODULE types_tests
Код ошибки:
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
unittests.exe 00000000005B3E14 Unknown Unknown Unknown
libpthread-2.17.s 00002B1D3DDE35E0 Unknown Unknown Unknown
unittests.exe 0000000000410F9B types_tests_mp_ty 78 types_tests.f90
unittests.exe 000000000040CEB5 MAIN__ 64 unittests.f90
unittests.exe 000000000040C95E Unknown Unknown Unknown
libc-2.17.so 00002B1D3E215C05 __libc_start_main Unknown Unknown
unittests.exe 000000000040C869 Unknown Unknown Unknown
srun: error: irene1124: task 0: Exited with exit code 174