How to pass derived type argument to a subroutine

In summary, this conversation covers how to pass a derived type to a function. The first step is to create an interface and make a subroutine. The next step is to reference the definition for the derived type in the interface. However, this does not work because the type is not defined within the interface. The final step is to make the type global by creating a module.
  • #1
shitij
19
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
  • #2
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.
 
  • #3
Hmm...so I guess there's no other way, huh?
Thanks !
 
  • #4
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.
 
  • #5
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"
 
  • #6
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 !
 

FAQ: How to pass derived type argument to a subroutine

How do I pass a derived type argument to a subroutine in Fortran?

In Fortran, derived types are passed by reference, meaning that the actual argument is not copied but rather a pointer to the derived type is passed to the subroutine. This allows the subroutine to directly access and modify the original derived type.

Can I pass a derived type argument by value?

No, derived types cannot be passed by value in Fortran. This is because derived types can potentially be large and copying them by value would be inefficient. Additionally, passing by reference allows the subroutine to modify the original derived type, which would not be possible if passed by value.

Do I need to declare the derived type in the subroutine if I want to pass it as an argument?

Yes, the derived type must be declared in the subroutine before it can be passed as an argument. This is to ensure that the subroutine knows the structure and types of the variables within the derived type.

Can I pass a derived type argument to a subroutine in any order?

Yes, the order in which the derived type arguments are passed to a subroutine does not matter as long as the correct number of arguments are passed and the data types match the declared types in the subroutine.

How do I access the components of a derived type argument within a subroutine?

To access the components of a derived type argument within a subroutine, you can use the % operator. For example, if the derived type argument is named "my_type", and it has a component named "my_component", you can access it as "my_type%my_component" within the subroutine.

Similar threads

Replies
5
Views
7K
Replies
3
Views
2K
Replies
59
Views
10K
Replies
6
Views
3K
Replies
8
Views
4K
Replies
7
Views
2K
Replies
2
Views
1K
Replies
5
Views
3K
Back
Top