Strip extra spaces from code.
[voro++.git] / branches / 2d / src / worklist_gen.pl
blob0cda50de727e56218562e7569da074e8109c5586
1 #!/usr/bin/perl
2 # Voro++, a 2D and 3D cell-based Voronoi library
4 # Author : Chris H. Rycroft (LBL / UC Berkeley)
5 # Email : chr@alum.mit.edu
6 # Date : August 30th 2011
8 # worklist_gen.pl - this perl script is used to automatically generate the
9 # worklists of blocks that are stored in worklist.cc, that are used by the
10 # compute_cell() routine to ensure maximum efficiency
12 # Each region is divided into a grid of subregions, and a worklist is
13 # constructed for each. This parameter sets is set to half the number of
14 # subregions that the block is divided into.
15 $hr=4;
17 # This parameter is automatically set to the the number of subregions that the
18 # block is divided into
19 $r=$hr*2;
21 # This parameter sets the total number of block entries in each worklist
22 $ls=63;
24 # When the worklists are being constructed, a mask array is made use of. To
25 # prevent the creation of array elements with negative indices, this parameter
26 # sets an arbitrary displacement.
27 $dis=8;
29 # Constants used mask indexing
30 $d=2*$dis+1;$d0=(1+$d)*$dis;
32 use Math::Trig;
34 # Construct the worklist header file, based on the parameters above
35 open W,">worklist_2d.hh";
36 print W <<EOF;
37 // Voro++, a 2D and 3D cell-based Voronoi library
39 // Author : Chris H. Rycroft (LBL / UC Berkeley)
40 // Email : chr\@alum.mit.edu
41 // Date : August 30th 2011
43 /** \\file worklist_2d.hh
44 * \\brief Header file for setting constants used in the block worklists that are
45 * used during cell computation.
47 * This file is automatically generated by worklist_gen.pl and it is not
48 * intended to be edited by hand. */
50 #ifndef VOROPP_WORKLIST_2D_HH
51 #define VOROPP_WORKLIST_2D_HH
53 namespace voro {
55 /** Each region is divided into a grid of subregions, and a worklist is
56 # constructed for each. This parameter sets is set to half the number of
57 # subregions that the block is divided into. */
58 EOF
59 print W "const int wl_hgrid_2d=$hr;\n";
60 print W <<EOF;
61 /** The number of subregions that a block is subdivided into, which is twice
62 the value of hgrid. */
63 EOF
64 print W "const int wl_fgrid_2d=$r;\n";
65 print W <<EOF;
66 /** The total number of worklists, set to the cube of hgrid. */
67 EOF
68 printf W "const int wl_hgridsq_2d=%d;\n",$hr*$hr;
69 print W <<EOF;
70 /** The number of elements in each worklist. */
71 EOF
72 printf W "const int wl_seq_length_2d=%d;\n",$ls+1;
73 print W <<EOF;
76 #endif
77 EOF
78 close W;
80 # Construct the preamble to the worklist.cc file
81 open W,">v_base_wl_2d.cc";
82 print W <<EOF;
83 // Voro++, a 2D and 3D cell-based Voronoi library
85 // Author : Chris H. Rycroft (LBL / UC Berkeley)
86 // Email : chr\@alum.mit.edu
87 // Date : August 30th 2011
89 /** \\file v_base_wl_2d.cc
90 * \\brief The table of block worklists that are used during the cell
91 * computation, which is part of the voro_base class.
93 * This file is automatically generated by worklist_gen.pl and it is not
94 * intended to be edited by hand. */
96 EOF
97 printf W "const unsigned int voro_base_2d::wl[wl_seq_length_2d*wl_hgridsq_2d]={\n";
99 # Now create a worklist for each subregion
100 for($jj=0;$jj<$hr;$jj++) {
101 for($ii=0;$ii<$hr;$ii++) {
102 worklist($ii,$jj);
106 # Finish the file and close it
107 print W "};\n";
108 close W;
110 sub worklist {
111 $ind=@_[0]+$hr*@_[1];
112 $ac=0;$v+=2;
113 $xp=$yp=0;
114 $x=(@_[0]+0.5)/$r;
115 $y=(@_[1]+0.5)/$r;
116 $m[$d0]=$v;
117 add(1,0,0);add(0,1,0);add(-1,0,0);add(0,-1,0);
118 foreach $l (1..$ls) {
119 $minwei=1e9;
120 foreach (0..$ac-1) {
121 $xt=@a[2*$_];$yt=@a[2*$_+1];
122 $wei=adis($x,$y,$xt,$yt)+0.02*sqrt(($xt-$xp)**2+($yt-$yp)**2);
123 $nx=$_,$minwei=$wei if $wei<$minwei;
125 $xp=@a[2*$nx];$yp=@a[2*$nx+1];
126 add($xp+1,$yp);add($xp,$yp+1);
127 add($xp-1,$yp);add($xp,$yp-1);
128 # print "=> $l $xp $yp $zp\n" if $l<4;
129 push @b,(splice @a,2*$nx,2);$ac--;
132 # Mark all blocks that are on this worklist entry
133 $m[$d0]=++$v;
134 for($i=0;$i<$#b;$i+=2) {
135 $xt=$b[$i];$yt=$b[$i+1];
136 #print "$xt $yt\n";
137 $m[$d0+$xt+$d*$yt]=$v;
140 # Find which neighboring outside blocks need to be marked when
141 # considering this block, being as conservative as possible by
142 # overwriting the marks, so that the last possible entry that can reach
143 # a block is used
144 for($i=$j=0;$i<$#b;$i+=2,$j++) {
145 $xt=$b[$i];$yt=$b[$i+1];
146 $k=$d0+$xt+$yt*$d;
147 $la[$k+1]=$j, $m[$k+1]=$v+1 if $xt>=0 && $m[$k+1]!=$v;
148 $la[$k+$d]=$j, $m[$k+$d]=$v+1 if $yt>=0 && $m[$k+$d]!=$v;
149 $la[$k-1]=$j, $m[$k-1]=$v+1 if $xt<=0 && $m[$k-1]!=$v;
150 $la[$k-$d]=$j, $m[$k-$d]=$v+1 if $yt<=0 && $m[$k-$d]!=$v;
153 # Scan to ensure that no neighboring blocks have been missed by the
154 # outwards-looking logic in the above section
155 for($i=0;$i<$#b;$i+=2) {
156 wl_check($d0+$b[$i]+$b[$i+1]*$d);
159 # Compute the number of entries where outside blocks do not need to be
160 # consider
161 for($i=$j=0;$i<$#b;$i+=2,$j++) {
162 $k=$d0+$b[$i]+$b[$i+1]*$d;
163 last if $m[$k+1]!=$v;
164 last if $m[$k+$d]!=$v;
165 last if $m[$k-1]!=$v;
166 last if $m[$k-$d]!=$v;
168 print W "\t$j";
170 # Create worklist entry and save to file
171 $j=0;
172 while ($#b>0) {
173 $xt=shift @b;$yt=shift @b;
174 $k=$d0+$xt+$yt*$d;
175 $o=0;
176 $o|=1 if $m[$k+1]!=$v && $la[$k+1]==$j;
177 $o^=3 if $m[$k-1]!=$v && $la[$k-1]==$j;
178 $o|=8 if $m[$k+$d]!=$v && $la[$k+$d]==$j;
179 $o^=24 if $m[$k-$d]!=$v && $la[$k-$d]==$j;
180 printf W ",%#x",(($xt+64)|($yt+64)<<7|$o<<21);
181 $j++;
183 print W "," unless $ind==$hr*$hr-1;
184 print W "\n";
186 # Remove list memory
187 undef @a;
188 undef @b;
191 sub add {
192 if ($m[$d0+@_[0]+$d*@_[1]]!=$v) {
193 $ac++;
194 push @a,@_[0],@_[1];
195 $m[$d0+@_[0]+$d*@_[1]]=$v;
199 sub adis {
200 $xco=$yco=0;
201 $xco=@_[0]-@_[2] if @_[2]>0;
202 $xco=@_[0]-@_[2]-1 if @_[2]<0;
203 $yco=@_[1]-@_[3] if @_[3]>0;
204 $yco=@_[1]-@_[3]-1 if @_[3]<0;
205 return sqrt $xco*$xco+$yco*$yco;
208 sub wl_check {
209 die "Failure in worklist construction\n" if $m[@_[0]+1]<$v||$m[@_[0]-1]<$v
210 ||$m[@_[0]+$d]<$v||$m[@_[0]-$d]<$v;