Skip to content

Commit 7f79a06

Browse files
committed
Add multifield tutorial for interpolation
1 parent 88126e2 commit 7f79a06

2 files changed

Lines changed: 84 additions & 14 deletions

File tree

deps/build.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ files = [
1919
"Electromagnetic scattering in 2D"=>"emscatter.jl",
2020
"Low-level API Poisson equation"=>"poisson_dev_fe.jl",
2121
"On using DrWatson.jl"=>"validation_DrWatson.jl",
22-
"Interpolation"=>"interpolation_fe.jl"]
22+
"Interpolation of CellFields"=>"interpolation_fe.jl"]
2323

2424
Sys.rm(notebooks_dir;recursive=true,force=true)
2525
for (i,(title,filename)) in enumerate(files)

src/interpolation_fe.jl

Lines changed: 83 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
# - Interpolate finite element functions defined on different
44
# triangulations. We will consider examples for
55
# - Lagrangian finite element spaces
6-
# - Vector-Valued Spaces
76
# - Raviart Thomas finite element spaces
7+
# - Vector-Valued Spaces
88
# - Multifield finite element spaces
99

1010
# ## Problem Statement
@@ -78,22 +78,13 @@ fₕ(pt), fₕ.(pts)
7878
@test fₕ.(pts) f.(pts)
7979

8080
# Now let us define the new triangulation $\mathcal{T}_2$ of
81-
# $\Omega$. We define the map
82-
83-
function sinusoidal(p::Point)
84-
r, s = p
85-
x = r + 0.05*sin(2π*r)*sin(2π*s)
86-
y = s + 0.05*sin(2π*r)*sin(2π*s)
87-
Point(x,y)
88-
end
89-
90-
# to build the new triangulation using a partition of 20 cells per
81+
# $\Omega$. We build the new triangulation using a partition of 20 cells per
9182
# direction. The map can be passed as an argument to
9283
# `CartesianDiscreteModel` to define the position of the vertices in
9384
# the new mesh.
9485

9586
partition = (20,20)
96-
𝒯₂ = CartesianDiscreteModel(domain,partition; map=sinusoidal)
87+
𝒯₂ = CartesianDiscreteModel(domain,partition)
9788

9889
# As before, we define the new `FESpace` consisting of second order
9990
# elements
@@ -187,7 +178,86 @@ gₕ = interpolate_everywhere(ifₕ, V₂)
187178

188179
# Like earlier we can check our results
189180

190-
gₕ(pt), f(pt)
181+
@test gₕ(pt) f(pt) fₕ(pt)
182+
183+
# ## Interpolating vector-valued functions
184+
185+
# We can also interpolate vector-valued functions across
186+
# triangulations. First, we define a vector-valued function on a
187+
# two-dimensional mesh.
188+
189+
f(x) = VectorValue([x[1], x[1]+x[2]])
190+
191+
# We then create a vector-valued reference element containing linear
192+
# elements along with the source finite element space $V_1$.
193+
194+
reffe₁ = ReferenceFE(lagrangian, VectorValue{2,Float64}, 1)
195+
V₁ = FESpace(𝒯₁, reffe₁)
196+
fₕ = interpolate_everywhere(f, V₁)
197+
198+
# The target finite element space $V_2$ can be defined in a similar manner.
199+
200+
reffe₂ = ReferenceFE(lagrangian, VectorValue{2,Float64}, 2)
201+
V₂ = FESpace(𝒯₂, reffe₂)
202+
203+
# The rest of the process is similar to the previous sections, i.e.,
204+
# define the `Interpolable` version of $f_h$ and use
205+
# `interpolate_everywhere` to find $g_h \in V₂$.
206+
207+
if= Interpolable(fₕ)
208+
gₕ = interpolate_everywhere(ifₕ, V₂)
209+
210+
# We can then check the results
211+
212+
@test gₕ(pt) f(pt) fₕ(pt)
213+
214+
215+
# ## Interpolating Multi-field Functions
216+
217+
# Similarly, it is possible to interpolate between multi-field finite element
218+
# functions. First, we define the components $h_1(x), h_2(x)$ of a
219+
# multi-field function $h(x)$ as follows.
220+
221+
h₁(x) = x[1]+x[2]
222+
h₂(x) = x[1]
223+
224+
# Next we create a Lagrangian finite element space containing linear
225+
# elements.
226+
227+
reffe₁ = ReferenceFE(lagrangian, Float64, 1)
228+
V₁ = FESpace(𝒯₁, reffe₁)
229+
230+
# Next we create a `MultiFieldFESpace` $V_1 \times V_1$ and
231+
# interpolate the function $h(x)$ to the source space $V_1$.
232+
233+
V₁xV₁ = MultiFieldFESpace([V₁,V₁])
234+
fₕ = interpolate_everywhere([h₁, h₂], V₁xV₁)
235+
236+
# Similarly, the target multi-field finite element space is created
237+
# using $\Omega_2$.
238+
239+
reffe₂ = ReferenceFE(lagrangian, Float64, 2)
240+
V₂ = FESpace(𝒯₂, reffe₂)
241+
V₂xV₂ = MultiFieldFESpace([V₂,V₂])
242+
243+
# Now, to find $g_h \in V_2 \times V_2$, we first extract the components of
244+
# $f_h$ and obtain the `Interpolable` version of the components.
245+
246+
fₕ¹, fₕ² = fₕ
247+
ifₕ¹ = Interpolable(fₕ¹)
248+
ifₕ² = Interpolable(fₕ²)
249+
250+
# We can then use `interpolate_everywhere` on the `Interpolable`
251+
# version of the components and obtain $g_h \in V_2 \times V_2$ as
252+
# follows.
253+
254+
gₕ = interpolate_everywhere([ifₕ¹,ifₕ²], V₂xV₂)
255+
256+
# We can then check the results of the interpolation, component-wise.
257+
258+
gₕ¹, gₕ² = gₕ
259+
@test fₕ¹(pt) gₕ¹(pt)
260+
@test fₕ²(pt) gₕ²(pt)
191261

192262
# ## Acknowledgements
193263

0 commit comments

Comments
 (0)