
/* Definitions of ET stencil operators. This file was generated by
   generate/genstencils.py. Do not edit.

   Note: You can't pass templates with >1 parameter as macro
   parameters because cpp doesn't recognize that the comma is balanced
   between the angle brackets and interprets them as multiple
   arguments, i.e., the following alternative declaration of grad2D
   will not work:

   BZ_ET_STENCIL(grad2D, TinyVector<P_numtype, 2>, 
   TinyVector<typename T1::T_numtype, 2>, shape(-1,1), shape(1,1))

   instead, you have to use the above bzCC ("ConCatenate") macro to
   protect the things containing commas. The following would work:

   BZ_ET_STENCIL(grad2D, bzCC(TinyVector<P_numtype, 2>), 
   bzCC(TinyVector<typename T1::T_numtype, 2>), shape(-1,-1), shape(1,1))

*/

BZ_NAMESPACE(blitz)




/* Defines a stencil ET difference operator "central12" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -1 and 1 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central12_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central12_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central12_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central12_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central12_et(const central12_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central12_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central12_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central12_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central12_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central12_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central12_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central12_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central12_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central12_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central12_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central12_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central12_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central12(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-1; maxb[dim]=1;					
  return _bz_ArrayExpr<central12_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central12(const Array<T,N>& d1, int dim)					
{ return central12(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central12(Array<T,N>& d1, int dim)						
{ return central12(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central22" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -1 and 1 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central22_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central22_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central22_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central22_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central22_et(const central22_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central22_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central22_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central22_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central22_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central22_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central22_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central22_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central22_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central22_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central22_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central22_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central22_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central22(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-1; maxb[dim]=1;					
  return _bz_ArrayExpr<central22_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central22(const Array<T,N>& d1, int dim)					
{ return central22(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central22(Array<T,N>& d1, int dim)						
{ return central22(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central32" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central32_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central32_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central32_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central32_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central32_et(const central32_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central32_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central32_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central32_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central32_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central32_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central32_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central32_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central32_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central32_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central32_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central32_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central32_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central32(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central32_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central32(const Array<T,N>& d1, int dim)					
{ return central32(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central32(Array<T,N>& d1, int dim)						
{ return central32(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central42" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central42_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central42_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central42_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central42_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central42_et(const central42_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central42_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central42_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central42_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central42_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central42_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central42_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central42_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central42_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central42_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central42_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central42_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central42_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central42(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central42_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central42(const Array<T,N>& d1, int dim)					
{ return central42(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central42(Array<T,N>& d1, int dim)						
{ return central42(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central14" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central14_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central14_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central14_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central14_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central14_et(const central14_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central14_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central14_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central14_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central14_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central14_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central14_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central14_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central14_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central14_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central14_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central14_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central14_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central14(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central14_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central14_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central14(const Array<T,N>& d1, int dim)					
{ return central14(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central14_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central14(Array<T,N>& d1, int dim)						
{ return central14(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central24" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central24_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central24_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central24_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central24_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central24_et(const central24_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central24_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central24_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central24_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central24_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central24_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central24_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central24_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central24_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central24_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central24_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central24_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central24_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central24(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central24_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central24_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central24(const Array<T,N>& d1, int dim)					
{ return central24(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central24_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central24(Array<T,N>& d1, int dim)						
{ return central24(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central34" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central34_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central34_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central34_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central34_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central34_et(const central34_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central34_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central34_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central34_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central34_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central34_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central34_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central34_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central34_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central34_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central34_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central34_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central34_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central34(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central34_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central34_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central34(const Array<T,N>& d1, int dim)					
{ return central34(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central34_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central34(Array<T,N>& d1, int dim)						
{ return central34(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central44" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central44_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central44_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central44_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central44_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central44_et(const central44_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central44_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central44_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central44_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central44_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central44_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central44_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central44_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central44_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central44_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central44_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central44_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central44_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central44(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central44_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central44_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central44(const Array<T,N>& d1, int dim)					
{ return central44(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central44_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central44(Array<T,N>& d1, int dim)						
{ return central44(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central12n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -1 and 1 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central12n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central12n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central12n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central12n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central12n_et(const central12n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central12n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central12n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central12n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central12n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central12n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central12n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central12n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central12n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central12n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central12n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central12n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-1; maxb[dim]=1;					
  return _bz_ArrayExpr<central12n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central12n(const Array<T,N>& d1, int dim)					
{ return central12n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central12n(Array<T,N>& d1, int dim)						
{ return central12n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central22n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -1 and 1 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central22n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central22n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central22n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central22n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central22n_et(const central22n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central22n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central22n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central22n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central22n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central22n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central22n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central22n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central22n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central22n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central22n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central22n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-1; maxb[dim]=1;					
  return _bz_ArrayExpr<central22n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central22n(const Array<T,N>& d1, int dim)					
{ return central22n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central22n(Array<T,N>& d1, int dim)						
{ return central22n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central32n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central32n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central32n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central32n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central32n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central32n_et(const central32n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central32n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central32n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central32n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central32n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central32n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central32n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central32n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central32n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central32n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central32n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central32n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central32n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central32n(const Array<T,N>& d1, int dim)					
{ return central32n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central32n(Array<T,N>& d1, int dim)						
{ return central32n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central42n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central42n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central42n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central42n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central42n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central42n_et(const central42n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central42n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central42n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central42n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central42n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central42n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central42n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central42n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central42n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central42n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central42n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central42n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central42n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central42n(const Array<T,N>& d1, int dim)					
{ return central42n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central42n(Array<T,N>& d1, int dim)						
{ return central42n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central14n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central14n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central14n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central14n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central14n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central14n_et(const central14n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central14n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central14n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central14n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central14n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central14n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central14n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central14n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central14n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central14n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central14n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central14n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central14n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central14n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central14n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central14n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central14n(const Array<T,N>& d1, int dim)					
{ return central14n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central14n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central14n(Array<T,N>& d1, int dim)						
{ return central14n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central24n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central24n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central24n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central24n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central24n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central24n_et(const central24n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central24n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central24n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central24n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central24n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central24n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central24n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central24n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central24n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central24n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central24n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central24n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central24n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central24n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central24n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central24n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central24n(const Array<T,N>& d1, int dim)					
{ return central24n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central24n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central24n(Array<T,N>& d1, int dim)						
{ return central24n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central34n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central34n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central34n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central34n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central34n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central34n_et(const central34n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central34n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central34n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central34n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central34n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central34n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central34n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central34n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central34n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central34n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central34n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central34n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central34n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central34n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central34n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central34n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central34n(const Array<T,N>& d1, int dim)					
{ return central34n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central34n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central34n(Array<T,N>& d1, int dim)						
{ return central34n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "central44n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class central44n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    central44n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central44n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central44n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central44n_et(const central44n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  central44n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  central44n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return central44n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central44n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return central44n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = central44n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = central44n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = central44n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central44n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central44n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central44n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<central44n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central44n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central44n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central44n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central44n(const Array<T,N>& d1, int dim)					
{ return central44n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<central44n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central44n(Array<T,N>& d1, int dim)						
{ return central44n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward11" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -1 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward11_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward11_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward11_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward11_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward11_et(const backward11_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward11_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward11_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward11_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward11_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward11_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward11_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward11_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward11_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward11_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward11_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward11_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward11_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward11(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-1; maxb[dim]=0;					
  return _bz_ArrayExpr<backward11_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward11_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward11(const Array<T,N>& d1, int dim)					
{ return backward11(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward11_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward11(Array<T,N>& d1, int dim)						
{ return backward11(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward21" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward21_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward21_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward21_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward21_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward21_et(const backward21_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward21_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward21_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward21_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward21_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward21_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward21_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward21_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward21_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward21_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward21_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward21_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward21_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward21(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=0;					
  return _bz_ArrayExpr<backward21_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward21_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward21(const Array<T,N>& d1, int dim)					
{ return backward21(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward21_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward21(Array<T,N>& d1, int dim)						
{ return backward21(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward31" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -3 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward31_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward31_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward31_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward31_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward31_et(const backward31_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward31_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward31_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward31_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward31_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward31_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward31_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward31_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward31_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward31_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward31_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward31_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward31_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward31(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-3; maxb[dim]=0;					
  return _bz_ArrayExpr<backward31_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward31_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward31(const Array<T,N>& d1, int dim)					
{ return backward31(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward31_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward31(Array<T,N>& d1, int dim)						
{ return backward31(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward41" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -4 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward41_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward41_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward41_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward41_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward41_et(const backward41_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward41_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward41_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward41_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward41_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward41_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward41_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward41_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward41_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward41_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward41_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward41_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward41_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward41(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-4; maxb[dim]=0;					
  return _bz_ArrayExpr<backward41_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward41_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward41(const Array<T,N>& d1, int dim)					
{ return backward41(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward41_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward41(Array<T,N>& d1, int dim)						
{ return backward41(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward12" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward12_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward12_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward12_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward12_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward12_et(const backward12_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward12_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward12_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward12_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward12_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward12_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward12_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward12_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward12_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward12_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward12_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward12_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward12_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward12(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=0;					
  return _bz_ArrayExpr<backward12_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward12(const Array<T,N>& d1, int dim)					
{ return backward12(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward12(Array<T,N>& d1, int dim)						
{ return backward12(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward22" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -3 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward22_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward22_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward22_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward22_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward22_et(const backward22_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward22_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward22_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward22_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward22_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward22_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward22_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward22_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward22_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward22_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward22_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward22_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward22_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward22(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-3; maxb[dim]=0;					
  return _bz_ArrayExpr<backward22_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward22(const Array<T,N>& d1, int dim)					
{ return backward22(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward22(Array<T,N>& d1, int dim)						
{ return backward22(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward32" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -4 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward32_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward32_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward32_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward32_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward32_et(const backward32_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward32_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward32_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward32_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward32_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward32_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward32_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward32_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward32_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward32_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward32_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward32_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward32_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward32(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-4; maxb[dim]=0;					
  return _bz_ArrayExpr<backward32_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward32(const Array<T,N>& d1, int dim)					
{ return backward32(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward32(Array<T,N>& d1, int dim)						
{ return backward32(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward42" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -5 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward42_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward42_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward42_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward42_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward42_et(const backward42_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward42_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward42_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward42_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward42_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward42_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward42_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward42_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward42_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward42_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward42_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward42_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward42_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward42(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-5; maxb[dim]=0;					
  return _bz_ArrayExpr<backward42_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward42(const Array<T,N>& d1, int dim)					
{ return backward42(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward42(Array<T,N>& d1, int dim)						
{ return backward42(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward11n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -1 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward11n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward11n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward11n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward11n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward11n_et(const backward11n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward11n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward11n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward11n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward11n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward11n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward11n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward11n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward11n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward11n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward11n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward11n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward11n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward11n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-1; maxb[dim]=0;					
  return _bz_ArrayExpr<backward11n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward11n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward11n(const Array<T,N>& d1, int dim)					
{ return backward11n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward11n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward11n(Array<T,N>& d1, int dim)						
{ return backward11n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward21n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward21n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward21n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward21n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward21n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward21n_et(const backward21n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward21n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward21n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward21n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward21n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward21n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward21n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward21n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward21n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward21n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward21n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward21n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward21n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward21n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=0;					
  return _bz_ArrayExpr<backward21n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward21n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward21n(const Array<T,N>& d1, int dim)					
{ return backward21n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward21n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward21n(Array<T,N>& d1, int dim)						
{ return backward21n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward31n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -3 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward31n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward31n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward31n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward31n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward31n_et(const backward31n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward31n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward31n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward31n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward31n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward31n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward31n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward31n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward31n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward31n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward31n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward31n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward31n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward31n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-3; maxb[dim]=0;					
  return _bz_ArrayExpr<backward31n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward31n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward31n(const Array<T,N>& d1, int dim)					
{ return backward31n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward31n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward31n(Array<T,N>& d1, int dim)						
{ return backward31n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward41n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -4 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward41n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward41n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward41n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward41n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward41n_et(const backward41n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward41n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward41n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward41n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward41n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward41n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward41n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward41n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward41n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward41n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward41n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward41n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward41n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward41n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-4; maxb[dim]=0;					
  return _bz_ArrayExpr<backward41n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward41n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward41n(const Array<T,N>& d1, int dim)					
{ return backward41n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward41n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward41n(Array<T,N>& d1, int dim)						
{ return backward41n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward12n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -2 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward12n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward12n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward12n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward12n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward12n_et(const backward12n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward12n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward12n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward12n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward12n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward12n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward12n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward12n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward12n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward12n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward12n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward12n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-2; maxb[dim]=0;					
  return _bz_ArrayExpr<backward12n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward12n(const Array<T,N>& d1, int dim)					
{ return backward12n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward12n(Array<T,N>& d1, int dim)						
{ return backward12n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward22n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -3 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward22n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward22n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward22n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward22n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward22n_et(const backward22n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward22n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward22n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward22n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward22n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward22n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward22n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward22n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward22n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward22n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward22n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward22n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-3; maxb[dim]=0;					
  return _bz_ArrayExpr<backward22n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward22n(const Array<T,N>& d1, int dim)					
{ return backward22n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward22n(Array<T,N>& d1, int dim)						
{ return backward22n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward32n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -4 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward32n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward32n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward32n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward32n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward32n_et(const backward32n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward32n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward32n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward32n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward32n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward32n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward32n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward32n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward32n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward32n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward32n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward32n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-4; maxb[dim]=0;					
  return _bz_ArrayExpr<backward32n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward32n(const Array<T,N>& d1, int dim)					
{ return backward32n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward32n(Array<T,N>& d1, int dim)						
{ return backward32n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "backward42n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). -5 and 0 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class backward42n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    backward42n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward42n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward42n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward42n_et(const backward42n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  backward42n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  backward42n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return backward42n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward42n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return backward42n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = backward42n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = backward42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = backward42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward42n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward42n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward42n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<backward42n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward42n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=-5; maxb[dim]=0;					
  return _bz_ArrayExpr<backward42n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward42n(const Array<T,N>& d1, int dim)					
{ return backward42n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<backward42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward42n(Array<T,N>& d1, int dim)						
{ return backward42n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward11" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 1 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward11_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward11_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward11_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward11_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward11_et(const forward11_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward11_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward11_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward11_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward11_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward11_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward11_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward11_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward11_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward11_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward11_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward11_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward11_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward11(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=1;					
  return _bz_ArrayExpr<forward11_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward11_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward11(const Array<T,N>& d1, int dim)					
{ return forward11(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward11_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward11(Array<T,N>& d1, int dim)						
{ return forward11(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward21" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward21_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward21_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward21_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward21_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward21_et(const forward21_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward21_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward21_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward21_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward21_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward21_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward21_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward21_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward21_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward21_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward21_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward21_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward21_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward21(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=2;					
  return _bz_ArrayExpr<forward21_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward21_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward21(const Array<T,N>& d1, int dim)					
{ return forward21(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward21_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward21(Array<T,N>& d1, int dim)						
{ return forward21(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward31" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 3 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward31_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward31_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward31_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward31_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward31_et(const forward31_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward31_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward31_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward31_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward31_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward31_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward31_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward31_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward31_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward31_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward31_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward31_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward31_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward31(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=3;					
  return _bz_ArrayExpr<forward31_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward31_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward31(const Array<T,N>& d1, int dim)					
{ return forward31(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward31_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward31(Array<T,N>& d1, int dim)						
{ return forward31(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward41" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 4 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward41_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward41_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward41_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward41_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward41_et(const forward41_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward41_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward41_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward41_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward41_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward41_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward41_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward41_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward41_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward41_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward41_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward41_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward41_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward41(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=4;					
  return _bz_ArrayExpr<forward41_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward41_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward41(const Array<T,N>& d1, int dim)					
{ return forward41(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward41_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward41(Array<T,N>& d1, int dim)						
{ return forward41(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward12" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward12_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward12_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward12_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward12_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward12_et(const forward12_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward12_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward12_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward12_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward12_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward12_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward12_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward12_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward12_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward12_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward12_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward12_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward12_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward12(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=2;					
  return _bz_ArrayExpr<forward12_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward12(const Array<T,N>& d1, int dim)					
{ return forward12(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward12(Array<T,N>& d1, int dim)						
{ return forward12(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward22" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 3 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward22_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward22_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward22_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward22_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward22_et(const forward22_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward22_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward22_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward22_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward22_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward22_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward22_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward22_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward22_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward22_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward22_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward22_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward22_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward22(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=3;					
  return _bz_ArrayExpr<forward22_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward22(const Array<T,N>& d1, int dim)					
{ return forward22(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward22(Array<T,N>& d1, int dim)						
{ return forward22(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward32" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 4 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward32_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward32_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward32_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward32_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward32_et(const forward32_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward32_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward32_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward32_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward32_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward32_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward32_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward32_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward32_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward32_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward32_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward32_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward32_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward32(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=4;					
  return _bz_ArrayExpr<forward32_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward32(const Array<T,N>& d1, int dim)					
{ return forward32(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward32(Array<T,N>& d1, int dim)						
{ return forward32(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward42" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 5 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward42_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward42_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward42_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward42_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward42_et(const forward42_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward42_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward42_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward42_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward42_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward42_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward42_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward42_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward42_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward42_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward42_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward42_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward42_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward42(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=5;					
  return _bz_ArrayExpr<forward42_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward42(const Array<T,N>& d1, int dim)					
{ return forward42(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward42(Array<T,N>& d1, int dim)						
{ return forward42(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward11n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 1 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward11n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward11n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward11n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward11n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward11n_et(const forward11n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward11n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward11n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward11n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward11n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward11n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward11n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward11n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward11n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward11n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward11n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward11n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward11n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward11n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=1;					
  return _bz_ArrayExpr<forward11n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward11n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward11n(const Array<T,N>& d1, int dim)					
{ return forward11n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward11n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward11n(Array<T,N>& d1, int dim)						
{ return forward11n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward21n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward21n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward21n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward21n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward21n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward21n_et(const forward21n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward21n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward21n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward21n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward21n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward21n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward21n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward21n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward21n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward21n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward21n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward21n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward21n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward21n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=2;					
  return _bz_ArrayExpr<forward21n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward21n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward21n(const Array<T,N>& d1, int dim)					
{ return forward21n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward21n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward21n(Array<T,N>& d1, int dim)						
{ return forward21n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward31n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 3 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward31n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward31n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward31n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward31n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward31n_et(const forward31n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward31n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward31n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward31n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward31n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward31n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward31n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward31n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward31n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward31n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward31n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward31n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward31n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward31n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=3;					
  return _bz_ArrayExpr<forward31n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward31n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward31n(const Array<T,N>& d1, int dim)					
{ return forward31n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward31n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward31n(Array<T,N>& d1, int dim)						
{ return forward31n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward41n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 4 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward41n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward41n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward41n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward41n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward41n_et(const forward41n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward41n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward41n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward41n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward41n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward41n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward41n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward41n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward41n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward41n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward41n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward41n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward41n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward41n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=4;					
  return _bz_ArrayExpr<forward41n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward41n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward41n(const Array<T,N>& d1, int dim)					
{ return forward41n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward41n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward41n(Array<T,N>& d1, int dim)						
{ return forward41n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward12n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 2 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward12n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward12n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward12n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward12n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward12n_et(const forward12n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward12n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward12n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward12n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward12n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward12n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward12n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward12n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward12n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward12n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward12n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward12n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=2;					
  return _bz_ArrayExpr<forward12n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward12n(const Array<T,N>& d1, int dim)					
{ return forward12n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward12n(Array<T,N>& d1, int dim)						
{ return forward12n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward22n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 3 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward22n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward22n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward22n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward22n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward22n_et(const forward22n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward22n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward22n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward22n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward22n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward22n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward22n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward22n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward22n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward22n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward22n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward22n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=3;					
  return _bz_ArrayExpr<forward22n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward22n(const Array<T,N>& d1, int dim)					
{ return forward22n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward22n(Array<T,N>& d1, int dim)						
{ return forward22n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward32n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 4 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward32n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward32n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward32n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward32n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward32n_et(const forward32n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward32n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward32n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward32n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward32n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward32n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward32n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward32n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward32n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward32n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward32n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward32n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=4;					
  return _bz_ArrayExpr<forward32n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward32n(const Array<T,N>& d1, int dim)					
{ return forward32n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward32n(Array<T,N>& d1, int dim)						
{ return forward32n(d1.wrap(), dim); }



/* Defines a stencil ET difference operator "forward42n" that operates on
   an array<P_numtype, N_rank> and returns an array of identical
   type. (The only significance of the "difference" aspect is that the
   operator is assumed to take a second argument which is the
   dimension to do the difference in). 0 and 5 are integer
   expressions describing the extent of the operator in the operating
   dimension. */

