-
-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathlow_level_petscsection.jl
More file actions
244 lines (202 loc) · 8.46 KB
/
Copy pathlow_level_petscsection.jl
File metadata and controls
244 lines (202 loc) · 8.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
using Test
using PETSc
using MPI
# Initialize PETSc
petsclib = PETSc.getlib()
PETSc.initialize(petsclib)
test_comm = Sys.iswindows() ? LibPETSc.PETSC_COMM_SELF : MPI.COMM_SELF
@testset "PetscSection Low-Level API" begin
@testset "Basic Section Creation and Query" begin
# Create a section (wrapper has wrong signature, use ccall)
section = Ref{LibPETSc.PetscSection}()
err = ccall(
(:PetscSectionCreate, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(MPI.MPI_Comm, Ptr{LibPETSc.PetscSection}),
test_comm, section
)
@test err == 0
@test section[] != C_NULL
# Set chart: range of valid point indices [pStart, pEnd)
LibPETSc.PetscSectionSetChart(petsclib, section[], 0, 10)
# Verify chart
pStart, pEnd = LibPETSc.PetscSectionGetChart(petsclib, section[])
@test pStart == 0
@test pEnd == 10
# Set DOF count for each point
for p in 0:9
num_dofs = (p < 4) ? 1 : 2 # Different DOFs per point
LibPETSc.PetscSectionSetDof(petsclib, section[], p, num_dofs)
end
# Setup: compute offsets
LibPETSc.PetscSectionSetUp(petsclib, section[])
# Query DOF counts
for p in 0:9
dof = LibPETSc.PetscSectionGetDof(petsclib, section[], p)
expected_dof = (p < 4) ? 1 : 2
@test dof == expected_dof
end
# Query offsets
offset5 = LibPETSc.PetscSectionGetOffset(petsclib, section[], 5)
@test offset5 == 4 * 1 + 1 * 2 # Points 0-3 have 1 DOF each (4), point 4 has 2 DOFs (2)
# Get total storage size
storage_size = LibPETSc.PetscSectionGetStorageSize(petsclib, section[])
expected_size = 4 * 1 + 6 * 2 # 4 points with 1 DOF + 6 points with 2 DOFs
@test storage_size == expected_size
# Cleanup (wrapper has wrong signature, use ccall)
err = ccall(
(:PetscSectionDestroy, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(Ptr{LibPETSc.PetscSection},),
section
)
@test err == 0
end
@testset "Multi-Field Section" begin
# Create section with 2 fields
section = Ref{LibPETSc.PetscSection}()
err = ccall(
(:PetscSectionCreate, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(MPI.MPI_Comm, Ptr{LibPETSc.PetscSection}),
test_comm, section
)
@test err == 0
LibPETSc.PetscSectionSetNumFields(petsclib, section[], 2)
# Verify number of fields
num_fields = LibPETSc.PetscSectionGetNumFields(petsclib, section[])
@test num_fields == 2
# Set field names
LibPETSc.PetscSectionSetFieldName(petsclib, section[], 0, "velocity")
LibPETSc.PetscSectionSetFieldName(petsclib, section[], 1, "pressure")
# Note: PetscSectionGetFieldName wrapper has signature issues, skip testing retrieval
# Set chart
LibPETSc.PetscSectionSetChart(petsclib, section[], 0, 5)
# Set field components
LibPETSc.PetscSectionSetFieldComponents(petsclib, section[], 0, 3)
LibPETSc.PetscSectionSetFieldComponents(petsclib, section[], 1, 1)
# Verify field components
vel_comp = LibPETSc.PetscSectionGetFieldComponents(petsclib, section[], 0)
pres_comp = LibPETSc.PetscSectionGetFieldComponents(petsclib, section[], 1)
@test vel_comp == 3
@test pres_comp == 1
# Set DOFs per field per point
for p in 0:4
LibPETSc.PetscSectionSetFieldDof(petsclib, section[], p, 0, 3) # 3 velocity DOFs
LibPETSc.PetscSectionSetFieldDof(petsclib, section[], p, 1, 1) # 1 pressure DOF
LibPETSc.PetscSectionSetDof(petsclib, section[], p, 4) # Total: 4 DOFs
end
LibPETSc.PetscSectionSetUp(petsclib, section[])
# Verify field DOFs
for p in 0:4
vel_dof = LibPETSc.PetscSectionGetFieldDof(petsclib, section[], p, 0)
pres_dof = LibPETSc.PetscSectionGetFieldDof(petsclib, section[], p, 1)
total_dof = LibPETSc.PetscSectionGetDof(petsclib, section[], p)
@test vel_dof == 3
@test pres_dof == 1
@test total_dof == 4
end
# Get total storage
storage_size = LibPETSc.PetscSectionGetStorageSize(petsclib, section[])
@test storage_size == 5 * 4 # 5 points with 4 DOFs each
# Cleanup
err = ccall(
(:PetscSectionDestroy, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(Ptr{LibPETSc.PetscSection},),
section
)
@test err == 0
end
@testset "Section with Uniform DOFs" begin
# Create section
section = Ref{LibPETSc.PetscSection}()
err = ccall(
(:PetscSectionCreate, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(MPI.MPI_Comm, Ptr{LibPETSc.PetscSection}),
test_comm, section
)
@test err == 0
# Set chart
npoints = 100
LibPETSc.PetscSectionSetChart(petsclib, section[], 0, npoints)
# Set uniform DOF count
dofs_per_point = 5
for p in 0:npoints-1
LibPETSc.PetscSectionSetDof(petsclib, section[], p, dofs_per_point)
end
LibPETSc.PetscSectionSetUp(petsclib, section[])
# Verify storage size
storage_size = LibPETSc.PetscSectionGetStorageSize(petsclib, section[])
@test storage_size == npoints * dofs_per_point
# Verify max DOF
max_dof = LibPETSc.PetscSectionGetMaxDof(petsclib, section[])
@test max_dof == dofs_per_point
# Verify offsets are sequential
for p in 0:npoints-1
expected_offset = p * dofs_per_point
actual_offset = LibPETSc.PetscSectionGetOffset(petsclib, section[], p)
@test actual_offset == expected_offset
end
# Cleanup
err = ccall(
(:PetscSectionDestroy, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(Ptr{LibPETSc.PetscSection},),
section
)
@test err == 0
end
@testset "Section Copy" begin
# Create original section
section = Ref{LibPETSc.PetscSection}()
err = ccall(
(:PetscSectionCreate, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(MPI.MPI_Comm, Ptr{LibPETSc.PetscSection}),
test_comm, section
)
@test err == 0
LibPETSc.PetscSectionSetChart(petsclib, section[], 0, 5)
for p in 0:4
LibPETSc.PetscSectionSetDof(petsclib, section[], p, p + 1)
end
LibPETSc.PetscSectionSetUp(petsclib, section[])
# Create new section for copy
section_copy = Ref{LibPETSc.PetscSection}()
err = ccall(
(:PetscSectionCreate, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(MPI.MPI_Comm, Ptr{LibPETSc.PetscSection}),
test_comm, section_copy
)
@test err == 0
# Copy section
LibPETSc.PetscSectionCopy(petsclib, section[], section_copy[])
# Verify copy has same properties
pStart_orig, pEnd_orig = LibPETSc.PetscSectionGetChart(petsclib, section[])
pStart_copy, pEnd_copy = LibPETSc.PetscSectionGetChart(petsclib, section_copy[])
@test pStart_orig == pStart_copy
@test pEnd_orig == pEnd_copy
storage_orig = LibPETSc.PetscSectionGetStorageSize(petsclib, section[])
storage_copy = LibPETSc.PetscSectionGetStorageSize(petsclib, section_copy[])
@test storage_orig == storage_copy
# Cleanup
err = ccall(
(:PetscSectionDestroy, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(Ptr{LibPETSc.PetscSection},),
section
)
@test err == 0
err = ccall(
(:PetscSectionDestroy, petsclib.petsc_library),
PETSc.LibPETSc.PetscErrorCode,
(Ptr{LibPETSc.PetscSection},),
section_copy
)
@test err == 0
end
end
PETSc.finalize(petsclib)