Mercurial > repos > public > sbplib_julia
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 |