template<typename P_expr>						
class forward42n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype>	
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    forward42n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward42n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward42n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward42n_et(const forward42n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(a.dim_)	
  { }								
									
  forward42n_et(BZ_ETPARM(T_expr) a, int dim) :			
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  forward42n_et(_bz_typename T_expr::T_ctorArg1 a, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a), dim_(dim)		
  { }								
									
  T_result operator*() const						
  { return forward42n_stencilop(iter_, dim_); }					
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward42n_stencilop(iter_, dim_); }			
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim_); }				
									
  T_result operator[](int i) const					
  { return forward42n_stencilop(iter_[i], dim_); }					
									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = forward42n_stencilop (iter_, dim_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim_); }

  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = forward42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = forward42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward42n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward42n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward42n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),dim_);				
  }									
									
private:								
  int dim_;								
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<forward42n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward42n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim)			
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0); 
  minb[dim]=0; maxb[dim]=5;					
  return _bz_ArrayExpr<forward42n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward42n(const Array<T,N>& d1, int dim)					
{ return forward42n(d1.wrap(), dim); }					
template<typename T, int N>						
inline _bz_ArrayExpr<forward42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward42n(Array<T,N>& d1, int dim)						
{ return forward42n(d1.wrap(), dim); }



