@@ -56,7 +56,7 @@ def test_concatenation(self):
56
56
with self .assertRaisesRegex (pybamm .ShapeError , "child must have size n_nodes" ):
57
57
fin_vol .concatenation (edges )
58
58
59
- def test_extrapolate_left_right (self ):
59
+ def test_linear_extrapolate_left_right (self ):
60
60
# create discretisation
61
61
mesh = get_mesh_for_testing ()
62
62
spatial_methods = {
@@ -74,8 +74,8 @@ def test_extrapolate_left_right(self):
74
74
# create variable
75
75
var = pybamm .Variable ("var" , domain = whole_cell )
76
76
# boundary value should work with something more complicated than a variable
77
- extrap_left = pybamm .BoundaryValue (2 * var , "left" )
78
- extrap_right = pybamm .BoundaryValue (4 - var , "right" )
77
+ extrap_left = pybamm .BoundaryValue (2 * var , "left" , "linear" )
78
+ extrap_right = pybamm .BoundaryValue (4 - var , "right" , "linear" )
79
79
disc .set_variable_slices ([var ])
80
80
extrap_left_disc = disc .process_symbol (extrap_left )
81
81
extrap_right_disc = disc .process_symbol (extrap_right )
@@ -104,6 +104,80 @@ def test_extrapolate_left_right(self):
104
104
self .assertEqual (extrap_flux_left_disc .evaluate (None , linear_y ), 2 )
105
105
self .assertEqual (extrap_flux_right_disc .evaluate (None , linear_y ), - 1 )
106
106
107
+ # Microscale
108
+ # create variable
109
+ var = pybamm .Variable ("var" , domain = "negative particle" )
110
+ surf_eqn = pybamm .surf (var , extrapolation = "linear" )
111
+ disc .set_variable_slices ([var ])
112
+ surf_eqn_disc = disc .process_symbol (surf_eqn )
113
+
114
+ # check constant extrapolates to constant
115
+ constant_y = np .ones_like (micro_submesh [0 ].nodes [:, np .newaxis ])
116
+ self .assertEqual (surf_eqn_disc .evaluate (None , constant_y ), 1.0 )
117
+
118
+ # check linear variable extrapolates correctly
119
+ linear_y = micro_submesh [0 ].nodes
120
+ y_surf = micro_submesh [0 ].edges [- 1 ]
121
+ np .testing .assert_array_almost_equal (
122
+ surf_eqn_disc .evaluate (None , linear_y ), y_surf
123
+ )
124
+
125
+ def test_quadratic_extrapolate_left_right (self ):
126
+ # create discretisation
127
+ mesh = get_mesh_for_testing ()
128
+ spatial_methods = {
129
+ "macroscale" : pybamm .FiniteVolume ,
130
+ "negative particle" : pybamm .FiniteVolume ,
131
+ "current collector" : pybamm .ZeroDimensionalMethod ,
132
+ }
133
+ disc = pybamm .Discretisation (mesh , spatial_methods )
134
+
135
+ whole_cell = ["negative electrode" , "separator" , "positive electrode" ]
136
+ macro_submesh = mesh .combine_submeshes (* whole_cell )
137
+ micro_submesh = mesh ["negative particle" ]
138
+
139
+ # Macroscale
140
+ # create variable
141
+ var = pybamm .Variable ("var" , domain = whole_cell )
142
+ # boundary value should work with something more complicated than a variable
143
+ extrap_left = pybamm .BoundaryValue (2 * var , "left" , "quadratic" )
144
+ extrap_right = pybamm .BoundaryValue (4 - var , "right" , "quadratic" )
145
+ disc .set_variable_slices ([var ])
146
+ extrap_left_disc = disc .process_symbol (extrap_left )
147
+ extrap_right_disc = disc .process_symbol (extrap_right )
148
+
149
+ # check constant extrapolates to constant
150
+ constant_y = np .ones_like (macro_submesh [0 ].nodes [:, np .newaxis ])
151
+ np .testing .assert_array_almost_equal (
152
+ extrap_left_disc .evaluate (None , constant_y ), 2.0
153
+ )
154
+ np .testing .assert_array_almost_equal (
155
+ extrap_right_disc .evaluate (None , constant_y ), 3.0
156
+ )
157
+
158
+ # check linear variable extrapolates correctly
159
+ linear_y = macro_submesh [0 ].nodes
160
+ np .testing .assert_array_almost_equal (
161
+ extrap_left_disc .evaluate (None , linear_y ), 0
162
+ )
163
+ np .testing .assert_array_almost_equal (
164
+ extrap_right_disc .evaluate (None , linear_y ), 3
165
+ )
166
+
167
+ # Fluxes
168
+ extrap_flux_left = pybamm .BoundaryGradient (2 * var , "left" )
169
+ extrap_flux_right = pybamm .BoundaryGradient (1 - var , "right" )
170
+ extrap_flux_left_disc = disc .process_symbol (extrap_flux_left )
171
+ extrap_flux_right_disc = disc .process_symbol (extrap_flux_right )
172
+
173
+ # check constant extrapolates to constant
174
+ self .assertEqual (extrap_flux_left_disc .evaluate (None , constant_y ), 0 )
175
+ self .assertEqual (extrap_flux_right_disc .evaluate (None , constant_y ), 0 )
176
+
177
+ # check linear variable extrapolates correctly
178
+ self .assertEqual (extrap_flux_left_disc .evaluate (None , linear_y ), 2 )
179
+ self .assertEqual (extrap_flux_right_disc .evaluate (None , linear_y ), - 1 )
180
+
107
181
# Microscale
108
182
# create variable
109
183
var = pybamm .Variable ("var" , domain = "negative particle" )
@@ -113,11 +187,53 @@ def test_extrapolate_left_right(self):
113
187
114
188
# check constant extrapolates to constant
115
189
constant_y = np .ones_like (micro_submesh [0 ].nodes [:, np .newaxis ])
116
- self .assertEqual (surf_eqn_disc .evaluate (None , constant_y ), 1 )
190
+ np .testing .assert_array_almost_equal (
191
+ surf_eqn_disc .evaluate (None , constant_y ), 1
192
+ )
117
193
118
194
# check linear variable extrapolates correctly
119
195
linear_y = micro_submesh [0 ].nodes
120
- y_surf = micro_submesh [0 ].nodes [- 1 ] + micro_submesh [0 ].d_nodes [- 1 ] / 2
196
+ y_surf = micro_submesh [0 ].edges [- 1 ]
197
+ np .testing .assert_array_almost_equal (
198
+ surf_eqn_disc .evaluate (None , linear_y ), y_surf
199
+ )
200
+
201
+ def test_extrapolate_on_nonuniform_grid (self ):
202
+ geometry = pybamm .Geometry ("1D micro" )
203
+
204
+ submesh_types = {
205
+ "negative particle" : pybamm .MeshGenerator (pybamm .Exponential1DSubMesh ),
206
+ "positive particle" : pybamm .MeshGenerator (pybamm .Exponential1DSubMesh ),
207
+ }
208
+
209
+ var = pybamm .standard_spatial_vars
210
+ rpts = 10
211
+ var_pts = {
212
+ var .r_n : rpts ,
213
+ var .r_p : rpts ,
214
+ }
215
+ mesh = pybamm .Mesh (geometry , submesh_types , var_pts )
216
+ spatial_methods = {
217
+ "negative particle" : pybamm .FiniteVolume ,
218
+ }
219
+ disc = pybamm .Discretisation (mesh , spatial_methods )
220
+
221
+ var = pybamm .Variable ("var" , domain = "negative particle" )
222
+ surf_eqn = pybamm .surf (var )
223
+ disc .set_variable_slices ([var ])
224
+ surf_eqn_disc = disc .process_symbol (surf_eqn )
225
+
226
+ micro_submesh = mesh ["negative particle" ]
227
+
228
+ # check constant extrapolates to constant
229
+ constant_y = np .ones_like (micro_submesh [0 ].nodes [:, np .newaxis ])
230
+ np .testing .assert_array_almost_equal (
231
+ surf_eqn_disc .evaluate (None , constant_y ), 1
232
+ )
233
+
234
+ # check linear variable extrapolates correctly
235
+ linear_y = micro_submesh [0 ].nodes
236
+ y_surf = micro_submesh [0 ].edges [- 1 ]
121
237
np .testing .assert_array_almost_equal (
122
238
surf_eqn_disc .evaluate (None , linear_y ), y_surf
123
239
)
@@ -1033,7 +1149,7 @@ def test_indefinite_integral(self):
1033
1149
}
1034
1150
}
1035
1151
int_grad_phi_disc = disc .process_symbol (int_grad_phi )
1036
- left_boundary_value = pybamm .BoundaryValue (int_grad_phi , "left" )
1152
+ left_boundary_value = pybamm .BoundaryValue (int_grad_phi , "left" , "linear" )
1037
1153
left_boundary_value_disc = disc .process_symbol (left_boundary_value )
1038
1154
1039
1155
combined_submesh = mesh .combine_submeshes ("negative electrode" , "separator" )
@@ -1087,15 +1203,19 @@ def test_indefinite_integral(self):
1087
1203
)
1088
1204
phi_approx = int_grad_phi_disc .evaluate (None , phi_exact )
1089
1205
np .testing .assert_array_almost_equal (phi_exact , phi_approx )
1090
- self .assertEqual (left_boundary_value_disc .evaluate (y = phi_exact ), 0 )
1206
+ np .testing .assert_array_almost_equal (
1207
+ left_boundary_value_disc .evaluate (y = phi_exact ), 0
1208
+ )
1091
1209
1092
1210
# sine case
1093
1211
phi_exact = np .sin (
1094
1212
combined_submesh [0 ].nodes [:, np .newaxis ] - combined_submesh [0 ].edges [0 ]
1095
1213
)
1096
1214
phi_approx = int_grad_phi_disc .evaluate (None , phi_exact )
1097
1215
np .testing .assert_array_almost_equal (phi_exact , phi_approx )
1098
- self .assertEqual (left_boundary_value_disc .evaluate (y = phi_exact ), 0 )
1216
+ np .testing .assert_array_almost_equal (
1217
+ left_boundary_value_disc .evaluate (y = phi_exact ), 0
1218
+ )
1099
1219
1100
1220
# --------------------------------------------------------------------
1101
1221
# micrsoscale case
@@ -1112,7 +1232,7 @@ def test_indefinite_integral(self):
1112
1232
}
1113
1233
1114
1234
c_integral_disc = disc .process_symbol (c_integral )
1115
- left_boundary_value = pybamm .BoundaryValue (c_integral , "left" )
1235
+ left_boundary_value = pybamm .BoundaryValue (c_integral , "left" , "linear" )
1116
1236
left_boundary_value_disc = disc .process_symbol (left_boundary_value )
1117
1237
combined_submesh = mesh ["negative particle" ]
1118
1238
@@ -1127,13 +1247,17 @@ def test_indefinite_integral(self):
1127
1247
c_exact = combined_submesh [0 ].nodes [:, np .newaxis ]
1128
1248
c_approx = c_integral_disc .evaluate (None , c_exact )
1129
1249
np .testing .assert_array_almost_equal (c_exact , c_approx )
1130
- self .assertEqual (left_boundary_value_disc .evaluate (y = c_exact ), 0 )
1250
+ np .testing .assert_array_almost_equal (
1251
+ left_boundary_value_disc .evaluate (y = c_exact ), 0
1252
+ )
1131
1253
1132
1254
# sine case
1133
1255
c_exact = np .sin (combined_submesh [0 ].nodes [:, np .newaxis ])
1134
1256
c_approx = c_integral_disc .evaluate (None , c_exact )
1135
1257
np .testing .assert_array_almost_equal (c_exact , c_approx , decimal = 3 )
1136
- self .assertEqual (left_boundary_value_disc .evaluate (y = c_exact ), 0 )
1258
+ np .testing .assert_array_almost_equal (
1259
+ left_boundary_value_disc .evaluate (y = c_exact ), 0
1260
+ )
1137
1261
1138
1262
def test_indefinite_integral_on_nodes (self ):
1139
1263
mesh = get_mesh_for_testing ()
0 commit comments