Skip to content

Commit 5a0f322

Browse files
committed
Added div, curl, and trace operators
1 parent 8f5338d commit 5a0f322

File tree

9 files changed

+107
-20
lines changed

9 files changed

+107
-20
lines changed

src/FESpaces/FEBases.jl

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ export FEBasis
77
import Gridap: CellBasis
88
import Gridap: gradient
99
import Gridap: symmetric_gradient
10+
import Base: div
11+
import Gridap: trace
12+
import Gridap: curl
1013
import Gridap: inner
1114
import Base: +, -, *
1215
import Gridap: restrict
@@ -23,7 +26,7 @@ function FEBasis(fespace::FESpace)
2326
FEBasis(b,trian)
2427
end
2528

26-
for op in (:+, :-, :(gradient),:(symmetric_gradient))
29+
for op in (:+,:-,:(gradient),:(symmetric_gradient),:(div),:(trace),:(curl))
2730
@eval begin
2831
function ($op)(a::FEBasis)
2932
FEBasis($op(a.cellbasis),a.trian)

src/FESpaces/FEFunctions.jl

+11-10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import Gridap: value_type
1212

1313
import Gridap: evaluate, gradient, return_size
1414
import Gridap: symmetric_gradient
15+
import Base: div
16+
import Gridap: trace
17+
import Gridap: curl
1518
import Gridap: reindex
1619
import Gridap: restrict
1720
import Gridap: Triangulation
@@ -85,16 +88,14 @@ end
8588

8689
evaluate(f::FEFunction{D,Z},q::CellPoints{Z}) where {D,Z} = evaluate(f.cellfield,q)
8790

88-
function gradient(f::FEFunction)
89-
g = gradient(f.cellfield)
90-
trian = Triangulation(f)
91-
_attach_triangulation(g,trian)
92-
end
93-
94-
function symmetric_gradient(f::FEFunction)
95-
g = symmetric_gradient(f.cellfield)
96-
trian = Triangulation(f)
97-
_attach_triangulation(g,trian)
91+
for op in (:+,:-,:(gradient),:(symmetric_gradient),:(div),:(trace),:(curl))
92+
@eval begin
93+
function ($op)(a::FEFunction)
94+
g = $op(a.cellfield)
95+
trian = Triangulation(a)
96+
_attach_triangulation(g,trian)
97+
end
98+
end
9899
end
99100

100101
for op in (:+, :-, :*)

src/Fields/CellFieldsOperations.jl

+28
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ export lincomb
1717
export attachgeomap
1818
export compose
1919
export symmetric_gradient
20+
export curl
2021
export ε
22+
import Base: div
23+
import Gridap: trace
2124
import Gridap: evaluate
2225
import Gridap: gradient
2326
import Gridap: reindex
@@ -72,6 +75,31 @@ end
7275

7376
const ε = symmetric_gradient
7477

78+
function trace(f::CellFieldLike{D,T}) where {D,T<:TensorValue}
79+
apply(trace,f,broadcast=true)
80+
end
81+
82+
function div(f::CellFieldLike{D,T}) where {D,T<:VectorValue}
83+
g = gradient(f)
84+
trace(g)
85+
end
86+
87+
function curl(f::CellFieldLike{D,T}) where {D,T<:VectorValue}
88+
g = gradient(f)
89+
apply(_curl_kernel,g,broadcast=true)
90+
end
91+
92+
function _curl_kernel(∇u::TensorValue{2})
93+
∇u[1,2] - ∇u[2,1]
94+
end
95+
96+
function _curl_kernel(∇u::TensorValue{3})
97+
c1 = ∇u[2,3] - ∇u[3,2]
98+
c2 = ∇u[3,1] - ∇u[1,3]
99+
c3 = ∇u[1,2] - ∇u[2,1]
100+
VectorValue(c1,c2,c3)
101+
end
102+
75103
function _compose(::Val{true},f,u...)
76104
fgrad = gradient(f)
77105
v = apply(f,u...,broadcast=true)

src/Integration/Triangulations.jl

+11-8
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ import Gridap: CellGeomap
1818
import Gridap: CellField
1919
import Gridap: evaluate, gradient, return_size
2020
import Gridap: symmetric_gradient
21+
import Base: div
22+
import Gridap: trace
23+
import Gridap: curl
2124
import Gridap: reindex
2225
import Base: IndexStyle
2326
import Base: size
2427
import Base: getindex
28+
import Base: +, -, *
2529

