Mercurial > repos > public > sbplib_julia
comparison SbpOperators/src/SbpOperators.jl @ 219:69a6049e14d9 package_refactor
Create package SbpOperators
author | Jonatan Werpers <jonatan@werpers.com> |
---|---|
date | Wed, 26 Jun 2019 13:12:38 +0200 |
parents | sbpD2.jl@6ba2238a9687 |
children | 235f0a771c8f |
comparison
equal
deleted
inserted
replaced
218:03375aa30edd | 219:69a6049e14d9 |
---|---|
1 module SbpOperators | |
2 | |
3 using RegionIndices | |
4 | |
5 include("stencil.jl") | |
6 | |
7 abstract type ConstantStencilOperator end | |
8 | |
9 # Apply for different regions Lower/Interior/Upper or Unknown region | |
10 @inline function apply(op::ConstantStencilOperator, h::Real, v::AbstractVector, i::Index{Lower}) | |
11 return @inbounds h*h*apply(op.closureStencils[Int(i)], v, Int(i)) | |
12 end | |
13 | |
14 @inline function apply(op::ConstantStencilOperator, h::Real, v::AbstractVector, i::Index{Interior}) | |
15 return @inbounds h*h*apply(op.innerStencil, v, Int(i)) | |
16 end | |
17 | |
18 @inline function apply(op::ConstantStencilOperator, h::Real, v::AbstractVector, i::Index{Upper}) | |
19 N = length(v) | |
20 return @inbounds h*h*Int(op.parity)*apply_backwards(op.closureStencils[N-Int(i)+1], v, Int(i)) | |
21 end | |
22 | |
23 @inline function apply(op::ConstantStencilOperator, h::Real, v::AbstractVector, index::Index{Unknown}) | |
24 cSize = closureSize(op) | |
25 N = length(v) | |
26 | |
27 i = Int(index) | |
28 | |
29 if 0 < i <= cSize | |
30 return apply(op, h, v, Index{Lower}(i)) | |
31 elseif cSize < i <= N-cSize | |
32 return apply(op, h, v, Index{Interior}(i)) | |
33 elseif N-cSize < i <= N | |
34 return apply(op, h, v, Index{Upper}(i)) | |
35 else | |
36 error("Bounds error") # TODO: Make this more standard | |
37 end | |
38 end | |
39 | |
40 | |
41 # Wrapper functions for using regular indecies without specifying regions | |
42 @inline function apply(op::ConstantStencilOperator, h::Real, v::AbstractVector, i::Int) | |
43 return apply(op, h, v, Index{Unknown}(i)) | |
44 end | |
45 | |
46 @enum Parity begin | |
47 odd = -1 | |
48 even = 1 | |
49 end | |
50 | |
51 struct D2{T,N,M,K} <: ConstantStencilOperator | |
52 quadratureClosure::NTuple{M,T} | |
53 innerStencil::Stencil{T,N} | |
54 closureStencils::NTuple{M,Stencil{T,K}} | |
55 eClosure::Stencil{T,M} | |
56 dClosure::Stencil{T,M} | |
57 parity::Parity | |
58 end | |
59 | |
60 function closureSize(D::D2)::Int | |
61 return length(D.quadratureClosure) | |
62 end | |
63 | |
64 function readOperator(D2fn, Hfn) | |
65 d = readSectionedFile(D2fn) | |
66 h = readSectionedFile(Hfn) | |
67 | |
68 # Create inner stencil | |
69 innerStencilWeights = stringToTuple(Float64, d["inner_stencil"][1]) | |
70 width = length(innerStencilWeights) | |
71 r = (-div(width,2), div(width,2)) | |
72 | |
73 innerStencil = Stencil(r, innerStencilWeights) | |
74 | |
75 # Create boundary stencils | |
76 boundarySize = length(d["boundary_stencils"]) | |
77 closureStencils = Vector{typeof(innerStencil)}() # TBD: is the the right way to get the correct type? | |
78 | |
79 for i ∈ 1:boundarySize | |
80 stencilWeights = stringToTuple(Float64, d["boundary_stencils"][i]) | |
81 width = length(stencilWeights) | |
82 r = (1-i,width-i) | |
83 closureStencils = (closureStencils..., Stencil(r, stencilWeights)) | |
84 end | |
85 | |
86 quadratureClosure = pad_tuple(stringToTuple(Float64, h["closure"][1]), boundarySize) | |
87 eClosure = Stencil((0,boundarySize-1), pad_tuple(stringToTuple(Float64, d["e"][1]), boundarySize)) | |
88 dClosure = Stencil((0,boundarySize-1), pad_tuple(stringToTuple(Float64, d["d1"][1]), boundarySize)) | |
89 | |
90 d2 = D2( | |
91 quadratureClosure, | |
92 innerStencil, | |
93 closureStencils, | |
94 eClosure, | |
95 dClosure, | |
96 even | |
97 ) | |
98 | |
99 return d2 | |
100 end | |
101 | |
102 | |
103 function apply_e(op::D2, v::AbstractVector, ::Type{Lower}) | |
104 apply(op.eClosure,v,1) | |
105 end | |
106 | |
107 function apply_e(op::D2, v::AbstractVector, ::Type{Upper}) | |
108 apply(flip(op.eClosure),v,length(v)) | |
109 end | |
110 | |
111 | |
112 function apply_d(op::D2, h_inv::Real, v::AbstractVector, ::Type{Lower}) | |
113 -h_inv*apply(op.dClosure,v,1) | |
114 end | |
115 | |
116 function apply_d(op::D2, h_inv::Real, v::AbstractVector, ::Type{Upper}) | |
117 -h_inv*apply(flip(op.dClosure),v,length(v)) | |
118 end | |
119 | |
120 function readSectionedFile(filename)::Dict{String, Vector{String}} | |
121 f = open(filename) | |
122 sections = Dict{String, Vector{String}}() | |
123 currentKey = "" | |
124 | |
125 for ln ∈ eachline(f) | |
126 if ln == "" || ln[1] == '#' # Skip comments and empty lines | |
127 continue | |
128 end | |
129 | |
130 if isletter(ln[1]) # Found start of new section | |
131 if ~haskey(sections, ln) | |
132 sections[ln] = Vector{String}() | |
133 end | |
134 currentKey = ln | |
135 continue | |
136 end | |
137 | |
138 push!(sections[currentKey], ln) | |
139 end | |
140 | |
141 return sections | |
142 end | |
143 | |
144 function stringToTuple(T::DataType, s::String) | |
145 return Tuple(stringToVector(T,s)) | |
146 end | |
147 | |
148 function stringToVector(T::DataType, s::String) | |
149 return T.(eval.(Meta.parse.(split(s)))) | |
150 end | |
151 | |
152 | |
153 function pad_tuple(t::NTuple{N, T}, n::Integer) where {N,T} | |
154 if N >= n | |
155 return t | |
156 else | |
157 return pad_tuple((t..., zero(T)), n) | |
158 end | |
159 end | |
160 | |
161 end # module |