Skip to content

Commit 34e3830

Browse files
VTKAPI | #236 | Create vtkAPI for mapvtk output as a replacement for external submodule
1 parent 603d30c commit 34e3830

File tree

13 files changed

+312
-42
lines changed

13 files changed

+312
-42
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ if (SEMBA_FDTD_ENABLE_OUTPUT_MODULE)
219219
add_subdirectory(external/VTKFortran)
220220
add_subdirectory(src_output)
221221
set(OUTPUT_LIBRARIES fdtd-output)
222+
set(VTK_API_LIBRARIES vtkAPI)
222223
endif()
223224
add_subdirectory(src_conformal)
224225
set(CONFORMAL_LIBRARIES conformal)
@@ -295,6 +296,7 @@ if(SEMBA_FDTD_MAIN_LIB)
295296
semba-outputs
296297
fdtd-utils
297298
${OUTPUT_LIBRARIES}
299+
${VTK_API_LIBRARIES}
298300
${SMBJSON_LIBRARIES}
299301
${MTLN_LIBRARIES})
300302
endif()

src_output/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ add_library(fdtd-output
1212
"farFieldProbeOutput.F90"
1313
"mapVTKOutput.F90"
1414
)
15+
add_library(vtkAPI
16+
"vtkAPI.F90"
17+
)
1518
target_link_libraries(fdtd-output
1619
semba-types
1720
semba-components
1821
fdtd-utils
1922
VTKFortran::VTKFortran
20-
)
23+
)
24+

src_output/vtkAPI.F90

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
module mod_vtkAPI
2+
implicit none
3+
private
4+
public :: vtk_structured_grid
5+
public :: create_vts_file
6+
public :: add_scalar
7+
public :: add_vector
8+
9+
type :: vtk_data_array
10+
character(len=:), allocatable :: name
11+
character(len=:), allocatable :: type
12+
integer :: num_components
13+
real, allocatable :: data(:)
14+
end type vtk_data_array
15+
16+
type :: vtk_structured_grid
17+
integer :: nx, ny, nz
18+
real, allocatable :: points(:, :) ! size(3, nx*ny*nz)
19+
type(vtk_data_array), allocatable :: scalars(:)
20+
type(vtk_data_array), allocatable :: vectors(:)
21+
end type vtk_structured_grid
22+
23+
contains
24+
25+
subroutine add_scalar(grid, name, data)
26+
type(vtk_structured_grid), intent(inout) :: grid
27+
character(len=*), intent(in) :: name
28+
real, intent(in) :: data(:)
29+
30+
type(vtk_data_array), allocatable :: tmp(:)
31+
integer :: n
32+
33+
if (.not. allocated(grid%scalars)) then
34+
allocate (grid%scalars(1))
35+
n = 1
36+
else
37+
n = size(grid%scalars) + 1
38+
allocate (tmp(n))
39+
tmp(1:n - 1) = grid%scalars
40+
call move_alloc(tmp, grid%scalars)
41+
end if
42+
43+
grid%scalars(n)%name = name
44+
grid%scalars(n)%type = 'Float32'
45+
grid%scalars(n)%num_components = 1
46+
grid%scalars(n)%data = data
47+
end subroutine add_scalar
48+
49+
subroutine add_vector(grid, name, data)
50+
type(vtk_structured_grid), intent(inout) :: grid
51+
character(len=*), intent(in) :: name
52+
real, intent(in) :: data(:)
53+
54+
type(vtk_data_array), allocatable :: tmp(:)
55+
integer :: n
56+
57+
if (.not. allocated(grid%vectors)) then
58+
allocate (grid%vectors(1))
59+
n = 1
60+
else
61+
n = size(grid%vectors) + 1
62+
allocate (tmp(n))
63+
tmp(1:n - 1) = grid%vectors
64+
call move_alloc(tmp, grid%vectors)
65+
end if
66+
67+
grid%vectors(n)%name = name
68+
grid%vectors(n)%type = 'Float32'
69+
grid%vectors(n)%num_components = 3
70+
grid%vectors(n)%data = data
71+
end subroutine add_vector
72+
73+
subroutine create_vts_file(grid, filename)
74+
type(vtk_structured_grid), intent(in) :: grid
75+
character(len=*), intent(in) :: filename
76+
integer :: iunit, i
77+
78+
open (newunit=iunit, file=filename, status='replace', action='write', form='formatted')
79+
80+
! write header
81+
write (iunit, *) '<VTKFile type="StructuredGrid" version="1.0" byte_order="LittleEndian" header_type="UInt64">'
82+
write (iunit, *) ' <StructuredGrid WholeExtent="0 ', grid%nx - 1, ' 0 ', grid%ny - 1, ' 0 ', grid%nz - 1, '">'
83+
write (iunit, *) ' <Piece Extent="0 ', grid%nx - 1, ' 0 ', grid%ny - 1, ' 0 ', grid%nz - 1, '">'
84+
write (iunit, *) ' <PointData Scalars="Density" Vectors="Momentum">'
85+
86+
! write scalars
87+
do i = 1, size(grid%scalars)
88+
write (iunit, '(A)') ' <DataArray type="Float32" Name="'//trim(grid%scalars(i)%name)//'" format="ascii">'
89+
write (iunit, '(1000(F12.6,1X))') grid%scalars(i)%data
90+
write (iunit, '(A)') ' </DataArray>'
91+
end do
92+
93+
! write vectors
94+
do i = 1, size(grid%vectors)
95+
write(iunit,'(A)') ' <DataArray type="Float32" Name="'//trim(grid%vectors(i)%name)//'" NumberOfComponents="3" format="ascii">'
96+
write (iunit, '(1000(F12.6,1X))') grid%vectors(i)%data
97+
write (iunit, '(A)') ' </DataArray>'
98+
end do
99+
100+
write (iunit, *) ' </PointData>'
101+
write (iunit, *) ' <CellData>'
102+
write (iunit, *) ' </CellData>'
103+
write (iunit, *) ' <Points>'
104+
write (iunit, '(A)') ' <DataArray type="Float32" Name="Points" NumberOfComponents="3" format="ascii">'
105+
write (iunit, '(1000(F12.6,1X))') grid%points
106+
write (iunit, '(A)') ' </DataArray>'
107+
write (iunit, *) ' </Points>'
108+
write (iunit, *) ' </Piece>'
109+
write (iunit, *) ' </StructuredGrid>'
110+
write (iunit, *) '</VTKFile>'
111+
112+
close (iunit)
113+
end subroutine create_vts_file
114+
115+
end module mod_vtkAPI