/** Defines a stencil ET difference operator "central12" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central12_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central12_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central12_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central12_et_multi(const central12_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central12_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central12_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central12_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central12_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central12_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central12_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central12_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central12_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central12_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central12_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central12_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central12_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central12(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-1; maxb[dim]=1;					
  return _bz_ArrayExpr<central12_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central12_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central12(const Array<T,N>& d1, int comp, int dim)				
{ return central12(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central12_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central12(Array<T,N>& d1, int comp, int dim)				
{ return central12(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central12(const Array<T,N>& d1)
{ return central12(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central12(Array<T,N>& d1)
{ return central12(d1.wrap()); }



/** Defines a stencil ET difference operator "central22" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central22_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central22_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central22_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central22_et_multi(const central22_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central22_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central22_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central22_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central22_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central22_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central22_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central22_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central22_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central22_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central22_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central22_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central22_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central22(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-1; maxb[dim]=1;					
  return _bz_ArrayExpr<central22_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central22_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central22(const Array<T,N>& d1, int comp, int dim)				
{ return central22(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central22_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central22(Array<T,N>& d1, int comp, int dim)				
{ return central22(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central22(const Array<T,N>& d1)
{ return central22(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central22(Array<T,N>& d1)
{ return central22(d1.wrap()); }



/** Defines a stencil ET difference operator "central32" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central32_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central32_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central32_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central32_et_multi(const central32_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central32_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central32_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central32_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central32_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central32_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central32_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central32_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central32_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central32_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central32_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central32_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central32_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central32(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central32_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central32_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central32(const Array<T,N>& d1, int comp, int dim)				
{ return central32(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central32_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central32(Array<T,N>& d1, int comp, int dim)				
{ return central32(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central32(const Array<T,N>& d1)
{ return central32(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central32(Array<T,N>& d1)
{ return central32(d1.wrap()); }



/** Defines a stencil ET difference operator "central42" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central42_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central42_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central42_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central42_et_multi(const central42_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central42_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central42_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central42_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central42_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central42_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central42_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central42_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central42_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central42_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central42_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central42_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central42_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central42(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central42_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central42_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central42(const Array<T,N>& d1, int comp, int dim)				
{ return central42(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central42_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central42(Array<T,N>& d1, int comp, int dim)				
{ return central42(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central42(const Array<T,N>& d1)
{ return central42(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central42(Array<T,N>& d1)
{ return central42(d1.wrap()); }



/** Defines a stencil ET difference operator "central14" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central14_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central14_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central14_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central14_et_multi(const central14_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central14_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central14_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central14_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central14_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central14_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central14_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central14_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central14_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central14_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central14_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central14_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central14_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central14(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central14_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central14_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central14(const Array<T,N>& d1, int comp, int dim)				
{ return central14(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central14_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central14(Array<T,N>& d1, int comp, int dim)				
{ return central14(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central14_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central14(const Array<T,N>& d1)
{ return central14(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central14_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central14(Array<T,N>& d1)
{ return central14(d1.wrap()); }



/** Defines a stencil ET difference operator "central24" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central24_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central24_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central24_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central24_et_multi(const central24_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central24_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central24_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central24_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central24_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central24_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central24_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central24_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central24_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central24_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central24_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central24_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central24_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central24(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central24_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central24_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central24(const Array<T,N>& d1, int comp, int dim)				
{ return central24(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central24_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central24(Array<T,N>& d1, int comp, int dim)				
{ return central24(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central24_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central24(const Array<T,N>& d1)
{ return central24(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central24_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central24(Array<T,N>& d1)
{ return central24(d1.wrap()); }



/** Defines a stencil ET difference operator "central34" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central34_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central34_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central34_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central34_et_multi(const central34_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central34_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central34_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central34_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central34_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central34_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central34_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central34_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central34_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central34_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central34_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central34_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central34_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central34(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central34_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central34_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central34(const Array<T,N>& d1, int comp, int dim)				
{ return central34(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central34_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central34(Array<T,N>& d1, int comp, int dim)				
{ return central34(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central34_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central34(const Array<T,N>& d1)
{ return central34(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central34_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central34(Array<T,N>& d1)
{ return central34(d1.wrap()); }



/** Defines a stencil ET difference operator "central44" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central44_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central44_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central44_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central44_et_multi(const central44_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central44_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central44_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central44_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central44_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central44_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central44_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central44_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central44_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central44_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central44_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central44_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central44_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central44(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central44_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central44_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central44(const Array<T,N>& d1, int comp, int dim)				
{ return central44(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central44_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central44(Array<T,N>& d1, int comp, int dim)				
{ return central44(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central44_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central44(const Array<T,N>& d1)
{ return central44(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central44_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central44(Array<T,N>& d1)
{ return central44(d1.wrap()); }



/** Defines a stencil ET difference operator "central12n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central12n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central12n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central12n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central12n_et_multi(const central12n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central12n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central12n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central12n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central12n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central12n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central12n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central12n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central12n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central12n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central12n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central12n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-1; maxb[dim]=1;					
  return _bz_ArrayExpr<central12n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central12n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central12n(const Array<T,N>& d1, int comp, int dim)				
{ return central12n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central12n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central12n(Array<T,N>& d1, int comp, int dim)				
{ return central12n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central12n(const Array<T,N>& d1)
{ return central12n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central12n(Array<T,N>& d1)
{ return central12n(d1.wrap()); }



/** Defines a stencil ET difference operator "central22n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central22n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central22n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central22n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central22n_et_multi(const central22n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central22n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central22n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central22n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central22n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central22n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central22n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central22n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central22n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central22n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central22n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central22n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-1; maxb[dim]=1;					
  return _bz_ArrayExpr<central22n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central22n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central22n(const Array<T,N>& d1, int comp, int dim)				
{ return central22n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central22n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central22n(Array<T,N>& d1, int comp, int dim)				
{ return central22n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central22n(const Array<T,N>& d1)
{ return central22n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central22n(Array<T,N>& d1)
{ return central22n(d1.wrap()); }



/** Defines a stencil ET difference operator "central32n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central32n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central32n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central32n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central32n_et_multi(const central32n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central32n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central32n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central32n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central32n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central32n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central32n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central32n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central32n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central32n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central32n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central32n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central32n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central32n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central32n(const Array<T,N>& d1, int comp, int dim)				
{ return central32n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central32n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central32n(Array<T,N>& d1, int comp, int dim)				
{ return central32n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central32n(const Array<T,N>& d1)
{ return central32n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central32n(Array<T,N>& d1)
{ return central32n(d1.wrap()); }



/** Defines a stencil ET difference operator "central42n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central42n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central42n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central42n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central42n_et_multi(const central42n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central42n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central42n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central42n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central42n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central42n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central42n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central42n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central42n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central42n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central42n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central42n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central42n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central42n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central42n(const Array<T,N>& d1, int comp, int dim)				
{ return central42n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central42n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central42n(Array<T,N>& d1, int comp, int dim)				
{ return central42n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central42n(const Array<T,N>& d1)
{ return central42n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central42n(Array<T,N>& d1)
{ return central42n(d1.wrap()); }



/** Defines a stencil ET difference operator "central14n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central14n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central14n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central14n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central14n_et_multi(const central14n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central14n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central14n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central14n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central14n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central14n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central14n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central14n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central14n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central14n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central14n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central14n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central14n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central14n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central14n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central14n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central14n(const Array<T,N>& d1, int comp, int dim)				
{ return central14n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central14n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central14n(Array<T,N>& d1, int comp, int dim)				
{ return central14n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central14n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central14n(const Array<T,N>& d1)
{ return central14n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central14n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central14n(Array<T,N>& d1)
{ return central14n(d1.wrap()); }



/** Defines a stencil ET difference operator "central24n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central24n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central24n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central24n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central24n_et_multi(const central24n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central24n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central24n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central24n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central24n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central24n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central24n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central24n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central24n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central24n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central24n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central24n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central24n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central24n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central24n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central24n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central24n(const Array<T,N>& d1, int comp, int dim)				
{ return central24n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central24n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central24n(Array<T,N>& d1, int comp, int dim)				
{ return central24n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central24n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central24n(const Array<T,N>& d1)
{ return central24n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central24n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central24n(Array<T,N>& d1)
{ return central24n(d1.wrap()); }



/** Defines a stencil ET difference operator "central34n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central34n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central34n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central34n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central34n_et_multi(const central34n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central34n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central34n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central34n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central34n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central34n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central34n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central34n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central34n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central34n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central34n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central34n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central34n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central34n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central34n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central34n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central34n(const Array<T,N>& d1, int comp, int dim)				
{ return central34n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central34n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central34n(Array<T,N>& d1, int comp, int dim)				
{ return central34n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central34n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central34n(const Array<T,N>& d1)
{ return central34n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central34n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central34n(Array<T,N>& d1)
{ return central34n(d1.wrap()); }



/** Defines a stencil ET difference operator "central44n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class central44n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef central44n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  central44n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  central44n_et_multi(const central44n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  central44n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  central44n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return central44n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return central44n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return central44n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = central44n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = central44n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = central44n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef central44n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  central44n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return central44n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<central44n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
central44n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=2;					
  return _bz_ArrayExpr<central44n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<central44n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central44n(const Array<T,N>& d1, int comp, int dim)				
{ return central44n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<central44n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
central44n(Array<T,N>& d1, int comp, int dim)				
{ return central44n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<central44n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central44n(const Array<T,N>& d1)
{ return central44n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<central44n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
central44n(Array<T,N>& d1)
{ return central44n(d1.wrap()); }



/** Defines a stencil ET difference operator "backward11" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward11_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward11_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward11_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward11_et_multi(const backward11_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward11_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward11_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward11_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward11_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward11_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward11_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward11_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward11_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward11_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward11_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward11_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward11_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward11(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-1; maxb[dim]=0;					
  return _bz_ArrayExpr<backward11_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward11_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward11(const Array<T,N>& d1, int comp, int dim)				
{ return backward11(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward11_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward11(Array<T,N>& d1, int comp, int dim)				
{ return backward11(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward11_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward11(const Array<T,N>& d1)
{ return backward11(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward11_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward11(Array<T,N>& d1)
{ return backward11(d1.wrap()); }



/** Defines a stencil ET difference operator "backward21" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward21_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward21_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward21_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward21_et_multi(const backward21_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward21_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward21_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward21_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward21_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward21_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward21_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward21_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward21_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward21_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward21_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward21_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward21_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward21(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=0;					
  return _bz_ArrayExpr<backward21_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward21_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward21(const Array<T,N>& d1, int comp, int dim)				
{ return backward21(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward21_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward21(Array<T,N>& d1, int comp, int dim)				
{ return backward21(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward21_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward21(const Array<T,N>& d1)
{ return backward21(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward21_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward21(Array<T,N>& d1)
{ return backward21(d1.wrap()); }



/** Defines a stencil ET difference operator "backward31" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward31_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward31_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward31_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward31_et_multi(const backward31_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward31_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward31_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward31_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward31_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward31_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward31_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward31_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward31_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward31_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward31_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward31_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward31_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward31(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-3; maxb[dim]=0;					
  return _bz_ArrayExpr<backward31_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward31_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward31(const Array<T,N>& d1, int comp, int dim)				
{ return backward31(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward31_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward31(Array<T,N>& d1, int comp, int dim)				
{ return backward31(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward31_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward31(const Array<T,N>& d1)
{ return backward31(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward31_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward31(Array<T,N>& d1)
{ return backward31(d1.wrap()); }



/** Defines a stencil ET difference operator "backward41" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward41_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward41_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward41_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward41_et_multi(const backward41_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward41_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward41_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward41_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward41_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward41_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward41_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward41_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward41_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward41_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward41_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward41_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward41_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward41(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-4; maxb[dim]=0;					
  return _bz_ArrayExpr<backward41_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward41_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward41(const Array<T,N>& d1, int comp, int dim)				
{ return backward41(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward41_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward41(Array<T,N>& d1, int comp, int dim)				
{ return backward41(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward41_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward41(const Array<T,N>& d1)
{ return backward41(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward41_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward41(Array<T,N>& d1)
{ return backward41(d1.wrap()); }



/** Defines a stencil ET difference operator "backward12" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward12_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward12_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward12_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward12_et_multi(const backward12_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward12_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward12_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward12_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward12_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward12_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward12_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward12_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward12_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward12_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward12_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward12_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward12_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward12(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=0;					
  return _bz_ArrayExpr<backward12_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward12_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward12(const Array<T,N>& d1, int comp, int dim)				
{ return backward12(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward12_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward12(Array<T,N>& d1, int comp, int dim)				
{ return backward12(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward12(const Array<T,N>& d1)
{ return backward12(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward12(Array<T,N>& d1)
{ return backward12(d1.wrap()); }



/** Defines a stencil ET difference operator "backward22" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward22_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward22_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward22_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward22_et_multi(const backward22_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward22_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward22_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward22_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward22_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward22_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward22_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward22_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward22_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward22_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward22_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward22_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward22_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward22(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-3; maxb[dim]=0;					
  return _bz_ArrayExpr<backward22_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward22_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward22(const Array<T,N>& d1, int comp, int dim)				
{ return backward22(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward22_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward22(Array<T,N>& d1, int comp, int dim)				
{ return backward22(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward22(const Array<T,N>& d1)
{ return backward22(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward22(Array<T,N>& d1)
{ return backward22(d1.wrap()); }



/** Defines a stencil ET difference operator "backward32" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward32_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward32_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward32_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward32_et_multi(const backward32_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward32_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward32_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward32_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward32_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward32_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward32_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward32_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward32_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward32_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward32_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward32_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward32_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward32(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-4; maxb[dim]=0;					
  return _bz_ArrayExpr<backward32_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward32_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward32(const Array<T,N>& d1, int comp, int dim)				
{ return backward32(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward32_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward32(Array<T,N>& d1, int comp, int dim)				
{ return backward32(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward32(const Array<T,N>& d1)
{ return backward32(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward32(Array<T,N>& d1)
{ return backward32(d1.wrap()); }



/** Defines a stencil ET difference operator "backward42" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward42_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward42_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward42_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward42_et_multi(const backward42_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward42_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward42_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward42_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward42_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward42_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward42_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward42_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward42_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward42_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward42_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward42_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward42_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward42(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-5; maxb[dim]=0;					
  return _bz_ArrayExpr<backward42_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward42_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward42(const Array<T,N>& d1, int comp, int dim)				
{ return backward42(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward42_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward42(Array<T,N>& d1, int comp, int dim)				
{ return backward42(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward42(const Array<T,N>& d1)
{ return backward42(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward42(Array<T,N>& d1)
{ return backward42(d1.wrap()); }



/** Defines a stencil ET difference operator "backward11n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward11n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward11n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward11n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward11n_et_multi(const backward11n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward11n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward11n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward11n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward11n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward11n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward11n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward11n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward11n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward11n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward11n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward11n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward11n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward11n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-1; maxb[dim]=0;					
  return _bz_ArrayExpr<backward11n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward11n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward11n(const Array<T,N>& d1, int comp, int dim)				
{ return backward11n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward11n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward11n(Array<T,N>& d1, int comp, int dim)				
{ return backward11n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward11n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward11n(const Array<T,N>& d1)
{ return backward11n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward11n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward11n(Array<T,N>& d1)
{ return backward11n(d1.wrap()); }



/** Defines a stencil ET difference operator "backward21n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward21n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward21n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward21n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward21n_et_multi(const backward21n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward21n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward21n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward21n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward21n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward21n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward21n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward21n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward21n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward21n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward21n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward21n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward21n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward21n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=0;					
  return _bz_ArrayExpr<backward21n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward21n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward21n(const Array<T,N>& d1, int comp, int dim)				
{ return backward21n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward21n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward21n(Array<T,N>& d1, int comp, int dim)				
{ return backward21n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward21n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward21n(const Array<T,N>& d1)
{ return backward21n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward21n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward21n(Array<T,N>& d1)
{ return backward21n(d1.wrap()); }



/** Defines a stencil ET difference operator "backward31n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward31n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward31n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward31n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward31n_et_multi(const backward31n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward31n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward31n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward31n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward31n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward31n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward31n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward31n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward31n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward31n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward31n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward31n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward31n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward31n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-3; maxb[dim]=0;					
  return _bz_ArrayExpr<backward31n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward31n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward31n(const Array<T,N>& d1, int comp, int dim)				
{ return backward31n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward31n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward31n(Array<T,N>& d1, int comp, int dim)				
{ return backward31n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward31n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward31n(const Array<T,N>& d1)
{ return backward31n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward31n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward31n(Array<T,N>& d1)
{ return backward31n(d1.wrap()); }



/** Defines a stencil ET difference operator "backward41n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward41n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward41n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward41n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward41n_et_multi(const backward41n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward41n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward41n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward41n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward41n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward41n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward41n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward41n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward41n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward41n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward41n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward41n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward41n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward41n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-4; maxb[dim]=0;					
  return _bz_ArrayExpr<backward41n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward41n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward41n(const Array<T,N>& d1, int comp, int dim)				
{ return backward41n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward41n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward41n(Array<T,N>& d1, int comp, int dim)				
{ return backward41n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward41n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward41n(const Array<T,N>& d1)
{ return backward41n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward41n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward41n(Array<T,N>& d1)
{ return backward41n(d1.wrap()); }



/** Defines a stencil ET difference operator "backward12n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward12n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward12n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward12n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward12n_et_multi(const backward12n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward12n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward12n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward12n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward12n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward12n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward12n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward12n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward12n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward12n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward12n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward12n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-2; maxb[dim]=0;					
  return _bz_ArrayExpr<backward12n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward12n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward12n(const Array<T,N>& d1, int comp, int dim)				
{ return backward12n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward12n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward12n(Array<T,N>& d1, int comp, int dim)				
{ return backward12n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward12n(const Array<T,N>& d1)
{ return backward12n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward12n(Array<T,N>& d1)
{ return backward12n(d1.wrap()); }



/** Defines a stencil ET difference operator "backward22n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward22n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward22n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward22n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward22n_et_multi(const backward22n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward22n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward22n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward22n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward22n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward22n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward22n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward22n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward22n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward22n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward22n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward22n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-3; maxb[dim]=0;					
  return _bz_ArrayExpr<backward22n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward22n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward22n(const Array<T,N>& d1, int comp, int dim)				
{ return backward22n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward22n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward22n(Array<T,N>& d1, int comp, int dim)				
{ return backward22n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward22n(const Array<T,N>& d1)
{ return backward22n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward22n(Array<T,N>& d1)
{ return backward22n(d1.wrap()); }



/** Defines a stencil ET difference operator "backward32n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward32n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward32n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward32n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward32n_et_multi(const backward32n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward32n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward32n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward32n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward32n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward32n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward32n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward32n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward32n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward32n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward32n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward32n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-4; maxb[dim]=0;					
  return _bz_ArrayExpr<backward32n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward32n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward32n(const Array<T,N>& d1, int comp, int dim)				
{ return backward32n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward32n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward32n(Array<T,N>& d1, int comp, int dim)				
{ return backward32n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward32n(const Array<T,N>& d1)
{ return backward32n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward32n(Array<T,N>& d1)
{ return backward32n(d1.wrap()); }



/** Defines a stencil ET difference operator "backward42n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class backward42n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef backward42n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  backward42n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  backward42n_et_multi(const backward42n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  backward42n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  backward42n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return backward42n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return backward42n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return backward42n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = backward42n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = backward42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = backward42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef backward42n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  backward42n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return backward42n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<backward42n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
backward42n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=-5; maxb[dim]=0;					
  return _bz_ArrayExpr<backward42n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<backward42n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward42n(const Array<T,N>& d1, int comp, int dim)				
{ return backward42n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<backward42n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
backward42n(Array<T,N>& d1, int comp, int dim)				
{ return backward42n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<backward42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward42n(const Array<T,N>& d1)
{ return backward42n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<backward42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
backward42n(Array<T,N>& d1)
{ return backward42n(d1.wrap()); }



/** Defines a stencil ET difference operator "forward11" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward11_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward11_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward11_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward11_et_multi(const forward11_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward11_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward11_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward11_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward11_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward11_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward11_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward11_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward11_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward11_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward11_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward11_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward11_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward11(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=1;					
  return _bz_ArrayExpr<forward11_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward11_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward11(const Array<T,N>& d1, int comp, int dim)				
{ return forward11(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward11_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward11(Array<T,N>& d1, int comp, int dim)				
{ return forward11(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward11_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward11(const Array<T,N>& d1)
{ return forward11(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward11_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward11(Array<T,N>& d1)
{ return forward11(d1.wrap()); }



/** Defines a stencil ET difference operator "forward21" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward21_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward21_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward21_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward21_et_multi(const forward21_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward21_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward21_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward21_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward21_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward21_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward21_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward21_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward21_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward21_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward21_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward21_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward21_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward21(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=2;					
  return _bz_ArrayExpr<forward21_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward21_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward21(const Array<T,N>& d1, int comp, int dim)				
{ return forward21(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward21_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward21(Array<T,N>& d1, int comp, int dim)				
{ return forward21(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward21_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward21(const Array<T,N>& d1)
{ return forward21(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward21_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward21(Array<T,N>& d1)
{ return forward21(d1.wrap()); }



/** Defines a stencil ET difference operator "forward31" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward31_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward31_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward31_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward31_et_multi(const forward31_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward31_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward31_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward31_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward31_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward31_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward31_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward31_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward31_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward31_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward31_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward31_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward31_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward31(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=3;					
  return _bz_ArrayExpr<forward31_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward31_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward31(const Array<T,N>& d1, int comp, int dim)				
{ return forward31(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward31_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward31(Array<T,N>& d1, int comp, int dim)				
{ return forward31(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward31_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward31(const Array<T,N>& d1)
{ return forward31(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward31_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward31(Array<T,N>& d1)
{ return forward31(d1.wrap()); }



/** Defines a stencil ET difference operator "forward41" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward41_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward41_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward41_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward41_et_multi(const forward41_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward41_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward41_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward41_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward41_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward41_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward41_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward41_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward41_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward41_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward41_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward41_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward41_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward41(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=4;					
  return _bz_ArrayExpr<forward41_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward41_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward41(const Array<T,N>& d1, int comp, int dim)				
{ return forward41(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward41_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward41(Array<T,N>& d1, int comp, int dim)				
{ return forward41(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward41_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward41(const Array<T,N>& d1)
{ return forward41(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward41_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward41(Array<T,N>& d1)
{ return forward41(d1.wrap()); }



/** Defines a stencil ET difference operator "forward12" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward12_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward12_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward12_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward12_et_multi(const forward12_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward12_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward12_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward12_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward12_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward12_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward12_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward12_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward12_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward12_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward12_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward12_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward12_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward12(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=2;					
  return _bz_ArrayExpr<forward12_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward12_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward12(const Array<T,N>& d1, int comp, int dim)				
{ return forward12(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward12_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward12(Array<T,N>& d1, int comp, int dim)				
{ return forward12(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward12(const Array<T,N>& d1)
{ return forward12(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward12_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward12(Array<T,N>& d1)
{ return forward12(d1.wrap()); }



/** Defines a stencil ET difference operator "forward22" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward22_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward22_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward22_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward22_et_multi(const forward22_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward22_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward22_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward22_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward22_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward22_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward22_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward22_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward22_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward22_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward22_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward22_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward22_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward22(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=3;					
  return _bz_ArrayExpr<forward22_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward22_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward22(const Array<T,N>& d1, int comp, int dim)				
{ return forward22(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward22_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward22(Array<T,N>& d1, int comp, int dim)				
{ return forward22(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward22(const Array<T,N>& d1)
{ return forward22(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward22(Array<T,N>& d1)
{ return forward22(d1.wrap()); }



/** Defines a stencil ET difference operator "forward32" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward32_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward32_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward32_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward32_et_multi(const forward32_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward32_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward32_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward32_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward32_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward32_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward32_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward32_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward32_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward32_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward32_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward32_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward32_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward32(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=4;					
  return _bz_ArrayExpr<forward32_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward32_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward32(const Array<T,N>& d1, int comp, int dim)				
{ return forward32(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward32_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward32(Array<T,N>& d1, int comp, int dim)				
{ return forward32(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward32(const Array<T,N>& d1)
{ return forward32(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward32_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward32(Array<T,N>& d1)
{ return forward32(d1.wrap()); }



/** Defines a stencil ET difference operator "forward42" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward42_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward42_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward42_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward42_et_multi(const forward42_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward42_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward42_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward42_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward42_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward42_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward42_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward42_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward42_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward42_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward42_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward42_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward42_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward42(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=5;					
  return _bz_ArrayExpr<forward42_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward42_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward42(const Array<T,N>& d1, int comp, int dim)				
{ return forward42(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward42_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward42(Array<T,N>& d1, int comp, int dim)				
{ return forward42(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward42(const Array<T,N>& d1)
{ return forward42(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward42_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward42(Array<T,N>& d1)
{ return forward42(d1.wrap()); }



/** Defines a stencil ET difference operator "forward11n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward11n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward11n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward11n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward11n_et_multi(const forward11n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward11n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward11n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward11n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward11n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward11n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward11n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward11n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward11n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward11n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward11n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward11n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward11n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward11n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=1;					
  return _bz_ArrayExpr<forward11n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward11n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward11n(const Array<T,N>& d1, int comp, int dim)				
{ return forward11n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward11n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward11n(Array<T,N>& d1, int comp, int dim)				
{ return forward11n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward11n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward11n(const Array<T,N>& d1)
{ return forward11n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward11n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward11n(Array<T,N>& d1)
{ return forward11n(d1.wrap()); }



/** Defines a stencil ET difference operator "forward21n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward21n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward21n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward21n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward21n_et_multi(const forward21n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward21n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward21n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward21n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward21n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward21n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward21n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward21n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward21n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward21n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward21n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward21n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward21n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward21n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=2;					
  return _bz_ArrayExpr<forward21n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward21n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward21n(const Array<T,N>& d1, int comp, int dim)				
{ return forward21n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward21n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward21n(Array<T,N>& d1, int comp, int dim)				
{ return forward21n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward21n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward21n(const Array<T,N>& d1)
{ return forward21n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward21n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward21n(Array<T,N>& d1)
{ return forward21n(d1.wrap()); }



/** Defines a stencil ET difference operator "forward31n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward31n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward31n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward31n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward31n_et_multi(const forward31n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward31n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward31n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward31n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward31n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward31n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward31n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward31n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward31n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward31n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward31n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward31n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward31n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward31n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=3;					
  return _bz_ArrayExpr<forward31n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward31n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward31n(const Array<T,N>& d1, int comp, int dim)				
{ return forward31n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward31n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward31n(Array<T,N>& d1, int comp, int dim)				
{ return forward31n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward31n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward31n(const Array<T,N>& d1)
{ return forward31n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward31n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward31n(Array<T,N>& d1)
{ return forward31n(d1.wrap()); }



/** Defines a stencil ET difference operator "forward41n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward41n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward41n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward41n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward41n_et_multi(const forward41n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward41n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward41n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward41n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward41n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward41n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward41n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward41n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward41n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward41n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward41n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward41n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward41n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward41n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=4;					
  return _bz_ArrayExpr<forward41n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward41n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward41n(const Array<T,N>& d1, int comp, int dim)				
{ return forward41n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward41n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward41n(Array<T,N>& d1, int comp, int dim)				
{ return forward41n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward41n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward41n(const Array<T,N>& d1)
{ return forward41n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward41n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward41n(Array<T,N>& d1)
{ return forward41n(d1.wrap()); }



/** Defines a stencil ET difference operator "forward12n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward12n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward12n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward12n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward12n_et_multi(const forward12n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward12n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward12n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward12n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward12n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward12n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward12n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward12n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward12n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward12n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward12n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward12n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward12n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=2;					
  return _bz_ArrayExpr<forward12n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward12n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward12n(const Array<T,N>& d1, int comp, int dim)				
{ return forward12n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward12n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward12n(Array<T,N>& d1, int comp, int dim)				
{ return forward12n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward12n(const Array<T,N>& d1)
{ return forward12n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward12n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward12n(Array<T,N>& d1)
{ return forward12n(d1.wrap()); }



/** Defines a stencil ET difference operator "forward22n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward22n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward22n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward22n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward22n_et_multi(const forward22n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward22n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward22n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward22n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward22n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward22n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward22n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward22n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward22n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward22n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward22n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward22n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=3;					
  return _bz_ArrayExpr<forward22n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward22n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward22n(const Array<T,N>& d1, int comp, int dim)				
{ return forward22n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward22n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward22n(Array<T,N>& d1, int comp, int dim)				
{ return forward22n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward22n(const Array<T,N>& d1)
{ return forward22n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward22n(Array<T,N>& d1)
{ return forward22n(d1.wrap()); }



/** Defines a stencil ET difference operator "forward32n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward32n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward32n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward32n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward32n_et_multi(const forward32n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward32n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward32n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward32n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward32n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward32n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward32n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward32n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward32n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward32n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward32n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward32n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward32n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=4;					
  return _bz_ArrayExpr<forward32n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward32n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward32n(const Array<T,N>& d1, int comp, int dim)				
{ return forward32n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward32n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward32n(Array<T,N>& d1, int comp, int dim)				
{ return forward32n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward32n(const Array<T,N>& d1)
{ return forward32n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward32n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward32n(Array<T,N>& d1)
{ return forward32n(d1.wrap()); }



/** Defines a stencil ET difference operator "forward42n" that operates on a
   multicomponent array<P_numtype, N_rank> and returns an
   array<P_numtype::T_element, N_rank>. */
