diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e440e99..8ce9513a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +# [1.17.0] - 2026-04-15 +- new kwargs `not_in_domain_value = nothing` and `check_if_not_in_domain = isnothing(not_in_domain_value)` for grid interpolation. + This enables the user to interpolate values between grids which do not share the same domain. The value _outside_ the target domain has to be provided by the user. + ## [1.15.0] - 2026-01-14 - add and export `explode` function that produces a grid with all adjacencies removed diff --git a/Project.toml b/Project.toml index dcb083f3..cdaf7d8a 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ExtendableGrids" uuid = "cfc395e8-590f-11e8-1f13-43a2532b2fa8" authors = ["Juergen Fuhrmann ", "Christian Merdon ", "Johannes Taraz ", "Patrick Jaap "] -version = "1.16.0" +version = "1.17.0" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/src/cellfinder.jl b/src/cellfinder.jl index 0a2d7232..7ec8ac37 100644 --- a/src/cellfinder.jl +++ b/src/cellfinder.jl @@ -95,7 +95,7 @@ Upon return, xref contains the barycentric coordinates of the point in the seque !!! warning Currently implemented for simplex grids only. """ -function gFindLocal!(xref, CF::CellFinder{Tv, Ti}, x; icellstart = 1, trybrute = true, eps = 1.0e-14) where {Tv, Ti} +function gFindLocal!(xref, CF::CellFinder{Tv, Ti}, x; icellstart = 1, stay_in_cell = false, trybrute = true, eps = 1.0e-14) where {Tv, Ti} # works for convex domains and simplices only ! xCellFaces::Adjacency{Ti} = CF.xCellFaces xFaceCells::Adjacency{Ti} = CF.xFaceCells @@ -131,6 +131,11 @@ function gFindLocal!(xref, CF::CellFinder{Tv, Ti}, x; icellstart = 1, trybrute = cx[j] = x[j] - L2Gb[j] end mapderiv!(invA, L2G, xref) + + if stay_in_cell + return icell + end + fill!(xreftest, 0) for j in 1:length(cx), k in 1:length(cx) xreftest[k] += invA[j, k] * cx[j] @@ -258,7 +263,7 @@ end Mutating form of [`interpolate`](@ref) """ -function interpolate!(u_to::AbstractArray, grid_to, u_from::AbstractArray, grid_from; eps = 1.0e-14, trybrute = true) +function interpolate!(u_to::AbstractArray, grid_to, u_from::AbstractArray, grid_from; eps = 1.0e-14, not_in_domain_value = nothing, check_if_not_in_domain = isnothing(not_in_domain_value), trybrute = true) shuffle = [[2, 1], [3, 1, 2], [4, 1, 2, 3]] update!(u_to::AbstractVector, inode_to, λ, u_from::AbstractVector, inode_from) = u_to[inode_to] += λ * u_from[inode_from] @@ -286,10 +291,14 @@ function interpolate!(u_to::AbstractArray, grid_to, u_from::AbstractArray, grid_ icellstart = 1 for inode_to in 1:nnodes_to @views icell_from = gFindLocal!(λ, cf, coord[:, inode_to]; icellstart, eps, trybrute) - @assert icell_from > 0 - for i in 1:(dim + 1) - inode_from = cn_from[i, icell_from] - update!(u_to, inode_to, λ_shuffle[i], u_from, inode_from) + if icell_from <= 0 && !check_if_not_in_domain + u_to[inode_to] = not_in_domain_value + else + @assert icell_from > 0 "could not find cell for node $inode_to with coordinate $(coord[:, inode_to])" + for i in 1:(dim + 1) + inode_from = cn_from[i, icell_from] + update!(u_to, inode_to, λ_shuffle[i], u_from, inode_from) + end end icell_start = icell_from end