test/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ if (SEMBA_FDTD_ENABLE_SMBJSON)
2121
set(SMBJSON_TESTS_LIBRARY smbjson_tests)
2222
add_subdirectory(rotate)
2323
set(ROTATE_TESTS_LIBRARY rotate_tests)
24-
add_subdirectory(vtk)
25-
set(VTK_TESTS_LIBRARY vtk_tests)
2624

2725
if (SEMBA_FDTD_ENABLE_OUTPUT_MODULE)
2826
add_subdirectory(output)
2927
set(OUPUT_TESTS_LIBRARY output_tests)
28+
set(VTK_API_TESTS_LIBRARY vtkAPI_tests)
3029
endif()
3130

3231
if (NOT SEMBA_FDTD_ENABLE_MPI)
@@ -50,7 +49,8 @@ target_link_libraries(fdtd_tests
5049
${HDF_TESTS_LIBRARY}
5150
${VTK_TESTS_LIBRARY}
5251
${SYSTEM_TESTS_LIBRARY}
53-
${OBSERVATION_TESTS_LIBRARY}
52+
${VTK_API_TESTS_LIBRARY}
5453
${OUPUT_TESTS_LIBRARY}
54+
${OBSERVATION_TESTS_LIBRARY}
5555
GTest::gtest_main
5656
)

test/fdtd_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#ifdef CompileWithSMBJSON
88
#include "smbjson/smbjson_tests.h"
99
#include "rotate/rotate_tests.h"
10-
#include "vtk/vtk_tests.h"
1110
#include "output/output_tests.h"
11+
#include "output/vtkAPI_tests.h"
1212
#endif
1313
#ifndef CompileWithMPI
1414
#include "observation/observation_tests.h"

