@@ -34,6 +34,10 @@ class FiniteVolume(pybamm.SpatialMethod):
34
34
35
35
def __init__ (self , mesh ):
36
36
super ().__init__ (mesh )
37
+
38
+ # there is no way to set this at the moment
39
+ self .extrapolation = "linear"
40
+
37
41
# add npts_for_broadcast to mesh domains for this particular discretisation
38
42
for dom in mesh .keys ():
39
43
for i in range (len (mesh [dom ])):
@@ -572,7 +576,7 @@ def add_ghost_nodes(self, symbol, discretised_symbol, bcs):
572
576
573
577
return pybamm .Matrix (matrix ) @ discretised_symbol + bcs_vector
574
578
575
- def boundary_value_or_flux (self , symbol , discretised_child , extrapolation = "linear" ):
579
+ def boundary_value_or_flux (self , symbol , discretised_child ):
576
580
"""
577
581
Uses linear extrapolation to get the boundary value or flux of a variable in the
578
582
Finite Volume Method.
@@ -592,13 +596,17 @@ def boundary_value_or_flux(self, symbol, discretised_child, extrapolation="linea
592
596
nodes = submesh_list [0 ].nodes
593
597
edges = submesh_list [0 ].edges
594
598
595
- # assumes uniform!
599
+ dx0 = nodes [0 ] - edges [0 ]
600
+ dx1 = submesh_list [0 ].d_nodes [0 ]
601
+ dx2 = submesh_list [0 ].d_nodes [1 ]
602
+
603
+ dxN = edges [- 1 ] - nodes [- 1 ]
604
+ dxNm1 = submesh_list [0 ].d_nodes [- 1 ]
605
+ dxNm2 = submesh_list [0 ].d_nodes [- 2 ]
606
+
596
607
if symbol .side == "left" :
597
- dx0 = nodes [0 ] - edges [0 ]
598
- dx1 = submesh_list [0 ].d_nodes [0 ]
599
- dx2 = submesh_list [0 ].d_nodes [1 ]
600
608
601
- if extrapolation == "linear" :
609
+ if self . extrapolation == "linear" :
602
610
# to find value at x* use formula:
603
611
# f(x*) = f_1 - (dx0 / dx1) (f_2 - f_1)
604
612
# where
@@ -609,7 +617,7 @@ def boundary_value_or_flux(self, symbol, discretised_child, extrapolation="linea
609
617
([1 + (dx0 / dx1 ), - (dx0 / dx1 )], ([0 , 0 ], [0 , 1 ])),
610
618
shape = (1 , prim_pts ),
611
619
)
612
- elif extrapolation == "quadratic" :
620
+ elif self . extrapolation == "quadratic" :
613
621
# to find value at x* use formula:
614
622
# see mathematica notebook at:
615
623
# https://github.com/Scottmar93/extrapolation-coefficents/tree/master
@@ -626,11 +634,8 @@ def boundary_value_or_flux(self, symbol, discretised_child, extrapolation="linea
626
634
raise NotImplementedError
627
635
628
636
elif symbol .side == "right" :
629
- dxN = edges [- 1 ] - nodes [- 1 ]
630
- dxNm1 = submesh_list [0 ].d_nodes [- 1 ]
631
- dxNm2 = submesh_list [0 ].d_nodes [- 2 ]
632
637
633
- if extrapolation == "linear" :
638
+ if self . extrapolation == "linear" :
634
639
# to find value at x* use formula:
635
640
# f(x*) = f_N - (dxN / dxNm1) (f_N - f_Nm1)
636
641
# where
@@ -644,7 +649,7 @@ def boundary_value_or_flux(self, symbol, discretised_child, extrapolation="linea
644
649
),
645
650
shape = (1 , prim_pts ),
646
651
)
647
- elif extrapolation == "quadratic" :
652
+ elif self . extrapolation == "quadratic" :
648
653
# to find value at x* use formula:
649
654
# see mathematica notebook at:
650
655
# https://github.com/Scottmar93/extrapolation-coefficents/tree/master
@@ -670,23 +675,46 @@ def boundary_value_or_flux(self, symbol, discretised_child, extrapolation="linea
670
675
671
676
elif isinstance (symbol , pybamm .BoundaryGradient ):
672
677
if symbol .side == "left" :
673
- dx = submesh_list [0 ].d_nodes [0 ]
678
+ # use formula:
679
+ # f'(x*) = (f_2 - f_1) / dx1
680
+ # where dx1 = x_2 - x_1
674
681
675
- if extrapolation == "linear" :
676
- sub_matrix = (1 / dx ) * csr_matrix (
682
+ if self . extrapolation == "linear" :
683
+ sub_matrix = (1 / dx1 ) * csr_matrix (
677
684
([- 1 , 1 ], ([0 , 0 ], [0 , 1 ])), shape = (1 , prim_pts )
678
685
)
686
+ elif self .extrapolation == "quadratic" :
687
+
688
+ a = - (2 * dx0 + 2 * dx1 + dx2 ) / (dx1 ** 2 + dx1 * dx2 )
689
+ b = (2 * dx0 + dx1 + dx2 ) / (dx1 * dx2 )
690
+ c = - (2 * dx0 + dx1 ) / (dx1 * dx2 + dx2 ** 2 )
691
+
692
+ sub_matrix = csr_matrix (
693
+ ([a , b , c ], ([0 , 0 , 0 ], [0 , 1 , 2 ])), shape = (1 , prim_pts )
694
+ )
679
695
else :
680
696
raise NotImplementedError
681
697
682
698
elif symbol .side == "right" :
683
699
dx = submesh_list [0 ].d_nodes [- 1 ]
684
700
685
- if extrapolation == "linear" :
701
+ if self . extrapolation == "linear" :
686
702
sub_matrix = (1 / dx ) * csr_matrix (
687
703
([- 1 , 1 ], ([0 , 0 ], [prim_pts - 2 , prim_pts - 1 ])),
688
704
shape = (1 , prim_pts ),
689
705
)
706
+ elif self .extrapolation == "quadratic" :
707
+ a = (2 * dxN + 2 * dxNm1 + dxNm2 ) / (dxNm1 ** 2 + dxNm1 * dxNm2 )
708
+ b = - (2 * dxN + dxNm1 + dxNm2 ) / (dxNm1 * dxNm2 )
709
+ c = (2 * dxN + dxNm1 ) / (dxNm1 * dxNm2 + dxNm2 ** 2 )
710
+
711
+ sub_matrix = csr_matrix (
712
+ (
713
+ [c , b , a ],
714
+ ([0 , 0 , 0 ], [prim_pts - 3 , prim_pts - 2 , prim_pts - 1 ]),
715
+ ),
716
+ shape = (1 , prim_pts ),
717
+ )
690
718
else :
691
719
raise NotImplementedError
692
720
0 commit comments