template<typename P_expr>						
class forward42n_et_multi : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:								
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;		
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // T_result, there's no question of whether we could be doing
   // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef forward42n_et_multi<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  forward42n_et_multi<_bz_typename P_expr::T_range_result> T_range_result; 
									
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  forward42n_et_multi(const forward42n_et_multi& a) :		
  _bz_StencilExpr<P_expr, T_numtype>(a), comp_(a.comp_), dim_(a.dim_) 
  { }								

  forward42n_et_multi(BZ_ETPARM(T_expr) a, int comp, int dim) :	
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  forward42n_et_multi(_bz_typename T_expr::T_ctorArg1 a, int comp, int dim) : 
  _bz_StencilExpr<P_expr, T_numtype>(a),			
    comp_(comp), dim_(dim)						
  { }								
									
  T_numtype operator*() const						
  { return forward42n_stencilop(iter_, comp_, dim_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return forward42n_stencilop(iter_, comp_, dim_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), comp_, dim_); }			
									
  T_numtype operator[](int i) const					
  { return forward42n_stencilop(iter_[i], comp_, dim_); }				
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = forward42n_stencilop (iter_, comp_, dim_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),comp_,dim_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = forward42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = forward42n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef forward42n_et_multi<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  forward42n_et_multi							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return forward42n_et_multi						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)),comp_, dim_);			
  }									
									