test/output/CMakeLists.txt

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,28 @@ add_library(
77
"test_volumic_utils.F90"
88
)
99

10+
add_library(
11+
vtkAPI_test_fortran
12+
"test_vtkAPI.F90"
13+
)
14+
15+
add_library(output_tests "output_tests.cpp")
16+
add_library(vtkAPI_tests "vtkAPI_tests.cpp")
17+
1018
target_link_libraries(output_test_fortran
1119
semba-outputs
1220
fdtd-output
1321
test_utils_fortran
1422
)
15-
16-
add_library(output_tests "output_tests.cpp")
17-
1823
target_link_libraries(output_tests
1924
output_test_fortran
2025
GTest::gtest
26+
)
27+
target_link_libraries(vtkAPI_test_fortran
28+
vtkAPI
29+
test_utils_fortran
30+
)
31+
target_link_libraries(vtkAPI_tests
32+
vtkAPI_test_fortran
33+
GTest::gtest
2134
)

test/output/test_vtkAPI.F90

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
!==============================
2+
! mod_vtkAPI testsuite
3+
!==============================
4+
5+
integer function test_vtkAPI_basic() bind(C) result(error_cnt)
6+
use mod_vtkAPI
7+
implicit none
8+
type(vtk_structured_grid) :: grid
9+
real, allocatable :: points(:,:), density(:), momentum(:)
10+
integer :: nx, ny, nz, n, i,j,k
11+
12+
error_cnt = 0
13+
nx = 3; ny = 2; nz = 2
14+
grid%nx = nx; grid%ny = ny; grid%nz = nz
15+
16+
allocate(grid%points(3, nx*ny*nz))
17+
! Fill points
18+
n = 0
19+
do k=0,nz-1
20+
do j=0,ny-1
21+
do i=0,nx-1
22+
n = n + 1
23+
grid%points(1,n) = real(i)
24+
grid%points(2,n) = real(j)
25+
grid%points(3,n) = real(k)
26+
end do
27+
end do
28+
end do
29+
30+
! Single scalar field
31+
allocate(density(nx*ny*nz))
32+
do i=1,nx*ny*nz
33+
density(i) = real(i)
34+
end do
35+
call add_scalar(grid,'Density',density)
36+
37+
! Single vector field
38+
allocate(momentum(3*nx*ny*nz))
39+
do i=1,nx*ny*nz
40+
momentum(3*i-2) = real(i)
41+
momentum(3*i-1) = real(i*10)
42+
momentum(3*i ) = real(i*100)
43+
end do
44+
call add_vector(grid,'Momentum',momentum)
45+
46+
! ==== Tests ====
47+
if (size(grid%points,1)/=3 .or. size(grid%points,2)/=nx*ny*nz) error_cnt=error_cnt+1
48+
if (.not. allocated(grid%scalars) .or. size(grid%scalars)/=1) error_cnt=error_cnt+1
49+
if (.not. allocated(grid%vectors) .or. size(grid%vectors)/=1) error_cnt=error_cnt+1
50+
if (grid%scalars(1)%data(1)/=1.0) error_cnt=error_cnt+1
51+
if (grid%vectors(1)%data(2)/=10.0) error_cnt=error_cnt+1
52+
if (grid%vectors(1)%data(3)/=100.0) error_cnt=error_cnt+1
53+
54+
end function
55+
56+
57+
!--------------------------------------------------
58+
integer function test_vtkAPI_multiple_scalars_vectors() bind(C) result(error_cnt)
59+
use mod_vtkAPI
60+
implicit none
61+
type(vtk_structured_grid) :: grid
62+
real, allocatable :: density(:), temperature(:), momentum(:), velocity(:)
63+
integer :: nx, ny, nz, i
64+
65+
error_cnt = 0
66+
nx = 2; ny = 2; nz = 2
67+
grid%nx = nx; grid%ny = ny; grid%nz = nz
68+
allocate(grid%points(3, nx*ny*nz))
69+
grid%points = 0.0
70+
71+
! Scalars
72+
allocate(density(nx*ny*nz), temperature(nx*ny*nz))
73+
do i=1,nx*ny*nz
74+
density(i) = real(i)
75+
temperature(i) = real(i*2)
76+
end do
77+
call add_scalar(grid,'Density',density)
78+
call add_scalar(grid,'Temperature',temperature)
79+
80+
! Vectors
81+
allocate(momentum(3*nx*ny*nz), velocity(3*nx*ny*nz))
82+
do i=1,nx*ny*nz
83+
momentum(3*i-2) = real(i)
84+
momentum(3*i-1) = real(i*10)
85+
momentum(3*i ) = real(i*100)
86+
velocity(3*i-2) = real(i*0.1)
87+
velocity(3*i-1) = real(i*0.2)
88+
velocity(3*i ) = real(i*0.3)
89+
end do
90+
call add_vector(grid,'Momentum',momentum)
91+
call add_vector(grid,'Velocity',velocity)
92+
93+
! ==== Tests ====
94+
if (size(grid%scalars)/=2) error_cnt=error_cnt+1
95+
if (size(grid%vectors)/=2) error_cnt=error_cnt+1
96+
if (grid%scalars(2)%data(1)/=2.0) error_cnt=error_cnt+1
97+
if (grid%vectors(2)%data(3)/=0.6) error_cnt=error_cnt+1
98+
99+
end function
100+
101+
102+
!--------------------------------------------------
103+
integer function test_vtkAPI_empty_grid() bind(C) result(error_cnt)
104+
use mod_vtkAPI
105+
implicit none
106+
type(vtk_structured_grid) :: grid
107+
108+
error_cnt = 0
109+
grid%nx = 0; grid%ny = 0; grid%nz = 0
110+
111+
! Should handle empty allocations gracefully
112+
if (allocated(grid%points)) error_cnt=error_cnt+1
113+
if (allocated(grid%scalars)) error_cnt=error_cnt+1
114+
if (allocated(grid%vectors)) error_cnt=error_cnt+1
115+
116+
end function
117+
118+
119+
!--------------------------------------------------
120+
integer function test_vtkAPI_write_file() bind(C)
121+
use mod_vtkAPI
122+
implicit none
123+
type(vtk_structured_grid) :: grid
124+
real, allocatable :: points(:,:), density(:)
125+
integer :: nx, ny, nz, n, i
126+
integer :: error_cnt
127+
128+
error_cnt = 0
129+
nx=2; ny=2; nz=1
130+
grid%nx = nx; grid%ny = ny; grid%nz = nz
131+
allocate(grid%points(3, nx*ny*nz))
132+
! Fill points
133+
n=0
134+
do i=0,nx*ny*nz-1
135+
grid%points(:,i+1) = real(i)
136+
end do
137+
138+
! Scalar
139+
allocate(density(nx*ny*nz))
140+
density = 1.0
141+
call add_scalar(grid,'Density',density)
142+
143+
! ==== Tests ====
144+
! Attempt to write file
145+
call create_vts_file(grid,'test_vtk_output.vts')
146+
147+
! If file created, assume success
148+
open(unit=10, file='test_vtk_output.vts', status='old', action='read', iostat=i)
149+
if (i /= 0) then
150+
error_cnt = error_cnt + 1
151+
else
152+
close(10)
153+
end if
154+
155+
end function

test/output/vtkAPI_tests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "vtkAPI_tests.h"

test/output/vtkAPI_tests.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifdef CompileWithNewOutputModule
2+
#include <gtest/gtest.h>
3+
4+
extern "C" int test_vtkapi_basic();
5+
extern "C" int test_vtkapi_multiple_scalars_vectors();
6+
extern "C" int test_vtkapi_empty_grid();
7+
extern "C" int test_vtkapi_write_file();
8+
9+
TEST(vtkapi, test_basic_single_scalar_vector) {EXPECT_EQ(0, test_vtkapi_basic());}
10+
TEST(vtkapi, test_multiple_scalars_vectors) {EXPECT_EQ(0, test_vtkapi_multiple_scalars_vectors());}
11+
TEST(vtkapi, test_empty_grid_handling) {EXPECT_EQ(0, test_vtkapi_empty_grid());}
12+
TEST(vtkapi, test_write_vts_file) {EXPECT_EQ(0, test_vtkapi_write_file());}
13+
14+
#endif

0 commit comments

Comments
 (0)