comparison src/BoundaryConditions/boundary_condition.jl @ 1396:35840a0681d1 feature/boundary_conditions

Start drafting new implemenentation of boundary conditions
author Vidar Stiernström <vidar.stiernstrom@it.uu.se>
date Wed, 26 Jul 2023 23:11:02 +0200
parents bdcdbd4ea9cd
children 481960ca366f
comparison
equal deleted inserted replaced
1395:bdcdbd4ea9cd 1396:35840a0681d1
1 # TODO: Should BoundaryData just be used for traits
2 # of the BoundaryConditions? Seems like one then could move the
3 # the boundary data value val directly to BoundaryCondition
4 # Not sure how one would do this tho.
5 """ 1 """
6 BoundaryData 2 BoundaryCondition
7 3
8 A type for storing boundary data, e.g. constant, space-dependent, time-dependent etc. 4 A type for implementing data needed in order to impose a boundary condition.
9 Subtypes of `BoundaryData` should store the boundary data in a field `val`. The exception 5 Subtypes refer to perticular types of boundary conditions, e.g. Neumann conditions.
10 to this is ZeroBoundaryData.
11 """ 6 """
12 abstract type BoundaryData end 7 abstract type BoundaryCondition end
13 8
14 """ 9 """
15 ConstantBoundaryData 10 id(::BoundaryCondition)
16 11
17 `val` is a scalar value of type T 12 The boundary identifier of the BoundaryCondition.
13 Must be implemented by subtypes.
18 """ 14 """
19 struct ConstantBoundaryData{T<:Number} <: BoundaryData 15 function id end
20 val::T
21 end
22 16
23 """ 17 """
24 SpaceDependentBoundaryData 18 data(::BoundaryCondition)
25 19
26 `val` is a function of dimensionality equal to the boundary 20 If implemented, the data associated with the BoundaryCondition
27 """ 21 """
28 struct SpaceDependentBoundaryData{T<:Function} <: BoundaryData 22 function data end
29 val::T
30 end
31
32 """
33 TimeDependentBoundaryData
34
35 `val` is a scalar function val(t)
36 """
37 struct TimeDependentBoundaryData{T<:Function} <: BoundaryData
38 val::T
39 end
40
41 """
42 SpaceTimeDependentBoundaryData
43
44 `val` is a timedependent function returning the spacedependent
45 boundary data at a specific time. For instance, if f(t,x)
46 is the function describing the spacetimedependent boundary data then
47 val(t*) returns the function g(x) = f(t*,x...)
48 """
49 struct SpaceTimeDependentBoundaryData{T<:Function} <: BoundaryData
50 val::T
51
52 function SpaceTimeDependentBoundaryData(f::Function)
53 val(t) = (args...) -> f(t,args...)
54 return new{typeof(val)}(val)
55 end
56 end
57
58 """
59 ZeroBoundaryData
60 """
61 struct ZeroBoundaryData <: BoundaryData end
62
63 23
64 """ 24 """
65 discretize(::BoundaryData, boundary_grid) 25 discretize(::BoundaryData, boundary_grid)
66 26
67 Returns an anonymous time-dependent function f, such that f(t) is 27 Returns an anonymous time-dependent function f, such that f(t) is
68 a `LazyArray` holding the `BoundaryData` discretized on `boundary_grid`. 28 a `LazyArray` holding the `BoundaryData` discretized on `boundary_grid`.
69 """ 29 """
70 # TODO: Is the return type of discretize really a good interface 30 function discretize_data(grid, bc::BoundaryCondition)
71 # for the boundary data? 31 return eval_on(boundary_grid(grid, id(bc)), data(bc))
72 # Moreover, instead of explicitly converting to a LazyArray here
73 # should we defer this to eval_on (and extend eval_on for scalars as well)?
74 # I.e. if eval_on returns a LazyArray, the boundary data is lazy. Otherwise
75 # it is preallocated.
76
77 function discretize(bd::ConstantBoundaryData, boundary_grid)
78 return t -> LazyTensors.LazyConstantArray(bd.val, size(boundary_grid))
79 end 32 end
80
81 function discretize(bd::TimeDependentBoundaryData, boundary_grid)
82 return t -> LazyTensors.LazyConstantArray(bd.val(t), size(boundary_grid))
83 end
84
85 function discretize(bd::SpaceDependentBoundaryData, boundary_grid)
86 return t -> eval_on(boundary_grid, bd.val)
87 end
88
89 function discretize(bd::SpaceTimeDependentBoundaryData, boundary_grid)
90 return t -> eval_on(boundary_grid, bd.val(t))
91 end
92
93 function discretize(::ZeroBoundaryData, boundary_grid)
94 return t -> LazyTensors.LazyConstantArray(zero(eltype(boundary_grid)), size(boundary_grid))
95 end
96
97 """
98 BoundaryCondition
99
100 A type for implementing data needed in order to impose a boundary condition.
101 Subtypes refer to perticular types of boundary conditions, e.g. Neumann conditions.
102 """
103 abstract type BoundaryCondition{T<:BoundaryData} end
104
105 """
106 data(::BoundaryCondition)
107
108 Returns the data stored by the `BoundaryCondition`.
109 """
110 data(bc::BoundaryCondition) = bc.data
111 33
112 34 struct NeumannCondition{DT} <: BoundaryCondition{DT}
113 struct NeumannCondition{BD<:BoundaryData} <: BoundaryCondition{BD} 35 data::DT
114 data::BD
115 id::BoundaryIdentifier 36 id::BoundaryIdentifier
116 end 37 end
38 id(bc::NeumannCondition) = bc.id
39 data(bc::NeumannCondition) = bc.data
117 40
118 struct DirichletCondition{BD<:BoundaryData} <: BoundaryCondition{BD} 41 struct DirichletCondition{DT} <: BoundaryCondition{DT}
119 data::BD 42 data::DT
120 id::BoundaryIdentifier 43 id::BoundaryIdentifier
121 end 44 end
45 id(bc::NeumannCondition) = bc.id
46 data(bc::DirichletCondition) = bc.data