source: Sophya/trunk/Poubelle/DPC:FitsIOServer/Blitz/blitz/array/stencilops.h@ 658

Last change on this file since 658 was 658, checked in by ansari, 26 years ago

no message

File size: 30.7 KB
Line 
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
19BZ_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
34const double recip_2 = .500000000000000000000000000000000000000000000;
35const double recip_4 = .250000000000000000000000000000000000000000000;
36const double recip_6 = .166666666666666666666666666666666666666666667;
37const double recip_8 = .125000000000000000000000000000000000000000000;
38const double recip_12 = .0833333333333333333333333333333333333333333333;
39const double recip_144 = .00694444444444444444444444444444444444444444444;
40
41/****************************************************************************
42 * Laplacian Operators
43 ****************************************************************************/
44
45BZ_DECLARE_STENCIL_OPERATOR1(Laplacian2D, A)
46 return -4*A(0,0) + A(-1,0) + A(1,0) + A(0,-1) + A(0,1);
47BZ_END_STENCIL_OPERATOR
48
49BZ_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);
52BZ_END_STENCIL_OPERATOR
53
54BZ_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);
57BZ_END_STENCIL_OPERATOR
58
59BZ_DECLARE_STENCIL_OPERATOR1(Laplacian2D4n, A)
60 return Laplacian2D4(A) * recip_12;
61BZ_END_STENCIL_OPERATOR
62
63BZ_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);
67BZ_END_STENCIL_OPERATOR
68
69BZ_DECLARE_STENCIL_OPERATOR1(Laplacian3D4n, A)
70 return Laplacian3D4(A) * recip_12;
71BZ_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
90BZ_DECLARE_DIFF(central12) {
91 return A.shift(1,dim) - A.shift(-1,dim);
92}
93
94BZ_DECLARE_DIFF(central22) {
95 return A.shift(-1,dim) - 2 * A + A.shift(+1,dim);
96}
97
98BZ_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
102BZ_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
111BZ_DECLARE_MULTIDIFF(central12) {
112 return A.shift(1,dim)[comp] - A.shift(-1,dim)[comp];
113}
114
115BZ_DECLARE_MULTIDIFF(central22) {
116 return A.shift(-1,dim)[comp] - 2 * (*A)[comp] + A.shift(+1,dim)[comp];
117}
118
119BZ_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
124BZ_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
133BZ_DECLARE_DIFF(central12n) {
134 return central12(A,dim) * recip_2;
135}
136
137BZ_DECLARE_DIFF(central22n) {
138 return central22(A,dim);
139}
140
141BZ_DECLARE_DIFF(central32n) {
142 return central32(A,dim) * recip_2;
143}
144
145BZ_DECLARE_DIFF(central42n) {
146 return central42(A,dim);
147}
148
149/****************************************************************************
150 * Central differences with accuracy O(h^2) (normalized multicomponent)
151 ****************************************************************************/
152
153BZ_DECLARE_MULTIDIFF(central12n) {
154 return central12(A,comp,dim) * recip_2;
155}
156
157BZ_DECLARE_MULTIDIFF(central22n) {
158 return central22(A,comp,dim);
159}
160
161BZ_DECLARE_MULTIDIFF(central32n) {
162 return central32(A,comp,dim) * recip_2;
163}
164
165BZ_DECLARE_MULTIDIFF(central42n) {
166 return central42(A,comp,dim);
167}
168
169/****************************************************************************
170 * Central differences with accuracy O(h^4)
171 ****************************************************************************/
172
173BZ_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
178BZ_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
183BZ_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
188BZ_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
197BZ_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
202BZ_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
207BZ_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
213BZ_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
223BZ_DECLARE_DIFF(central14n) {
224 return central14(A,dim) * recip_12;
225}
226
227BZ_DECLARE_DIFF(central24n) {
228 return central24(A,dim) * recip_12;
229}
230
231BZ_DECLARE_DIFF(central34n) {
232 return central34(A,dim) * recip_8;
233}
234
235BZ_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
243BZ_DECLARE_MULTIDIFF(central14n) {
244 return central14(A,comp,dim) * recip_12;
245}
246
247BZ_DECLARE_MULTIDIFF(central24n) {
248 return central24(A,comp,dim) * recip_12;
249}
250
251BZ_DECLARE_MULTIDIFF(central34n) {
252 return central34(A,comp,dim) * recip_8;
253}
254
255BZ_DECLARE_MULTIDIFF(central44n) {
256 return central44(A,comp,dim) * recip_6;
257}
258
259/****************************************************************************
260 * Backward differences with accuracy O(h)
261 ****************************************************************************/
262
263BZ_DECLARE_DIFF(backward11) {
264 return A - A.shift(-1,dim);
265}
266
267BZ_DECLARE_DIFF(backward21) {
268 return A -2*A.shift(-1,dim) + A.shift(-2,dim);
269}
270
271BZ_DECLARE_DIFF(backward31) {
272 return A -3*A.shift(-1,dim) + 3*A.shift(-2,dim)-A.shift(-3,dim);
273}
274
275BZ_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
284BZ_DECLARE_MULTIDIFF(backward11) {
285 return (*A)[comp] - A.shift(-1,dim)[comp];
286}
287
288BZ_DECLARE_MULTIDIFF(backward21) {
289 return (*A)[comp] -2*A.shift(-1,dim)[comp] + A.shift(-2,dim)[comp];
290}
291
292BZ_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
297BZ_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
306BZ_DECLARE_DIFF(backward11n) { return backward11(A,dim); }
307BZ_DECLARE_DIFF(backward21n) { return backward21(A,dim); }
308BZ_DECLARE_DIFF(backward31n) { return backward31(A,dim); }
309BZ_DECLARE_DIFF(backward41n) { return backward41(A,dim); }
310
311/****************************************************************************
312 * Backward differences with accuracy O(h) (normalized, multicomponent)
313 ****************************************************************************/
314
315BZ_DECLARE_MULTIDIFF(backward11n) { return backward11(A,comp,dim); }
316BZ_DECLARE_MULTIDIFF(backward21n) { return backward21(A,comp,dim); }
317BZ_DECLARE_MULTIDIFF(backward31n) { return backward31(A,comp,dim); }
318BZ_DECLARE_MULTIDIFF(backward41n) { return backward41(A,comp,dim); }
319
320/****************************************************************************
321 * Backward differences with accuracy O(h^2)
322 ****************************************************************************/
323
324BZ_DECLARE_DIFF(backward12) {
325 return 3*A -4*A.shift(-1,dim) + A.shift(-2,dim);
326}
327
328BZ_DECLARE_DIFF(backward22) {
329 return 2*A -5*A.shift(-1,dim) + 4*A.shift(-2,dim) -1*A.shift(-3,dim);
330}
331
332BZ_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
337BZ_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
346BZ_DECLARE_MULTIDIFF(backward12) {
347 return 3*(*A)[comp] -4*A.shift(-1,dim)[comp] + A.shift(-2,dim)[comp];
348}
349
350BZ_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
355BZ_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
360BZ_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
370BZ_DECLARE_DIFF(backward12n) { return backward12(A,dim) * recip_2; }
371BZ_DECLARE_DIFF(backward22n) { return backward22(A,dim); }
372BZ_DECLARE_DIFF(backward32n) { return backward32(A,dim) * recip_2; }
373BZ_DECLARE_DIFF(backward42n) { return backward42(A,dim); }
374
375/****************************************************************************
376 * Backward differences with accuracy O(h^2) (normalized, multicomponent)
377 ****************************************************************************/
378
379BZ_DECLARE_MULTIDIFF(backward12n) { return backward12(A,comp,dim) * recip_2; }
380BZ_DECLARE_MULTIDIFF(backward22n) { return backward22(A,comp,dim); }
381BZ_DECLARE_MULTIDIFF(backward32n) { return backward32(A,comp,dim) * recip_2; }
382BZ_DECLARE_MULTIDIFF(backward42n) { return backward42(A,comp,dim); }
383
384/****************************************************************************
385 * Forward differences with accuracy O(h)
386 ****************************************************************************/
387
388BZ_DECLARE_DIFF(forward11) {
389 return -1*A+A.shift(1,dim);
390}
391
392BZ_DECLARE_DIFF(forward21) {
393 return A - 2*A.shift(1,dim) + A.shift(2,dim);
394}
395
396BZ_DECLARE_DIFF(forward31) {
397 return -A + 3*A.shift(1,dim) -3*A.shift(2,dim) + A.shift(3,dim);
398}
399
400BZ_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
409BZ_DECLARE_MULTIDIFF(forward11) {
410 return -1*(*A)[comp]+A.shift(1,dim)[comp];
411}
412
413BZ_DECLARE_MULTIDIFF(forward21) {
414 return (*A)[comp] - 2*A.shift(1,dim)[comp] + A.shift(2,dim)[comp];
415}
416
417BZ_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
422BZ_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
431BZ_DECLARE_DIFF(forward11n) { return forward11(A,dim); }
432BZ_DECLARE_DIFF(forward21n) { return forward21(A,dim); }
433BZ_DECLARE_DIFF(forward31n) { return forward31(A,dim); }
434BZ_DECLARE_DIFF(forward41n) { return forward41(A,dim); }
435
436/****************************************************************************
437 * Forward differences with accuracy O(h) (multicomponent,normalized)
438 ****************************************************************************/
439
440BZ_DECLARE_MULTIDIFF(forward11n) { return forward11(A,comp,dim); }
441BZ_DECLARE_MULTIDIFF(forward21n) { return forward21(A,comp,dim); }
442BZ_DECLARE_MULTIDIFF(forward31n) { return forward31(A,comp,dim); }
443BZ_DECLARE_MULTIDIFF(forward41n) { return forward41(A,comp,dim); }
444
445/****************************************************************************
446 * Forward differences with accuracy O(h^2)
447 ****************************************************************************/
448
449BZ_DECLARE_DIFF(forward12) {
450 return -3*A + 4*A.shift(1,dim) - A.shift(2,dim);
451}
452
453BZ_DECLARE_DIFF(forward22) {
454 return 2*A -5*A.shift(1,dim) + 4*A.shift(2,dim) -A.shift(3,dim);
455}
456
457BZ_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
462BZ_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
471BZ_DECLARE_MULTIDIFF(forward12) {
472 return -3*(*A)[comp] + 4*A.shift(1,dim)[comp] - A.shift(2,dim)[comp];
473}
474
475BZ_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
480BZ_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
485BZ_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
496BZ_DECLARE_DIFF(forward12n) { return forward12(A,dim) * recip_2; }
497BZ_DECLARE_DIFF(forward22n) { return forward22(A,dim); }
498BZ_DECLARE_DIFF(forward32n) { return forward32(A,dim) * recip_2; }
499BZ_DECLARE_DIFF(forward42n) { return forward42(A,dim); }
500
501/****************************************************************************
502 * Forward differences with accuracy O(h^2) (normalized)
503 ****************************************************************************/
504
505BZ_DECLARE_MULTIDIFF(forward12n) { return forward12(A,comp,dim) * recip_2; }
506BZ_DECLARE_MULTIDIFF(forward22n) { return forward22(A,comp,dim); }
507BZ_DECLARE_MULTIDIFF(forward32n) { return forward32(A,comp,dim) * recip_2; }
508BZ_DECLARE_MULTIDIFF(forward42n) { return forward42(A,comp,dim); }
509
510/****************************************************************************
511 * Gradient operators
512 ****************************************************************************/
513
514template<class T>
515inline 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
521template<class T>
522inline 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
528template<class T>
529inline 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
536template<class T>
537inline 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
548template<class T>
549inline 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
555template<class T>
556inline 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
562template<class T>
563inline 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
570template<class T>
571inline 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
582template<class T>
583inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2Dn(T& A) {
584 return gradSqr2D(A);
585}
586
587template<class T>
588inline 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
594template<class T>
595inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3Dn(T& A) {
596 return gradSqr3D(A);
597}
598
599template<class T>
600inline 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
611template<class T>
612inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
613 T::T_numtype>::T_element, 3, 3>
614Jacobian3D(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
635template<class T>
636inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
637 T::T_numtype>::T_element, 3, 3>
638Jacobian3Dn(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
659template<class T>
660inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
661 T::T_numtype>::T_element, 3, 3>
662Jacobian3D4(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
683template<class T>
684inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
685 T::T_numtype>::T_element, 3, 3>
686Jacobian3D4n(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
713template<class T>
714inline TinyVector<_bz_typename T::T_numtype,3>
715curl(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
725template<class T>
726inline TinyVector<_bz_typename T::T_numtype,3>
727curln(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
737template<class T>
738inline _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
748template<class T>
749inline _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
759template<class T>
760inline TinyVector<_bz_typename T::T_numtype,3>
761curl4(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)
771template<class T>
772inline _bz_typename T::T_numtype
773curl4(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
783template<class T>
784inline TinyVector<_bz_typename T::T_numtype,3>
785curl4n(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)
795template<class T>
796inline _bz_typename T::T_numtype
797curl4n(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
810BZ_DECLARE_STENCIL_OPERATOR3(div,vx,vy,vz)
811 return central12(vx,firstDim) + central12(vy,secondDim)
812 + central12(vz,thirdDim);
813BZ_END_STENCIL_OPERATOR
814
815BZ_DECLARE_STENCIL_OPERATOR3(divn,vx,vy,vz)
816 return (central12(vx,firstDim) + central12(vy,secondDim)
817 + central12(vz,thirdDim)) * recip_2;
818BZ_END_STENCIL_OPERATOR
819
820BZ_DECLARE_STENCIL_OPERATOR3(div4,vx,vy,vz)
821 return central14(vx,firstDim) + central14(vy,secondDim)
822 + central14(vz,thirdDim);
823BZ_END_STENCIL_OPERATOR
824
825BZ_DECLARE_STENCIL_OPERATOR3(div4n,vx,vy,vz)
826 return (central14(vx,firstDim) + central14(vy,secondDim)
827 + central14(vz,thirdDim)) * recip_12;
828BZ_END_STENCIL_OPERATOR
829
830/****************************************************************************
831 * Mixed Partial derivatives
832 ****************************************************************************/
833
834template<class T>
835inline _bz_typename T::T_numtype
836mixed22(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
842template<class T>
843inline _bz_typename T::T_numtype
844mixed22n(T& A, int x, int y)
845{
846 return mixed22(A, x, y) * recip_4;
847}
848
849template<class T>
850inline _bz_typename T::T_numtype
851mixed24(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
863template<class T>
864inline _bz_typename T::T_numtype
865mixed24n(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
883template<class T>
884inline _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
894template<class T>
895inline _bz_typename T::T_numtype Laplacian3D4(T& A,
896 const UniformCubicGeometry<3>& geom)
897{
898 return Laplacian3D4n(A) * geom.recipSpatialStepPow2();
899}
900
901template<class T>
902inline _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
926template<class T>
927inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
928 T::T_numtype>::T_element, 3, 3>
929grad3DVec4(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
951template<class T>
952inline 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
960BZ_NAMESPACE_END
961
962#endif // BZ_ARRAYSTENCILOPS_H
963
Note: See TracBrowser for help on using the repository browser.