PottsMeshGenerator.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "PottsMeshGenerator.hpp"
00037
00038 #include <boost/scoped_array.hpp>
00039
00040 template<unsigned DIM>
00041 PottsMeshGenerator<DIM>::PottsMeshGenerator(unsigned numNodesAcross, unsigned numElementsAcross, unsigned elementWidth,
00042 unsigned numNodesUp, unsigned numElementsUp, unsigned elementHeight,
00043 unsigned numNodesDeep, unsigned numElementsDeep, unsigned elementDepth,
00044 bool startAtBottomLeft, bool isPeriodicInX, bool isPeriodicInY ,bool isPeriodicInZ)
00045 {
00046 assert(numNodesAcross > 0);
00047 assert(numNodesUp > 0);
00048 assert(numNodesDeep > 0);
00049
00050 assert(numElementsAcross*elementWidth <= numNodesAcross);
00051 assert(numElementsUp*elementHeight <= numNodesUp);
00052 assert(numElementsDeep*elementDepth <= numNodesDeep);
00053
00054 std::vector<Node<DIM>*> nodes;
00055 std::vector<PottsElement<DIM>*> elements;
00056 std::vector<std::set<unsigned> > moore_neighbours;
00057 std::vector<std::set<unsigned> > von_neumann_neighbours;
00058
00059 unsigned num_nodes = numNodesAcross*numNodesUp*numNodesDeep;
00060
00061 unsigned next_node_index = 0;
00062 boost::scoped_array<unsigned> node_indices(new unsigned[elementWidth*elementHeight*elementDepth]);
00063 unsigned element_index;
00064
00065 unsigned index_offset = 0;
00066
00067 if (!startAtBottomLeft)
00068 {
00069
00070 unsigned across_gap = (numNodesAcross - numElementsAcross*elementWidth)/2;
00071 unsigned up_gap = (numNodesUp - numElementsUp*elementHeight)/2;
00072 unsigned deep_gap = (numNodesDeep - numElementsDeep*elementDepth)/2;
00073
00074 index_offset = deep_gap*numNodesAcross*numNodesUp + up_gap*numNodesAcross + across_gap;
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 for (unsigned k=0; k<numNodesDeep; k++)
00084 {
00085 for (unsigned j=0; j<numNodesUp; j++)
00086 {
00087 for (unsigned i=0; i<numNodesAcross; i++)
00088 {
00089 bool is_boundary_node=false;
00090 if (DIM==2)
00091 {
00092 is_boundary_node = (j==0 || j==numNodesUp-1 || (i==0 && !isPeriodicInX) || (i==numNodesAcross-1 && !isPeriodicInX) ) ? true : false;
00093 }
00094 if (DIM==3)
00095 {
00096 is_boundary_node = (j==0 || j==numNodesUp-1 || (i==0 && !isPeriodicInX) || (i==numNodesAcross-1 && !isPeriodicInX) || k==0 || k==numNodesDeep-1) ? true : false;
00097 }
00098 Node<DIM>* p_node = new Node<DIM>(next_node_index, is_boundary_node, i, j, k);
00099 nodes.push_back(p_node);
00100 next_node_index++;
00101 }
00102 }
00103 }
00104 assert(nodes.size()==num_nodes);
00105
00106
00107
00108
00109
00110 for (unsigned n=0; n<numElementsDeep; n++)
00111 {
00112 for (unsigned j=0; j<numElementsUp; j++)
00113 {
00114 for (unsigned i=0; i<numElementsAcross; i++)
00115 {
00116 for (unsigned m=0; m<elementDepth; m++)
00117 {
00118 for (unsigned l=0; l<elementHeight; l++)
00119 {
00120 for (unsigned k=0; k<elementWidth; k++)
00121 {
00122 node_indices[m*elementHeight*elementWidth + l*elementWidth + k] = n*elementDepth*numNodesUp*numNodesAcross +
00123 j*elementHeight*numNodesAcross +
00124 i*elementWidth +
00125 m*numNodesAcross*numNodesUp +
00126 l*numNodesAcross +
00127 k + index_offset;
00128 }
00129 }
00130 }
00131 std::vector<Node<DIM>*> element_nodes;
00132 for (unsigned k=0; k<elementDepth*elementHeight*elementWidth; k++)
00133 {
00134 element_nodes.push_back(nodes[node_indices[k]]);
00135 }
00136
00137 element_index = n*numElementsAcross*numElementsUp + j*numElementsAcross + i;
00138 PottsElement<DIM>* p_element = new PottsElement<DIM>(element_index, element_nodes);
00139 elements.push_back(p_element);
00140 }
00141 }
00142 }
00143
00144
00145
00146
00147
00148 moore_neighbours.resize(num_nodes);
00149 von_neumann_neighbours.resize(num_nodes);
00150
00151 for (unsigned node_index=0; node_index<num_nodes; node_index++)
00152 {
00153
00154
00155 moore_neighbours[node_index].clear();
00156
00157 switch (DIM)
00158 {
00159 case 2:
00160 {
00161 assert(DIM == 2);
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 std::vector<unsigned> moore_neighbour_indices_vector(8, node_index);
00176 moore_neighbour_indices_vector[0] += numNodesAcross;
00177 moore_neighbour_indices_vector[1] += numNodesAcross - 1;
00178 moore_neighbour_indices_vector[2] -= 1;
00179 moore_neighbour_indices_vector[3] -= numNodesAcross + 1;
00180 moore_neighbour_indices_vector[4] -= numNodesAcross;
00181 moore_neighbour_indices_vector[5] -= numNodesAcross - 1;
00182 moore_neighbour_indices_vector[6] += 1;
00183 moore_neighbour_indices_vector[7] += numNodesAcross + 1;
00184
00185
00186 bool on_south_edge = (node_index < numNodesAcross);
00187 bool on_north_edge = ((int) node_index > (int)numNodesAcross*((int)numNodesUp - 1) - 1);
00188 bool on_west_edge = (node_index%numNodesAcross == 0);
00189 bool on_east_edge = (node_index%numNodesAcross == numNodesAcross - 1);
00190
00191 if (isPeriodicInX)
00192 {
00193 if (on_west_edge)
00194 {
00195 moore_neighbour_indices_vector[1] = node_index + 2*numNodesAcross - 1;
00196 moore_neighbour_indices_vector[2] = node_index + numNodesAcross - 1;
00197 moore_neighbour_indices_vector[3] = node_index - 1;
00198 }
00199
00200 if (on_east_edge)
00201 {
00202 moore_neighbour_indices_vector[5] = node_index - 2*numNodesAcross + 1;
00203 moore_neighbour_indices_vector[6] = node_index - numNodesAcross + 1;
00204 moore_neighbour_indices_vector[7] = node_index + 1;
00205 }
00206 }
00207
00208 if (isPeriodicInY)
00209 {
00210 if (on_north_edge)
00211 {
00212 moore_neighbour_indices_vector[0] = node_index - numNodesAcross*(numNodesUp-1);
00213 moore_neighbour_indices_vector[1] = moore_neighbour_indices_vector[0] - 1;
00214 moore_neighbour_indices_vector[7] = moore_neighbour_indices_vector[0] + 1;
00215
00216 if (on_west_edge)
00217 {
00218 moore_neighbour_indices_vector[1] = moore_neighbour_indices_vector[1] + numNodesAcross;
00219 }
00220 if (on_east_edge)
00221 {
00222 moore_neighbour_indices_vector[7] = moore_neighbour_indices_vector[7] - numNodesAcross;
00223 }
00224 }
00225
00226 if (on_south_edge)
00227 {
00228 moore_neighbour_indices_vector[4] = node_index + numNodesAcross*(numNodesUp-1);
00229 moore_neighbour_indices_vector[3] = moore_neighbour_indices_vector[4] - 1;
00230 moore_neighbour_indices_vector[5] = moore_neighbour_indices_vector[4] + 1;
00231
00232 if (on_west_edge)
00233 {
00234 moore_neighbour_indices_vector[3] = moore_neighbour_indices_vector[3] + numNodesAcross;
00235 }
00236 if (on_east_edge)
00237 {
00238 moore_neighbour_indices_vector[5] = moore_neighbour_indices_vector[5] - numNodesAcross;
00239 }
00240 }
00241 }
00242
00243 if (isPeriodicInX)
00244 {
00245 on_east_edge = false;
00246 on_west_edge = false;
00247 }
00248 if (isPeriodicInY)
00249 {
00250 on_south_edge = false;
00251 on_north_edge = false;
00252 }
00253
00254
00255
00256 std::vector<bool> available_neighbours = std::vector<bool>(8, true);
00257 available_neighbours[0] = !on_north_edge;
00258 available_neighbours[1] = !(on_north_edge || on_west_edge);
00259 available_neighbours[2] = !on_west_edge;
00260 available_neighbours[3] = !(on_south_edge || on_west_edge);
00261 available_neighbours[4] = !on_south_edge;
00262 available_neighbours[5] = !(on_south_edge || on_east_edge);
00263 available_neighbours[6] = !on_east_edge;
00264 available_neighbours[7] = !(on_north_edge || on_east_edge);
00265
00266
00267 for (unsigned i=0; i<8; i++)
00268 {
00269 if (available_neighbours[i])
00270 {
00271 assert(moore_neighbour_indices_vector[i] < nodes.size());
00272 moore_neighbours[node_index].insert(moore_neighbour_indices_vector[i]);
00273 }
00274 }
00275 break;
00276 }
00277 case 3:
00278 {
00279 assert(DIM ==3);
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 std::vector<unsigned> moore_neighbour_indices_vector(26, node_index);
00294 moore_neighbour_indices_vector[0] += numNodesAcross;
00295 moore_neighbour_indices_vector[1] += numNodesAcross - 1;
00296 moore_neighbour_indices_vector[2] -= 1;
00297 moore_neighbour_indices_vector[3] -= numNodesAcross + 1;
00298 moore_neighbour_indices_vector[4] -= numNodesAcross;
00299 moore_neighbour_indices_vector[5] -= numNodesAcross - 1;
00300 moore_neighbour_indices_vector[6] += 1;
00301 moore_neighbour_indices_vector[7] += numNodesAcross + 1;
00302 moore_neighbour_indices_vector[8] -= numNodesAcross*numNodesUp;
00303 for (unsigned i=9; i<17; i++)
00304 {
00305 moore_neighbour_indices_vector[i] = moore_neighbour_indices_vector[i-9]-numNodesAcross*numNodesUp;
00306 }
00307 moore_neighbour_indices_vector[17] += numNodesAcross*numNodesUp;
00308 for (unsigned i=18; i<26; i++)
00309 {
00310 moore_neighbour_indices_vector[i]=moore_neighbour_indices_vector[i-18]+numNodesAcross*numNodesUp;
00311 }
00312
00313
00314 bool on_south_edge = (node_index%(numNodesAcross*numNodesUp)<numNodesAcross);
00315 bool on_north_edge = (node_index%(numNodesAcross*numNodesUp)>(numNodesAcross*numNodesUp-numNodesAcross-1));
00316 bool on_west_edge = (node_index%numNodesAcross == 0);
00317 bool on_east_edge = (node_index%numNodesAcross == numNodesAcross - 1);
00318 bool on_front_edge = (node_index < numNodesAcross*numNodesUp);
00319 bool on_back_edge = (node_index > numNodesAcross*numNodesUp*(numNodesDeep-1)-1);
00320
00321 if (isPeriodicInX)
00322 {
00323 if (on_west_edge)
00324 {
00325 moore_neighbour_indices_vector[1] = node_index + 2*numNodesAcross - 1;
00326 moore_neighbour_indices_vector[2] = node_index + numNodesAcross - 1;
00327 moore_neighbour_indices_vector[3] = node_index - 1;
00328
00329 moore_neighbour_indices_vector[10] = moore_neighbour_indices_vector[1] - numNodesAcross*numNodesUp;
00330 moore_neighbour_indices_vector[11] = moore_neighbour_indices_vector[2] - numNodesAcross*numNodesUp;
00331 moore_neighbour_indices_vector[12] = moore_neighbour_indices_vector[3] - numNodesAcross*numNodesUp;
00332
00333 moore_neighbour_indices_vector[19] = moore_neighbour_indices_vector[1] + numNodesAcross*numNodesUp;
00334 moore_neighbour_indices_vector[20] = moore_neighbour_indices_vector[2] + numNodesAcross*numNodesUp;
00335 moore_neighbour_indices_vector[21] = moore_neighbour_indices_vector[3] + numNodesAcross*numNodesUp;
00336 }
00337
00338 if (on_east_edge)
00339 {
00340 moore_neighbour_indices_vector[5] = node_index - 2*numNodesAcross + 1;
00341 moore_neighbour_indices_vector[6] = node_index - numNodesAcross + 1;
00342 moore_neighbour_indices_vector[7] = node_index + 1;
00343
00344 moore_neighbour_indices_vector[14] = moore_neighbour_indices_vector[5] - numNodesAcross*numNodesUp;
00345 moore_neighbour_indices_vector[15] = moore_neighbour_indices_vector[6] - numNodesAcross*numNodesUp;
00346 moore_neighbour_indices_vector[16] = moore_neighbour_indices_vector[7] - numNodesAcross*numNodesUp;
00347
00348 moore_neighbour_indices_vector[23] = moore_neighbour_indices_vector[5] + numNodesAcross*numNodesUp;
00349 moore_neighbour_indices_vector[24] = moore_neighbour_indices_vector[6] + numNodesAcross*numNodesUp;
00350 moore_neighbour_indices_vector[25] = moore_neighbour_indices_vector[7] + numNodesAcross*numNodesUp;
00351 }
00352 }
00353
00354 if (isPeriodicInY)
00355 {
00356 if (on_north_edge)
00357 {
00358 moore_neighbour_indices_vector[0] = node_index - numNodesAcross*(numNodesUp-1);
00359 moore_neighbour_indices_vector[1] = moore_neighbour_indices_vector[0] - 1;
00360 moore_neighbour_indices_vector[7] = moore_neighbour_indices_vector[0] + 1;
00361
00362 moore_neighbour_indices_vector[10] = moore_neighbour_indices_vector[1] - numNodesAcross*numNodesUp;
00363 moore_neighbour_indices_vector[9] = moore_neighbour_indices_vector[0] - numNodesAcross*numNodesUp;
00364 moore_neighbour_indices_vector[16] = moore_neighbour_indices_vector[7] - numNodesAcross*numNodesUp;
00365
00366 moore_neighbour_indices_vector[19] = moore_neighbour_indices_vector[1] + numNodesAcross*numNodesUp;
00367 moore_neighbour_indices_vector[18] = moore_neighbour_indices_vector[0] + numNodesAcross*numNodesUp;
00368 moore_neighbour_indices_vector[25] = moore_neighbour_indices_vector[7] + numNodesAcross*numNodesUp;
00369
00370 if (on_west_edge)
00371 {
00372 moore_neighbour_indices_vector[1] = moore_neighbour_indices_vector[1] + numNodesAcross;
00373 moore_neighbour_indices_vector[10] = moore_neighbour_indices_vector[10] + numNodesAcross;
00374 moore_neighbour_indices_vector[19] = moore_neighbour_indices_vector[19] + numNodesAcross;
00375 }
00376 if (on_east_edge)
00377 {
00378 moore_neighbour_indices_vector[7] = moore_neighbour_indices_vector[7] - numNodesAcross;
00379 moore_neighbour_indices_vector[16] = moore_neighbour_indices_vector[16] - numNodesAcross;
00380 moore_neighbour_indices_vector[25] = moore_neighbour_indices_vector[25] - numNodesAcross;
00381 }
00382 }
00383
00384 if (on_south_edge)
00385 {
00386 moore_neighbour_indices_vector[4] = node_index + numNodesAcross*(numNodesUp-1);
00387 moore_neighbour_indices_vector[3] = moore_neighbour_indices_vector[4] - 1;
00388 moore_neighbour_indices_vector[5] = moore_neighbour_indices_vector[4] + 1;
00389
00390 moore_neighbour_indices_vector[12] = moore_neighbour_indices_vector[3] - numNodesAcross*numNodesUp;
00391 moore_neighbour_indices_vector[13] = moore_neighbour_indices_vector[4] - numNodesAcross*numNodesUp;
00392 moore_neighbour_indices_vector[14] = moore_neighbour_indices_vector[5] - numNodesAcross*numNodesUp;
00393
00394 moore_neighbour_indices_vector[21] = moore_neighbour_indices_vector[3] + numNodesAcross*numNodesUp;
00395 moore_neighbour_indices_vector[22] = moore_neighbour_indices_vector[4] + numNodesAcross*numNodesUp;
00396 moore_neighbour_indices_vector[23] = moore_neighbour_indices_vector[5] + numNodesAcross*numNodesUp;
00397
00398 if (on_west_edge)
00399 {
00400 moore_neighbour_indices_vector[3] = moore_neighbour_indices_vector[3] + numNodesAcross;
00401 moore_neighbour_indices_vector[12] = moore_neighbour_indices_vector[12] + numNodesAcross;
00402 moore_neighbour_indices_vector[21] = moore_neighbour_indices_vector[21] + numNodesAcross;
00403 }
00404 if (on_east_edge)
00405 {
00406 moore_neighbour_indices_vector[5] = moore_neighbour_indices_vector[5] - numNodesAcross;
00407 moore_neighbour_indices_vector[14] = moore_neighbour_indices_vector[14] - numNodesAcross;
00408 moore_neighbour_indices_vector[23] = moore_neighbour_indices_vector[23] - numNodesAcross;
00409 }
00410 }
00411 }
00412
00413 if (isPeriodicInZ)
00414 {
00415 if (on_back_edge)
00416 {
00417 moore_neighbour_indices_vector[17] = node_index - numNodesAcross*numNodesUp*(numNodesDeep-1);
00418 moore_neighbour_indices_vector[20] = moore_neighbour_indices_vector[17] - 1;
00419 moore_neighbour_indices_vector[24] = moore_neighbour_indices_vector[17] + 1;
00420
00421 moore_neighbour_indices_vector[21] = moore_neighbour_indices_vector[20] - numNodesAcross;
00422 moore_neighbour_indices_vector[22] = moore_neighbour_indices_vector[17] - numNodesAcross;
00423 moore_neighbour_indices_vector[23] = moore_neighbour_indices_vector[24] - numNodesAcross;
00424
00425 moore_neighbour_indices_vector[19] = moore_neighbour_indices_vector[20] + numNodesAcross;
00426 moore_neighbour_indices_vector[18] = moore_neighbour_indices_vector[17] + numNodesAcross;
00427 moore_neighbour_indices_vector[25] = moore_neighbour_indices_vector[24] + numNodesAcross;
00428
00429 if (on_west_edge)
00430 {
00431 moore_neighbour_indices_vector[19] = moore_neighbour_indices_vector[19] + numNodesAcross;
00432 moore_neighbour_indices_vector[20] = moore_neighbour_indices_vector[20] + numNodesAcross;
00433 moore_neighbour_indices_vector[21] = moore_neighbour_indices_vector[21] + numNodesAcross;
00434 }
00435 if (on_east_edge)
00436 {
00437 moore_neighbour_indices_vector[23] = moore_neighbour_indices_vector[23] - numNodesAcross;
00438 moore_neighbour_indices_vector[24] = moore_neighbour_indices_vector[24] - numNodesAcross;
00439 moore_neighbour_indices_vector[25] = moore_neighbour_indices_vector[25] - numNodesAcross;
00440 }
00441
00442 if (on_south_edge)
00443 {
00444 moore_neighbour_indices_vector[21] = moore_neighbour_indices_vector[21] + numNodesAcross*numNodesUp;
00445 moore_neighbour_indices_vector[22] = moore_neighbour_indices_vector[22] + numNodesAcross*numNodesUp;
00446 moore_neighbour_indices_vector[23] = moore_neighbour_indices_vector[23] + numNodesAcross*numNodesUp;
00447 }
00448
00449 if (on_north_edge)
00450 {
00451 moore_neighbour_indices_vector[18] = moore_neighbour_indices_vector[18] - numNodesAcross*numNodesUp;
00452 moore_neighbour_indices_vector[19] = moore_neighbour_indices_vector[19] - numNodesAcross*numNodesUp;
00453 moore_neighbour_indices_vector[25] = moore_neighbour_indices_vector[25] - numNodesAcross*numNodesUp;
00454 }
00455 }
00456
00457 if (on_front_edge)
00458 {
00459 moore_neighbour_indices_vector[8] = node_index + numNodesAcross*numNodesUp*(numNodesDeep-1);
00460 moore_neighbour_indices_vector[11] = moore_neighbour_indices_vector[8] - 1;
00461 moore_neighbour_indices_vector[15] = moore_neighbour_indices_vector[8] + 1;
00462
00463 moore_neighbour_indices_vector[12] = moore_neighbour_indices_vector[11] - numNodesAcross;
00464 moore_neighbour_indices_vector[13] = moore_neighbour_indices_vector[8] - numNodesAcross;
00465 moore_neighbour_indices_vector[14] = moore_neighbour_indices_vector[15] - numNodesAcross;
00466
00467 moore_neighbour_indices_vector[10] = moore_neighbour_indices_vector[11] + numNodesAcross;
00468 moore_neighbour_indices_vector[9] = moore_neighbour_indices_vector[8] + numNodesAcross;
00469 moore_neighbour_indices_vector[16] = moore_neighbour_indices_vector[15] + numNodesAcross;
00470
00471 if (on_west_edge)
00472 {
00473 moore_neighbour_indices_vector[10] = moore_neighbour_indices_vector[10] + numNodesAcross;
00474 moore_neighbour_indices_vector[11] = moore_neighbour_indices_vector[11] + numNodesAcross;
00475 moore_neighbour_indices_vector[12] = moore_neighbour_indices_vector[12] + numNodesAcross;
00476 }
00477 if (on_east_edge)
00478 {
00479 moore_neighbour_indices_vector[14] = moore_neighbour_indices_vector[14] - numNodesAcross;
00480 moore_neighbour_indices_vector[15] = moore_neighbour_indices_vector[15] - numNodesAcross;
00481 moore_neighbour_indices_vector[16] = moore_neighbour_indices_vector[16] - numNodesAcross;
00482 }
00483
00484 if (on_south_edge)
00485 {
00486 moore_neighbour_indices_vector[12] = moore_neighbour_indices_vector[12] + numNodesAcross*numNodesUp;
00487 moore_neighbour_indices_vector[13] = moore_neighbour_indices_vector[13] + numNodesAcross*numNodesUp;
00488 moore_neighbour_indices_vector[14] = moore_neighbour_indices_vector[14] + numNodesAcross*numNodesUp;
00489 }
00490
00491 if (on_north_edge)
00492 {
00493 moore_neighbour_indices_vector[9] = moore_neighbour_indices_vector[9] - numNodesAcross*numNodesUp;
00494 moore_neighbour_indices_vector[10] = moore_neighbour_indices_vector[10] - numNodesAcross*numNodesUp;
00495 moore_neighbour_indices_vector[16] = moore_neighbour_indices_vector[16] - numNodesAcross*numNodesUp;
00496 }
00497 }
00498 }
00499
00500 if (isPeriodicInX)
00501 {
00502 on_east_edge = false;
00503 on_west_edge = false;
00504 }
00505 if (isPeriodicInY)
00506 {
00507 on_south_edge = false;
00508 on_north_edge = false;
00509 }
00510 if (isPeriodicInZ)
00511 {
00512 on_front_edge = false;
00513 on_back_edge = false;
00514 }
00515
00516
00517
00518 std::vector<bool> available_neighbours = std::vector<bool>(26, true);
00519 available_neighbours[0] = !on_north_edge;
00520 available_neighbours[1] = !(on_north_edge || on_west_edge);
00521 available_neighbours[2] = !on_west_edge;
00522 available_neighbours[3] = !(on_south_edge || on_west_edge);
00523 available_neighbours[4] = !on_south_edge;
00524 available_neighbours[5] = !(on_south_edge || on_east_edge);
00525 available_neighbours[6] = !on_east_edge;
00526 available_neighbours[7] = !(on_north_edge || on_east_edge);
00527 available_neighbours[8] = !(on_front_edge);
00528 for (unsigned i=9; i<17; i++)
00529 {
00530 available_neighbours[i] = (available_neighbours[i-9] && !(on_front_edge));
00531 }
00532 available_neighbours[17] = !(on_back_edge);
00533 for (unsigned i=18; i<26; i++)
00534 {
00535 available_neighbours[i] = (available_neighbours[i-18] && !(on_back_edge));
00536 }
00537
00538
00539 for (unsigned i=0; i<26; i++)
00540 {
00541 if (available_neighbours[i] && moore_neighbour_indices_vector[i] < numNodesAcross*numNodesUp*numNodesDeep)
00542 {
00543 assert(moore_neighbour_indices_vector[i] < nodes.size());
00544 moore_neighbours[node_index].insert(moore_neighbour_indices_vector[i]);
00545 }
00546 }
00547 break;
00548 }
00549 default:
00550 NEVER_REACHED;
00551 }
00552
00553
00554 von_neumann_neighbours[node_index].clear();
00555
00556 switch (DIM)
00557 {
00558 case 2:
00559 {
00560 assert(DIM == 2);
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 std::vector<unsigned> von_neumann_neighbour_indices_vector(4, node_index);
00574 von_neumann_neighbour_indices_vector[0] += numNodesAcross;
00575 von_neumann_neighbour_indices_vector[1] -= 1;
00576 von_neumann_neighbour_indices_vector[2] -= numNodesAcross;
00577 von_neumann_neighbour_indices_vector[3] += 1;
00578
00579
00580 bool on_south_edge = (node_index < numNodesAcross);
00581 bool on_north_edge = ((int)node_index > (int)numNodesAcross*((int)numNodesUp - 1) - 1);
00582 bool on_west_edge = (node_index%numNodesAcross == 0);
00583 bool on_east_edge = (node_index%numNodesAcross == numNodesAcross - 1);
00584
00585 if (isPeriodicInX)
00586 {
00587 if (on_west_edge)
00588 {
00589 von_neumann_neighbour_indices_vector[1] = node_index + numNodesAcross - 1;
00590 on_west_edge = false;
00591 }
00592
00593 if (on_east_edge)
00594 {
00595 von_neumann_neighbour_indices_vector[3] = node_index - numNodesAcross + 1;
00596 on_east_edge = false;
00597 }
00598 }
00599
00600 if (isPeriodicInY)
00601 {
00602 if (on_north_edge)
00603 {
00604 von_neumann_neighbour_indices_vector[0] = node_index - numNodesAcross*(numNodesUp-1);
00605 on_north_edge = false;
00606 }
00607
00608 if (on_south_edge)
00609 {
00610 von_neumann_neighbour_indices_vector[2] = node_index + numNodesAcross*(numNodesUp-1);
00611 on_south_edge = false;
00612 }
00613 }
00614
00615
00616
00617 std::vector<bool> available_neighbours = std::vector<bool>(2*DIM, true);
00618 available_neighbours[0] = !on_north_edge;
00619 available_neighbours[1] = !on_west_edge;
00620 available_neighbours[2] = !on_south_edge;
00621 available_neighbours[3] = !on_east_edge;
00622
00623
00624 for (unsigned i=0; i<4; i++)
00625 {
00626 if (available_neighbours[i])
00627 {
00628 assert(von_neumann_neighbour_indices_vector[i] < nodes.size());
00629 von_neumann_neighbours[node_index].insert(von_neumann_neighbour_indices_vector[i]);
00630 }
00631 }
00632 break;
00633 }
00634 case 3:
00635 {
00636 assert(DIM == 3);
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 std::vector<unsigned> von_neumann_neighbour_indices_vector(6, node_index);
00651 von_neumann_neighbour_indices_vector[0] += numNodesAcross;
00652 von_neumann_neighbour_indices_vector[1] -= 1;
00653 von_neumann_neighbour_indices_vector[2] -= numNodesAcross;
00654 von_neumann_neighbour_indices_vector[3] += 1;
00655 von_neumann_neighbour_indices_vector[4] -= numNodesAcross*numNodesUp;
00656 von_neumann_neighbour_indices_vector[5] += numNodesAcross*numNodesUp;
00657
00658
00659 bool on_south_edge = (node_index%(numNodesAcross*numNodesUp)<numNodesAcross);
00660 bool on_north_edge = (node_index%(numNodesAcross*numNodesUp)>(numNodesAcross*numNodesUp-numNodesAcross-1));
00661 bool on_west_edge = (node_index%numNodesAcross== 0);
00662 bool on_east_edge = (node_index%numNodesAcross == numNodesAcross - 1);
00663 bool on_front_edge = (node_index < numNodesAcross*numNodesUp);
00664 bool on_back_edge = (node_index > numNodesAcross*numNodesUp*(numNodesDeep-1)-1);
00665
00666 if (isPeriodicInX)
00667 {
00668 if (on_west_edge)
00669 {
00670 von_neumann_neighbour_indices_vector[1] = node_index + numNodesAcross - 1;
00671 on_west_edge = false;
00672 }
00673
00674 if (on_east_edge)
00675 {
00676 von_neumann_neighbour_indices_vector[3] = node_index - numNodesAcross + 1;
00677 on_east_edge = false;
00678 }
00679 }
00680
00681 if (isPeriodicInY)
00682 {
00683 if (on_north_edge)
00684 {
00685 von_neumann_neighbour_indices_vector[0] = node_index - numNodesAcross*(numNodesUp-1);
00686 on_north_edge = false;
00687 }
00688
00689 if (on_south_edge)
00690 {
00691 von_neumann_neighbour_indices_vector[2] = node_index + numNodesAcross*(numNodesUp-1);
00692 on_south_edge = false;
00693 }
00694 }
00695
00696 if (isPeriodicInZ)
00697 {
00698 if (on_front_edge)
00699 {
00700 von_neumann_neighbour_indices_vector[4] = node_index + numNodesAcross*numNodesUp*(numNodesDeep-1);
00701 on_front_edge = false;
00702 }
00703
00704 if (on_back_edge)
00705 {
00706 von_neumann_neighbour_indices_vector[5] = node_index - numNodesAcross*numNodesUp*(numNodesDeep-1);
00707 on_back_edge = false;
00708 }
00709 }
00710
00711
00712
00713 std::vector<bool> available_neighbours = std::vector<bool>(2*DIM, true);
00714 available_neighbours[0] = !on_north_edge;
00715 available_neighbours[1] = !on_west_edge;
00716 available_neighbours[2] = !on_south_edge;
00717 available_neighbours[3] = !on_east_edge;
00718 available_neighbours[4] = !on_front_edge;
00719 available_neighbours[5] = !on_back_edge;
00720
00721
00722 for (unsigned i=0; i<6; i++)
00723 {
00724 if (available_neighbours[i] && von_neumann_neighbour_indices_vector[i]<numNodesAcross*numNodesUp*numNodesDeep)
00725 {
00726 assert(von_neumann_neighbour_indices_vector[i] < nodes.size());
00727 von_neumann_neighbours[node_index].insert(von_neumann_neighbour_indices_vector[i]);
00728 }
00729 }
00730 break;
00731 }
00732 default:
00733 NEVER_REACHED;
00734 }
00735 }
00736
00737 mpMesh = new PottsMesh<DIM>(nodes, elements, von_neumann_neighbours, moore_neighbours);
00738 }
00739
00740 template<unsigned DIM>
00741 PottsMeshGenerator<DIM>::~PottsMeshGenerator()
00742 {
00743 delete mpMesh;
00744 }
00745
00746 template<unsigned DIM>
00747 PottsMesh<DIM>* PottsMeshGenerator<DIM>::GetMesh()
00748 {
00749 return mpMesh;
00750 }
00751
00753
00755
00756 template class PottsMeshGenerator<1>;
00757 template class PottsMeshGenerator<2>;
00758 template class PottsMeshGenerator<3>;