|
3 | 3 | # - Interpolate finite element functions defined on different |
4 | 4 | # triangulations. We will consider examples for |
5 | 5 | # - Lagrangian finite element spaces |
6 | | -# - Vector-Valued Spaces |
7 | 6 | # - Raviart Thomas finite element spaces |
| 7 | +# - Vector-Valued Spaces |
8 | 8 | # - Multifield finite element spaces |
9 | 9 |
|
10 | 10 | # ## Problem Statement |
@@ -78,22 +78,13 @@ fₕ(pt), fₕ.(pts) |
78 | 78 | @test fₕ.(pts) ≈ f.(pts) |
79 | 79 |
|
80 | 80 | # 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 |
91 | 82 | # direction. The map can be passed as an argument to |
92 | 83 | # `CartesianDiscreteModel` to define the position of the vertices in |
93 | 84 | # the new mesh. |
94 | 85 |
|
95 | 86 | partition = (20,20) |
96 | | -𝒯₂ = CartesianDiscreteModel(domain,partition; map=sinusoidal) |
| 87 | +𝒯₂ = CartesianDiscreteModel(domain,partition) |
97 | 88 |
|
98 | 89 | # As before, we define the new `FESpace` consisting of second order |
99 | 90 | # elements |
@@ -187,7 +178,86 @@ gₕ = interpolate_everywhere(ifₕ, V₂) |
187 | 178 |
|
188 | 179 | # Like earlier we can check our results |
189 | 180 |
|
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) |
191 | 261 |
|
192 | 262 | # ## Acknowledgements |
193 | 263 |
|
|
0 commit comments