@@ -995,9 +995,23 @@ def _grid_map(self):
995995 Mapper of off-grid interpolation points indices for each dimension.
996996 """
997997 mapper = {}
998+ subs = {}
998999 for i , j , d in zip (self .indices , self .indices_ref , self .dimensions ):
9991000 # Two indices are aligned if they differ by an Integer*spacing.
1000- v = (i - j )/ d .spacing
1001+ if not i .has (d ):
1002+ # Maybe a subdimension
1003+ dims = {sd for sd in i .free_symbols if getattr (sd , 'is_Dimension' , False )
1004+ and d in sd ._defines }
1005+ # More than one dimension, cannot handle
1006+ if len (dims ) != 1 :
1007+ continue
1008+ sd = dims .pop ()
1009+ v = (i - j ._subs (d , sd ))/ d .spacing
1010+ i = i ._subs (sd , d )
1011+ subs [d ] = sd
1012+ else :
1013+ v = (i - j )/ d .spacing
1014+
10011015 try :
10021016 if not isinstance (v , sympy .Number ) or int (v ) == v :
10031017 continue
@@ -1008,6 +1022,11 @@ def _grid_map(self):
10081022 mapper .update ({d : i })
10091023 except (AttributeError , TypeError ):
10101024 mapper .update ({d : i })
1025+
1026+ # Substitutions for self.function
1027+ if mapper :
1028+ mapper ['subs' ] = subs
1029+
10111030 return mapper
10121031
10131032 def _evaluate (self , ** kwargs ):
@@ -1019,29 +1038,33 @@ def _evaluate(self, **kwargs):
10191038 This allow to evaluate off grid points as EvalDerivative that are better
10201039 for the compiler.
10211040 """
1041+ mapper = self ._grid_map
1042+ subs = mapper .pop ('subs' , {})
10221043 # Average values if at a location not on the Function's grid
1023- if not self . _grid_map :
1044+ if not mapper :
10241045 return self
10251046
10261047 io = self .interp_order
1027- # Base function
10281048 if self ._avg_mode == 'harmonic' :
1029- retval = 1 / self . function
1049+ retval = 1 / self
10301050 else :
1031- retval = self . function
1051+ retval = self
10321052
10331053 # Apply interpolation from inner most dim
1034- for d , i in self ._grid_map .items ():
1054+ for d , i in mapper .items ():
1055+ retval = retval ._subs (i .subs (subs ), self .indices_ref [d ])
10351056 retval = retval .diff (d , deriv_order = 0 , fd_order = io , x0 = {d : i })
10361057
10371058 # Evaluate. Since we used `self.function` it will be on the grid when
10381059 # evaluate is called again within FD
10391060 retval = retval ._evaluate (** kwargs )
1061+ if subs :
1062+ retval = retval .subs (subs )
10401063
10411064 # If harmonic averaging, invert at the end
10421065 if self ._avg_mode == 'harmonic' :
10431066 from devito .finite_differences .differentiable import SafeInv
1044- retval = SafeInv (retval , self .function )
1067+ retval = SafeInv (retval , self .function . subs ( subs ) )
10451068
10461069 return retval
10471070
0 commit comments