From: aborel on
Good evening
I am writing a program which mainly converts text input files in
different file formats (ASCII) as input for FEM Pre-and
Postprocessors.
The program reads the input data in an array (init_material_data) of
the type material_data and then writes the data in a different file
format doing different conversions.
Due to the different maximum lengths of the input variables I have to
use of a derived type variable which is in module "defs".
!
!
module defs
!
implicit none
!
type material_data
character(8) :: id
character(256) :: name
character(2) :: type
character(10) :: info1
character(10) :: info2
character(12), dimension(25) :: mat_data
end type material_data
!
type(material_data), pointer, dimension(:) :: init_mat_data
type(material_data) :: iso_mat_data
!
end module defs
!
!

Now I searched my books and this group for a description of how to
initialize above derived type "init_mat_data" but the only way I can
imagine would be

do m=1,n_rows,1

init_mat_data(m)%id = "xx"
init_mat_data(m)%name = "xx"
init_mat_data(m)%type = "xx"
init_mat_data(m)%info1 = "xx"
init_mat_data(m)%info2 = "xx"
do j=1,25,1
init_mat_data(m)%mat_data(j) = "xx"
end do
end do

at run time. The same with the derived type iso_mat_data.

Is there any more elegant way of solving this problem, it seems to me
that my solution is not very efficient...
Thank you for any answer (I am a "free time programmer" and this will
surely increase my programming skills...)

Regards Alex

From: Paul van Delst on
aborel(a)pilatus-aircraft.com wrote:
> Good evening
> I am writing a program which mainly converts text input files in
> different file formats (ASCII) as input for FEM Pre-and
> Postprocessors.
> The program reads the input data in an array (init_material_data) of
> the type material_data and then writes the data in a different file
> format doing different conversions.
> Due to the different maximum lengths of the input variables I have to
> use of a derived type variable which is in module "defs".
> !
> !
> module defs
> !
> implicit none
> !
> type material_data
> character(8) :: id
> character(256) :: name
> character(2) :: type
> character(10) :: info1
> character(10) :: info2
> character(12), dimension(25) :: mat_data
> end type material_data
> !
> type(material_data), pointer, dimension(:) :: init_mat_data
> type(material_data) :: iso_mat_data
> !
> end module defs
> !
> !
>
> Now I searched my books and this group for a description of how to
> initialize above derived type "init_mat_data" but the only way I can
> imagine would be
>
> do m=1,n_rows,1
>
> init_mat_data(m)%id = "xx"
> init_mat_data(m)%name = "xx"
> init_mat_data(m)%type = "xx"
> init_mat_data(m)%info1 = "xx"
> init_mat_data(m)%info2 = "xx"
> do j=1,25,1
> init_mat_data(m)%mat_data(j) = "xx"
> end do
> end do
>
> at run time. The same with the derived type iso_mat_data.

If you have a f95 compiler, you can do:

type material_data
character(8) :: id = 'xx'
character(256) :: name = 'xx'
character(2) :: type = 'xx'
character(10) :: info1 = 'xx'
character(10) :: info2 = 'xx'
character(12), dimension(25) :: mat_data = 'xx'
end type material_data

and then every instance you create will be initialised.

And don't forget to do,

type(material_data), pointer, dimension(:) :: init_mat_data => NULL()

cheers,

paulv


>
> Is there any more elegant way of solving this problem, it seems to me
> that my solution is not very efficient...
> Thank you for any answer (I am a "free time programmer" and this will
> surely increase my programming skills...)
>
> Regards Alex
>
From: David Frank on
You are allowed to initialize type members at their declaration

type material_data
character(8) :: id = 'id123456' ! note you can indicate format of id at
same time
....
end type


From: Richard Maine on
<aborel(a)pilatus-aircraft.com> wrote:

