aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpollney <pollney@c78560ca-4b45-4335-b268-5f3340f3cb52>2002-06-10 09:54:03 +0000
committerpollney <pollney@c78560ca-4b45-4335-b268-5f3340f3cb52>2002-06-10 09:54:03 +0000
commitb5cb6c915077b883a637178a3a070b0dae739b83 (patch)
tree6aa06e1564a8a65b031e6bec7311760ac2c9e496
parentc340c4d5674bf05cada2bb73fd0a04be6e354204 (diff)
Added "bitant_rotate" and "quadrant_reflect_rotate" domains for
systems which have a rotational symmetry. There are some notes describing these domains and the implementation in the doc directory: rotating_sym.tex Currently only works for a single processor. git-svn-id: http://svn.cactuscode.org/arrangements/CactusBase/CartGrid3D/trunk@161 c78560ca-4b45-4335-b268-5f3340f3cb52
-rw-r--r--doc/fig/rotate_bbh.eps162
-rw-r--r--doc/fig/rotate_bbh.fig29
-rw-r--r--doc/fig/rotate_bitant.eps143
-rw-r--r--doc/fig/rotate_bitant.fig25
-rw-r--r--doc/fig/rotate_bitant.fig.bak25
-rw-r--r--doc/fig/rotate_bitant_example.eps193
-rw-r--r--doc/fig/rotate_bitant_example.fig46
-rw-r--r--doc/fig/rotate_general.eps138
-rw-r--r--doc/fig/rotate_general.fig19
-rw-r--r--doc/fig/rotate_general.fig.bak18
-rw-r--r--doc/fig/rotate_grid.eps197
-rw-r--r--doc/fig/rotate_grid.fig54
-rw-r--r--doc/fig/rotate_octant.eps143
-rw-r--r--doc/fig/rotate_octant.fig25
-rw-r--r--doc/fig/rotate_octant.fig.bak23
-rw-r--r--doc/fig/rotate_quadrant_example.eps200
-rw-r--r--doc/fig/rotate_quadrant_example.fig47
-rw-r--r--doc/fig/rotate_reflect.eps340
-rw-r--r--doc/fig/rotate_reflect.fig101
-rw-r--r--doc/rotating_sym.tex468
-rw-r--r--param.ccl18
-rw-r--r--src/CartGrid3D.c14
-rw-r--r--src/DecodeSymParameters.c92
-rw-r--r--src/ParamCheck.c52
-rw-r--r--src/SetSymmetry.c38
-rw-r--r--src/Symmetry.c211
-rw-r--r--src/Symmetry.h12
-rw-r--r--src/SymmetryWrappers.c27
28 files changed, 2795 insertions, 65 deletions
diff --git a/doc/fig/rotate_bbh.eps b/doc/fig/rotate_bbh.eps
new file mode 100644
index 0000000..a4a2eb0
--- /dev/null
+++ b/doc/fig/rotate_bbh.eps
@@ -0,0 +1,162 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: rotate_bbh.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 3d
+%%CreationDate: Thu Jun 6 19:51:10 2002
+%%For: dp@nbdell15 (Denis Pollney,,,)
+%%BoundingBox: 0 0 203 204
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 204 moveto 0 0 lineto 203 0 lineto 203 204 lineto closepath clip newpath
+-78.6 264.4 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% Polyline
+7.500 slw
+n 2700 1350 m 4050 1350 l 4050 4050 l 2700 4050 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Ellipse
+n 3375 2250 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr
+
+% Ellipse
+n 2025 3375 64 64 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr
+
+% Polyline
+n 1350 1350 m 4050 1350 l 4050 4050 l 1350 4050 l
+ cp gs col0 s gr
+% Polyline
+gs clippath
+2421 3767 m 2460 3721 l 2346 3623 l 2418 3724 l 2307 3668 l cp
+eoclip
+n 2115 3465 m
+ 2430 3735 l gs col0 s gr gr
+
+% arrowhead
+n 2307 3668 m 2418 3724 l 2346 3623 l 2307 3668 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+2978 1857 m 2939 1903 l 3053 2001 l 2982 1901 l 3092 1956 l cp
+eoclip
+n 3285 2160 m
+ 2970 1890 l gs col0 s gr gr
+
+% arrowhead
+n 3092 1956 m 2982 1901 l 3053 2001 l 3092 1956 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+4290 2730 m 4290 2670 l 4139 2670 l 4259 2700 l 4139 2730 l cp
+eoclip
+n 1260 2700 m
+ 4275 2700 l gs col0 s gr gr
+
+% arrowhead
+n 4139 2730 m 4259 2700 l 4139 2670 l 4139 2730 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+2730 1110 m 2670 1110 l 2670 1261 l 2700 1141 l 2730 1261 l cp
+eoclip
+n 2700 4185 m
+ 2700 1125 l gs col0 s gr gr
+
+% arrowhead
+n 2730 1261 m 2700 1141 l 2670 1261 l 2730 1261 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+2655 1080 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4365 2745 m
+gs 1 -1 sc (x) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/fig/rotate_bbh.fig b/doc/fig/rotate_bbh.fig
new file mode 100644
index 0000000..970fcb2
--- /dev/null
+++ b/doc/fig/rotate_bbh.fig
@@ -0,0 +1,29 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 3375 2250 64 64 3375 2250 3439 2250
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2025 3375 64 64 2025 3375 2089 3375
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 1350 1350 4050 1350 4050 4050 1350 4050 1350 1350
+2 2 0 1 0 6 60 0 20 0.000 0 0 -1 0 0 5
+ 2700 1350 4050 1350 4050 4050 2700 4050 2700 1350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2115 3465 2430 3735
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3285 2160 2970 1890
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1260 2700 4275 2700
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2700 4185 2700 1125
+4 0 0 50 0 16 12 0.0000 4 150 105 2655 1080 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 4365 2745 x\001
diff --git a/doc/fig/rotate_bitant.eps b/doc/fig/rotate_bitant.eps
new file mode 100644
index 0000000..88d0bcb
--- /dev/null
+++ b/doc/fig/rotate_bitant.eps
@@ -0,0 +1,143 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: rotate_bitant.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 3d
+%%CreationDate: Sun Jun 9 11:06:24 2002
+%%For: pollney@xeon20.aei-potsdam.mpg.de (Denis Pollney,0.21,1.21,none)
+%%BoundingBox: 0 0 165 202
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 202 moveto 0 0 lineto 165 0 lineto 165 202 lineto closepath clip newpath
+-56.7 261.5 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% Arc
+7.500 slw
+gs clippath
+1765 3181 m 1774 3122 l 1624 3100 l 1739 3148 l 1615 3159 l cp
+1774 2277 m 1765 2218 l 1615 2240 l 1739 2252 l 1624 2299 l cp
+eoclip
+n 1755.0 2700.0 450.0 -90.0 90.0 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+n 1615 3159 m 1739 3148 l 1624 3100 l 1615 3159 l cp gs 0.00 setgray ef gr col0 s
+% arrowhead
+n 1624 2299 m 1739 2252 l 1615 2240 l 1624 2299 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 1800 1350 m 3150 1350 l 3150 4050 l 1800 4050 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Polyline
+gs clippath
+3390 2730 m 3390 2670 l 3239 2670 l 3359 2700 l 3239 2730 l cp
+eoclip
+n 1710 2700 m
+ 3375 2700 l gs col0 s gr gr
+
+% arrowhead
+n 3239 2730 m 3359 2700 l 3239 2670 l 3239 2730 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+1830 1110 m 1770 1110 l 1770 1261 l 1800 1141 l 1830 1261 l cp
+eoclip
+n 1800 4140 m
+ 1800 1125 l gs col0 s gr gr
+
+% arrowhead
+n 1830 1261 m 1800 1141 l 1770 1261 l 1830 1261 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+1755 1080 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3420 2790 m
+gs 1 -1 sc (x) col0 sh gr
+/Symbol ff 180.00 scf sf
+900 2745 m
+gs 1 -1 sc (q=p) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1575 2025 m
+gs 1 -1 sc (A) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1575 3600 m
+gs 1 -1 sc (B) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/fig/rotate_bitant.fig b/doc/fig/rotate_bitant.fig
new file mode 100644
index 0000000..ac2e497
--- /dev/null
+++ b/doc/fig/rotate_bitant.fig
@@ -0,0 +1,25 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 0 -1 0.000 0 1 1 1 1755.000 2700.000 1755 2250 1305 2700 1755 3150
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
+ 1800 1350 3150 1350 3150 4050 1800 4050 1800 1350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1710 2700 3375 2700
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1800 4140 1800 1125
+4 0 0 50 0 16 12 0.0000 4 150 105 1755 1080 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 3420 2790 x\001
+4 0 0 50 0 32 12 0.0000 4 135 315 900 2745 q=p\001
+4 0 0 50 0 16 12 0.0000 4 135 135 1575 2025 A\001
+4 0 0 50 0 16 12 0.0000 4 135 120 1575 3600 B\001
diff --git a/doc/fig/rotate_bitant.fig.bak b/doc/fig/rotate_bitant.fig.bak
new file mode 100644
index 0000000..cbf06fa
--- /dev/null
+++ b/doc/fig/rotate_bitant.fig.bak
@@ -0,0 +1,25 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 0 -1 0.000 0 1 1 1 1755.000 2700.000 1755 2250 1305 2700 1755 3150
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
+ 1800 1350 3150 1350 3150 4050 1800 4050 1800 1350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1710 2700 3375 2700
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1800 4140 1800 1125
+4 0 0 50 0 16 12 0.0000 4 150 105 1755 1080 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 3420 2790 x\001
+4 0 0 50 0 32 12 0.0000 4 135 315 900 2745 q=p\001
+4 0 0 50 0 16 12 0.0000 4 135 135 1575 2025 A\001
+4 0 0 50 0 16 12 0.0000 4 135 120 1575 3825 B\001
diff --git a/doc/fig/rotate_bitant_example.eps b/doc/fig/rotate_bitant_example.eps
new file mode 100644
index 0000000..91254da
--- /dev/null
+++ b/doc/fig/rotate_bitant_example.eps
@@ -0,0 +1,193 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: rotate_bitant_example.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 3d
+%%CreationDate: Sat Jun 8 19:19:08 2002
+%%For: dp@nbdell15 (Denis Pollney,,,)
+%%BoundingBox: 0 0 302 269
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 269 moveto 0 0 lineto 302 0 lineto 302 269 lineto closepath clip newpath
+-65.2 315.4 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% Polyline
+7.500 slw
+n 1800 2250 m 3375 2250 l 3375 4725 l 1800 4725 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 3375 1350 m 1800 2250 l 3375 2250 l 4950 1350 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 3375 2250 m 4950 1350 l 4950 3825 l 3375 4725 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Ellipse
+n 2700 1350 315 135 0 360 DrawEllipse gs col0 s gr
+
+% Polyline
+gs clippath
+1142 3806 m 1171 3858 l 1303 3783 l 1184 3817 l 1273 3731 l cp
+eoclip
+n 1800 3465 m
+ 1170 3825 l gs col0 s gr gr
+
+% arrowhead
+n 1273 3731 m 1184 3817 l 1303 3783 l 1273 3731 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+n 3375 1350 m
+ 3375 3825 l gs col0 s gr [] 0 sd
+% Polyline
+ [60] 0 sd
+n 3375 3825 m
+ 4950 3825 l gs col0 s gr [] 0 sd
+% Polyline
+ [60] 0 sd
+n 3375 3825 m
+ 1800 4725 l gs col0 s gr [] 0 sd
+% Polyline
+ [60] 0 sd
+n 2700 1755 m
+ 2700 4725 l gs col0 s gr [] 0 sd
+% Polyline
+ [60] 0 sd
+n 1805 3474 m
+ 4145 2124 l gs col0 s gr [] 0 sd
+% Polyline
+ [60] 0 sd
+n 4140 2970 m
+ 1575 2970 l gs col0 s gr [] 0 sd
+% Polyline
+gs clippath
+5685 3000 m 5685 2940 l 5534 2940 l 5654 2970 l 5534 3000 l cp
+eoclip
+n 4140 2970 m
+ 5670 2970 l gs col0 s gr gr
+
+% arrowhead
+n 5534 3000 m 5654 2970 l 5534 2940 l 5534 3000 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 2700 4725 m
+ 2700 4995 l gs col0 s gr
+% Polyline
+ [60] 0 sd
+n 1800 2970 m
+ 1575 2970 l gs col0 s gr [] 0 sd
+% Polyline
+gs clippath
+2730 885 m 2670 885 l 2670 1036 l 2700 916 l 2730 1036 l cp
+eoclip
+n 2700 1710 m
+ 2700 900 l gs col0 s gr gr
+
+% arrowhead
+n 2730 1036 m 2700 916 l 2670 1036 l 2730 1036 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+1035 3960 m
+gs 1 -1 sc (x) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2655 855 m
+gs 1 -1 sc (z) col0 sh gr
+/Helvetica ff 180.00 scf sf
+5715 3015 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1710 1305 m
+gs 1 -1 sc (rotation) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1845 1485 m
+gs 1 -1 sc (axis) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/fig/rotate_bitant_example.fig b/doc/fig/rotate_bitant_example.fig
new file mode 100644
index 0000000..38d3e2d
--- /dev/null
+++ b/doc/fig/rotate_bitant_example.fig
@@ -0,0 +1,46 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+1 1 0 1 0 7 50 0 -1 0.000 1 0.0000 2700 1350 315 135 2700 1350 3015 1350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1800 3465 1170 3825
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 3375 1350 3375 3825
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 3375 3825 4950 3825
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 3375 3825 1800 4725
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 2700 1755 2700 4725
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 1805 3474 4145 2124
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 4140 2970 1575 2970
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4140 2970 5670 2970
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 2700 4725 2700 4995
+2 2 0 1 0 6 60 0 20 0.000 0 0 -1 0 0 5
+ 1800 2250 3375 2250 3375 4725 1800 4725 1800 2250
+2 3 0 1 0 6 60 0 20 0.000 0 0 -1 0 0 5
+ 3375 1350 1800 2250 3375 2250 4950 1350 3375 1350
+2 3 0 1 0 6 60 0 20 0.000 0 0 -1 0 0 5
+ 3375 2250 4950 1350 4950 3825 3375 4725 3375 2250
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 1800 2970 1575 2970
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2700 1710 2700 900
+4 0 0 50 0 16 12 0.0000 4 105 90 1035 3960 x\001
+4 0 0 50 0 16 12 0.0000 4 105 90 2655 855 z\001
+4 0 0 50 0 16 12 0.0000 4 150 105 5715 3015 y\001
+4 0 0 50 0 16 12 0.0000 4 135 615 1710 1305 rotation\001
+4 0 0 50 0 16 12 0.0000 4 135 330 1845 1485 axis\001
diff --git a/doc/fig/rotate_general.eps b/doc/fig/rotate_general.eps
new file mode 100644
index 0000000..5d48bed
--- /dev/null
+++ b/doc/fig/rotate_general.eps
@@ -0,0 +1,138 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: rotate_general.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 3d
+%%CreationDate: Sun Jun 9 11:03:43 2002
+%%For: pollney@xeon20.aei-potsdam.mpg.de (Denis Pollney,0.21,1.21,none)
+%%BoundingBox: 0 0 154 158
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 158 moveto 0 0 lineto 154 0 lineto 154 158 lineto closepath clip newpath
+-73.7 241.7 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% Arc
+7.500 slw
+gs clippath
+2053 2808 m 2022 2756 l 1892 2833 l 2011 2798 l 1923 2885 l cp
+2022 2193 m 2053 2141 l 1923 2064 l 2011 2152 l 1892 2116 l cp
+eoclip
+n 1761.0 2475.0 411.0 -50.0 50.0 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+n 1923 2885 m 2011 2798 l 1892 2833 l 1923 2885 l cp gs 0.00 setgray ef gr col0 s
+% arrowhead
+n 1892 2116 m 2011 2152 l 1923 2064 l 1892 2116 l cp gs 0.00 setgray ef gr col0 s
+% Ellipse
+n 1800 2475 45 45 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr
+
+% Polyline
+n 1800 2475 m 3600 1350 l 3600 3825 l
+ 1800 2475 l cp gs col6 1.00 shd ef gr gs col0 s gr
+/Symbol ff 180.00 scf sf
+1170 2475 m
+gs 1 -1 sc (q) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2340 1980 m
+gs 1 -1 sc (A) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2340 3240 m
+gs 1 -1 sc (B) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2925 2610 m
+gs 1 -1 sc (Grid) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/fig/rotate_general.fig b/doc/fig/rotate_general.fig
new file mode 100644
index 0000000..5658283
--- /dev/null
+++ b/doc/fig/rotate_general.fig
@@ -0,0 +1,19 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 0 -1 0.000 0 1 1 1 1761.000 2475.000 2025 2160 1350 2475 2025 2790
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 1800 2475 45 45 1800 2475 1845 2475
+2 1 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 4
+ 1800 2475 3600 1350 3600 3825 1800 2475
+4 0 0 50 0 32 12 0.0000 4 135 105 1170 2475 q\001
+4 0 0 50 0 16 12 0.0000 4 135 135 2340 1980 A\001
+4 0 0 50 0 16 12 0.0000 4 135 120 2340 3240 B\001
+4 0 0 50 0 16 12 0.0000 4 135 345 2925 2610 Grid\001
diff --git a/doc/fig/rotate_general.fig.bak b/doc/fig/rotate_general.fig.bak
new file mode 100644
index 0000000..eb39772
--- /dev/null
+++ b/doc/fig/rotate_general.fig.bak
@@ -0,0 +1,18 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 0 -1 0.000 0 1 1 0 1761.000 2475.000 2025 2160 1350 2475 2025 2790
+ 1 1 1.00 60.00 120.00
+1 3 0 1 0 0 50 0 20 0.000 1 0.0000 1800 2475 45 45 1800 2475 1845 2475
+2 1 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 4
+ 1800 2475 3600 1350 3600 3825 1800 2475
+4 0 0 50 0 32 12 0.0000 4 135 105 1170 2475 q\001
+4 0 0 50 0 16 12 0.0000 4 135 135 2340 1980 A\001
+4 0 0 50 0 16 12 0.0000 4 135 120 2340 3240 B\001
+4 0 0 50 0 16 12 0.0000 4 135 345 2925 2610 Grid\001
diff --git a/doc/fig/rotate_grid.eps b/doc/fig/rotate_grid.eps
new file mode 100644
index 0000000..a725f92
--- /dev/null
+++ b/doc/fig/rotate_grid.eps
@@ -0,0 +1,197 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: rotate_grid.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 3d
+%%CreationDate: Sat Jun 8 18:10:26 2002
+%%For: dp@nbdell15 (Denis Pollney,,,)
+%%BoundingBox: 0 0 290 261
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 261 moveto 0 0 lineto 290 0 lineto 290 261 lineto closepath clip newpath
+-59.5 346.6 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% Polyline
+7.500 slw
+n 1800 1800 m 5175 1800 l 5175 5400 l 1800 5400 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 2070 1800 m
+ 2070 2565 l gs col0 s gr
+% Polyline
+n 2430 2070 m
+ 1800 2070 l gs col0 s gr
+% Polyline
+n 2430 2295 m
+ 1800 2295 l gs col0 s gr
+% Polyline
+n 1530 4635 m
+ 1530 5400 l gs col0 s gr
+% Polyline
+n 1800 5400 m 1260 5400 l 1260 1800 l 1800 1800 l
+ cp gs col0 s gr
+% Polyline
+n 2430 2520 m
+ 1800 2520 l gs col0 s gr
+% Polyline
+n 2340 1800 m
+ 2340 2565 l gs col0 s gr
+% Polyline
+n 1260 5175 m
+ 1800 5175 l gs col0 s gr
+% Polyline
+n 1260 4950 m
+ 1800 4950 l gs col0 s gr
+% Polyline
+n 1260 4725 m
+ 1800 4725 l gs col0 s gr
+% Polyline
+gs clippath
+1830 1560 m 1770 1560 l 1770 1711 l 1800 1591 l 1830 1711 l cp
+eoclip
+n 1800 5490 m
+ 1800 1575 l gs col0 s gr gr
+
+% arrowhead
+n 1830 1711 m 1800 1591 l 1770 1711 l 1830 1711 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+5415 3630 m 5415 3570 l 5264 3570 l 5384 3600 l 5264 3630 l cp
+eoclip
+n 1125 3600 m
+ 5400 3600 l gs col0 s gr gr
+
+% arrowhead
+n 5264 3630 m 5384 3600 l 5264 3570 l 5264 3630 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+1845 2025 m
+gs 1 -1 sc (00 01) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1845 2250 m
+gs 1 -1 sc (10 11) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1845 2475 m
+gs 1 -1 sc (20 21) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1305 5130 m
+gs 1 -1 sc (11 10) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1305 5355 m
+gs 1 -1 sc (01 00) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1305 4905 m
+gs 1 -1 sc (21 20) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3105 2880 m
+gs 1 -1 sc (physical grid) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1575 4095 m
+gs 1 -1 sc 90.0 rot (ghost zones) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1800 1485 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+5445 3690 m
+gs 1 -1 sc (x) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1935 1755 m
+gs 1 -1 sc (0) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2160 1755 m
+gs 1 -1 sc (1) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4995 1755 m
+gs 1 -1 sc (n) col0 sh gr
+/Helvetica ff 180.00 scf sf
+945 1980 m
+gs 1 -1 sc (0) col0 sh gr
+/Helvetica ff 180.00 scf sf
+945 2205 m
+gs 1 -1 sc (1) col0 sh gr
+/Helvetica ff 180.00 scf sf
+945 5400 m
+gs 1 -1 sc (m) col0 sh gr
+/Times-Roman ff 180.00 scf sf
+945 2430 m
+gs 1 -1 sc (2) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/fig/rotate_grid.fig b/doc/fig/rotate_grid.fig
new file mode 100644
index 0000000..f2897c2
--- /dev/null
+++ b/doc/fig/rotate_grid.fig
@@ -0,0 +1,54 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+2 2 0 1 0 6 60 0 20 0.000 0 0 -1 0 0 5
+ 1800 1800 5175 1800 5175 5400 1800 5400 1800 1800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 2070 1800 2070 2565
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 2430 2070 1800 2070
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 2430 2295 1800 2295
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 1530 4635 1530 5400
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 1800 5400 1260 5400 1260 1800 1800 1800 1800 5400
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 2430 2520 1800 2520
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 2340 1800 2340 2565
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 1260 5175 1800 5175
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 1260 4950 1800 4950
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2
+ 1260 4725 1800 4725
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1800 5490 1800 1575
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1125 3600 5400 3600
+4 0 0 50 0 16 12 0.0000 4 135 480 1845 2025 00 01\001
+4 0 0 50 0 16 12 0.0000 4 135 480 1845 2250 10 11\001
+4 0 0 50 0 16 12 0.0000 4 135 480 1845 2475 20 21\001
+4 0 0 50 0 16 12 0.0000 4 135 480 1305 5130 11 10\001
+4 0 0 50 0 16 12 0.0000 4 135 480 1305 5355 01 00\001
+4 0 0 50 0 16 12 0.0000 4 135 480 1305 4905 21 20\001
+4 0 0 50 0 16 12 0.0000 4 180 1080 3105 2880 physical grid\001
+4 0 0 50 0 16 12 1.5708 4 180 1005 1575 4095 ghost zones\001
+4 0 0 50 0 16 12 0.0000 4 150 105 1800 1485 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 5445 3690 x\001
+4 0 0 50 0 16 12 0.0000 4 135 105 1935 1755 0\001
+4 0 0 50 0 16 12 0.0000 4 135 105 2160 1755 1\001
+4 0 0 50 0 16 12 0.0000 4 105 105 4995 1755 n\001
+4 0 0 50 0 16 12 0.0000 4 135 105 945 1980 0\001
+4 0 0 50 0 16 12 0.0000 4 135 105 945 2205 1\001
+4 0 0 50 0 16 12 0.0000 4 105 135 945 5400 m\001
+4 0 0 50 0 0 12 0.0000 4 135 90 945 2430 2\001
diff --git a/doc/fig/rotate_octant.eps b/doc/fig/rotate_octant.eps
new file mode 100644
index 0000000..2fa5e69
--- /dev/null
+++ b/doc/fig/rotate_octant.eps
@@ -0,0 +1,143 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: rotate_octant.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 3d
+%%CreationDate: Sun Jun 9 11:05:54 2002
+%%For: pollney@xeon20.aei-potsdam.mpg.de (Denis Pollney,0.21,1.21,none)
+%%BoundingBox: 0 0 148 130
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 130 moveto 0 0 lineto 148 0 lineto 148 130 lineto closepath clip newpath
+-31.2 218.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% Arc
+7.500 slw
+gs clippath
+1833 3011 m 1777 2990 l 1724 3132 l 1794 3030 l 1780 3152 l cp
+1327 2499 m 1311 2442 l 1165 2482 l 1289 2479 l 1181 2539 l cp
+eoclip
+n 1357.6 2923.7 451.8 -96.7 11.7 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+n 1780 3152 m 1794 3030 l 1724 3132 l 1780 3152 l cp gs 0.00 setgray ef gr col0 s
+% arrowhead
+n 1181 2539 m 1289 2479 l 1165 2482 l 1181 2539 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+n 1350 1800 m 2475 1800 l 2475 2925 l 1350 2925 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Polyline
+gs clippath
+2715 2955 m 2715 2895 l 2564 2895 l 2684 2925 l 2564 2955 l cp
+eoclip
+n 1260 2925 m
+ 2700 2925 l gs col0 s gr gr
+
+% arrowhead
+n 2564 2955 m 2684 2925 l 2564 2895 l 2564 2955 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+1380 1560 m 1320 1560 l 1320 1711 l 1350 1591 l 1380 1711 l cp
+eoclip
+n 1350 3015 m
+ 1350 1575 l gs col0 s gr gr
+
+% arrowhead
+n 1380 1711 m 1350 1591 l 1320 1711 l 1380 1711 l cp gs 0.00 setgray ef gr col0 s
+/Symbol ff 180.00 scf sf
+495 3420 m
+gs 1 -1 sc (q=3p/2) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1305 1530 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2745 3015 m
+gs 1 -1 sc (x) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1125 2250 m
+gs 1 -1 sc (A) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1935 3150 m
+gs 1 -1 sc (B) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/fig/rotate_octant.fig b/doc/fig/rotate_octant.fig
new file mode 100644
index 0000000..83d2834
--- /dev/null
+++ b/doc/fig/rotate_octant.fig
@@ -0,0 +1,25 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 0 -1 0.000 0 1 1 1 1357.558 2923.697 1305 2475 1035 3240 1800 3015
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
+ 1350 1800 2475 1800 2475 2925 1350 2925 1350 1800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1260 2925 2700 2925
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1350 3015 1350 1575
+4 0 0 50 0 32 12 0.0000 4 135 540 495 3420 q=3p/2\001
+4 0 0 50 0 16 12 0.0000 4 150 105 1305 1530 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 2745 3015 x\001
+4 0 0 50 0 16 12 0.0000 4 135 135 1125 2250 A\001
+4 0 0 50 0 16 12 0.0000 4 135 120 1935 3150 B\001
diff --git a/doc/fig/rotate_octant.fig.bak b/doc/fig/rotate_octant.fig.bak
new file mode 100644
index 0000000..ff81b04
--- /dev/null
+++ b/doc/fig/rotate_octant.fig.bak
@@ -0,0 +1,23 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+5 1 0 1 0 7 50 0 -1 0.000 0 1 1 1 1357.558 2923.697 1305 2475 1035 3240 1800 3015
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+2 2 0 1 0 6 50 0 20 0.000 0 0 -1 0 0 5
+ 1350 1800 2475 1800 2475 2925 1350 2925 1350 1800
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1260 2925 2700 2925
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1350 3015 1350 1575
+4 0 0 50 0 32 12 0.0000 4 135 540 495 3420 q=3p/2\001
+4 0 0 50 0 16 12 0.0000 4 150 105 1305 1530 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 2745 3015 x\001
diff --git a/doc/fig/rotate_quadrant_example.eps b/doc/fig/rotate_quadrant_example.eps
new file mode 100644
index 0000000..100013a
--- /dev/null
+++ b/doc/fig/rotate_quadrant_example.eps
@@ -0,0 +1,200 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: rotate_quadrant_example.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 3d
+%%CreationDate: Sat Jun 8 19:04:20 2002
+%%For: dp@nbdell15 (Denis Pollney,,,)
+%%BoundingBox: 0 0 302 203
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 203 moveto 0 0 lineto 302 0 lineto 302 203 lineto closepath clip newpath
+-65.2 249.4 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% Polyline
+7.500 slw
+n 3375 1350 m 1800 2250 l 3375 2250 l 4950 1350 l 3375 1350 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 1800 2250 m 3375 2250 l 3375 3465 l 1800 3465 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Polyline
+n 3375 2250 m 3375 3465 l 4950 2520 l 4950 1350 l 3375 2250 l
+ cp gs col6 1.00 shd ef gr gs col0 s gr
+% Ellipse
+n 2700 1350 315 135 0 360 DrawEllipse gs col0 s gr
+
+% Polyline
+gs clippath
+1142 3806 m 1171 3858 l 1303 3783 l 1184 3817 l 1273 3731 l cp
+eoclip
+n 1800 3465 m
+ 1170 3825 l gs col0 s gr gr
+
+% arrowhead
+n 1273 3731 m 1184 3817 l 1303 3783 l 1273 3731 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+n 1805 3474 m
+ 4145 2124 l gs col0 s gr [] 0 sd
+% Polyline
+ [60] 0 sd
+n 4140 2970 m
+ 1575 2970 l gs col0 s gr [] 0 sd
+% Polyline
+gs clippath
+5685 3000 m 5685 2940 l 5534 2940 l 5654 2970 l 5534 3000 l cp
+eoclip
+n 4140 2970 m
+ 5670 2970 l gs col0 s gr gr
+
+% arrowhead
+n 5534 3000 m 5654 2970 l 5534 2940 l 5534 3000 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+n 1800 2970 m
+ 1575 2970 l gs col0 s gr [] 0 sd
+% Polyline
+gs clippath
+2730 885 m 2670 885 l 2670 1036 l 2700 916 l 2730 1036 l cp
+eoclip
+n 2700 1710 m
+ 2700 900 l gs col0 s gr gr
+
+% arrowhead
+n 2730 1036 m 2700 916 l 2670 1036 l 2730 1036 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+ [60] 0 sd
+n 3375 1350 m
+ 3375 2250 l gs col0 s gr [] 0 sd
+% Polyline
+ [60] 0 sd
+n 2700 1755 m
+ 2700 3465 l gs col0 s gr [] 0 sd
+% Polyline
+n 2700 3465 m
+ 2700 3825 l gs col0 s gr
+% Polyline
+gs clippath
+3075 3660 m 3135 3660 l 3135 3509 l 3105 3629 l 3075 3509 l cp
+3135 3225 m 3075 3225 l 3075 3376 l 3105 3256 l 3135 3376 l cp
+eoclip
+n 3105 3240 m
+ 3105 3645 l gs col0 s gr gr
+
+% arrowhead
+n 3135 3376 m 3105 3256 l 3075 3376 l 3135 3376 l cp gs 0.00 setgray ef gr col0 s
+% arrowhead
+n 3075 3509 m 3105 3629 l 3135 3509 l 3075 3509 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+1035 3960 m
+gs 1 -1 sc (x) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2655 855 m
+gs 1 -1 sc (z) col0 sh gr
+/Helvetica ff 180.00 scf sf
+5715 3015 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3240 3690 m
+gs 1 -1 sc (reflection plane) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1755 1395 m
+gs 1 -1 sc (rotation) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1890 1575 m
+gs 1 -1 sc (axis) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/fig/rotate_quadrant_example.fig b/doc/fig/rotate_quadrant_example.fig
new file mode 100644
index 0000000..1b8b9df
--- /dev/null
+++ b/doc/fig/rotate_quadrant_example.fig
@@ -0,0 +1,47 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+1 1 0 1 0 7 50 0 -1 0.000 1 0.0000 2700 1350 315 135 2700 1350 3015 1350
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1800 3465 1170 3825
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 1805 3474 4145 2124
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 4140 2970 1575 2970
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4140 2970 5670 2970
+2 3 0 1 0 6 60 0 20 0.000 0 0 -1 0 0 6
+ 3375 1350 1800 2250 3375 2250 4950 1350 3375 1350 3375 1350
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 1800 2970 1575 2970
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2700 1710 2700 900
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 3375 1350 3375 2250
+2 2 0 1 0 6 60 0 20 0.000 0 0 -1 0 0 5
+ 1800 2250 3375 2250 3375 3465 1800 3465 1800 2250
+2 3 0 1 0 6 60 0 20 0.000 0 0 -1 0 0 6
+ 3375 2250 3375 3465 4950 2520 4950 1350 3375 2250 3375 2250
+2 1 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 2700 1755 2700 3465
+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2
+ 2700 3465 2700 3825
+2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 1 2
+ 1 1 1.00 60.00 120.00
+ 1 1 1.00 60.00 120.00
+ 3105 3240 3105 3645
+4 0 0 50 0 16 12 0.0000 4 105 90 1035 3960 x\001
+4 0 0 50 0 16 12 0.0000 4 105 90 2655 855 z\001
+4 0 0 50 0 16 12 0.0000 4 150 105 5715 3015 y\001
+4 0 0 50 0 16 12 0.0000 4 180 1290 3240 3690 reflection plane\001
+4 0 0 50 0 16 12 0.0000 4 135 615 1755 1395 rotation\001
+4 0 0 50 0 16 12 0.0000 4 135 330 1890 1575 axis\001
diff --git a/doc/fig/rotate_reflect.eps b/doc/fig/rotate_reflect.eps
new file mode 100644
index 0000000..9f2ce06
--- /dev/null
+++ b/doc/fig/rotate_reflect.eps
@@ -0,0 +1,340 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: rotate_reflect.eps
+%%Creator: fig2dev Version 3.2 Patchlevel 3d
+%%CreationDate: Sat Jun 8 18:20:30 2002
+%%For: dp@nbdell15 (Denis Pollney,,,)
+%%BoundingBox: 0 0 524 277
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+newpath 0 277 moveto 0 0 lineto 524 0 lineto 524 277 lineto closepath clip newpath
+-10.6 340.9 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+% Polyline
+435.000 slw
+gs clippath
+3300 2580 m 3300 1830 l 3161 1830 l 3281 2205 l 3161 2580 l cp
+eoclip
+n 2385 2205 m
+ 3285 2205 l gs col6 s gr gr
+
+% arrowhead
+7.500 slw
+n 3161 2580 m 3281 2205 l 3161 1830 l 3161 2580 l cp gs col6 1.00 shd ef gr col6 s
+% Polyline
+435.000 slw
+gs clippath
+6225 2580 m 6225 1830 l 6086 1830 l 6206 2205 l 6086 2580 l cp
+eoclip
+n 5310 2205 m
+ 6210 2205 l gs col6 s gr gr
+
+% arrowhead
+7.500 slw
+n 6086 2580 m 6206 2205 l 6086 1830 l 6086 2580 l cp gs col6 1.00 shd ef gr col6 s
+% Polyline
+435.000 slw
+gs clippath
+4965 4830 m 4965 4080 l 4826 4080 l 4946 4455 l 4826 4830 l cp
+eoclip
+n 3800 4455 m
+ 4950 4455 l gs col7 1.00 shd ef gr gs col6 s gr gr
+
+% arrowhead
+7.500 slw
+n 4826 4830 m 4946 4455 l 4826 4080 l 4826 4830 l cp gs col6 1.00 shd ef gr col6 s
+% Polyline
+gs clippath
+1815 2280 m 1815 2220 l 1664 2220 l 1784 2250 l 1664 2280 l cp
+eoclip
+n 1125 2250 m
+ 1800 2250 l gs col0 s gr gr
+
+% arrowhead
+n 1664 2280 m 1784 2250 l 1664 2220 l 1664 2280 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+643 2689 m 685 2731 l 792 2625 l 686 2689 l 749 2582 l cp
+eoclip
+n 1125 2250 m
+ 675 2700 l gs col0 s gr gr
+
+% arrowhead
+n 749 2582 m 686 2689 l 792 2625 l 749 2582 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+1155 1560 m 1095 1560 l 1095 1711 l 1125 1591 l 1155 1711 l cp
+eoclip
+n 1125 2250 m
+ 1125 1575 l gs col0 s gr gr
+
+% arrowhead
+n 1155 1711 m 1125 1591 l 1095 1711 l 1155 1711 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+630 2835 m
+gs 1 -1 sc (x) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1845 2340 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+1080 1530 m
+gs 1 -1 sc (z) col0 sh gr
+% Polyline
+gs clippath
+7365 1560 m 7305 1560 l 7305 1711 l 7335 1591 l 7365 1711 l cp
+eoclip
+n 7335 2250 m
+ 7335 1575 l gs col0 s gr gr
+
+% arrowhead
+n 7365 1711 m 7335 1591 l 7305 1711 l 7365 1711 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6645 2220 m 6645 2280 l 6796 2280 l 6676 2250 l 6796 2220 l cp
+eoclip
+n 7335 2250 m
+ 6660 2250 l gs col0 s gr gr
+
+% arrowhead
+n 6796 2220 m 6676 2250 l 6796 2280 l 6796 2220 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+7816 1810 m 7774 1768 l 7667 1874 l 7774 1811 l 7710 1917 l cp
+eoclip
+n 7335 2250 m
+ 7785 1800 l gs col0 s gr gr
+
+% arrowhead
+n 7710 1917 m 7774 1811 l 7667 1874 l 7710 1917 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+7290 1530 m
+gs 1 -1 sc (z) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6525 2295 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+7785 1800 m
+gs 1 -1 sc (x) col0 sh gr
+% Polyline
+gs clippath
+4620 1560 m 4560 1560 l 4560 1711 l 4590 1591 l 4620 1711 l cp
+eoclip
+n 4590 2250 m
+ 4590 1575 l gs col0 s gr gr
+
+% arrowhead
+n 4620 1711 m 4590 1591 l 4560 1711 l 4620 1711 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+4108 2689 m 4150 2731 l 4257 2625 l 4151 2689 l 4214 2582 l cp
+eoclip
+n 4590 2250 m
+ 4140 2700 l gs col0 s gr gr
+
+% arrowhead
+n 4214 2582 m 4151 2689 l 4257 2625 l 4214 2582 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+3855 2220 m 3855 2280 l 4006 2280 l 3886 2250 l 4006 2220 l cp
+eoclip
+n 4545 2250 m
+ 3870 2250 l gs col0 s gr gr
+
+% arrowhead
+n 4006 2220 m 3886 2250 l 4006 2280 l 4006 2220 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+3900 2220 m 3900 2280 l 4051 2280 l 3931 2250 l 4051 2220 l cp
+eoclip
+n 4590 2250 m
+ 3915 2250 l gs col0 s gr gr
+
+% arrowhead
+n 4051 2220 m 3931 2250 l 4051 2280 l 4051 2220 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+4050 2835 m
+gs 1 -1 sc (x) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3780 2295 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4545 1530 m
+gs 1 -1 sc (z) col0 sh gr
+% Polyline
+gs clippath
+6240 3810 m 6180 3810 l 6180 3961 l 6210 3841 l 6240 3961 l cp
+eoclip
+n 6210 4500 m
+ 6210 3825 l gs col0 s gr gr
+
+% arrowhead
+n 6240 3961 m 6210 3841 l 6180 3961 l 6240 3961 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+5520 4470 m 5520 4530 l 5671 4530 l 5551 4500 l 5671 4470 l cp
+eoclip
+n 6210 4500 m
+ 5535 4500 l gs col0 s gr gr
+
+% arrowhead
+n 5671 4470 m 5551 4500 l 5671 4530 l 5671 4470 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+6691 4060 m 6649 4018 l 6542 4124 l 6649 4061 l 6585 4167 l cp
+eoclip
+n 6210 4500 m
+ 6660 4050 l gs col0 s gr gr
+
+% arrowhead
+n 6585 4167 m 6649 4061 l 6542 4124 l 6585 4167 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+6165 3780 m
+gs 1 -1 sc (z) col0 sh gr
+/Helvetica ff 180.00 scf sf
+5400 4545 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+6660 4050 m
+gs 1 -1 sc (x) col0 sh gr
+% Polyline
+gs clippath
+3255 4530 m 3255 4470 l 3104 4470 l 3224 4500 l 3104 4530 l cp
+eoclip
+n 2565 4500 m
+ 3240 4500 l gs col0 s gr gr
+
+% arrowhead
+n 3104 4530 m 3224 4500 l 3104 4470 l 3104 4530 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+2083 4939 m 2125 4981 l 2232 4875 l 2126 4939 l 2189 4832 l cp
+eoclip
+n 2565 4500 m
+ 2115 4950 l gs col0 s gr gr
+
+% arrowhead
+n 2189 4832 m 2126 4939 l 2232 4875 l 2189 4832 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+gs clippath
+2595 3810 m 2535 3810 l 2535 3961 l 2565 3841 l 2595 3961 l cp
+eoclip
+n 2565 4500 m
+ 2565 3825 l gs col0 s gr gr
+
+% arrowhead
+n 2595 3961 m 2565 3841 l 2535 3961 l 2595 3961 l cp gs 0.00 setgray ef gr col0 s
+/Helvetica ff 180.00 scf sf
+2070 5085 m
+gs 1 -1 sc (x) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3285 4590 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2520 3780 m
+gs 1 -1 sc (z) col0 sh gr
+% Polyline
+n 180 1035 m 8460 1035 l 8460 3150 l 180 3150 l
+ cp gs col0 s gr
+% Polyline
+n 180 3285 m 8460 3285 l 8460 5400 l 180 5400 l
+ cp gs col0 s gr
+/Helvetica ff 180.00 scf sf
+2745 2340 m
+gs 1 -1 sc (y) col0 sh gr
+/Helvetica ff 180.00 scf sf
+2565 2160 m
+gs 1 -1 sc (reflect) col0 sh gr
+/Helvetica ff 180.00 scf sf
+3825 4410 m
+gs 1 -1 sc (rotate about) col0 sh gr
+/Helvetica ff 180.00 scf sf
+5490 2205 m
+gs 1 -1 sc (reflect) col0 sh gr
+/Helvetica ff 180.00 scf sf
+5670 2385 m
+gs 1 -1 sc (x) col0 sh gr
+/Helvetica ff 180.00 scf sf
+4230 4590 m
+gs 1 -1 sc (z) col0 sh gr
+$F2psEnd
+rs
diff --git a/doc/fig/rotate_reflect.fig b/doc/fig/rotate_reflect.fig
new file mode 100644
index 0000000..d5598ba
--- /dev/null
+++ b/doc/fig/rotate_reflect.fig
@@ -0,0 +1,101 @@
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+6 630 1395 1980 2835
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1125 2250 1800 2250
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1125 2250 675 2700
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 1125 2250 1125 1575
+4 0 0 50 0 16 12 0.0000 4 105 90 630 2835 x\001
+4 0 0 50 0 16 12 0.0000 4 150 105 1845 2340 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 1080 1530 z\001
+-6
+6 6525 1395 7875 2340
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7335 2250 7335 1575
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7335 2250 6660 2250
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 7335 2250 7785 1800
+4 0 0 50 0 16 12 0.0000 4 105 90 7290 1530 z\001
+4 0 0 50 0 16 12 0.0000 4 150 105 6525 2295 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 7785 1800 x\001
+-6
+6 3780 1395 4635 2835
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4590 2250 4590 1575
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4590 2250 4140 2700
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4545 2250 3870 2250
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4590 2250 3915 2250
+4 0 0 50 0 16 12 0.0000 4 105 90 4050 2835 x\001
+4 0 0 50 0 16 12 0.0000 4 150 105 3780 2295 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 4545 1530 z\001
+-6
+6 5400 3645 6750 4590
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6210 4500 6210 3825
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6210 4500 5535 4500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6210 4500 6660 4050
+4 0 0 50 0 16 12 0.0000 4 105 90 6165 3780 z\001
+4 0 0 50 0 16 12 0.0000 4 150 105 5400 4545 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 6660 4050 x\001
+-6
+6 2070 3645 3420 5085
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2565 4500 3240 4500
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2565 4500 2115 4950
+2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2565 4500 2565 3825
+4 0 0 50 0 16 12 0.0000 4 105 90 2070 5085 x\001
+4 0 0 50 0 16 12 0.0000 4 150 105 3285 4590 y\001
+4 0 0 50 0 16 12 0.0000 4 105 90 2520 3780 z\001
+-6
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 180 1035 8460 1035 8460 3150 180 3150 180 1035
+2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5
+ 180 3285 8460 3285 8460 5400 180 5400 180 3285
+2 1 0 30 6 7 60 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 750.00 120.00
+ 2385 2205 3285 2205
+2 1 0 30 6 7 60 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 750.00 120.00
+ 5310 2205 6210 2205
+2 1 0 30 6 7 60 0 20 0.000 0 0 -1 1 0 2
+ 1 1 1.00 750.00 120.00
+ 3800 4455 4950 4455
+4 0 0 50 0 16 12 0.0000 4 150 105 2745 2340 y\001
+4 0 0 50 0 16 12 0.0000 4 135 510 2565 2160 reflect\001
+4 0 0 50 0 16 12 0.0000 4 135 990 3825 4410 rotate about\001
+4 0 0 50 0 16 12 0.0000 4 135 510 5490 2205 reflect\001
+4 0 0 50 0 16 12 0.0000 4 105 90 5670 2385 x\001
+4 0 0 50 0 16 12 0.0000 4 105 90 4230 4590 z\001
diff --git a/doc/rotating_sym.tex b/doc/rotating_sym.tex
new file mode 100644
index 0000000..e5ef6b7
--- /dev/null
+++ b/doc/rotating_sym.tex
@@ -0,0 +1,468 @@
+% /*@@
+% @file rotating_sym.tex
+% @date 6 June 2002
+% @author Denis Pollney
+% @desc
+% Description of the implementation of `rotating'
+% symmetry conditions in CartGrid3D.
+% @enddesc
+% @version $Header$
+% @@*/
+
+\documentclass{article}
+
+\newif\ifpdf
+\ifx\pdfoutput\undefined
+\pdffalse % we are not running PDFLaTeX
+\else
+\pdfoutput=1 % we are running PDFLaTeX
+\pdftrue
+\fi
+
+\ifpdf
+\usepackage[pdftex]{graphicx}
+\else
+\usepackage{graphicx}
+\fi
+
+\parskip = 0 pt
+\parindent = 0pt
+\oddsidemargin = 0 cm
+\textwidth = 16 cm
+\topmargin = -1 cm
+\textheight = 24 cm
+
+\begin{document}
+
+\title{Rotating symmetry conditions}
+\author{Denis Pollney}
+\date{June 2002}
+
+\maketitle
+
+\begin{abstract}
+These notes describe the implentation of rotating symmetry conditions
+for \emph{bitant} and \emph{quadrant} domains in \texttt{CartGrid3D}.
+For these particular domain types, the condition that fields on the
+grid are have a rotational symmetry in a plane along one of the
+coordinate axes can be simply implemented with minor extensions to the
+already existing symmetry mechanism, which copies the components of
+a given field to the required ghost-zones with a possible plus-minus
+inversion.
+\end{abstract}
+
+%------------------------------------------------------------------------------
+\section{Introduction}
+\label{sec:rs_intro}
+%------------------------------------------------------------------------------
+
+A number of useful physical models involve situations where a
+rotational symmetry is present in all of the relevant fields. By
+`rotational symmetry' we mean that there exists a pair of half-planes
+extending from one of the coordinate axes and separated by an angle
+$\theta$ which have the property that on $A$ and near to $A$ can be
+mapped onto $B$ and corresponding points near to $B$ (see Figure
+\ref{fig:rs_rotation_examples}).
+%
+\begin{figure}
+\centering
+\begin{tabular}{ccc}
+\ifpdf
+\else
+\includegraphics[height=40mm]{fig/rotate_general.eps}
+\fi
+&
+\ifpdf
+\else
+\includegraphics[height=40mm]{fig/rotate_bitant.eps}
+\fi
+&
+\ifpdf
+\else
+\includegraphics[height=25mm]{fig/rotate_octant.eps}
+\fi
+\\
+(a) & (b) & (c)
+\end{tabular}
+\caption{Rotational symmetries, looking down the $z$-axis. In the
+general case (a), the half-planes $A$ and $B$ are separated by an
+angle $\theta$. Data at $A$ can be mapped on to points of $B$ via a
+rotation through $\theta$. Particular cases of importance are the
+rotation through $\theta=\pi$, so that data on the positive $y$-axis
+is mapped onto the negative $y$, and vice versa; and the rotation
+through $\theta=3\pi/2$ so that data need be specified only in a
+single quarter-plane.}
+\label{fig:rs_rotation_examples}
+\end{figure}
+%
+In particular, situations for which such conditions can be useful
+include
+\begin{itemize}
+ \item rotating axisymmetric bodies -- satisfies the rotational
+ symmetry for arbitrary $\theta$.
+ \item pairs of massive bodies separated by distances $\pm
+ \mathbf{d}$ from the origin and with identical oppositely directed
+ momenta $\pm \mathbf{p}$ (Figure \ref{fig:rs_bbh}) -- satisfies
+ the half-plane rotational symmetry ($\theta=\pi$) or, if
+ $\mathbf{p}=0$ then also the quarter plane symmetry
+ ($\theta=3\pi/2$).
+\end{itemize}
+\begin{figure}
+\centering
+\ifpdf
+\else
+\includegraphics[height=40mm]{fig/rotate_bbh.eps}
+\fi
+\caption{A physical system consisting of a pair of identical bodies
+ separated equal distance along a line through the origin, and moving
+ with equal but opposite momenta, can be modelled using only the
+ positive half-plane if the rotating symmetry condition is applied to
+ the $x=0$ plane.}
+\label{fig:rs_bbh}
+\end{figure}
+
+In order to apply the boundary condition exactly on a numerical grid,
+it is necessary that grid points to each side of the mapping planes
+$A$ and $B$ can be mapped onto each other exactly. In particular, this
+means that the rotating symmetry conditions can be applied exactly if
+the half-planes are each aligned with one of the coordinate axes. For
+general planes $A$ and $B$, however, interpolation would be required
+to put data in the neighbourhood of $A$ onto grid points near
+$B$. Only the particular cases described by Figures
+\ref{fig:rs_rotation_examples} (b) and (c) will be
+considered here.
+
+%------------------------------------------------------------------------------
+\section{Symmetry conditions}
+\label{sec:rs_application}
+%------------------------------------------------------------------------------
+
+For a given field, the boundary condition is applied as follows. For
+each ghost-zone point along the symmetry plane, the corresponding
+point on the physical grid (under the rotational $\theta$) is
+determined. To determine the value of the ghost-zone point, the
+value on the physical grid is simply transformed under the given
+rotation.\\
+
+The first of these issues is not difficult to resolve. As an example,
+consider the half-plane rotational symmetry about the $z$-axis applied
+in the $x=0$ plane, as depicted in Figure \ref{fig:rs_grid}. The has
+$j=0\ldots m$ in the $y$ direction, an arbitrary number of points in the
+$x$ and $z$ directions, and some ghostzones whose $j$ coordinates are
+labelled $j=-1,-2,\ldots$. Then for the ghost-zone point $(n-i, -j,
+k)$, the corresponding physical point under rotation is (1) $(i,j-1,k)$
+if the $x=0$ plane is on the grid, or (2) $(i,j,k)$ if the $x=0$ plane
+is staggered between a grid point and the first ghost-zone
+point. There is an implicit assumption here that the grid extends
+exactly the same distance to each side of the rotation axis. \\
+
+\begin{figure}
+\centering
+\ifpdf
+\else
+\includegraphics[height=40mm]{fig/rotate_grid.eps}
+\fi
+\caption{The mapping of physical points onto ghost-zone points for a
+ half-plane rotation about the $z$-axis, where the $x=0$ plane is
+ staggered between gridpoints, and two ghost zones have been
+ allocated.}
+\label{fig:rs_grid}
+\end{figure}
+
+The remaining issue is to determine how the fields at a point
+$(i,j,k)$ are modified under a rotation of a given angle. A set of
+basis vectors $(\mathbf{\hat{x}},\mathbf{\hat{y}},\mathbf{\hat{z}})$
+can be rotated to an arbitrary direction by applying the rotation
+matrix
+\begin{equation}
+ \mathbf{P} =
+ \left[
+ \begin{array}{ccc}
+ \eta_1(\cos\theta_1\cos\theta_3 - \sin\theta_1\cos\theta_2\sin\theta_3) &
+ \sin\theta_1\cos\theta_3 + \cos\theta_1\cos\theta_2\sin\theta_3 &
+ \sin\theta_2\sin\theta_3 \\
+ -(\cos\theta_1\sin\theta_3 + \sin\theta_1\cos\theta_2\cos\theta3) &
+ \eta_2(\sin\theta_1\sin\theta_3 + \cos\theta_1\cos\theta_2\cos\theta_3) &
+ \sin\theta_2\cos\theta_3 \\
+ \sin\theta_1\sin\theta_2 &
+ -\cos\theta_1\sin\theta_2 &
+ \eta_3\cos\theta_2
+ \end{array}
+ \right],
+\end{equation}
+which preserves the orthogonality of the basis. The matrix
+$\mathbf{P}$ has been written in terms of the Euler angles
+$0\leq\theta_1<2\pi$, $0\leq\theta_2<2\pi$, and $0\leq\theta_3<\pi$,
+and the factors $\eta_1=\pm 1$, $\eta_2=\pm 1$, $\eta_3=\pm 1$ are
+introduced to allow for reflections of individual axes (ie. changes of
+handedness of the basis).
+The basis is transformed under $\mathbf{P}$ via the matrix multiplication
+\begin{equation}
+ \left[
+ \begin{array}{c}
+ \mathbf{\hat{x}^\prime} \\
+ \mathbf{\hat{y}^\prime} \\
+ \mathbf{\hat{z}^\prime}
+ \end{array}
+ \right]
+ =
+ \mathbf{P}
+ \left[
+ \begin{array}{c}
+ \mathbf{\hat{x}} \\
+ \mathbf{\hat{y}} \\
+ \mathbf{\hat{z}}
+ \end{array}
+ \right].
+\end{equation}
+
+Vectors and tensor components are transformed under the given rotation
+by applying the $\mathbf{P}$ matrix:
+\begin{eqnarray}
+ \mathbf{v} & \rightarrow & \mathbf{P}^T \mathbf{v}, \\
+ \mathbf{G} & \rightarrow & \mathbf{P}^T \mathbf{G} \mathbf{P},
+\end{eqnarray}
+where $\mathbf{v}$ is a 3-vector,
+\begin{equation}
+ \mathbf{v} = [v_x, v_y, v_z]^T,
+\end{equation}
+and $\mathbf{G}$ is a two-index tensor treated as a matrix,
+\begin{equation}
+ \mathbf{G} =
+ \left[
+ \begin{array}{ccc}
+ g_{xx} & g_{xy} & g_{xz} \\
+ g_{yx} & g_{yy} & g_{yz} \\
+ g_{zx} & g_{zy} & g_{zz}
+ \end{array}
+ \right].
+\end{equation}
+
+\emph{Example 1.} The special case of a reflection in the $x=0$ plane
+corresponds to an inversion of the $x$-axis, so that
+$\theta_1=\theta_2=\theta_3=0$ and $\eta_1=-1$,
+\begin{equation}
+ \mathbf{P}_{x-\mathrm{reflect}} = \left[
+ \begin{array}{ccc}
+ -1 & 0 & 0 \\
+ 0 & 1 & 0 \\
+ 0 & 0 & 1
+ \end{array}
+ \right].
+\end{equation}
+
+\emph{Example 2.} For a rotation about the $z$ axis by an angle of
+$\theta=\pi$ (corresponding to Figure \ref{fig:rs_grid}), the only
+non-zero rotation angle is $\theta_1=\pi$, so that
+\begin{equation}
+ \mathbf{P}_{z-\mathrm{rotate}} = \left[
+ \begin{array}{ccc}
+ -1 & 0 & 0 \\
+ 0 & -1 & 0 \\
+ 0 & 0 & 1
+ \end{array}
+ \right].
+\end{equation}
+
+\emph{Example 3.} A quarter-plane grid with positive $y$-axis values
+mapped onto the positive $x$-axis (as in Figure\nobreak~
+\ref{fig:rs_rotation_examples}) corresponds non-zero angle
+$\theta_1=3\pi/2$, with the resulting rotation matrix
+\begin{equation}
+ \mathbf{P}_{z-\mathrm{rotate(3/2)}} = \left[
+ \begin{array}{ccc}
+ 0 & -1 & 0 \\
+ 1 & 0 & 0 \\
+ 0 & 0 & 1
+ \end{array}
+ \right].
+\end{equation}
+
+%------------------------------------------------------------------------------
+\section{Implementation}
+\label{sec:rs_implementation}
+%------------------------------------------------------------------------------
+
+In order to implement the bitant, quadrant and octant
+\emph{reflection} symmetries which already exist in
+\texttt{CartGrid3D}, it was necessary to attach to each grid function
+information corresponding to how the field transforms under
+reflections in each of the $x$, $y$, and $z$ axes. These are
+specified as an array of three integers, each taking the value $+1$ or
+$-1$, which is passed to the symmetry registration function. For
+example,
+\begin{verbatim}
+ static int one=1;
+ int sym[3];
+ sym[0] = -one;
+ sym[1] = -one;
+ sym[2] = one;
+ SetCartSymVN(cctkGH, sym,"einstein::gxy");
+\end{verbatim}
+specifies that the grid function \texttt{einstein::gxy} should be
+negated under reflections in $x=0$ and $y=0$, but keeps the same value
+under reflections in the $z=0$ plane.\\
+
+This is the only information required for the reflection symmetry
+since the value of the field at the new (reflected) point does not
+require information from any other fields. For example, for a vector
+$v = (v_x, v_y, v_z)^T$ reflected in $x=0$, we have
+\begin{equation}
+ v_x \rightarrow -v_x, \qquad v_y \rightarrow v_y, \qquad
+ v_z \rightarrow v_z.
+\end{equation}
+That is, the transformation of $v_x$ only needs to know the values of
+$v_x$, and does not need to know anything about the values of $v_y$ or
+$v_z$. On the other hand, for the $3\pi/2$-rotation corresponding to
+Example 3, above, the vector would transform as:
+\begin{equation}
+ v_x \rightarrow -v_y, \qquad v_y \rightarrow v_x, \qquad
+ v_z \rightarrow v_z.
+\end{equation}
+In this case, to determine the rotated $v_x$ component it is necessary
+to know the value of $v_y$. However, there is no concept of vector or
+tensor within Cactus, so that given a grid function corresponding to
+$v_x$, it is not generally possible to know which grid function
+corresponds to $v_y$ which should be used to determine the rotated
+values.\\
+
+As a result, the only symmetries which can easily be implemented
+within the current mechanism are those which require only the grid
+function itself in order to determine the ghost zone points. This
+includes the $\pi$-rotation symmetries (`half-plane', Figure
+\ref{fig:rs_rotation_examples} (b)) but not the $3\pi/2$-rotation
+symmetries (`quarter-plane', Figure \ref{fig:rs_rotation_examples}
+(c)).\\
+
+Table \ref{tbl:rs_xform} lists the transformations of the components
+of an arbitrary scalar, vector and two-index tensor under reflections
+in each plane, and rotations about each axis.
+\begin{table}
+\centering
+\begin{tabular}{r|rrr|rrr}\hline\hline
+ & \multicolumn{3}{c|}{reflection in}
+ & \multicolumn{3}{c}{rotation about} \\
+ & $x$ & $y$ & $z$ & $x$ & $y$ & $z$ \\ \hline
+$\phi$ & 1 & 1 & 1 & 1 & 1 & 1 \\ \hline
+$v_x$ & -1 & 1 & 1 & 1 & -1 & -1 \\
+$v_y$ & 1 & -1 & 1 & -1 & 1 & -1 \\
+$v_z$ & 1 & 1 & -1 & -1 & -1 & 1 \\ \hline
+$g_{xx}$ & 1 & 1 & 1 & 1 & 1 & 1 \\
+$g_{xy}$ & -1 & -1 & 1 & -1 & -1 & 1 \\
+$g_{xz}$ & -1 & 1 & -1 & -1 & 1 & -1 \\
+$g_{yy}$ & 1 & 1 & 1 & 1 & 1 & 1 \\
+$g_{yz}$ & 1 & -1 & -1 & 1 & -1 & -1 \\
+$g_{zz}$ & 1 & 1 & 1 & 1 & 1 & 1 \\ \hline\hline
+\end{tabular}
+\caption{Transformation factors for reflection and half-plane rotation
+symmetries.}
+\label{tbl:rs_xform}
+\end{table}
+We note the following useful fact: The transformation factor $s_i$ for
+a rotation about the axis $i$ is given by $s_j \times s_k$ where
+$i\neq j\neq k$. For example, for a rotation about the $z$-axis, the
+transformation factor for the is given by
+\begin{equation}
+ s_x \times s_y = -1 \times -1 = 1.
+\end{equation}
+Intuitively, this is clear since the rotation of the axes by $\pi$
+radians about $z$ is equivalent to a reflection in $y$ followed by
+a reflection in $x$ (Figure \ref{fig:rs_rotate_reflect}).\\
+
+\begin{figure}
+\centering
+\ifpdf
+\else
+\includegraphics[height=40mm]{fig/rotate_reflect.eps}
+\fi
+\caption{A rotation by $\pi$ radians about the $z$-axis is equivalent
+ to successive reflections about the $y$- and $x$-axes.}
+\label{fig:rs_rotate_reflect}
+\end{figure}
+
+Since the transformation values for reflection symmetries are
+already specified for each Cactus grid function, we can use this
+information to unambiguously determine the $\pi$-rotation
+transformation coefficients, without requiring that any new
+information be added if the reflection symmetries have already
+been defined (as is the case for any Cactus GFs which are able to
+use the current \texttt{bitant}, \texttt{quadrant} and \texttt{octant}
+domains).
+
+%------------------------------------------------------------------------------
+\section{\texttt{CartGrid3D} Notes}
+\label{sec:rs_cartgrid3d}
+%------------------------------------------------------------------------------
+
+Two types of rotating symmetry conditions have been implemented in
+\texttt{CartGrid3D} as extensions to the \texttt{grid::domain}
+parameter.\\
+
+The first, \texttt{bitant\_rotate}, defines a grid which is half-sized
+along one axis, and assumes a field that is rotating about a
+perpendicular axis. The half-axis is chosen using the
+\texttt{bitant\_plane} parameter, which specifies the plane at which
+the grid is to be cut as either ``\texttt{xy}'', ``\texttt{xz}'' or
+``\texttt{yz}''. The rotation axis is chosen using the
+\texttt{rotation\_axis} parameter, which takes values of
+``\texttt{x}'', ``\texttt{y}'' or ``\texttt{z}''. For example, to
+specify a bitant domain along the positive $y$-axis, on which fields
+are rotating about the $z$-axis, the following parameters would do the
+job:
+\begin{verbatim}
+ grid::domain = "bitant_rotate"
+ grid::bitant_plane = "xz"
+ grid::rotation_axis = "z"
+\end{verbatim}
+This setup is illustrated in Figure \ref{fig:rs_bitant_example} (a).\\
+
+\begin{figure}
+\centering
+\begin{tabular}{cc}
+\ifpdf
+\else
+\includegraphics[height=40mm]{fig/rotate_bitant_example.eps}
+\fi
+&
+\ifpdf
+\else
+\includegraphics[height=30mm]{fig/rotate_quadrant_example.eps}
+\fi
+\\
+(a) & (b)
+\end{tabular}
+\caption{Active grids for the \texttt{bitant\_rotate} and
+ \texttt{quadrant\_reflect\_rotate} domains for the examples given in
+ the text. (a) The given \texttt{bitant\_rotate} domain corresponds
+ to the $y>0$ half-grid, with fields rotating about the $z$-axis. (b)
+ The \texttt{quadrant\_reflect\_rotate} example is similar, except
+ the active grid is only along the positive $z$-axis and a reflection
+ symmetry is assumed in the $z=0$ plane.}
+\label{fig:rs_bitant_example}
+\end{figure}
+
+The \texttt{quadrant\_reflect\_rotate} symmetry cuts two of the axes
+in half so that only a quadrant of the full domain is active. A
+standard reflection symmetry is applied to one of the half-planes,
+while the physical fields are assumed to rotate in the other plane. To
+set up such a grid which rotates about the $z$-axis and which is
+reflection symmetric in the $z=0$ plane, the following parameters
+could be used:
+\begin{verbatim}
+ grid::domain = "quadrant_rotate_reflect"
+ grid::quadrant_direction = "x"
+ grid::rotation_axis = "z"
+\end{verbatim}
+Note that the \texttt{quadrant\_direction} parameter follows the
+current \texttt{CartGrid3D} standard, which defines the domain on the
+\emph{positive} quadrant with the long edge aligned with the specified
+axis. It is currently not possible to choose the negative quadrant.\\
+
+Octant rotation symmetries, or the alternate quadrant symmetry (for
+which the data on one half-plane is rotated onto the other), are more
+difficult to implement without some generalisation of the existing
+\texttt{CartGrid3D} specification of symmetry boundaries for the
+reasons mentioned in the previous section.
+
+%------------------------------------------------------------------------------
+\end{document}
diff --git a/param.ccl b/param.ccl
index 0b9e7b9..f17943a 100644
--- a/param.ccl
+++ b/param.ccl
@@ -118,10 +118,12 @@ KEYWORD type "Grid type"
KEYWORD domain "Domain type"
{
- "octant" :: "Use an octant about the origin"
- "quadrant" :: "Use a quadrant in x-y plane"
- "bitant" :: "Use a bitant about the x-y plane"
- "full" :: "Use the full domain"
+ "octant" :: "Use an octant about the origin"
+ "quadrant" :: "Use a quadrant in x-y plane"
+ "quadrant_reflect_rotate" :: "Use a quadrant with rotation symmetry about an axis"
+ "bitant" :: "Use a bitant about the x-y plane"
+ "bitant_rotate" :: "Use a bitant with rotation symmetry about an axis"
+ "full" :: "Use the full domain"
} "full"
KEYWORD bitant_plane "Plane defining bitant domain"
@@ -138,6 +140,14 @@ KEYWORD quadrant_direction "Direction defining quadrant domain"
"z" :: "z-direction"
} "z"
+KEYWORD rotation_axis "Axis about which the rotation symmetry is to be applied"
+{
+ "x" :: "x-axis"
+ "y" :: "y-axis"
+ "z" :: "z-axis"
+} "z"
+
+
BOOLEAN symmetry_xmin "Symmetry boundary condition on lower x boundary"
{
: :: "Logical"
diff --git a/src/CartGrid3D.c b/src/CartGrid3D.c
index 64792f5..c4674aa 100644
--- a/src/CartGrid3D.c
+++ b/src/CartGrid3D.c
@@ -16,6 +16,7 @@
#include "cctk.h"
#include "cctk_Arguments.h"
#include "cctk_Parameters.h"
+#include "Symmetry.h"
static const char *rcsid = "$Header$";
@@ -425,6 +426,19 @@ void CartGrid3D(CCTK_ARGUMENTS)
} /* if (coarsest refinement level) */
+ if ((domainsym[0]==GFSYM_ROTATION_Y || domainsym[2]==GFSYM_ROTATION_X)
+ && (lowerz != -upperz))
+ CCTK_WARN(0, "minimum z must equal maximum z for rotation symmetry");
+
+ if ((domainsym[0]==GFSYM_ROTATION_Z || domainsym[4]==GFSYM_ROTATION_X)
+ && (lowery != -uppery))
+ CCTK_WARN(0, "minimum y must equal maximum y for rotation symmetry");
+
+ if ((domainsym[2]==GFSYM_ROTATION_Z || domainsym[4]==GFSYM_ROTATION_Y)
+ && (lowerx != -upperx))
+ CCTK_WARN(0, "minimum x must equal maximum x for rotation symmetry");
+
+
#ifdef CCTK_DEBUG
printf("\n");
printf("CartGrid3D\n");
diff --git a/src/DecodeSymParameters.c b/src/DecodeSymParameters.c
index df8d581..88b12b5 100644
--- a/src/DecodeSymParameters.c
+++ b/src/DecodeSymParameters.c
@@ -1,3 +1,4 @@
+
/*@@
@file DecodeSymParameters.c
@date Wed May 10 18:58:00 EST 2000
@@ -11,6 +12,7 @@
#include "cctk.h"
#include "cctk_Arguments.h"
#include "cctk_Parameters.h"
+#include "Symmetry.h"
static const char *rcsid = "$Header$";
@@ -55,39 +57,105 @@ void DecodeSymParameters3D(int sym[6])
{
if (CCTK_Equals(bitant_plane, "xy"))
{
- sym[4] = 1;
+ sym[4] = GFSYM_REFLECTION;
+ }
+ else if (CCTK_Equals(bitant_plane, "xz"))
+ {
+ sym[2] = GFSYM_REFLECTION;
+ }
+ else if (CCTK_Equals(bitant_plane, "yz"))
+ {
+ sym[0] = GFSYM_REFLECTION;
+ }
+ }
+ else if (CCTK_Equals(domain, "bitant_rotate"))
+ {
+ if (CCTK_Equals(bitant_plane, "xy"))
+ {
+ if (CCTK_Equals(rotation_axis, "y"))
+ sym[4] = GFSYM_ROTATION_Y;
+ else if (CCTK_Equals(rotation_axis, "x"))
+ sym[4] = GFSYM_ROTATION_X;
}
else if (CCTK_Equals(bitant_plane, "xz"))
{
- sym[2] = 1;
+ if (CCTK_Equals(rotation_axis, "x"))
+ sym[2] = GFSYM_ROTATION_X;
+ else if (CCTK_Equals(rotation_axis, "z"))
+ sym[2] = GFSYM_ROTATION_Z;
}
else if (CCTK_Equals(bitant_plane, "yz"))
{
- sym[0] = 1;
+ if (CCTK_Equals(rotation_axis, "y"))
+ sym[0] = GFSYM_ROTATION_Y;
+ else if (CCTK_Equals(rotation_axis, "z"))
+ sym[0] = GFSYM_ROTATION_Z;
}
}
else if (CCTK_Equals(domain, "quadrant"))
{
if (CCTK_Equals(quadrant_direction, "x"))
{
- sym[2] = 1;
- sym[4] = 1;
+ sym[2] = GFSYM_REFLECTION;
+ sym[4] = GFSYM_REFLECTION;
+ }
+ else if (CCTK_Equals(quadrant_direction, "y"))
+ {
+ sym[0] = GFSYM_REFLECTION;
+ sym[4] = GFSYM_REFLECTION;
+ }
+ else if (CCTK_Equals(quadrant_direction, "z"))
+ {
+ sym[0] = GFSYM_REFLECTION;
+ sym[2] = GFSYM_REFLECTION;
+ }
+ }
+ else if (CCTK_Equals(domain, "quadrant_reflect_rotate"))
+ {
+ if (CCTK_Equals(quadrant_direction, "x"))
+ {
+ if (CCTK_Equals(rotation_axis, "y"))
+ {
+ sym[2] = GFSYM_REFLECTION;
+ sym[4] = GFSYM_ROTATION_Y;
+ }
+ else if (CCTK_Equals(rotation_axis, "z"))
+ {
+ sym[2] = GFSYM_ROTATION_Z;
+ sym[4] = GFSYM_REFLECTION;
+ }
}
else if (CCTK_Equals(quadrant_direction, "y"))
{
- sym[0] = 1;
- sym[4] = 1;
+ if (CCTK_Equals(rotation_axis, "x"))
+ {
+ sym[0] = GFSYM_REFLECTION;
+ sym[4] = GFSYM_ROTATION_X;
+ }
+ if (CCTK_Equals(rotation_axis, "z"))
+ {
+ sym[0] = GFSYM_ROTATION_Z;
+ sym[4] = GFSYM_REFLECTION;
+ }
}
else if (CCTK_Equals(quadrant_direction, "z"))
{
- sym[0] = 1;
- sym[2] = 1;
+ if (CCTK_Equals(rotation_axis, "x"))
+ {
+ sym[0] = GFSYM_REFLECTION;
+ sym[2] = GFSYM_ROTATION_X;
+ }
+ if (CCTK_Equals(rotation_axis, "y"))
+ {
+ sym[0] = GFSYM_ROTATION_Y;
+ sym[2] = GFSYM_REFLECTION;
+ }
}
}
else if (CCTK_Equals(domain, "octant"))
{
- sym[0] = 1;
- sym[2] = 1;
- sym[4] = 1;
+ sym[0] = GFSYM_REFLECTION;
+ sym[2] = GFSYM_REFLECTION;
+ sym[4] = GFSYM_REFLECTION;
}
}
diff --git a/src/ParamCheck.c b/src/ParamCheck.c
index 71a8ab2..35d7a42 100644
--- a/src/ParamCheck.c
+++ b/src/ParamCheck.c
@@ -51,10 +51,18 @@ void ParamCheck_CartGrid3D(CCTK_ARGUMENTS)
{
iflag++;
}
+ else if (CCTK_Equals(domain,"quadrant_reflect_rotate"))
+ {
+ iflag++;
+ }
else if (CCTK_Equals(domain,"bitant"))
{
iflag++;
}
+ else if (CCTK_Equals(domain,"bitant_rotate"))
+ {
+ iflag++;
+ }
else if (CCTK_Equals(domain,"full"))
{
iflag++;
@@ -67,10 +75,19 @@ void ParamCheck_CartGrid3D(CCTK_ARGUMENTS)
{
iflag++;
}
+ if (CCTK_Equals(domain,"bitant_rotate"))
+ {
+ iflag++;
+ }
else if (CCTK_Equals(domain,"quadrant"))
{
iflag++;
- } else if (CCTK_Equals(domain,"octant"))
+ }
+ else if (CCTK_Equals(domain,"quadrant_reflect_rotate"))
+ {
+ iflag++;
+ }
+ else if (CCTK_Equals(domain,"octant"))
{
iflag++;
}
@@ -94,6 +111,39 @@ void ParamCheck_CartGrid3D(CCTK_ARGUMENTS)
CCTK_PARAMWARN("No grid set up in CartGrid3D");
}
+ if (CCTK_Equals(domain, "bitant_rotate"))
+ {
+ if (CCTK_Equals(bitant_plane, "xy") && CCTK_Equals(rotation_axis, "z"))
+ CCTK_PARAMWARN(
+ "rotation_axis=\"z\" is incompatible with bitant_plane=\"xy\"");
+
+ if (CCTK_Equals(bitant_plane, "xz") && CCTK_Equals(rotation_axis, "y"))
+ CCTK_PARAMWARN(
+ "rotation_axis=\"y\" is incompatible with bitant_plane=\"xz\"");
+
+ if (CCTK_Equals(bitant_plane, "yz") && CCTK_Equals(rotation_axis, "x"))
+ CCTK_PARAMWARN(
+ "rotation_axis=\"x\" is incompatible with bitant_plane=\"yz\"");
+ }
+
+ if (CCTK_Equals(domain, "quadrant_reflect_rotate"))
+ {
+ if (CCTK_Equals(quadrant_direction, "x") &&
+ CCTK_Equals(rotation_axis, "x"))
+ CCTK_PARAMWARN(
+ "rotation_axis=\"x\" is incompatible with quadrant_direction=\"x\"");
+
+ if (CCTK_Equals(quadrant_direction, "y") &&
+ CCTK_Equals(rotation_axis, "y"))
+ CCTK_PARAMWARN(
+ "rotation_axis=\"y\" is incompatible with quadrant_direction=\"y\"");
+
+ if (CCTK_Equals(quadrant_direction, "z") &&
+ CCTK_Equals(rotation_axis, "z"))
+ CCTK_PARAMWARN(
+ "rotation_axis=\"z\" is incompatible with quadrant_direction=\"z\"");
+ }
+
return;
}
diff --git a/src/SetSymmetry.c b/src/SetSymmetry.c
index 092dafb..afefea2 100644
--- a/src/SetSymmetry.c
+++ b/src/SetSymmetry.c
@@ -20,10 +20,6 @@ static const char *rcsid = "$Header$";
CCTK_FILEVERSION(CactusBase_CartGrid3D_SetSymmetry_c)
-#define MAX_DIM 3
-#define MAX_FACE 6
-
-
/********************************************************************
********************* Local Data Types ***********************
********************************************************************/
@@ -94,10 +90,22 @@ int SetCartSymVI(cGH *GH, int *sym, int vi)
DecodeSymParameters3D(domainsym);
for (dir=0; dir<MAX_FACE; ++dir)
{
- if (domainsym[dir])
+ if (domainsym[dir] == GFSYM_REFLECTION)
{
sGHex->GFSym[vi][dir] = sym[dir/2];
- }
+ }
+ else if (domainsym[dir] == GFSYM_ROTATION_X)
+ {
+ sGHex->GFSym[vi][dir] = sym[1]*sym[2];
+ }
+ else if (domainsym[dir] == GFSYM_ROTATION_Y)
+ {
+ sGHex->GFSym[vi][dir] = sym[0]*sym[2];
+ }
+ else if (domainsym[dir] == GFSYM_ROTATION_Z)
+ {
+ sGHex->GFSym[vi][dir] = sym[0]*sym[1];
+ }
else
{
sGHex->GFSym[vi][dir] = GFSYM_NOSYM;
@@ -105,7 +113,7 @@ int SetCartSymVI(cGH *GH, int *sym, int vi)
}
#ifdef SYM_DEBUG
- printf("SetSymmetry: %s [%d,%d,%d]\n\n",imp_gf,
+ printf("SetSymmetry: %s [%d,%d,%d]\n\n", CCTK_VarName(vi),
sGHex->GFSym[vi][0],
sGHex->GFSym[vi][2],
sGHex->GFSym[vi][4]);
@@ -217,10 +225,22 @@ int SetCartSymGI(cGH *GH, int *sym, int gi)
DecodeSymParameters3D (domainsym);
for (dir=0; dir<MAX_FACE; dir++)
{
- if (domainsym[dir])
+ if (domainsym[dir] == GFSYM_REFLECTION)
{
sGHex->GFSym[vi][dir] = sym[dir/2];
}
+ else if (domainsym[dir] == GFSYM_ROTATION_X)
+ {
+ sGHex->GFSym[vi][dir] = sym[1]*sym[2];
+ }
+ else if (domainsym[dir] == GFSYM_ROTATION_Y)
+ {
+ sGHex->GFSym[vi][dir] = sym[0]*sym[2];
+ }
+ else if (domainsym[dir] == GFSYM_ROTATION_Z)
+ {
+ sGHex->GFSym[vi][dir] = sym[0]*sym[1];
+ }
else
{
sGHex->GFSym[vi][dir] = GFSYM_NOSYM;
@@ -228,7 +248,7 @@ int SetCartSymGI(cGH *GH, int *sym, int gi)
}
#ifdef SYM_DEBUG
- printf("SetSymmetry: %s [%d,%d,%d]\n\n",imp_gf,
+ printf("SetSymmetry: %s [%d,%d,%d]\n\n", CCTK_VarName(vi),
sGHex->GFSym[vi][0],
sGHex->GFSym[vi][2],
sGHex->GFSym[vi][4]);
diff --git a/src/Symmetry.c b/src/Symmetry.c
index 7b65592..f245600 100644
--- a/src/Symmetry.c
+++ b/src/Symmetry.c
@@ -15,6 +15,7 @@
#include <string.h>
#include "cctk.h"
+#include "Symmetry.h"
static const char *rcsid = "$Header$";
@@ -66,7 +67,7 @@ int CartApplySym3Di(cGH *GH, int *doSym, int *cntstag,
int *lssh, int *ghostz, int *sym, CCTK_REAL *var)
{
- int i,j,k;
+ int i, j, k;
#ifdef SYM_DEBUG
printf(" doSym: %d %d / %d %d / %d %d \n",
@@ -79,7 +80,10 @@ int CartApplySym3Di(cGH *GH, int *doSym, int *cntstag,
printf(" cntstag: %d %d %d\n",cntstag[0],cntstag[1],cntstag[2]);
#endif
- if (doSym[0] == 1)
+ /*
+ * Apply symmetry to the lower x face.
+ */
+ if (doSym[0] == GFSYM_REFLECTION)
{
for(k=0; k < lssh[2]; k++)
{
@@ -87,40 +91,157 @@ int CartApplySym3Di(cGH *GH, int *doSym, int *cntstag,
{
for(i=0; i < ghostz[0]; i++)
{
- var[CCTK_GFINDEX3D(GH,i,j,k)] =
- sym[0]*var[CCTK_GFINDEX3D(GH,2*ghostz[0]-cntstag[0]-i,j,k)];
+ var[CCTK_GFINDEX3D(GH,i,j,k)] = sym[0] *
+ var[CCTK_GFINDEX3D(GH, 2*ghostz[0]-cntstag[0]-i, j, k)];
}
}
}
}
- if (doSym[2] == 1)
+ else if (doSym[0] == GFSYM_ROTATION_Y)
+ {
+ /*
+ * FIXME: The following loop is local, but global indices are
+ * FIXME: needed for this to work on multiple processors.
+ */
+ for(k=0; k < lssh[2]; k++)
+ {
+ for(j=0; j < lssh[1]; j++)
+ {
+ for(i=0; i < ghostz[0]; i++)
+ {
+ var[CCTK_GFINDEX3D(GH,i,j,k)] = sym[0] *
+ var[CCTK_GFINDEX3D(GH, 2*ghostz[0]-cntstag[0]-i, j, lssh[2]-k-1)];
+ }
+ }
+ }
+ }
+ else if (doSym[0] == GFSYM_ROTATION_Z)
+ {
+ /*
+ * FIXME: The following loop is local, but global indices are
+ * FIXME: needed for this to work on multiple processors.
+ */
+ for(k=0; k < lssh[2]; k++)
+ {
+ for(j=0; j < lssh[1]; j++)
+ {
+ for(i=0; i < ghostz[0]; i++)
+ {
+ var[CCTK_GFINDEX3D(GH,i,j,k)] = sym[0] *
+ var[CCTK_GFINDEX3D(GH, 2*ghostz[0]-cntstag[0]-i, lssh[1]-j-1, k)];
+ }
+ }
+ }
+ }
+
+ /*
+ * Apply symmetry to the lower y face.
+ */
+ if (doSym[2] == GFSYM_REFLECTION)
+ {
+ for(i=0; i < lssh[0]; i++)
+ {
+ for(k=0; k < lssh[2]; k++)
+ {
+ for(j=0; j < ghostz[1]; j++)
+ {
+ var[CCTK_GFINDEX3D(GH,i,j,k)] = sym[2] *
+ var[CCTK_GFINDEX3D(GH, i, 2*ghostz[1]-cntstag[1]-j, k)];
+ }
+ }
+ }
+ }
+ else if (doSym[2] == GFSYM_ROTATION_X)
+ {
+ /*
+ * FIXME: The following loop is local, but global indices are
+ * FIXME: needed for this to work on multiple processors.
+ */
+ for(i=0; i < lssh[0]; i++)
+ {
+ for(k=0; k < lssh[2]; k++)
+ {
+ for(j=0; j < ghostz[1]; j++)
+ {
+ var[CCTK_GFINDEX3D(GH,i,j,k)] = sym[2] *
+ var[CCTK_GFINDEX3D(GH, i, 2*ghostz[1]-cntstag[1]-j, lssh[2]-k-1)];
+ }
+ }
+ }
+ }
+ else if (doSym[2] == GFSYM_ROTATION_Z)
+ {
+ /*
+ * FIXME: The following loop is local, but global indices are
+ * FIXME: needed for this to work on multiple processors.
+ */
+ for(i=0; i < lssh[0]; i++)
+ {
+ for(k=0; k < lssh[2]; k++)
+ {
+ for(j=0; j < ghostz[1]; j++)
+ {
+ var[CCTK_GFINDEX3D(GH,i,j,k)] = sym[2] *
+ var[CCTK_GFINDEX3D(GH, lssh[0]-i-1, 2*ghostz[1]-cntstag[1]-j, k)];
+ }
+ }
+ }
+ }
+
+ /*
+ * Apply symmetry to the lower z face.
+ */
+ if (doSym[4] == GFSYM_REFLECTION)
{
for(i=0; i < lssh[0]; i++)
+ {
+ for(j=0; j < lssh[1]; j++)
{
- for(k=0; k < lssh[2]; k++)
- {
- for(j=0; j < ghostz[1]; j++)
- {
- var[CCTK_GFINDEX3D(GH,i,j,k)] =
- sym[2]*var[CCTK_GFINDEX3D(GH,i,2*ghostz[1]-cntstag[1]-j,k)];
- }
- }
+ for(k=0; k < ghostz[2]; k++)
+ {
+ var[CCTK_GFINDEX3D(GH,i,j,k)] = sym[4] *
+ var[CCTK_GFINDEX3D(GH, i, j, 2*ghostz[2]-cntstag[2]-k)];
+ }
}
+ }
}
- if (doSym[4] == 1)
+ else if (doSym[4] == GFSYM_ROTATION_X)
{
+ /*
+ * FIXME: The following loop is local, but global indices are
+ * FIXME: needed for this to work on multiple processors.
+ */
for(i=0; i < lssh[0]; i++)
+ {
+ for(j=0; j < lssh[1]; j++)
{
- for(j=0; j < lssh[1]; j++)
- {
- for(k=0; k < ghostz[2]; k++)
- {
- var[CCTK_GFINDEX3D(GH,i,j,k)] =
- sym[4]*var[CCTK_GFINDEX3D(GH,i,j,2*ghostz[2]-cntstag[2]-k)];
- }
- }
+ for(k=0; k < ghostz[2]; k++)
+ {
+ var[CCTK_GFINDEX3D(GH,i,j,k)] = sym[4] *
+ var[CCTK_GFINDEX3D(GH, i, lssh[1]-j-1, 2*ghostz[2]-cntstag[2]-k)];
+ }
}
+ }
}
+ else if (doSym[4] == GFSYM_ROTATION_Y)
+ {
+ /*
+ * FIXME: The following loop is local, but global indices are
+ * FIXME: needed for this to work on multiple processors.
+ */
+ for(i=0; i < lssh[0]; i++)
+ {
+ for(j=0; j < lssh[1]; j++)
+ {
+ for(k=0; k < ghostz[2]; k++)
+ {
+ var[CCTK_GFINDEX3D(GH,i,j,k)] = sym[4] *
+ var[CCTK_GFINDEX3D(GH, lssh[0]-i-1, j, 2*ghostz[2]-cntstag[2]-k)];
+ }
+ }
+ }
+ }
+
return(0);
}
@@ -149,28 +270,58 @@ int CartApplySym3Di(cGH *GH, int *doSym, int *cntstag,
int CartApplySym2Di(cGH *GH, int *doSym, int *cntstag,
int *lssh, int *ghostz, int *sym, CCTK_REAL *var)
{
- int i,j;
+ int i, j;
- if (doSym[0] == 1)
+ if (doSym[0] == GFSYM_REFLECTION)
+ {
+ for(j=0; j < lssh[1]; j++)
+ {
+ for(i=0; i < ghostz[0]; i++)
+ {
+ var[CCTK_GFINDEX2D(GH,i,j)] = sym[0] *
+ var[CCTK_GFINDEX2D(GH, 2*ghostz[0]-cntstag[0]-i, j)];
+ }
+ }
+ }
+ else if (doSym[0] == GFSYM_ROTATION_Z)
{
+ /*
+ * FIXME: The following loop is local, but global indices are
+ * FIXME: needed for this to work on multiple processors.
+ */
for(j=0; j < lssh[1]; j++)
{
for(i=0; i < ghostz[0]; i++)
{
- var[CCTK_GFINDEX2D(GH,i,j)] =
- sym[0]*var[CCTK_GFINDEX2D(GH,2*ghostz[0]-cntstag[0]-i,j)];
+ var[CCTK_GFINDEX2D(GH,i,j)] = sym[0] *
+ var[CCTK_GFINDEX2D(GH, 2*ghostz[0]-cntstag[0]-i, lssh[1]-j-1)];
}
}
}
- if (doSym[2] == 1)
+ if (doSym[2] == GFSYM_REFLECTION)
+ {
+ for(i=0; i < lssh[0]; i++)
+ {
+ for(j=0; j < ghostz[1]; j++)
+ {
+ var[CCTK_GFINDEX2D(GH,i,j)] = sym[2] *
+ var[CCTK_GFINDEX2D(GH, i, 2*ghostz[1]-cntstag[1]-j)];
+ }
+ }
+ }
+ else if (doSym[2] == GFSYM_ROTATION_Z)
{
+ /*
+ * FIXME: The following loop is local, but global indices are
+ * FIXME: needed for this to work on multiple processors.
+ */
for(i=0; i < lssh[0]; i++)
{
for(j=0; j < ghostz[1]; j++)
{
- var[CCTK_GFINDEX2D(GH,i,j)] =
- sym[2]*var[CCTK_GFINDEX2D(GH,i,2*ghostz[1]-cntstag[1]-j)];
+ var[CCTK_GFINDEX2D(GH,i,j)] = sym[2] *
+ var[CCTK_GFINDEX2D(GH, lssh[0]-i-1, 2*ghostz[1]-cntstag[1]-j)];
}
}
}
@@ -210,7 +361,7 @@ int CartApplySym1Di(cGH *GH, int *doSym, int *cntstag,
GH = GH;
lssh = lssh;
- if (doSym[0] == 1)
+ if (doSym[0] == GFSYM_REFLECTION)
{
for(i=0; i < ghostz[0]; i++)
{
diff --git a/src/Symmetry.h b/src/Symmetry.h
index e0b496a..4d23baf 100644
--- a/src/Symmetry.h
+++ b/src/Symmetry.h
@@ -19,8 +19,16 @@
#ifndef _SYMMETRY_H_
#define _SYMMETRY_H_
-#define GFSYM_UNSET -42
-#define GFSYM_NOSYM -41
+#define GFSYM_UNSET -41
+#define GFSYM_NOSYM -42
+
+#define GFSYM_REFLECTION 1
+#define GFSYM_ROTATION_X 2
+#define GFSYM_ROTATION_Y 3
+#define GFSYM_ROTATION_Z 4
+
+#define MAX_DIM 3
+#define MAX_FACE 6
typedef struct Symmetry
{
diff --git a/src/SymmetryWrappers.c b/src/SymmetryWrappers.c
index 19386fb..548c149 100644
--- a/src/SymmetryWrappers.c
+++ b/src/SymmetryWrappers.c
@@ -14,6 +14,8 @@
#include "cctk_FortranString.h"
#include "Symmetry.h"
+void DecodeSymParameters3D(int sym[6]);
+
void CCTK_FCALL CCTK_FNAME(CartSymGI)(int *ierr, cGH *GH, int *gi);
void CCTK_FCALL CCTK_FNAME(CartSymGN)
(int *ierr, cGH *GH, ONE_FORTSTRING_ARG);
@@ -50,7 +52,7 @@ static const char *rcsid = "$Header$";
CCTK_FILEVERSION(CactusBase_CartGrid3D_SymmetryWrappers_c)
-/*$#define SYM_DEBUG$*/
+/*#define SYM_DEBUG*/
/*@@
@@ -77,6 +79,7 @@ int CartSymGI(cGH *GH, int gi)
int berr=-1,ierr=-1;
int time;
int *doSym, *dstag, *lssh, *cntstag;
+ int domainsym[MAX_FACE];
SymmetryGHex *sGHex;
/* Get out if we are sure no symmetries should be applied */
@@ -118,6 +121,8 @@ int CartSymGI(cGH *GH, int gi)
time = 0;
}*/
+ DecodeSymParameters3D(domainsym);
+
for (vi=first_vi; vi<first_vi+numvars; vi++)
{
/* Apply Symmetries to lower sides [0,2,4,...] if:
@@ -139,16 +144,24 @@ int CartSymGI(cGH *GH, int gi)
}
lssh[idim] = GH->cctk_lssh[CCTK_LSSH_IDX(dstag[idim],idim)];
-
- doSym[idim*2] = (((sGHex->GFSym[vi][idim*2]!=GFSYM_NOSYM) &&
- (sGHex->GFSym[vi][idim*2]!=GFSYM_UNSET)) &&
- lssh[idim]>1 && GH->cctk_bbox[idim*2]==1);
+
+ if (((sGHex->GFSym[vi][idim*2] != GFSYM_NOSYM) &&
+ (sGHex->GFSym[vi][idim*2] != GFSYM_UNSET)) &&
+ lssh[idim]>1 && GH->cctk_bbox[idim*2]==1)
+ {
+ doSym[idim*2] = domainsym[idim*2];
+ }
+ else
+ {
+ doSym[idim*2] = 0;
+ }
+
doSym[idim*2+1] = 0;
}
#ifdef SYM_DEBUG
- printf(" DOSYM: %s [%d,%d] [%d,%d] [%d,%d] --- %d %d %d \n",
+ printf(" DOSYM: %s [%d,%d] [%d,%d] [%d,%d] --- %d %d %d\n",
CCTK_VarName(vi),
doSym[0],doSym[1],
doSym[2],doSym[3],
@@ -335,7 +348,7 @@ int CartSymVI(cGH *GH, int vi)
}
#ifdef SYM_DEBUG
- printf(" DOSYM: %s [%d,%d] [%d,%d] [%d,%d] --- %d %d %d \n",
+ printf(" DOSYM: %s [%d,%d] [%d,%d] [%d,%d] --- %d %d %d\n",
CCTK_VarName(vi),
doSym[0],doSym[1],
doSym[2],doSym[3],