program ESMF_MeshFileIOUTest
!------------------------------------------------------------------------------
#include "ESMF_Macros.inc"
#include "ESMF.h"
!==============================================================================
!BOP
! !PROGRAM: ESMF_MeshUTest - This unit test file tests Mesh methods.
! !DESCRIPTION:
!
! The code in this file drives F90 MeshCreate() unit tests.
! The companion file ESMF\_Mesh.F90 contains the definitions for the
! Mesh methods.
!
!-----------------------------------------------------------------------------
! !USES:
use ESMF_TestMod ! test methods
use ESMF
use ESMF_MeshMod
implicit none
!------------------------------------------------------------------------------
! The following line turns the CVS identifier string into a printable variable.
character(*), parameter :: version = &
'$Id$'
!------------------------------------------------------------------------------
! cumulative result: count failures; no failures equals "all pass"
integer :: result = 0
! individual test result code
integer :: localrc, rc, petCount,localPet
! individual test failure message
character(ESMF_MAXSTR) :: failMsg
character(ESMF_MAXSTR) :: name
logical :: correct
!-------------------------------------------------------------------------------
! The unit tests are divided into Sanity and Exhaustive. The Sanity tests are
! always run. When the environment variable, EXHAUSTIVE, is set to ON then
! the EXHAUSTIVE and sanity tests both run. If the EXHAUSTIVE variable is set
! to OFF, then only the sanity unit tests.
! Special strings (Non-exhaustive and exhaustive) have been
! added to allow a script to count the number and types of unit tests.
!-------------------------------------------------------------------------------
!------------------------------------------------------------------------
call ESMF_TestStart(ESMF_SRCLINE, rc=rc) ! calls ESMF_Initialize() internally
if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT)
!------------------------------------------------------------------------
! Make sure MOAB is off
call ESMF_MeshSetMOAB(.false.)
! This surrounds all the tests to make turning off everything but one test easier
#if 1
!------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test Mesh create from medium size ESMFMesh file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call test_mesh_create_from_med_EM_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from spherical 3x3 ESMFMesh file with a given elem distribution."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_from_sph_3x3_EM_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from spherical 3x3 ESMFMesh file with a given node distribution."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_node_redist_from_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from Cartesian 3x3 ESMFMesh file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_from_cart_3x3_EM_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from ESMFMesh file with 1D elementConn."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_sph_1DeC_EM_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test coordSys conversion for ESMFMesh file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_coordSys_convert_EM_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from spherical 3D ESMFMesh file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_from_sph_3D_EM_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from spherical polybreak ESMFMesh file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_from_sph_pb_EM_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from spherical 3x3 UGrid file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_from_sph_3x3_UG_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from spherical polybreak UGrid file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_from_sph_pb_UG_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from spherical 3x3 SCRIP file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_from_sph_3x3_SC_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test create Mesh from spherical 3D UGRID file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call check_mesh_from_sph_3D_UG_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
!-----------------------------------------------------------------------------
!NEX_UTest
write(name, *) "Test creating a dual mesh from file."
write(failMsg, *) "Did not return ESMF_SUCCESS"
! initialize check variables
correct=.true.
rc=ESMF_SUCCESS
call test_create_dual_from_file(correct, rc)
#ifdef ESMF_PIO
call ESMF_Test(((rc.eq.ESMF_SUCCESS)), name, failMsg, result, ESMF_SRCLINE)
#else
write(failMsg, *) "Did not return ESMC_RC_LIB_NOT_PRESENT"
call ESMF_Test((rc==ESMC_RC_LIB_NOT_PRESENT), name, failMsg, result, ESMF_SRCLINE)
#endif
!-----------------------------------------------------------------------------
#endif
!------------------------------------------------------------------------
call ESMF_TestEnd(ESMF_SRCLINE) ! calls ESMF_Finalize() internally
!------------------------------------------------------------------------
contains
! Read in a medium sized ESMFMesh file that we got from a user
! and make sure that mesh create from file doesn't return errors.
! Since this is a larger file it's harder to verify that every
! part is correct, so this is more of a smoke test in the unit tests
! to make sure a reasonably sized file will work.
! More precise verifications are done with smaller files in the following tests.
! Larger mesh files are checked in the esmf_extended_tests
subroutine test_mesh_create_from_med_EM_file(correct, rc)
logical :: correct
integer :: rc
type(ESMF_Mesh) :: mesh
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: nodeDistgrid, elemDistgrid
integer, allocatable :: elemIds(:)
integer :: numElems, numPerPet, numThisPet
integer :: minId,maxId
integer :: i, pos
! Init correct
correct=.true.
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Number of elems in file
numElems=936
! Approx. number per PET
numPerPet=numElems/petCount
! Figure out range for this PET
minId=localPet*numPerPet+1
maxId=(localPet+1)*numPerPet
! If this Pet is last, put the rest there
if (localPet .eq. petCount-1) maxId=numElems
!write(*,*) localPet,"# ",minId,maxId
! Allocate elemIds
allocate(elemIds(maxId-minId+1))
! Fill
pos=1
do i=minId,maxId
elemIds(pos)=i
pos=pos+1
enddo
! Create element Distgrid
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Create Mesh from file
mesh=ESMF_MeshCreate("data/ne4np4-esmf.nc", &
fileformat=ESMF_FILEFORMAT_ESMFMESH, &
elementDistgrid=elemDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
!! Write mesh for debugging
! call ESMF_MeshWrite(mesh,"test_mesh",rc=rc)
! if (rc /= ESMF_SUCCESS) return
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemIds
deallocate(elemIds)
! Return success
rc=ESMF_SUCCESS
end subroutine test_mesh_create_from_med_EM_file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Creates the following mesh on
! 1 or 4 PETs. Returns an error
! if run on other than 1 or 4 PETs
!
! Mesh Ids
!
! 3.0 13 ------ 14 ------- 15 ------- 16
! | | | 10 / |
! 2.5 | 7 | 8 | / |
! | | | / 9 |
! 2.0 9 ------- 10 ------- 11 ------- 12
! | | | |
! 1.5 | 4 | 5 | 6 |
! | | | |
! 1.0 5 ------- 6 -------- 7 -------- 8
! | | | |
! 0.5 | 1 | 2 | 3 |
! | | | |
! 0.0 1 ------- 2 -------- 3 -------- 4
!
! 0.0 0.5 1.0 1.5 2.0 2.5 3.0
!
! Node Ids at corners
! Element Ids in centers
!
!!!!!
!
! The owners for 1 PET are all Pet 0.
! The owners for 4 PETs are as follows:
!
! Mesh Owners
!
! 3.0 2 ------- 2 -------- 3 -------- 3
! | | | 3 / |
! | 2 | 2 | / |
! | | | / 3 |
! 2.0 2 ------- 2 -------- 3 -------- 3
! | | | |
! | 2 | 2 | 3 |
! | | | |
! 1.0 0 ------- 0 -------- 1 -------- 1
! | | | |
! | 0 | 1 | 1 |
! | | | |
! 0.0 0 ------- 0 -------- 1 -------- 1
!
! 0.0 1.0 2.0 3.0
!
! Node Owners at corners
! Element Owners in centers
!
!
! This is a more through test that reads in a spherical 3x3 mesh file
! (that creates the mesh drawn above) and verifies that every part
! is correct.
subroutine check_mesh_from_sph_3x3_EM_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns, numTriElems, numQuadElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Setup mesh info depending on the
! number of PETs
if (petCount .eq. 1) then
! Fill in node data
numNodes=16
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8, &
9,10,11,12,13,14,&
15,16/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1,0,1,0,1,0, &
1,0,1,0,1,0,&
1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0, & ! 8
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
3.0,2.0, & ! 12
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=2
numQuadElems=8
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2,3,4,5,6,7,8,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 1
ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD, & ! 3
ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD, & ! 8
ESMF_MESHELEMTYPE_TRI, & ! 9
ESMF_MESHELEMTYPE_TRI/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5, & ! 1
1.5,0.5, & ! 2
2.5,0.5, & ! 3
0.5,1.5, & ! 4
1.5,1.5, & ! 5
2.5,1.5, & ! 6
0.5,2.5, & ! 7
1.5,2.5, & ! 8
2.75,2.25,& ! 9
2.25,2.75/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,6,5, & ! 1
2,3,7,6, & ! 2
3,4,8,7, & ! 3
5,6,10,9, & ! 4
6,7,11,10, & ! 5
7,8,12,11, & ! 6
9,10,14,13, & ! 7
10,11,15,14, & ! 8
11,12,16, & ! 9
11,16,15/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1, 0, 1, 1, 1, 1, 1, 1, 1, 1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.1_ESMF_KIND_R8, 1.2_ESMF_KIND_R8, 1.3_ESMF_KIND_R8, 1.4_ESMF_KIND_R8, &
1.5_ESMF_KIND_R8, 1.6_ESMF_KIND_R8, 1.7_ESMF_KIND_R8, 1.8_ESMF_KIND_R8, 0.59_ESMF_KIND_R8, 0.5_ESMF_KIND_R8/)
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPet .eq. 0) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,5,6/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
0.0,1.0, & ! 5
1.0,1.0 /) ! 6
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=0
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! 1
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5/) ! 1
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3/) ! 1
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.1_ESMF_KIND_R8/)
else if (localPet .eq. 1) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/2,3,4,6,7,8/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/0,1,0,0,1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0 /) ! 8
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 2
1, & ! 3
1, & ! 4
0, & ! 6
1, & ! 7
1/) ! 8
! Fill in elem data
numTriElems=0
numQuadElems=2
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/2,3/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD/) ! 3
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/1.5,0.5, & ! 2
2.5,0.5/) ! 3
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 2
2,3,6,5/) ! 3
!! elem mask
allocate(elemMask(numElems))
elemMask=(/0,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.2_ESMF_KIND_R8,1.3_ESMF_KIND_R8/)
else if (localPet .eq. 2) then
! Fill in node data
numNodes=9
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/5,6,7, &
9,10,11, &
13,14,15/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1, &
1,0,1, &
1,0,1/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0/) ! 15
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 5
0, & ! 6
1, & ! 7
2, & ! 9
2, & ! 10
2, & ! 11
2, & ! 13
2, & ! 14
2/) ! 15
! Fill in elem data
numTriElems=0
numQuadElems=4
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/4,5,7,8/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD/) ! 8
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,1.5, & ! 4
1.5,1.5, & ! 5
0.5,2.5, & ! 7
1.5,2.5/) ! 8
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 4
2,3,6,5, & ! 5
4,5,8,7, & ! 7
5,6,9,8/) ! 8
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,1,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.4_ESMF_KIND_R8,1.5_ESMF_KIND_R8,1.7_ESMF_KIND_R8,1.8_ESMF_KIND_R8/)
else if (localPet .eq. 3) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/7,8,11,12,15,16/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1,0,1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/2.0,1.0, & ! 7
3.0,1.0, & ! 8
2.0,2.0, & ! 11
3.0,2.0, & ! 12
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/1, & ! 7
1, & ! 8
2, & ! 11
3, & ! 12
2, & ! 15
3/) ! 16
! Fill in elem data
numTriElems=2
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/6,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_TRI, & ! 9
ESMF_MESHELEMTYPE_TRI/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/2.5,1.5, & ! 6
2.75,2.25,& ! 9
2.25,2.75/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3, & ! 6
3,4,6, & ! 9
3,6,5/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.6_ESMF_KIND_R8,0.59_ESMF_KIND_R8,0.5_ESMF_KIND_R8/)
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_sph_3x3_esmf.nc", &
fileformat=ESMF_FILEFORMAT_ESMFMESH, &
addUserArea=.true., &
elementDistgrid=elemDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 2) correct=.false.
if (sdim .ne. 2) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_SPH_DEG) correct=.false.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
elementCount=numElemsTst, &
elementConnCount=numElemConnsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (numNodes .ne. numNodesTst) correct=.false.
if (numElems .ne. numElemsTst) correct=.false.
if (numElemConns .ne. numElemConnsTst) correct=.false.
! Debugging
!write(*,*) "numNodes=",numNodes,numNodesTst
!write(*,*) "numElems=",numElems,numElemsTst
!write(*,*) "numElemConns=",numElemConns,numElemConnsTst
! Get is present information
call ESMF_MeshGet(mesh, &
nodeMaskIsPresent=nodeMaskIsPresentTst, &
elementMaskIsPresent=elemMaskIsPresentTst, &
elementAreaIsPresent=elemAreaIsPresentTst, &
elementCoordsIsPresent=elemCoordsIsPresentTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug
! write(*,*) "nodeMaskIsPresent=",nodeMaskIsPresentTst
! write(*,*) "elemMaskIsPresent=",elemMaskIsPresentTst
! write(*,*) "elemAreaIsPresent=",elemAreaIsPresentTst
! write(*,*) "elemCoordsIsPresent=",elemCoordsIsPresentTst
! Check is present info
if (.not. nodeMaskIsPresentTst) correct=.false.
if (.not. elemMaskIsPresentTst) correct=.false.
if (.not. elemAreaIsPresentTst) correct=.false.
if (.not. elemCoordsIsPresentTst) correct=.false.
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeCoordsTst(2*numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
allocate(nodeMaskTst(numNodesTst))
allocate(elemIdsTst(numElemsTst))
allocate(elemTypesTst(numElemsTst))
allocate(elemConnTst(numElemConnsTst))
allocate(elemMaskTst(numElemsTst))
allocate(elemAreaTst(numElemsTst))
allocate(elemCoordsTst(2*numElemsTst))
! XMRKX
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeCoords=nodeCoordsTst, &
nodeOwners=nodeOwnersTst, &
nodeMask=nodeMaskTst, &
elementIds=elemIdsTst, &
elementTypes=elemTypesTst, &
elementConn=elemConnTst, &
elementMask=elemMaskTst, &
elementArea=elemAreaTst, &
elementCoords=elemCoordsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! do i=1,numElemsTst
! write(*,*) localPet,"# ",elemIdsTst(i),"ea=",elemAreaTst(i),"ec=",elemCoordsTst(2*i-1),elemCoordsTst(2*i),"em=",elemMaskTst(i)
! enddo
! Check node ids
do i=1,numNodesTst
if (nodeIds(i) .ne. nodeIdsTst(i)) correct=.false.
enddo
! Check node Coords
k=1
do i=1,numNodesTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (nodeCoords(k) .ne. nodeCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Check node Owners
do i=1,numNodesTst
if (nodeOwners(i) .ne. nodeOwnersTst(i)) correct=.false.
enddo
! Check node Mask
do i=1,numNodesTst
if (nodeMask(i) .ne. nodeMaskTst(i)) correct=.false.
enddo
! Debug output
! write(*,*) "nodeMask =",nodeMask
! write(*,*) "nodeMaskTst=",nodeMaskTst
! Check elem ids
do i=1,numElemsTst
if (elemIds(i) .ne. elemIdsTst(i)) correct=.false.
enddo
! Check elem Types
do i=1,numElemsTst
if (elemTypes(i) .ne. elemTypesTst(i)) correct=.false.
enddo
! Check elem Connections
do i=1,numElemConnsTst
if (elemConn(i) .ne. elemConnTst(i)) correct=.false.
enddo
! Check elem mask
do i=1,numElems
if (elemMask(i) .ne. elemMaskTst(i)) correct=.false.
enddo
! Check elem area
do i=1,numElems
if (elemArea(i) .ne. elemAreaTst(i)) correct=.false.
enddo
! Check elem Coords
k=1
do i=1,numElemsTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (elemCoords(k) .ne. elemCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Debug output
! write(*,*) "elemCoords =",elemCoords
! write(*,*) "elemCoordsTst=",elemCoordsTst
! deallocate node data
deallocate(nodeIds)
deallocate(nodeCoords)
deallocate(nodeOwners)
deallocate(nodeMask)
! deallocate elem data
deallocate(elemIds)
deallocate(elemTypes)
deallocate(elemCoords)
deallocate(elemConn)
deallocate(elemMask)
deallocate(elemArea)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeCoordsTst)
deallocate(nodeOwnersTst)
deallocate(nodeMaskTst)
deallocate(elemIdsTst)
deallocate(elemTypesTst)
deallocate(elemConnTst)
deallocate(elemMaskTst)
deallocate(elemAreaTst)
deallocate(elemCoordsTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_from_sph_3x3_EM_file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Creates the following mesh on
! 1 or 4 PETs. Returns an error
! if run on other than 1 or 4 PETs
!
! Mesh Ids
!
! 3.0 13 ------ 14 ------- 15 ------- 16
! | | | 10 / |
! 2.5 | 7 | 8 | / |
! | | | / 9 |
! 2.0 9 ------- 10 ------- 11 ------- 12
! | | | |
! 1.5 | 4 | 5 | 6 |
! | | | |
! 1.0 5 ------- 6 -------- 7 -------- 8
! | | | |
! 0.5 | 1 | 2 | 3 |
! | | | |
! 0.0 1 ------- 2 -------- 3 -------- 4
!
! 0.0 0.5 1.0 1.5 2.0 2.5 3.0
!
! Node Ids at corners
! Element Ids in centers
!
!!!!!
!
! The owners for 1 PET are all Pet 0.
! The owners for 4 PETs are as follows:
!
! Mesh Owners
!
! 3.0 2 ------- 2 -------- 3 -------- 3
! | | | 3 / |
! | 2 | 2 | / |
! | | | / 3 |
! 2.0 2 ------- 2 -------- 3 -------- 3
! | | | |
! | 2 | 2 | 3 |
! | | | |
! 1.0 0 ------- 0 -------- 1 -------- 1
! | | | |
! | 0 | 1 | 1 |
! | | | |
! 0.0 0 ------- 0 -------- 1 -------- 1
!
! 0.0 1.0 2.0 3.0
!
! Node Owners at corners
! Element Owners in centers
!
!
! This is a more through test that reads in a Cartesian 3x3 mesh file
! (that creates the mesh drawn above) and verifies that every part
! is correct.
subroutine check_mesh_from_cart_3x3_EM_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns, numTriElems, numQuadElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Setup mesh info depending on the
! number of PETs
if (petCount .eq. 1) then
! Fill in node data
numNodes=16
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8, &
9,10,11,12,13,14,&
15,16/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0, & ! 8
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
3.0,2.0, & ! 12
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=2
numQuadElems=8
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2,3,4,5,6,7,8,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 1
ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD, & ! 3
ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD, & ! 8
ESMF_MESHELEMTYPE_TRI, & ! 9
ESMF_MESHELEMTYPE_TRI/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5, & ! 1
1.5,0.5, & ! 2
2.5,0.5, & ! 3
0.5,1.5, & ! 4
1.5,1.5, & ! 5
2.5,1.5, & ! 6
0.5,2.5, & ! 7
1.5,2.5, & ! 8
2.75,2.25,& ! 9
2.25,2.75/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,6,5, & ! 1
2,3,7,6, & ! 2
3,4,8,7, & ! 3
5,6,10,9, & ! 4
6,7,11,10, & ! 5
7,8,12,11, & ! 6
9,10,14,13, & ! 7
10,11,15,14, & ! 8
11,12,16, & ! 9
11,16,15/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1, 0, 1, 1, 1, 1, 1, 1, 1, 1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.1_ESMF_KIND_R8, 1.2_ESMF_KIND_R8, 1.3_ESMF_KIND_R8, 1.4_ESMF_KIND_R8, &
1.5_ESMF_KIND_R8, 1.6_ESMF_KIND_R8, 1.7_ESMF_KIND_R8, 1.8_ESMF_KIND_R8, 0.59_ESMF_KIND_R8, 0.5_ESMF_KIND_R8/)
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPet .eq. 0) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,5,6/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
0.0,1.0, & ! 5
1.0,1.0 /) ! 6
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=0
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! 1
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5/) ! 1
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3/) ! 1
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.1_ESMF_KIND_R8/)
else if (localPet .eq. 1) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/2,3,4,6,7,8/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0 /) ! 8
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 2
1, & ! 3
1, & ! 4
0, & ! 6
1, & ! 7
1/) ! 8
! Fill in elem data
numTriElems=0
numQuadElems=2
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/2,3/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD/) ! 3
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/1.5,0.5, & ! 2
2.5,0.5/) ! 3
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 2
2,3,6,5/) ! 3
!! elem mask
allocate(elemMask(numElems))
elemMask=(/0,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.2_ESMF_KIND_R8,1.3_ESMF_KIND_R8/)
else if (localPet .eq. 2) then
! Fill in node data
numNodes=9
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/5,6,7, &
9,10,11, &
13,14,15/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0/) ! 15
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 5
0, & ! 6
1, & ! 7
2, & ! 9
2, & ! 10
2, & ! 11
2, & ! 13
2, & ! 14
2/) ! 15
! Fill in elem data
numTriElems=0
numQuadElems=4
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/4,5,7,8/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD/) ! 8
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,1.5, & ! 4
1.5,1.5, & ! 5
0.5,2.5, & ! 7
1.5,2.5/) ! 8
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 4
2,3,6,5, & ! 5
4,5,8,7, & ! 7
5,6,9,8/) ! 8
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,1,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.4_ESMF_KIND_R8,1.5_ESMF_KIND_R8,1.7_ESMF_KIND_R8,1.8_ESMF_KIND_R8/)
else if (localPet .eq. 3) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/7,8,11,12,15,16/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/2.0,1.0, & ! 7
3.0,1.0, & ! 8
2.0,2.0, & ! 11
3.0,2.0, & ! 12
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/1, & ! 7
1, & ! 8
2, & ! 11
3, & ! 12
2, & ! 15
3/) ! 16
! Fill in elem data
numTriElems=2
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/6,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_TRI, & ! 9
ESMF_MESHELEMTYPE_TRI/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/2.5,1.5, & ! 6
2.75,2.25,& ! 9
2.25,2.75/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3, & ! 6
3,4,6, & ! 9
3,6,5/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.6_ESMF_KIND_R8,0.59_ESMF_KIND_R8,0.5_ESMF_KIND_R8/)
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_cart_3x3_esmf.nc", &
fileformat=ESMF_FILEFORMAT_ESMFMESH, &
addUserArea=.true., &
elementDistgrid=elemDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 2) correct=.false.
if (sdim .ne. 2) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_CART) correct=.false.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
elementCount=numElemsTst, &
elementConnCount=numElemConnsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (numNodes .ne. numNodesTst) correct=.false.
if (numElems .ne. numElemsTst) correct=.false.
if (numElemConns .ne. numElemConnsTst) correct=.false.
! Debugging
!write(*,*) "numNodes=",numNodes,numNodesTst
!write(*,*) "numElems=",numElems,numElemsTst
!write(*,*) "numElemConns=",numElemConns,numElemConnsTst
! Get is present information
call ESMF_MeshGet(mesh, &
nodeMaskIsPresent=nodeMaskIsPresentTst, &
elementMaskIsPresent=elemMaskIsPresentTst, &
elementAreaIsPresent=elemAreaIsPresentTst, &
elementCoordsIsPresent=elemCoordsIsPresentTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug
! write(*,*) "nodeMaskIsPresent=",nodeMaskIsPresentTst
! write(*,*) "elemMaskIsPresent=",elemMaskIsPresentTst
! write(*,*) "elemAreaIsPresent=",elemAreaIsPresentTst
! write(*,*) "elemCoordsIsPresent=",elemCoordsIsPresentTst
! Check is present info
if ( nodeMaskIsPresentTst) correct=.false. ! There isn't a nodeMask in the file
if (.not. elemMaskIsPresentTst) correct=.false.
if (.not. elemAreaIsPresentTst) correct=.false.
if (.not. elemCoordsIsPresentTst) correct=.false.
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeCoordsTst(2*numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
allocate(elemIdsTst(numElemsTst))
allocate(elemTypesTst(numElemsTst))
allocate(elemConnTst(numElemConnsTst))
allocate(elemMaskTst(numElemsTst))
allocate(elemAreaTst(numElemsTst))
allocate(elemCoordsTst(2*numElemsTst))
! XMRKX
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeCoords=nodeCoordsTst, &
nodeOwners=nodeOwnersTst, &
elementIds=elemIdsTst, &
elementTypes=elemTypesTst, &
elementConn=elemConnTst, &
elementMask=elemMaskTst, &
elementArea=elemAreaTst, &
elementCoords=elemCoordsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! do i=1,numElemsTst
! write(*,*) localPet,"# ",elemIdsTst(i),"ea=",elemAreaTst(i),"ec=",elemCoordsTst(2*i-1),elemCoordsTst(2*i),"em=",elemMaskTst(i)
! enddo
! Check node ids
do i=1,numNodesTst
if (nodeIds(i) .ne. nodeIdsTst(i)) correct=.false.
enddo
! Check node Coords
k=1
do i=1,numNodesTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (nodeCoords(k) .ne. nodeCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Check node Owners
do i=1,numNodesTst
if (nodeOwners(i) .ne. nodeOwnersTst(i)) correct=.false.
enddo
! Check elem ids
do i=1,numElemsTst
if (elemIds(i) .ne. elemIdsTst(i)) correct=.false.
enddo
! Check elem Types
do i=1,numElemsTst
if (elemTypes(i) .ne. elemTypesTst(i)) correct=.false.
enddo
! Check elem Connections
do i=1,numElemConnsTst
if (elemConn(i) .ne. elemConnTst(i)) correct=.false.
enddo
! Check elem mask
do i=1,numElems
if (elemMask(i) .ne. elemMaskTst(i)) correct=.false.
enddo
! Check elem area
do i=1,numElems
if (elemArea(i) .ne. elemAreaTst(i)) correct=.false.
enddo
! Check elem Coords
k=1
do i=1,numElemsTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (elemCoords(k) .ne. elemCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Debugging
! write(*,*) "elemCoords =",elemCoords
! write(*,*) "elemCoordsTst=",elemCoordsTst
! deallocate node data
deallocate(nodeIds)
deallocate(nodeCoords)
deallocate(nodeOwners)
! deallocate elem data
deallocate(elemIds)
deallocate(elemTypes)
deallocate(elemCoords)
deallocate(elemConn)
deallocate(elemMask)
deallocate(elemArea)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeCoordsTst)
deallocate(nodeOwnersTst)
deallocate(elemIdsTst)
deallocate(elemTypesTst)
deallocate(elemConnTst)
deallocate(elemMaskTst)
deallocate(elemAreaTst)
deallocate(elemCoordsTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_from_cart_3x3_EM_file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Creates the following mesh on
! 1 or 4 PETs. Returns an error
! if run on other than 1 or 4 PETs
!
! Mesh Ids
!
! 3.0 13 ------ 14 ------- 15 ------- 16
! | | | 12 / |
! 2.5 | 9 | 10 | / |
! | | | / 11 |
! 2.0 9 ------- 10 ------- 11 ------- 12
! | | | |
! 1.5 | 6 | 7 | 8 |
! | | | |
! 1.0 5 ------- 6 -------- 7 -------- 8
! | 1 / | 3 / | |
! 0.5 | / | / | 5 |
! | / 2 | / 4 | |
! 0.0 1 ------- 2 -------- 3 -------- 4
!
! 0.0 0.5 1.0 1.5 2.0 2.5 3.0
!
! Node Ids at corners
! Element Ids in centers
!
!!!!!
!
! The owners for 1 PET are all Pet 0.
! The owners for 4 PETs are as follows:
!
! Mesh Owners
!
! 3.0 2 ------- 2 -------- 3 -------- 3
! | | | 3 / |
! | 2 | 2 | / |
! | | | / 3 |
! 2.0 2 ------- 2 -------- 3 -------- 3
! | | | |
! | 2 | 2 | 3 |
! | | | |
! 1.0 0 ------- 0 -------- 1 -------- 1
! | 0 / | 1 / | |
! | / | / | 1 |
! | / 0 | / 1 | |
! 0.0 0 ------- 0 -------- 1 -------- 1
!
! 0.0 1.0 2.0 3.0
!
! Node Owners at corners
! Element Owners in centers
!
!
! This is a test that reads in a mesh from an ESMFMesh format file that
! has a 1D elementConn array, and verifies that everything is correct.
! The mesh is drawn above.
subroutine check_mesh_sph_1DeC_EM_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns, numTriElems, numQuadElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Setup mesh info depending on the
! number of PETs
if (petCount .eq. 1) then
! Fill in node data
numNodes=16
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8, &
9,10,11,12,13,14,&
15,16/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1,0,1,0,1,0, &
1,0,1,0,1,0,&
1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0, & ! 8
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
3.0,2.0, & ! 12
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=6
numQuadElems=6
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2,3,4,5,6,7,8,9,10,11,12/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_TRI, & ! 1
ESMF_MESHELEMTYPE_TRI, & ! 2
ESMF_MESHELEMTYPE_TRI, & ! 3
ESMF_MESHELEMTYPE_TRI, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD, & ! 8
ESMF_MESHELEMTYPE_QUAD, & ! 9
ESMF_MESHELEMTYPE_QUAD, & ! 10
ESMF_MESHELEMTYPE_TRI, & ! 11
ESMF_MESHELEMTYPE_TRI/) ! 12
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.25,0.75, & ! 1
0.75,0.25, & ! 2
1.25,0.75, & ! 3
1.75,0.25, & ! 4
2.5,0.5, & ! 5
0.5,1.5, & ! 6
1.5,1.5, & ! 7
2.5,1.5, & ! 8
0.5,2.5, & ! 9
1.5,2.5, & ! 10
2.75,2.25, & ! 11
2.25,2.75/) ! 12
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,6,5, & ! 1
1,2,6, & ! 2
2,7,6, & ! 3
2,3,7, & ! 4
3,4,8,7, & ! 5
5,6,10,9, & ! 6
6,7,11,10, & ! 7
7,8,12,11, & ! 8
9,10,14,13, & ! 9
10,11,15,14, & ! 10
11,12,16, & ! 11
11,16,15/) ! 12
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/0.51_ESMF_KIND_R8, 0.52_ESMF_KIND_R8, 0.53_ESMF_KIND_R8, 0.54_ESMF_KIND_R8, &
1.5_ESMF_KIND_R8, 1.6_ESMF_KIND_R8, 1.7_ESMF_KIND_R8, 1.8_ESMF_KIND_R8, &
1.9_ESMF_KIND_R8, 1.1_ESMF_KIND_R8, 0.511_ESMF_KIND_R8, 0.512_ESMF_KIND_R8/)
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPet .eq. 0) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,5,6/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
0.0,1.0, & ! 5
1.0,1.0 /) ! 6
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=2
numQuadElems=0
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_TRI, & ! 1
ESMF_MESHELEMTYPE_TRI/) ! 2
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.25,0.75, & ! 1
0.75,0.25/) ! 2
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,4,3, & ! 1
1,2,4 /) ! 2
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,0/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/0.51_ESMF_KIND_R8, 0.52_ESMF_KIND_R8/)
else if (localPet .eq. 1) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/2,3,4,6,7,8/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/0,1,0,0,1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0 /) ! 8
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 2
1, & ! 3
1, & ! 4
0, & ! 6
1, & ! 7
1/) ! 8
! Fill in elem data
numTriElems=2
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/3,4,5/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_TRI, & ! 3
ESMF_MESHELEMTYPE_TRI, & ! 4
ESMF_MESHELEMTYPE_QUAD/) ! 5
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/1.25,0.75, & ! 3
1.75,0.25, & ! 4
2.50,0.50/) ! 5
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,5,4, & ! 3
1,2,5, & ! 4
2,3,6,5/) ! 5
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/0.53_ESMF_KIND_R8,0.54_ESMF_KIND_R8,1.5_ESMF_KIND_R8/)
else if (localPet .eq. 2) then
! Fill in node data
numNodes=9
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/5,6,7, &
9,10,11, &
13,14,15/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1, &
1,0,1, &
1,0,1/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0/) ! 15
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 5
0, & ! 6
1, & ! 7
2, & ! 9
2, & ! 10
2, & ! 11
2, & ! 13
2, & ! 14
2/) ! 15
! Fill in elem data
numTriElems=0
numQuadElems=4
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/6,7,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD, & ! 9
ESMF_MESHELEMTYPE_QUAD/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,1.5, & ! 6
1.5,1.5, & ! 7
0.5,2.5, & ! 9
1.5,2.5/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 6
2,3,6,5, & ! 7
4,5,8,7, & ! 9
5,6,9,8/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,1,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.6_ESMF_KIND_R8,1.7_ESMF_KIND_R8,1.9_ESMF_KIND_R8,1.1_ESMF_KIND_R8/)
else if (localPet .eq. 3) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/7,8,11,12,15,16/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1,0,1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/2.0,1.0, & ! 7
3.0,1.0, & ! 8
2.0,2.0, & ! 11
3.0,2.0, & ! 12
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/1, & ! 7
1, & ! 8
2, & ! 11
3, & ! 12
2, & ! 15
3/) ! 16
! Fill in elem data
numTriElems=2
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/8,11,12/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 8
ESMF_MESHELEMTYPE_TRI, & ! 11
ESMF_MESHELEMTYPE_TRI/) ! 12
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/2.5,1.5, & ! 8
2.75,2.25,& ! 11
2.25,2.75/) ! 12
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3, & ! 8
3,4,6, & ! 11
3,6,5/) ! 12
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,0,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.8_ESMF_KIND_R8,0.511_ESMF_KIND_R8,0.512_ESMF_KIND_R8/)
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_sph_1D_elemConn_esmf.nc", &
fileformat=ESMF_FILEFORMAT_ESMFMESH, &
addUserArea=.true., &
elementDistgrid=elemDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! DEBUG OUTPUT
!call ESMF_MeshWrite(mesh,"mesh_1Dec",rc=rc)
!if (rc .ne. ESMF_SUCCESS) return
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 2) correct=.false.
if (sdim .ne. 2) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_SPH_DEG) correct=.false.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
elementCount=numElemsTst, &
elementConnCount=numElemConnsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (numNodes .ne. numNodesTst) correct=.false.
if (numElems .ne. numElemsTst) correct=.false.
if (numElemConns .ne. numElemConnsTst) correct=.false.
! Debugging
!write(*,*) "numNodes=",numNodes,numNodesTst
!write(*,*) "numElems=",numElems,numElemsTst
!write(*,*) "numElemConns=",numElemConns,numElemConnsTst
! Get is present information
call ESMF_MeshGet(mesh, &
nodeMaskIsPresent=nodeMaskIsPresentTst, &
elementMaskIsPresent=elemMaskIsPresentTst, &
elementAreaIsPresent=elemAreaIsPresentTst, &
elementCoordsIsPresent=elemCoordsIsPresentTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug
! write(*,*) "nodeMaskIsPresent=",nodeMaskIsPresentTst
! write(*,*) "elemMaskIsPresent=",elemMaskIsPresentTst
! write(*,*) "elemAreaIsPresent=",elemAreaIsPresentTst
! write(*,*) "elemCoordsIsPresent=",elemCoordsIsPresentTst
! Check is present info
if (.not. nodeMaskIsPresentTst) correct=.false.
if (.not. elemMaskIsPresentTst) correct=.false.
if (.not. elemAreaIsPresentTst) correct=.false.
if (.not. elemCoordsIsPresentTst) correct=.false.
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeCoordsTst(2*numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
allocate(nodeMaskTst(numNodesTst))
allocate(elemIdsTst(numElemsTst))
allocate(elemTypesTst(numElemsTst))
allocate(elemConnTst(numElemConnsTst))
allocate(elemMaskTst(numElemsTst))
allocate(elemAreaTst(numElemsTst))
allocate(elemCoordsTst(2*numElemsTst))
! XMRKX
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeCoords=nodeCoordsTst, &
nodeOwners=nodeOwnersTst, &
nodeMask=nodeMaskTst, &
elementIds=elemIdsTst, &
elementTypes=elemTypesTst, &
elementConn=elemConnTst, &
elementMask=elemMaskTst, &
elementArea=elemAreaTst, &
elementCoords=elemCoordsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! do i=1,numElemsTst
! write(*,*) localPet,"# ",elemIdsTst(i),"ea=",elemAreaTst(i),"ec=",elemCoordsTst(2*i-1),elemCoordsTst(2*i),"em=",elemMaskTst(i)
! enddo
! Check node ids
do i=1,numNodesTst
if (nodeIds(i) .ne. nodeIdsTst(i)) correct=.false.
enddo
! Check node Coords
k=1
do i=1,numNodesTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (nodeCoords(k) .ne. nodeCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Check node Owners
do i=1,numNodesTst
if (nodeOwners(i) .ne. nodeOwnersTst(i)) correct=.false.
enddo
! Check node Mask
do i=1,numNodesTst
if (nodeMask(i) .ne. nodeMaskTst(i)) correct=.false.
enddo
! Debug output
! write(*,*) "nodeMask =",nodeMask
! write(*,*) "nodeMaskTst=",nodeMaskTst
! Check elem ids
do i=1,numElemsTst
if (elemIds(i) .ne. elemIdsTst(i)) correct=.false.
enddo
! Check elem Types
do i=1,numElemsTst
if (elemTypes(i) .ne. elemTypesTst(i)) correct=.false.
enddo
! Check elem Connections
do i=1,numElemConnsTst
if (elemConn(i) .ne. elemConnTst(i)) correct=.false.
enddo
! Check elem mask
do i=1,numElems
if (elemMask(i) .ne. elemMaskTst(i)) correct=.false.
enddo
! Check elem area
do i=1,numElems
if (elemArea(i) .ne. elemAreaTst(i)) correct=.false.
enddo
! Check elem Coords
k=1
do i=1,numElemsTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (elemCoords(k) .ne. elemCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Debug output
! write(*,*) "elemCoords =",elemCoords
! write(*,*) "elemCoordsTst=",elemCoordsTst
! deallocate node data
deallocate(nodeIds)
deallocate(nodeCoords)
deallocate(nodeOwners)
deallocate(nodeMask)
! deallocate elem data
deallocate(elemIds)
deallocate(elemTypes)
deallocate(elemCoords)
deallocate(elemConn)
deallocate(elemMask)
deallocate(elemArea)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeCoordsTst)
deallocate(nodeOwnersTst)
deallocate(nodeMaskTst)
deallocate(elemIdsTst)
deallocate(elemTypesTst)
deallocate(elemConnTst)
deallocate(elemMaskTst)
deallocate(elemAreaTst)
deallocate(elemCoordsTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_sph_1DeC_EM_file
! This test checks the coordinate system conversion functionality
! It reads in a small 3x3 spherical grid specified in degrees
! in the file and converts it to radians. The file used
! it the same 3x3 spherical one used for other tests in this file.
subroutine check_coordSys_convert_EM_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns, numTriElems, numQuadElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Setup mesh info depending on the
! number of PETs
if (petCount .eq. 1) then
! Fill in node data
numNodes=16
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0, & ! 8
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
3.0,2.0, & ! 12
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
! Fill in elem data
numTriElems=2
numQuadElems=8
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2,3,4,5,6,7,8,9,10/)
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5, & ! 1
1.5,0.5, & ! 2
2.5,0.5, & ! 3
0.5,1.5, & ! 4
1.5,1.5, & ! 5
2.5,1.5, & ! 6
0.5,2.5, & ! 7
1.5,2.5, & ! 8
2.75,2.25,& ! 9
2.25,2.75/) ! 10
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPet .eq. 0) then
! Fill in node data
numNodes=4
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
0.0,1.0, & ! 5
1.0,1.0 /) ! 6
! Fill in elem data
numTriElems=0
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1/)
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5/) ! 1
else if (localPet .eq. 1) then
! Fill in node data
numNodes=6
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0 /) ! 8
! Fill in elem data
numTriElems=0
numQuadElems=2
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/2,3/)
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/1.5,0.5, & ! 2
2.5,0.5/) ! 3
else if (localPet .eq. 2) then
! Fill in node data
numNodes=9
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0/) ! 15
! Fill in elem data
numTriElems=0
numQuadElems=4
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/4,5,7,8/)
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,1.5, & ! 4
1.5,1.5, & ! 5
0.5,2.5, & ! 7
1.5,2.5/) ! 8
else if (localPet .eq. 3) then
! Fill in node data
numNodes=6
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/2.0,1.0, & ! 7
3.0,1.0, & ! 8
2.0,2.0, & ! 11
3.0,2.0, & ! 12
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
! Fill in elem data
numTriElems=2
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/6,9,10/)
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/2.5,1.5, & ! 6
2.75,2.25,& ! 9
2.25,2.75/) ! 10
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_sph_3x3_esmf.nc", &
fileformat=ESMF_FILEFORMAT_ESMFMESH, &
addUserArea=.true., &
coordSys=ESMF_COORDSYS_SPH_RAD, &
elementDistgrid=elemDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 2) correct=.false.
if (sdim .ne. 2) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_SPH_RAD) correct=.false.
! Allocate space for tst arrays
allocate(nodeCoordsTst(2*numNodes))
allocate(elemCoordsTst(2*numElems))
! XMRKX
! Get Information
call ESMF_MeshGet(mesh, &
nodeCoords=nodeCoordsTst, &
elementCoords=elemCoordsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check node coords
k=1
do i=1,numNodes ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (nodeCoords(k)*ESMF_COORDSYS_DEG2RAD .ne. nodeCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! check elem coords
k=1
do i=1,numElems ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (elemCoords(k)*ESMF_COORDSYS_DEG2RAD .ne. elemCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Debug output
!write(*,*) "elemCoords =",elemCoords
!write(*,*) "elemCoordsTst=",elemCoordsTst
! deallocate node data
deallocate(nodeCoords)
! deallocate elem data
deallocate(elemIds)
deallocate(elemCoords)
! Deallocate tst Arrays
deallocate(nodeCoordsTst)
deallocate(elemCoordsTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_coordSys_convert_EM_file
! This is a more through test that reads in a spherical 3D 2x2x1 mesh file
! and verifies that every part is correct.
subroutine check_mesh_from_sph_3D_EM_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns, numTriElems, numQuadElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! XMRKX !
! Create Dest Mesh
if (petCount .eq. 1) then
! Set number of nodes
numNodes=18
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8,9, &
10,11,12,13,14,15,16,17,18/)
! Allocate and fill node coordinate array.
! Since this is a 3D Mesh the size is 3x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/0.0,0.0,1.0, & ! node id 1
1.0,0.0,1.0, & ! node id 2
2.0,0.0,1.0, & ! node id 3
0.0,1.0,1.0, & ! node id 4
1.0,1.0,1.0, & ! node id 5
2.0,1.0,1.0, & ! node id 6
0.0,2.0,1.0, & ! node id 7
1.0,2.0,1.0, & ! node id 8
2.0,2.0,1.0, & ! node id 9
0.0,0.0,2.0, & ! node id 10
1.0,0.0,2.0, & ! node id 11
2.0,0.0,2.0, & ! node id 12
0.0,1.0,2.0, & ! node id 13
1.0,1.0,2.0, & ! node id 14
2.0,1.0,2.0, & ! node id 15
0.0,2.0,2.0, & ! node id 16
1.0,2.0,2.0, & ! node id 17
2.0,2.0,2.0 /) ! node id 18
! Allocate and fill the node owner array.
! Since this Mesh is all on PET 0, it's just set to all 0.
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on PET 0
! Set the number of each type of element, plus the total number.
numElems=4
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/1,2,3,4/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=ESMF_MESHELEMTYPE_HEX
! Allocate and fill the element connection type array.
! Note that entries in this array refer to the
! positions in the nodeIds, etc. arrays and that
! the order and number of entries for each element
! reflects that given in the Mesh options
! section for the corresponding entry
! in the elemTypes array.
allocate(elemConn(8*numElems))
elemConn=(/1,2,5,4,10,11,14,13, & ! elem id 1
2,3,6,5,11,12,15,14, & ! elem id 2
4,5,8,7,13,14,17,16, & ! elem id 3
5,6,9,8,14,15,18,17/) ! elem id 4
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPET .eq. 0) then !!! This part only for PET 0
! Set number of nodes
numNodes=8
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/1,2,4,5,10,11,13,14/)
! Allocate and fill node coordinate array.
! Since this is a 2D Mesh the size is 2x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/0.0,0.0,1.0, & ! node id 1
1.0,0.0,1.0, & ! node id 2
0.0,1.0,1.0, & ! node id 4
1.0,1.0,1.0, & ! node id 5
0.0,0.0,2.0, & ! node id 10
1.0,0.0,2.0, & ! node id 11
0.0,1.0,2.0, & ! node id 13
1.0,1.0,2.0 /) ! node id 14
! Allocate and fill the node owner array.
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! node id 1
0, & ! node id 2
0, & ! node id 4
0, & ! node id 5
0, & ! node id 10
0, & ! node id 11
0, & ! node id 13
0/) ! node id 14
! Set the number of each type of element, plus the total number.
numElems=1
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/1/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_HEX/) ! elem id 1
! Allocate and fill the element connection type array.
! Note that entry are local indices
allocate(elemConn(8*numElems))
elemConn=(/1,2,4,3,5,6,8,7/) ! elem id 1
else if (localPET .eq. 1) then !!! This part only for PET 1
! Set number of nodes
numNodes=8
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/2,3,5,6,11,12,14,15/)
! Allocate and fill node coordinate array.
! Since this is a 3D Mesh the size is 2x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/1.0,0.0,1.0, & ! node id 2
2.0,0.0,1.0, & ! node id 3
1.0,1.0,1.0, & ! node id 5
2.0,1.0,1.0, & ! node id 6
1.0,0.0,2.0, & ! node id 11
2.0,0.0,2.0, & ! node id 12
1.0,1.0,2.0, & ! node id 14
2.0,1.0,2.0/) ! node id 15
! Allocate and fill the node owner array.
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! node id 2
1, & ! node id 3
0, & ! node id 5
1, & ! node id 6
0, & ! node id 11
1, & ! node id 12
0, & ! node id 14
1/) ! node id 15
! Set the number of each type of element, plus the total number.
numElems=1
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/2/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_HEX/) ! elem id 1
! Allocate and fill the element connection type array.
! Note that entry are local indices
allocate(elemConn(8*numElems))
elemConn=(/1,2,4,3,5,6,8,7/) ! elem id 1
else if (localPET .eq. 2) then !!! This part only for PET 2
! Set number of nodes
numNodes=8
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/4,5,7,8,13,14,16,17/)
! Allocate and fill node coordinate array.
! Since this is a 3D Mesh the size is 2x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/0.0,1.0,1.0, & ! node id 4
1.0,1.0,1.0, & ! node id 5
0.0,2.0,1.0, & ! node id 7
1.0,2.0,1.0, & ! node id 8
0.0,1.0,2.0, & ! node id 13
1.0,1.0,2.0, & ! node id 14
0.0,2.0,2.0, & ! node id 16
1.0,2.0,2.0/) ! node id 17
! Allocate and fill the node owner array.
! Since this Mesh is all on PET 0, it's just set to all 0.
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! node id 4
0, & ! node id 5
2, & ! node id 7
2, & ! node id 8
0, & ! node id 13
0, & ! node id 14
2, & ! node id 16
2/) ! node id 17
! Set the number of each type of element, plus the total number.
numElems=1
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/3/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_HEX/) ! elem id 1
! Allocate and fill the element connection type array.
! Note that entry are local indices
allocate(elemConn(8*numElems))
elemConn=(/1,2,4,3,5,6,8,7/) ! elem id 1
else if (localPET .eq. 3) then !!! This part only for PET 3
! Set number of nodes
numNodes=8
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/5,6,8,9,14,15,17,18/)
! Allocate and fill node coordinate array.
! Since this is a 3D Mesh the size is 2x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/1.0,1.0,1.0, & ! node id 5
2.0,1.0,1.0, & ! node id 6
1.0,2.0,1.0, & ! node id 8
2.0,2.0,1.0, & ! node id 9
1.0,1.0,2.0, & ! node id 14
2.0,1.0,2.0, & ! node id 15
1.0,2.0,2.0, & ! node id 17
2.0,2.0,2.0/) ! node id 18
! Allocate and fill the node owner array.
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! node id 5
1, & ! node id 6
2, & ! node id 8
3, & ! node id 9
0, & ! node id 14
1, & ! node id 15
2, & ! node id 17
3/) ! node id 18
! Set the number of each type of element, plus the total number.
numElems=1
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/4/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_HEX/) ! elem id 1
! Allocate and fill the element connection type array.
! Note that entry are local indices
allocate(elemConn(8*numElems))
elemConn=(/1,2,4,3,5,6,8,7/) ! elem id 1
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_sph_2x2x1_esmf.nc", &
fileformat=ESMF_FILEFORMAT_ESMFMESH, &
elementDistgrid=elemDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! DEBUG OUTPUT
!call ESMF_MeshWrite(mesh,"mesh_3D_EM",rc=rc)
!if (rc .ne. ESMF_SUCCESS) return
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 3) correct=.false.
if (sdim .ne. 3) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_SPH_DEG) correct=.false.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
elementCount=numElemsTst, &
elementConnCount=numElemConnsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (numNodes .ne. numNodesTst) correct=.false.
if (numElems .ne. numElemsTst) correct=.false.
if (numElems*8 .ne. numElemConnsTst) correct=.false.
! Debugging
!write(*,*) "numNodes=",numNodes,numNodesTst
!write(*,*) "numElems=",numElems,numElemsTst
!write(*,*) "numElemConns=",numElemConns,numElemConnsTst
! Get is present information
call ESMF_MeshGet(mesh, &
nodeMaskIsPresent=nodeMaskIsPresentTst, &
elementMaskIsPresent=elemMaskIsPresentTst, &
elementAreaIsPresent=elemAreaIsPresentTst, &
elementCoordsIsPresent=elemCoordsIsPresentTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug
! write(*,*) "nodeMaskIsPresent=",nodeMaskIsPresentTst
! write(*,*) "elemMaskIsPresent=",elemMaskIsPresentTst
! write(*,*) "elemAreaIsPresent=",elemAreaIsPresentTst
! write(*,*) "elemCoordsIsPresent=",elemCoordsIsPresentTst
! Check is present info
if (nodeMaskIsPresentTst) correct=.false.
if (elemMaskIsPresentTst) correct=.false.
if (elemAreaIsPresentTst) correct=.false.
if (elemCoordsIsPresentTst) correct=.false.
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeCoordsTst(3*numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
allocate(elemIdsTst(numElemsTst))
allocate(elemTypesTst(numElemsTst))
allocate(elemConnTst(numElemConnsTst))
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeCoords=nodeCoordsTst, &
nodeOwners=nodeOwnersTst, &
elementIds=elemIdsTst, &
elementTypes=elemTypesTst, &
elementConn=elemConnTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! do i=1,numElemsTst
! write(*,*) localPet,"# ",elemIdsTst(i),"ea=",elemAreaTst(i),"ec=",elemCoordsTst(2*i-1),elemCoordsTst(2*i),"em=",elemMaskTst(i)
! enddo
! Check node ids
do i=1,numNodesTst
if (nodeIds(i) .ne. nodeIdsTst(i)) correct=.false.
enddo
! Check node Coords
k=1
do i=1,numNodesTst ! Loop over nodes
do j=1,3 ! Loop over coord spatial dim
if (nodeCoords(k) .ne. nodeCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Check node Owners
do i=1,numNodesTst
if (nodeOwners(i) .ne. nodeOwnersTst(i)) correct=.false.
enddo
! Debug output
! write(*,*) "nodeMask =",nodeMask
! write(*,*) "nodeMaskTst=",nodeMaskTst
! Check elem ids
do i=1,numElemsTst
if (elemIds(i) .ne. elemIdsTst(i)) correct=.false.
enddo
! Check elem Types
do i=1,numElemsTst
if (elemTypes(i) .ne. elemTypesTst(i)) correct=.false.
enddo
! Check elem Connections
do i=1,numElemConnsTst
if (elemConn(i) .ne. elemConnTst(i)) correct=.false.
enddo
! Debug output
! write(*,*) "elemCoords =",elemCoords
! write(*,*) "elemCoordsTst=",elemCoordsTst
! deallocate node data
deallocate(nodeIds)
deallocate(nodeCoords)
deallocate(nodeOwners)
! deallocate elem data
deallocate(elemIds)
deallocate(elemTypes)
deallocate(elemConn)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeCoordsTst)
deallocate(nodeOwnersTst)
deallocate(elemIdsTst)
deallocate(elemTypesTst)
deallocate(elemConnTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_from_sph_3D_EM_file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Creates the following mesh on
! 1 or 4 PETs. Returns an error
! if run on other than 1 or 4 PETs
!
! Mesh Ids
!
! 3.0 13 ------ 14 ------- 15 ------- 16
! | | | 11b / |
! 2.5 | 9 | 10 | / |
! | | | / 11a |
! 2.0 9 ------- 10 ------- 11 ------- 12
! | | | |
! 1.5 | 6 | 7 | 8 |
! | | | |
! 1.0 5 ------- 6 -------- 7 -------- 8
! | 1 / | 3 / | |
! 0.5 | / | / | 5 |
! | / 2 | / 4 | |
! 0.0 1 ------- 2 -------- 3 -------- 4
!
! 0.0 0.5 1.0 1.5 2.0 2.5 3.0
!
! Node Ids at corners
! Element Ids in centers
!
!!!!!
!
! The owners for 1 PET are all Pet 0.
! The owners for 4 PETs are as follows:
!
! Mesh Owners
!
! 3.0 2 ------- 2 -------- 3 -------- 3
! | | | 3 / |
! | 2 | 2 | / |
! | | | / 3 |
! 2.0 2 ------- 2 -------- 3 -------- 3
! | | | |
! | 2 | 2 | 3 |
! | | | |
! 1.0 0 ------- 0 -------- 1 -------- 1
! | 0 / | 1 / | |
! | / | / | 1 |
! | / 0 | / 1 | |
! 0.0 0 ------- 0 -------- 1 -------- 1
!
! 0.0 1.0 2.0 3.0
!
! Node Owners at corners
! Element Owners in centers
!
!
! This is a test that reads in a mesh from an ESMFMesh format file that
! has a 1D elementConn array, and a polybreak in the elementConn variable.
! It verifies everything that it can verify is correct.
! (Some ESMF_MeshGet() arguments don't work for polybreak yet.)
! The mesh is drawn above.
subroutine check_mesh_from_sph_pb_EM_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns
integer :: numTriElems, numQuadElems, numPolyBreakElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Setup mesh info depending on the
! number of PETs
if (petCount .eq. 1) then
! Fill in node data
numNodes=16
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8, &
9,10,11,12,13,14,&
15,16/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1,0,1,0,1,0, &
1,0,1,0,1,0,&
1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0, & ! 8
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
3.0,2.0, & ! 12
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=4
numQuadElems=6
numPolyBreakElems=1
numElems=numTriElems+numQuadElems+numPolyBreakElems
numElemConns=3*numTriElems+ &
4*numQuadElems+ &
7*numPolyBreakElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2,3,4,5,6,7,8,9,10,11/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_TRI, & ! 1
ESMF_MESHELEMTYPE_TRI, & ! 2
ESMF_MESHELEMTYPE_TRI, & ! 3
ESMF_MESHELEMTYPE_TRI, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD, & ! 8
ESMF_MESHELEMTYPE_QUAD, & ! 9
ESMF_MESHELEMTYPE_QUAD, & ! 10
7/) ! 11
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.25,0.75, & ! 1
0.75,0.25, & ! 2
1.25,0.75, & ! 3
1.75,0.25, & ! 4
2.5,0.5, & ! 5
0.5,1.5, & ! 6
1.5,1.5, & ! 7
2.5,1.5, & ! 8
0.5,2.5, & ! 9
1.5,2.5, & ! 10
2.5,2.5/) ! 11
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,6,5, & ! 1
1,2,6, & ! 2
2,7,6, & ! 3
2,3,7, & ! 4
3,4,8,7, & ! 5
5,6,10,9, & ! 6
6,7,11,10, & ! 7
7,8,12,11, & ! 8
9,10,14,13, & ! 9
10,11,15,14, & ! 10
11,12,16, ESMF_MESH_POLYBREAK, 11,16,15/) ! 11
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/0.51_ESMF_KIND_R8, 0.52_ESMF_KIND_R8, 0.53_ESMF_KIND_R8, 0.54_ESMF_KIND_R8, &
1.5_ESMF_KIND_R8, 1.6_ESMF_KIND_R8, 1.7_ESMF_KIND_R8, 1.8_ESMF_KIND_R8, &
1.9_ESMF_KIND_R8, 1.1_ESMF_KIND_R8, 1.11_ESMF_KIND_R8/)
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPet .eq. 0) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,5,6/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
0.0,1.0, & ! 5
1.0,1.0 /) ! 6
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=2
numQuadElems=0
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_TRI, & ! 1
ESMF_MESHELEMTYPE_TRI/) ! 2
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.25,0.75, & ! 1
0.75,0.25/) ! 2
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,4,3, & ! 1
1,2,4 /) ! 2
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,0/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/0.51_ESMF_KIND_R8, 0.52_ESMF_KIND_R8/)
else if (localPet .eq. 1) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/2,3,4,6,7,8/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/0,1,0,0,1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0 /) ! 8
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 2
1, & ! 3
1, & ! 4
0, & ! 6
1, & ! 7
1/) ! 8
! Fill in elem data
numTriElems=2
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/3,4,5/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_TRI, & ! 3
ESMF_MESHELEMTYPE_TRI, & ! 4
ESMF_MESHELEMTYPE_QUAD/) ! 5
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/1.25,0.75, & ! 3
1.75,0.25, & ! 4
2.50,0.50/) ! 5
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,5,4, & ! 3
1,2,5, & ! 4
2,3,6,5/) ! 5
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/0.53_ESMF_KIND_R8,0.54_ESMF_KIND_R8,1.5_ESMF_KIND_R8/)
else if (localPet .eq. 2) then
! Fill in node data
numNodes=9
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/5,6,7, &
9,10,11, &
13,14,15/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1, &
1,0,1, &
1,0,1/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0/) ! 15
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 5
0, & ! 6
1, & ! 7
2, & ! 9
2, & ! 10
2, & ! 11
2, & ! 13
2, & ! 14
2/) ! 15
! Fill in elem data
numTriElems=0
numQuadElems=4
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/6,7,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD, & ! 9
ESMF_MESHELEMTYPE_QUAD/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,1.5, & ! 6
1.5,1.5, & ! 7
0.5,2.5, & ! 9
1.5,2.5/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 6
2,3,6,5, & ! 7
4,5,8,7, & ! 9
5,6,9,8/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,1,1/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.6_ESMF_KIND_R8,1.7_ESMF_KIND_R8,1.9_ESMF_KIND_R8,1.1_ESMF_KIND_R8/)
else if (localPet .eq. 3) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/7,8,11,12,15,16/)
!! node Mask
allocate(nodeMask(numNodes))
nodeMask=(/1,0,1,0,1,0/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/2.0,1.0, & ! 7
3.0,1.0, & ! 8
2.0,2.0, & ! 11
3.0,2.0, & ! 12
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/1, & ! 7
1, & ! 8
2, & ! 11
3, & ! 12
2, & ! 15
3/) ! 16
! Fill in elem data
numTriElems=0
numQuadElems=1
numPolyBreakElems=1
numElems=numTriElems+numQuadElems+numPolyBreakElems
numElemConns=3*numTriElems+ &
4*numQuadElems+ &
7*numPolyBreakElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/8,11/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 8
7/) ! 11
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/2.5,1.5, & ! 8
2.5,2.5/) ! 11
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3, & ! 8
11,12,16, ESMF_MESH_POLYBREAK, 11,16,15/) ! 11
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,0/)
!! elem area
!! (need kinds because not R4 doesn't rep. close enough)
allocate(elemArea(numElems))
elemArea=(/1.8_ESMF_KIND_R8,1.11_ESMF_KIND_R8/)
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_sph_polybreak_esmf.nc", &
fileformat=ESMF_FILEFORMAT_ESMFMESH, &
addUserArea=.true., &
elementDistgrid=elemDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! DEBUG OUTPUT
!call ESMF_MeshWrite(mesh,"mesh_pb_esmf",rc=rc)
!if (rc .ne. ESMF_SUCCESS) return
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 2) correct=.false.
if (sdim .ne. 2) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_SPH_DEG) correct=.false.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
elementCount=numElemsTst, &
! elementConnCount=numElemConnsTst, & ! DOESN'T WORK YET WITH NGONS
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (numNodes .ne. numNodesTst) correct=.false.
if (numElems .ne. numElemsTst) correct=.false.
! if (numElemConns .ne. numElemConnsTst) correct=.false. ! DOESN'T WORK YET WITH NGONS
! Debugging
!write(*,*) "numNodes=",numNodes,numNodesTst
!write(*,*) "numElems=",numElems,numElemsTst
!write(*,*) "numElemConns=",numElemConns,numElemConnsTst
! Get is present information
call ESMF_MeshGet(mesh, &
nodeMaskIsPresent=nodeMaskIsPresentTst, &
elementMaskIsPresent=elemMaskIsPresentTst, &
elementAreaIsPresent=elemAreaIsPresentTst, &
elementCoordsIsPresent=elemCoordsIsPresentTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug
! write(*,*) "nodeMaskIsPresent=",nodeMaskIsPresentTst
! write(*,*) "elemMaskIsPresent=",elemMaskIsPresentTst
! write(*,*) "elemAreaIsPresent=",elemAreaIsPresentTst
! write(*,*) "elemCoordsIsPresent=",elemCoordsIsPresentTst
! Check is present info
if (.not. nodeMaskIsPresentTst) correct=.false.
if (.not. elemMaskIsPresentTst) correct=.false.
if (.not. elemAreaIsPresentTst) correct=.false.
if (.not. elemCoordsIsPresentTst) correct=.false.
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeCoordsTst(2*numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
allocate(nodeMaskTst(numNodesTst))
! allocate(elemIdsTst(numElemsTst)) ! DOESN'T WORK YET WITH NGONS
! allocate(elemTypesTst(numElemsTst)) ! DOESN'T WORK YET WITH NGONS
! allocate(elemConnTst(numElemConnsTst)) ! DOESN'T WORK YET WITH NGONS
! allocate(elemMaskTst(numElemsTst)) ! DOESN'T WORK YET WITH NGONS
! allocate(elemAreaTst(numElemsTst)) ! DOESN'T WORK YET WITH NGONS
! allocate(elemCoordsTst(2*numElemsTst)) ! DOESN'T WORK YET WITH NGONS
! XMRKX
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeCoords=nodeCoordsTst, &
nodeOwners=nodeOwnersTst, &
nodeMask=nodeMaskTst, &
! elementIds=elemIdsTst, & ! DOESN'T WORK YET WITH NGONS
! elementTypes=elemTypesTst, & ! DOESN'T WORK YET WITH NGONS
! elementConn=elemConnTst, & ! DOESN'T WORK YET WITH NGONS
! elementMask=elemMaskTst, & ! DOESN'T WORK YET WITH NGONS
! elementArea=elemAreaTst, & ! DOESN'T WORK YET WITH NGONS
! elementCoords=elemCoordsTst, & ! DOESN'T WORK YET WITH NGONS
rc=rc)
if (rc /= ESMF_SUCCESS) return
! do i=1,numElemsTst
! write(*,*) localPet,"# ",elemIdsTst(i),"ea=",elemAreaTst(i),"ec=",elemCoordsTst(2*i-1),elemCoordsTst(2*i),"em=",elemMaskTst(i)
! enddo
! Check node ids
do i=1,numNodesTst
if (nodeIds(i) .ne. nodeIdsTst(i)) correct=.false.
enddo
! Check node Coords
k=1
do i=1,numNodesTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (nodeCoords(k) .ne. nodeCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Check node Owners
do i=1,numNodesTst
if (nodeOwners(i) .ne. nodeOwnersTst(i)) correct=.false.
enddo
! Check node Mask
do i=1,numNodesTst
if (nodeMask(i) .ne. nodeMaskTst(i)) correct=.false.
enddo
! Debug output
! write(*,*) "nodeMask =",nodeMask
! write(*,*) "nodeMaskTst=",nodeMaskTst
! Check elem ids
! DOESN'T WORK YET WITH NGONS
!do i=1,numElemsTst
! if (elemIds(i) .ne. elemIdsTst(i)) correct=.false.
!enddo
! Check elem Types
! DOESN'T WORK YET WITH NGONS
!do i=1,numElemsTst
! if (elemTypes(i) .ne. elemTypesTst(i)) correct=.false.
!enddo
! Check elem Connections
! DOESN'T WORK YET WITH NGONS
!do i=1,numElemConnsTst
! if (elemConn(i) .ne. elemConnTst(i)) correct=.false.
!enddo
! Check elem mask
! DOESN'T WORK YET WITH NGONS
!do i=1,numElems
! if (elemMask(i) .ne. elemMaskTst(i)) correct=.false.
!enddo
! Check elem area
! DOESN'T WORK YET WITH NGONS
!do i=1,numElems
! if (elemArea(i) .ne. elemAreaTst(i)) correct=.false.
!enddo
! Check elem Coords
! DOESN'T WORK YET WITH NGONS
!k=1
!do i=1,numElemsTst ! Loop over nodes
! do j=1,2 ! Loop over coord spatial dim
! if (elemCoords(k) .ne. elemCoordsTst(k)) correct=.false.
! k=k+1
! enddo
!enddo
! Debug output
! write(*,*) "elemCoords =",elemCoords
! write(*,*) "elemCoordsTst=",elemCoordsTst
! deallocate node data
deallocate(nodeIds)
deallocate(nodeCoords)
deallocate(nodeOwners)
deallocate(nodeMask)
! deallocate elem data
deallocate(elemIds)
deallocate(elemTypes)
deallocate(elemCoords)
deallocate(elemConn)
deallocate(elemMask)
deallocate(elemArea)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeCoordsTst)
deallocate(nodeOwnersTst)
deallocate(nodeMaskTst)
!deallocate(elemIdsTst) ! DOESN'T WORK YET WITH NGONS
!deallocate(elemTypesTst) ! DOESN'T WORK YET WITH NGONS
!deallocate(elemConnTst) ! DOESN'T WORK YET WITH NGONS
!deallocate(elemMaskTst) ! DOESN'T WORK YET WITH NGONS
!deallocate(elemAreaTst) ! DOESN'T WORK YET WITH NGONS
!deallocate(elemCoordsTst) ! DOESN'T WORK YET WITH NGONS
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_from_sph_pb_EM_file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Creates the following mesh on
! 1 or 4 PETs. Returns an error
! if run on other than 1 or 4 PETs
!
! Mesh Ids
!
! 3.0 13 ------ 14 ------- 15 ------- 16
! | | | 10 / |
! 2.5 | 7 | 8 | / |
! | | | / 9 |
! 2.0 9 ------- 10 ------- 11 ------- 12
! | | | |
! 1.5 | 4 | 5 | 6 |
! | | | |
! 1.0 5 ------- 6 -------- 7 -------- 8
! | | | |
! 0.5 | 1 | 2 | 3 |
! | | | |
! 0.0 1 ------- 2 -------- 3 -------- 4
!
! 0.0 0.5 1.0 1.5 2.0 2.5 3.0
!
! Node Ids at corners
! Element Ids in centers
!
!!!!!
!
! The owners for 1 PET are all Pet 0.
! The owners for 4 PETs are as follows:
!
! Mesh Owners
!
! 3.0 2 ------- 2 -------- 3 -------- 3
! | | | 3 / |
! | 2 | 2 | / |
! | | | / 3 |
! 2.0 2 ------- 2 -------- 3 -------- 3
! | | | |
! | 2 | 2 | 3 |
! | | | |
! 1.0 0 ------- 0 -------- 1 -------- 1
! | | | |
! | 0 | 1 | 1 |
! | | | |
! 0.0 0 ------- 0 -------- 1 -------- 1
!
! 0.0 1.0 2.0 3.0
!
! Node Owners at corners
! Element Owners in centers
!
!
! This is a more through test that reads in a spherical 3x3 UGRID mesh file
! (that creates the mesh drawn above) and verifies that every part
! is correct.
subroutine check_mesh_from_sph_3x3_UG_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns, numTriElems, numQuadElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Setup mesh info depending on the
! number of PETs
if (petCount .eq. 1) then
! Fill in node data
numNodes=16
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8, &
9,10,11,12,13,14,&
15,16/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0, & ! 8
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
3.0,2.0, & ! 12
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=2
numQuadElems=8
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2,3,4,5,6,7,8,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 1
ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD, & ! 3
ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD, & ! 8
ESMF_MESHELEMTYPE_TRI, & ! 9
ESMF_MESHELEMTYPE_TRI/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5, & ! 1
1.5,0.5, & ! 2
2.5,0.5, & ! 3
0.5,1.5, & ! 4
1.5,1.5, & ! 5
2.5,1.5, & ! 6
0.5,2.5, & ! 7
1.5,2.5, & ! 8
2.75,2.25,& ! 9
2.25,2.75/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,6,5, & ! 1
2,3,7,6, & ! 2
3,4,8,7, & ! 3
5,6,10,9, & ! 4
6,7,11,10, & ! 5
7,8,12,11, & ! 6
9,10,14,13, & ! 7
10,11,15,14, & ! 8
11,12,16, & ! 9
11,16,15/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1, 0, 1, 1, 1, 1, 0, 1, 0, 1/)
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPet .eq. 0) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,5,6/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
0.0,1.0, & ! 5
1.0,1.0 /) ! 6
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=0
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! 1
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5/) ! 1
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3/) ! 1
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1/)
else if (localPet .eq. 1) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/2,3,4,6,7,8/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0 /) ! 8
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 2
1, & ! 3
1, & ! 4
0, & ! 6
1, & ! 7
1/) ! 8
! Fill in elem data
numTriElems=0
numQuadElems=2
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/2,3/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD/) ! 3
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/1.5,0.5, & ! 2
2.5,0.5/) ! 3
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 2
2,3,6,5/) ! 3
!! elem mask
allocate(elemMask(numElems))
elemMask=(/0,1/)
else if (localPet .eq. 2) then
! Fill in node data
numNodes=9
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/5,6,7, &
9,10,11, &
13,14,15/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0/) ! 15
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 5
0, & ! 6
1, & ! 7
2, & ! 9
2, & ! 10
2, & ! 11
2, & ! 13
2, & ! 14
2/) ! 15
! Fill in elem data
numTriElems=0
numQuadElems=4
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/4,5,7,8/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD/) ! 8
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,1.5, & ! 4
1.5,1.5, & ! 5
0.5,2.5, & ! 7
1.5,2.5/) ! 8
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 4
2,3,6,5, & ! 5
4,5,8,7, & ! 7
5,6,9,8/) ! 8
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,0,1/)
else if (localPet .eq. 3) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/7,8,11,12,15,16/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/2.0,1.0, & ! 7
3.0,1.0, & ! 8
2.0,2.0, & ! 11
3.0,2.0, & ! 12
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/1, & ! 7
1, & ! 8
2, & ! 11
3, & ! 12
2, & ! 15
3/) ! 16
! Fill in elem data
numTriElems=2
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/6,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_TRI, & ! 9
ESMF_MESHELEMTYPE_TRI/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/2.5,1.5, & ! 6
2.75,2.25,& ! 9
2.25,2.75/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3, & ! 6
3,4,6, & ! 9
3,6,5/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,0,1/)
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_sph_3x3_ugrid.nc", &
fileformat=ESMF_FILEFORMAT_UGRID, &
elementDistgrid=elemDistgrid, &
maskFlag=ESMF_MESHLOC_ELEMENT, &
varName="elemMask", &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! DEBUG OUTPUT
!call ESMF_MeshWrite(mesh,"mesh_3x3_ugrid",rc=rc)
!if (rc .ne. ESMF_SUCCESS) rc=ESMF_FAILURE
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 2) correct=.false.
if (sdim .ne. 2) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_SPH_DEG) correct=.false.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
elementCount=numElemsTst, &
elementConnCount=numElemConnsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (numNodes .ne. numNodesTst) correct=.false.
if (numElems .ne. numElemsTst) correct=.false.
if (numElemConns .ne. numElemConnsTst) correct=.false.
! Debugging
!write(*,*) "numNodes=",numNodes,numNodesTst
!write(*,*) "numElems=",numElems,numElemsTst
!write(*,*) "numElemConns=",numElemConns,numElemConnsTst
! Get is present information
call ESMF_MeshGet(mesh, &
nodeMaskIsPresent=nodeMaskIsPresentTst, &
elementMaskIsPresent=elemMaskIsPresentTst, &
elementAreaIsPresent=elemAreaIsPresentTst, &
elementCoordsIsPresent=elemCoordsIsPresentTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug
! write(*,*) "nodeMaskIsPresent=",nodeMaskIsPresentTst
! write(*,*) "elemMaskIsPresent=",elemMaskIsPresentTst
! write(*,*) "elemAreaIsPresent=",elemAreaIsPresentTst
! write(*,*) "elemCoordsIsPresent=",elemCoordsIsPresentTst
! Check is present info
if ( nodeMaskIsPresentTst) correct=.false.
if (.not. elemMaskIsPresentTst) correct=.false.
if ( elemAreaIsPresentTst) correct=.false.
if (.not. elemCoordsIsPresentTst) correct=.false.
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeCoordsTst(2*numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
allocate(elemIdsTst(numElemsTst))
allocate(elemTypesTst(numElemsTst))
allocate(elemConnTst(numElemConnsTst))
allocate(elemMaskTst(numElemsTst))
allocate(elemCoordsTst(2*numElemsTst))
! XMRKX
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeCoords=nodeCoordsTst, &
nodeOwners=nodeOwnersTst, &
elementIds=elemIdsTst, &
elementTypes=elemTypesTst, &
elementConn=elemConnTst, &
elementMask=elemMaskTst, &
elementCoords=elemCoordsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! do i=1,numElemsTst
! write(*,*) localPet,"# ",elemIdsTst(i),"ea=",elemAreaTst(i),"ec=",elemCoordsTst(2*i-1),elemCoordsTst(2*i),"em=",elemMaskTst(i)
! enddo
! Check node ids
do i=1,numNodesTst
if (nodeIds(i) .ne. nodeIdsTst(i)) correct=.false.
enddo
! Check node Coords
k=1
do i=1,numNodesTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (nodeCoords(k) .ne. nodeCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Check node Owners
do i=1,numNodesTst
if (nodeOwners(i) .ne. nodeOwnersTst(i)) correct=.false.
enddo
! Check elem ids
do i=1,numElemsTst
if (elemIds(i) .ne. elemIdsTst(i)) correct=.false.
enddo
! Check elem Types
do i=1,numElemsTst
if (elemTypes(i) .ne. elemTypesTst(i)) correct=.false.
enddo
! Check elem Connections
do i=1,numElemConnsTst
if (elemConn(i) .ne. elemConnTst(i)) correct=.false.
enddo
! Check elem mask
do i=1,numElems
if (elemMask(i) .ne. elemMaskTst(i)) correct=.false.
enddo
! Debug output
!write(*,*) "elemMask =",elemMask
!write(*,*) "elemMaskTst=",elemMaskTst
! Check elem Coords
k=1
do i=1,numElemsTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (elemCoords(k) .ne. elemCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Debug output
! write(*,*) "elemCoords =",elemCoords
! write(*,*) "elemCoordsTst=",elemCoordsTst
! deallocate node data
deallocate(nodeIds)
deallocate(nodeCoords)
deallocate(nodeOwners)
! deallocate elem data
deallocate(elemIds)
deallocate(elemTypes)
deallocate(elemCoords)
deallocate(elemConn)
deallocate(elemMask)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeCoordsTst)
deallocate(nodeOwnersTst)
deallocate(elemIdsTst)
deallocate(elemTypesTst)
deallocate(elemConnTst)
deallocate(elemMaskTst)
deallocate(elemCoordsTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_from_sph_3x3_UG_file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Creates the following mesh on
! 1 or 4 PETs. Returns an error
! if run on other than 1 or 4 PETs
!
! Mesh Ids
!
! 3.0 13 ------ 14 ------- 15 ------- 16
! | | | 9b / |
! 2.5 | 7 | 8 | / |
! | | | / 9a |
! 2.0 9 ------- 10 ------- 11 ------- 12
! | | | |
! 1.5 | 4 | 5 | 6 |
! | | | |
! 1.0 5 ------- 6 -------- 7 -------- 8
! | | | |
! 0.5 | 1 | 2 | 3 |
! | | | |
! 0.0 1 ------- 2 -------- 3 -------- 4
!
! 0.0 0.5 1.0 1.5 2.0 2.5 3.0
!
! Node Ids at corners
! Element Ids in centers
!
!!!!!
!
! The owners for 1 PET are all Pet 0.
! The owners for 4 PETs are as follows:
!
! Mesh Owners
!
! 3.0 2 ------- 2 -------- 3 -------- 3
! | | | 3 / |
! | 2 | 2 | / |
! | | | / 3 |
! 2.0 2 ------- 2 -------- 3 -------- 3
! | | | |
! | 2 | 2 | 3 |
! | | | |
! 1.0 0 ------- 0 -------- 1 -------- 1
! | | | |
! | 0 | 1 | 1 |
! | | | |
! 0.0 0 ------- 0 -------- 1 -------- 1
!
! 0.0 1.0 2.0 3.0
!
! Node Owners at corners
! Element Owners in centers
!
!
! This is a more through test that reads in a spherical polybreak UGRID mesh file
! (that creates the mesh drawn above) and verifies that every part we can check
! is correct.
subroutine check_mesh_from_sph_pb_UG_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns
integer :: numTriElems, numQuadElems, numPolybreakElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Setup mesh info depending on the
! number of PETs
if (petCount .eq. 1) then
! Fill in node data
numNodes=16
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8, &
9,10,11,12,13,14,&
15,16/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0, & ! 8
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
3.0,2.0, & ! 12
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=0
numQuadElems=8
numPolybreakElems=1
numElems=numTriElems+numQuadElems+numPolybreakElems
numElemConns=3*numTriElems+4*numQuadElems+7*numPolybreakElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2,3,4,5,6,7,8,9/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 1
ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD, & ! 3
ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD, & ! 8
7/) ! 9
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5, & ! 1
1.5,0.5, & ! 2
2.5,0.5, & ! 3
0.5,1.5, & ! 4
1.5,1.5, & ! 5
2.5,1.5, & ! 6
0.5,2.5, & ! 7
1.5,2.5, & ! 8
2.5,2.5/) ! 9
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,6,5, & ! 1
2,3,7,6, & ! 2
3,4,8,7, & ! 3
5,6,10,9, & ! 4
6,7,11,10, & ! 5
7,8,12,11, & ! 6
9,10,14,13, & ! 7
10,11,15,14, & ! 8
11,12,16, ESMF_MESH_POLYBREAK, 11,16,15/) ! 9
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1, 0, 1, 1, 1, 1, 0, 1, 0/)
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPet .eq. 0) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,5,6/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
0.0,1.0, & ! 5
1.0,1.0 /) ! 6
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=0
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! 1
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5/) ! 1
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3/) ! 1
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1/)
else if (localPet .eq. 1) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/2,3,4,6,7,8/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/1.0,0.0, & ! 2
2.0,0.0, & ! 3
3.0,0.0, & ! 4
1.0,1.0, & ! 6
2.0,1.0, & ! 7
3.0,1.0 /) ! 8
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 2
1, & ! 3
1, & ! 4
0, & ! 6
1, & ! 7
1/) ! 8
! Fill in elem data
numTriElems=0
numQuadElems=2
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/2,3/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD/) ! 3
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/1.5,0.5, & ! 2
2.5,0.5/) ! 3
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 2
2,3,6,5/) ! 3
!! elem mask
allocate(elemMask(numElems))
elemMask=(/0,1/)
else if (localPet .eq. 2) then
! Fill in node data
numNodes=9
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/5,6,7, &
9,10,11, &
13,14,15/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,1.0, & ! 5
1.0,1.0, & ! 6
2.0,1.0, & ! 7
0.0,2.0, & ! 9
1.0,2.0, & ! 10
2.0,2.0, & ! 11
0.0,3.0, & ! 13
1.0,3.0, & ! 14
2.0,3.0/) ! 15
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 5
0, & ! 6
1, & ! 7
2, & ! 9
2, & ! 10
2, & ! 11
2, & ! 13
2, & ! 14
2/) ! 15
! Fill in elem data
numTriElems=0
numQuadElems=4
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/4,5,7,8/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD/) ! 8
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,1.5, & ! 4
1.5,1.5, & ! 5
0.5,2.5, & ! 7
1.5,2.5/) ! 8
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,5,4, & ! 4
2,3,6,5, & ! 5
4,5,8,7, & ! 7
5,6,9,8/) ! 8
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,0,1/)
else if (localPet .eq. 3) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/7,8,11,12,15,16/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/2.0,1.0, & ! 7
3.0,1.0, & ! 8
2.0,2.0, & ! 11
3.0,2.0, & ! 12
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/1, & ! 7
1, & ! 8
2, & ! 11
3, & ! 12
2, & ! 15
3/) ! 16
! Fill in elem data
numTriElems=0
numQuadElems=1
numPolybreakElems=1
numElems=numTriElems+numQuadElems+numPolybreakElems
numElemConns=3*numTriElems+4*numQuadElems+7*numPolybreakElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/6,9/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 6
7/) ! 9
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/2.5,1.5, & ! 6
2.5,2.5/) ! 9
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3, & ! 6
3,4,6,ESMF_MESH_POLYBREAK,3,6,5/) ! 9
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,0/)
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_sph_polybreak_ugrid.nc", &
fileformat=ESMF_FILEFORMAT_UGRID, &
elementDistgrid=elemDistgrid, &
maskFlag=ESMF_MESHLOC_ELEMENT, &
varName="elemMask", &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! DEBUG OUTPUT
!call ESMF_MeshWrite(mesh,"mesh_pb_ugrid",rc=rc)
!if (rc .ne. ESMF_SUCCESS) rc=ESMF_FAILURE
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 2) correct=.false.
if (sdim .ne. 2) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_SPH_DEG) correct=.false.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
elementCount=numElemsTst, &
! elementConnCount=numElemConnsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (numNodes .ne. numNodesTst) correct=.false.
if (numElems .ne. numElemsTst) correct=.false.
!if (numElemConns .ne. numElemConnsTst) correct=.false.
! Debugging
!write(*,*) "numNodes=",numNodes,numNodesTst
!write(*,*) "numElems=",numElems,numElemsTst
!write(*,*) "numElemConns=",numElemConns,numElemConnsTst
! Get is present information
call ESMF_MeshGet(mesh, &
nodeMaskIsPresent=nodeMaskIsPresentTst, &
elementMaskIsPresent=elemMaskIsPresentTst, &
elementAreaIsPresent=elemAreaIsPresentTst, &
elementCoordsIsPresent=elemCoordsIsPresentTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug
! write(*,*) "nodeMaskIsPresent=",nodeMaskIsPresentTst
! write(*,*) "elemMaskIsPresent=",elemMaskIsPresentTst
! write(*,*) "elemAreaIsPresent=",elemAreaIsPresentTst
! write(*,*) "elemCoordsIsPresent=",elemCoordsIsPresentTst
! Check is present info
if ( nodeMaskIsPresentTst) correct=.false.
if (.not. elemMaskIsPresentTst) correct=.false.
if ( elemAreaIsPresentTst) correct=.false.
if (.not. elemCoordsIsPresentTst) correct=.false.
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeCoordsTst(2*numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
! allocate(elemIdsTst(numElemsTst))
! allocate(elemTypesTst(numElemsTst))
! allocate(elemConnTst(numElemConnsTst))
! allocate(elemMaskTst(numElemsTst))
! allocate(elemCoordsTst(2*numElemsTst))
! XMRKX
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeCoords=nodeCoordsTst, &
nodeOwners=nodeOwnersTst, &
! elementIds=elemIdsTst, &
! elementTypes=elemTypesTst, &
! elementConn=elemConnTst, &
! elementMask=elemMaskTst, &
! elementCoords=elemCoordsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! do i=1,numElemsTst
! write(*,*) localPet,"# ",elemIdsTst(i),"ea=",elemAreaTst(i),"ec=",elemCoordsTst(2*i-1),elemCoordsTst(2*i),"em=",elemMaskTst(i)
! enddo
! Check node ids
do i=1,numNodesTst
if (nodeIds(i) .ne. nodeIdsTst(i)) correct=.false.
enddo
! Check node Coords
k=1
do i=1,numNodesTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (nodeCoords(k) .ne. nodeCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Check node Owners
do i=1,numNodesTst
if (nodeOwners(i) .ne. nodeOwnersTst(i)) correct=.false.
enddo
! Check elem ids
! do i=1,numElemsTst
! if (elemIds(i) .ne. elemIdsTst(i)) correct=.false.
! enddo
! Check elem Types
! do i=1,numElemsTst
! if (elemTypes(i) .ne. elemTypesTst(i)) correct=.false.
! enddo
! Check elem Connections
! do i=1,numElemConnsTst
! if (elemConn(i) .ne. elemConnTst(i)) correct=.false.
! enddo
! Check elem mask
! do i=1,numElems
! if (elemMask(i) .ne. elemMaskTst(i)) correct=.false.
! enddo
! Debug output
!write(*,*) "elemMask =",elemMask
!write(*,*) "elemMaskTst=",elemMaskTst
! Check elem Coords
! k=1
! do i=1,numElemsTst ! Loop over nodes
! do j=1,2 ! Loop over coord spatial dim
! if (elemCoords(k) .ne. elemCoordsTst(k)) correct=.false.
! k=k+1
! enddo
! enddo
! Debug output
! write(*,*) "elemCoords =",elemCoords
! write(*,*) "elemCoordsTst=",elemCoordsTst
! deallocate node data
deallocate(nodeIds)
deallocate(nodeCoords)
deallocate(nodeOwners)
! deallocate elem data
deallocate(elemIds)
deallocate(elemTypes)
deallocate(elemCoords)
deallocate(elemConn)
deallocate(elemMask)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeCoordsTst)
deallocate(nodeOwnersTst)
! deallocate(elemIdsTst)
! deallocate(elemTypesTst)
! deallocate(elemConnTst)
! deallocate(elemMaskTst)
! deallocate(elemCoordsTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_from_sph_pb_UG_file
! This is a more through test that reads in a spherical 3D 2x2x1 mesh file
! and verifies that every part is correct.
subroutine check_mesh_from_sph_3D_UG_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns, numTriElems, numQuadElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! XMRKX !
! Create Dest Mesh
if (petCount .eq. 1) then
! Set number of nodes
numNodes=18
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8,9, &
10,11,12,13,14,15,16,17,18/)
! Allocate and fill node coordinate array.
! Since this is a 3D Mesh the size is 3x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/0.0,0.0,1.0, & ! node id 1
1.0,0.0,1.0, & ! node id 2
2.0,0.0,1.0, & ! node id 3
0.0,1.0,1.0, & ! node id 4
1.0,1.0,1.0, & ! node id 5
2.0,1.0,1.0, & ! node id 6
0.0,2.0,1.0, & ! node id 7
1.0,2.0,1.0, & ! node id 8
2.0,2.0,1.0, & ! node id 9
0.0,0.0,2.0, & ! node id 10
1.0,0.0,2.0, & ! node id 11
2.0,0.0,2.0, & ! node id 12
0.0,1.0,2.0, & ! node id 13
1.0,1.0,2.0, & ! node id 14
2.0,1.0,2.0, & ! node id 15
0.0,2.0,2.0, & ! node id 16
1.0,2.0,2.0, & ! node id 17
2.0,2.0,2.0 /) ! node id 18
! Allocate and fill the node owner array.
! Since this Mesh is all on PET 0, it's just set to all 0.
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on PET 0
! Set the number of each type of element, plus the total number.
numElems=4
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/1,2,3,4/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=ESMF_MESHELEMTYPE_HEX
! Allocate and fill the element connection type array.
! Note that entries in this array refer to the
! positions in the nodeIds, etc. arrays and that
! the order and number of entries for each element
! reflects that given in the Mesh options
! section for the corresponding entry
! in the elemTypes array.
allocate(elemConn(8*numElems))
elemConn=(/1,2,5,4,10,11,14,13, & ! elem id 1
2,3,6,5,11,12,15,14, & ! elem id 2
4,5,8,7,13,14,17,16, & ! elem id 3
5,6,9,8,14,15,18,17/) ! elem id 4
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPET .eq. 0) then !!! This part only for PET 0
! Set number of nodes
numNodes=8
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/1,2,4,5,10,11,13,14/)
! Allocate and fill node coordinate array.
! Since this is a 2D Mesh the size is 2x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/0.0,0.0,1.0, & ! node id 1
1.0,0.0,1.0, & ! node id 2
0.0,1.0,1.0, & ! node id 4
1.0,1.0,1.0, & ! node id 5
0.0,0.0,2.0, & ! node id 10
1.0,0.0,2.0, & ! node id 11
0.0,1.0,2.0, & ! node id 13
1.0,1.0,2.0 /) ! node id 14
! Allocate and fill the node owner array.
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! node id 1
0, & ! node id 2
0, & ! node id 4
0, & ! node id 5
0, & ! node id 10
0, & ! node id 11
0, & ! node id 13
0/) ! node id 14
! Set the number of each type of element, plus the total number.
numElems=1
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/1/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_HEX/) ! elem id 1
! Allocate and fill the element connection type array.
! Note that entry are local indices
allocate(elemConn(8*numElems))
elemConn=(/1,2,4,3,5,6,8,7/) ! elem id 1
else if (localPET .eq. 1) then !!! This part only for PET 1
! Set number of nodes
numNodes=8
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/2,3,5,6,11,12,14,15/)
! Allocate and fill node coordinate array.
! Since this is a 3D Mesh the size is 2x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/1.0,0.0,1.0, & ! node id 2
2.0,0.0,1.0, & ! node id 3
1.0,1.0,1.0, & ! node id 5
2.0,1.0,1.0, & ! node id 6
1.0,0.0,2.0, & ! node id 11
2.0,0.0,2.0, & ! node id 12
1.0,1.0,2.0, & ! node id 14
2.0,1.0,2.0/) ! node id 15
! Allocate and fill the node owner array.
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! node id 2
1, & ! node id 3
0, & ! node id 5
1, & ! node id 6
0, & ! node id 11
1, & ! node id 12
0, & ! node id 14
1/) ! node id 15
! Set the number of each type of element, plus the total number.
numElems=1
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/2/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_HEX/) ! elem id 1
! Allocate and fill the element connection type array.
! Note that entry are local indices
allocate(elemConn(8*numElems))
elemConn=(/1,2,4,3,5,6,8,7/) ! elem id 1
else if (localPET .eq. 2) then !!! This part only for PET 2
! Set number of nodes
numNodes=8
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/4,5,7,8,13,14,16,17/)
! Allocate and fill node coordinate array.
! Since this is a 3D Mesh the size is 2x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/0.0,1.0,1.0, & ! node id 4
1.0,1.0,1.0, & ! node id 5
0.0,2.0,1.0, & ! node id 7
1.0,2.0,1.0, & ! node id 8
0.0,1.0,2.0, & ! node id 13
1.0,1.0,2.0, & ! node id 14
0.0,2.0,2.0, & ! node id 16
1.0,2.0,2.0/) ! node id 17
! Allocate and fill the node owner array.
! Since this Mesh is all on PET 0, it's just set to all 0.
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! node id 4
0, & ! node id 5
2, & ! node id 7
2, & ! node id 8
0, & ! node id 13
0, & ! node id 14
2, & ! node id 16
2/) ! node id 17
! Set the number of each type of element, plus the total number.
numElems=1
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/3/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_HEX/) ! elem id 1
! Allocate and fill the element connection type array.
! Note that entry are local indices
allocate(elemConn(8*numElems))
elemConn=(/1,2,4,3,5,6,8,7/) ! elem id 1
else if (localPET .eq. 3) then !!! This part only for PET 3
! Set number of nodes
numNodes=8
! Allocate and fill the node id array.
allocate(nodeIds(numNodes))
nodeIds=(/5,6,8,9,14,15,17,18/)
! Allocate and fill node coordinate array.
! Since this is a 3D Mesh the size is 2x the
! number of nodes.
allocate(nodeCoords(3*numNodes))
nodeCoords=(/1.0,1.0,1.0, & ! node id 5
2.0,1.0,1.0, & ! node id 6
1.0,2.0,1.0, & ! node id 8
2.0,2.0,1.0, & ! node id 9
1.0,1.0,2.0, & ! node id 14
2.0,1.0,2.0, & ! node id 15
1.0,2.0,2.0, & ! node id 17
2.0,2.0,2.0/) ! node id 18
! Allocate and fill the node owner array.
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! node id 5
1, & ! node id 6
2, & ! node id 8
3, & ! node id 9
0, & ! node id 14
1, & ! node id 15
2, & ! node id 17
3/) ! node id 18
! Set the number of each type of element, plus the total number.
numElems=1
! Allocate and fill the element id array.
allocate(elemIds(numElems))
elemIds=(/4/)
! Allocate and fill the element topology type array.
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_HEX/) ! elem id 1
! Allocate and fill the element connection type array.
! Note that entry are local indices
allocate(elemConn(8*numElems))
elemConn=(/1,2,4,3,5,6,8,7/) ! elem id 1
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_sph_2x2x1_ugrid.nc", &
fileformat=ESMF_FILEFORMAT_UGRID, &
elementDistgrid=elemDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! DEBUG OUTPUT
!call ESMF_MeshWrite(mesh,"mesh_3D_UG",rc=rc)
!if (rc .ne. ESMF_SUCCESS) return
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 3) correct=.false.
if (sdim .ne. 3) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_SPH_DEG) correct=.false.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
elementCount=numElemsTst, &
elementConnCount=numElemConnsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (numNodes .ne. numNodesTst) correct=.false.
if (numElems .ne. numElemsTst) correct=.false.
if (numElems*8 .ne. numElemConnsTst) correct=.false.
! Debugging
!write(*,*) "numNodes=",numNodes,numNodesTst
!write(*,*) "numElems=",numElems,numElemsTst
!write(*,*) "numElemConns=",numElemConns,numElemConnsTst
! Get is present information
call ESMF_MeshGet(mesh, &
nodeMaskIsPresent=nodeMaskIsPresentTst, &
elementMaskIsPresent=elemMaskIsPresentTst, &
elementAreaIsPresent=elemAreaIsPresentTst, &
elementCoordsIsPresent=elemCoordsIsPresentTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug
! write(*,*) "nodeMaskIsPresent=",nodeMaskIsPresentTst
! write(*,*) "elemMaskIsPresent=",elemMaskIsPresentTst
! write(*,*) "elemAreaIsPresent=",elemAreaIsPresentTst
! write(*,*) "elemCoordsIsPresent=",elemCoordsIsPresentTst
! Check is present info
if (nodeMaskIsPresentTst) correct=.false.
if (elemMaskIsPresentTst) correct=.false.
if (elemAreaIsPresentTst) correct=.false.
if (elemCoordsIsPresentTst) correct=.false.
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeCoordsTst(3*numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
allocate(elemIdsTst(numElemsTst))
allocate(elemTypesTst(numElemsTst))
allocate(elemConnTst(numElemConnsTst))
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeCoords=nodeCoordsTst, &
nodeOwners=nodeOwnersTst, &
elementIds=elemIdsTst, &
elementTypes=elemTypesTst, &
elementConn=elemConnTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! do i=1,numElemsTst
! write(*,*) localPet,"# ",elemIdsTst(i),"ea=",elemAreaTst(i),"ec=",elemCoordsTst(2*i-1),elemCoordsTst(2*i),"em=",elemMaskTst(i)
! enddo
! Check node ids
do i=1,numNodesTst
if (nodeIds(i) .ne. nodeIdsTst(i)) correct=.false.
enddo
! Check node Coords
k=1
do i=1,numNodesTst ! Loop over nodes
do j=1,3
! Don't check 3rd dim, because it's normalized to Earth radius
if ((j<3) .and. (nodeCoords(k) .ne. nodeCoordsTst(k))) correct=.false.
k=k+1
enddo
enddo
! Check node Owners
do i=1,numNodesTst
if (nodeOwners(i) .ne. nodeOwnersTst(i)) correct=.false.
enddo
! Debug output
! write(*,*) "nodeMask =",nodeMask
! write(*,*) "nodeMaskTst=",nodeMaskTst
! Check elem ids
do i=1,numElemsTst
if (elemIds(i) .ne. elemIdsTst(i)) correct=.false.
enddo
! Check elem Types
do i=1,numElemsTst
if (elemTypes(i) .ne. elemTypesTst(i)) correct=.false.
enddo
! Check elem Connections
do i=1,numElemConnsTst
if (elemConn(i) .ne. elemConnTst(i)) correct=.false.
enddo
! Debug output
! write(*,*) "elemCoords =",elemCoords
! write(*,*) "elemCoordsTst=",elemCoordsTst
! deallocate node data
deallocate(nodeIds)
deallocate(nodeCoords)
deallocate(nodeOwners)
! deallocate elem data
deallocate(elemIds)
deallocate(elemTypes)
deallocate(elemConn)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeCoordsTst)
deallocate(nodeOwnersTst)
deallocate(elemIdsTst)
deallocate(elemTypesTst)
deallocate(elemConnTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_from_sph_3D_UG_file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Creates the following mesh on
! 1 or 4 PETs. Returns an error
! if run on other than 1 or 4 PETs
!
! Mesh Ids
!
! 3.0 13 ------ 14 ------- 15 ------- 16
! | | | 10 / |
! 2.5 | 7 | 8 | / |
! | | | / 9 |
! 2.0 9 ------- 10 ------- 11 ------- 12
! | | | |
! 1.5 | 4 | 5 | 6 |
! | | | |
! 1.0 5 ------- 6 -------- 7 -------- 8
! | | | |
! 0.5 | 1 | 2 | 3 |
! | | | |
! 0.0 1 ------- 2 -------- 3 -------- 4
!
! 0.0 0.5 1.0 1.5 2.0 2.5 3.0
!
! Node Ids at corners
! Element Ids in centers
!
!!!!!
!
! The owners for 1 PET are all Pet 0.
! The owners for 4 PETs are as follows:
!
! Mesh Owners
!
! 3.0 2 ------- 2 -------- 3 -------- 3
! | | | 3 / |
! | 2 | 2 | / |
! | | | / 3 |
! 2.0 2 ------- 2 -------- 3 -------- 3
! | | | |
! | 2 | 2 | 3 |
! | | | |
! 1.0 0 ------- 0 -------- 1 -------- 1
! | | | |
! | 0 | 1 | 1 |
! | | | |
! 0.0 0 ------- 0 -------- 1 -------- 1
!
! 0.0 1.0 2.0 3.0
!
! Node Owners at corners
! Element Owners in centers
!
!
! This is a more through test that reads in a spherical 3x3 SCRIP mesh file
! (that creates the mesh drawn above) and verifies that every part is correct.
! NOTE: The order of the nodes in the created mesh is heavily dependant on the SCRIP format to
! ESMF Mesh format conversion program in IO/interface. If that changes it's possible that this
! test will start reporting a failure and it will need to be changed to correct the order, etc.
! of the nodes.
subroutine check_mesh_from_sph_3x3_SC_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns, numTriElems, numQuadElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: elemDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Setup mesh info depending on the
! number of PETs
if (petCount .eq. 1) then
! Fill in node data
numNodes=16
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8, &
9,10,11,12,13,14,&
15,16/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
1.0,1.0, & ! 3
0.0,1.0, & ! 4
2.0,0.0, & ! 5
2.0,1.0, & ! 6
3.0,0.0, & ! 7
3.0,1.0, & ! 8
1.0,2.0, & ! 9
0.0,2.0, & ! 10
2.0,2.0, & ! 11
3.0,2.0, & ! 12
1.0,3.0, & ! 13
0.0,3.0, & ! 14
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=2
numQuadElems=8
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1,2,3,4,5,6,7,8,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 1
ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD, & ! 3
ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD, & ! 8
ESMF_MESHELEMTYPE_TRI, & ! 9
ESMF_MESHELEMTYPE_TRI/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5, & ! 1
1.5,0.5, & ! 2
2.5,0.5, & ! 3
0.5,1.5, & ! 4
1.5,1.5, & ! 5
2.5,1.5, & ! 6
0.5,2.5, & ! 7
1.5,2.5, & ! 8
2.75,2.25,& ! 9
2.25,2.75/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,3,4, & ! 1
2,5,6,3, & ! 2
5,7,8,6, & ! 3
4,3,9,10, & ! 4
3,6,11,9, & ! 5
6,8,12,11, & ! 6
10,9,13,14, & ! 7
9,11,15,13, & ! 8
11,12,16, & ! 9
11,16,15/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1, 0, 1, 1, 1, 1, 0, 1, 0, 1/)
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPet .eq. 0) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/0.0,0.0, & ! 1
1.0,0.0, & ! 2
1.0,1.0, & ! 3
0.0,1.0 /) ! 4
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=0 ! everything on proc 0
! Fill in elem data
numTriElems=0
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/1/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD/) ! 1
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,0.5/) ! 1
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,3,4/) ! 1
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1/)
else if (localPet .eq. 1) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/2,3,5,6,7,8/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/1.0,0.0, & ! 2
1.0,1.0, & ! 3
2.0,0.0, & ! 5
2.0,1.0, & ! 6
3.0,0.0, & ! 7
3.0,1.0 /) ! 8
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 2
0, & ! 3
1, & ! 5
1, & ! 6
1, & ! 7
1/) ! 8
! Fill in elem data
numTriElems=0
numQuadElems=2
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/2,3/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 2
ESMF_MESHELEMTYPE_QUAD/) ! 3
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/1.5,0.5, & ! 2
2.5,0.5/) ! 3
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,3,4,2, & ! 2
3,5,6,4/) ! 3
!! elem mask
allocate(elemMask(numElems))
elemMask=(/0,1/)
else if (localPet .eq. 2) then
! Fill in node data
numNodes=9
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/3,4,6, &
9,10,11, &
13,14,15/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/1.0,1.0, & ! 3
0.0,1.0, & ! 4
2.0,1.0, & ! 6
1.0,2.0, & ! 9
0.0,2.0, & ! 10
2.0,2.0, & ! 11
1.0,3.0, & ! 13
0.0,3.0, & ! 14
2.0,3.0/) ! 15
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/0, & ! 3
0, & ! 4
1, & ! 6
2, & ! 9
2, & ! 10
2, & ! 11
2, & ! 13
2, & ! 14
2/) ! 15
! Fill in elem data
numTriElems=0
numQuadElems=4
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/4,5,7,8/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 4
ESMF_MESHELEMTYPE_QUAD, & ! 5
ESMF_MESHELEMTYPE_QUAD, & ! 7
ESMF_MESHELEMTYPE_QUAD/) ! 8
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/0.5,1.5, & ! 4
1.5,1.5, & ! 5
0.5,2.5, & ! 7
1.5,2.5/) ! 8
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/2,1,4,5, & ! 4
1,3,6,4, & ! 5
5,4,7,8, & ! 7
4,6,9,7/) ! 8
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,1,0,1/)
else if (localPet .eq. 3) then
! Fill in node data
numNodes=6
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/6,8,11,12,15,16/)
!! node Coords
allocate(nodeCoords(numNodes*2))
nodeCoords=(/2.0,1.0, & ! 6
3.0,1.0, & ! 8
2.0,2.0, & ! 11
3.0,2.0, & ! 12
2.0,3.0, & ! 15
3.0,3.0 /) ! 16
!! node owners
allocate(nodeOwners(numNodes))
nodeOwners=(/1, & ! 7
1, & ! 8
2, & ! 11
3, & ! 12
2, & ! 15
3/) ! 16
! Fill in elem data
numTriElems=2
numQuadElems=1
numElems=numTriElems+numQuadElems
numElemConns=3*numTriElems+4*numQuadElems
!! elem ids
allocate(elemIds(numElems))
elemIds=(/6,9,10/)
!! elem types
allocate(elemTypes(numElems))
elemTypes=(/ESMF_MESHELEMTYPE_QUAD, & ! 6
ESMF_MESHELEMTYPE_TRI, & ! 9
ESMF_MESHELEMTYPE_TRI/) ! 10
!! elem coords
allocate(elemCoords(2*numElems))
elemCoords=(/2.5,1.5, & ! 6
2.75,2.25,& ! 9
2.25,2.75/) ! 10
!! elem conn
allocate(elemConn(numElemConns))
elemConn=(/1,2,4,3, & ! 6
3,4,6, & ! 9
3,6,5/) ! 10
!! elem mask
allocate(elemMask(numElems))
elemMask=(/1,0,1/)
endif
endif
! Create distgrid to ensure that elements are created on the
! same PET as described above
elemdistgrid=ESMF_DistGridCreate(elemIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file that's the same as the one described by info set up above
mesh=ESMF_MeshCreate("data/test_sph_3x3_scrip.nc", &
fileformat=ESMF_FILEFORMAT_SCRIP, &
elementDistgrid=elemDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! DEBUG OUTPUT
!call ESMF_MeshWrite(mesh,"mesh_3x3_scrip",rc=rc)
!if (rc .ne. ESMF_SUCCESS) rc=ESMF_FAILURE
! Init correct to true before looking for problems
correct=.true.
! Get dim and coord info
call ESMF_MeshGet(mesh, &
parametricDim=pdim, &
spatialDim=sdim, &
coordSys=coordSys, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (pdim .ne. 2) correct=.false.
if (sdim .ne. 2) correct=.false.
if (coordSys .ne. ESMF_COORDSYS_SPH_DEG) correct=.false.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
elementCount=numElemsTst, &
elementConnCount=numElemConnsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check Counts
if (numNodes .ne. numNodesTst) correct=.false.
if (numElems .ne. numElemsTst) correct=.false.
if (numElemConns .ne. numElemConnsTst) correct=.false.
! Debugging
!write(*,*) localPet,"numNodes=",numNodes,numNodesTst
!write(*,*) localPet,"numElems=",numElems,numElemsTst
!write(*,*) localPet,"numElemConns=",numElemConns,numElemConnsTst
! Get is present information
call ESMF_MeshGet(mesh, &
nodeMaskIsPresent=nodeMaskIsPresentTst, &
elementMaskIsPresent=elemMaskIsPresentTst, &
elementAreaIsPresent=elemAreaIsPresentTst, &
elementCoordsIsPresent=elemCoordsIsPresentTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug
! write(*,*) "nodeMaskIsPresent=",nodeMaskIsPresentTst
! write(*,*) "elemMaskIsPresent=",elemMaskIsPresentTst
! write(*,*) "elemAreaIsPresent=",elemAreaIsPresentTst
! write(*,*) "elemCoordsIsPresent=",elemCoordsIsPresentTst
! Check is present info
if ( nodeMaskIsPresentTst) correct=.false.
if (.not. elemMaskIsPresentTst) correct=.false.
if ( elemAreaIsPresentTst) correct=.false.
if (.not. elemCoordsIsPresentTst) correct=.false.
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeCoordsTst(2*numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
allocate(elemIdsTst(numElemsTst))
allocate(elemTypesTst(numElemsTst))
allocate(elemConnTst(numElemConnsTst))
allocate(elemMaskTst(numElemsTst))
allocate(elemCoordsTst(2*numElemsTst))
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeCoords=nodeCoordsTst, &
nodeOwners=nodeOwnersTst, &
elementIds=elemIdsTst, &
elementTypes=elemTypesTst, &
elementConn=elemConnTst, &
elementMask=elemMaskTst, &
elementCoords=elemCoordsTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Check node ids
do i=1,numNodesTst
if (nodeIds(i) .ne. nodeIdsTst(i)) correct=.false.
enddo
! Check node Coords
k=1
do i=1,numNodesTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (nodeCoords(k) .ne. nodeCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! Check node Owners
do i=1,numNodesTst
if (nodeOwners(i) .ne. nodeOwnersTst(i)) correct=.false.
enddo
! Check elem ids
do i=1,numElemsTst
if (elemIds(i) .ne. elemIdsTst(i)) correct=.false.
enddo
! Check elem Types
do i=1,numElemsTst
if (elemTypes(i) .ne. elemTypesTst(i)) correct=.false.
enddo
! Check elem Connections
do i=1,numElemConnsTst
if (elemConn(i) .ne. elemConnTst(i)) correct=.false.
enddo
! Check elem mask
do i=1,numElems
if (elemMask(i) .ne. elemMaskTst(i)) correct=.false.
enddo
! Check elem Coords
k=1
do i=1,numElemsTst ! Loop over nodes
do j=1,2 ! Loop over coord spatial dim
if (elemCoords(k) .ne. elemCoordsTst(k)) correct=.false.
k=k+1
enddo
enddo
! deallocate node data
deallocate(nodeIds)
deallocate(nodeCoords)
deallocate(nodeOwners)
! deallocate elem data
deallocate(elemIds)
deallocate(elemTypes)
deallocate(elemCoords)
deallocate(elemConn)
deallocate(elemMask)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeCoordsTst)
deallocate(nodeOwnersTst)
deallocate(elemIdsTst)
deallocate(elemTypesTst)
deallocate(elemConnTst)
deallocate(elemMaskTst)
deallocate(elemCoordsTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(elemDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_from_sph_3x3_SC_file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Creates the following mesh on
! 1 or 4 PETs. Returns an error
! if run on other than 1 or 4 PETs
!
! Mesh Ids
!
! 3.0 13 ------ 14 ------- 15 ------- 16
! | | | 10 / |
! 2.5 | 7 | 8 | / |
! | | | / 9 |
! 2.0 9 ------- 10 ------- 11 ------- 12
! | | | |
! 1.5 | 4 | 5 | 6 |
! | | | |
! 1.0 5 ------- 6 -------- 7 -------- 8
! | | | |
! 0.5 | 1 | 2 | 3 |
! | | | |
! 0.0 1 ------- 2 -------- 3 -------- 4
!
! 0.0 0.5 1.0 1.5 2.0 2.5 3.0
!
! Node Ids at corners
! Element Ids in centers
!
!!!!!
!
! The owners for 1 PET are all Pet 0.
! The owners for 4 PETs are as follows:
!
! Mesh Owners
!
! 3.0 2 ------- 2 -------- 3 -------- 3
! | | | 3 / |
! | 2 | 2 | / |
! | | | / 3 |
! 2.0 2 ------- 2 -------- 3 -------- 3
! | | | |
! | 2 | 2 | 3 |
! | | | |
! 1.0 0 ------- 0 -------- 1 -------- 1
! | | | |
! | 0 | 1 | 1 |
! | | | |
! 0.0 0 ------- 0 -------- 1 -------- 1
!
! 0.0 1.0 2.0 3.0
!
! Node Owners at corners
! Element Owners in centers
!
!
! This test checks the create dual option to mesh create from file.
! It uses a 3x3 ESMF Mesh file (shown above) and creates a dual
! from it.
subroutine test_create_dual_from_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer :: petCount, localPet
type(ESMF_VM) :: vm
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Read mesh from file
mesh=ESMF_MeshCreate("data/test_sph_3x3_esmf.nc", &
fileformat=ESMF_FILEFORMAT_ESMFMESH, &
convertToDual=.true., &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! DEBUG OUTPUT
!call ESMF_MeshWrite(mesh,"mesh_dual",rc=rc)
!if (rc .ne. ESMF_SUCCESS) rc=ESMF_FAILURE
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine test_create_dual_from_file
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Creates the following mesh on
! 1 or 4 PETs. Returns an error
! if run on other than 1 or 4 PETs
!
! Mesh Ids
!
! 3.0 13 ------ 14 ------- 15 ------- 16
! | | | 10 / |
! 2.5 | 7 | 8 | / |
! | | | / 9 |
! 2.0 9 ------- 10 ------- 11 ------- 12
! | | | |
! 1.5 | 4 | 5 | 6 |
! | | | |
! 1.0 5 ------- 6 -------- 7 -------- 8
! | | | |
! 0.5 | 1 | 2 | 3 |
! | | | |
! 0.0 1 ------- 2 -------- 3 -------- 4
!
! 0.0 0.5 1.0 1.5 2.0 2.5 3.0
!
! Node Ids at corners
! Element Ids in centers
!
!!!!!
!
! The owners for 1 PET are all Pet 0.
! The owners for 4 PETs are as follows:
!
! Mesh Owners
!
! 3.0 2 ------- 2 -------- 3 -------- 3
! | | | 3 / |
! | 2 | 2 | / |
! | | | / 3 |
! 2.0 2 ------- 2 -------- 3 -------- 3
! | | | |
! | 2 | 2 | 3 |
! | | | |
! 1.0 0 ------- 0 -------- 1 -------- 1
! | | | |
! | 0 | 1 | 1 |
! | | | |
! 0.0 0 ------- 0 -------- 1 -------- 1
!
! 0.0 1.0 2.0 3.0
!
! Node Owners at corners
! Element Owners in centers
!
!
! This test reads in a mesh and then uses the mesh create from file's
! built in redist capability to redist to a node distribution
subroutine check_mesh_node_redist_from_file(correct, rc)
type(ESMF_Mesh) :: mesh
logical :: correct
integer :: rc
integer, pointer :: nodeIds(:),nodeOwners(:),nodeMask(:)
real(ESMF_KIND_R8), pointer :: nodeCoords(:)
real(ESMF_KIND_R8), pointer :: ownedNodeCoords(:)
integer :: numNodes, numOwnedNodes, numOwnedNodesTst
integer :: numElems,numOwnedElemsTst
integer :: numElemConns, numTriElems, numQuadElems
real(ESMF_KIND_R8), pointer :: elemCoords(:)
integer, pointer :: elemIds(:),elemTypes(:),elemConn(:)
integer, allocatable :: elemMask(:)
real(ESMF_KIND_R8),allocatable :: elemArea(:)
integer :: petCount, localPet
type(ESMF_VM) :: vm
type(ESMF_DistGrid) :: nodeDistgrid
type(ESMF_Field) :: nodeField, elemField
integer :: i,j,k
integer :: numNodesTst, numElemsTst,numElemConnsTst
integer,allocatable :: elemIdsTst(:)
integer,allocatable :: elemTypesTst(:)
integer,allocatable :: elemConnTst(:)
real(ESMF_KIND_R8),allocatable :: elemAreaTst(:)
integer,allocatable :: nodeIdsTst(:)
real(ESMF_KIND_R8),allocatable :: nodeCoordsTst(:)
integer,allocatable :: nodeOwnersTst(:)
integer,allocatable :: nodeMaskTst(:)
integer,allocatable :: elemMaskTst(:)
real(ESMF_KIND_R8), allocatable :: elemCoordsTst(:)
logical :: nodeMaskIsPresentTst
logical :: elemMaskIsPresentTst
logical :: elemAreaIsPresentTst
logical :: elemCoordsIsPresentTst
integer :: pdim, sdim
type(ESMF_CoordSys_Flag) :: coordSys
logical :: found
! get global VM
call ESMF_VMGetGlobal(vm, rc=rc)
if (rc /= ESMF_SUCCESS) return
call ESMF_VMGet(vm, localPet=localPet, petCount=petCount, rc=rc)
if (rc /= ESMF_SUCCESS) return
! return with an error if not 1 or 4 PETs
if ((petCount /= 1) .and. (petCount /=4)) then
rc=ESMF_FAILURE
return
endif
! Setup mesh info depending on the
! number of PETs
if (petCount .eq. 1) then
! Fill in node data
numNodes=16
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,3,4,5,6,7,8, &
9,10,11,12,13,14,&
15,16/)
else if (petCount .eq. 4) then
! Setup mesh data depending on PET
if (localPet .eq. 0) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/11,12,15,16/)
else if (localPet .eq. 1) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/9,10, &
13,14/)
else if (localPet .eq. 2) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/3,4,7,8/)
else if (localPet .eq. 3) then
! Fill in node data
numNodes=4
!! node ids
allocate(nodeIds(numNodes))
nodeIds=(/1,2,5,6/)
endif
endif
! Create distgrid to test node redist
nodedistgrid=ESMF_DistGridCreate(nodeIds, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Read mesh from file and redist to node distribution in distgrid
mesh=ESMF_MeshCreate("data/test_sph_3x3_esmf.nc", &
fileformat=ESMF_FILEFORMAT_ESMFMESH, &
nodalDistgrid=nodeDistgrid, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Init correct to true before looking for problems
correct=.true.
! Get counts
call ESMF_MeshGet(mesh, &
nodeCount=numNodesTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Debug Output
!write(*,*) "numNodes=",numNodes,numNodesTst
! Allocate space for tst arrays
allocate(nodeIdsTst(numNodesTst))
allocate(nodeOwnersTst(numNodesTst))
! XMRKX
! Get Information
call ESMF_MeshGet(mesh, &
nodeIds=nodeIdsTst, &
nodeOwners=nodeOwnersTst, &
rc=rc)
if (rc /= ESMF_SUCCESS) return
! Loop over node ids that we specified should
! be on this PET and make sure they are here
do i=1,numNodes
! See if we can find in list of node ids from mesh
found=.false.
do j=1,numNodesTst
if (nodeIdsTst(j) == nodeIds(i)) then
found=.true.
exit
endif
enddo
! If not found set correct to false
if (.not. found) correct=.false.
enddo
! deallocate node data
deallocate(nodeIds)
! Deallocate tst Arrays
deallocate(nodeIdsTst)
deallocate(nodeOwnersTst)
! Get rid of Mesh
call ESMF_MeshDestroy(mesh, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Get rid of elemDistgrid
call ESMF_DistGridDestroy(nodeDistgrid, rc=rc)
if (rc /= ESMF_SUCCESS) return
! Return success
rc=ESMF_SUCCESS
end subroutine check_mesh_node_redist_from_file
end program ESMF_MeshFileIOUTest