2630
"""
2731
Minimal interface for a mesh used for numerical integration
@@ -275,14 +279,13 @@ function evaluate(f::IndexCellFieldWithTriangulation{Z},q::CellPoints{Z}) where
275279
evaluate(f.cellfield,q)
276280
end
277281

278-
function gradient(f::IndexCellFieldWithTriangulation)
279-
g = gradient(f.cellfield)
280-
IndexCellFieldWithTriangulation(g,f.trian)
281-
end
282-
283-
function symmetric_gradient(f::IndexCellFieldWithTriangulation)
284-
g = symmetric_gradient(f.cellfield)
285-
IndexCellFieldWithTriangulation(g,f.trian)
282+
for op in (:+,:-,:(gradient),:(symmetric_gradient),:(div),:(trace),:(curl))
283+
@eval begin
284+
function ($op)(a::IndexCellFieldWithTriangulation)
285+
g = $op(a.cellfield)
286+
IndexCellFieldWithTriangulation(g,a.trian)
287+
end
288+
end
286289
end
287290

288291
return_size(f::IndexCellFieldWithTriangulation,s::Tuple{Int}) = return_size(f.cellfield,s)

src/MultiField/MultiFEBases.jl

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ using Gridap
44
using Gridap.Helpers
55

66
import Gridap: gradient
7+
import Gridap: symmetric_gradient
8+
import Base: div
9+
import Gridap: trace
10+
import Gridap: curl
711
import Gridap: inner
812
import Base: +, -, *
913
import Base: length, getindex
@@ -29,7 +33,7 @@ function CellBasis(
2933
FEBasisWithFieldId(febasis,b.fieldid)
3034
end
3135

32-
for op in (:+, :-, :(gradient))
36+
for op in (:+,:-,:(gradient),:(symmetric_gradient),:(div),:(trace),:(curl))
3337
@eval begin
3438
function ($op)(a::FEBasisWithFieldId)
3539
FEBasisWithFieldId($op(a.febasis),a.fieldid)

test/FESpacesTests/FEBasesTests.jl

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ ufun(x) = VectorValue(x[2],x[1])
6060
uh = interpolate(fespace,ufun)
6161
bh = FEBasis(fespace)
6262
@test isa(ε(bh),FEBasis)
63+
@test isa(div(bh),FEBasis)
64+
@test isa(curl(bh),FEBasis)
6365
@test isa(inner(ε(bh),ε(bh)),CellMap{Point{2},1,Float64,3})
6466
@test isa(inner(ε(bh),ε(uh)),CellMap{Point{2},1,Float64,2})
6567

test/FESpacesTests/FEFunctionsTests.jl

+10
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,14 @@ u = CellField(trian,ufun)
5151
e = u - uh
5252
@test isa(e,IndexCellFieldWithTriangulation)
5353

54+
T = VectorValue{2,Float64}
55+
fespace = ConformingFESpace(T,model,order,diritag)
56+
ufun(x) = VectorValue(x[2],x[1])
57+
uh = interpolate(fespace,ufun)
58+
59+
@test isa(div(uh),IndexCellFieldWithTriangulation)
60+
@test isa(curl(uh),IndexCellFieldWithTriangulation)
61+
62+
63+
5464
end # module

test/FieldsTests/CellFieldsOperationsTests.jl

+18
Original file line numberDiff line numberDiff line change
@@ -189,5 +189,23 @@ test_iter_cell_field_without_grad(sg,cp,r)
189189

190190
@test ε == symmetric_gradient
191191

192+
gr = (cf)
193+
sg = trace(gr)
194+
195+
ri = fill(6.0,4)
196+
r = fill(ri,l)
197+
198+
test_iter_cell_field_without_grad(sg,cp,r)
199+
200+
sg = div(cf)
201+
202+
test_iter_cell_field_without_grad(sg,cp,r)
203+
204+
sg = curl(cf)
205+
206+
ri = fill(0.0,4)
207+
r = fill(ri,l)
208+
test_iter_cell_field_without_grad(sg,cp,r)
209+
192210
end # module
193211

test/MultiFieldTests/MultiFEBasesTests.jl

+18
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module MultiFEBasesTests
22

33
using Test
44
using Gridap
5+
using Gridap.MultiFEBases: FEBasisWithFieldId
56

67
import Gridap:
78

@@ -78,4 +79,21 @@ mca = integrate(mcm,trian,quad)
7879

7980
@test isa(mca,MultiCellArray{Float64,1})
8081

82+
T = VectorValue{2,Float64}
83+
order = 1
84+
diritag = "boundary"
85+
fespace = ConformingFESpace(T,model,order,diritag)
86+
87+
V1 = TestFESpace(fespace)
88+
V2 = V1
89+
90+
V = MultiFESpace([V1,V2])
91+
92+
bh = FEBasis(V)
93+
94+
@test isa((bh[1]),FEBasisWithFieldId)
95+
@test isa(ε(bh[1]),FEBasisWithFieldId)
96+
@test isa(div(bh[1]),FEBasisWithFieldId)
97+
@test isa(curl(bh[1]),FEBasisWithFieldId)
98+
8199
end # module MultiFEBasesTests

0 commit comments

Comments
 (0)