@@ -503,7 +503,27 @@ def _eval_at(self, func):
503503 if self .expr .staggered == func .staggered and self .expr .is_Function :
504504 return self
505505
506+ # Check if x0's keys come from a DerivedDimension
506507 x0 = func .indices_ref .getters
508+ psubs = {}
509+ nx0 = x0 .copy ()
510+ for d , d0 in x0 .items ():
511+ if d in self .dims :
512+ # d is a valid Derivative dimension
513+ continue
514+ for sd in self .dims :
515+ if sd in d ._defines :
516+ # x0 key is a DerivedDimension of the derivative dimension
517+ # e.g f.dx(x0={ix: ix + h_x/2}) for a subdomain
518+ # Set x0 to the derivative dimension and add a substitution
519+ # to the parent
520+ # e.g f.dx(x0={x: x + h_x/2}).subs({x: ix})
521+ psubs [sd ] = d
522+ nx0 [sd ] = nx0 .pop (d )._subs (d , sd )
523+ rkw = {'x0' : nx0 }
524+ if psubs :
525+ rkw ['subs' ] = (psubs ,)
526+
507527 if self .expr .is_Add :
508528 # If `expr` has both staggered and non-staggered terms such as
509529 # `(u(x + h_x/2) + v(x)).dx` then we exploit linearity of FD to split
@@ -512,19 +532,19 @@ def _eval_at(self, func):
512532 mapper = as_mapper (self .expr ._args_diff , lambda i : i .staggered )
513533 args = [self .expr .func (* v ) for v in mapper .values ()]
514534 args .extend ([a for a in self .expr .args if a not in self .expr ._args_diff ])
515- args = [self ._rebuild (expr = a , x0 = x0 ) for a in args ]
535+ args = [self ._rebuild (a , ** rkw ) for a in args ]
516536 return self .expr .func (* args )
517537 elif self .expr .is_Mul :
518538 # For Mul, We treat the basic case `u(x + h_x/2) * v(x) which is what appear
519539 # in most equation with div(a * u) for example. The expression is re-centered
520540 # at the highest priority index (see _gather_for_diff) to compute the
521541 # derivative at x0.
522- return self ._rebuild (self .expr ._gather_for_diff , x0 = x0 )
542+ return self ._rebuild (self .expr ._gather_for_diff , ** rkw )
523543 else :
524544 # For every other cases, that has more functions or more complexe arithmetic,
525545 # there is not actual way to decide what to do so it’s as safe to use
526546 # the expression as is.
527- return self ._rebuild (x0 = x0 )
547+ return self ._rebuild (self . expr , ** rkw )
528548
529549 def _evaluate (self , ** kwargs ):
530550 # Evaluate finite-difference.
0 commit comments