source: XMLIO_V2/external/include/blitz/array/stencilops.h @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 37.3 KB
Line 
1// -*- C++ -*-
2/***************************************************************************
3 * blitz/array/stencilops.h  Stencil operators
4 *
5 * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * Suggestions:          blitz-dev@oonumerics.org
18 * Bugs:                 blitz-bugs@oonumerics.org
19 *
20 * For more information, please see the Blitz++ Home Page:
21 *    http://oonumerics.org/blitz/
22 *
23 ****************************************************************************/
24#ifndef BZ_ARRAYSTENCILOPS_H
25#define BZ_ARRAYSTENCILOPS_H
26
27// NEEDS_WORK: need to factor many of the stencils in terms of the
28// integer constants, e.g. 16*(A(-1,0)+A(0,-1)+A(0,1)+A(1,0))
29
30#ifndef BZ_ARRAYSTENCILS_H
31 #error <blitz/array/stencilops.h> must be included via <blitz/array/stencils.h>
32#endif
33
34#ifndef BZ_GEOMETRY_H
35 #include <blitz/array/geometry.h>
36#endif
37
38#ifndef BZ_TINYMAT_H
39 #include <blitz/tinymat.h>
40#endif
41
42BZ_NAMESPACE(blitz)
43
44#define BZ_DECLARE_STENCIL_OPERATOR1(name,A)     \
45  template<typename T>                              \
46  inline _bz_typename T::T_numtype name(T& A)    \
47  {
48
49#define BZ_END_STENCIL_OPERATOR   }
50
51#define BZ_DECLARE_STENCIL_OPERATOR2(name,A,B)       \
52  template<typename T>                                  \
53  inline _bz_typename T::T_numtype name(T& A, T& B)  \
54  {
55
56#define BZ_DECLARE_STENCIL_OPERATOR3(name,A,B,C) \
57  template<typename T>                              \
58  inline _bz_typename T::T_numtype name(T& A, T& B, T& C)    \
59  {
60
61// These constants are accurate to 45 decimal places = 149 bits of mantissa
62const double recip_2 = .500000000000000000000000000000000000000000000;
63const double recip_4 = .250000000000000000000000000000000000000000000;
64const double recip_6 = .166666666666666666666666666666666666666666667;
65const double recip_8 = .125000000000000000000000000000000000000000000;
66const double recip_12 = .0833333333333333333333333333333333333333333333;
67const double recip_144 = .00694444444444444444444444444444444444444444444;
68
69/****************************************************************************
70 * Laplacian Operators
71 ****************************************************************************/
72
73BZ_DECLARE_STENCIL_OPERATOR1(Laplacian2D, A)
74  return -4.0 * (*A)
75    + A.shift(-1,0) + A.shift(1,0)
76    + A.shift(-1,1) + A.shift(1,1);
77BZ_END_STENCIL_OPERATOR
78
79BZ_DECLARE_STENCIL_OPERATOR1(Laplacian3D, A)
80  return -6.0 * (*A) 
81    + A.shift(-1,0) + A.shift(1,0) 
82    + A.shift(-1,1) + A.shift(1,1)
83    + A.shift(-1,2) + A.shift(1,2);
84BZ_END_STENCIL_OPERATOR
85
86BZ_DECLARE_STENCIL_OPERATOR1(Laplacian2D4, A)
87  return -60.0 * (*A) 
88    + 16.0 * (A.shift(-1,0) + A.shift(1,0) + A.shift(-1,1) + A.shift(1,1))
89    -        (A.shift(-2,0) + A.shift(2,0) + A.shift(-2,1) + A.shift(2,1));
90BZ_END_STENCIL_OPERATOR
91
92BZ_DECLARE_STENCIL_OPERATOR1(Laplacian2D4n, A)
93  return Laplacian2D4(A) * recip_12;
94BZ_END_STENCIL_OPERATOR
95
96BZ_DECLARE_STENCIL_OPERATOR1(Laplacian3D4, A)
97  return -90.0 * (*A) 
98    + 16.0 * (A.shift(-1,0) + A.shift(1,0) + A.shift(-1,1) + A.shift(1,1) +
99              A.shift(-1,2) + A.shift(1,2))
100    -        (A.shift(-2,0) + A.shift(2,0) + A.shift(-2,1) + A.shift(2,1) +
101              A.shift(-2,2) + A.shift(2,2));
102BZ_END_STENCIL_OPERATOR
103
104BZ_DECLARE_STENCIL_OPERATOR1(Laplacian3D4n, A)
105  return Laplacian3D4(A) * recip_12;
106BZ_END_STENCIL_OPERATOR
107
108/****************************************************************************
109 * Derivatives
110 ****************************************************************************/
111
112#define BZ_DECLARE_DIFF(name)  \
113  template<typename T> \
114  inline _bz_typename T::T_numtype name(T& A, int dim = firstDim)
115
116#define BZ_DECLARE_MULTIDIFF(name) \
117  template<typename T> \
118  inline _bz_typename multicomponent_traits<_bz_typename     \
119     T::T_numtype>::T_element name(T& A, int comp, int dim)
120
121/****************************************************************************
122 * Central differences with accuracy O(h^2)
123 ****************************************************************************/
124
125BZ_DECLARE_DIFF(central12) {
126  return A.shift(1,dim) - A.shift(-1,dim);
127}
128
129BZ_DECLARE_DIFF(central22) {
130  return -2.0 * (*A) + A.shift(1,dim) + A.shift(-1,dim);
131}
132
133BZ_DECLARE_DIFF(central32) {
134  return -2.0 * (A.shift(1,dim) - A.shift(-1,dim))
135    +           (A.shift(2,dim) - A.shift(-2,dim));
136}
137
138BZ_DECLARE_DIFF(central42) {
139  return 6.0 * (*A)
140    - 4.0 * (A.shift(1,dim) + A.shift(-1,dim))
141    +       (A.shift(2,dim) + A.shift(-2,dim));
142}
143
144/****************************************************************************
145 * Central differences with accuracy O(h^2)  (multicomponent versions)
146 ****************************************************************************/
147
148BZ_DECLARE_MULTIDIFF(central12) {
149  return A.shift(1,dim)[comp] - A.shift(-1,dim)[comp];
150}
151
152BZ_DECLARE_MULTIDIFF(central22) {
153  return -2.0 * (*A)[comp]
154    + A.shift(1,dim)[comp] + A.shift(-1,dim)[comp];
155}
156
157BZ_DECLARE_MULTIDIFF(central32) {
158  return -2.0 * (A.shift(1,dim)[comp] - A.shift(-1,dim)[comp])
159    +           (A.shift(2,dim)[comp] - A.shift(-2,dim)[comp]);
160}
161
162BZ_DECLARE_MULTIDIFF(central42) {
163  return 6.0 * (*A)[comp]
164    -4.0 * (A.shift(1,dim)[comp] + A.shift(-1,dim)[comp])
165    +      (A.shift(2,dim)[comp] + A.shift(-2,dim)[comp]);
166}
167
168/****************************************************************************
169 * Central differences with accuracy O(h^2)  (normalized versions)
170 ****************************************************************************/
171
172BZ_DECLARE_DIFF(central12n) {
173  return central12(A,dim) * recip_2;
174}
175
176BZ_DECLARE_DIFF(central22n) {
177  return central22(A,dim);
178}
179
180BZ_DECLARE_DIFF(central32n) {
181  return central32(A,dim) * recip_2;
182}
183
184BZ_DECLARE_DIFF(central42n) {
185  return central42(A,dim);
186}
187
188/****************************************************************************
189 * Central differences with accuracy O(h^2)  (normalized multicomponent)
190 ****************************************************************************/
191
192BZ_DECLARE_MULTIDIFF(central12n) {
193  return central12(A,comp,dim) * recip_2;
194}
195
196BZ_DECLARE_MULTIDIFF(central22n) {
197  return central22(A,comp,dim);
198}
199
200BZ_DECLARE_MULTIDIFF(central32n) {
201  return central32(A,comp,dim) * recip_2;
202}
203
204BZ_DECLARE_MULTIDIFF(central42n) {
205  return central42(A,comp,dim);
206}
207
208/****************************************************************************
209 * Central differences with accuracy O(h^4) 
210 ****************************************************************************/
211
212BZ_DECLARE_DIFF(central14) {
213  return 8.0 * (A.shift(1,dim) - A.shift(-1,dim))
214    -          (A.shift(2,dim) - A.shift(-2,dim));
215}
216
217BZ_DECLARE_DIFF(central24) {
218  return -30.0 * (*A)
219    + 16.0 * (A.shift(1,dim) + A.shift(-1,dim))
220    -        (A.shift(2,dim) + A.shift(-2,dim));
221}
222
223BZ_DECLARE_DIFF(central34) {
224  return -13.0 * (A.shift(1,dim) - A.shift(-1,dim))
225    +      8.0 * (A.shift(2,dim) - A.shift(-2,dim))
226    -            (A.shift(3,dim) - A.shift(-3,dim));
227}
228
229BZ_DECLARE_DIFF(central44) {
230  return 56.0 * (*A)
231    - 39.0 * (A.shift(1,dim) + A.shift(-1,dim))
232    + 12.0 * (A.shift(2,dim) + A.shift(-2,dim))
233    -        (A.shift(3,dim) + A.shift(-3,dim));
234}
235
236/****************************************************************************
237 * Central differences with accuracy O(h^4)  (multicomponent versions)
238 ****************************************************************************/
239
240BZ_DECLARE_MULTIDIFF(central14) {
241  return 8.0 * (A.shift(1,dim)[comp] - A.shift(-1,dim)[comp])
242    -          (A.shift(2,dim)[comp] - A.shift(-2,dim)[comp]);
243}
244
245BZ_DECLARE_MULTIDIFF(central24) {
246  return - 30.0 * (*A)[comp]
247    + 16.0 * (A.shift(1,dim)[comp] + A.shift(-1,dim)[comp])
248    -        (A.shift(2,dim)[comp] + A.shift(-2,dim)[comp]);
249}
250
251BZ_DECLARE_MULTIDIFF(central34) {
252  return -13.0 * (A.shift(1,dim)[comp] - A.shift(-1,dim)[comp])
253    +      8.0 * (A.shift(2,dim)[comp] - A.shift(-2,dim)[comp])
254    -            (A.shift(3,dim)[comp] - A.shift(-3,dim)[comp]);
255}
256
257BZ_DECLARE_MULTIDIFF(central44) {
258  return 56.0 * (*A)[comp]
259    - 39.0 * (A.shift(1,dim)[comp] + A.shift(-1,dim)[comp])
260    + 12.0 * (A.shift(2,dim)[comp] + A.shift(-2,dim)[comp])
261    -        (A.shift(3,dim)[comp] + A.shift(-3,dim)[comp]);
262}
263
264/****************************************************************************
265 * Central differences with accuracy O(h^4)  (normalized)
266 ****************************************************************************/
267
268BZ_DECLARE_DIFF(central14n) {
269  return central14(A,dim) * recip_12;
270}
271
272BZ_DECLARE_DIFF(central24n) {
273  return central24(A,dim) * recip_12;
274}
275
276BZ_DECLARE_DIFF(central34n) {
277  return central34(A,dim) * recip_8;
278}
279
280BZ_DECLARE_DIFF(central44n) {
281  return central44(A,dim) * recip_6;
282}
283
284/****************************************************************************
285 * Central differences with accuracy O(h^4)  (normalized, multicomponent)
286 ****************************************************************************/
287
288BZ_DECLARE_MULTIDIFF(central14n) {
289  return central14(A,comp,dim) * recip_12;
290}
291
292BZ_DECLARE_MULTIDIFF(central24n) {
293  return central24(A,comp,dim) * recip_12;
294}
295
296BZ_DECLARE_MULTIDIFF(central34n) {
297  return central34(A,comp,dim) * recip_8;
298}
299
300BZ_DECLARE_MULTIDIFF(central44n) {
301  return central44(A,comp,dim) * recip_6;
302}
303
304/****************************************************************************
305 * Backward differences with accuracy O(h)
306 ****************************************************************************/
307
308BZ_DECLARE_DIFF(backward11) {
309  return (*A) - A.shift(-1,dim);
310}
311
312BZ_DECLARE_DIFF(backward21) {
313  return (*A) - 2.0 * A.shift(-1,dim) + A.shift(-2,dim);
314}
315
316BZ_DECLARE_DIFF(backward31) {
317  return (*A) - 3.0 * A.shift(-1,dim) + 3.0 * A.shift(-2,dim)
318    - A.shift(-3,dim);
319}
320
321BZ_DECLARE_DIFF(backward41) {
322  return (*A) - 4.0 * A.shift(-1,dim) + 6.0 * A.shift(-2,dim)
323    - 4.0 * A.shift(-3,dim) + A.shift(-4,dim);
324}
325
326/****************************************************************************
327 * Backward differences with accuracy O(h) (multicomponent versions)
328 ****************************************************************************/
329
330BZ_DECLARE_MULTIDIFF(backward11) {
331  return (*A)[comp] - A.shift(-1,dim)[comp];
332}
333
334BZ_DECLARE_MULTIDIFF(backward21) {
335  return (*A)[comp] - 2.0 * A.shift(-1,dim)[comp] + A.shift(-2,dim)[comp];
336}
337
338BZ_DECLARE_MULTIDIFF(backward31) {
339  return (*A)[comp] - 3.0 * A.shift(-1,dim)[comp] + 3.0 * A.shift(-2,dim)[comp]
340    - A.shift(-3,dim)[comp];
341}
342
343BZ_DECLARE_MULTIDIFF(backward41) {
344  return (*A)[comp] - 4.0 * A.shift(-1,dim)[comp] + 6.0 * A.shift(-2,dim)[comp]
345    - 4.0 * A.shift(-3,dim)[comp] + A.shift(-4,dim)[comp];
346}
347
348/****************************************************************************
349 * Backward differences with accuracy O(h)  (normalized)
350 ****************************************************************************/
351
352BZ_DECLARE_DIFF(backward11n) { return backward11(A,dim); }
353BZ_DECLARE_DIFF(backward21n) { return backward21(A,dim); }
354BZ_DECLARE_DIFF(backward31n) { return backward31(A,dim); }
355BZ_DECLARE_DIFF(backward41n) { return backward41(A,dim); }
356
357/****************************************************************************
358 * Backward differences with accuracy O(h)  (normalized, multicomponent)
359 ****************************************************************************/
360
361BZ_DECLARE_MULTIDIFF(backward11n) { return backward11(A,comp,dim); }
362BZ_DECLARE_MULTIDIFF(backward21n) { return backward21(A,comp,dim); }
363BZ_DECLARE_MULTIDIFF(backward31n) { return backward31(A,comp,dim); }
364BZ_DECLARE_MULTIDIFF(backward41n) { return backward41(A,comp,dim); }
365
366/****************************************************************************
367 * Backward differences with accuracy O(h^2)
368 ****************************************************************************/
369
370BZ_DECLARE_DIFF(backward12) {
371  return 3.0 * (*A) - 4.0 * A.shift(-1,dim) + A.shift(-2,dim);
372}
373
374BZ_DECLARE_DIFF(backward22) {
375  return 2.0 * (*A) - 5.0 * A.shift(-1,dim) + 4.0 * A.shift(-2,dim)
376    - A.shift(-3,dim);
377}
378
379BZ_DECLARE_DIFF(backward32) {
380  return 5.0 * (*A) - 18.0 * A.shift(-1,dim) + 24.0 * A.shift(-2,dim)
381    - 14.0 * A.shift(-3,dim) + 3.0 * A.shift(-4,dim);
382}
383
384BZ_DECLARE_DIFF(backward42) {
385  return 3.0 * (*A) - 14.0 * A.shift(-1,dim) + 26.0 * A.shift(-2,dim)
386    - 24.0 * A.shift(-3,dim) + 11.0 * A.shift(-4,dim) - 2.0 * A.shift(-5,dim);
387}
388
389/****************************************************************************
390 * Backward differences with accuracy O(h^2) (multicomponent versions)
391 ****************************************************************************/
392
393BZ_DECLARE_MULTIDIFF(backward12) {
394  return 3.0 * (*A)[comp] - 4.0 * A.shift(-1,dim)[comp]
395    + A.shift(-2,dim)[comp];
396}
397
398BZ_DECLARE_MULTIDIFF(backward22) {
399  return 2.0 * (*A)[comp] - 5.0 * A.shift(-1,dim)[comp]
400    + 4.0 * A.shift(-2,dim)[comp] - A.shift(-3,dim)[comp];
401}
402
403BZ_DECLARE_MULTIDIFF(backward32) {
404  return 5.0 * (*A)[comp] - 18.0 * A.shift(-1,dim)[comp]
405    + 24.0 * A.shift(-2,dim)[comp] - 14.0 * A.shift(-3,dim)[comp]
406    + 3.0 * A.shift(-4,dim)[comp];
407}
408
409BZ_DECLARE_MULTIDIFF(backward42) {
410  return 3.0 * (*A)[comp] - 14.0 * A.shift(-1,dim)[comp]
411    + 26.0 * A.shift(-2,dim)[comp] - 24.0 * A.shift(-3,dim)[comp]
412    + 11.0 * A.shift(-4,dim)[comp] - 2.0 * A.shift(-5,dim)[comp];
413}
414
415/****************************************************************************
416 * Backward differences with accuracy O(h^2)  (normalized)
417 ****************************************************************************/
418
419BZ_DECLARE_DIFF(backward12n) { return backward12(A,dim) * recip_2; }
420BZ_DECLARE_DIFF(backward22n) { return backward22(A,dim); }
421BZ_DECLARE_DIFF(backward32n) { return backward32(A,dim) * recip_2; }
422BZ_DECLARE_DIFF(backward42n) { return backward42(A,dim); }
423
424/****************************************************************************
425 * Backward differences with accuracy O(h^2)  (normalized, multicomponent)
426 ****************************************************************************/
427
428BZ_DECLARE_MULTIDIFF(backward12n) { return backward12(A,comp,dim) * recip_2; }
429BZ_DECLARE_MULTIDIFF(backward22n) { return backward22(A,comp,dim); }
430BZ_DECLARE_MULTIDIFF(backward32n) { return backward32(A,comp,dim) * recip_2; }
431BZ_DECLARE_MULTIDIFF(backward42n) { return backward42(A,comp,dim); }
432
433/****************************************************************************
434 * Forward differences with accuracy O(h) 
435 ****************************************************************************/
436
437BZ_DECLARE_DIFF(forward11) {
438  return -(*A) + A.shift(1,dim);
439}
440
441BZ_DECLARE_DIFF(forward21) {
442  return (*A) - 2.0 * A.shift(1,dim) + A.shift(2,dim);
443}
444
445BZ_DECLARE_DIFF(forward31) {
446  return -(*A) + 3.0 * A.shift(1,dim) - 3.0 * A.shift(2,dim) + A.shift(3,dim);
447}
448
449BZ_DECLARE_DIFF(forward41) {
450  return (*A) - 4.0 * A.shift(1,dim) + 6.0 * A.shift(2,dim)
451    - 4.0 * A.shift(3,dim) + A.shift(4,dim);
452}
453
454/****************************************************************************
455 * Forward differences with accuracy O(h)  (multicomponent versions)
456 ****************************************************************************/
457
458BZ_DECLARE_MULTIDIFF(forward11) {
459  return  -(*A)[comp] + A.shift(1,dim)[comp];
460}
461
462BZ_DECLARE_MULTIDIFF(forward21) {
463  return (*A)[comp] - 2.0 * A.shift(1,dim)[comp] + A.shift(2,dim)[comp];
464}
465
466BZ_DECLARE_MULTIDIFF(forward31) {
467  return -(*A)[comp] + 3.0 * A.shift(1,dim)[comp] - 3.0 * A.shift(2,dim)[comp]
468    + A.shift(3,dim)[comp];
469}
470
471BZ_DECLARE_MULTIDIFF(forward41) {
472  return (*A)[comp] - 4.0 * A.shift(1,dim)[comp] + 6.0 * A.shift(2,dim)[comp]
473    - 4.0 * A.shift(3,dim)[comp] + A.shift(4,dim)[comp];
474}
475
476/****************************************************************************
477 * Forward differences with accuracy O(h)     (normalized)
478 ****************************************************************************/
479
480BZ_DECLARE_DIFF(forward11n) { return forward11(A,dim); }
481BZ_DECLARE_DIFF(forward21n) { return forward21(A,dim); }
482BZ_DECLARE_DIFF(forward31n) { return forward31(A,dim); }
483BZ_DECLARE_DIFF(forward41n) { return forward41(A,dim); }
484
485/****************************************************************************
486 * Forward differences with accuracy O(h)     (multicomponent,normalized)
487 ****************************************************************************/
488
489BZ_DECLARE_MULTIDIFF(forward11n) { return forward11(A,comp,dim); }
490BZ_DECLARE_MULTIDIFF(forward21n) { return forward21(A,comp,dim); }
491BZ_DECLARE_MULTIDIFF(forward31n) { return forward31(A,comp,dim); }
492BZ_DECLARE_MULTIDIFF(forward41n) { return forward41(A,comp,dim); }
493
494/****************************************************************************
495 * Forward differences with accuracy O(h^2)     
496 ****************************************************************************/
497
498BZ_DECLARE_DIFF(forward12) {
499  return -3.0 * (*A) + 4.0 * A.shift(1,dim) - A.shift(2,dim);
500}
501
502BZ_DECLARE_DIFF(forward22) {
503  return 2.0 * (*A) - 5.0 * A.shift(1,dim) + 4.0 * A.shift(2,dim)
504    - A.shift(3,dim);
505}
506
507BZ_DECLARE_DIFF(forward32) {
508  return -5.0 * (*A) + 18.0 * A.shift(1,dim) - 24.0 * A.shift(2,dim) 
509    + 14.0 * A.shift(3,dim) - 3.0 * A.shift(4,dim);
510}
511
512BZ_DECLARE_DIFF(forward42) {
513  return 3.0 * (*A) - 14.0 * A.shift(1,dim) + 26.0 * A.shift(2,dim)
514    - 24.0 * A.shift(3,dim) + 11.0 * A.shift(4,dim) - 2.0 * A.shift(5,dim);
515}
516
517/****************************************************************************
518 * Forward differences with accuracy O(h^2)   (multicomponent versions)
519 ****************************************************************************/
520
521BZ_DECLARE_MULTIDIFF(forward12) {
522  return -3.0 * (*A)[comp] + 4.0 * A.shift(1,dim)[comp] - A.shift(2,dim)[comp];
523}
524
525BZ_DECLARE_MULTIDIFF(forward22) {
526  return 2.0 * (*A)[comp] - 5.0 * A.shift(1,dim)[comp]
527    + 4.0 * A.shift(2,dim)[comp] - A.shift(3,dim)[comp];
528}
529
530BZ_DECLARE_MULTIDIFF(forward32) {
531  return -5.0 * (*A)[comp] + 18.0 * A.shift(1,dim)[comp]
532    - 24.0 * A.shift(2,dim)[comp] + 14.0 * A.shift(3,dim)[comp]
533    - 3.0 * A.shift(4,dim)[comp];
534}
535
536BZ_DECLARE_MULTIDIFF(forward42) {
537  return 3.0 * (*A)[comp] - 14.0 * A.shift(1,dim)[comp]
538    + 26.0 * A.shift(2,dim)[comp] - 24.0 * A.shift(3,dim)[comp]
539    + 11.0 * A.shift(4,dim)[comp] - 2.0 * A.shift(5,dim)[comp];
540}
541
542
543/****************************************************************************
544 * Forward differences with accuracy O(h^2)     (normalized)
545 ****************************************************************************/
546
547BZ_DECLARE_DIFF(forward12n) { return forward12(A,dim) * recip_2; }
548BZ_DECLARE_DIFF(forward22n) { return forward22(A,dim); }
549BZ_DECLARE_DIFF(forward32n) { return forward32(A,dim) * recip_2; }
550BZ_DECLARE_DIFF(forward42n) { return forward42(A,dim); }
551
552/****************************************************************************
553 * Forward differences with accuracy O(h^2)     (normalized)
554 ****************************************************************************/
555
556BZ_DECLARE_MULTIDIFF(forward12n) { return forward12(A,comp,dim) * recip_2; }
557BZ_DECLARE_MULTIDIFF(forward22n) { return forward22(A,comp,dim); }
558BZ_DECLARE_MULTIDIFF(forward32n) { return forward32(A,comp,dim) * recip_2; }
559BZ_DECLARE_MULTIDIFF(forward42n) { return forward42(A,comp,dim); }
560
561/****************************************************************************
562 * Gradient operators
563 ****************************************************************************/
564
565template<typename T>
566inline TinyVector<_bz_typename T::T_numtype,2> grad2D(T& A) {
567  return TinyVector<_bz_typename T::T_numtype,2>(
568    central12(A,firstDim),
569    central12(A,secondDim));
570}
571
572template<typename T>
573inline TinyVector<_bz_typename T::T_numtype,2> grad2D4(T& A) {
574  return TinyVector<_bz_typename T::T_numtype,2>(
575    central14(A,firstDim),
576    central14(A,secondDim));
577}
578
579template<typename T>
580inline TinyVector<_bz_typename T::T_numtype,3> grad3D(T& A) {
581  return TinyVector<_bz_typename T::T_numtype,3>(
582    central12(A,firstDim),
583    central12(A,secondDim),
584    central12(A,thirdDim));
585}
586
587template<typename T>
588inline TinyVector<_bz_typename T::T_numtype,3> grad3D4(T& A) {
589  return TinyVector<_bz_typename T::T_numtype,3>(
590    central14(A,firstDim),
591    central14(A,secondDim),
592    central14(A,thirdDim));
593}
594
595template<typename T>
596inline TinyVector<_bz_typename T::T_numtype,2> grad2Dn(T& A) {
597  return TinyVector<_bz_typename T::T_numtype,2>(
598    central12n(A,firstDim),
599    central12n(A,secondDim));
600}
601
602template<typename T>
603inline TinyVector<_bz_typename T::T_numtype,2> grad2D4n(T& A) {
604  return TinyVector<_bz_typename T::T_numtype,2>(
605    central14n(A,firstDim),
606    central14n(A,secondDim));
607}
608
609template<typename T>
610inline TinyVector<_bz_typename T::T_numtype,3> grad3Dn(T& A) {
611  return TinyVector<_bz_typename T::T_numtype,3>(
612    central12n(A,firstDim),
613    central12n(A,secondDim),
614    central12n(A,thirdDim));
615}
616
617template<typename T>
618inline TinyVector<_bz_typename T::T_numtype,3> grad3D4n(T& A) {
619  return TinyVector<_bz_typename T::T_numtype,3>(
620    central14n(A,firstDim),
621    central14n(A,secondDim),
622    central14n(A,thirdDim));
623}
624
625/****************************************************************************
626 * Grad-squared operators
627 ****************************************************************************/
628
629template<typename T>
630inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D(T& A) {
631  return TinyVector<_bz_typename T::T_numtype,2>(
632    central22(A,firstDim),
633    central22(A,secondDim));
634}
635
636template<typename T>
637inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D4(T& A) {
638  return TinyVector<_bz_typename T::T_numtype,2>(
639    central24(A,firstDim),
640    central24(A,secondDim));
641}
642
643template<typename T>
644inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D(T& A) {
645  return TinyVector<_bz_typename T::T_numtype,3>(
646    central22(A,firstDim),
647    central22(A,secondDim),
648    central22(A,thirdDim));
649}
650
651template<typename T>
652inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D4(T& A) {
653  return TinyVector<_bz_typename T::T_numtype,3>(
654    central24(A,firstDim),
655    central24(A,secondDim),
656    central24(A,thirdDim));
657}
658
659/****************************************************************************
660 * Grad-squared operators (normalized)
661 ****************************************************************************/
662
663template<typename T>
664inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2Dn(T& A) {
665  return gradSqr2D(A);
666}
667
668template<typename T>
669inline TinyVector<_bz_typename T::T_numtype,2> gradSqr2D4n(T& A) {
670  return TinyVector<_bz_typename T::T_numtype,2>(
671    central24(A,firstDim) * recip_12,
672    central24(A,secondDim) * recip_12);
673}
674
675template<typename T>
676inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3Dn(T& A) {
677  return gradSqr3D(A);
678}
679
680template<typename T>
681inline TinyVector<_bz_typename T::T_numtype,3> gradSqr3D4n(T& A) {
682  return TinyVector<_bz_typename T::T_numtype,3>(
683    central24(A,firstDim) * recip_12,
684    central24(A,secondDim) * recip_12,
685    central24(A,thirdDim) * recip_12);
686}
687
688/****************************************************************************
689 * Gradient operators on a vector field
690 ****************************************************************************/
691
692template<typename T>
693inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
694    T::T_numtype>::T_element, 3, 3>
695Jacobian3D(T& A)
696{
697    const int x=0, y=1, z=2;
698    const int u=0, v=1, w=2;
699
700    TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
701        T::T_numtype>::T_element, 3, 3> grad;
702
703    grad(u,x) = central12(A,u,x);
704    grad(u,y) = central12(A,u,y);
705    grad(u,z) = central12(A,u,z);
706    grad(v,x) = central12(A,v,x);
707    grad(v,y) = central12(A,v,y);
708    grad(v,z) = central12(A,v,z);
709    grad(w,x) = central12(A,w,x);
710    grad(w,y) = central12(A,w,y);
711    grad(w,z) = central12(A,w,z);
712
713    return grad;
714}
715
716template<typename T>
717inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
718    T::T_numtype>::T_element, 3, 3>
719Jacobian3Dn(T& A)
720{
721    const int x=0, y=1, z=2;
722    const int u=0, v=1, w=2;
723
724    TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
725        T::T_numtype>::T_element, 3, 3> grad;
726   
727    grad(u,x) = central12n(A,u,x);
728    grad(u,y) = central12n(A,u,y);
729    grad(u,z) = central12n(A,u,z);
730    grad(v,x) = central12n(A,v,x);
731    grad(v,y) = central12n(A,v,y);
732    grad(v,z) = central12n(A,v,z);
733    grad(w,x) = central12n(A,w,x);
734    grad(w,y) = central12n(A,w,y);
735    grad(w,z) = central12n(A,w,z);
736
737    return grad;
738}
739
740template<typename T>
741inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
742    T::T_numtype>::T_element, 3, 3>
743Jacobian3D4(T& A)
744{
745    const int x=0, y=1, z=2;
746    const int u=0, v=1, w=2;
747
748    TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
749        T::T_numtype>::T_element, 3, 3> grad;
750   
751    grad(u,x) = central14(A,u,x);
752    grad(u,y) = central14(A,u,y);
753    grad(u,z) = central14(A,u,z);
754    grad(v,x) = central14(A,v,x);
755    grad(v,y) = central14(A,v,y);
756    grad(v,z) = central14(A,v,z);
757    grad(w,x) = central14(A,w,x);
758    grad(w,y) = central14(A,w,y);
759    grad(w,z) = central14(A,w,z);
760
761    return grad;
762}
763
764template<typename T>
765inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
766    T::T_numtype>::T_element, 3, 3>
767Jacobian3D4n(T& A)
768{
769    const int x=0, y=1, z=2;
770    const int u=0, v=1, w=2;
771
772    TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
773        T::T_numtype>::T_element, 3, 3> grad;
774   
775    grad(u,x) = central14n(A,u,x);
776    grad(u,y) = central14n(A,u,y);
777    grad(u,z) = central14n(A,u,z);
778    grad(v,x) = central14n(A,v,x);
779    grad(v,y) = central14n(A,v,y);
780    grad(v,z) = central14n(A,v,z);
781    grad(w,x) = central14n(A,w,x);
782    grad(w,y) = central14n(A,w,y);
783    grad(w,z) = central14n(A,w,z);
784
785    return grad;
786}
787
788/****************************************************************************
789 * Curl operators
790 ****************************************************************************/
791
792// O(h^2) curl, using central difference
793
794template<typename T>
795inline TinyVector<_bz_typename T::T_numtype,3> 
796curl(T& vx, T& vy, T& vz) {
797  const int x = firstDim, y = secondDim, z = thirdDim;
798
799  return TinyVector<_bz_typename T::T_numtype,3>(
800    central12(vz,y)-central12(vy,z),
801    central12(vx,z)-central12(vz,x),
802    central12(vy,x)-central12(vx,y));
803}
804
805// Normalized O(h^2) curl, using central difference
806template<typename T>
807inline TinyVector<_bz_typename T::T_numtype,3>
808curln(T& vx, T& vy, T& vz) {
809  const int x = firstDim, y = secondDim, z = thirdDim;
810
811  return TinyVector<_bz_typename T::T_numtype,3>(
812    (central12(vz,y)-central12(vy,z)) * recip_2,
813    (central12(vx,z)-central12(vz,x)) * recip_2,
814    (central12(vy,x)-central12(vx,y)) * recip_2);
815}
816
817// Multicomponent curl
818template<typename T>
819inline _bz_typename T::T_numtype curl(T& A) {
820  const int x = firstDim, y = secondDim, z = thirdDim;
821
822  return _bz_typename T::T_numtype(
823    central12(A,z,y)-central12(A,y,z),
824    central12(A,x,z)-central12(A,z,x),
825    central12(A,y,x)-central12(A,x,y));
826}
827
828// Normalized multicomponent curl
829template<typename T>
830inline _bz_typename T::T_numtype curln(T& A) {
831  const int x = firstDim, y = secondDim, z = thirdDim;
832
833  return _bz_typename T::T_numtype(
834    (central12(A,z,y)-central12(A,y,z)) * recip_2,
835    (central12(A,x,z)-central12(A,z,x)) * recip_2,
836    (central12(A,y,x)-central12(A,x,y)) * recip_2);
837}
838
839// O(h^4) curl, using 4th order central difference
840template<typename T>
841inline TinyVector<_bz_typename T::T_numtype,3>
842curl4(T& vx, T& vy, T& vz) {
843  const int x = firstDim, y = secondDim, z = thirdDim;
844
845  return TinyVector<_bz_typename T::T_numtype,3>(
846    central14(vz,y)-central14(vy,z),
847    central14(vx,z)-central14(vz,x),
848    central14(vy,x)-central14(vx,y));
849}
850
851// O(h^4) curl, using 4th order central difference (multicomponent version)
852template<typename T>
853inline _bz_typename T::T_numtype
854curl4(T& A) {
855  const int x = firstDim, y = secondDim, z = thirdDim;
856
857  return _bz_typename T::T_numtype(
858    central14(A,z,y)-central14(A,y,z),
859    central14(A,x,z)-central14(A,z,x),
860    central14(A,y,x)-central14(A,x,y));
861}
862
863// Normalized O(h^4) curl, using 4th order central difference
864template<typename T>
865inline TinyVector<_bz_typename T::T_numtype,3>
866curl4n(T& vx, T& vy, T& vz) {
867  const int x = firstDim, y = secondDim, z = thirdDim;
868
869  return TinyVector<_bz_typename T::T_numtype,3>(
870    (central14(vz,y)-central14(vy,z)) * recip_2,
871    (central14(vx,z)-central14(vz,x)) * recip_2,
872    (central14(vy,x)-central14(vx,y)) * recip_2);
873}
874
875// O(h^4) curl, using 4th order central difference (normalized multicomponent)
876template<typename T>
877inline _bz_typename T::T_numtype
878curl4n(T& A) {
879  const int x = firstDim, y = secondDim, z = thirdDim;
880
881  return _bz_typename T::T_numtype(
882    (central14(A,z,y)-central14(A,y,z)) * recip_2,
883    (central14(A,x,z)-central14(A,z,x)) * recip_2,
884    (central14(A,y,x)-central14(A,x,y)) * recip_2);
885}
886
887
888
889// Two-dimensional curl
890
891template<typename T>
892inline _bz_typename T::T_numtype
893curl(T& vx, T& vy) {
894  const int x = firstDim, y = secondDim;
895
896  return central12(vy,x)-central12(vx,y);
897}
898
899template<typename T>
900inline _bz_typename T::T_numtype
901curln(T& vx, T& vy) {
902  const int x = firstDim, y = secondDim;
903
904  return (central12(vy,x)-central12(vx,y)) * recip_2;
905}
906
907// Multicomponent curl
908template<typename T>
909inline _bz_typename T::T_numtype::T_numtype curl2D(T& A) {
910  const int x = firstDim, y = secondDim;
911  return central12(A,y,x)-central12(A,x,y);
912}
913
914template<typename T>
915inline _bz_typename T::T_numtype::T_numtype curl2Dn(T& A) {
916  const int x = firstDim, y = secondDim;
917  return (central12(A,y,x)-central12(A,x,y)) * recip_2;
918}
919
920
921// 4th order versions
922
923template<typename T>
924inline _bz_typename T::T_numtype
925curl4(T& vx, T& vy) {
926  const int x = firstDim, y = secondDim;
927
928  return central14(vy,x)-central14(vx,y);
929}
930
931template<typename T>
932inline _bz_typename T::T_numtype
933curl4n(T& vx, T& vy) {
934  const int x = firstDim, y = secondDim;
935
936  return (central14(vy,x)-central14(vx,y)) * recip_12;
937}
938
939// Multicomponent curl
940template<typename T>
941inline _bz_typename T::T_numtype::T_numtype curl2D4(T& A) {
942  const int x = firstDim, y = secondDim;
943  return central14(A,y,x)-central14(A,x,y);
944}
945
946template<typename T>
947inline _bz_typename T::T_numtype::T_numtype curl2D4n(T& A) {
948  const int x = firstDim, y = secondDim;
949  return (central14(A,y,x)-central14(A,x,y)) * recip_12;
950}
951
952/****************************************************************************
953 * Divergence
954 ****************************************************************************/
955
956
957BZ_DECLARE_STENCIL_OPERATOR2(div,vx,vy)
958  return central12(vx,firstDim) + central12(vy,secondDim);
959BZ_END_STENCIL_OPERATOR
960
961BZ_DECLARE_STENCIL_OPERATOR2(divn,vx,vy)
962  return (central12(vx,firstDim) + central12(vy,secondDim))
963     * recip_2;
964BZ_END_STENCIL_OPERATOR
965
966BZ_DECLARE_STENCIL_OPERATOR2(div4,vx,vy)
967  return central14(vx,firstDim) + central14(vy,secondDim);
968BZ_END_STENCIL_OPERATOR
969
970BZ_DECLARE_STENCIL_OPERATOR2(div4n,vx,vy)
971  return (central14(vx,firstDim) + central14(vy,secondDim))
972    * recip_12;
973BZ_END_STENCIL_OPERATOR
974
975BZ_DECLARE_STENCIL_OPERATOR3(div,vx,vy,vz)
976  return central12(vx,firstDim) + central12(vy,secondDim) 
977    + central12(vz,thirdDim);
978BZ_END_STENCIL_OPERATOR
979
980BZ_DECLARE_STENCIL_OPERATOR3(divn,vx,vy,vz)
981  return (central12(vx,firstDim) + central12(vy,secondDim) 
982    + central12(vz,thirdDim)) * recip_2;
983BZ_END_STENCIL_OPERATOR
984
985BZ_DECLARE_STENCIL_OPERATOR3(div4,vx,vy,vz)
986  return central14(vx,firstDim) + central14(vy,secondDim) 
987    + central14(vz,thirdDim);
988BZ_END_STENCIL_OPERATOR
989
990BZ_DECLARE_STENCIL_OPERATOR3(div4n,vx,vy,vz)
991  return (central14(vx,firstDim) + central14(vy,secondDim)
992    + central14(vz,thirdDim)) * recip_12;
993BZ_END_STENCIL_OPERATOR
994
995template<typename T>
996inline _bz_typename T::T_numtype::T_numtype
997div2D(T& A)
998{
999    const int x = firstDim, y = secondDim;
1000    return central12(A,x,x) + central12(A,y,y);
1001}
1002
1003template<typename T>
1004inline _bz_typename T::T_numtype::T_numtype
1005div2D4(T& A)
1006{
1007    const int x = firstDim, y = secondDim;
1008    return central14(A,x,x) + central14(A,y,y);
1009}
1010
1011template<typename T>
1012inline _bz_typename T::T_numtype::T_numtype
1013div2Dn(T& A)
1014{
1015    const int x = firstDim, y = secondDim;
1016    return (central12(A,x,x) + central12(A,y,y)) * recip_2;
1017}
1018
1019template<typename T>
1020inline _bz_typename T::T_numtype::T_numtype
1021div2D4n(T& A)
1022{
1023    const int x = firstDim, y = secondDim;
1024    return (central14(A,x,x) + central14(A,y,y)) * recip_12;
1025}
1026
1027template<typename T>
1028inline _bz_typename T::T_numtype::T_numtype
1029div3D(T& A)
1030{
1031    const int x = firstDim, y = secondDim, z = thirdDim;
1032    return central12(A,x,x) + central12(A,y,y) + central12(A,z,z);
1033}
1034
1035template<typename T>
1036inline _bz_typename T::T_numtype::T_numtype
1037div3D4(T& A)
1038{
1039    const int x = firstDim, y = secondDim, z = thirdDim;
1040    return central14(A,x,x) + central14(A,y,y) + central14(A,z,z);
1041}
1042
1043template<typename T>
1044inline _bz_typename T::T_numtype::T_numtype
1045div3Dn(T& A)
1046{
1047    const int x = firstDim, y = secondDim, z = thirdDim;
1048    return (central12(A,x,x) + central12(A,y,y) + central12(A,z,z)) * recip_2;
1049}
1050
1051template<typename T>
1052inline _bz_typename T::T_numtype::T_numtype
1053div3D4n(T& A)
1054{
1055    const int x = firstDim, y = secondDim, z = thirdDim;
1056    return (central14(A,x,x) + central14(A,y,y) + central14(A,z,z)) * recip_12;
1057}
1058
1059/****************************************************************************
1060 * Mixed Partial derivatives
1061 ****************************************************************************/
1062
1063template<typename T>
1064inline _bz_typename T::T_numtype
1065mixed22(T& A, int x, int y)
1066{
1067    return A.shift(-1,x,-1,y) - A.shift(-1,x,1,y)
1068        -  A.shift(1,x,-1,y) + A.shift(1,x,1,y);
1069}
1070
1071template<typename T>
1072inline _bz_typename T::T_numtype
1073mixed22n(T& A, int x, int y)
1074{
1075    return mixed22(A,x,y) * recip_4;
1076}
1077
1078template<typename T>
1079inline _bz_typename T::T_numtype
1080mixed24(T& A, int x, int y)
1081{
1082    return 64.0 * (A.shift(-1,x,-1,y) - A.shift(-1,x,1,y) -
1083                   A.shift(1,x,-1,y) + A.shift(1,x,1,y))
1084        +         (A.shift(-2,x,1,y) - A.shift(-1,x,2,y) -
1085                   A.shift(1,x,2,y) - A.shift(2,x,1,y) +
1086                   A.shift(2,x,-1,y) + A.shift(1,x,-2,y) -
1087                   A.shift(-1,x,-2,y) + A.shift(-2,x,-1,y))
1088        +   8.0 * (A.shift(-1,x,1,y) + A.shift(-1,x,2,y) -
1089                   A.shift(2,x,-2,y) + A.shift(2,x,2,y));
1090}
1091
1092template<typename T>
1093inline _bz_typename T::T_numtype
1094mixed24n(T& A, int x, int y)
1095{
1096    return mixed24(A,x,y) * recip_144;
1097}
1098
1099/****************************************************************************
1100 * Smoothers
1101 ****************************************************************************/
1102
1103// NEEDS_WORK-- put other stencil operators here:
1104//   Average5pt2D
1105//   Average7pt3D
1106// etc.
1107
1108/****************************************************************************
1109 * Stencil operators with geometry (experimental)
1110 ****************************************************************************/
1111
1112template<typename T>
1113inline _bz_typename multicomponent_traits<_bz_typename
1114    T::T_numtype>::T_element div3DVec4(T& A, 
1115    const UniformCubicGeometry<3>& geom)
1116{
1117    const int x = 0, y = 1, z = 2;
1118
1119    return (central14(A, x, firstDim) + central14(A, y, secondDim)
1120        + central14(A, z, thirdDim)) * recip_12 * geom.recipSpatialStep();
1121}
1122
1123template<typename T>
1124inline _bz_typename T::T_numtype Laplacian3D4(T& A, 
1125    const UniformCubicGeometry<3>& geom)
1126{
1127    return Laplacian3D4n(A) * geom.recipSpatialStepPow2();
1128}
1129
1130template<typename T>
1131inline _bz_typename T::T_numtype Laplacian3DVec4(T& A,
1132    const UniformCubicGeometry<3>& geom)
1133{
1134    typedef _bz_typename T::T_numtype vector3d;
1135    typedef _bz_typename multicomponent_traits<vector3d>::T_element
1136        T_element;
1137    const int u = 0, v = 1, w = 2;
1138    const int x = 0, y = 1, z = 2;
1139
1140    // central24 is a 5-point stencil
1141    // This is a 9*5 = 45 point stencil
1142
1143    T_element t1 = (central24(A,u,x) + central24(A,u,y) + central24(A,u,z))
1144        * recip_12 * geom.recipSpatialStepPow2();
1145
1146    T_element t2 = (central24(A,v,x) + central24(A,v,y) + central24(A,v,z))
1147        * recip_12 * geom.recipSpatialStepPow2();
1148
1149    T_element t3 = (central24(A,w,x) + central24(A,w,y) + central24(A,w,z))
1150        * recip_12 * geom.recipSpatialStepPow2();
1151
1152    return vector3d(t1,t2,t3);
1153}
1154
1155template<typename T>
1156inline TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
1157    T::T_numtype>::T_element, 3, 3>
1158grad3DVec4(T& A, const UniformCubicGeometry<3>& geom)
1159{
1160    const int x=0, y=1, z=2;
1161    const int u=0, v=1, w=2;
1162
1163    TinyMatrix<_bz_typename multicomponent_traits<_bz_typename
1164        T::T_numtype>::T_element, 3, 3> grad;
1165
1166    // This is a 9*4 = 36 point stencil
1167    grad(u,x) = central14n(A,u,x) * geom.recipSpatialStep();
1168    grad(u,y) = central14n(A,u,y) * geom.recipSpatialStep();
1169    grad(u,z) = central14n(A,u,z) * geom.recipSpatialStep();
1170    grad(v,x) = central14n(A,v,x) * geom.recipSpatialStep();
1171    grad(v,y) = central14n(A,v,y) * geom.recipSpatialStep();
1172    grad(v,z) = central14n(A,v,z) * geom.recipSpatialStep();
1173    grad(w,x) = central14n(A,w,x) * geom.recipSpatialStep();
1174    grad(w,y) = central14n(A,w,y) * geom.recipSpatialStep();
1175    grad(w,z) = central14n(A,w,z) * geom.recipSpatialStep();
1176
1177    return grad;
1178}
1179
1180template<typename T>
1181inline TinyVector<_bz_typename T::T_numtype,3> grad3D4(T& A,
1182    const UniformCubicGeometry<3>& geom) {
1183  return TinyVector<_bz_typename T::T_numtype,3>(
1184    central14(A,firstDim) * recip_12 * geom.recipSpatialStep(),
1185    central14(A,secondDim) * recip_12 * geom.recipSpatialStep(),
1186    central14(A,thirdDim) * recip_12 * geom.recipSpatialStep());
1187}
1188
1189BZ_NAMESPACE_END
1190
1191#endif // BZ_ARRAYSTENCILOPS_H
1192
Note: See TracBrowser for help on using the repository browser.