SundancePartitionedRectangleMesher.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 
00043 #include "SundancePartitionedRectangleMesher.hpp"
00044 #include "SundanceOut.hpp"
00045 
00046 using namespace Sundance;
00047 using namespace Sundance;
00048 
00049 using namespace Teuchos;
00050 using namespace Sundance;
00051 
00052 PartitionedRectangleMesher::PartitionedRectangleMesher(const ParameterList& params)
00053   : MeshSourceBase(params),
00054     ax_(params.get<double>("ax")),
00055     bx_(params.get<double>("bx")),
00056     nx_(params.get<int>("nx")),
00057     npx_(1),
00058     ay_(params.get<double>("ay")),
00059     by_(params.get<double>("by")),
00060     ny_(params.get<int>("ny")),
00061     npy_(1)
00062 {
00063   if (params.isParameter("npx"))
00064     {
00065       npx_ = params.get<int>("npx");
00066     }
00067   if (params.isParameter("npy"))
00068     {
00069       npy_ = params.get<int>("npy");
00070     }
00071 }
00072 
00073 
00074 void PartitionedRectangleMesher::balanceXY(int n, int* npx, int* npy)
00075 {
00076   int m = (int) floor(sqrt((double)n));
00077   for (int i=m; i>=1; i--)
00078   {
00079     if (n % i == 0) 
00080     {
00081       *npx = i;
00082       *npy = n/i;
00083       return ;
00084     }
00085   }
00086 
00087   *npx = n;
00088   *npy = 1;
00089 }
00090 
00091 
00092 Mesh PartitionedRectangleMesher::fillMesh() const
00093 {
00094   SUNDANCE_OUT(this->verb() > 0,
00095                "PartitionedRectangleMesher::fillLocalMesh() is meshing "
00096                "rectangle [" << ax_ << ", " << bx_ << "] by ["
00097                << ay_ << ", " << by_ << "]");
00098 
00099   SUNDANCE_OUT(this->verb() >= 3,
00100                "PartitionedRectangleMesher::fillLocalMesh() starting creation "
00101                "of empty mesh");
00102 
00103   Mesh mesh = createMesh(2);
00104 
00105   SUNDANCE_OUT(this->verb() >= 3,
00106                "PartitionedRectangleMesher::fillLocalMesh() done creation of "
00107                "empty mesh");
00108   
00109   /* compute number of points per proc */
00110 
00111   int np = nProc();
00112   int rank = myRank();
00113 
00114   TEUCHOS_TEST_FOR_EXCEPTION(npx_ * npy_ != np, std::runtime_error,
00115                      "PartitionedRectangleMesher::fillLocalMesh(): product "
00116                      "of npx=" << npx_ << " and npy=" << npy_
00117                      << " is not equal to np=" << np);
00118 
00119   /* compute number of points per proc */
00120 
00121   int nppx = nx_;
00122   int nppy = ny_;
00123   int nxTot = nx_*npx_;
00124   int nyTot = ny_*npy_;
00125 
00126   int px = rank/npy_;
00127   int py = rank % npy_;
00128 
00129   int lowestVisiblePtX = px*nppx-1;
00130   int lowestVisiblePtY = py*nppy-1;
00131   if (lowestVisiblePtX < 0) lowestVisiblePtX = 0;
00132   if (lowestVisiblePtY < 0) lowestVisiblePtY = 0;
00133 
00134   
00135   int highestVisiblePtX = lowestVisiblePtX + nppx + 1;
00136   int highestVisiblePtY = lowestVisiblePtY + nppy + 1;
00137   if (highestVisiblePtX > nxTot) highestVisiblePtX = nxTot;
00138   if (highestVisiblePtY > nyTot) highestVisiblePtY = nyTot;
00139 
00140 
00141   Array<Array<int> > pts(highestVisiblePtX-lowestVisiblePtX+1);
00142   for (int i=0; i<pts.size(); i++) pts[i].resize(highestVisiblePtY-lowestVisiblePtY+1);
00143 
00144   int globalIndex = 0;
00145 
00146   /* add the visible points into the mesh */
00147   for (int i=0; i<=nxTot; i++)
00148     {
00149       for (int j=0; j<=nyTot; j++, globalIndex++)
00150         {
00151           if (i < lowestVisiblePtX || i > highestVisiblePtX) continue;
00152           if (j < lowestVisiblePtY || j > highestVisiblePtY) continue;
00153 
00154           int ip = i/nppx;
00155           if (i==nxTot) ip--;
00156           int jp = j/nppy;
00157           if (j==nyTot) jp--;
00158           int pointOwner = ip*npy_ + jp;
00159 
00160           Point x( ax_ + ((double) i)*(bx_-ax_)/((double) nxTot) ,
00161                    ay_ + ((double) j)*(by_-ay_)/((double) nyTot));
00162           SUNDANCE_OUT(this->verb() > 1, "adding point GID=" 
00163                        << globalIndex << " x=" << x << " owner=" 
00164                        << pointOwner);
00165           int lid = mesh.addVertex(globalIndex, x, pointOwner, 0);
00166           pts[i-lowestVisiblePtX][j-lowestVisiblePtY] = globalIndex;
00167           
00168           SUNDANCE_OUT(this->verb() >=  3,
00169                        "point " << x << " registered with LID=" << lid);
00170         }
00171     }
00172 
00173   /* add the visible cells to the mesh */
00174   globalIndex = 0 ;
00175 
00176   for (int i=0; i<nxTot; i++)
00177     {
00178       for (int j=0; j<nyTot; j++, globalIndex+=2)
00179         {
00180           if (i < lowestVisiblePtX || i >= highestVisiblePtX) continue;
00181           if (j < lowestVisiblePtY || j >= highestVisiblePtY) continue;
00182 
00183           int a = pts[i-lowestVisiblePtX][j-lowestVisiblePtY];
00184           int b = pts[i+1-lowestVisiblePtX][j-lowestVisiblePtY];
00185           int c = pts[i+1-lowestVisiblePtX][j+1-lowestVisiblePtY];
00186           int d = pts[i-lowestVisiblePtX][j+1-lowestVisiblePtY];
00187 
00188           int ip = i/nppx;
00189           int jp = j/nppy;
00190           int cellOwner = ip*npy_ + jp;
00191           Array<int> tri1;
00192           Array<int> tri2;
00193           if (i%2 == j%2)
00194             {
00195               tri1 = tuple(a,b,c);
00196               tri2 = tuple(a,c,d);
00197             }
00198           else
00199             {
00200               tri1 = tuple(a,b,d);
00201               tri2 = tuple(b,c,d);
00202             }
00203           int lid1 = mesh.addElement(globalIndex, tri1, cellOwner, 0);
00204           SUNDANCE_OUT(this->verb() >=  3,
00205                        "elem " << tri1 
00206                        << " registered with LID=" << lid1);
00207           int lid2 = mesh.addElement(globalIndex+1, tri2, cellOwner, 0);
00208           SUNDANCE_OUT(this->verb() >=  3,
00209                        "elem " << tri2 
00210                        << " registered with LID=" << lid2);
00211           
00212         }
00213     }
00214 
00215   mesh.freezeTopology();
00216 
00217   return mesh;
00218 }

Site Contact