| [658] | 1 | #ifndef BZ_ARRAYSTENCILOPS_H | 
|---|
|  | 2 | #define BZ_ARRAYSTENCILOPS_H | 
|---|
|  | 3 |  | 
|---|
|  | 4 | // NEEDS_WORK: need to factor many of the stencils in terms of the | 
|---|
|  | 5 | // integer constants, e.g. 16*(A(-1,0)+A(0,-1)+A(0,1)+A(1,0)) | 
|---|
|  | 6 |  | 
|---|
|  | 7 | #ifndef BZ_ARRAYSTENCIL_H | 
|---|
|  | 8 | #error <blitz/array/stencilops.h> must be included via <blitz/array/stencil.h> | 
|---|
|  | 9 | #endif | 
|---|
|  | 10 |  | 
|---|
|  | 11 | #ifndef BZ_GEOMETRY_H | 
|---|
|  | 12 | #include <blitz/array/geometry.h> | 
|---|
|  | 13 | #endif | 
|---|
|  | 14 |  | 
|---|
|  | 15 | #ifndef BZ_TINYMAT_H | 
|---|
|  | 16 | #include <blitz/tinymat.h> | 
|---|
|  | 17 | #endif | 
|---|
|  | 18 |  | 
|---|
|  | 19 | BZ_NAMESPACE(blitz) | 
|---|
|  | 20 |  | 
|---|
|  | 21 | #define BZ_DECLARE_STENCIL_OPERATOR1(name,A)     \ | 
|---|
|  | 22 | template<class T>                              \ | 
|---|
|  | 23 | inline _bz_typename T::T_numtype name(T& A)    \ | 
|---|
|  | 24 | { | 
|---|
|  | 25 |  | 
|---|
|  | 26 | #define BZ_END_STENCIL_OPERATOR   } | 
|---|
|  | 27 |  | 
|---|
|  | 28 | #define BZ_DECLARE_STENCIL_OPERATOR3(name,A,B,C) \ | 
|---|
|  | 29 | template<class T>                              \ | 
|---|
|  | 30 | inline _bz_typename T::T_numtype name(T& A, T& B, T& C)    \ | 
|---|
|  | 31 | { | 
|---|
|  | 32 |  | 
|---|
|  | 33 | // These constants are accurate to 45 decimal places = 149 bits of mantissa | 
|---|
|  | 34 | const double recip_2 = .500000000000000000000000000000000000000000000; | 
|---|
|  | 35 | const double recip_4 = .250000000000000000000000000000000000000000000; | 
|---|
|  | 36 | const double recip_6 = .166666666666666666666666666666666666666666667; | 
|---|
|  | 37 | const double recip_8 = .125000000000000000000000000000000000000000000; | 
|---|
|  | 38 | const double recip_12 = .0833333333333333333333333333333333333333333333; | 
|---|
|  | 39 | const double recip_144 = .00694444444444444444444444444444444444444444444; | 
|---|
|  | 40 |  | 
|---|
|  | 41 | /**************************************************************************** | 
|---|
|  | 42 | * Laplacian Operators | 
|---|
|  | 43 | ****************************************************************************/ | 
|---|
|  | 44 |  | 
|---|
|  | 45 | BZ_DECLARE_STENCIL_OPERATOR1(Laplacian2D, A) | 
|---|
|  | 46 | return -4*A(0,0) + A(-1,0) + A(1,0) + A(0,-1) + A(0,1); | 
|---|
|  | 47 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 48 |  | 
|---|
|  | 49 | BZ_DECLARE_STENCIL_OPERATOR1(Laplacian3D, A) | 
|---|
|  | 50 | return -6*A(0,0,0) + A(-1,0,0) + A(1,0,0) + A(0,-1,0) + A(0,1,0) | 
|---|
|  | 51 | + A(0,0,-1) + A(0,0,1); | 
|---|
|  | 52 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 53 |  | 
|---|
|  | 54 | BZ_DECLARE_STENCIL_OPERATOR1(Laplacian2D4, A) | 
|---|
|  | 55 | return -1*A(-2,0) + 16*A(-1,0) -A(0,-2) + 16*A(0,-1) -60*A(0,0) | 
|---|
|  | 56 | +16*A(0,1) -A(0,2) + 16*A(1,0) - A(2,0); | 
|---|
|  | 57 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 58 |  | 
|---|
|  | 59 | BZ_DECLARE_STENCIL_OPERATOR1(Laplacian2D4n, A) | 
|---|
|  | 60 | return Laplacian2D4(A) * recip_12; | 
|---|
|  | 61 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 62 |  | 
|---|
|  | 63 | BZ_DECLARE_STENCIL_OPERATOR1(Laplacian3D4, A) | 
|---|
|  | 64 | return -1*A(-2,0,0) + 16*A(-1,0,0) -A(0,-2,0) + 16*A(0,-1,0) -90*A | 
|---|
|  | 65 | +16*A(0,1,0) -A(0,2,0) + 16*A(1,0,0) - A(2,0,0) | 
|---|
|  | 66 | - A(0,0,-2) + 16*A(0,0,-1) + 16*A(0,0,1) - A(0,0,2); | 
|---|
|  | 67 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 68 |  | 
|---|
|  | 69 | BZ_DECLARE_STENCIL_OPERATOR1(Laplacian3D4n, A) | 
|---|
|  | 70 | return Laplacian3D4(A) * recip_12; | 
|---|
|  | 71 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 72 |  | 
|---|
|  | 73 | /**************************************************************************** | 
|---|
|  | 74 | * Derivatives | 
|---|
|  | 75 | ****************************************************************************/ | 
|---|
|  | 76 |  | 
|---|
|  | 77 | #define BZ_DECLARE_DIFF(name)  \ | 
|---|
|  | 78 | template<class T> \ | 
|---|
|  | 79 | inline _bz_typename T::T_numtype name(T& A, int dim = firstDim) | 
|---|
|  | 80 |  | 
|---|
|  | 81 | #define BZ_DECLARE_MULTIDIFF(name) \ | 
|---|
|  | 82 | template<class T> \ | 
|---|
|  | 83 | inline _bz_typename multicomponent_traits<_bz_typename     \ | 
|---|
|  | 84 | T::T_numtype>::T_element name(T& A, int comp, int dim) | 
|---|
|  | 85 |  | 
|---|
|  | 86 | /**************************************************************************** | 
|---|
|  | 87 | * Central differences with accuracy O(h^2) | 
|---|
|  | 88 | ****************************************************************************/ | 
|---|
|  | 89 |  | 
|---|
|  | 90 | BZ_DECLARE_DIFF(central12) { | 
|---|
|  | 91 | return A.shift(1,dim) - A.shift(-1,dim); | 
|---|
|  | 92 | } | 
|---|
|  | 93 |  | 
|---|
|  | 94 | BZ_DECLARE_DIFF(central22) { | 
|---|
|  | 95 | return A.shift(-1,dim) - 2 * A + A.shift(+1,dim); | 
|---|
|  | 96 | } | 
|---|
|  | 97 |  | 
|---|
|  | 98 | BZ_DECLARE_DIFF(central32) { | 
|---|
|  | 99 | return -A.shift(-2,dim) + 2*A.shift(-1,dim) -2*A.shift(+1,dim) + A.shift(+2,dim); | 
|---|
|  | 100 | } | 
|---|
|  | 101 |  | 
|---|
|  | 102 | BZ_DECLARE_DIFF(central42) { | 
|---|
|  | 103 | return A.shift(-2,dim) -4*A.shift(-1,dim) +6*A.shift(0,dim) -4*A.shift(1,dim) | 
|---|
|  | 104 | +A.shift(2,dim); | 
|---|
|  | 105 | } | 
|---|
|  | 106 |  | 
|---|
|  | 107 | /**************************************************************************** | 
|---|
|  | 108 | * Central differences with accuracy O(h^2)  (multicomponent versions) | 
|---|
|  | 109 | ****************************************************************************/ | 
|---|
|  | 110 |  | 
|---|
|  | 111 | BZ_DECLARE_MULTIDIFF(central12) { | 
|---|
|  | 112 | return A.shift(1,dim)[comp] - A.shift(-1,dim)[comp]; | 
|---|
|  | 113 | } | 
|---|
|  | 114 |  | 
|---|
|  | 115 | BZ_DECLARE_MULTIDIFF(central22) { | 
|---|
|  | 116 | return A.shift(-1,dim)[comp] - 2 * (*A)[comp] + A.shift(+1,dim)[comp]; | 
|---|
|  | 117 | } | 
|---|
|  | 118 |  | 
|---|
|  | 119 | BZ_DECLARE_MULTIDIFF(central32) { | 
|---|
|  | 120 | return -A.shift(-2,dim)[comp] + 2*A.shift(-1,dim)[comp] | 
|---|
|  | 121 | -2*A.shift(+1,dim)[comp] + A.shift(+2,dim)[comp]; | 
|---|
|  | 122 | } | 
|---|
|  | 123 |  | 
|---|
|  | 124 | BZ_DECLARE_MULTIDIFF(central42) { | 
|---|
|  | 125 | return A.shift(-2,dim)[comp] -4*A.shift(-1,dim)[comp] | 
|---|
|  | 126 | +6*A.shift(0,dim)[comp] -4*A.shift(1,dim)[comp] +A.shift(2,dim)[comp]; | 
|---|
|  | 127 | } | 
|---|
|  | 128 |  | 
|---|
|  | 129 | /**************************************************************************** | 
|---|
|  | 130 | * Central differences with accuracy O(h^2)  (normalized versions) | 
|---|
|  | 131 | ****************************************************************************/ | 
|---|
|  | 132 |  | 
|---|
|  | 133 | BZ_DECLARE_DIFF(central12n) { | 
|---|
|  | 134 | return central12(A,dim) * recip_2; | 
|---|
|  | 135 | } | 
|---|
|  | 136 |  | 
|---|
|  | 137 | BZ_DECLARE_DIFF(central22n) { | 
|---|
|  | 138 | return central22(A,dim); | 
|---|
|  | 139 | } | 
|---|
|  | 140 |  | 
|---|
|  | 141 | BZ_DECLARE_DIFF(central32n) { | 
|---|
|  | 142 | return central32(A,dim) * recip_2; | 
|---|
|  | 143 | } | 
|---|
|  | 144 |  | 
|---|
|  | 145 | BZ_DECLARE_DIFF(central42n) { | 
|---|
|  | 146 | return central42(A,dim); | 
|---|
|  | 147 | } | 
|---|
|  | 148 |  | 
|---|
|  | 149 | /**************************************************************************** | 
|---|
|  | 150 | * Central differences with accuracy O(h^2)  (normalized multicomponent) | 
|---|
|  | 151 | ****************************************************************************/ | 
|---|
|  | 152 |  | 
|---|
|  | 153 | BZ_DECLARE_MULTIDIFF(central12n) { | 
|---|
|  | 154 | return central12(A,comp,dim) * recip_2; | 
|---|
|  | 155 | } | 
|---|
|  | 156 |  | 
|---|
|  | 157 | BZ_DECLARE_MULTIDIFF(central22n) { | 
|---|
|  | 158 | return central22(A,comp,dim); | 
|---|
|  | 159 | } | 
|---|
|  | 160 |  | 
|---|
|  | 161 | BZ_DECLARE_MULTIDIFF(central32n) { | 
|---|
|  | 162 | return central32(A,comp,dim) * recip_2; | 
|---|
|  | 163 | } | 
|---|
|  | 164 |  | 
|---|
|  | 165 | BZ_DECLARE_MULTIDIFF(central42n) { | 
|---|
|  | 166 | return central42(A,comp,dim); | 
|---|
|  | 167 | } | 
|---|
|  | 168 |  | 
|---|
|  | 169 | /**************************************************************************** | 
|---|
|  | 170 | * Central differences with accuracy O(h^4) | 
|---|
|  | 171 | ****************************************************************************/ | 
|---|
|  | 172 |  | 
|---|
|  | 173 | BZ_DECLARE_DIFF(central14) { | 
|---|
|  | 174 | return (A.shift(-2,dim) - A.shift(2,dim)) | 
|---|
|  | 175 | + 8*(A.shift(1,dim)-A.shift(-1,dim)); | 
|---|
|  | 176 | } | 
|---|
|  | 177 |  | 
|---|
|  | 178 | BZ_DECLARE_DIFF(central24) { | 
|---|
|  | 179 | return -30*A + 16*(A.shift(-1,dim)+A.shift(1,dim)) | 
|---|
|  | 180 | - (A.shift(-2,dim)+A.shift(2,dim)); | 
|---|
|  | 181 | } | 
|---|
|  | 182 |  | 
|---|
|  | 183 | BZ_DECLARE_DIFF(central34) { | 
|---|
|  | 184 | return A.shift(-3,dim) - 8*A.shift(-2,dim) +13*A.shift(-1,dim) | 
|---|
|  | 185 | -13*A.shift(1,dim)+8*A.shift(2,dim)-A.shift(3,dim); | 
|---|
|  | 186 | } | 
|---|
|  | 187 |  | 
|---|
|  | 188 | BZ_DECLARE_DIFF(central44) { | 
|---|
|  | 189 | return -1*A.shift(-3,dim)+12*A.shift(-2,dim)-39*A.shift(-1,dim) | 
|---|
|  | 190 | +56*A-39*A.shift(1,dim)+12*A.shift(2,dim)-A.shift(3,dim); | 
|---|
|  | 191 | } | 
|---|
|  | 192 |  | 
|---|
|  | 193 | /**************************************************************************** | 
|---|
|  | 194 | * Central differences with accuracy O(h^4)  (multicomponent versions) | 
|---|
|  | 195 | ****************************************************************************/ | 
|---|
|  | 196 |  | 
|---|
|  | 197 | BZ_DECLARE_MULTIDIFF(central14) { | 
|---|
|  | 198 | return A.shift(-2,dim)[comp] - 8 * A.shift(-1,dim)[comp] | 
|---|
|  | 199 | + 8 * A.shift(1,dim)[comp] - A.shift(2,dim)[comp]; | 
|---|
|  | 200 | } | 
|---|
|  | 201 |  | 
|---|
|  | 202 | BZ_DECLARE_MULTIDIFF(central24) { | 
|---|
|  | 203 | return - A.shift(-2,dim)[comp] + 16*A.shift(-1,dim)[comp] - 30*(*A)[comp] | 
|---|
|  | 204 | + 16*A.shift(1,dim)[comp] - A.shift(2,dim)[comp]; | 
|---|
|  | 205 | } | 
|---|
|  | 206 |  | 
|---|
|  | 207 | BZ_DECLARE_MULTIDIFF(central34) { | 
|---|
|  | 208 | return A.shift(-3,dim)[comp] - 8*A.shift(-2,dim)[comp] | 
|---|
|  | 209 | +13*A.shift(-1,dim)[comp] - 13*A.shift(1,dim)[comp] | 
|---|
|  | 210 | + 8*A.shift(2,dim)[comp] - A.shift(3,dim)[comp]; | 
|---|
|  | 211 | } | 
|---|
|  | 212 |  | 
|---|
|  | 213 | BZ_DECLARE_MULTIDIFF(central44) { | 
|---|
|  | 214 | return -1*A.shift(-3,dim)[comp]+12*A.shift(-2,dim)[comp] | 
|---|
|  | 215 | -39*A.shift(-1,dim)[comp] +56*(*A)[comp]-39*A.shift(1,dim)[comp] | 
|---|
|  | 216 | +12*A.shift(2,dim)[comp]-A.shift(3,dim)[comp]; | 
|---|
|  | 217 | } | 
|---|
|  | 218 |  | 
|---|
|  | 219 | /**************************************************************************** | 
|---|
|  | 220 | * Central differences with accuracy O(h^4)  (normalized) | 
|---|
|  | 221 | ****************************************************************************/ | 
|---|
|  | 222 |  | 
|---|
|  | 223 | BZ_DECLARE_DIFF(central14n) { | 
|---|
|  | 224 | return central14(A,dim) * recip_12; | 
|---|
|  | 225 | } | 
|---|
|  | 226 |  | 
|---|
|  | 227 | BZ_DECLARE_DIFF(central24n) { | 
|---|
|  | 228 | return central24(A,dim) * recip_12; | 
|---|
|  | 229 | } | 
|---|
|  | 230 |  | 
|---|
|  | 231 | BZ_DECLARE_DIFF(central34n) { | 
|---|
|  | 232 | return central34(A,dim) * recip_8; | 
|---|
|  | 233 | } | 
|---|
|  | 234 |  | 
|---|
|  | 235 | BZ_DECLARE_DIFF(central44n) { | 
|---|
|  | 236 | return central44(A,dim) * recip_6; | 
|---|
|  | 237 | } | 
|---|
|  | 238 |  | 
|---|
|  | 239 | /**************************************************************************** | 
|---|
|  | 240 | * Central differences with accuracy O(h^4)  (normalized, multicomponent) | 
|---|
|  | 241 | ****************************************************************************/ | 
|---|
|  | 242 |  | 
|---|
|  | 243 | BZ_DECLARE_MULTIDIFF(central14n) { | 
|---|
|  | 244 | return central14(A,comp,dim) * recip_12; | 
|---|
|  | 245 | } | 
|---|
|  | 246 |  | 
|---|
|  | 247 | BZ_DECLARE_MULTIDIFF(central24n) { | 
|---|
|  | 248 | return central24(A,comp,dim) * recip_12; | 
|---|
|  | 249 | } | 
|---|
|  | 250 |  | 
|---|
|  | 251 | BZ_DECLARE_MULTIDIFF(central34n) { | 
|---|
|  | 252 | return central34(A,comp,dim) * recip_8; | 
|---|
|  | 253 | } | 
|---|
|  | 254 |  | 
|---|
|  | 255 | BZ_DECLARE_MULTIDIFF(central44n) { | 
|---|
|  | 256 | return central44(A,comp,dim) * recip_6; | 
|---|
|  | 257 | } | 
|---|
|  | 258 |  | 
|---|
|  | 259 | /**************************************************************************** | 
|---|
|  | 260 | * Backward differences with accuracy O(h) | 
|---|
|  | 261 | ****************************************************************************/ | 
|---|
|  | 262 |  | 
|---|
|  | 263 | BZ_DECLARE_DIFF(backward11) { | 
|---|
|  | 264 | return A - A.shift(-1,dim); | 
|---|
|  | 265 | } | 
|---|
|  | 266 |  | 
|---|
|  | 267 | BZ_DECLARE_DIFF(backward21) { | 
|---|
|  | 268 | return A -2*A.shift(-1,dim) + A.shift(-2,dim); | 
|---|
|  | 269 | } | 
|---|
|  | 270 |  | 
|---|
|  | 271 | BZ_DECLARE_DIFF(backward31) { | 
|---|
|  | 272 | return A -3*A.shift(-1,dim) + 3*A.shift(-2,dim)-A.shift(-3,dim); | 
|---|
|  | 273 | } | 
|---|
|  | 274 |  | 
|---|
|  | 275 | BZ_DECLARE_DIFF(backward41) { | 
|---|
|  | 276 | return A - 4*A.shift(-1,dim) + 6*A.shift(-2,dim) -4*A.shift(-3,dim) | 
|---|
|  | 277 | + A.shift(-4,dim); | 
|---|
|  | 278 | } | 
|---|
|  | 279 |  | 
|---|
|  | 280 | /**************************************************************************** | 
|---|
|  | 281 | * Backward differences with accuracy O(h) (multicomponent versions) | 
|---|
|  | 282 | ****************************************************************************/ | 
|---|
|  | 283 |  | 
|---|
|  | 284 | BZ_DECLARE_MULTIDIFF(backward11) { | 
|---|
|  | 285 | return (*A)[comp] - A.shift(-1,dim)[comp]; | 
|---|
|  | 286 | } | 
|---|
|  | 287 |  | 
|---|
|  | 288 | BZ_DECLARE_MULTIDIFF(backward21) { | 
|---|
|  | 289 | return (*A)[comp] -2*A.shift(-1,dim)[comp] + A.shift(-2,dim)[comp]; | 
|---|
|  | 290 | } | 
|---|
|  | 291 |  | 
|---|
|  | 292 | BZ_DECLARE_MULTIDIFF(backward31) { | 
|---|
|  | 293 | return (*A)[comp] -3*A.shift(-1,dim)[comp] + 3*A.shift(-2,dim)[comp] | 
|---|
|  | 294 | -A.shift(-3,dim)[comp]; | 
|---|
|  | 295 | } | 
|---|
|  | 296 |  | 
|---|
|  | 297 | BZ_DECLARE_MULTIDIFF(backward41) { | 
|---|
|  | 298 | return (*A)[comp] - 4*A.shift(-1,dim)[comp] + 6*A.shift(-2,dim)[comp] | 
|---|
|  | 299 | -4*A.shift(-3,dim)[comp] + A.shift(-4,dim)[comp]; | 
|---|
|  | 300 | } | 
|---|
|  | 301 |  | 
|---|
|  | 302 | /**************************************************************************** | 
|---|
|  | 303 | * Backward differences with accuracy O(h)  (normalized) | 
|---|
|  | 304 | ****************************************************************************/ | 
|---|
|  | 305 |  | 
|---|
|  | 306 | BZ_DECLARE_DIFF(backward11n) { return backward11(A,dim); } | 
|---|
|  | 307 | BZ_DECLARE_DIFF(backward21n) { return backward21(A,dim); } | 
|---|
|  | 308 | BZ_DECLARE_DIFF(backward31n) { return backward31(A,dim); } | 
|---|
|  | 309 | BZ_DECLARE_DIFF(backward41n) { return backward41(A,dim); } | 
|---|
|  | 310 |  | 
|---|
|  | 311 | /**************************************************************************** | 
|---|
|  | 312 | * Backward differences with accuracy O(h)  (normalized, multicomponent) | 
|---|
|  | 313 | ****************************************************************************/ | 
|---|
|  | 314 |  | 
|---|
|  | 315 | BZ_DECLARE_MULTIDIFF(backward11n) { return backward11(A,comp,dim); } | 
|---|
|  | 316 | BZ_DECLARE_MULTIDIFF(backward21n) { return backward21(A,comp,dim); } | 
|---|
|  | 317 | BZ_DECLARE_MULTIDIFF(backward31n) { return backward31(A,comp,dim); } | 
|---|
|  | 318 | BZ_DECLARE_MULTIDIFF(backward41n) { return backward41(A,comp,dim); } | 
|---|
|  | 319 |  | 
|---|
|  | 320 | /**************************************************************************** | 
|---|
|  | 321 | * Backward differences with accuracy O(h^2) | 
|---|
|  | 322 | ****************************************************************************/ | 
|---|
|  | 323 |  | 
|---|
|  | 324 | BZ_DECLARE_DIFF(backward12) { | 
|---|
|  | 325 | return 3*A -4*A.shift(-1,dim) + A.shift(-2,dim); | 
|---|
|  | 326 | } | 
|---|
|  | 327 |  | 
|---|
|  | 328 | BZ_DECLARE_DIFF(backward22) { | 
|---|
|  | 329 | return 2*A -5*A.shift(-1,dim) + 4*A.shift(-2,dim) -1*A.shift(-3,dim); | 
|---|
|  | 330 | } | 
|---|
|  | 331 |  | 
|---|
|  | 332 | BZ_DECLARE_DIFF(backward32) { | 
|---|
|  | 333 | return 5*A - 18*A.shift(-1,dim) + 24*A.shift(-2,dim) -14*A.shift(-3,dim) | 
|---|
|  | 334 | + 3*A.shift(-4,dim); | 
|---|
|  | 335 | } | 
|---|
|  | 336 |  | 
|---|
|  | 337 | BZ_DECLARE_DIFF(backward42) { | 
|---|
|  | 338 | return 3*A -14*A.shift(-1,dim) + 26*A.shift(-2,dim) -24*A.shift(-3,dim) | 
|---|
|  | 339 | + 11*A.shift(-4,dim) -2*A.shift(-5,dim); | 
|---|
|  | 340 | } | 
|---|
|  | 341 |  | 
|---|
|  | 342 | /**************************************************************************** | 
|---|
|  | 343 | * Backward differences with accuracy O(h^2) (multicomponent versions) | 
|---|
|  | 344 | ****************************************************************************/ | 
|---|
|  | 345 |  | 
|---|
|  | 346 | BZ_DECLARE_MULTIDIFF(backward12) { | 
|---|
|  | 347 | return 3*(*A)[comp] -4*A.shift(-1,dim)[comp] + A.shift(-2,dim)[comp]; | 
|---|
|  | 348 | } | 
|---|
|  | 349 |  | 
|---|
|  | 350 | BZ_DECLARE_MULTIDIFF(backward22) { | 
|---|
|  | 351 | return 2*(*A)[comp] -5*A.shift(-1,dim)[comp] + 4*A.shift(-2,dim)[comp] | 
|---|
|  | 352 | -1*A.shift(-3,dim)[comp]; | 
|---|
|  | 353 | } | 
|---|
|  | 354 |  | 
|---|
|  | 355 | BZ_DECLARE_MULTIDIFF(backward32) { | 
|---|
|  | 356 | return 5*(*A)[comp] - 18*A.shift(-1,dim)[comp] + 24*A.shift(-2,dim)[comp] | 
|---|
|  | 357 | -14*A.shift(-3,dim)[comp] + 3*A.shift(-4,dim)[comp]; | 
|---|
|  | 358 | } | 
|---|
|  | 359 |  | 
|---|
|  | 360 | BZ_DECLARE_MULTIDIFF(backward42) { | 
|---|
|  | 361 | return 3*(*A)[comp] -14*A.shift(-1,dim)[comp] + 26*A.shift(-2,dim)[comp] | 
|---|
|  | 362 | -24*A.shift(-3,dim)[comp] + 11*A.shift(-4,dim)[comp] | 
|---|
|  | 363 | -2*A.shift(-5,dim)[comp]; | 
|---|
|  | 364 | } | 
|---|
|  | 365 |  | 
|---|
|  | 366 | /**************************************************************************** | 
|---|
|  | 367 | * Backward differences with accuracy O(h^2)  (normalized) | 
|---|
|  | 368 | ****************************************************************************/ | 
|---|
|  | 369 |  | 
|---|
|  | 370 | BZ_DECLARE_DIFF(backward12n) { return backward12(A,dim) * recip_2; } | 
|---|
|  | 371 | BZ_DECLARE_DIFF(backward22n) { return backward22(A,dim); } | 
|---|
|  | 372 | BZ_DECLARE_DIFF(backward32n) { return backward32(A,dim) * recip_2; } | 
|---|
|  | 373 | BZ_DECLARE_DIFF(backward42n) { return backward42(A,dim); } | 
|---|
|  | 374 |  | 
|---|
|  | 375 | /**************************************************************************** | 
|---|
|  | 376 | * Backward differences with accuracy O(h^2)  (normalized, multicomponent) | 
|---|
|  | 377 | ****************************************************************************/ | 
|---|
|  | 378 |  | 
|---|
|  | 379 | BZ_DECLARE_MULTIDIFF(backward12n) { return backward12(A,comp,dim) * recip_2; } | 
|---|
|  | 380 | BZ_DECLARE_MULTIDIFF(backward22n) { return backward22(A,comp,dim); } | 
|---|
|  | 381 | BZ_DECLARE_MULTIDIFF(backward32n) { return backward32(A,comp,dim) * recip_2; } | 
|---|
|  | 382 | BZ_DECLARE_MULTIDIFF(backward42n) { return backward42(A,comp,dim); } | 
|---|
|  | 383 |  | 
|---|
|  | 384 | /**************************************************************************** | 
|---|
|  | 385 | * Forward differences with accuracy O(h) | 
|---|
|  | 386 | ****************************************************************************/ | 
|---|
|  | 387 |  | 
|---|
|  | 388 | BZ_DECLARE_DIFF(forward11) { | 
|---|
|  | 389 | return -1*A+A.shift(1,dim); | 
|---|
|  | 390 | } | 
|---|
|  | 391 |  | 
|---|
|  | 392 | BZ_DECLARE_DIFF(forward21) { | 
|---|
|  | 393 | return A - 2*A.shift(1,dim) + A.shift(2,dim); | 
|---|
|  | 394 | } | 
|---|
|  | 395 |  | 
|---|
|  | 396 | BZ_DECLARE_DIFF(forward31) { | 
|---|
|  | 397 | return -A + 3*A.shift(1,dim) -3*A.shift(2,dim) + A.shift(3,dim); | 
|---|
|  | 398 | } | 
|---|
|  | 399 |  | 
|---|
|  | 400 | BZ_DECLARE_DIFF(forward41) { | 
|---|
|  | 401 | return A -4*A.shift(1,dim) + 6*A.shift(2,dim) -4*A.shift(3,dim) | 
|---|
|  | 402 | + A.shift(4,dim); | 
|---|
|  | 403 | } | 
|---|
|  | 404 |  | 
|---|
|  | 405 | /**************************************************************************** | 
|---|
|  | 406 | * Forward differences with accuracy O(h)  (multicomponent versions) | 
|---|
|  | 407 | ****************************************************************************/ | 
|---|
|  | 408 |  | 
|---|
|  | 409 | BZ_DECLARE_MULTIDIFF(forward11) { | 
|---|
|  | 410 | return -1*(*A)[comp]+A.shift(1,dim)[comp]; | 
|---|
|  | 411 | } | 
|---|
|  | 412 |  | 
|---|
|  | 413 | BZ_DECLARE_MULTIDIFF(forward21) { | 
|---|
|  | 414 | return (*A)[comp] - 2*A.shift(1,dim)[comp] + A.shift(2,dim)[comp]; | 
|---|
|  | 415 | } | 
|---|
|  | 416 |  | 
|---|
|  | 417 | BZ_DECLARE_MULTIDIFF(forward31) { | 
|---|
|  | 418 | return -(*A)[comp] + 3*A.shift(1,dim)[comp] -3*A.shift(2,dim)[comp] | 
|---|
|  | 419 | + A.shift(3,dim)[comp]; | 
|---|
|  | 420 | } | 
|---|
|  | 421 |  | 
|---|
|  | 422 | BZ_DECLARE_MULTIDIFF(forward41) { | 
|---|
|  | 423 | return (*A)[comp] -4*A.shift(1,dim)[comp] + 6*A.shift(2,dim)[comp] | 
|---|
|  | 424 | -4*A.shift(3,dim)[comp] + A.shift(4,dim)[comp]; | 
|---|
|  | 425 | } | 
|---|
|  | 426 |  | 
|---|
|  | 427 | /**************************************************************************** | 
|---|
|  | 428 | * Forward differences with accuracy O(h)     (normalized) | 
|---|
|  | 429 | ****************************************************************************/ | 
|---|
|  | 430 |  | 
|---|
|  | 431 | BZ_DECLARE_DIFF(forward11n) { return forward11(A,dim); } | 
|---|
|  | 432 | BZ_DECLARE_DIFF(forward21n) { return forward21(A,dim); } | 
|---|
|  | 433 | BZ_DECLARE_DIFF(forward31n) { return forward31(A,dim); } | 
|---|
|  | 434 | BZ_DECLARE_DIFF(forward41n) { return forward41(A,dim); } | 
|---|
|  | 435 |  | 
|---|
|  | 436 | /**************************************************************************** | 
|---|
|  | 437 | * Forward differences with accuracy O(h)     (multicomponent,normalized) | 
|---|
|  | 438 | ****************************************************************************/ | 
|---|
|  | 439 |  | 
|---|
|  | 440 | BZ_DECLARE_MULTIDIFF(forward11n) { return forward11(A,comp,dim); } | 
|---|
|  | 441 | BZ_DECLARE_MULTIDIFF(forward21n) { return forward21(A,comp,dim); } | 
|---|
|  | 442 | BZ_DECLARE_MULTIDIFF(forward31n) { return forward31(A,comp,dim); } | 
|---|
|  | 443 | BZ_DECLARE_MULTIDIFF(forward41n) { return forward41(A,comp,dim); } | 
|---|
|  | 444 |  | 
|---|
|  | 445 | /**************************************************************************** | 
|---|
|  | 446 | * Forward differences with accuracy O(h^2) | 
|---|
|  | 447 | ****************************************************************************/ | 
|---|
|  | 448 |  | 
|---|
|  | 449 | BZ_DECLARE_DIFF(forward12) { | 
|---|
|  | 450 | return -3*A + 4*A.shift(1,dim) - A.shift(2,dim); | 
|---|
|  | 451 | } | 
|---|
|  | 452 |  | 
|---|
|  | 453 | BZ_DECLARE_DIFF(forward22) { | 
|---|
|  | 454 | return 2*A -5*A.shift(1,dim) + 4*A.shift(2,dim) -A.shift(3,dim); | 
|---|
|  | 455 | } | 
|---|
|  | 456 |  | 
|---|
|  | 457 | BZ_DECLARE_DIFF(forward32) { | 
|---|
|  | 458 | return -5*A + 18*A.shift(1,dim) -24*A.shift(2,dim) | 
|---|
|  | 459 | + 14*A.shift(3,dim) -3*A.shift(4,dim); | 
|---|
|  | 460 | } | 
|---|
|  | 461 |  | 
|---|
|  | 462 | BZ_DECLARE_DIFF(forward42) { | 
|---|
|  | 463 | return 3*A -14*A.shift(1,dim) + 26*A.shift(2,dim) -24*A.shift(3,dim) | 
|---|
|  | 464 | +11*A.shift(4,dim) + 11*A.shift(5,dim); | 
|---|
|  | 465 | } | 
|---|
|  | 466 |  | 
|---|
|  | 467 | /**************************************************************************** | 
|---|
|  | 468 | * Forward differences with accuracy O(h^2)   (multicomponent versions) | 
|---|
|  | 469 | ****************************************************************************/ | 
|---|
|  | 470 |  | 
|---|
|  | 471 | BZ_DECLARE_MULTIDIFF(forward12) { | 
|---|
|  | 472 | return -3*(*A)[comp] + 4*A.shift(1,dim)[comp] - A.shift(2,dim)[comp]; | 
|---|
|  | 473 | } | 
|---|
|  | 474 |  | 
|---|
|  | 475 | BZ_DECLARE_MULTIDIFF(forward22) { | 
|---|
|  | 476 | return 2*(*A)[comp] -5*A.shift(1,dim)[comp] + 4*A.shift(2,dim)[comp] | 
|---|
|  | 477 | -A.shift(3,dim)[comp]; | 
|---|
|  | 478 | } | 
|---|
|  | 479 |  | 
|---|
|  | 480 | BZ_DECLARE_MULTIDIFF(forward32) { | 
|---|
|  | 481 | return -5*(*A)[comp] + 18*A.shift(1,dim)[comp] -24*A.shift(2,dim)[comp] | 
|---|
|  | 482 | + 14*A.shift(3,dim)[comp] -3*A.shift(4,dim)[comp]; | 
|---|
|  | 483 | } | 
|---|
|  | 484 |  | 
|---|
|  | 485 | BZ_DECLARE_MULTIDIFF(forward42) { | 
|---|
|  | 486 | return 3*(*A)[comp] -14*A.shift(1,dim)[comp] + 26*A.shift(2,dim)[comp] | 
|---|
|  | 487 | -24*A.shift(3,dim)[comp] +11*A.shift(4,dim)[comp] | 
|---|
|  | 488 | + 11*A.shift(5,dim)[comp]; | 
|---|
|  | 489 | } | 
|---|
|  | 490 |  | 
|---|
|  | 491 |  | 
|---|
|  | 492 | /**************************************************************************** | 
|---|
|  | 493 | * Forward differences with accuracy O(h^2)     (normalized) | 
|---|
|  | 494 | ****************************************************************************/ | 
|---|
|  | 495 |  | 
|---|
|  | 496 | BZ_DECLARE_DIFF(forward12n) { return forward12(A,dim) * recip_2; } | 
|---|
|  | 497 | BZ_DECLARE_DIFF(forward22n) { return forward22(A,dim); } | 
|---|
|  | 498 | BZ_DECLARE_DIFF(forward32n) { return forward32(A,dim) * recip_2; } | 
|---|
|  | 499 | BZ_DECLARE_DIFF(forward42n) { return forward42(A,dim); } | 
|---|
|  | 500 |  | 
|---|
|  | 501 | /**************************************************************************** | 
|---|
|  | 502 | * Forward differences with accuracy O(h^2)     (normalized) | 
|---|
|  | 503 | ****************************************************************************/ | 
|---|
|  | 504 |  | 
|---|
|  | 505 | BZ_DECLARE_MULTIDIFF(forward12n) { return forward12(A,comp,dim) * recip_2; } | 
|---|
|  | 506 | BZ_DECLARE_MULTIDIFF(forward22n) { return forward22(A,comp,dim); } | 
|---|
|  | 507 | BZ_DECLARE_MULTIDIFF(forward32n) { return forward32(A,comp,dim) * recip_2; } | 
|---|
|  | 508 | BZ_DECLARE_MULTIDIFF(forward42n) { return forward42(A,comp,dim); } | 
|---|
|  | 509 |  | 
|---|
|  | 510 | /**************************************************************************** | 
|---|
|  | 511 | * Gradient operators | 
|---|
|  | 512 | ****************************************************************************/ | 
|---|
|  | 513 |  | 
|---|
|  | 514 | template<class T> | 
|---|
|  | 515 | inline TinyVector<_bz_typename T::T_numtype,2> grad2D(T& A) { | 
|---|
|  | 516 | return TinyVector<_bz_typename T::T_numtype,2>( | 
|---|
|  | 517 | central12(A,firstDim), | 
|---|
|  | 518 | central12(A,secondDim)); | 
|---|
|  | 519 | } | 
|---|
|  | 520 |  | 
|---|
|  | 521 | template<class T> | 
|---|
|  | 522 | inline TinyVector<_bz_typename T::T_numtype,2> grad2D4(T& A) { | 
|---|
|  | 523 | return TinyVector<_bz_typename T::T_numtype,2>( | 
|---|
|  | 524 | central14(A,firstDim), | 
|---|
|  | 525 | central14(A,secondDim)); | 
|---|
|  | 526 | } | 
|---|
|  | 527 |  | 
|---|
|  | 528 | template<class T> | 
|---|
|  | 529 | inline TinyVector<_bz_typename T::T_numtype,3> grad3D(T& A) { | 
|---|
|  | 530 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 531 | central12(A,firstDim), | 
|---|
|  | 532 | central12(A,secondDim), | 
|---|
|  | 533 | central12(A,thirdDim)); | 
|---|
|  | 534 | } | 
|---|
|  | 535 |  | 
|---|
|  | 536 | template<class T> | 
|---|
|  | 537 | inline TinyVector<_bz_typename T::T_numtype,3> grad3D4(T& A) { | 
|---|
|  | 538 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 539 | central14(A,firstDim), | 
|---|
|  | 540 | central14(A,secondDim), | 
|---|
|  | 541 | central14(A,thirdDim)); | 
|---|
|  | 542 | } | 
|---|
|  | 543 |  | 
|---|
|  | 544 | /**************************************************************************** | 
|---|
|  | 545 | * Grad-squared operators | 
|---|
|  | 546 | ****************************************************************************/ | 
|---|
|  | 547 |  | 
|---|
|  | 548 | template<class T> | 
|---|
|  | 549 | inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D(T& A) { | 
|---|
|  | 550 | return TinyVector<_bz_typename T::T_numtype,2>( | 
|---|
|  | 551 | central22(A,firstDim), | 
|---|
|  | 552 | central22(A,secondDim)); | 
|---|
|  | 553 | } | 
|---|
|  | 554 |  | 
|---|
|  | 555 | template<class T> | 
|---|
|  | 556 | inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D4(T& A) { | 
|---|
|  | 557 | return TinyVector<_bz_typename T::T_numtype,2>( | 
|---|
|  | 558 | central24(A,firstDim), | 
|---|
|  | 559 | central24(A,secondDim)); | 
|---|
|  | 560 | } | 
|---|
|  | 561 |  | 
|---|
|  | 562 | template<class T> | 
|---|
|  | 563 | inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D(T& A) { | 
|---|
|  | 564 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 565 | central22(A,firstDim), | 
|---|
|  | 566 | central22(A,secondDim), | 
|---|
|  | 567 | central22(A,thirdDim)); | 
|---|
|  | 568 | } | 
|---|
|  | 569 |  | 
|---|
|  | 570 | template<class T> | 
|---|
|  | 571 | inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D4(T& A) { | 
|---|
|  | 572 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 573 | central24(A,firstDim), | 
|---|
|  | 574 | central24(A,secondDim), | 
|---|
|  | 575 | central24(A,thirdDim)); | 
|---|
|  | 576 | } | 
|---|
|  | 577 |  | 
|---|
|  | 578 | /**************************************************************************** | 
|---|
|  | 579 | * Grad-squared operators (normalized) | 
|---|
|  | 580 | ****************************************************************************/ | 
|---|
|  | 581 |  | 
|---|
|  | 582 | template<class T> | 
|---|
|  | 583 | inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2Dn(T& A) { | 
|---|
|  | 584 | return gradSqr2D(A); | 
|---|
|  | 585 | } | 
|---|
|  | 586 |  | 
|---|
|  | 587 | template<class T> | 
|---|
|  | 588 | inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D4n(T& A) { | 
|---|
|  | 589 | return TinyVector<_bz_typename T::T_numtype,2>( | 
|---|
|  | 590 | central24(A,firstDim) * recip_12, | 
|---|
|  | 591 | central24(A,secondDim) * recip_12); | 
|---|
|  | 592 | } | 
|---|
|  | 593 |  | 
|---|
|  | 594 | template<class T> | 
|---|
|  | 595 | inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3Dn(T& A) { | 
|---|
|  | 596 | return gradSqr3D(A); | 
|---|
|  | 597 | } | 
|---|
|  | 598 |  | 
|---|
|  | 599 | template<class T> | 
|---|
|  | 600 | inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D4n(T& A) { | 
|---|
|  | 601 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 602 | central24(A,firstDim) * recip_12, | 
|---|
|  | 603 | central24(A,secondDim) * recip_12, | 
|---|
|  | 604 | central24(A,thirdDim) * recip_12); | 
|---|
|  | 605 | } | 
|---|
|  | 606 |  | 
|---|
|  | 607 | /**************************************************************************** | 
|---|
|  | 608 | * Gradient operators on a vector field | 
|---|
|  | 609 | ****************************************************************************/ | 
|---|
|  | 610 |  | 
|---|
|  | 611 | template<class T> | 
|---|
|  | 612 | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 613 | T::T_numtype>::T_element, 3, 3> | 
|---|
|  | 614 | Jacobian3D(T& A) | 
|---|
|  | 615 | { | 
|---|
|  | 616 | const int x=0, y=1, z=2; | 
|---|
|  | 617 | const int u=0, v=1, w=2; | 
|---|
|  | 618 |  | 
|---|
|  | 619 | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 620 | T::T_numtype>::T_element, 3, 3> grad; | 
|---|
|  | 621 |  | 
|---|
|  | 622 | grad(u,x) = central12(A,u,x); | 
|---|
|  | 623 | grad(u,y) = central12(A,u,y); | 
|---|
|  | 624 | grad(u,z) = central12(A,u,z); | 
|---|
|  | 625 | grad(v,x) = central12(A,v,x); | 
|---|
|  | 626 | grad(v,y) = central12(A,v,y); | 
|---|
|  | 627 | grad(v,z) = central12(A,v,z); | 
|---|
|  | 628 | grad(w,x) = central12(A,w,x); | 
|---|
|  | 629 | grad(w,y) = central12(A,w,y); | 
|---|
|  | 630 | grad(w,z) = central12(A,w,z); | 
|---|
|  | 631 |  | 
|---|
|  | 632 | return grad; | 
|---|
|  | 633 | } | 
|---|
|  | 634 |  | 
|---|
|  | 635 | template<class T> | 
|---|
|  | 636 | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 637 | T::T_numtype>::T_element, 3, 3> | 
|---|
|  | 638 | Jacobian3Dn(T& A) | 
|---|
|  | 639 | { | 
|---|
|  | 640 | const int x=0, y=1, z=2; | 
|---|
|  | 641 | const int u=0, v=1, w=2; | 
|---|
|  | 642 |  | 
|---|
|  | 643 | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 644 | T::T_numtype>::T_element, 3, 3> grad; | 
|---|
|  | 645 |  | 
|---|
|  | 646 | grad(u,x) = central12n(A,u,x); | 
|---|
|  | 647 | grad(u,y) = central12n(A,u,y); | 
|---|
|  | 648 | grad(u,z) = central12n(A,u,z); | 
|---|
|  | 649 | grad(v,x) = central12n(A,v,x); | 
|---|
|  | 650 | grad(v,y) = central12n(A,v,y); | 
|---|
|  | 651 | grad(v,z) = central12n(A,v,z); | 
|---|
|  | 652 | grad(w,x) = central12n(A,w,x); | 
|---|
|  | 653 | grad(w,y) = central12n(A,w,y); | 
|---|
|  | 654 | grad(w,z) = central12n(A,w,z); | 
|---|
|  | 655 |  | 
|---|
|  | 656 | return grad; | 
|---|
|  | 657 | } | 
|---|
|  | 658 |  | 
|---|
|  | 659 | template<class T> | 
|---|
|  | 660 | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 661 | T::T_numtype>::T_element, 3, 3> | 
|---|
|  | 662 | Jacobian3D4(T& A) | 
|---|
|  | 663 | { | 
|---|
|  | 664 | const int x=0, y=1, z=2; | 
|---|
|  | 665 | const int u=0, v=1, w=2; | 
|---|
|  | 666 |  | 
|---|
|  | 667 | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 668 | T::T_numtype>::T_element, 3, 3> grad; | 
|---|
|  | 669 |  | 
|---|
|  | 670 | grad(u,x) = central14(A,u,x); | 
|---|
|  | 671 | grad(u,y) = central14(A,u,y); | 
|---|
|  | 672 | grad(u,z) = central14(A,u,z); | 
|---|
|  | 673 | grad(v,x) = central14(A,v,x); | 
|---|
|  | 674 | grad(v,y) = central14(A,v,y); | 
|---|
|  | 675 | grad(v,z) = central14(A,v,z); | 
|---|
|  | 676 | grad(w,x) = central14(A,w,x); | 
|---|
|  | 677 | grad(w,y) = central14(A,w,y); | 
|---|
|  | 678 | grad(w,z) = central14(A,w,z); | 
|---|
|  | 679 |  | 
|---|
|  | 680 | return grad; | 
|---|
|  | 681 | } | 
|---|
|  | 682 |  | 
|---|
|  | 683 | template<class T> | 
|---|
|  | 684 | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 685 | T::T_numtype>::T_element, 3, 3> | 
|---|
|  | 686 | Jacobian3D4n(T& A) | 
|---|
|  | 687 | { | 
|---|
|  | 688 | const int x=0, y=1, z=2; | 
|---|
|  | 689 | const int u=0, v=1, w=2; | 
|---|
|  | 690 |  | 
|---|
|  | 691 | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 692 | T::T_numtype>::T_element, 3, 3> grad; | 
|---|
|  | 693 |  | 
|---|
|  | 694 | grad(u,x) = central14n(A,u,x); | 
|---|
|  | 695 | grad(u,y) = central14n(A,u,y); | 
|---|
|  | 696 | grad(u,z) = central14n(A,u,z); | 
|---|
|  | 697 | grad(v,x) = central14n(A,v,x); | 
|---|
|  | 698 | grad(v,y) = central14n(A,v,y); | 
|---|
|  | 699 | grad(v,z) = central14n(A,v,z); | 
|---|
|  | 700 | grad(w,x) = central14n(A,w,x); | 
|---|
|  | 701 | grad(w,y) = central14n(A,w,y); | 
|---|
|  | 702 | grad(w,z) = central14n(A,w,z); | 
|---|
|  | 703 |  | 
|---|
|  | 704 | return grad; | 
|---|
|  | 705 | } | 
|---|
|  | 706 |  | 
|---|
|  | 707 | /**************************************************************************** | 
|---|
|  | 708 | * Curl operators | 
|---|
|  | 709 | ****************************************************************************/ | 
|---|
|  | 710 |  | 
|---|
|  | 711 | // O(h^2) curl, using central difference | 
|---|
|  | 712 |  | 
|---|
|  | 713 | template<class T> | 
|---|
|  | 714 | inline TinyVector<_bz_typename T::T_numtype,3> | 
|---|
|  | 715 | curl(T& vx, T& vy, T& vz) { | 
|---|
|  | 716 | const int x = firstDim, y = secondDim, z = thirdDim; | 
|---|
|  | 717 |  | 
|---|
|  | 718 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 719 | central12(vz,y)-central12(vy,z), | 
|---|
|  | 720 | central12(vx,z)-central12(vz,x), | 
|---|
|  | 721 | central12(vy,x)-central12(vx,y)); | 
|---|
|  | 722 | } | 
|---|
|  | 723 |  | 
|---|
|  | 724 | // Normalized O(h^2) curl, using central difference | 
|---|
|  | 725 | template<class T> | 
|---|
|  | 726 | inline TinyVector<_bz_typename T::T_numtype,3> | 
|---|
|  | 727 | curln(T& vx, T& vy, T& vz) { | 
|---|
|  | 728 | const int x = firstDim, y = secondDim, z = thirdDim; | 
|---|
|  | 729 |  | 
|---|
|  | 730 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 731 | (central12(vz,y)-central12(vy,z)) * recip_2, | 
|---|
|  | 732 | (central12(vx,z)-central12(vz,x)) * recip_2, | 
|---|
|  | 733 | (central12(vy,x)-central12(vx,y)) * recip_2); | 
|---|
|  | 734 | } | 
|---|
|  | 735 |  | 
|---|
|  | 736 | // Multicomponent curl | 
|---|
|  | 737 | template<class T> | 
|---|
|  | 738 | inline _bz_typename T::T_numtype curl(T& A) { | 
|---|
|  | 739 | const int x = firstDim, y = secondDim, z = thirdDim; | 
|---|
|  | 740 |  | 
|---|
|  | 741 | return _bz_typename T::T_numtype( | 
|---|
|  | 742 | central12(A,z,y)-central12(A,y,z), | 
|---|
|  | 743 | central12(A,x,z)-central12(A,z,x), | 
|---|
|  | 744 | central12(A,y,x)-central12(A,x,y)); | 
|---|
|  | 745 | } | 
|---|
|  | 746 |  | 
|---|
|  | 747 | // Normalized multicomponent curl | 
|---|
|  | 748 | template<class T> | 
|---|
|  | 749 | inline _bz_typename T::T_numtype curln(T& A) { | 
|---|
|  | 750 | const int x = firstDim, y = secondDim, z = thirdDim; | 
|---|
|  | 751 |  | 
|---|
|  | 752 | return _bz_typename T::T_numtype( | 
|---|
|  | 753 | (central12(A,z,y)-central12(A,y,z)) * recip_2, | 
|---|
|  | 754 | (central12(A,x,z)-central12(A,z,x)) * recip_2, | 
|---|
|  | 755 | (central12(A,y,x)-central12(A,x,y)) * recip_2); | 
|---|
|  | 756 | } | 
|---|
|  | 757 |  | 
|---|
|  | 758 | // O(h^4) curl, using 4th order central difference | 
|---|
|  | 759 | template<class T> | 
|---|
|  | 760 | inline TinyVector<_bz_typename T::T_numtype,3> | 
|---|
|  | 761 | curl4(T& vx, T& vy, T& vz) { | 
|---|
|  | 762 | const int x = firstDim, y = secondDim, z = thirdDim; | 
|---|
|  | 763 |  | 
|---|
|  | 764 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 765 | central14(vz,y)-central14(vy,z), | 
|---|
|  | 766 | central14(vx,z)-central14(vz,x), | 
|---|
|  | 767 | central14(vy,x)-central14(vx,y)); | 
|---|
|  | 768 | } | 
|---|
|  | 769 |  | 
|---|
|  | 770 | // O(h^4) curl, using 4th order central difference (multicomponent version) | 
|---|
|  | 771 | template<class T> | 
|---|
|  | 772 | inline _bz_typename T::T_numtype | 
|---|
|  | 773 | curl4(T& A) { | 
|---|
|  | 774 | const int x = firstDim, y = secondDim, z = thirdDim; | 
|---|
|  | 775 |  | 
|---|
|  | 776 | return _bz_typename T::T_numtype( | 
|---|
|  | 777 | central14(A,z,y)-central14(A,y,z), | 
|---|
|  | 778 | central14(A,x,z)-central14(A,z,x), | 
|---|
|  | 779 | central14(A,y,x)-central14(A,x,y)); | 
|---|
|  | 780 | } | 
|---|
|  | 781 |  | 
|---|
|  | 782 | // Normalized O(h^4) curl, using 4th order central difference | 
|---|
|  | 783 | template<class T> | 
|---|
|  | 784 | inline TinyVector<_bz_typename T::T_numtype,3> | 
|---|
|  | 785 | curl4n(T& vx, T& vy, T& vz) { | 
|---|
|  | 786 | const int x = firstDim, y = secondDim, z = thirdDim; | 
|---|
|  | 787 |  | 
|---|
|  | 788 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 789 | (central14(vz,y)-central14(vy,z)) * recip_2, | 
|---|
|  | 790 | (central14(vx,z)-central14(vz,x)) * recip_2, | 
|---|
|  | 791 | (central14(vy,x)-central14(vx,y)) * recip_2); | 
|---|
|  | 792 | } | 
|---|
|  | 793 |  | 
|---|
|  | 794 | // O(h^4) curl, using 4th order central difference (normalized multicomponent) | 
|---|
|  | 795 | template<class T> | 
|---|
|  | 796 | inline _bz_typename T::T_numtype | 
|---|
|  | 797 | curl4n(T& A) { | 
|---|
|  | 798 | const int x = firstDim, y = secondDim, z = thirdDim; | 
|---|
|  | 799 |  | 
|---|
|  | 800 | return _bz_typename T::T_numtype( | 
|---|
|  | 801 | (central14(A,z,y)-central14(A,y,z)) * recip_2, | 
|---|
|  | 802 | (central14(A,x,z)-central14(A,z,x)) * recip_2, | 
|---|
|  | 803 | (central14(A,y,x)-central14(A,x,y)) * recip_2); | 
|---|
|  | 804 | } | 
|---|
|  | 805 |  | 
|---|
|  | 806 | /**************************************************************************** | 
|---|
|  | 807 | * Divergence | 
|---|
|  | 808 | ****************************************************************************/ | 
|---|
|  | 809 |  | 
|---|
|  | 810 | BZ_DECLARE_STENCIL_OPERATOR3(div,vx,vy,vz) | 
|---|
|  | 811 | return central12(vx,firstDim) + central12(vy,secondDim) | 
|---|
|  | 812 | + central12(vz,thirdDim); | 
|---|
|  | 813 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 814 |  | 
|---|
|  | 815 | BZ_DECLARE_STENCIL_OPERATOR3(divn,vx,vy,vz) | 
|---|
|  | 816 | return (central12(vx,firstDim) + central12(vy,secondDim) | 
|---|
|  | 817 | + central12(vz,thirdDim)) * recip_2; | 
|---|
|  | 818 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 819 |  | 
|---|
|  | 820 | BZ_DECLARE_STENCIL_OPERATOR3(div4,vx,vy,vz) | 
|---|
|  | 821 | return central14(vx,firstDim) + central14(vy,secondDim) | 
|---|
|  | 822 | + central14(vz,thirdDim); | 
|---|
|  | 823 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 824 |  | 
|---|
|  | 825 | BZ_DECLARE_STENCIL_OPERATOR3(div4n,vx,vy,vz) | 
|---|
|  | 826 | return (central14(vx,firstDim) + central14(vy,secondDim) | 
|---|
|  | 827 | + central14(vz,thirdDim)) * recip_12; | 
|---|
|  | 828 | BZ_END_STENCIL_OPERATOR | 
|---|
|  | 829 |  | 
|---|
|  | 830 | /**************************************************************************** | 
|---|
|  | 831 | * Mixed Partial derivatives | 
|---|
|  | 832 | ****************************************************************************/ | 
|---|
|  | 833 |  | 
|---|
|  | 834 | template<class T> | 
|---|
|  | 835 | inline _bz_typename T::T_numtype | 
|---|
|  | 836 | mixed22(T& A, int x, int y) | 
|---|
|  | 837 | { | 
|---|
|  | 838 | return A.shift(-1,x,-1,y) - A.shift(-1,x,1,y) | 
|---|
|  | 839 | -A.shift(1,x,-1,y) + A.shift(1,x,1,y); | 
|---|
|  | 840 | } | 
|---|
|  | 841 |  | 
|---|
|  | 842 | template<class T> | 
|---|
|  | 843 | inline _bz_typename T::T_numtype | 
|---|
|  | 844 | mixed22n(T& A, int x, int y) | 
|---|
|  | 845 | { | 
|---|
|  | 846 | return mixed22(A, x, y) * recip_4; | 
|---|
|  | 847 | } | 
|---|
|  | 848 |  | 
|---|
|  | 849 | template<class T> | 
|---|
|  | 850 | inline _bz_typename T::T_numtype | 
|---|
|  | 851 | mixed24(T& A, int x, int y) | 
|---|
|  | 852 | { | 
|---|
|  | 853 | return 64*(A.shift(-1,x,-1,y) - A.shift(-1,x,1,y) | 
|---|
|  | 854 | -A.shift(1,x,-1,y) + A.shift(1,x,1,y)) | 
|---|
|  | 855 | + (A.shift(-2,x,+1,y) - A.shift(-1,x,2,y) | 
|---|
|  | 856 | - A.shift(1,x,2,y)-A.shift(2,x,1,y) | 
|---|
|  | 857 | + A.shift(2,x,-1,y)+A.shift(1,x,-2,y) | 
|---|
|  | 858 | - A.shift(-1,x,-2,y)+A.shift(-2,x,-1,y)) | 
|---|
|  | 859 | + 8*(A.shift(-1,x,1,y)+A.shift(-1,x,2,y) | 
|---|
|  | 860 | -A.shift(2,x,-2,y) + A.shift(2,x,2,y)); | 
|---|
|  | 861 | } | 
|---|
|  | 862 |  | 
|---|
|  | 863 | template<class T> | 
|---|
|  | 864 | inline _bz_typename T::T_numtype | 
|---|
|  | 865 | mixed24n(T& A, int x, int y) | 
|---|
|  | 866 | { | 
|---|
|  | 867 | return mixed24(A,x,y) * recip_144; | 
|---|
|  | 868 | } | 
|---|
|  | 869 |  | 
|---|
|  | 870 | /**************************************************************************** | 
|---|
|  | 871 | * Smoothers | 
|---|
|  | 872 | ****************************************************************************/ | 
|---|
|  | 873 |  | 
|---|
|  | 874 | // NEEDS_WORK-- put other stencil operators here: | 
|---|
|  | 875 | //   Average5pt2D | 
|---|
|  | 876 | //   Average7pt3D | 
|---|
|  | 877 | // etc. | 
|---|
|  | 878 |  | 
|---|
|  | 879 | /**************************************************************************** | 
|---|
|  | 880 | * Stencil operators with geometry (experimental) | 
|---|
|  | 881 | ****************************************************************************/ | 
|---|
|  | 882 |  | 
|---|
|  | 883 | template<class T> | 
|---|
|  | 884 | inline _bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 885 | T::T_numtype>::T_element div3DVec4(T& A, | 
|---|
|  | 886 | const UniformCubicGeometry<3>& geom) | 
|---|
|  | 887 | { | 
|---|
|  | 888 | const int x = 0, y = 1, z = 2; | 
|---|
|  | 889 |  | 
|---|
|  | 890 | return (central14(A, x, firstDim) + central14(A, y, secondDim) | 
|---|
|  | 891 | + central14(A, z, thirdDim)) * recip_12 * geom.recipSpatialStep(); | 
|---|
|  | 892 | } | 
|---|
|  | 893 |  | 
|---|
|  | 894 | template<class T> | 
|---|
|  | 895 | inline _bz_typename T::T_numtype Laplacian3D4(T& A, | 
|---|
|  | 896 | const UniformCubicGeometry<3>& geom) | 
|---|
|  | 897 | { | 
|---|
|  | 898 | return Laplacian3D4n(A) * geom.recipSpatialStepPow2(); | 
|---|
|  | 899 | } | 
|---|
|  | 900 |  | 
|---|
|  | 901 | template<class T> | 
|---|
|  | 902 | inline _bz_typename T::T_numtype Laplacian3DVec4(T& A, | 
|---|
|  | 903 | const UniformCubicGeometry<3>& geom) | 
|---|
|  | 904 | { | 
|---|
|  | 905 | typedef _bz_typename T::T_numtype vector3d; | 
|---|
|  | 906 | typedef multicomponent_traits<vector3d>::T_element | 
|---|
|  | 907 | T_element; | 
|---|
|  | 908 | const int u = 0, v = 1, w = 2; | 
|---|
|  | 909 | const int x = 0, y = 1, z = 2; | 
|---|
|  | 910 |  | 
|---|
|  | 911 | // central24 is a 5-point stencil | 
|---|
|  | 912 | // This is a 9*5 = 45 point stencil | 
|---|
|  | 913 |  | 
|---|
|  | 914 | T_element t1 = (central24(A,u,x) + central24(A,u,y) + central24(A,u,z)) | 
|---|
|  | 915 | * recip_12 * geom.recipSpatialStepPow2(); | 
|---|
|  | 916 |  | 
|---|
|  | 917 | T_element t2 = (central24(A,v,x) + central24(A,v,y) + central24(A,v,z)) | 
|---|
|  | 918 | * recip_12 * geom.recipSpatialStepPow2(); | 
|---|
|  | 919 |  | 
|---|
|  | 920 | T_element t3 = (central24(A,w,x) + central24(A,w,y) + central24(A,w,z)) | 
|---|
|  | 921 | * recip_12 * geom.recipSpatialStepPow2(); | 
|---|
|  | 922 |  | 
|---|
|  | 923 | return vector3d(t1,t2,t3); | 
|---|
|  | 924 | } | 
|---|
|  | 925 |  | 
|---|
|  | 926 | template<class T> | 
|---|
|  | 927 | inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 928 | T::T_numtype>::T_element, 3, 3> | 
|---|
|  | 929 | grad3DVec4(T& A, const UniformCubicGeometry<3>& geom) | 
|---|
|  | 930 | { | 
|---|
|  | 931 | const int x=0, y=1, z=2; | 
|---|
|  | 932 | const int u=0, v=1, w=2; | 
|---|
|  | 933 |  | 
|---|
|  | 934 | TinyMatrix<_bz_typename multicomponent_traits<_bz_typename | 
|---|
|  | 935 | T::T_numtype>::T_element, 3, 3> grad; | 
|---|
|  | 936 |  | 
|---|
|  | 937 | // This is a 9*4 = 36 point stencil | 
|---|
|  | 938 | grad(u,x) = central14n(A,u,x) * geom.recipSpatialStep(); | 
|---|
|  | 939 | grad(u,y) = central14n(A,u,y) * geom.recipSpatialStep(); | 
|---|
|  | 940 | grad(u,z) = central14n(A,u,z) * geom.recipSpatialStep(); | 
|---|
|  | 941 | grad(v,x) = central14n(A,v,x) * geom.recipSpatialStep(); | 
|---|
|  | 942 | grad(v,y) = central14n(A,v,y) * geom.recipSpatialStep(); | 
|---|
|  | 943 | grad(v,z) = central14n(A,v,z) * geom.recipSpatialStep(); | 
|---|
|  | 944 | grad(w,x) = central14n(A,w,x) * geom.recipSpatialStep(); | 
|---|
|  | 945 | grad(w,y) = central14n(A,w,y) * geom.recipSpatialStep(); | 
|---|
|  | 946 | grad(w,z) = central14n(A,w,z) * geom.recipSpatialStep(); | 
|---|
|  | 947 |  | 
|---|
|  | 948 | return grad; | 
|---|
|  | 949 | } | 
|---|
|  | 950 |  | 
|---|
|  | 951 | template<class T> | 
|---|
|  | 952 | inline TinyVector<_bz_typename T::T_numtype,3> grad3D4(T& A, | 
|---|
|  | 953 | const UniformCubicGeometry<3>& geom) { | 
|---|
|  | 954 | return TinyVector<_bz_typename T::T_numtype,3>( | 
|---|
|  | 955 | central14(A,firstDim) * recip_12 * geom.recipSpatialStep(), | 
|---|
|  | 956 | central14(A,secondDim) * recip_12 * geom.recipSpatialStep(), | 
|---|
|  | 957 | central14(A,thirdDim) * recip_12 * geom.recipSpatialStep()); | 
|---|
|  | 958 | } | 
|---|
|  | 959 |  | 
|---|
|  | 960 | BZ_NAMESPACE_END | 
|---|
|  | 961 |  | 
|---|
|  | 962 | #endif // BZ_ARRAYSTENCILOPS_H | 
|---|
|  | 963 |  | 
|---|