Skip to content

Commit

Permalink
Merge branch 'master' of github.com:gridap/Gridap.jl into optimizing_…
Browse files Browse the repository at this point in the history
…conforming_rt_fes
  • Loading branch information
amartinhuertas committed Aug 14, 2021
2 parents f263ff8 + 5bb96bd commit 2a3874f
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/CellData/CellData.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export ∫
export CellDof
export get_normal_vector
export get_cell_measure
export Interpolable

export make_inverse_table
export compute_cell_points_from_vector_of_points
Expand Down
1 change: 0 additions & 1 deletion src/CellData/CellDofs.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

"""
"""
struct CellDof{DS} <: CellDatum
Expand Down
22 changes: 19 additions & 3 deletions src/CellData/CellFields.jl
Original file line number Diff line number Diff line change
Expand Up @@ -262,17 +262,18 @@ function _point_to_cell_cache(trian::Triangulation)
ctype_to_reffe = get_reffes(trian)
ctype_to_polytope = map(get_polytope, ctype_to_reffe)
cell_map = get_cell_map(trian)
cache1 = kdtree, vertex_to_cells, cell_to_ctype, ctype_to_polytope, cell_map
table_cache = array_cache(vertex_to_cells)
cache1 = kdtree, vertex_to_cells, cell_to_ctype, ctype_to_polytope, cell_map, table_cache
end

function _point_to_cell!(cache, x::Point)
kdtree, vertex_to_cells, cell_to_ctype, ctype_to_polytope, cell_map = cache
kdtree, vertex_to_cells, cell_to_ctype, ctype_to_polytope, cell_map, table_cache = cache

# Find nearest vertex
id,dist = nn(kdtree, SVector(Tuple(x)))

# Find all neighbouring cells
cells = vertex_to_cells[id]
cells = getindex!(table_cache,vertex_to_cells,id)
@assert !isempty(cells)

