I have a mesh like so:
| . | . | . | ... |
0 1 2 3 nc
To store the position of the cell boundaries, centers, etc., I have created the following derived data type:
testgrid1.f90 (2.1 KB)
type :: grid
!! 1D grid
character(20) :: name = "x [-]"
!! variable name
real(rk), allocatable :: edges(:)
!! vector(0:nc) of cell edges
real(rk), allocatable :: center(:)
!! vector(nc) of cell centers, \( x_i \)
real(rk), allocatable :: width(:)
!! vector(nc) of cell widths, \( x_{i+1/2} - x_{i-1/2} \)
real(rk), allocatable :: left(:)
!! vector(nc) of left cell boundaries, \( x_{i-1/2} \)
real(rk), allocatable :: right(:)
!! vector(nc) of right cell boundaries, , \( x_{i+1/2} \)
integer :: ncells
!! number of cells
contains
procedure, pass(self) :: new
end type grid
This implementation works well and is convenient to use, but it is far from efficient in terms of memory, because the left=edges(0:nc-1)
and right=edges(1:nc)
. The same info is being stored 3 times.
To “solve” this problem, I naively thought about redefining left
and right
to be pointers that would point to edges
, i.e, something like:
type :: grid
!! 1D grid - DOES NOT WORK
character(20) :: name = "x [-]"
!! variable name
real(rk), allocatable, TARGET:: edges(:)
!! vector(0:nc) of cell edges
real(rk), allocatable :: center(:)
!! vector(nc) of cell centers, \( x_i \)
real(rk), allocatable :: width(:)
!! vector(nc) of cell widths, \( x_{i+1/2} - x_{i-1/2} \)
real(rk), dimension(:), POINTER :: left
!! vector(nc) of left cell boundaries, \( x_{i-1/2} \)
real(rk), dimension(:), POINTER :: right
!! vector(nc) of right cell boundaries, , \( x_{i+1/2} \)
integer :: ncells
!! number of cells
contains
procedure, pass(self) :: new
end type grid
But his kind of silly trick is completely illegal! The attribute target
is not allowed inside a derived data type.
So, what is proper way to achieve the intended result?
Thanks!