Skip to content

Commit 0ac3b9e

Browse files
Merge pull request #199 from gridap/add_hcurl_projection_tests
Add Hcurl-projection test + fix BUG
2 parents 49cdff0 + 2ac5643 commit 0ac3b9e

File tree

5 files changed

+141
-4
lines changed

5 files changed

+141
-4
lines changed

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
- BUG fix in `_generate_sign_flips(...)` private helper function for Nedelec elements. Since PR[#199](https://github.com/gridap/GridapDistributed.jl/pull/199).
12+
13+
### Added
14+
- An Hcurl projection test case. Since PR[#199](https://github.com/gridap/GridapDistributed.jl/pull/199).
15+
1016
## [0.4.12] - 2026-03-14
1117

1218
### Changed

src/DivAndCurlConformingFESpaces.jl

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,8 @@ function _common_fe_space_constructor(model,cell_reffes;conformity,split_own_and
8787
DistributedSingleFieldFESpace(spaces,gids,trian,vector_type)
8888
end
8989

90-
function _generate_sign_flips(model,cell_reffes)
91-
cell_gids = get_cell_gids(model)
92-
sign_flips = map(local_views(model),partition(cell_gids),cell_reffes) do m, p, cell_reffe
90+
function _generate_sign_flips(model, cell_gids, cell_reffes)
91+
sign_flips = map(local_views(model),partition(cell_gids),cell_reffes) do m, p, cell_reffe
9392
D = num_cell_dims(model)
9493

9594
gtopo = get_grid_topology(m)
@@ -145,4 +144,34 @@ function _generate_sign_flips(model,cell_reffes)
145144
cache = fetch_vector_ghost_values_cache(sign_flips,partition(cell_gids))
146145
fetch_vector_ghost_values!(sign_flips,cache) |> wait
147146
sign_flips
147+
end
148+
149+
150+
function _generate_sign_flips(model::DistributedDiscreteModel,
151+
cell_reffes::AbstractVector{<:AbstractVector{<:GenericRefFE{<:RaviartThomas}}})
152+
cell_gids = get_cell_gids(model)
153+
_generate_sign_flips(model,cell_gids,cell_reffes)
148154
end
155+
156+
function _generate_sign_flips(model::DistributedDiscreteModel,
157+
cell_reffes::AbstractVector{<:AbstractVector{<:GenericRefFE{<:Nedelec}}})
158+
Dc=num_cell_dims(model)
159+
is_simp = false
160+
map(cell_reffes) do cell_reffes
161+
cell_reffe = cell_reffes[1]
162+
polytope = get_polytope(cell_reffe)
163+
if (Gridap.Geometry.is_simplex(polytope))
164+
is_simp=true
165+
end
166+
end
167+
if (Dc==2 || is_simp)
168+
map(local_views(model), cell_reffes) do model, cell_reffes
169+
Gridap.FESpaces._no_sign_flip(model, cell_reffes)
170+
end
171+
else
172+
@assert Dc==3
173+
cell_gids = get_cell_gids(model)
174+
_generate_sign_flips(model,cell_gids,cell_reffes)
175+
end
176+
end
177+

test/HcurlProjectionTests.jl

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
module HcurlProjectionTests
2+
3+
using Gridap
4+
using PartitionedArrays
5+
using GridapDistributed
6+
using Test
7+
8+
u_ex_2D((x,y)) = 2*VectorValue(-y,x)
9+
f_ex_2D(x) = u_ex_2D(x)
10+
u_ex_3D((x,y,z)) = 2*VectorValue(-y,x,0.) - VectorValue(0.,-z,y)
11+
f_ex_3D(x) = u_ex_3D(x)
12+
13+
function get_analytical_functions(Dc)
14+
if Dc==2
15+
return u_ex_2D, f_ex_2D
16+
else
17+
@assert Dc==3
18+
return u_ex_3D, f_ex_3D
19+
end
20+
end
21+
22+
function solve_hcurl_projection(model::GridapDistributed.DistributedDiscreteModel{Dc},order) where {Dc}
23+
u_ex, f_ex=get_analytical_functions(Dc)
24+
25+
V = FESpace(model,
26+
ReferenceFE(nedelec,order),
27+
conformity=:Hcurl,
28+
dirichlet_tags="boundary")
29+
30+
U = TrialFESpace(V,u_ex)
31+
32+
trian = Triangulation(model)
33+
degree = 2*(order+1)
34+
= Measure(trian,degree)
35+
36+
a(u,v) = ( (∇×u)(∇×v) + uv )dΩ
37+
l(v) = (f_exv)dΩ
38+
39+
op = AffineFEOperator(a,l,U,V)
40+
if (num_free_dofs(U)==0)
41+
# UMFPACK cannot handle empty linear systems
42+
uh = zero(U)
43+
else
44+
uh = solve(op)
45+
end
46+
uh,U
47+
end
48+
49+
function check_error_hcurl_projection(model::GridapDistributed.DistributedDiscreteModel{Dc},order,uh) where {Dc}
50+
trian = Triangulation(model)
51+
degree = 2*(order+1)
52+
= Measure(trian,degree)
53+
54+
u_ex, f_ex = get_analytical_functions(Dc)
55+
56+
eu = u_ex - uh
57+
58+
l2(v) = sqrt(sum((vv)*dΩ))
59+
hcurl(v) = sqrt(sum((vv + (∇×v)(∇×v))*dΩ))
60+
61+
eu_l2 = l2(eu)
62+
eu_hcurl = hcurl(eu)
63+
64+
tol = 1.0e-6
65+
@test eu_l2 < tol
66+
@test eu_hcurl < tol
67+
end
68+
69+
function test_2d(ranks,parts,order)
70+
domain = (0,1,0,1)
71+
model = CartesianDiscreteModel(ranks,parts,domain,(4,4))
72+
solve_hcurl_projection(model,order) |> x -> check_error_hcurl_projection(model,order,x[1])
73+
end
74+
75+
function test_3d(ranks,parts,order)
76+
domain = (0,1,0,1,0,1)
77+
model = CartesianDiscreteModel(ranks,parts,domain,(4,4,4))
78+
solve_hcurl_projection(model,order) |> x -> check_error_hcurl_projection(model,order,x[1])
79+
end
80+
81+
function main(distribute,parts)
82+
ranks = distribute(LinearIndices((prod(parts),)))
83+
84+
if length(parts)==2
85+
for order=0:2
86+
test_2d(ranks,parts,order)
87+
end
88+
elseif length(parts)==3
89+
for order=0:2
90+
test_3d(ranks,parts,order)
91+
end
92+
else
93+
@assert false
94+
end
95+
end
96+
97+
end #module

test/mpi/runtests_np4.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module NP4
2-
# All test running on 4 procs here
2+
# All tests running on either 1 or 4 procs here
33

44
using GridapDistributed
55
using PartitionedArrays
@@ -35,6 +35,7 @@ include("../VisualizationTests.jl")
3535
include("../AutodiffTests.jl")
3636
include("../ConstantFESpacesTests.jl")
3737
include("../MacroDiscreteModelsTests.jl")
38+
include("../HcurlProjectionTests.jl")
3839

3940
include("runtests_np4_body.jl")
4041

test/mpi/runtests_np4_body.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ function all_tests(distribute, parts)
4848

4949
StokesHdivDGTests.main(distribute, parts)
5050
PArrays.toc!(t, "StokesHdivDG")
51+
52+
HcurlProjectionTests.main(distribute, parts)
53+
PArrays.toc!(t, "HcurlProjection")
54+
5155
end
5256

5357
if TESTCASE ("all", "mpi-transient")

0 commit comments

Comments
 (0)