private:								
  int comp_;								
  int dim_;								
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<forward42n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
forward42n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int comp, int dim)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim]=0; maxb[dim]=5;					
  return _bz_ArrayExpr<forward42n_et_multi<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), comp, dim); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<forward42n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward42n(const Array<T,N>& d1, int comp, int dim)				
{ return forward42n(d1.wrap(), comp, dim); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<forward42n_et_multi<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
forward42n(Array<T,N>& d1, int comp, int dim)				
{ return forward42n(d1.wrap(), comp, dim); }



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<forward42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward42n(const Array<T,N>& d1)
{ return forward42n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<forward42n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
forward42n(Array<T,N>& d1)
{ return forward42n(d1.wrap()); }



/** Defines a stencil ET "Laplacian2D" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-1,-1)-shape(1,1).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class Laplacian2D_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Laplacian2D_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  Laplacian2D_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    Laplacian2D_et(const Laplacian2D_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian2D_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian2D_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return Laplacian2D_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return Laplacian2D_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return Laplacian2D_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = Laplacian2D_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = Laplacian2D_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = Laplacian2D_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "Laplacian2D (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef Laplacian2D_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      Laplacian2D_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return Laplacian2D_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<Laplacian2D_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  Laplacian2D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<Laplacian2D_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian2D_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian2D(const Array<T,N>& d1)						
  { return Laplacian2D(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian2D_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian2D(Array<T,N>& d1)							
   { return Laplacian2D(d1.wrap()); }


/** Defines a stencil ET "Laplacian3D" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-1,-1,-1)-shape(1,1,1).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class Laplacian3D_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Laplacian3D_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  Laplacian3D_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    Laplacian3D_et(const Laplacian3D_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian3D_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian3D_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return Laplacian3D_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return Laplacian3D_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return Laplacian3D_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = Laplacian3D_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = Laplacian3D_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = Laplacian3D_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "Laplacian3D (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef Laplacian3D_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      Laplacian3D_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return Laplacian3D_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<Laplacian3D_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  Laplacian3D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<Laplacian3D_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian3D_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian3D(const Array<T,N>& d1)						
  { return Laplacian3D(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian3D_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian3D(Array<T,N>& d1)							
   { return Laplacian3D(d1.wrap()); }


/** Defines a stencil ET "Laplacian2D4" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-2,-2)-shape(2,2).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class Laplacian2D4_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Laplacian2D4_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  Laplacian2D4_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    Laplacian2D4_et(const Laplacian2D4_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian2D4_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian2D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return Laplacian2D4_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return Laplacian2D4_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return Laplacian2D4_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = Laplacian2D4_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = Laplacian2D4_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = Laplacian2D4_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "Laplacian2D4 (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef Laplacian2D4_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      Laplacian2D4_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return Laplacian2D4_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<Laplacian2D4_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  Laplacian2D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<Laplacian2D4_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian2D4_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian2D4(const Array<T,N>& d1)						
  { return Laplacian2D4(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian2D4_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian2D4(Array<T,N>& d1)							
   { return Laplacian2D4(d1.wrap()); }


/** Defines a stencil ET "Laplacian2D4n" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-2,-2)-shape(2,2).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class Laplacian2D4n_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Laplacian2D4n_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  Laplacian2D4n_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    Laplacian2D4n_et(const Laplacian2D4n_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian2D4n_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian2D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return Laplacian2D4n_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return Laplacian2D4n_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return Laplacian2D4n_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = Laplacian2D4n_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = Laplacian2D4n_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = Laplacian2D4n_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "Laplacian2D4n (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef Laplacian2D4n_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      Laplacian2D4n_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return Laplacian2D4n_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<Laplacian2D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  Laplacian2D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<Laplacian2D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian2D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian2D4n(const Array<T,N>& d1)						
  { return Laplacian2D4n(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian2D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian2D4n(Array<T,N>& d1)							
   { return Laplacian2D4n(d1.wrap()); }


/** Defines a stencil ET "Laplacian3D4" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-2,-2,-2)-shape(2,2,2).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class Laplacian3D4_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Laplacian3D4_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  Laplacian3D4_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    Laplacian3D4_et(const Laplacian3D4_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian3D4_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian3D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return Laplacian3D4_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return Laplacian3D4_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return Laplacian3D4_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = Laplacian3D4_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = Laplacian3D4_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = Laplacian3D4_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "Laplacian3D4 (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef Laplacian3D4_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      Laplacian3D4_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return Laplacian3D4_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<Laplacian3D4_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  Laplacian3D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<Laplacian3D4_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian3D4_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian3D4(const Array<T,N>& d1)						
  { return Laplacian3D4(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian3D4_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian3D4(Array<T,N>& d1)							
   { return Laplacian3D4(d1.wrap()); }


/** Defines a stencil ET "Laplacian3D4n" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-2,-2,-2)-shape(2,2,2).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class Laplacian3D4n_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Laplacian3D4n_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  Laplacian3D4n_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    Laplacian3D4n_et(const Laplacian3D4n_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian3D4n_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    Laplacian3D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return Laplacian3D4n_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return Laplacian3D4n_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return Laplacian3D4n_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = Laplacian3D4n_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = Laplacian3D4n_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = Laplacian3D4n_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "Laplacian3D4n (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef Laplacian3D4n_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      Laplacian3D4n_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return Laplacian3D4n_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<Laplacian3D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  Laplacian3D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<Laplacian3D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian3D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian3D4n(const Array<T,N>& d1)						
  { return Laplacian3D4n(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<Laplacian3D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  Laplacian3D4n(Array<T,N>& d1)							
   { return Laplacian3D4n(d1.wrap()); }


/* Defines a stencil ET "grad2D" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 2> >, N_rank>. */

template<typename P_expr>						
class grad2D_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 2> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef grad2D_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  grad2D_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  grad2D_et(const grad2D_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad2D_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad2D_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return grad2D_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return grad2D_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return grad2D_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = grad2D_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = grad2D_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = grad2D_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef grad2D_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  grad2D_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return grad2D_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<grad2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
grad2D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<grad2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<grad2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad2D(const Array<T,N>& d1)
{ return grad2D(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<grad2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad2D(Array<T,N>& d1)
{ return grad2D(d1.wrap()); }



/* Defines a stencil ET "grad2D4" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 2> >, N_rank>. */

template<typename P_expr>						
class grad2D4_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 2> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef grad2D4_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  grad2D4_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  grad2D4_et(const grad2D4_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad2D4_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad2D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return grad2D4_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return grad2D4_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return grad2D4_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = grad2D4_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = grad2D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = grad2D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef grad2D4_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  grad2D4_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return grad2D4_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<grad2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
grad2D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<grad2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<grad2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad2D4(const Array<T,N>& d1)
{ return grad2D4(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<grad2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad2D4(Array<T,N>& d1)
{ return grad2D4(d1.wrap()); }



/* Defines a stencil ET "grad3D" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 3> >, N_rank>. */

template<typename P_expr>						
class grad3D_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef grad3D_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  grad3D_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  grad3D_et(const grad3D_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad3D_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad3D_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return grad3D_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return grad3D_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return grad3D_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = grad3D_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = grad3D_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = grad3D_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef grad3D_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  grad3D_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return grad3D_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<grad3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
grad3D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<grad3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<grad3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad3D(const Array<T,N>& d1)
{ return grad3D(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<grad3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad3D(Array<T,N>& d1)
{ return grad3D(d1.wrap()); }



/* Defines a stencil ET "grad3D4" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 3> >, N_rank>. */

template<typename P_expr>						
class grad3D4_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef grad3D4_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  grad3D4_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  grad3D4_et(const grad3D4_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad3D4_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad3D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return grad3D4_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return grad3D4_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return grad3D4_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = grad3D4_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = grad3D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = grad3D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef grad3D4_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  grad3D4_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return grad3D4_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<grad3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
grad3D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<grad3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<grad3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad3D4(const Array<T,N>& d1)
{ return grad3D4(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<grad3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad3D4(Array<T,N>& d1)
{ return grad3D4(d1.wrap()); }



/* Defines a stencil ET "grad2Dn" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 2> >, N_rank>. */

template<typename P_expr>						
class grad2Dn_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 2> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef grad2Dn_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  grad2Dn_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  grad2Dn_et(const grad2Dn_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad2Dn_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad2Dn_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return grad2Dn_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return grad2Dn_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return grad2Dn_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = grad2Dn_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = grad2Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = grad2Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef grad2Dn_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  grad2Dn_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return grad2Dn_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<grad2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
grad2Dn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<grad2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<grad2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad2Dn(const Array<T,N>& d1)
{ return grad2Dn(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<grad2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad2Dn(Array<T,N>& d1)
{ return grad2Dn(d1.wrap()); }



/* Defines a stencil ET "grad2D4n" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 2> >, N_rank>. */

template<typename P_expr>						
class grad2D4n_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 2> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef grad2D4n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  grad2D4n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  grad2D4n_et(const grad2D4n_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad2D4n_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad2D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return grad2D4n_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return grad2D4n_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return grad2D4n_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = grad2D4n_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = grad2D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = grad2D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef grad2D4n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  grad2D4n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return grad2D4n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<grad2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
grad2D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<grad2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<grad2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad2D4n(const Array<T,N>& d1)
{ return grad2D4n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<grad2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad2D4n(Array<T,N>& d1)
{ return grad2D4n(d1.wrap()); }



/* Defines a stencil ET "grad3Dn" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 3> >, N_rank>. */

template<typename P_expr>						
class grad3Dn_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef grad3Dn_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  grad3Dn_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  grad3Dn_et(const grad3Dn_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad3Dn_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad3Dn_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return grad3Dn_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return grad3Dn_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return grad3Dn_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = grad3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = grad3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = grad3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef grad3Dn_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  grad3Dn_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return grad3Dn_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<grad3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
grad3Dn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<grad3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<grad3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad3Dn(const Array<T,N>& d1)
{ return grad3Dn(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<grad3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad3Dn(Array<T,N>& d1)
{ return grad3Dn(d1.wrap()); }



/* Defines a stencil ET "grad3D4n" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 3> >, N_rank>. */

template<typename P_expr>						
class grad3D4n_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef grad3D4n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  grad3D4n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  grad3D4n_et(const grad3D4n_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad3D4n_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  grad3D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return grad3D4n_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return grad3D4n_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return grad3D4n_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = grad3D4n_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = grad3D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = grad3D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef grad3D4n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  grad3D4n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return grad3D4n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<grad3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
grad3D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<grad3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<grad3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad3D4n(const Array<T,N>& d1)
{ return grad3D4n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<grad3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
grad3D4n(Array<T,N>& d1)
{ return grad3D4n(d1.wrap()); }



/* Defines a stencil ET "gradSqr2D" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 2> >, N_rank>. */

template<typename P_expr>						
class gradSqr2D_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 2> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef gradSqr2D_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  gradSqr2D_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  gradSqr2D_et(const gradSqr2D_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr2D_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr2D_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return gradSqr2D_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return gradSqr2D_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return gradSqr2D_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = gradSqr2D_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = gradSqr2D_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = gradSqr2D_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef gradSqr2D_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  gradSqr2D_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return gradSqr2D_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<gradSqr2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
gradSqr2D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<gradSqr2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<gradSqr2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr2D(const Array<T,N>& d1)
{ return gradSqr2D(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<gradSqr2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr2D(Array<T,N>& d1)
{ return gradSqr2D(d1.wrap()); }



/* Defines a stencil ET "gradSqr2D4" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 2> >, N_rank>. */

template<typename P_expr>						
class gradSqr2D4_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 2> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef gradSqr2D4_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  gradSqr2D4_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  gradSqr2D4_et(const gradSqr2D4_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr2D4_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr2D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return gradSqr2D4_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return gradSqr2D4_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return gradSqr2D4_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = gradSqr2D4_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = gradSqr2D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = gradSqr2D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef gradSqr2D4_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  gradSqr2D4_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return gradSqr2D4_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<gradSqr2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
gradSqr2D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<gradSqr2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<gradSqr2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr2D4(const Array<T,N>& d1)
{ return gradSqr2D4(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<gradSqr2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr2D4(Array<T,N>& d1)
{ return gradSqr2D4(d1.wrap()); }



/* Defines a stencil ET "gradSqr3D" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 3> >, N_rank>. */

template<typename P_expr>						
class gradSqr3D_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef gradSqr3D_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  gradSqr3D_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  gradSqr3D_et(const gradSqr3D_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr3D_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr3D_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return gradSqr3D_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return gradSqr3D_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return gradSqr3D_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = gradSqr3D_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = gradSqr3D_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = gradSqr3D_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef gradSqr3D_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  gradSqr3D_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return gradSqr3D_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<gradSqr3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
gradSqr3D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<gradSqr3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<gradSqr3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr3D(const Array<T,N>& d1)
{ return gradSqr3D(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<gradSqr3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr3D(Array<T,N>& d1)
{ return gradSqr3D(d1.wrap()); }



/* Defines a stencil ET "gradSqr3D4" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 3> >, N_rank>. */

template<typename P_expr>						
class gradSqr3D4_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef gradSqr3D4_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  gradSqr3D4_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  gradSqr3D4_et(const gradSqr3D4_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr3D4_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr3D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return gradSqr3D4_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return gradSqr3D4_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return gradSqr3D4_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = gradSqr3D4_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = gradSqr3D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = gradSqr3D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef gradSqr3D4_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  gradSqr3D4_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return gradSqr3D4_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<gradSqr3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
gradSqr3D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<gradSqr3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<gradSqr3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr3D4(const Array<T,N>& d1)
{ return gradSqr3D4(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<gradSqr3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr3D4(Array<T,N>& d1)
{ return gradSqr3D4(d1.wrap()); }



/* Defines a stencil ET "gradSqr2Dn" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 2> >, N_rank>. */

template<typename P_expr>						
class gradSqr2Dn_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 2> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef gradSqr2Dn_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  gradSqr2Dn_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  gradSqr2Dn_et(const gradSqr2Dn_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr2Dn_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr2Dn_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return gradSqr2Dn_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return gradSqr2Dn_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return gradSqr2Dn_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = gradSqr2Dn_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = gradSqr2Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = gradSqr2Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef gradSqr2Dn_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  gradSqr2Dn_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return gradSqr2Dn_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<gradSqr2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
gradSqr2Dn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<gradSqr2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<gradSqr2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr2Dn(const Array<T,N>& d1)
{ return gradSqr2Dn(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<gradSqr2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr2Dn(Array<T,N>& d1)
{ return gradSqr2Dn(d1.wrap()); }



/* Defines a stencil ET "gradSqr2D4n" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 2> >, N_rank>. */

template<typename P_expr>						
class gradSqr2D4n_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,2> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 2> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef gradSqr2D4n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  gradSqr2D4n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  gradSqr2D4n_et(const gradSqr2D4n_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr2D4n_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr2D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return gradSqr2D4n_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return gradSqr2D4n_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return gradSqr2D4n_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = gradSqr2D4n_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = gradSqr2D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = gradSqr2D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef gradSqr2D4n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  gradSqr2D4n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return gradSqr2D4n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<gradSqr2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
gradSqr2D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<gradSqr2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<gradSqr2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr2D4n(const Array<T,N>& d1)
{ return gradSqr2D4n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<gradSqr2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr2D4n(Array<T,N>& d1)
{ return gradSqr2D4n(d1.wrap()); }



/* Defines a stencil ET "gradSqr3Dn" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 3> >, N_rank>. */

template<typename P_expr>						
class gradSqr3Dn_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef gradSqr3Dn_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  gradSqr3Dn_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  gradSqr3Dn_et(const gradSqr3Dn_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr3Dn_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr3Dn_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return gradSqr3Dn_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return gradSqr3Dn_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return gradSqr3Dn_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = gradSqr3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = gradSqr3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = gradSqr3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef gradSqr3Dn_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  gradSqr3Dn_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return gradSqr3Dn_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<gradSqr3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
gradSqr3Dn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<gradSqr3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<gradSqr3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr3Dn(const Array<T,N>& d1)
{ return gradSqr3Dn(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<gradSqr3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr3Dn(Array<T,N>& d1)
{ return gradSqr3Dn(d1.wrap()); }



/* Defines a stencil ET "gradSqr3D4n" that operates on a (scalar) array<P_numtype,
   N_rank> and returns a multicomponent
   array<TinyVector<P_numtype::T_element, 3> >, N_rank>. */

template<typename P_expr>						
class gradSqr3D4n_et : public _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyVector<typename P_expr::T_numtype,3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, we assume P_numtype is scalar
  // and that we are returning a TinyVector. This needs to be returned
  // as a FastTVCopyIterator that keeps a copy of the TV it is
  // iterating over, since the result of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTV2CopyIterator<typename P_expr::T_numtype, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef typename T_expr::T_numtype T_optype;

  template<int N> struct tvresult {
    typedef gradSqr3D4n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  gradSqr3D4n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  gradSqr3D4n_et(const gradSqr3D4n_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr3D4n_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  gradSqr3D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  T_result operator*() const					
  { return gradSqr3D4n_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return gradSqr3D4n_stencilop(iter_); }				
									 
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									 
  T_result operator[](int i) const					
  { return gradSqr3D4n_stencilop(iter_[i]); }						
									 
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = gradSqr3D4n_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									
									 
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = gradSqr3D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									 
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = gradSqr3D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef gradSqr3D4n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  gradSqr3D4n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return gradSqr3D4n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */				
template<typename T1>							
inline _bz_ArrayExpr<gradSqr3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
gradSqr3D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<gradSqr3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<gradSqr3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr3D4n(const Array<T,N>& d1)
{ return gradSqr3D4n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<gradSqr3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
gradSqr3D4n(Array<T,N>& d1)
{ return gradSqr3D4n(d1.wrap()); }



/* Defines a stencil ET "Jacobian3D" that operates on an array
   array<P_numtype, N_rank> and returns a multicomponent
   array<TinyMatrix<P_numtype::T_element, rank, rank> >,
   N_rank>. P_numtype can be a TinyVector or a scalar, I think. */

template<typename P_expr>						
class Jacobian3D_et : public _bz_StencilExpr<P_expr, TinyMatrix<_bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyMatrix<_bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, as we are returning a
  // TinyMatrix. This must be returned as a FastTMCopyIterator since the
  // output of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTM2CopyIterator<typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Jacobian3D_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  Jacobian3D_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;						
public:								
  Jacobian3D_et(const Jacobian3D_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
     									
  Jacobian3D_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  Jacobian3D_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
     									
  T_result operator*() const					
  { return Jacobian3D_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return Jacobian3D_stencilop(iter_); }				
     									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
     									
  T_result operator[](int i) const					
  { return Jacobian3D_stencilop(iter_[i]); }						
     									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = Jacobian3D_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
     									
  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = Jacobian3D_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;							
  }									
									 
  T_result shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = Jacobian3D_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;							
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,			
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef Jacobian3D_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  Jacobian3D_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return Jacobian3D_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>						
inline _bz_ArrayExpr<Jacobian3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
Jacobian3D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<Jacobian3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
}								



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<Jacobian3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
Jacobian3D(const Array<T,N>& d1)
{ return Jacobian3D(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<Jacobian3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
Jacobian3D(Array<T,N>& d1)
{ return Jacobian3D(d1.wrap()); }



/* Defines a stencil ET "Jacobian3Dn" that operates on an array
   array<P_numtype, N_rank> and returns a multicomponent
   array<TinyMatrix<P_numtype::T_element, rank, rank> >,
   N_rank>. P_numtype can be a TinyVector or a scalar, I think. */

template<typename P_expr>						
class Jacobian3Dn_et : public _bz_StencilExpr<P_expr, TinyMatrix<_bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyMatrix<_bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, as we are returning a
  // TinyMatrix. This must be returned as a FastTMCopyIterator since the
  // output of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTM2CopyIterator<typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Jacobian3Dn_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  Jacobian3Dn_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;						
public:								
  Jacobian3Dn_et(const Jacobian3Dn_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
     									
  Jacobian3Dn_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  Jacobian3Dn_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
     									
  T_result operator*() const					
  { return Jacobian3Dn_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return Jacobian3Dn_stencilop(iter_); }				
     									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
     									
  T_result operator[](int i) const					
  { return Jacobian3Dn_stencilop(iter_[i]); }						
     									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = Jacobian3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
     									
  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = Jacobian3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;							
  }									
									 
  T_result shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = Jacobian3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;							
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,			
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef Jacobian3Dn_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  Jacobian3Dn_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return Jacobian3Dn_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>						
inline _bz_ArrayExpr<Jacobian3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
Jacobian3Dn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<Jacobian3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
}								



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<Jacobian3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
Jacobian3Dn(const Array<T,N>& d1)
{ return Jacobian3Dn(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<Jacobian3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
Jacobian3Dn(Array<T,N>& d1)
{ return Jacobian3Dn(d1.wrap()); }



/* Defines a stencil ET "Jacobian3D4" that operates on an array
   array<P_numtype, N_rank> and returns a multicomponent
   array<TinyMatrix<P_numtype::T_element, rank, rank> >,
   N_rank>. P_numtype can be a TinyVector or a scalar, I think. */

template<typename P_expr>						
class Jacobian3D4_et : public _bz_StencilExpr<P_expr, TinyMatrix<_bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyMatrix<_bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, as we are returning a
  // TinyMatrix. This must be returned as a FastTMCopyIterator since the
  // output of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTM2CopyIterator<typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Jacobian3D4_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  Jacobian3D4_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;						
public:								
  Jacobian3D4_et(const Jacobian3D4_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
     									
  Jacobian3D4_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  Jacobian3D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
     									
  T_result operator*() const					
  { return Jacobian3D4_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return Jacobian3D4_stencilop(iter_); }				
     									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
     									
  T_result operator[](int i) const					
  { return Jacobian3D4_stencilop(iter_[i]); }						
     									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = Jacobian3D4_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
     									
  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = Jacobian3D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;							
  }									
									 
  T_result shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = Jacobian3D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;							
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,			
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef Jacobian3D4_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  Jacobian3D4_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return Jacobian3D4_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>						
inline _bz_ArrayExpr<Jacobian3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
Jacobian3D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<Jacobian3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
}								



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<Jacobian3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
Jacobian3D4(const Array<T,N>& d1)
{ return Jacobian3D4(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<Jacobian3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
Jacobian3D4(Array<T,N>& d1)
{ return Jacobian3D4(d1.wrap()); }



/* Defines a stencil ET "Jacobian3D4n" that operates on an array
   array<P_numtype, N_rank> and returns a multicomponent
   array<TinyMatrix<P_numtype::T_element, rank, rank> >,
   N_rank>. P_numtype can be a TinyVector or a scalar, I think. */

template<typename P_expr>						
class Jacobian3D4n_et : public _bz_StencilExpr<P_expr, TinyMatrix<_bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > 
{									
public:									
  typedef _bz_StencilExpr<P_expr, TinyMatrix<_bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > T_base; 
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no return type selection, as we are returning a
  // TinyMatrix. This must be returned as a FastTMCopyIterator since the
  // output of the stencil operator is a temporary.
  typedef ETBase<_bz_ArrayExpr<FastTM2CopyIterator<typename multicomponent_traits<typename P_expr::T_numtype>::T_element, 3, 3> > > T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef Jacobian3D4n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

  typedef  Jacobian3D4n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;						
public:								
  Jacobian3D4n_et(const Jacobian3D4n_et& a) :				
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
     									
  Jacobian3D4n_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  Jacobian3D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
     									
  T_result operator*() const					
  { return Jacobian3D4n_stencilop(iter_); }						

  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return Jacobian3D4n_stencilop(iter_); }				
     									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
     									
  T_result operator[](int i) const					
  { return Jacobian3D4n_stencilop(iter_[i]); }						
     									
  T_result fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_result r = Jacobian3D4n_stencilop (iter_);					
    iter_._bz_offsetData(-i);					
    return r;							
  }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
     									
  T_result shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_result r = Jacobian3D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;							
  }									
									 
  T_result shift(int offset1, int dim1, int offset2, int dim2) const 
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = Jacobian3D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;							
  }									
									 
  void prettyPrint(BZ_STD_SCOPE(string) &str,			
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef Jacobian3D4n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  Jacobian3D4n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return Jacobian3D4n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>						
inline _bz_ArrayExpr<Jacobian3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> > 
Jacobian3D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<Jacobian3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
}								



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<Jacobian3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
Jacobian3D4n(const Array<T,N>& d1)
{ return Jacobian3D4n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<Jacobian3D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
Jacobian3D4n(Array<T,N>& d1)
{ return Jacobian3D4n(d1.wrap()); }



/** Defines a stencil ET "curl3D" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-1,-1,-1)-shape(1,1,1).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class curl3D_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef curl3D_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  curl3D_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    curl3D_et(const curl3D_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl3D_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl3D_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return curl3D_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return curl3D_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return curl3D_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = curl3D_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = curl3D_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = curl3D_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "curl3D (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef curl3D_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      curl3D_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return curl3D_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<curl3D_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  curl3D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<curl3D_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl3D_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl3D(const Array<T,N>& d1)						
  { return curl3D(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl3D_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl3D(Array<T,N>& d1)							
   { return curl3D(d1.wrap()); }


/** Defines a stencil ET "curl3Dn" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-1,-1,-1)-shape(1,1,1).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class curl3Dn_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef curl3Dn_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  curl3Dn_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    curl3Dn_et(const curl3Dn_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl3Dn_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl3Dn_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return curl3Dn_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return curl3Dn_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return curl3Dn_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = curl3Dn_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = curl3Dn_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = curl3Dn_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "curl3Dn (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef curl3Dn_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      curl3Dn_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return curl3Dn_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<curl3Dn_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  curl3Dn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<curl3Dn_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl3Dn_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl3Dn(const Array<T,N>& d1)						
  { return curl3Dn(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl3Dn_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl3Dn(Array<T,N>& d1)							
   { return curl3Dn(d1.wrap()); }


/** Defines a stencil ET "curl3D4" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-2,-2,-2)-shape(2,2,2).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class curl3D4_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef curl3D4_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  curl3D4_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    curl3D4_et(const curl3D4_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl3D4_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl3D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return curl3D4_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return curl3D4_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return curl3D4_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = curl3D4_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = curl3D4_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = curl3D4_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "curl3D4 (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef curl3D4_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      curl3D4_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return curl3D4_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<curl3D4_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  curl3D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<curl3D4_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl3D4_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl3D4(const Array<T,N>& d1)						
  { return curl3D4(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl3D4_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl3D4(Array<T,N>& d1)							
   { return curl3D4(d1.wrap()); }


/** Defines a stencil ET "curl3D4n" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-2,-2,-2)-shape(2,2,2).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class curl3D4n_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef curl3D4n_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  curl3D4n_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    curl3D4n_et(const curl3D4n_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl3D4n_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl3D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return curl3D4n_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return curl3D4n_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return curl3D4n_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = curl3D4n_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = curl3D4n_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = curl3D4n_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "curl3D4n (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef curl3D4n_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      curl3D4n_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return curl3D4n_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<curl3D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  curl3D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<curl3D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl3D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl3D4n(const Array<T,N>& d1)						
  { return curl3D4n(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl3D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl3D4n(Array<T,N>& d1)							
   { return curl3D4n(d1.wrap()); }


/** Defines a stencil ET "curl2D" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-1,-1)-shape(1,1).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class curl2D_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef curl2D_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  curl2D_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    curl2D_et(const curl2D_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl2D_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl2D_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return curl2D_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return curl2D_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return curl2D_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = curl2D_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = curl2D_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = curl2D_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "curl2D (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef curl2D_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      curl2D_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return curl2D_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<curl2D_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  curl2D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<curl2D_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl2D_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl2D(const Array<T,N>& d1)						
  { return curl2D(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl2D_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl2D(Array<T,N>& d1)							
   { return curl2D(d1.wrap()); }


/** Defines a stencil ET "curl2Dn" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-1,-1)-shape(1,1).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class curl2Dn_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef curl2Dn_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  curl2Dn_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    curl2Dn_et(const curl2Dn_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl2Dn_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl2Dn_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return curl2Dn_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return curl2Dn_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return curl2Dn_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = curl2Dn_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = curl2Dn_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = curl2Dn_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "curl2Dn (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef curl2Dn_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      curl2Dn_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return curl2Dn_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<curl2Dn_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  curl2Dn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<curl2Dn_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl2Dn_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl2Dn(const Array<T,N>& d1)						
  { return curl2Dn(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl2Dn_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl2Dn(Array<T,N>& d1)							
   { return curl2Dn(d1.wrap()); }


/** Defines a stencil ET "curl2D4" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-2,-2)-shape(2,2).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class curl2D4_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef curl2D4_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  curl2D4_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    curl2D4_et(const curl2D4_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl2D4_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl2D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return curl2D4_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return curl2D4_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return curl2D4_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = curl2D4_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = curl2D4_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = curl2D4_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "curl2D4 (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef curl2D4_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      curl2D4_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return curl2D4_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<curl2D4_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  curl2D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<curl2D4_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl2D4_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl2D4(const Array<T,N>& d1)						
  { return curl2D4(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl2D4_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl2D4(Array<T,N>& d1)							
   { return curl2D4(d1.wrap()); }


/** Defines a stencil ET "curl2D4n" that operates on an Array<P_numtype, N_rank>
   and specifies the return type as Array<T, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. The extent of the stencil is shape(-2,-2)-shape(2,2).
   If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. The stencil ET calls the stencil operator
   name_stencilop, defined in stencilops.h. **/

  template<typename P_expr, _bz_typename P_numtype>			
  class curl2D4n_et : public _bz_StencilExpr<P_expr, P_numtype>		
  {									
  public:								
    typedef _bz_StencilExpr<P_expr, P_numtype> T_base;			
    typedef _bz_typename T_base::T_numtype T_numtype;			
    typedef _bz_typename T_base::T_expr T_expr;				

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef curl2D4n_et<
      typename T_expr::template tvresult<N>::Type,
      T_numtype> Type;
  };

    typedef  curl2D4n_et<_bz_typename P_expr::T_range_result, T_numtype> T_range_result; 
									
    using T_base::iter_;						
    using T_base::rank_;							
  public:								
    curl2D4n_et(const curl2D4n_et& a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl2D4n_et(BZ_ETPARM(T_expr) a) :					
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    curl2D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
    _bz_StencilExpr<P_expr, T_numtype>(a)				
      { }								
									
    T_result operator*() const						
    { return curl2D4n_stencilop(iter_); }						
									
    /* this is not really const, because we don't undo the moveTo, but	
       that should not be visible to outside. It would be if we used	
       some kind of mixed index and stack traversal, but that will	
       screw things up, const or not. */				
    template<int N_rank2>						
      T_result operator()(const TinyVector<int, N_rank2>& i) const	
    { iter_.moveTo(i); return curl2D4n_stencilop(iter_); }    									
    T_range_result operator()(const RectDomain<rank_>& d) const		
    { return T_range_result(iter_(d)); }				
									
    T_result operator[](int i) const					
    { return curl2D4n_stencilop(iter_[i]); }									
    T_result fastRead(diffType i) const				
    {/* this probably isn't very fast... */				
      iter_._bz_offsetData(i);						
      T_result r = curl2D4n_stencilop(iter_);					
      iter_._bz_offsetData(-i);						
      return r;								
    }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }
      
    T_result shift(int offset, int dim) const				
    {									
      iter_._bz_offsetData(offset, dim);				
      T_result r = curl2D4n_stencilop(iter_);					
      iter_._bz_offsetData(-offset, dim);				
      return r;								
    }									
									
    T_result shift(int offset1, int dim1, int offset2, int dim2) const	
    {									
      iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
      T_result r = curl2D4n_stencilop (iter_);					
      iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
      return r;								
    }									
									
    void prettyPrint(BZ_STD_SCOPE(string) &str,				
		     prettyPrintFormat& format) const			
    {									
      str += "curl2D4n (stencil)";						
      str += "(";							
      iter_.prettyPrint(str, format);					
      str += ")";							
    }									
    									
    template<typename T1, typename T2 = nilArraySection,		
      class T3 = nilArraySection, typename T4 = nilArraySection,	
      class T5 = nilArraySection, typename T6 = nilArraySection,	
      class T7 = nilArraySection, typename T8 = nilArraySection,	
      class T9 = nilArraySection, typename T10 = nilArraySection,	
      class T11 = nilArraySection>					
      class SliceInfo {							
      public:								
      typedef curl2D4n_et<T_expr, T_numtype> T_slice;			
      };								
    									
    template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
      typename T7, typename T8, typename T9, typename T10, typename T11> 
      curl2D4n_et							
      operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
    {									
    /* because stencils work inherently in several dimensions it's	
       complicated to slice the domain. slices will be changed to unit	
        ranges instead. slicing stencil result thus *never* changes	
       the rank of the expression, unlike the normal case. */		
      return curl2D4n_et						
	(iter_(_bz_makeRange(r1),					
	       _bz_makeRange(r2),					
	       _bz_makeRange(r3),					
	       _bz_makeRange(r4),					
	       _bz_makeRange(r5),					
	       _bz_makeRange(r6),					
	       _bz_makeRange(r7),					
	       _bz_makeRange(r8),					
	       _bz_makeRange(r9),					
	       _bz_makeRange(r10),					
	       _bz_makeRange(r11)));					
    }									
									
  };									
  /* generate an ET object from an expression */			
  template<typename T1>							
  inline _bz_ArrayExpr<curl2D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
  curl2D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
  {									
    return _bz_ArrayExpr<curl2D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype> > 
      (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
  }									
  /* redirect calls with bare arrays to the main function */		
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl2D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl2D4n(const Array<T,N>& d1)						
  { return curl2D4n(d1.wrap()); }						
									
  template<typename T, int N>						
  inline _bz_ArrayExpr<curl2D4n_et<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, T> > 
  curl2D4n(Array<T,N>& d1)							
   { return curl2D4n(d1.wrap()); }


/** Defines a stencil ET "div2D" that operates on a multicomponent
   array<P_numtype, N_rank> and returns a scalar
   array<P_numtype::T_element, N_rank>. */

template<typename P_expr>						
class div2D_et : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:									
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;			
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // scalar T_result, there's no question of whether we could be doing
  // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef div2D_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  div2D_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  div2D_et(const div2D_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div2D_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div2D_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
    									
  T_numtype operator*() const						
  { return div2D_stencilop(iter_); }						
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return div2D_stencilop(iter_); }				
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									
  T_numtype operator[](int i) const					
  { return div2D_stencilop(iter_[i]); }						
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = div2D_stencilop (iter_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = div2D_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = div2D_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div2D_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div2D_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div2D_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<div2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
div2D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<div2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<div2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div2D(const Array<T,N>& d1)
{ return div2D(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<div2D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div2D(Array<T,N>& d1)
{ return div2D(d1.wrap()); }



/** Defines a stencil ET "div2Dn" that operates on a multicomponent
   array<P_numtype, N_rank> and returns a scalar
   array<P_numtype::T_element, N_rank>. */

template<typename P_expr>						
class div2Dn_et : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:									
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;			
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // scalar T_result, there's no question of whether we could be doing
  // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef div2Dn_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  div2Dn_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  div2Dn_et(const div2Dn_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div2Dn_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div2Dn_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
    									
  T_numtype operator*() const						
  { return div2Dn_stencilop(iter_); }						
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return div2Dn_stencilop(iter_); }				
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									
  T_numtype operator[](int i) const					
  { return div2Dn_stencilop(iter_[i]); }						
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = div2Dn_stencilop (iter_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = div2Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = div2Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div2Dn_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div2Dn_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div2Dn_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<div2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
div2Dn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<div2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<div2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div2Dn(const Array<T,N>& d1)
{ return div2Dn(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<div2Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div2Dn(Array<T,N>& d1)
{ return div2Dn(d1.wrap()); }



/** Defines a stencil ET "div2D4" that operates on a multicomponent
   array<P_numtype, N_rank> and returns a scalar
   array<P_numtype::T_element, N_rank>. */

template<typename P_expr>						
class div2D4_et : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:									
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;			
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // scalar T_result, there's no question of whether we could be doing
  // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef div2D4_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  div2D4_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  div2D4_et(const div2D4_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div2D4_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div2D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
    									
  T_numtype operator*() const						
  { return div2D4_stencilop(iter_); }						
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return div2D4_stencilop(iter_); }				
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									
  T_numtype operator[](int i) const					
  { return div2D4_stencilop(iter_[i]); }						
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = div2D4_stencilop (iter_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = div2D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = div2D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div2D4_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div2D4_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div2D4_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<div2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
div2D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<div2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<div2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div2D4(const Array<T,N>& d1)
{ return div2D4(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<div2D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div2D4(Array<T,N>& d1)
{ return div2D4(d1.wrap()); }



/** Defines a stencil ET "div2D4n" that operates on a multicomponent
   array<P_numtype, N_rank> and returns a scalar
   array<P_numtype::T_element, N_rank>. */

template<typename P_expr>						
class div2D4n_et : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:									
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;			
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // scalar T_result, there's no question of whether we could be doing
  // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef div2D4n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  div2D4n_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  div2D4n_et(const div2D4n_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div2D4n_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div2D4n_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
    									
  T_numtype operator*() const						
  { return div2D4n_stencilop(iter_); }						
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return div2D4n_stencilop(iter_); }				
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									
  T_numtype operator[](int i) const					
  { return div2D4n_stencilop(iter_[i]); }						
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = div2D4n_stencilop (iter_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = div2D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = div2D4n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div2D4n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div2D4n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div2D4n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<div2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
div2D4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<div2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<div2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div2D4n(const Array<T,N>& d1)
{ return div2D4n(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<div2D4n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div2D4n(Array<T,N>& d1)
{ return div2D4n(d1.wrap()); }



/** Defines a stencil ET "div3D" that operates on a multicomponent
   array<P_numtype, N_rank> and returns a scalar
   array<P_numtype::T_element, N_rank>. */

template<typename P_expr>						
class div3D_et : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:									
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;			
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // scalar T_result, there's no question of whether we could be doing
  // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef div3D_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  div3D_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  div3D_et(const div3D_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div3D_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div3D_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
    									
  T_numtype operator*() const						
  { return div3D_stencilop(iter_); }						
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return div3D_stencilop(iter_); }				
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									
  T_numtype operator[](int i) const					
  { return div3D_stencilop(iter_[i]); }						
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = div3D_stencilop (iter_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = div3D_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = div3D_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div3D_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div3D_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div3D_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<div3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
div3D(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<div3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<div3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div3D(const Array<T,N>& d1)
{ return div3D(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<div3D_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div3D(Array<T,N>& d1)
{ return div3D(d1.wrap()); }



/** Defines a stencil ET "div3Dn" that operates on a multicomponent
   array<P_numtype, N_rank> and returns a scalar
   array<P_numtype::T_element, N_rank>. */

template<typename P_expr>						
class div3Dn_et : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:									
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;			
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // scalar T_result, there's no question of whether we could be doing
  // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef div3Dn_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  div3Dn_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  div3Dn_et(const div3Dn_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div3Dn_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div3Dn_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
    									
  T_numtype operator*() const						
  { return div3Dn_stencilop(iter_); }						
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return div3Dn_stencilop(iter_); }				
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									
  T_numtype operator[](int i) const					
  { return div3Dn_stencilop(iter_[i]); }						
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = div3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = div3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = div3Dn_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div3Dn_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div3Dn_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div3Dn_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<div3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
div3Dn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<div3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1,-1), shape(1,1,1)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<div3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div3Dn(const Array<T,N>& d1)
{ return div3Dn(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<div3Dn_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div3Dn(Array<T,N>& d1)
{ return div3Dn(d1.wrap()); }



/** Defines a stencil ET "div3D4" that operates on a multicomponent
   array<P_numtype, N_rank> and returns a scalar
   array<P_numtype::T_element, N_rank>. */

template<typename P_expr>						
class div3D4_et : public _bz_StencilExpr<P_expr, _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element> 
{									
public:									
  typedef _bz_typename multicomponent_traits<typename P_expr::T_numtype>::T_element T_result; 
  typedef _bz_StencilExpr<P_expr, T_result> T_base;			
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

  // there is no selecting return type here. because we *know* it is
  // scalar T_result, there's no question of whether we could be doing
  // multicomponent evaluations.    
  typedef T_result T_typeprop;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef div3D4_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  div3D4_et<_bz_typename P_expr::T_range_result> T_range_result; 
									 
  using T_base::iter_;						
  using T_base::rank_;							
public:								
  div3D4_et(const div3D4_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div3D4_et(BZ_ETPARM(T_expr) a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
									 
  div3D4_et(_bz_typename T_expr::T_ctorArg1 a) :			
  _bz_StencilExpr<P_expr, T_numtype>(a)				
  { }								
    									
  T_numtype operator*() const						
  { return div3D4_stencilop(iter_); }						
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return div3D4_stencilop(iter_); }				
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d)); }				
									
  T_numtype operator[](int i) const					
  { return div3D4_stencilop(iter_[i]); }						
									
  T_numtype fastRead(diffType i) const				
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = div3D4_stencilop (iter_);					
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return iter_.fastRead_tv<N>(i); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = div3D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = div3D4_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div3D4_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div3D4_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div3D4_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
/* create ET from application to expression */			
template<typename T1>							
inline _bz_ArrayExpr<div3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
div3D4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1)				
{									
  return _bz_ArrayExpr<div3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2,-2), shape(2,2,2)))); 
}									



/* Explicit operators for arrays for stencil name. */
template<typename T, int N>						
inline _bz_ArrayExpr<div3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div3D4(const Array<T,N>& d1)
{ return div3D4(d1.wrap()); }

template<typename T, int N>
inline _bz_ArrayExpr<div3D4_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> >
div3D4(Array<T,N>& d1)
{ return div3D4(d1.wrap()); }



/** Defines a stencil "div" ET that operates on two arrays of arbitrary type
   and specifies the return type as array<double, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. */
template<typename P_expr1, typename P_expr2, _bz_typename P_numtype>	
class div_et2 : public _bz_StencilExpr2<P_expr1, P_expr2, P_numtype> 
{									
public:								
  typedef _bz_StencilExpr2<P_expr1, P_expr2, P_numtype> T_base;	
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr1 T_expr1;			
  typedef _bz_typename T_base::T_expr2 T_expr2;			

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  /// dummy
  template<int N> struct tvresult {
    typedef div_et2<
      typename T_expr1::template tvresult<N>::Type,
      typename T_expr2::template tvresult<N>::Type,
      T_numtype> Type; 
  };

  typedef  div_et2<_bz_typename P_expr1::T_range_result, _bz_typename P_expr2::T_range_result, T_numtype> T_range_result; 
									
  using T_base::iter1_;						
  using T_base::iter2_;						
  using T_base::rank_;							
public:								
  div_et2(const div_et2& a) :				
  _bz_StencilExpr2<P_expr1, P_expr2, T_numtype>(a)			
  { }								
									
  div_et2(BZ_ETPARM(T_expr1) a, BZ_ETPARM(T_expr2) b) :		
  _bz_StencilExpr2<P_expr1, P_expr2, T_numtype>(a, b)		
  { }								

  T_result operator*() const						
  { return div_stencilop(iter1_, iter2_); }					
									
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter1_.moveTo(i); iter2_.moveTo(i);
    return div_stencilop(iter1_, iter2_); } 
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter1_(d), iter2_(d)); }			
									
  T_result operator[](int i) const					
  { return div_stencilop(iter1_[i], iter2_[i]); }				
									
  T_result fastRead(diffType i) const					
  {/* this probably isn't very fast... */				
    iter1_._bz_offsetData(i); iter2_._bz_offsetData(i);		
    T_result r = div_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-i); iter2_._bz_offsetData(-i);		
    return r;								
  }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter1_.fastRead_tv<N>(i),
					iter2_.fastRead_tv<N>(i)); }
  
  T_result shift(int offset, int dim) const				
  {									
    iter1_._bz_offsetData(offset, dim);				
    iter2_._bz_offsetData(offset, dim);				
    T_result r = div_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-offset, dim);				
    iter2_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter1_._bz_offsetData(offset1, dim1, offset2, dim2);		
    iter2_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = div_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    iter2_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter1_.prettyPrint(str, format);					
    str += ", ";							
    iter2_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div_et2<T_expr1, T_expr2, T_numtype> T_slice;	
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div_et2							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div_et2						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
									
/* create ET object from application to expression */			
template<typename T1, typename T2>					
inline _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, BZ_PROMOTE(typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype)> > 
div(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1,				
     const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)				
{									
  return _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, BZ_PROMOTE(typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype)> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1))), 
     BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap())(_bz_shrinkDomain(d2.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
}									
/* matches to calls involving bare arrays (this is very annoying	
   because we have to exactly match every possible call combination	
   to ensure that this matches instead of the operator in		
   stencilops.h) */							
template<typename T1, typename T2, int N2>				
inline _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, Array<T2,N2>& d2)		
{ return div(d1.wrap(), d2.wrap()); }				
									
template<typename T1, typename T2, int N2>				
inline _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, const Array<T2,N2>& d2)	
{ return div(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2>				
inline _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, double> > 
div(Array<T1,N1>& d1, const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)		
{ return div(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2>				
inline _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, double> > 
div(const Array<T1,N1>& d1, const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)	
{ return div(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2, int N2>			
inline _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div(const Array<T1,N1>& d1, Array<T2,N2>& d2)				
{ return div(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2, int N2>			
inline _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div(Array<T1,N1>& d1, const Array<T2,N2>& d2)			
{ return div(d1.wrap(), d2.wrap()); }				
  									
template<typename T, int N>						
inline _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, double> > 
div(Array<T,N>& d1, Array<T,N>& d2)					
{ return div(d1.wrap(), d2.wrap()); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<div_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, double> > 
div(const Array<T,N>& d1, const Array<T,N>& d2)			
{ return div(d1.wrap(), d2.wrap()); }


/** Defines a stencil "divn" ET that operates on two arrays of arbitrary type
   and specifies the return type as array<double, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. */
template<typename P_expr1, typename P_expr2, _bz_typename P_numtype>	
class divn_et2 : public _bz_StencilExpr2<P_expr1, P_expr2, P_numtype> 
{									
public:								
  typedef _bz_StencilExpr2<P_expr1, P_expr2, P_numtype> T_base;	
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr1 T_expr1;			
  typedef _bz_typename T_base::T_expr2 T_expr2;			

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  /// dummy
  template<int N> struct tvresult {
    typedef divn_et2<
      typename T_expr1::template tvresult<N>::Type,
      typename T_expr2::template tvresult<N>::Type,
      T_numtype> Type; 
  };

  typedef  divn_et2<_bz_typename P_expr1::T_range_result, _bz_typename P_expr2::T_range_result, T_numtype> T_range_result; 
									
  using T_base::iter1_;						
  using T_base::iter2_;						
  using T_base::rank_;							
public:								
  divn_et2(const divn_et2& a) :				
  _bz_StencilExpr2<P_expr1, P_expr2, T_numtype>(a)			
  { }								
									
  divn_et2(BZ_ETPARM(T_expr1) a, BZ_ETPARM(T_expr2) b) :		
  _bz_StencilExpr2<P_expr1, P_expr2, T_numtype>(a, b)		
  { }								

  T_result operator*() const						
  { return divn_stencilop(iter1_, iter2_); }					
									
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter1_.moveTo(i); iter2_.moveTo(i);
    return divn_stencilop(iter1_, iter2_); } 
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter1_(d), iter2_(d)); }			
									
  T_result operator[](int i) const					
  { return divn_stencilop(iter1_[i], iter2_[i]); }				
									
  T_result fastRead(diffType i) const					
  {/* this probably isn't very fast... */				
    iter1_._bz_offsetData(i); iter2_._bz_offsetData(i);		
    T_result r = divn_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-i); iter2_._bz_offsetData(-i);		
    return r;								
  }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter1_.fastRead_tv<N>(i),
					iter2_.fastRead_tv<N>(i)); }
  
  T_result shift(int offset, int dim) const				
  {									
    iter1_._bz_offsetData(offset, dim);				
    iter2_._bz_offsetData(offset, dim);				
    T_result r = divn_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-offset, dim);				
    iter2_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter1_._bz_offsetData(offset1, dim1, offset2, dim2);		
    iter2_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = divn_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    iter2_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter1_.prettyPrint(str, format);					
    str += ", ";							
    iter2_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef divn_et2<T_expr1, T_expr2, T_numtype> T_slice;	
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  divn_et2							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return divn_et2						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
									
/* create ET object from application to expression */			
template<typename T1, typename T2>					
inline _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, BZ_PROMOTE(typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype)> > 
divn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1,				
     const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)				
{									
  return _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, BZ_PROMOTE(typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype)> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-1,-1), shape(1,1))), 
     BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap())(_bz_shrinkDomain(d2.unwrap().domain(),shape(-1,-1), shape(1,1)))); 
}									
/* matches to calls involving bare arrays (this is very annoying	
   because we have to exactly match every possible call combination	
   to ensure that this matches instead of the operator in		
   stencilops.h) */							
template<typename T1, typename T2, int N2>				
inline _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
divn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, Array<T2,N2>& d2)		
{ return divn(d1.wrap(), d2.wrap()); }				
									
template<typename T1, typename T2, int N2>				
inline _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
divn(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, const Array<T2,N2>& d2)	
{ return divn(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2>				
inline _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, double> > 
divn(Array<T1,N1>& d1, const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)		
{ return divn(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2>				
inline _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, double> > 
divn(const Array<T1,N1>& d1, const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)	
{ return divn(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2, int N2>			
inline _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
divn(const Array<T1,N1>& d1, Array<T2,N2>& d2)				
{ return divn(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2, int N2>			
inline _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
divn(Array<T1,N1>& d1, const Array<T2,N2>& d2)			
{ return divn(d1.wrap(), d2.wrap()); }				
  									
template<typename T, int N>						
inline _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, double> > 
divn(Array<T,N>& d1, Array<T,N>& d2)					
{ return divn(d1.wrap(), d2.wrap()); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<divn_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, double> > 
divn(const Array<T,N>& d1, const Array<T,N>& d2)			
{ return divn(d1.wrap(), d2.wrap()); }


/** Defines a stencil "div4" ET that operates on two arrays of arbitrary type
   and specifies the return type as array<double, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. */
template<typename P_expr1, typename P_expr2, _bz_typename P_numtype>	
class div4_et2 : public _bz_StencilExpr2<P_expr1, P_expr2, P_numtype> 
{									
public:								
  typedef _bz_StencilExpr2<P_expr1, P_expr2, P_numtype> T_base;	
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr1 T_expr1;			
  typedef _bz_typename T_base::T_expr2 T_expr2;			

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  /// dummy
  template<int N> struct tvresult {
    typedef div4_et2<
      typename T_expr1::template tvresult<N>::Type,
      typename T_expr2::template tvresult<N>::Type,
      T_numtype> Type; 
  };

  typedef  div4_et2<_bz_typename P_expr1::T_range_result, _bz_typename P_expr2::T_range_result, T_numtype> T_range_result; 
									
  using T_base::iter1_;						
  using T_base::iter2_;						
  using T_base::rank_;							
public:								
  div4_et2(const div4_et2& a) :				
  _bz_StencilExpr2<P_expr1, P_expr2, T_numtype>(a)			
  { }								
									
  div4_et2(BZ_ETPARM(T_expr1) a, BZ_ETPARM(T_expr2) b) :		
  _bz_StencilExpr2<P_expr1, P_expr2, T_numtype>(a, b)		
  { }								

  T_result operator*() const						
  { return div4_stencilop(iter1_, iter2_); }					
									
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter1_.moveTo(i); iter2_.moveTo(i);
    return div4_stencilop(iter1_, iter2_); } 
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter1_(d), iter2_(d)); }			
									
  T_result operator[](int i) const					
  { return div4_stencilop(iter1_[i], iter2_[i]); }				
									
  T_result fastRead(diffType i) const					
  {/* this probably isn't very fast... */				
    iter1_._bz_offsetData(i); iter2_._bz_offsetData(i);		
    T_result r = div4_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-i); iter2_._bz_offsetData(-i);		
    return r;								
  }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter1_.fastRead_tv<N>(i),
					iter2_.fastRead_tv<N>(i)); }
  
  T_result shift(int offset, int dim) const				
  {									
    iter1_._bz_offsetData(offset, dim);				
    iter2_._bz_offsetData(offset, dim);				
    T_result r = div4_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-offset, dim);				
    iter2_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter1_._bz_offsetData(offset1, dim1, offset2, dim2);		
    iter2_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = div4_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    iter2_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter1_.prettyPrint(str, format);					
    str += ", ";							
    iter2_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div4_et2<T_expr1, T_expr2, T_numtype> T_slice;	
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div4_et2							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div4_et2						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
									
/* create ET object from application to expression */			
template<typename T1, typename T2>					
inline _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, BZ_PROMOTE(typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype)> > 
div4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1,				
     const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)				
{									
  return _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, BZ_PROMOTE(typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype)> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2))), 
     BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap())(_bz_shrinkDomain(d2.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
}									
/* matches to calls involving bare arrays (this is very annoying	
   because we have to exactly match every possible call combination	
   to ensure that this matches instead of the operator in		
   stencilops.h) */							
template<typename T1, typename T2, int N2>				
inline _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, Array<T2,N2>& d2)		
{ return div4(d1.wrap(), d2.wrap()); }				
									
template<typename T1, typename T2, int N2>				
inline _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div4(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, const Array<T2,N2>& d2)	
{ return div4(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2>				
inline _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, double> > 
div4(Array<T1,N1>& d1, const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)		
{ return div4(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2>				
inline _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, double> > 
div4(const Array<T1,N1>& d1, const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)	
{ return div4(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2, int N2>			
inline _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div4(const Array<T1,N1>& d1, Array<T2,N2>& d2)				
{ return div4(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2, int N2>			
inline _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div4(Array<T1,N1>& d1, const Array<T2,N2>& d2)			
{ return div4(d1.wrap(), d2.wrap()); }				
  									
template<typename T, int N>						
inline _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, double> > 
div4(Array<T,N>& d1, Array<T,N>& d2)					
{ return div4(d1.wrap(), d2.wrap()); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<div4_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, double> > 
div4(const Array<T,N>& d1, const Array<T,N>& d2)			
{ return div4(d1.wrap(), d2.wrap()); }


/** Defines a stencil "div4n" ET that operates on two arrays of arbitrary type
   and specifies the return type as array<double, N_rank>. The result
   type is used when running on an array and the etresult type when
   running on an expression. If you want to refer to the native type
   of the expression, set result="P_numtype" and etresult="typename
   T1::T_numtype". Sorry for that ugliness, but they define types
   differently. */
template<typename P_expr1, typename P_expr2, _bz_typename P_numtype>	
class div4n_et2 : public _bz_StencilExpr2<P_expr1, P_expr2, P_numtype> 
{									
public:								
  typedef _bz_StencilExpr2<P_expr1, P_expr2, P_numtype> T_base;	
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr1 T_expr1;			
  typedef _bz_typename T_base::T_expr2 T_expr2;			

  // if P_numtype is an ET-type, we need to return an expr
  typedef typename selectET<P_numtype,
			    T_numtype, 
      ETBase<_bz_ArrayExpr<_bz_ArrayExprConstant<P_numtype> > > >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  /// dummy
  template<int N> struct tvresult {
    typedef div4n_et2<
      typename T_expr1::template tvresult<N>::Type,
      typename T_expr2::template tvresult<N>::Type,
      T_numtype> Type; 
  };

  typedef  div4n_et2<_bz_typename P_expr1::T_range_result, _bz_typename P_expr2::T_range_result, T_numtype> T_range_result; 
									
  using T_base::iter1_;						
  using T_base::iter2_;						
  using T_base::rank_;							
public:								
  div4n_et2(const div4n_et2& a) :				
  _bz_StencilExpr2<P_expr1, P_expr2, T_numtype>(a)			
  { }								
									
  div4n_et2(BZ_ETPARM(T_expr1) a, BZ_ETPARM(T_expr2) b) :		
  _bz_StencilExpr2<P_expr1, P_expr2, T_numtype>(a, b)		
  { }								

  T_result operator*() const						
  { return div4n_stencilop(iter1_, iter2_); }					
									
  T_result operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter1_.moveTo(i); iter2_.moveTo(i);
    return div4n_stencilop(iter1_, iter2_); } 
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter1_(d), iter2_(d)); }			
									
  T_result operator[](int i) const					
  { return div4n_stencilop(iter1_[i], iter2_[i]); }				
									
  T_result fastRead(diffType i) const					
  {/* this probably isn't very fast... */				
    iter1_._bz_offsetData(i); iter2_._bz_offsetData(i);		
    T_result r = div4n_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-i); iter2_._bz_offsetData(-i);		
    return r;								
  }									

    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter1_.fastRead_tv<N>(i),
					iter2_.fastRead_tv<N>(i)); }
  
  T_result shift(int offset, int dim) const				
  {									
    iter1_._bz_offsetData(offset, dim);				
    iter2_._bz_offsetData(offset, dim);				
    T_result r = div4n_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-offset, dim);				
    iter2_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_result shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter1_._bz_offsetData(offset1, dim1, offset2, dim2);		
    iter2_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_result r = div4n_stencilop (iter1_, iter2_);				
    iter1_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    iter2_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter1_.prettyPrint(str, format);					
    str += ", ";							
    iter2_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef div4n_et2<T_expr1, T_expr2, T_numtype> T_slice;	
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  div4n_et2							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return div4n_et2						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)));					
  }									
};									
									
/* create ET object from application to expression */			
template<typename T1, typename T2>					
inline _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, BZ_PROMOTE(typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype)> > 
div4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1,				
     const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)				
{									
  return _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, BZ_PROMOTE(typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_numtype, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_numtype)> > 
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),shape(-2,-2), shape(2,2))), 
     BZ_BLITZ_SCOPE(asExpr)<T2>::getExpr(d2.unwrap())(_bz_shrinkDomain(d2.unwrap().domain(),shape(-2,-2), shape(2,2)))); 
}									
/* matches to calls involving bare arrays (this is very annoying	
   because we have to exactly match every possible call combination	
   to ensure that this matches instead of the operator in		
   stencilops.h) */							
template<typename T1, typename T2, int N2>				
inline _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, Array<T2,N2>& d2)		
{ return div4n(d1.wrap(), d2.wrap()); }				
									
template<typename T1, typename T2, int N2>				
inline _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div4n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, const Array<T2,N2>& d2)	
{ return div4n(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2>				
inline _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, double> > 
div4n(Array<T1,N1>& d1, const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)		
{ return div4n(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2>				
inline _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<T2>::T_expr::T_range_result, double> > 
div4n(const Array<T1,N1>& d1, const BZ_BLITZ_SCOPE(ETBase)<T2>& d2)	
{ return div4n(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2, int N2>			
inline _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div4n(const Array<T1,N1>& d1, Array<T2,N2>& d2)				
{ return div4n(d1.wrap(), d2.wrap()); }				
									
template<typename T1, int N1, typename T2, int N2>			
inline _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T1,N1> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T2,N2> >::T_expr::T_range_result, double> > 
div4n(Array<T1,N1>& d1, const Array<T2,N2>& d2)			
{ return div4n(d1.wrap(), d2.wrap()); }				
  									
template<typename T, int N>						
inline _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, double> > 
div4n(Array<T,N>& d1, Array<T,N>& d2)					
{ return div4n(d1.wrap(), d2.wrap()); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<div4n_et2<typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result, double> > 
div4n(const Array<T,N>& d1, const Array<T,N>& d2)			
{ return div4n(d1.wrap(), d2.wrap()); }


/** Defines a stencil ET double-difference operator "mixed22" that
   operates on an array<P_numtype, N_rank> and returns an array of
   identical type. (The only significance of the "double-difference" aspect
   is that the operator is assumed to take two extra arguments which
   are the dimensions to do the differences in). */

template<typename P_expr>						
class mixed22_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> 
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base;	
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    mixed22_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef mixed22_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  mixed22_et<_bz_typename P_expr::T_range_result> T_range_result; 
   									
  using T_base::iter_;							
  using T_base::rank_;							
public:								
  mixed22_et(const mixed22_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(a.dim1_), dim2_(a.dim2_)					
  { }								
   									
  mixed22_et(BZ_ETPARM(T_expr) a, int dim1, int dim2) :		
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(dim1), dim2_(dim2)						
  { }									
   									
  mixed22_et(_bz_typename T_expr::T_ctorArg1 a,			
	      int dim1, int dim2) :					
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(dim1), dim2_(dim2)						
  { }									
   									
  T_numtype operator*() const						
  { return mixed22_stencilop(iter_, dim1_, dim2_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return mixed22_stencilop(iter_, dim1_, dim2_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim1_, dim2_); }			
   									
  T_numtype operator[](int i) const					
  { return mixed22_stencilop(iter_[i], dim1_, dim2_); }				
									
  T_numtype fastRead(diffType i) const					
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = mixed22_stencilop (iter_, dim1_, dim2_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim1_,dim2_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = mixed22_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = mixed22_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef mixed22_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  mixed22_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return mixed22_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)), dim1_, dim2_);			
  }									
   									
private:								
  int dim1_, dim2_;							
};									
 									
/* create ET from application to expression */
template<typename T1>							
inline _bz_ArrayExpr<mixed22_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
mixed22(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim1, int dim2)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim1]=-1; maxb[dim1]=1;					
  minb[dim2]=-1; maxb[dim2]=1;					
  return _bz_ArrayExpr<mixed22_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim1, dim2); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<mixed22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
mixed22(const Array<T,N>& d1, int dim1, int dim2)			
{ return mixed22(d1.wrap(), dim1, dim2); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<mixed22_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
mixed22(Array<T,N>& d1, int dim1, int dim2)				
{ return mixed22(d1.wrap(), dim1, dim2); }



/** Defines a stencil ET double-difference operator "mixed22n" that
   operates on an array<P_numtype, N_rank> and returns an array of
   identical type. (The only significance of the "double-difference" aspect
   is that the operator is assumed to take two extra arguments which
   are the dimensions to do the differences in). */

template<typename P_expr>						
class mixed22n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> 
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base;	
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    mixed22n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef mixed22n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  mixed22n_et<_bz_typename P_expr::T_range_result> T_range_result; 
   									
  using T_base::iter_;							
  using T_base::rank_;							
public:								
  mixed22n_et(const mixed22n_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(a.dim1_), dim2_(a.dim2_)					
  { }								
   									
  mixed22n_et(BZ_ETPARM(T_expr) a, int dim1, int dim2) :		
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(dim1), dim2_(dim2)						
  { }									
   									
  mixed22n_et(_bz_typename T_expr::T_ctorArg1 a,			
	      int dim1, int dim2) :					
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(dim1), dim2_(dim2)						
  { }									
   									
  T_numtype operator*() const						
  { return mixed22n_stencilop(iter_, dim1_, dim2_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return mixed22n_stencilop(iter_, dim1_, dim2_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim1_, dim2_); }			
   									
  T_numtype operator[](int i) const					
  { return mixed22n_stencilop(iter_[i], dim1_, dim2_); }				
									
  T_numtype fastRead(diffType i) const					
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = mixed22n_stencilop (iter_, dim1_, dim2_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim1_,dim2_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = mixed22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = mixed22n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef mixed22n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  mixed22n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return mixed22n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)), dim1_, dim2_);			
  }									
   									
private:								
  int dim1_, dim2_;							
};									
 									
/* create ET from application to expression */
template<typename T1>							
inline _bz_ArrayExpr<mixed22n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
mixed22n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim1, int dim2)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim1]=-1; maxb[dim1]=1;					
  minb[dim2]=-1; maxb[dim2]=1;					
  return _bz_ArrayExpr<mixed22n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim1, dim2); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<mixed22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
mixed22n(const Array<T,N>& d1, int dim1, int dim2)			
{ return mixed22n(d1.wrap(), dim1, dim2); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<mixed22n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
mixed22n(Array<T,N>& d1, int dim1, int dim2)				
{ return mixed22n(d1.wrap(), dim1, dim2); }



/** Defines a stencil ET double-difference operator "mixed24" that
   operates on an array<P_numtype, N_rank> and returns an array of
   identical type. (The only significance of the "double-difference" aspect
   is that the operator is assumed to take two extra arguments which
   are the dimensions to do the differences in). */

template<typename P_expr>						
class mixed24_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> 
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base;	
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    mixed24_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef mixed24_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  mixed24_et<_bz_typename P_expr::T_range_result> T_range_result; 
   									
  using T_base::iter_;							
  using T_base::rank_;							
public:								
  mixed24_et(const mixed24_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(a.dim1_), dim2_(a.dim2_)					
  { }								
   									
  mixed24_et(BZ_ETPARM(T_expr) a, int dim1, int dim2) :		
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(dim1), dim2_(dim2)						
  { }									
   									
  mixed24_et(_bz_typename T_expr::T_ctorArg1 a,			
	      int dim1, int dim2) :					
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(dim1), dim2_(dim2)						
  { }									
   									
  T_numtype operator*() const						
  { return mixed24_stencilop(iter_, dim1_, dim2_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return mixed24_stencilop(iter_, dim1_, dim2_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim1_, dim2_); }			
   									
  T_numtype operator[](int i) const					
  { return mixed24_stencilop(iter_[i], dim1_, dim2_); }				
									
  T_numtype fastRead(diffType i) const					
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = mixed24_stencilop (iter_, dim1_, dim2_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim1_,dim2_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = mixed24_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = mixed24_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef mixed24_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  mixed24_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return mixed24_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)), dim1_, dim2_);			
  }									
   									
private:								
  int dim1_, dim2_;							
};									
 									
/* create ET from application to expression */
template<typename T1>							
inline _bz_ArrayExpr<mixed24_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
mixed24(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim1, int dim2)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim1]=-2; maxb[dim1]=2;					
  minb[dim2]=-2; maxb[dim2]=2;					
  return _bz_ArrayExpr<mixed24_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim1, dim2); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<mixed24_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
mixed24(const Array<T,N>& d1, int dim1, int dim2)			
{ return mixed24(d1.wrap(), dim1, dim2); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<mixed24_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
mixed24(Array<T,N>& d1, int dim1, int dim2)				
{ return mixed24(d1.wrap(), dim1, dim2); }



/** Defines a stencil ET double-difference operator "mixed24n" that
   operates on an array<P_numtype, N_rank> and returns an array of
   identical type. (The only significance of the "double-difference" aspect
   is that the operator is assumed to take two extra arguments which
   are the dimensions to do the differences in). */

template<typename P_expr>						
class mixed24n_et : public _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> 
{									
public:								
  typedef _bz_StencilExpr<P_expr, _bz_typename P_expr::T_numtype> T_base;	
  typedef _bz_typename T_base::T_numtype T_numtype;			
  typedef _bz_typename T_base::T_expr T_expr;				

    // select return type
  typedef typename unwrapET<typename T_expr::T_result>::T_unwrapped test;
  typedef typename selectET<typename T_expr::T_typeprop, 
			    T_numtype, 
			    mixed24n_et<test> >::T_selected T_typeprop;
  typedef typename unwrapET<T_typeprop>::T_unwrapped T_result;
  typedef T_numtype T_optype;

  template<int N> struct tvresult {
    typedef mixed24n_et<
      typename T_expr::template tvresult<N>::Type> Type;
  };

typedef  mixed24n_et<_bz_typename P_expr::T_range_result> T_range_result; 
   									
  using T_base::iter_;							
  using T_base::rank_;							
public:								
  mixed24n_et(const mixed24n_et& a) :					
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(a.dim1_), dim2_(a.dim2_)					
  { }								
   									
  mixed24n_et(BZ_ETPARM(T_expr) a, int dim1, int dim2) :		
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(dim1), dim2_(dim2)						
  { }									
   									
  mixed24n_et(_bz_typename T_expr::T_ctorArg1 a,			
	      int dim1, int dim2) :					
  _bz_StencilExpr<P_expr, T_numtype>(a),				
    dim1_(dim1), dim2_(dim2)						
  { }									
   									
  T_numtype operator*() const						
  { return mixed24n_stencilop(iter_, dim1_, dim2_); }				
  T_numtype operator()(_bz_typename _bz_IndexParameter<TinyVector<int, rank_> >::type i) const 
  { iter_.moveTo(i); return mixed24n_stencilop(iter_, dim1_, dim2_); }		
									
  T_range_result operator()(const RectDomain<rank_>& d) const		
  { return T_range_result(iter_(d), dim1_, dim2_); }			
   									
  T_numtype operator[](int i) const					
  { return mixed24n_stencilop(iter_[i], dim1_, dim2_); }				
									
  T_numtype fastRead(diffType i) const					
  {/* this probably isn't very fast... */				
    iter_._bz_offsetData(i);						
    T_numtype r = mixed24n_stencilop (iter_, dim1_, dim2_);				
    iter_._bz_offsetData(-i);						
    return r;								
  }									
									
    /** This way of vectorizing won't work on stencils. */
    template<int N>
    typename tvresult<N>::Type fastRead_tv(diffType i) const {
      BZPRECHECK(0, "Can't vectorize stencils");
      return typename tvresult<N>::Type(iter_.fastRead_tv<N>(i),dim1_,dim2_); }

  T_numtype shift(int offset, int dim) const				
  {									
    iter_._bz_offsetData(offset, dim);				
    T_numtype r = mixed24n_stencilop (iter_);					
    iter_._bz_offsetData(-offset, dim);				
    return r;								
  }									
									
  T_numtype shift(int offset1, int dim1, int offset2, int dim2) const	
  {									
    iter_._bz_offsetData(offset1, dim1, offset2, dim2);		
    T_numtype r = mixed24n_stencilop (iter_);					
    iter_._bz_offsetData(-offset1, dim1, -offset2, dim2);		
    return r;								
  }									
									
  void prettyPrint(BZ_STD_SCOPE(string) &str,				
		   prettyPrintFormat& format) const			
  {									
    str += "name (stencil)";						
    str += "(";							
    iter_.prettyPrint(str, format);					
    str += ")";							
  }									
									
  template<typename T1, typename T2 = nilArraySection,		
	   class T3 = nilArraySection, typename T4 = nilArraySection,	
	   class T5 = nilArraySection, typename T6 = nilArraySection,	
	   class T7 = nilArraySection, typename T8 = nilArraySection,	
	   class T9 = nilArraySection, typename T10 = nilArraySection,	
	   class T11 = nilArraySection>					
  class SliceInfo {							
  public:								
    typedef mixed24n_et<T_expr> T_slice;				
  };								
    									
  template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, 
	   typename T7, typename T8, typename T9, typename T10, typename T11> 
  mixed24n_et							
  operator()(T1 r1, T2 r2, T3 r3, T4 r4, T5 r5, T6 r6, T7 r7, T8 r8, T9 r9, T10 r10, T11 r11) const 
  {									
    return mixed24n_et						
      (iter_(_bz_makeRange(r1),					
	     _bz_makeRange(r2),					
	     _bz_makeRange(r3),					
	     _bz_makeRange(r4),					
	     _bz_makeRange(r5),					
	     _bz_makeRange(r6),					
	     _bz_makeRange(r7),					
	     _bz_makeRange(r8),					
	     _bz_makeRange(r9),					
	     _bz_makeRange(r10),					
	     _bz_makeRange(r11)), dim1_, dim2_);			
  }									
   									
private:								
  int dim1_, dim2_;							
};									
 									
/* create ET from application to expression */
template<typename T1>							
inline _bz_ArrayExpr<mixed24n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
mixed24n(const BZ_BLITZ_SCOPE(ETBase)<T1>& d1, int dim1, int dim2)		
{									
  TinyVector<int, BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::rank_> minb(0), maxb(0);	
  minb[dim1]=-2; maxb[dim1]=2;					
  minb[dim2]=-2; maxb[dim2]=2;					
  return _bz_ArrayExpr<mixed24n_et<typename BZ_BLITZ_SCOPE(asExpr)<T1>::T_expr::T_range_result> >	
    (BZ_BLITZ_SCOPE(asExpr)<T1>::getExpr(d1.unwrap())(_bz_shrinkDomain(d1.unwrap().domain(),minb, maxb)), dim1, dim2); 
}									
/* forward operations on arrays to main function */			
template<typename T, int N>						
inline _bz_ArrayExpr<mixed24n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
mixed24n(const Array<T,N>& d1, int dim1, int dim2)			
{ return mixed24n(d1.wrap(), dim1, dim2); }				
									
template<typename T, int N>						
inline _bz_ArrayExpr<mixed24n_et<_bz_typename BZ_BLITZ_SCOPE(asExpr)<Array<T,N> >::T_expr::T_range_result> > 
mixed24n(Array<T,N>& d1, int dim1, int dim2)				
{ return mixed24n(d1.wrap(), dim1, dim2); }

BZ_NAMESPACE_END
