How to pass derived type argument to a subroutine

Click For Summary

Discussion Overview

The discussion revolves around how to properly pass a derived type argument to a subroutine in Fortran, specifically addressing issues related to type declarations and scope. Participants explore methods for making derived types accessible across different modules or files.

Discussion Character

  • Technical explanation
  • Debate/contested

Main Points Raised

  • One participant describes a derived type and an array of that type, expressing difficulty in passing it to a subroutine due to type declaration errors.
  • Another participant suggests using include files to make type definitions accessible across multiple modules, drawing a parallel to C/C++ practices.
  • Some participants express skepticism about the necessity of including type definitions multiple times, questioning the efficiency of such an approach.
  • A later reply introduces the concept of using modules in Fortran to declare types and variables globally, suggesting that this method is preferable to using include files.
  • One participant reports success after implementing a module for the derived type and its array, noting that it simplified function arguments.

Areas of Agreement / Disagreement

Participants generally agree on the utility of using modules for global type definitions, though there is some debate about the use of include files versus modules. The discussion reflects multiple viewpoints on best practices for managing type definitions in Fortran.

Contextual Notes

Participants mention potential issues with local variable scope when using include files and the advantages of modules for shared data. There is no consensus on the best approach, as participants weigh the pros and cons of each method.

shitij
Messages
19
Reaction score
0
Hi all !

I have a derived type as:

Code:
TYPE type_atom_type_info
		integer:: type_code
		character(len=4)::type_cname
		real(kind=dbl)::mass
	end TYPE type_atom_type_info
I have an array of this type as:
Code:
TYPE(type_atom_type_info) atom_type_info(250)

I want to pass this array to a subroutine. I have made an interface in the same file for the subroutine

Code:
interface
		subroutine cname_to_code(atom_type_info,cname,code)
			TYPE(type_atom_type_info),intent(in)::atom_type_info(250)
			character(len=4),intent(in)::cname
			integer,intent(out)::code
		end subroutine cname_to_code		
	end interface

But I am getting an error as:
Code:
nma.f90:234.60:

   TYPE(type_atom_type_info),intent(in)::atom_type_info(250)
                                                            1
Error: the type of 'atom_type_info' at (1) has not been declared within the interface
nma.f90:1496.20:

 call cname_to_code(atom_type_info,'NH1',temp_k)
                    1
Error: Type mismatch in argument 'atom_type_info' at (1); passed TYPE(type_atom_type_info) to REAL(4)
nma.f90:4072.26:

 TYPE(type_atom_type_info),intent(in)::atom_type_info(250)
                          1
Error: Derived type 'type_atom_type_info' at (1) is being used before it is defined

I tried redefining the whole TYPE in the interface, but that didn't work.
How do I make the type 'global' ? Or is there any other way to pass derived type arguments to functions?

Thank you in advance !
 
Technology news on Phys.org
Hey garbageij.

You will need to reference this definition in each module. In C/C++ We use include files to include definitons for the source files and also for other header files that use those definitions.

I just searched google and I believe the statement is INCLUDE 'file'. What you should do is save your definitions to some file (all your common data types) and include this file everytime you need to use and work with data of that type.
 
Hmm...so I guess there's no other way, huh?
Thanks !
 
garbageij said:
Hmm...so I guess there's no other way, huh?
Thanks !

You can copy the type statement and throw it in the module, but that's not a good thing to do.

It's better to update one include file than trying to search for every single instance. Imagine if you had 20 classes that used the one definition and then imagine having to each everything 20 times!

This is why we have include files.
 
A couple of comments.

Writing a separate file with such declaration and including it everywhere you need it, it's one thing...if just like that...you will simply get a local variable everywhere

BUT,

If you include the declaration and a common block THEN, you will get all those subroutines to use the same varaibles...even if it is not 'global'

The Fortran 90 way of making some variables global is via a MODULE...you just create a module, put in there all the variables you need to use in your various subroutines...then, wherever you need them, instead of the "include" statement, you do "use modulename"
 
Thank you so much for your replies !

So I have made a module, in which I have put the derived type as well as the array, and now it's working fine. Making a module it seems was a good idea to begin with as now some of my function take less arguments (a few arguments were common to many functions)


Thanks again !
 

Similar threads

  • · Replies 5 ·
Replies
5
Views
8K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 59 ·
2
Replies
59
Views
12K
  • · Replies 6 ·
Replies
6
Views
3K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 10 ·
Replies
10
Views
6K
  • · Replies 2 ·
Replies
2
Views
2K