최소화를 위해 일반적인 용도의 서브 루틴을 작성하려고합니다. 범용 서브 루틴을 원하기 때문에 객관적인 함수는 이름뿐 아니라 차원에서도 다른 매개 변수를 가질 수 있습니다. 그래서 매개 변수 구조를 전달할 방법이 필요합니다. (제 생각에는 Matlab에서 구조체 유형 변수와 같은 것을 사용하기 때문에 단어 구조를 사용하고 있습니다). 파생 데이터 형식을 사용할 수 있었지만 동일한 프로그램에서 두 가지 목적 함수가있을 때 문제가 발생합니다. 내가 CALL MYSUB(sol2,OBJ2,PARAM2)
과 PRINT *,sol2
로 라인을 코멘트 경우,포트란 : 임의의 "구조체"를 모듈 서브 루틴으로 전달
MODULE MYPAR
IMPLICIT NONE
TYPE PARPASS1 !! Parameter passing structure 1
INTEGER :: a
REAL :: X(2,2)
END TYPE PARPASS1
TYPE PARPASS2 !! Parameter passing structure 2
REAL :: b
REAL :: Y(3)
END TYPE PARPASS2
END MODULE MYPAR
PROGRAM MAIN
USE MYPAR
USE MYLIB
IMPLICIT NONE
INTEGER :: am
REAL :: bm,Xm(2,2),Ym(3),sol1,sol2
TYPE(PARPASS1) :: PARAM1
TYPE(PARPASS2) :: PARAM2
am = 1
bm = 3.5
Xm(1,:) = [1.0, 2.0]
Xm(2,:) = [0.5, 2.5]
Ym(1:3) = [0.25,0.50,0.75]
PARAM1%a = am
PARAM1%X = Xm
PARAM2%b = bm
PARAM2%Y = Ym
CALL MYSUB(sol1,OBJ1,PARAM1)
CALL MYSUB(sol2,OBJ2,PARAM2)
PRINT *,sol1
PRINT *,sol2
CONTAINS
SUBROUTINE OBJ1(sumval,PARAM)
REAL,INTENT(OUT) :: sumval
TYPE(PARPASS1),INTENT(IN) :: PARAM
INTEGER :: a
REAL,ALLOCATABLE :: X(:,:)
a = PARAM%a
X = PARAM%X
sumval = a+X(1,1)+X(2,2)
END SUBROUTINE OBJ1
SUBROUTINE OBJ2(divval,PARAM)
REAL,INTENT(OUT) :: divval
TYPE(PARPASS2),INTENT(IN) :: PARAM
REAL :: b
REAL,ALLOCATABLE :: Y(:)
b = PARAM%b
Y = PARAM%Y
divval = b/(Y(1)+Y(2))
END SUBROUTINE OBJ2
END PROGRAM MAIN
그리고 mylib.90
MODULE MYLIB
USE MYPAR
IMPLICIT NONE
CONTAINS
SUBROUTINE MYSUB(sol,FN,PARAM)
REAL,INTENT(OUT) :: sol
TYPE(PARPASS1), INTENT(IN) :: PARAM
CALL FN(sol,PARAM)
sol = 2*sol
END SUBROUTINE MYSUB
END MODULE MYLIB
분명히라는 모듈 : 주 프로그램 main.f90에서
:이 샘플 코드 내 코드가 원활하게 실행됩니다. 이것은 두 가지 "객관적인 함수"를 갖기 전 이었지만 지금은 MYSUB의 파생 된 유형 변수 PARPASS1이 임의적이어서는 안되기 때문에 작동하지 않습니다.
아이디어가 있으십니까?
감사합니다. 이것은 현재의 문제를 해결할 것이지만 불행히도 어떤 식 으로든 일반적인 해결책은 아닙니다. 누군가 MYSUB에 3 번 이상 전화해야한다면 어떻게해야합니까? MYSUB의 복사본을 다른 PARPASS 유형에 대해 복사하고 붙여 넣는 것은 거의 의미가 없습니다. 일반적인 목적의 서브 루틴 (생각하면)을 수정하지 않아도되기 때문입니다. 이 문제를 해결할 다른 방법이 없습니까? 파생 데이터 형식을 사용할 필요는 없습니다. 이것은 단지 초기 접근이었습니다. –
@ Lord_77 더 확장 성 있어야하는 새로운 솔루션을 추가했습니다. – Exascale
그냥 부탁드립니다. 서브 루틴의 입력으로 형식 이름을 전달하는 것이 가능하지 않습니까? 그래서 우리는 MYSUB이라고 부릅니다. 단지 CALL MYSUB (sol1, 'PARPASS1', PARAM1) 만 입력하면됩니다. 이 경우 'PARPASS1'은 MYSUB에서 PARAM1의 유형을 선언하는 데 사용되는 문자열이 될 수 있습니다. @ kyle-g –