- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey
I have a circular dependencie. Is there any way to solve this in fortran?
MODULE mElement USE mProject IMPLICIT NONE PRIVATE PUBLIC :: tElement TYPE :: tElement INTEGER(4) :: element_property = 1234 TYPE(tProject), POINTER :: project CONTAINS PROCEDURE, PUBLIC :: routine_using_project_data => routine_using_project_data END TYPE tElement CONTAINS SUBROUTINE routine_using_project_data(this) IMPLICIT NONE CLASS(tElement) :: this REAL(8) :: project_property(10) project_property = this%project%project_property END SUBROUTINE routine_using_project_data END MODULE mElement MODULE mProject USE mElement TYPE :: tProject TYPE(tElement), ALLOCATABLE :: elements(:) REAL(8) :: project_property(10) END TYPE tProject END MODULE mProject PROGRAM TEST USE mElement USE mProject IMPLICIT NONE TYPE(tProject) :: project CALL project%elements(1)%routine_using_project_data() END PROGRAM TEST
I have Superclass which is containing Subclass Objects. The Subclass should point back to its Superclass
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian is right - I misread the error message I got with an adjusted version of the program.
Here is the version that is accepted (it does not do anything useful of course :)):
MODULE mElement IMPLICIT NONE PRIVATE PUBLIC :: tElement, tProject TYPE :: tElement INTEGER(4) :: element_property = 1234 TYPE(tProject), POINTER :: project END TYPE tElement TYPE :: tProject TYPE(tElement), ALLOCATABLE :: elements(:) END TYPE tProject END MODULE mElement PROGRAM TEST USE mElement IMPLICIT NONE TYPE(tProject) :: project END PROGRAM TEST
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I thought the problem could be solved by merging the two modules, but no, you have a sort of forward use of tProject - it is not yet defined when you use it.
Solutions might be:
- Define a dummy type of which you let tProject be an extension
- Avoid the circularity altogether. As I am not sure what you are trying to achieve, that may or may not be simple
Fortran does allow types to be defined recursively, but that is no solution here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If the types were in the same module, then the forward reference is fine. What I think Arjen is referring to by recursive definition is just a specific case of the general rule - you can forward reference a type that is defined in the same scope in a pointer or allocatable component.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian is right - I misread the error message I got with an adjusted version of the program.
Here is the version that is accepted (it does not do anything useful of course :)):
MODULE mElement IMPLICIT NONE PRIVATE PUBLIC :: tElement, tProject TYPE :: tElement INTEGER(4) :: element_property = 1234 TYPE(tProject), POINTER :: project END TYPE tElement TYPE :: tProject TYPE(tElement), ALLOCATABLE :: elements(:) END TYPE tProject END MODULE mElement PROGRAM TEST USE mElement IMPLICIT NONE TYPE(tProject) :: project END PROGRAM TEST
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Arjen Markus wrote:
Ian is right - I misread the error message I got with an adjusted version of the program.
Here is the version that is accepted (it does not do anything useful of course :)):
MODULE mElement IMPLICIT NONE PRIVATE PUBLIC :: tElement, tProject TYPE :: tElement INTEGER(4) :: element_property = 1234 TYPE(tProject), POINTER :: project END TYPE tElement TYPE :: tProject TYPE(tElement), ALLOCATABLE :: elements(:) END TYPE tProject END MODULE mElement PROGRAM TEST USE mElement IMPLICIT NONE TYPE(tProject) :: project END PROGRAM TEST
Thanks a lot. I will add some usefull routines :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately I have to combine now a lot of different module and type in one big module with several thousand lines, which is not that handy. I discovered that I can also use submodules. This article from Dr. Fortran explains the basics and also this articel. But they do not explain how to handle type bounded subroutine and functions in submodules or how I can go around the circumference problem. How can I use tElement in tProject If I am not allowed in mElement to declare tElement public? Visa versa it is working. tElement is allowed to have a pointer to tProject.
mElement.f90
SUBMODULE (mProject) mElement TYPE :: tElement INTEGER(4) :: element_property = 1234 TYPE(tProject), POINTER :: project CONTAINS PROCEDURE :: test1 => test_element END TYPE tElement CONTAINS MODULE SUBROUTINE routine_using_project_data(elements_property) IMPLICIT NONE REAL(8), INTENT(IN) :: elements_property REAL(8) :: project_property project_property = elements_property END SUBROUTINE routine_using_project_data SUBROUTINE test_element(this) IMPLICIT NONE CLASS(tElement) :: this END SUBROUTINE test_element END SUBMODULE mElement
Test.f90
MODULE mProject IMPLICIT NONE PRIVATE ! TYPES PUBLIC :: tProject ! SUBROUTINES PUBLIC :: routine_using_project_data INTERFACE MODULE SUBROUTINE routine_using_project_data(elements_property) REAL(8), INTENT(IN) :: elements_property END SUBROUTINE END INTERFACE TYPE :: tProject REAL(8) :: project_property(10) = 10 END TYPE tProject CONTAINS END MODULE mProject PROGRAM TEST USE mProject IMPLICIT NONE TYPE(tProject), TARGET :: project REAL(8) :: elements_property elements_property = 5 CALL routine_using_project_data(elements_property) END PROGRAM TEST
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Put the type definitions in the scope of the module along with procedure interface definitions, put the procedure bodies in submodules.
MODULE mProject IMPLICIT NONE PRIVATE ! TYPES PUBLIC :: tProject ! SUBROUTINES PUBLIC :: routine_using_project_data INTEGER, PARAMETER, PUBLIC :: rk = KIND(1.0D0) INTEGER, PARAMETER :: ik = KIND(1) TYPE :: tProject REAL(rk) :: project_property(10) = 10 END TYPE tProject TYPE :: tElement INTEGER(ik) :: element_property = 1234 TYPE(tProject), POINTER :: project CONTAINS PROCEDURE :: test1 => test_element END TYPE tElement INTERFACE MODULE SUBROUTINE routine_using_project_data(elements_property) IMPLICIT NONE REAL(rk), INTENT(IN) :: elements_property END SUBROUTINE MODULE SUBROUTINE test_element(this) IMPLICIT NONE CLASS(tElement) :: this END SUBROUTINE test_element END INTERFACE END MODULE mProject SUBMODULE (mProject) mElement IMPLICIT NONE CONTAINS MODULE SUBROUTINE routine_using_project_data(elements_property) REAL(rk), INTENT(IN) :: elements_property REAL(rk) :: project_property project_property = elements_property END SUBROUTINE routine_using_project_data MODULE SUBROUTINE test_element(this) CLASS(tElement) :: this END SUBROUTINE test_element END SUBMODULE mElement PROGRAM TEST USE mProject IMPLICIT NONE TYPE(tProject), TARGET :: project REAL(rk) :: elements_property elements_property = 5 CALL routine_using_project_data(elements_property) END PROGRAM TEST
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
perfect thanks a lot. Thats exactly what I need.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page