1 // @HEADER 2 // ************************************************************************ 3 // 4 // Rapid Optimization Library (ROL) Package 5 // Copyright (2014) Sandia Corporation 6 // 7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 8 // license for use of this work by or on behalf of the U.S. Government. 9 // 10 // Redistribution and use in source and binary forms, with or without 11 // modification, are permitted provided that the following conditions are 12 // met: 13 // 14 // 1. Redistributions of source code must retain the above copyright 15 // notice, this list of conditions and the following disclaimer. 16 // 17 // 2. Redistributions in binary form must reproduce the above copyright 18 // notice, this list of conditions and the following disclaimer in the 19 // documentation and/or other materials provided with the distribution. 20 // 21 // 3. Neither the name of the Corporation nor the names of the 22 // contributors may be used to endorse or promote products derived from 23 // this software without specific prior written permission. 24 // 25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 // 37 // Questions? Contact lead developers: 38 // Drew Kouri (dpkouri@sandia.gov) and 39 // Denis Ridzal (dridzal@sandia.gov) 40 // 41 // ************************************************************************ 42 // @HEADER 43 44 /*! \file dofmanager.hpp 45 \brief Given a mesh with connectivity information, sets up data 46 structures for the indexing of the global degrees of 47 freedom (Dofs). 48 */ 49 50 #ifndef DOFMANAGER_HPP 51 #define DOFMANAGER_HPP 52 53 #include "Teuchos_ParameterList.hpp" 54 #include "Intrepid_FieldContainer.hpp" 55 #include "Intrepid_Basis.hpp" 56 #include "meshmanager.hpp" 57 58 template <class Real> 59 class DofManager { 60 61 private: 62 ROL::Ptr<MeshManager<Real> > meshManager_; 63 std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real> > > > intrepidBasis_; 64 65 int cellDim_; // cell dimension 66 67 int numCells_; // number of mesh cells 68 int numNodes_; // number of mesh nodes 69 int numEdges_; // number of mesh edges 70 int numFaces_; // number of mesh faces 71 72 ROL::Ptr<Intrepid::FieldContainer<int> > meshCellToNodeMap_; 73 ROL::Ptr<Intrepid::FieldContainer<int> > meshCellToEdgeMap_; 74 ROL::Ptr<Intrepid::FieldContainer<int> > meshCellToFaceMap_; 75 76 // Local dof information. 77 int numBases_; // number of bases (fields) 78 int numLocalNodes_; // number of nodes in the basic cell topology 79 int numLocalEdges_; // number of edges in the basic cell topology 80 int numLocalFaces_; // number of faces in the basic cell topology 81 int numLocalVoids_; // number of voids in the basic cell topology, =1 82 int numLocalNodeDofs_; // number of local (single-cell) node dofs for all bases 83 int numLocalEdgeDofs_; // number of local (single-cell) edge dofs for all bases 84 int numLocalFaceDofs_; // number of local (single-cell) face dofs for all bases 85 int numLocalVoidDofs_; // number of local (single-cell) face dofs for all bases 86 int numLocalDofs_; // total number of local (single-cell) face dofs for all bases 87 std::vector<int> numDofsPerNode_; // number of dofs per node in a cell (assumed constant), per basis 88 std::vector<int> numDofsPerEdge_; // number of dofs per edge in a cell (assumed constant), per basis 89 std::vector<int> numDofsPerFace_; // number of dofs per face in a cell (assumed constant), per basis 90 std::vector<int> numDofsPerVoid_; // number of dofs per void in a cell (assumed constant), per basis 91 std::vector<std::vector<int> > fieldPattern_; // local indexing of fields into the array [0,1,...,numLocalDofs-1]; 92 // contains [number of bases] index vectors, where each index vector 93 // is of size [basis cardinality] 94 // Global dof information. 95 int numNodeDofs_; // number of global node dofs 96 int numEdgeDofs_; // number of global edge dofs 97 int numFaceDofs_; // number of global face dofs 98 int numVoidDofs_; // number of global void dofs 99 int numDofs_; // total number of global dofs 100 101 ROL::Ptr<Intrepid::FieldContainer<int> > nodeDofs_; // global node dofs, of size [numNodes_ x numLocalNodeDofs_] 102 ROL::Ptr<Intrepid::FieldContainer<int> > edgeDofs_; // global edge dofs, of size [numEdges_ x numLocalEdgeDofs_] 103 ROL::Ptr<Intrepid::FieldContainer<int> > faceDofs_; // global face dofs, of size [numFaces_ x numLocalFaceDofs_] 104 ROL::Ptr<Intrepid::FieldContainer<int> > voidDofs_; // global face dofs, of size [numFaces_ x numLocalFaceDofs_] 105 ROL::Ptr<Intrepid::FieldContainer<int> > cellDofs_; // global cell dofs, of size [numCells_ x numLocalDofs_]; 106 // ordered by subcell (node, then edge, then face) and basis index 107 std::vector<int> mapToIntrepidPattern_; 108 std::vector<int> mapToFieldPattern_; 109 110 std::vector<ROL::Ptr<Intrepid::FieldContainer<int> > > fieldDofs_; // global cell dofs, indexed by field/basis, of size [numCells_ x basis cardinality]; 111 // ordered by subcell (node, then edge, then face) 112 113 public: 114 DofManager(ROL::Ptr<MeshManager<Real>> & meshManager,std::vector<ROL::Ptr<Intrepid::Basis<Real,Intrepid::FieldContainer<Real>>>> & intrepidBasis)115 DofManager(ROL::Ptr<MeshManager<Real> > &meshManager, 116 std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real> > > > &intrepidBasis) { 117 118 meshManager_ = meshManager; 119 intrepidBasis_ = intrepidBasis; 120 cellDim_ = intrepidBasis_[0]->getBaseCellTopology().getDimension(); 121 numCells_ = meshManager_->getNumCells(); 122 numNodes_ = meshManager_->getNumNodes(); 123 numEdges_ = meshManager_->getNumEdges(); 124 numFaces_ = meshManager_->getNumFaces(); 125 126 // Mesh data structures. 127 meshCellToNodeMap_ = meshManager_->getCellToNodeMap(); 128 meshCellToEdgeMap_ = meshManager_->getCellToEdgeMap(); 129 meshCellToFaceMap_ = meshManager_->getCellToFaceMap(); 130 131 // Local degree-of-freedom footprint. 132 numBases_ = static_cast<int>(intrepidBasis_.size()); 133 numDofsPerNode_.resize(numBases_, 0); 134 numDofsPerEdge_.resize(numBases_, 0); 135 numDofsPerFace_.resize(numBases_, 0); 136 numDofsPerVoid_.resize(numBases_, 0); 137 numLocalDofs_ = 0; 138 for (int i=0; i<numBases_; ++i) { 139 std::vector<std::vector<int> > dofTags = (intrepidBasis_[i])->getAllDofTags(); 140 for (int j=0; j<(intrepidBasis_[i])->getCardinality(); ++j) { 141 if (dofTags[j][0] == 0) { 142 numDofsPerNode_[i] = dofTags[j][3]; 143 } 144 else if (dofTags[j][0] == 1) { 145 if (cellDim_ == 1) { // 1D 146 numDofsPerVoid_[i] = dofTags[j][3]; 147 } 148 else { // 2D, 3D 149 numDofsPerEdge_[i] = dofTags[j][3]; 150 } 151 } 152 else if (dofTags[j][0] == 2) { 153 if (cellDim_ == 2) { // 2D 154 numDofsPerVoid_[i] = dofTags[j][3]; 155 } 156 else { // 3D 157 numDofsPerFace_[i] = dofTags[j][3]; 158 } 159 } 160 else if (dofTags[j][0] == 3) { 161 numDofsPerVoid_[i] = dofTags[j][3]; 162 } 163 } 164 numLocalDofs_ += (intrepidBasis_[i])->getCardinality(); 165 } 166 numLocalNodeDofs_ = 0; 167 numLocalEdgeDofs_ = 0; 168 numLocalFaceDofs_ = 0; 169 numLocalVoidDofs_ = 0; 170 for (int i=0; i<numBases_; ++i) { 171 numLocalNodeDofs_ += numDofsPerNode_[i]; 172 numLocalEdgeDofs_ += numDofsPerEdge_[i]; 173 numLocalFaceDofs_ += numDofsPerFace_[i]; 174 numLocalVoidDofs_ += numDofsPerVoid_[i]; 175 } 176 numLocalNodes_ = static_cast<int>( (intrepidBasis_[0])->getBaseCellTopology().getVertexCount() ); 177 numLocalEdges_ = static_cast<int>( (intrepidBasis_[0])->getBaseCellTopology().getEdgeCount() ); 178 numLocalFaces_ = static_cast<int>( (intrepidBasis_[0])->getBaseCellTopology().getFaceCount() ); 179 numLocalVoids_ = 1; 180 computeFieldPattern(); 181 182 // Global data structures. 183 computeDofArrays(); 184 computeCellDofs(); 185 computeFieldDofs(); 186 computeDofTransforms(); 187 } 188 189 getNodeDofs() const190 ROL::Ptr<Intrepid::FieldContainer<int> > getNodeDofs() const { 191 return nodeDofs_; 192 } 193 194 getEdgeDofs() const195 ROL::Ptr<Intrepid::FieldContainer<int> > getEdgeDofs() const { 196 return edgeDofs_; 197 } 198 199 getFaceDofs() const200 ROL::Ptr<Intrepid::FieldContainer<int> > getFaceDofs() const { 201 return faceDofs_; 202 } 203 204 getVoidDofs() const205 ROL::Ptr<Intrepid::FieldContainer<int> > getVoidDofs() const { 206 return voidDofs_; 207 } 208 209 getCellDofs() const210 ROL::Ptr<Intrepid::FieldContainer<int> > getCellDofs() const { 211 return cellDofs_; 212 } 213 214 getFieldDofs() const215 std::vector<ROL::Ptr<Intrepid::FieldContainer<int> > > getFieldDofs() const { 216 return fieldDofs_; 217 } 218 219 getFieldDofs(const int & fieldNumber) const220 ROL::Ptr<Intrepid::FieldContainer<int> > getFieldDofs(const int & fieldNumber) const { 221 return fieldDofs_[fieldNumber]; 222 } 223 224 getNumNodeDofs() const225 int getNumNodeDofs() const { 226 return numNodeDofs_; 227 } 228 229 getNumEdgeDofs() const230 int getNumEdgeDofs() const { 231 return numEdgeDofs_; 232 } 233 234 getNumFaceDofs() const235 int getNumFaceDofs() const { 236 return numFaceDofs_; 237 } 238 239 getNumVoidDofs() const240 int getNumVoidDofs() const { 241 return numVoidDofs_; 242 } 243 244 getNumDofs() const245 int getNumDofs() const { 246 return numDofs_; 247 } 248 249 getNumFields() const250 int getNumFields() const { 251 return numBases_; 252 } 253 254 getLocalFieldSize() const255 int getLocalFieldSize() const { 256 return numLocalDofs_; 257 } 258 259 getLocalFieldSize(const int & fieldNumber) const260 int getLocalFieldSize(const int & fieldNumber) const { 261 return (intrepidBasis_[fieldNumber])->getCardinality(); 262 } 263 264 getFieldPattern() const265 std::vector<std::vector<int> > getFieldPattern() const { 266 return fieldPattern_; 267 } 268 269 getFieldPattern(const int & fieldNumber) const270 std::vector<int> getFieldPattern(const int & fieldNumber) const { 271 return fieldPattern_[fieldNumber]; 272 } 273 transformToIntrepidPattern(const ROL::Ptr<Intrepid::FieldContainer<Real>> & array) const274 void transformToIntrepidPattern(const ROL::Ptr<Intrepid::FieldContainer<Real> > &array) const { 275 if ( array != ROL::nullPtr ) { 276 int rank = array->rank(); 277 int nc = array->dimension(0); 278 if ( rank == 2 ) { 279 int nf = array->dimension(1); 280 Intrepid::FieldContainer<Real> tmp(nc, nf); 281 for (int c = 0; c < nc; ++c) { 282 for (int f = 0; f < nf; ++f) { 283 tmp(c, mapToIntrepidPattern_[f]) = (*array)(c, f); 284 } 285 } 286 *array = tmp; 287 } 288 else if (rank == 3 ) { 289 int nf1 = array->dimension(1); 290 int nf2 = array->dimension(2); 291 Intrepid::FieldContainer<Real> tmp(nc, nf1, nf2); 292 for (int c = 0; c < nc; ++c) { 293 for (int f1 = 0; f1 < nf1; ++f1) { 294 for (int f2 = 0; f2 < nf2; ++f2) { 295 tmp(c, mapToIntrepidPattern_[f1], mapToIntrepidPattern_[f2]) = (*array)(c, f1, f2); 296 } 297 } 298 } 299 *array = tmp; 300 } 301 else { 302 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 303 ">>> PDE-OPT/TOOLS/dofmanager.hpp (transformToIntrepidPattern): Input array rank not 2 or 3!"); 304 } 305 } 306 } 307 mapToFieldPattern(int f) const308 int mapToFieldPattern(int f) const { 309 return mapToFieldPattern_[f]; 310 } 311 transformToFieldPattern(const ROL::Ptr<Intrepid::FieldContainer<Real>> & array) const312 void transformToFieldPattern(const ROL::Ptr<Intrepid::FieldContainer<Real> > &array) const { 313 if ( array != ROL::nullPtr ) { 314 int rank = array->rank(); 315 int nc = array->dimension(0); 316 if ( rank == 2 ) { 317 int nf = array->dimension(1); 318 Intrepid::FieldContainer<Real> tmp(nc, nf); 319 for (int c = 0; c < nc; ++c) { 320 for (int f = 0; f < nf; ++f) { 321 tmp(c, mapToFieldPattern_[f]) = (*array)(c, f); 322 } 323 } 324 *array = tmp; 325 } 326 else if (rank == 3 ) { 327 int nf1 = array->dimension(1); 328 int nf2 = array->dimension(2); 329 Intrepid::FieldContainer<Real> tmp(nc, nf1, nf2); 330 for (int c = 0; c < nc; ++c) { 331 for (int f1 = 0; f1 < nf1; ++f1) { 332 for (int f2 = 0; f2 < nf2; ++f2) { 333 tmp(c, mapToFieldPattern_[f1], mapToFieldPattern_[f2]) = (*array)(c, f1, f2); 334 } 335 } 336 } 337 *array = tmp; 338 } 339 else { 340 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 341 ">>> PDE-OPT/TOOLS/dofmanager.hpp (transformToFieldPattern): Input array rank not 2 or 3!"); 342 } 343 } 344 } 345 346 private: 347 computeDofArrays()348 void computeDofArrays() { 349 350 nodeDofs_ = ROL::makePtr<Intrepid::FieldContainer<int>>(numNodes_, numLocalNodeDofs_); 351 edgeDofs_ = ROL::makePtr<Intrepid::FieldContainer<int>>(numEdges_, numLocalEdgeDofs_); 352 faceDofs_ = ROL::makePtr<Intrepid::FieldContainer<int>>(numFaces_, numLocalFaceDofs_); 353 voidDofs_ = ROL::makePtr<Intrepid::FieldContainer<int>>(numCells_, numLocalVoidDofs_); 354 355 Intrepid::FieldContainer<int> &nodeDofs = *nodeDofs_; 356 Intrepid::FieldContainer<int> &edgeDofs = *edgeDofs_; 357 Intrepid::FieldContainer<int> &faceDofs = *faceDofs_; 358 Intrepid::FieldContainer<int> &voidDofs = *voidDofs_; 359 360 int dofCt = -1; 361 362 // 363 // This is the independent node id --> edge id --> cell id ordering. 364 // For example, for a Q2-Q2-Q1 basis (Taylor-Hood), we would have: 365 // 366 // Q2 Q2 Q1 367 // -------------- 368 // n1 1 1 1 369 // n2 1 1 1 370 // ... 371 // e1 1 1 0 372 // e2 1 1 0 373 // ... 374 // c1 1 1 0 375 // c2 1 1 0 376 // ... 377 // 378 379 // count node dofs 380 for (int i=0; i<numNodes_; ++i) { 381 int locNodeCt = -1; 382 for (int j=0; j<numBases_; ++j) { 383 for (int k=0; k<numDofsPerNode_[j]; ++k) { 384 nodeDofs(i, ++locNodeCt) = ++dofCt; 385 } 386 } 387 } 388 numNodeDofs_ = dofCt+1; 389 390 // count edge dofs 391 for (int i=0; i<numEdges_; ++i) { 392 int locEdgeCt = -1; 393 for (int j=0; j<numBases_; ++j) { 394 for (int k=0; k<numDofsPerEdge_[j]; ++k) { 395 edgeDofs(i, ++locEdgeCt) = ++dofCt; 396 } 397 } 398 } 399 numEdgeDofs_ = dofCt+1-numNodeDofs_; 400 401 // count face dofs 402 for (int i=0; i<numFaces_; ++i) { 403 int locFaceCt = -1; 404 for (int j=0; j<numBases_; ++j) { 405 for (int k=0; k<numDofsPerFace_[j]; ++k) { 406 faceDofs(i, ++locFaceCt) = ++dofCt; 407 } 408 } 409 } 410 numFaceDofs_ = dofCt+1-numNodeDofs_-numEdgeDofs_; 411 412 // count void dofs 413 for (int i=0; i<numCells_; ++i) { 414 int locVoidCt = -1; 415 for (int j=0; j<numBases_; ++j) { 416 for (int k=0; k<numDofsPerVoid_[j]; ++k) { 417 voidDofs(i, ++locVoidCt) = ++dofCt; 418 } 419 } 420 } 421 numVoidDofs_ = dofCt+1-numNodeDofs_-numEdgeDofs_-numFaceDofs_; 422 423 numDofs_ = numNodeDofs_+numEdgeDofs_+numFaceDofs_+numVoidDofs_; 424 425 } // computeDofArrays 426 427 computeCellDofs()428 void computeCellDofs() { 429 430 cellDofs_ = ROL::makePtr<Intrepid::FieldContainer<int>>(numCells_, numLocalDofs_); 431 432 // Grab object references, for easier indexing. 433 Intrepid::FieldContainer<int> &cdofs = *cellDofs_; 434 Intrepid::FieldContainer<int> &nodeDofs = *nodeDofs_; 435 Intrepid::FieldContainer<int> &edgeDofs = *edgeDofs_; 436 Intrepid::FieldContainer<int> &faceDofs = *faceDofs_; 437 Intrepid::FieldContainer<int> &voidDofs = *voidDofs_; 438 Intrepid::FieldContainer<int> &ctn = *meshCellToNodeMap_; 439 Intrepid::FieldContainer<int> &cte = *meshCellToEdgeMap_; 440 Intrepid::FieldContainer<int> &ctf = *meshCellToFaceMap_; 441 442 for (int i=0; i<numCells_; ++i) { 443 int ct = -1; 444 for (int j=0; j<numLocalNodes_; ++j) { 445 for (int k=0; k<numLocalNodeDofs_; ++k) { 446 cdofs(i,++ct) = nodeDofs(ctn(i,j), k); 447 } 448 } 449 for (int j=0; j<numLocalEdges_; ++j) { 450 for (int k=0; k<numLocalEdgeDofs_; ++k) { 451 cdofs(i,++ct) = edgeDofs(cte(i,j), k); 452 } 453 } 454 for (int j=0; j<numLocalFaces_; ++j) { 455 for (int k=0; k<numLocalFaceDofs_; ++k) { 456 cdofs(i,++ct) = faceDofs(ctf(i,j), k); 457 } 458 } 459 for (int j=0; j<numLocalVoids_; ++j) { 460 for (int k=0; k<numLocalVoidDofs_; ++k) { 461 cdofs(i,++ct) = voidDofs(i, k); 462 } 463 } 464 } 465 } // computeCellDofs 466 467 computeFieldPattern()468 void computeFieldPattern() { 469 470 fieldPattern_.resize(numBases_); 471 472 int dofCt = -1; 473 474 // count node dofs 475 for (int i=0; i<numLocalNodes_; ++i) { 476 for (int j=0; j<numBases_; ++j) { 477 for (int k=0; k<numDofsPerNode_[j]; ++k) { 478 fieldPattern_[j].push_back(++dofCt); 479 } 480 } 481 } 482 483 // count edge dofs 484 for (int i=0; i<numLocalEdges_; ++i) { 485 for (int j=0; j<numBases_; ++j) { 486 for (int k=0; k<numDofsPerEdge_[j]; ++k) { 487 fieldPattern_[j].push_back(++dofCt); 488 } 489 } 490 } 491 492 // count face dofs 493 for (int i=0; i<numLocalFaces_; ++i) { 494 for (int j=0; j<numBases_; ++j) { 495 for (int k=0; k<numDofsPerFace_[j]; ++k) { 496 fieldPattern_[j].push_back(++dofCt); 497 } 498 } 499 } 500 501 // count void dofs 502 for (int i=0; i<numLocalVoids_; ++i) { 503 for (int j=0; j<numBases_; ++j) { 504 for (int k=0; k<numDofsPerVoid_[j]; ++k) { 505 fieldPattern_[j].push_back(++dofCt); 506 } 507 } 508 } 509 510 } // computeFieldPattern 511 512 computeFieldDofs()513 void computeFieldDofs() { 514 515 fieldDofs_.resize(numBases_); 516 517 Intrepid::FieldContainer<int> &cdofs = *cellDofs_; 518 519 for (int fieldNum=0; fieldNum<numBases_; ++fieldNum) { 520 int basisCard = intrepidBasis_[fieldNum]->getCardinality(); 521 fieldDofs_[fieldNum] = ROL::makePtr<Intrepid::FieldContainer<int>>(numCells_, basisCard); 522 Intrepid::FieldContainer<int> &fdofs = *(fieldDofs_[fieldNum]); 523 for (int i=0; i<numCells_; ++i) { 524 for (int j=0; j<basisCard; ++j) { 525 fdofs(i,j) = cdofs(i, fieldPattern_[fieldNum][j]); 526 } 527 } 528 } 529 } // computeFieldDofs 530 computeDofTransforms(void)531 void computeDofTransforms(void) { 532 // Build basis maps 533 std::vector<std::vector<int> > map2IP(numBases_); 534 std::vector<std::vector<int> > map2FP(numBases_); 535 shards::CellTopology cellType = intrepidBasis_[0]->getBaseCellTopology(); 536 int nv = cellType.getVertexCount(); 537 for (int f=0; f<numBases_; ++f) { 538 int basisDeg = intrepidBasis_[f]->getDegree(); 539 if (cellDim_ == 1) { 540 if (basisDeg == 0) { 541 map2IP[f] = {0}; 542 map2FP[f] = {0}; 543 } 544 else if (basisDeg == 1) { 545 map2IP[f] = {0, 1}; 546 map2FP[f] = {0, 1}; 547 } 548 else if (basisDeg == 2) { 549 map2IP[f] = {0, 2, 1}; 550 map2FP[f] = {0, 2, 1}; 551 } 552 else { 553 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 554 ">>> PDE-OPT/TOOLS/dofmanager.hpp (ComputeDofTransforms): basisDeg > 2"); 555 } 556 } 557 else if (cellDim_ == 2) { 558 if (basisDeg == 0) { 559 map2IP[f] = {0}; 560 map2FP[f] = {0}; 561 } 562 else if (basisDeg == 1) { 563 map2IP[f].resize(nv); 564 map2FP[f].resize(nv); 565 for (int i = 0; i < nv; ++i) { 566 map2IP[f][i] = i; 567 map2FP[f][i] = i; 568 } 569 //map2IP[f] = {0, 1, 2, 3}; 570 //map2FP[f] = {0, 1, 2, 3}; 571 } 572 else if (basisDeg == 2) { 573 int lim = (nv==3 ? 6 : 9); 574 map2IP[f].resize(lim); 575 map2FP[f].resize(lim); 576 for (int i = 0; i < lim; ++i) { 577 map2IP[f][i] = i; 578 map2FP[f][i] = i; 579 } 580 //map2IP[f] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; 581 //map2FP[f] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; 582 } 583 else { 584 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 585 ">>> PDE-OPT/TOOLS/dofmanager.hpp (ComputeDofTransforms): basisDeg > 2"); 586 } 587 } 588 else if (cellDim_ == 3) { 589 if (basisDeg == 0) { 590 map2IP[f] = {0}; 591 map2FP[f] = {0}; 592 } 593 else if (basisDeg == 1) { 594 map2IP[f] = {0, 1, 2, 3, 4, 5, 6, 7}; 595 map2FP[f] = {0, 1, 2, 3, 4, 5, 6, 7}; 596 } 597 else if (basisDeg == 2) { 598 map2IP[f] = {0, 1, 2, 3, 4 ,5, 6, 7, // Nodes 599 8, 9, 10, 11, 16, 17, 18, 19, 12, 13, 14, 15, // Edges 600 25, 24, 26, 23, 21, 22, // Faces 601 20}; // Voids 602 map2FP[f] = {0, 1, 2, 3, 4 ,5, 6, 7, // Nodes 603 8, 9, 10, 11, 16, 17, 18, 19, 12, 13, 14, 15, // Edges 604 26, // Voids 605 24, 25, 23, 21, 20, 22}; // Faces 606 } 607 else { 608 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, 609 ">>> PDE-OPT/TOOLS/dofmanager.hpp (ComputeDofTransforms): basisDeg > 2"); 610 } 611 } 612 } 613 // Apply transformation to ind 614 mapToIntrepidPattern_.clear(); mapToIntrepidPattern_.resize(numDofs_); 615 mapToFieldPattern_.clear(); mapToFieldPattern_.resize(numDofs_); 616 for (int i = 0; i < numBases_; ++i) { 617 for (int j = 0; j < static_cast<int>(map2IP[i].size()); ++j) { 618 mapToIntrepidPattern_[fieldPattern_[i][j]] = fieldPattern_[i][map2IP[i][j]]; 619 mapToFieldPattern_[fieldPattern_[i][j]] = fieldPattern_[i][map2FP[i][j]]; 620 } 621 } 622 } 623 624 }; // DofManager 625 626 #endif 627