Hello,
I’m experimenting with coarray feature and trying to resolve a problem by domain decomposition. The particular problem I want to solve has a domain that cannot be represented with a matrix, but can be represented ( in 2D ) as connected patches of quadrilaterals (matrix). For starting, I’m using as a global domain a square that can be represented as a matrix, but let’s just pretend it can’t. So it must divided in patches and every images will have his matrix on which perform calculations.
I qant to resolve the heat equations on that square and the serial version works as expected.
I’m in doubt on how perform updating (a coarray that contains common boundaries ?).
Problems however start before updating boundaries, just before copying data from the global domain, created and decomposed by image 1, to the image patches. This is the code :
program heat_parallel
use mod_linspace
implicit none
!---------------
! type defining a patch/block of the multi-block domain (a 2D/3D domain that
! can be decomposed in quadrilateral/hexahedral blocks)
!---------------
type :: domain_patch
real, allocatable, dimension(:,:) :: temperature_domain , x_domain , y_domain
end type
!---------------
! every image will have its own patch. A global coarray cannot be used because
! the entire domain is not generally structured ( domain <--> matrix mXn )
!---------------
type(domain_patch),codimension[*] :: decomposed_domain
!-----------------
! the overall domain before decomposition in this particular case is a square, so
! for brevity is declared as a domain patch, but it's just a coincidence
!-----------------
type(domain_patch) :: total_domain
!----------------
! decomposition is done only along first dimension for simplicity
!---------------
integer, codimension[*] :: ni_size_block
!-----------------------
! variables related to the creation of the initial global domain to be decomposed
!-----------------------
integer :: ni=400
integer :: nj
integer :: niter=1000*200
real :: len_x_domain=1.0,x_start=0, temp_up_left = 50, temp_up_right=100
real :: len_y_domain=1.0,y_start=0, temp_down_left = 50, temp_down_right=100
real :: init_temp=0.0 , a
integer::i,j,k ,nii ,n_im , acc
character(len=50) :: err_string, filenm
integer :: ierror
logical :: if_print_arrays=.false.
nj=ni
n_im= num_images()
if (this_image().eq.1) then
allocate(total_domain%temperature_domain(ni,nj))
allocate(total_domain%x_domain(ni,nj))
allocate(total_domain%y_domain(ni,nj))
do j=1,nj
total_domain%x_domain( :, j )=linspace( x_start, x_start+len_x_domain, ni )
end do
do i=1,ni
total_domain%y_domain( i,: )=linspace( y_start, y_start+len_y_domain, nj )
end do
!-----------------------------------------------
! initializing temperature field
!-----------------------------------------------
total_domain%temperature_domain=init_temp
!-----------------------------------------------
! setting BC
!-----------------------------------------------
total_domain%temperature_domain( :, nj )=linspace( temp_up_left, temp_up_right, ni )
total_domain%temperature_domain( :, 1 )=linspace( temp_down_left, temp_down_right, ni )
total_domain%temperature_domain( 1, : )=linspace( temp_down_left, temp_up_left, nj )
total_domain%temperature_domain( ni, : )=linspace( temp_down_right, temp_up_right, nj )
!-----------------------------------------------
! simple domain decomposition
!-----------------------------------------------
nii=int( ni/n_im )
acc=1
do i=1,n_im
ni_size_block[i] = nii
!-----------------------
! allocating for each image its own block
!-----------------------
allocate(decomposed_domain[i]%temperature_domain(nii,nj))
allocate(decomposed_domain[i]%x_domain(nii,nj))
allocate(decomposed_domain[i]%y_domain(nii,nj))
!------------------------
! copying from the related global data portion to each image patch
!------------------------
decomposed_domain[i]%temperature_domain = total_domain%temperature_domain(acc:nii, :)
decomposed_domain[i]%x_domain = total_domain%x_domain(acc:nii, :)
decomposed_domain[i]%y_domain = total_domain%y_domain(acc:nii, :)
acc=acc+nii
end do
endif
!-----------
! assuring every image has received data before writing
! patches to VTK file for inspection
!-----------
sync all
!--------------
! deallocating global data
!--------------
deallocate(total_domain%temperature_domain)
deallocate(total_domain%x_domain)
deallocate(total_domain%y_domain)
!-----------------------------------------------
! writing VTK solution file for each patch
!-----------------------------------------------
!..........
!..........
end program heat_parallel
The module linspace is this.
When I try to compile :
82 | allocate(decomposed_domain[i]%temperature_domain(nii,nj))
| 1
Error: Allocate-object at (1) must be ALLOCATABLE or a POINTER
What is wrong ?
Every suggestion on other approaches on how to tackle a domain decomposition problem is well accepted.
Thanks
------------ EDIT -----------
I solved the problems and now the solver runs well with 1 image, but when I use more than 1 image by inspection of the solution (and of the print output) I can see that the sync all statement after every iteration is not working. I’m using OpenCoarrays with gfortran. Has anyone experienced similar issues?