> Good evening
> I am writing a program which mainly converts text input files in
> different file formats (ASCII) as input for FEM Pre-and
> Postprocessors.
> The program reads the input data in an array (init_material_data) of
> the type material_data and then writes the data in a different file
> format doing different conversions.
> Due to the different maximum lengths of the input variables I have to
> use of a derived type variable which is in module "defs".
> !
> !
> module defs
> !
> implicit none
> !
> type material_data
> character(8) :: id
> character(256) :: name
> character(2) :: type
> character(10) :: info1
> character(10) :: info2
> character(12), dimension(25) :: mat_data
> end type material_data
> !
> type(material_data), pointer, dimension(:) :: init_mat_data
> type(material_data) :: iso_mat_data
> !
> end module defs
> !
> !
>
> Now I searched my books and this group for a description of how to
> initialize above derived type "init_mat_data" but the only way I can
> imagine would be
>
> do m=1,n_rows,1
>
> init_mat_data(m)%id = "xx"
> init_mat_data(m)%name = "xx"
> init_mat_data(m)%type = "xx"
> init_mat_data(m)%info1 = "xx"
> init_mat_data(m)%info2 = "xx"
> do j=1,25,1
> init_mat_data(m)%mat_data(j) = "xx"
> end do
> end do
>
> at run time. The same with the derived type iso_mat_data.
>
> Is there any more elegant way of solving this problem, it seems to me
> that my solution is not very efficient...

If you are just worried about the efficiency, I'd stop worrying. You
aren't going to be able to measure any efficiency difference. I'd place
money on it. This won't take enough time to matter, no matter how you do
it. In fact, if the array is large enough for the time to be measurable,
there are at least decent odds that doing it at run-time like this might
be faster than doing it with static initialization. Static
initialization of large arrays tends to involve storing those arrays in
the executable file, which makes for large executable files. Reading the
data from that executable image into memory involves disk I/O, which is
several orders of magnitude slower than CPU and memory operations. Just
because you don't see a loop in your code, don't think that means that
things happen by magic and are automatically free of cost.

That being said, I'll offer some possible alternatives, but don't think
these will improve efficiency. You might consider some of them to
improve elegance.

1. I see that your init-mat_data is a pointer. That's fine, but note
that it is incompatible with compile-time initialization. You can't ever
initialize a pointer to anything other than nullified. I assume that you
allocate or assign the pointer somewhere.

2. Along the same lines, I wonder whether making it allocatable might be
more appropriate than making it a pointer. That won't allow compile-time
initialization, but many would consider it more "elegant" than using a
pointer. Allocatables are less error-prone and generally more efficient
than pointers unless you are really doing things that require the extra
functionality of pointers.

3. I would suggest that the most "elegant" way to initialize these
objects would be to use what is called default initialization. You set
this up with the type definition and it then applies to all objects of
the type. Thus, it is not appropriate for initializing individual
objects of the type with different values. There is only one initial
default value that applies to all objects of the type. But from your
example, that looks like what you are doing anyway. You'd do this
something like

type material_data
character(8) :: id = "xx"
character(256) :: name = "xx"
character(2) :: type = "xx"
character(10) :: info1 = "xx"
character(10) :: info2 = "xx"
character(12), dimension(25) :: mat_data = "xx"
end type material_data

The default initialization will be applied whenever an object of the
type is "created". For an allocatable array (or a pointer array that
gets allocated), that will be when you do the allocation.

4. Note that in the default initialization for the mat_data component
above, I have taken advantage of the feature that allows you to assign a
scalar value to an array. The scalar gets propogated to every element of
the array. That is independent of default initialization. You can use it
in other contexts as well. For example, in your sample code above, you
could replace

> do j=1,25,1
> init_mat_data(m)%mat_data(j) = "xx"
> end do

with

init_mat_data(m)%mat_data "xx"

It does the same thing. The loop is just implied. I'd consider it
slightly more "elegant", though opinions on that vary. (Some people like
making the array nature more explicit; I don't.)

5. The other feature that you might possibly be looking for is what is
called a structure constructor. It does allow you to put all this into a
single statement. I personally wouldn't do it that way, because I'd find
that single statement harder to read than the way that you spelled it
out. But if you really wanted to do that, it could look something like

init_mat_data = material_data("xx","xx","xx","xx","xx")

where I have also made use (twice) of the automatic expansion of scalars
into arrays. You could spell the arrays out with array constructors, but
that would make this a lot more long-winded.

This is probably the closest thing to what you were asking for. You can
even use this form in a static initialization (although not for a
pointer or allocatable).

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
From: Michael Metcalf on

<aborel(a)pilatus-aircraft.com> wrote in message
news:aee4286b-22d3-4425-aced-797e370294ea(a)k39g2000hsf.googlegroups.com...

> Now I searched my books and this group for a description of how to
> initialize above derived type "init_mat_data"

.... "Fortran 95/2003 Explained", Sections 7.5.3 and 7.5.4.

Regards,

Mike Metcalf