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
00037
00038
00039
00040
00041
00042 #include "SundancePeriodicMesh1D.hpp"
00043
00044 #include "SundanceCellJacobianBatch.hpp"
00045 #include "SundanceMaximalCofacetBatch.hpp"
00046 #include "SundanceDebug.hpp"
00047 #include "SundanceOut.hpp"
00048 #include "PlayaMPIContainerComm.hpp"
00049 #include "Teuchos_Time.hpp"
00050 #include "Teuchos_TimeMonitor.hpp"
00051 #include "SundanceObjectWithVerbosity.hpp"
00052
00053 using namespace Sundance;
00054 using namespace Teuchos;
00055 using namespace std;
00056 using Playa::MPIComm;
00057 using Playa::MPIContainerComm;
00058
00059
00060 PeriodicMesh1D::PeriodicMesh1D(double xMin, double xMax, int numElems)
00061 : MeshBase(1, MPIComm::self(), ExodusMeshOrder),
00062 numElems_(numElems),
00063 xMin_(xMin),
00064 xMax_(xMax),
00065 x_(numElems+1),
00066 verts_(numElems),
00067 labels_(2)
00068 {
00069 labels_[0].resize(numElems_);
00070 labels_[1].resize(numElems_);
00071
00072 for (int i=0; i<numElems_; i++)
00073 {
00074 labels_[0][i] = 0;
00075 labels_[1][i] = 1;
00076 verts_[i].resize(2);
00077 verts_[i][0] = i;
00078 verts_[i][1] = (i+1) % numElems;
00079 }
00080
00081 for (int i=0; i<=numElems_; i++)
00082 {
00083 x_[i] = Point(xMin_ + ((double) i)/((double) numElems_)*(xMax_-xMin_));
00084 }
00085 }
00086
00087 int PeriodicMesh1D::numCells(int cellDim) const
00088 {
00089 switch(cellDim)
00090 {
00091 case 0 :
00092 return numElems_;
00093 case 1:
00094 return numElems_;
00095 default:
00096 TEUCHOS_TEST_FOR_EXCEPT(true);
00097 }
00098 return -1;
00099 }
00100
00101
00102 Point PeriodicMesh1D::nodePosition(int i) const
00103 {
00104 return x_[i];
00105 }
00106
00107
00108 const double* PeriodicMesh1D::nodePositionView(int i) const
00109 {
00110 return &(x_[i][0]);
00111 }
00112
00113 void PeriodicMesh1D::getJacobians(int cellDim, const Array<int>& cellLID,
00114 CellJacobianBatch& jBatch) const
00115 {
00116 TEUCHOS_TEST_FOR_EXCEPTION(cellDim < 0 || cellDim > spatialDim(), std::logic_error,
00117 "cellDim=" << cellDim
00118 << " is not in expected range [0, " << spatialDim()
00119 << "]");
00120
00121 jBatch.resize(cellLID.size(), spatialDim(), cellDim);
00122
00123 int nCells = cellLID.size();
00124
00125 if (cellDim==0)
00126 {
00127 for (int i=0; i<nCells; i++)
00128 {
00129 double* detJ = jBatch.detJ(i);
00130 *detJ = 1.0;
00131 }
00132 }
00133 else
00134 {
00135 for (int i=0; i<nCells; i++)
00136 {
00137 int lid = cellLID[i];
00138 double* J = jBatch.jVals(i);
00139 double x0 = x_[lid][0];
00140 double x1 = x_[lid+1][0];
00141 J[0] = fabs(x1-x0);
00142 }
00143 }
00144 }
00145
00146
00147 void PeriodicMesh1D::getCellDiameters(int cellDim, const Array<int>& cellLID,
00148 Array<double>& cellDiameters) const
00149 {
00150 cellDiameters.resize(cellLID.size());
00151
00152 TEUCHOS_TEST_FOR_EXCEPT(cellDim < 0 || cellDim > 1);
00153
00154 if (cellDim==1)
00155 {
00156 for (int i=0; i<cellLID.size(); i++)
00157 {
00158 int c = cellLID[i];
00159 double h = x_[c+1][0]-x_[c][0];
00160 cellDiameters[i] = h;
00161 }
00162 }
00163 else
00164 {
00165 for (int i=0; i<cellLID.size(); i++)
00166 {
00167 cellDiameters[i] = 1.0;
00168 }
00169 }
00170 }
00171
00172 void PeriodicMesh1D::pushForward(int cellDim, const Array<int>& cellLID,
00173 const Array<Point>& refQuadPts,
00174 Array<Point>& physQuadPts) const
00175 {
00176 TEUCHOS_TEST_FOR_EXCEPT(cellDim < 0 || cellDim > 1);
00177
00178 if (cellDim==1)
00179 {
00180 if (physQuadPts.size() > 0) physQuadPts.resize(0);
00181 physQuadPts.reserve(refQuadPts.size() * cellLID.size());
00182
00183 for (int i=0; i<cellLID.size(); i++)
00184 {
00185 int c = cellLID[i];
00186 Point h = x_[c+1]-x_[c];
00187 for (int q=0; q<refQuadPts.size(); q++)
00188 {
00189 physQuadPts.append(Point(x_[c] + refQuadPts[q][0] * h));
00190 }
00191 }
00192 }
00193 else
00194 {
00195 for (int i=0; i<cellLID.size(); i++)
00196 {
00197 physQuadPts.append(x_[cellLID[i]]);
00198 }
00199 }
00200 }
00201
00202 int PeriodicMesh1D::numFacets(int cellDim, int cellLID,
00203 int facetDim) const
00204 {
00205 TEUCHOS_TEST_FOR_EXCEPT(cellLID < 0 || cellLID >= numElems_);
00206 if (cellDim == 1 && facetDim==0) return 2;
00207 return 0;
00208 }
00209
00210
00211
00212 int PeriodicMesh1D::facetLID(int cellDim, int cellLID,
00213 int facetDim, int facetIndex,
00214 int& facetOrientation) const
00215 {
00216 TEUCHOS_TEST_FOR_EXCEPT(cellLID < 0 || cellLID >= numElems_);
00217
00218 TEUCHOS_TEST_FOR_EXCEPT(cellDim != 1);
00219 TEUCHOS_TEST_FOR_EXCEPT(facetDim != 0);
00220 TEUCHOS_TEST_FOR_EXCEPT(facetIndex < 0);
00221 TEUCHOS_TEST_FOR_EXCEPT(facetIndex > 1);
00222
00223 return verts_[cellLID][facetIndex];
00224 }
00225
00226 void PeriodicMesh1D::getFacetLIDs(int cellDim,
00227 const Array<int>& cellLID,
00228 int facetDim,
00229 Array<int>& facetLID,
00230 Array<int>& facetSign) const
00231 {
00232 facetLID.resize(2*cellLID.size());
00233 facetSign.resize(2*cellLID.size());
00234
00235 for (int i=0; i<cellLID.size(); i++)
00236 {
00237 facetLID[2*i] = this->facetLID(cellDim, cellLID[i], facetDim, 0, facetSign[2*i]);
00238 facetLID[2*i+1] = this->facetLID(cellDim, cellLID[i], facetDim, 1, facetSign[2*i]);
00239 }
00240 }
00241
00242
00243 const int* PeriodicMesh1D::elemZeroFacetView(int cellLID) const
00244 {
00245 return &(verts_[cellLID][0]);
00246 }
00247
00248
00249 int PeriodicMesh1D::numMaxCofacets(int cellDim, int cellLID) const
00250 {
00251 TEUCHOS_TEST_FOR_EXCEPT(cellDim != 0);
00252 return 2;
00253 }
00254
00255 int PeriodicMesh1D::maxCofacetLID(int cellDim, int cellLID,
00256 int cofacetIndex,
00257 int& facetIndex) const
00258 {
00259 TEUCHOS_TEST_FOR_EXCEPT(cellDim != 0);
00260 if (cofacetIndex==0) return (cellLID-1) % numElems_;
00261 return cellLID;
00262 }
00263
00264 void PeriodicMesh1D::getMaxCofacetLIDs(const Array<int>& cellLIDs,
00265 MaximalCofacetBatch& cofacets) const
00266 {
00267 TEUCHOS_TEST_FOR_EXCEPT(true);
00268 }
00269
00270 void PeriodicMesh1D::getCofacets(int cellDim, int cellLID,
00271 int cofacetDim, Array<int>& cofacetLIDs) const
00272 {
00273 TEUCHOS_TEST_FOR_EXCEPT(cellDim != 0);
00274 TEUCHOS_TEST_FOR_EXCEPT(cofacetDim != 1);
00275
00276 cofacetLIDs.resize(2);
00277 cofacetLIDs[0] = (cellLID-1) % numElems_;
00278 cofacetLIDs[1] = cellLID;
00279 }
00280
00281 int PeriodicMesh1D::mapGIDToLID(int cellDim, int globalIndex) const
00282 {
00283 return globalIndex;
00284 }
00285
00286 bool PeriodicMesh1D::hasGID(int cellDim, int globalIndex) const
00287 {
00288 return true;
00289 }
00290
00291 int PeriodicMesh1D::mapLIDToGID(int cellDim, int localIndex) const
00292 {
00293 return localIndex;
00294 }
00295
00296 CellType PeriodicMesh1D::cellType(int cellDim) const
00297 {
00298 if (cellDim==0) return PointCell;
00299 else if (cellDim==1) return LineCell;
00300 else return NullCell;
00301 }
00302
00303 int PeriodicMesh1D::label(int cellDim, int cellLID) const
00304 {
00305 return labels_[cellDim][cellLID];
00306 }
00307
00308 void PeriodicMesh1D::getLabels(int cellDim, const Array<int>& cellLID,
00309 Array<int>& labels) const
00310 {
00311 labels.resize(cellLID.size());
00312 const Array<int>& ld = labels_[cellDim];
00313 for (int i=0; i<cellLID.size(); i++)
00314 {
00315 labels[i] = ld[cellLID[i]];
00316 }
00317 }
00318
00319 Set<int> PeriodicMesh1D::getAllLabelsForDimension(int cellDim) const
00320 {
00321 Set<int> rtn;
00322
00323 const Array<int>& ld = labels_[cellDim];
00324 for (int i=0; i<ld.size(); i++)
00325 {
00326 rtn.put(ld[i]);
00327 }
00328
00329 return rtn;
00330 }
00331
00332 void PeriodicMesh1D::setLabel(int cellDim, int cellLID, int label)
00333 {
00334 labels_[cellDim][cellLID] = label;
00335 }
00336
00337
00338 void PeriodicMesh1D::getLIDsForLabel(int cellDim, int label, Array<int>& cellLIDs) const
00339 {
00340 cellLIDs.resize(0);
00341 const Array<int>& ld = labels_[cellDim];
00342 for (int i=0; i<ld.size(); i++)
00343 {
00344 if (ld[i] == label) cellLIDs.append(i);
00345 }
00346 }