# Calculate the distance from the point to all the cells. Without
Expand Down Expand Up @@ -846,3 +847,18 @@ function (a::SkeletonPair{<:CellField})(x)
Evaluating `n(x)` is not allowed. You need to call either `n.⁺(x)` or `n.⁻(x)`.
"""
end

# Interpolable struct
struct KDTreeSearch end

struct Interpolable{M,A} <: Function
uh::A
tol::Float64
searchmethod::M
function Interpolable(uh; tol=1e-6, searchmethod=KDTreeSearch())
new{typeof(searchmethod),typeof(uh)}(uh, tol,searchmethod)
end
end

return_cache(a::Interpolable,x::Point) = return_cache(a.uh,x)
evaluate!(cache,a::Interpolable,x::Point) = evaluate!(cache,a.uh,x)
2 changes: 1 addition & 1 deletion src/FESpaces/SingleFieldFESpaces.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

"""
"""
abstract type SingleFieldFESpace <: FESpace end
Expand Down Expand Up @@ -300,6 +299,7 @@ function interpolate!(object, free_values,fs::SingleFieldFESpace)
FEFunction(fs,free_values)
end


function _cell_vals(fs::SingleFieldFESpace,object)
s = get_fe_dof_basis(fs)
trian = get_triangulation(s)
Expand Down
3 changes: 1 addition & 2 deletions src/Fields/InverseFields.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

# Inverse fields

struct InverseField{F} <: Field
Expand Down Expand Up @@ -27,7 +26,7 @@ function evaluate!(caches,a::InverseField,x::Point)
j!(J,y) = J .= SMatrix{D,D}(Tuple(evaluate!(∇cache,(a.original),P(y))))
df = OnceDifferentiable(f!,j!,y₀,F₀)
# Solve
res = nlsolve(df,y₀)
res = nlsolve(df,y₀,method=:newton,linesearch=BackTracking())
@check converged(res) "InverseField evaluation did not converge"
# Extract solution
y = res.zero
Expand Down
1 change: 0 additions & 1 deletion src/MultiField/MultiFieldFESpaces.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

function _can_be_restricted_to(trian_i,trian)
if have_compatible_domains(trian_i,trian) ||
have_compatible_domains(trian_i,get_background_triangulation(trian)) ||
Expand Down
6 changes: 3 additions & 3 deletions src/ReferenceFEs/LagrangianDofBases.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

struct PointValue{P} <: Dof
point::P
end
Expand Down Expand Up @@ -114,18 +113,19 @@ end
T = eltype(vals)
ncomps = num_components(T)
@check ncomps == num_components(eltype(b.node_and_comp_to_dof)) """\n
Unable to evaluate LagrangianDofBasis. The number of components of the
Unable to evaluate LagrangianDofBasis. The number of components of the
given Field does not match with the LagrangianDofBasis.
If you are trying to interpolate a function on a FESpace make sure that
both objects have the same value type.
For instance, trying to interpolate a vector-valued funciton on a scalar-valued FE space
would raise this error.
"""
_evaluate_lagr_dof!(c,vals,b.node_and_comp_to_dof,ndofs,ncomps)
end


function _evaluate_lagr_dof!(c::AbstractVector,node_comp_to_val,node_and_comp_to_dof,ndofs,ncomps)
setsize!(c,(ndofs,))
r = c.array
Expand Down
64 changes: 64 additions & 0 deletions test/CellDataTests/CellFieldsTests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,70 @@ Random.seed!(0)
end
end

p = QUAD
D = num_dims(QUAD)
et = Float64
source_model = CartesianDiscreteModel((0,1,0,1),(2,2))

@testset "Test interpolation Lagrangian" begin
# Lagrangian space -> Lagrangian space
f(x) = x[1] + x[2]
reffe = LagrangianRefFE(et, p, 1)
V₁ = FESpace(source_model, reffe, conformity=:H1)
fh = interpolate_everywhere(f, V₁)
# Target Lagrangian Space
reffe = LagrangianRefFE(et, p, 2)
model = CartesianDiscreteModel((0,1,0,1),(4,4))
V₂ = FESpace(model, reffe, conformity=:H1)

ifh = Interpolable(fh)
try
interpolate_everywhere(fh, V₂)
catch
gh = interpolate_everywhere(ifh, V₂)
pts = [VectorValue(rand(2)) for i=1:10]
for pt in pts
@test gh(pt) fh(pt)
end
end

# VectorValued Lagrangian
fᵥ(x) = VectorValue([x[1], x[1]+x[2]])
reffe = ReferenceFE(lagrangian, VectorValue{2,et}, 1)
V₁ = FESpace(source_model, reffe, conformity=:H1)
fh = interpolate_everywhere(fᵥ, V₁)
# Target
reffe = ReferenceFE(lagrangian, VectorValue{2,et}, 2)
V₂ = FESpace(model, reffe, conformity=:H1)

ifh = Interpolable(fh);
gh = interpolate_everywhere(ifh, V₂)
pts = [VectorValue(rand(2)) for i=1:10]
for pt in pts
@test gh(pt) fh(pt)
end
end

@testset "Test interpolation RT" begin
# RT Space -> RT Space
f(x) = VectorValue([x[1], x[2]])
reffe = RaviartThomasRefFE(et, p, 0)
V₁ = FESpace(source_model, reffe, conformity=:HDiv)
fh = interpolate_everywhere(f, V₁);
# Target RT Space
reffe = RaviartThomasRefFE(et, p, 1)
model = CartesianDiscreteModel((0,1,0,1),(40,40))
V₂ = FESpace(model, reffe, conformity=:HDiv)

ifh = Interpolable(fh)
gh = interpolate_everywhere(ifh, V₂)
pts = [VectorValue(rand(2)) for i=1:10]
for pt in pts
@test gh(pt) fh(pt)
end
end


#np = 3
#ndofs = 4
#
Expand Down
35 changes: 35 additions & 0 deletions test/MultiFieldTests/MultiFieldCellFieldsTests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,40 @@ test_array(cellmat1_Γ,cellmat2_Γ,≈)
#cache = array_cache(a)
#@btime getindex!($cache,$a,2)

# --- Some tests to check the Interpolation module
p = QUAD
D = num_dims(QUAD)
et = Float64
source_model = CartesianDiscreteModel((0,1,0,1),(10,10))

@testset "Test interpolation Multifield" begin
f₁(x) = x[1]+x[2]
f₂(x) = x[1]
# Source FESpace
reffe = LagrangianRefFE(et, p, 1)
V₁ = FESpace(source_model, reffe, conformity=:H1)
V₁² = MultiFieldFESpace([V₁,V₁])
fh = interpolate_everywhere([f₁, f₂], V₁²)

# Target Lagrangian FESpace
reffe = LagrangianRefFE(et, p, 2)
model = CartesianDiscreteModel((0,1,0,1), (40,40))
V₂ = FESpace(model, reffe, conformity=:H1)
V₂² = MultiFieldFESpace([V₂,V₂])

fh₁,fh₂ = fh
ifh₁ = Interpolable(fh₁)
ifh₂ = Interpolable(fh₂)

gh = interpolate_everywhere([ifh₁,ifh₂], V₂²)

pts = [VectorValue(rand(2)) for i=1:10]
gh₁,gh₂ = gh
for pt in pts
@test gh₁(pt) fh₁(pt)
@test gh₂(pt) fh₂(pt)
end
end


end # module

0 comments on commit 2a3874f

Please sign in to comment.