comparison RegionIndices/src/RegionIndices.jl @ 225:3ab0c61f1367 boundary_conditions

Merge in package_refactor
author Jonatan Werpers <jonatan@werpers.com>
date Wed, 26 Jun 2019 14:02:28 +0200
parents b3506cfbb9d8
children 6bce42abf43d
comparison
equal deleted inserted replaced
210:2aa33d0eef90 225:3ab0c61f1367
1 module RegionIndices
2
3 abstract type Region end
4 struct Interior <: Region end
5 struct Lower <: Region end
6 struct Upper <: Region end
7 struct Unknown <: Region end
8
9 export Region, Interior, Lower, Upper, Unknown
10
11 struct Index{R<:Region, T<:Integer}
12 i::T
13
14 Index{R,T}(i::T) where {R<:Region,T<:Integer} = new{R,T}(i)
15 Index{R}(i::T) where {R<:Region,T<:Integer} = new{R,T}(i)
16 Index(i::T, ::Type{R}) where {R<:Region,T<:Integer} = Index{R,T}(i)
17 Index(t::Tuple{T, DataType}) where {R<:Region,T<:Integer} = Index{t[2],T}(t[1]) # TBD: This is not very specific in what types are allowed in t[2]. Can this be fixed?
18 end
19
20 export Index
21
22 # Index(R::Type{<:Region}) = Index{R}
23
24 ## Vill kunna skriva
25 ## IndexTupleType(Int, (Lower, Interior))
26 Index(R::Type{<:Region}, T::Type{<:Integer}) = Index{R,T}
27 IndexTupleType(T::Type{<:Integer},R::NTuple{N, DataType} where N) = Tuple{Index.(R, T)...}
28
29 Base.convert(::Type{T}, i::Index{R,T} where R) where T = i.i
30 Base.convert(::Type{CartesianIndex}, I::NTuple{N,Index} where N) = CartesianIndex(convert.(Int, I))
31
32 Base.Int(I::Index) = I.i
33
34 function Index(i::Integer, boundary_width::Integer, dim_size::Integer)
35 return Index{getregion(i,boundary_width,dim_size)}(i)
36 end
37
38 IndexTuple(t::Vararg{Tuple{T, DataType}}) where T<:Integer = Index.(t)
39 export IndexTuple
40
41 # TODO: Use the values of the region structs, e.g. Lower(), for the region parameter instead of the types.
42 # For example the following works:
43 # (Lower(),Upper()) isa NTuple{2, Region} -> true
44 # typeof((Lower(),Upper())) -> Tuple{Lower,Upper}
45 function regionindices(gridsize::NTuple{Dim,Integer}, closuresize::Integer, region::NTuple{Dim,DataType}) where Dim
46 return regionindices(gridsize, ntuple(x->closuresize,Dim), region)
47 end
48
49 function regionindices(gridsize::NTuple{Dim,Integer}, closuresize::NTuple{Dim,Integer}, region::NTuple{Dim,DataType}) where Dim
50 regions = map(getrange,gridsize,closuresize,region)
51 return CartesianIndices(regions)
52 end
53
54 export regionindices
55
56 function getregion(i::Integer, boundary_width::Integer, dim_size::Integer)
57 if 0 < i <= boundary_width
58 return Lower
59 elseif boundary_width < i <= dim_size-boundary_width
60 return Interior
61 elseif dim_size-boundary_width < i <= dim_size
62 return Upper
63 else
64 error("Bounds error") # TODO: Make this more standard
65 end
66 end
67
68 function getrange(gridsize::Integer, closuresize::Integer, region::DataType)
69 if region == Lower
70 r = 1:closuresize
71 elseif region == Interior
72 r = (closuresize+1):(gridsize - closuresize)
73 elseif region == Upper
74 r = (gridsize - closuresize + 1):gridsize
75 else
76 error("Unspecified region")
77 end
78 return r
79 end
80
81 end # module