• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Albany_TmplSTKMeshStruct_Def.hpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 #include <iostream>
00008 #include "Albany_TmplSTKMeshStruct.hpp"
00009 #include <Shards_BasicTopologies.hpp>
00010 #include <stk_mesh/base/Entity.hpp>
00011 #include <stk_mesh/base/GetEntities.hpp>
00012 #include <stk_mesh/base/GetBuckets.hpp>
00013 #include <stk_mesh/base/FieldData.hpp>
00014 #include <stk_mesh/base/Selector.hpp>
00015 
00016 #include <stk_mesh/fem/FEMHelpers.hpp>
00017 #include "Albany_Utils.hpp"
00018 
00019 #ifdef ALBANY_SEACAS
00020 #include <stk_io/IossBridge.hpp>
00021 #endif
00022 
00023 template<unsigned Dim, class traits>
00024 Albany::TmplSTKMeshStruct<Dim, traits>::TmplSTKMeshStruct(
00025                   const Teuchos::RCP<Teuchos::ParameterList>& params,
00026                   const Teuchos::RCP<Teuchos::ParameterList>& adaptParams_,
00027                   const Teuchos::RCP<const Epetra_Comm>& comm) :
00028   GenericSTKMeshStruct(params, adaptParams_, traits_type::size),
00029   periodic_x(params->get("Periodic_x BC", false)),
00030   periodic_y(params->get("Periodic_y BC", false)),
00031   periodic_z(params->get("Periodic_z BC", false)),
00032   triangles(false)
00033 {
00034 
00035 /*
00036   There are two use cases of interest here.
00037 
00038   1. Do not specify element block information ("Element Blocks"). In this case, numEB = 1 and
00039       the scale (domain dimensions) and discretization is set globally across the mesh.
00040 
00041   2. "Element Blocks" is specified in the input file. In this case, the logical size of the element blocks
00042       must be specified, as well as the number of elements in each block and their size (block length).
00043 
00044 */
00045 
00046   int total_elems;
00047 
00048   int input_nEB = params->get<int>("Element Blocks", -1); // Read the number of element blocks. -1 if not listed
00049 
00050   if(input_nEB <= 0 || Dim == 0) // If "Element Blocks" are not present in input file
00051 
00052     numEB = 1;
00053 
00054   else 
00055 
00056     numEB = input_nEB;
00057 
00058   params->validateParameters(*this->getValidDiscretizationParameters(), 0,
00059     Teuchos::VALIDATE_USED_ENABLED, Teuchos::VALIDATE_DEFAULTS_DISABLED);
00060 
00061   nelem[0] = 1; // One element in the case of a single point 0D mesh (the below isn't executed)
00062   scale[0] = 1.0; // one unit length in the x dimension
00063 
00064   // The number of element blocks. Always at least one.
00065 
00066   EBSpecs.resize(numEB);
00067 
00068 #pragma clang diagnostic push
00069 #pragma clang diagnostic ignored "-Wtautological-compare"
00070 
00071   for(unsigned i = 0; i < Dim; i++){ // Get the number of elements in each dimension from params
00072                                 // Note that nelem will default to 0 and scale to 1 if element
00073                                 // blocks are specified
00074 
00075 #pragma clang diagnostic pop
00076 
00077     // Read the values for "1D Elements", "2D Elements", "3D Elements"
00078      std::stringstream buf;
00079      buf << i + 1 << "D Elements";
00080      nelem[i] = params->get<int>(buf.str(), 0);
00081 
00082     // Read the values for "1D Scale", "2D Scale", "3D Scale"
00083      std::stringstream buf2;
00084      buf2 << i + 1 << "D Scale";
00085 
00086      scale[i] = params->get<double>(buf2.str(),     1.0); 
00087   }
00088 
00089   if(input_nEB <= 0 || Dim == 0){ // If "Element Blocks" are not present in input file
00090 
00091     EBSpecs[0].Initialize(nelem, scale);
00092 
00093     // Format and print out information about the mesh that is being generated
00094 
00095     if (comm->MyPID()==0 && Dim > 0){ // Not reached for 0D problems
00096 
00097      std::cout <<"TmplSTKMeshStruct:: Creating " << Dim << "D mesh of size ";
00098 
00099      std::stringstream nelem_txt, scale_txt;
00100 
00101 #pragma clang diagnostic push
00102 #pragma clang diagnostic ignored "-Wtautological-compare"
00103 
00104      for(unsigned idx=0; idx < Dim - 1; idx++){
00105 
00106 #pragma clang diagnostic pop
00107 
00108        nelem_txt << nelem[idx] << "x";
00109        scale_txt << scale[idx] << "x";
00110 
00111      }
00112 
00113      nelem_txt << nelem[Dim - 1];
00114      scale_txt << scale[Dim - 1];
00115 
00116      std::cout << nelem_txt.str() << " elements and scaled to " <<
00117                  scale_txt.str() << std::endl;
00118 
00119      if (triangles)
00120        std::cout<<" Quad elements cut to make twice as many triangles " <<std::endl;
00121 
00122    }
00123 
00124    // Calculate total number of elements
00125    total_elems = nelem[0];
00126 
00127 #pragma clang diagnostic push
00128 #pragma clang diagnostic ignored "-Wtautological-compare"
00129 
00130    for(unsigned i = 1; i < Dim; i++)
00131       total_elems *= nelem[i];
00132 
00133 #pragma clang diagnostic pop
00134 
00135   }
00136   else { // Element blocks are present in input
00137 
00138     std::vector<int> min(Dim), max(Dim);
00139 
00140 #pragma clang diagnostic push
00141 #pragma clang diagnostic ignored "-Wtautological-compare"
00142 
00143     for(unsigned i = 0; i < Dim; i++){
00144 
00145 #pragma clang diagnostic pop
00146 
00147       min[i] = INT_MAX;
00148       max[i] = INT_MIN;
00149 
00150       nelem[i] = 0;
00151 
00152     }
00153 
00154     // Read the EB extents from the parameter list and initialize the EB structs
00155     for(unsigned int eb = 0; eb < numEB; eb++){
00156 
00157       EBSpecs[eb].Initialize(eb, params);
00158 
00159 //      for(int i = 0; i < Dim; i++)
00160 
00161 //        nelem[i] += EBSpecs[eb].numElems(i);
00162 
00163 #pragma clang diagnostic push
00164 #pragma clang diagnostic ignored "-Wtautological-compare"
00165 
00166       for(unsigned i = 0; i < Dim; i++){
00167 
00168 #pragma clang diagnostic pop
00169 
00170 
00171         min[i] = (min[i] < EBSpecs[eb].min[i]) ? min[i] : EBSpecs[eb].min[i];
00172         max[i] = (max[i] > EBSpecs[eb].max[i]) ? max[i] : EBSpecs[eb].max[i];
00173 
00174       }
00175 
00176     }
00177 
00178 #pragma clang diagnostic push
00179 #pragma clang diagnostic ignored "-Wtautological-compare"
00180 
00181     for(unsigned i = 0; i < Dim; i++)
00182 
00183 #pragma clang diagnostic pop
00184 
00185       nelem[i] = max[i] - min[i];
00186 
00187     // Calculate total number of elements
00188     total_elems = nelem[0];
00189 
00190 #pragma clang diagnostic push
00191 #pragma clang diagnostic ignored "-Wtautological-compare"
00192 
00193     for(unsigned i = 1; i < Dim; i++)
00194 
00195 #pragma clang diagnostic pop
00196 
00197       total_elems *= nelem[i];
00198 
00199   }
00200 
00201   std::vector<std::string> nsNames;
00202 
00203   // Construct the nodeset names
00204 
00205 #pragma clang diagnostic push
00206 #pragma clang diagnostic ignored "-Wtautological-compare"
00207 
00208   for(unsigned idx=0; idx < Dim*2; idx++){ // 2 nodesets per dimension (one at beginning, one at end)
00209     std::stringstream buf;
00210     buf << "NodeSet" << idx;
00211     nsNames.push_back(buf.str());
00212   }
00213   // For 2D and 3D, and extra node set of a single node for setting Pressure in confined incompressible flows
00214   if (Dim==2 || Dim==3) nsNames.push_back("NodeSet99");
00215 
00216   std::vector<std::string> ssNames;
00217 
00218   // Construct the sideset names
00219 
00220   if(Dim > 1 ) // Sidesets present only for 2 and 3D problems
00221 
00222     for(unsigned idx=0; idx < Dim*2; idx++){ // 2 sidesets per dimension (one at beginning, one at end)
00223       std::stringstream buf;
00224       buf << "SideSet" << idx;
00225       ssNames.push_back(buf.str());
00226     }
00227 
00228   DeclareParts(EBSpecs, ssNames, nsNames);
00229 
00230   // Different element topologies. Note that there is only a choice for triangles/quads in 2D
00231   // (all other dimensions select the default element type for now)
00232 
00233   std::string cellTopo = params->get("Cell Topology", "Quad");
00234   if (cellTopo == "Tri" || cellTopo == "Triangle")  
00235     triangles = true;
00236   // else TEST_FOR_EXCEPTION (cellTopo != "Quad", std::logic_error,
00237   //    "\nUnknown Cell Topology entry in STK2D(not \'Tri\' or \'Quad\'): "
00238   //     << cellTopo);
00239 
00240   // Set the element types in the EBs
00241 
00242   //get the type of transformation of STK mesh (for FELIX problems)
00243   transformType = params->get("Transform Type", "None"); //get the type of transformation of STK mesh (for FELIX problems)
00244   felixAlpha = params->get("FELIX alpha", 0.0); 
00245   felixL = params->get("FELIX L", 1.0); 
00246   
00247   //boolean specifying if ascii mesh has contiguous IDs; only used for ascii meshes on 1 processor
00248   contigIDs = params->get("Contiguous IDs", true);
00249 
00250   //Does user want to write coordinates to matrix market file (e.g., for ML analysis)? 
00251   writeCoordsToMMFile = params->get("Write Coordinates to MatrixMarket", false); 
00252 
00253   for(unsigned int i = 0; i < numEB; i++){
00254 
00255     if (triangles)
00256       stk::mesh::fem::set_cell_topology<optional_element_type>(*partVec[i]);
00257     else 
00258       stk::mesh::fem::set_cell_topology<default_element_type>(*partVec[i]);
00259   }
00260 
00261   for(std::map<std::string, stk::mesh::Part*>::const_iterator it = ssPartVec.begin(); 
00262     it != ssPartVec.end(); ++it)
00263 
00264     stk::mesh::fem::set_cell_topology<default_element_side_type>(*it->second);
00265 
00266   int cub = params->get("Cubature Degree",3);
00267   int worksetSizeMax = params->get("Workset Size",50);
00268 
00269   // Create just enough of the mesh to figure out number of owned elements 
00270   // so that the problem setup can know the worksetSize
00271 
00272   elem_map = Teuchos::rcp(new Epetra_Map(total_elems, 0, *comm)); // Distribute the elems equally
00273 
00274   int worksetSize = this->computeWorksetSize(worksetSizeMax, elem_map->NumMyElements());
00275 
00276   // Build a map to get the EB name given the index
00277 
00278   for (unsigned int eb=0; eb<numEB; eb++) 
00279   
00280     ebNameToIndex[partVec[eb]->name()] = eb;
00281 
00282   // Construct MeshSpecsStruct
00283   if (!params->get("Separate Evaluators by Element Block",false)) {
00284 
00285     const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[0]).getCellTopologyData();
00286 
00287     this->meshSpecs[0] = Teuchos::rcp(new Albany::MeshSpecsStruct(ctd, numDim, cub,
00288                                nsNames, ssNames, worksetSize, partVec[0]->name(), 
00289                                ebNameToIndex, this->interleavedOrdering));
00290   }
00291   else {
00292 
00293     meshSpecs.resize(numEB);
00294   
00295     this->allElementBlocksHaveSamePhysics=false;
00296   
00297     for (unsigned int eb=0; eb<numEB; eb++) {
00298   
00299       // MeshSpecs holds all info needed to set up an Albany problem
00300   
00301       const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[eb]).getCellTopologyData();
00302 
00303       this->meshSpecs[eb] = Teuchos::rcp(new Albany::MeshSpecsStruct(ctd, numDim, cub,
00304                                 nsNames, ssNames, worksetSize, partVec[eb]->name(), 
00305                                 ebNameToIndex, this->interleavedOrdering));
00306     }
00307  }
00308 }
00309 
00310 template<unsigned Dim, class traits>
00311 void
00312 Albany::TmplSTKMeshStruct<Dim, traits>::setFieldAndBulkData(
00313                   const Teuchos::RCP<const Epetra_Comm>& comm,
00314                   const Teuchos::RCP<Teuchos::ParameterList>& params,
00315                   const unsigned int neq_,
00316                   const AbstractFieldContainer::FieldContainerRequirements& req,
00317                   const Teuchos::RCP<Albany::StateInfoStruct>& sis,
00318                   const unsigned int worksetSize)
00319 {
00320 
00321   // Create global mesh: Dim-D structured, rectangular
00322 
00323 //  std::vector<std::vector<double> > h_dim;
00324   std::vector<double> h_dim[traits_type::size];
00325 //  h_dim.resize(traits_type::size);
00326 //  x.resize(traits_type::size);
00327 //  x.resize(Dim);
00328 
00329   for(unsigned idx=0; idx < Dim; idx++){ 
00330 
00331     // Allocate the storage
00332 
00333     x[idx].resize(nelem[idx] + 1);
00334     h_dim[idx].resize(nelem[idx] + 1);
00335 
00336   }
00337 
00338   for(unsigned int eb = 0; eb < numEB; eb++)
00339 
00340     EBSpecs[eb].calcElemSizes(h_dim);
00341 
00342   for(unsigned idx=0; idx < Dim; idx++){
00343 
00344     x[idx][0] = 0;
00345 
00346     for(unsigned int i=1; i <= nelem[idx]; i++)
00347 
00348       x[idx][i] = x[idx][i - 1] + h_dim[idx][i - 1]; // place the coordinates of the element nodes
00349 
00350 
00351   }
00352 
00353   SetupFieldData(comm, neq_, req, sis, worksetSize);
00354 
00355   metaData->commit();
00356 
00357   // STK
00358   bulkData->modification_begin(); // Begin modifying the mesh
00359 
00360   buildMesh(comm);
00361 
00362   // STK
00363   bulkData->modification_end();
00364 
00365   // Refine the mesh before starting the simulation if indicated
00366   uniformRefineMesh(comm);
00367 
00368   // Rebalance the mesh before starting the simulation if indicated
00369   rebalanceInitialMesh(comm);
00370 
00371   // Build additional mesh connectivity needed for mesh fracture (if indicated)
00372   computeAddlConnectivity();
00373 
00374 
00375 }
00376 
00377 template <unsigned Dim, class traits>
00378 void 
00379 Albany::TmplSTKMeshStruct<Dim, traits>::DeclareParts(
00380               std::vector<EBSpecsStruct<Dim, traits> > ebStructArray, 
00381               std::vector<std::string> ssNames,
00382               std::vector<std::string> nsNames)
00383 {
00384   // Element blocks
00385   for (std::size_t i=0; i<ebStructArray.size(); i++) {
00386     // declare each element block present in the mesh
00387     partVec[i] = & metaData->declare_part(ebStructArray[i].name, metaData->element_rank() );
00388 #ifdef ALBANY_SEACAS
00389     stk::io::put_io_part_attribute(*partVec[i]);
00390 #endif
00391   }
00392 
00393   // SideSets
00394   for (std::size_t i=0; i<ssNames.size(); i++) {
00395     std::string ssn = ssNames[i];
00396     ssPartVec[ssn] = & metaData->declare_part(ssn, metaData->side_rank() );
00397 #ifdef ALBANY_SEACAS
00398     stk::io::put_io_part_attribute(*ssPartVec[ssn]);
00399 #endif
00400   }
00401 
00402   // NodeSets
00403   for (std::size_t i=0; i<nsNames.size(); i++) {
00404     std::string nsn = nsNames[i];
00405     nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
00406 #ifdef ALBANY_SEACAS
00407     stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00408 #endif
00409   }
00410 
00411 }
00412 
00413 template <unsigned Dim, class traits>
00414 void
00415 Albany::EBSpecsStruct<Dim, traits>::Initialize(unsigned int nnelems[], double blLen[]){
00416 
00417     name = "Block0";
00418 
00419     for(unsigned i = 0; i < Dim; i++){
00420 
00421       min[i] = 0;
00422       max[i] = nnelems[i];
00423       blLength[i] = blLen[i];
00424 
00425     }
00426 }
00427 
00428 // Template specialization functions for the different dimensions
00429 
00430 
00431 // Specializations to read the element block information for each dimension
00432 
00433 template<>
00434 int
00435 Albany::EBSpecsStruct<0>::numElems(int i){ 
00436     return 1;
00437 }
00438 
00439 template<>
00440 void
00441 Albany::EBSpecsStruct<0>::calcElemSizes(std::vector<double> h[]){ 
00442      h[0][0] = 1.0;
00443 }
00444 
00445 template<>
00446 void
00447 Albany::EBSpecsStruct<0>::Initialize(unsigned int nelems[], double blLen[]){
00448     // Never more than one element block in a 0D problem
00449     name = "Block0";
00450     blLength[0] = blLen[0];
00451 }
00452 
00453 template<>
00454 void
00455 Albany::EBSpecsStruct<0>::Initialize(int i, const Teuchos::RCP<Teuchos::ParameterList>& params){
00456     // Never more than one element block in a 0D problem
00457     name = "Block0";
00458     blLength[0] = 1.0;
00459 }
00460 
00461 template<>
00462 void
00463 Albany::EBSpecsStruct<1>::Initialize(int i, const Teuchos::RCP<Teuchos::ParameterList>& params){
00464 
00465   // Read element block specs from input file. Note that this is called only for the multiple element 
00466   // block case, once per element block.
00467 
00468     // Construct the name of the element block desired
00469     std::stringstream ss;
00470     ss << "Block " << i;
00471 
00472     // Get the parameter string for this block. Note the default (below) applies if there is no block
00473     // information in the xml file.
00474 
00475     std::string blkinfo = params->get<std::string>(ss.str(), "begins at 0 ends at 100 length 1.0 named Block0");
00476 
00477     std::string junk;
00478 
00479     // Parse object to break up the line
00480     std::stringstream parsess(blkinfo);
00481 
00482     //       "begins"  "at"      0      "ends"   "at"     100   "length"     1.0        "named" "Bck0"
00483     parsess >> junk >> junk >> min[0] >> junk >> junk >> max[0] >> junk >> blLength[0] >> junk >> name;
00484 
00485 }
00486 
00487 template<>
00488 void
00489 Albany::EBSpecsStruct<2>::Initialize(int i, const Teuchos::RCP<Teuchos::ParameterList>& params)
00490 {
00491 
00492   // Read element block specs from input file, or set defaults
00493     char buf[256];
00494 
00495     // Construct the name of the element block desired
00496     std::stringstream ss;
00497     ss << "Block " << i;
00498 
00499     // Get the parameter string for this block. Note the default (below) applies if there is no block
00500     // information in the xml file.
00501 
00502     std::string blkinfo = params->get<std::string>(ss.str(), 
00503       "begins at (0, 0) ends at (100, 100) length (1.0, 1.0) named Block0");
00504 
00505     // Parse it
00506     sscanf(&blkinfo[0], "begins at (%d,%d) ends at (%d,%d) length (%lf,%lf) named %s", 
00507       &min[0], &min[1], &max[0], &max[1], &blLength[0], &blLength[1], buf);
00508 
00509     name = buf;
00510 
00511 }
00512 
00513 template<>
00514 void
00515 Albany::EBSpecsStruct<3>::Initialize(int i, const Teuchos::RCP<Teuchos::ParameterList>& params)
00516 {
00517 
00518   // Read element block specs from input file, or set defaults
00519     char buf[256];
00520 
00521     // Construct the name of the element block desired
00522     std::stringstream ss;
00523     ss << "Block " << i;
00524 
00525     // Get the parameter string for this block. Note the default (below) applies if there is no block
00526     // information in the xml file.
00527 
00528     std::string blkinfo = params->get<std::string>(ss.str(), 
00529       "begins at (0, 0, 0) ends at (100, 100, 100) length (1.0, 1.0, 1.0) named Block0");
00530 
00531     // Parse it
00532     sscanf(&blkinfo[0], "begins at (%d,%d,%d) ends at (%d,%d,%d) length (%lf,%lf,%lf) named %s", 
00533       &min[0], &min[1], &min[2], &max[0], &max[1], &max[2], &blLength[0], &blLength[1], &blLength[2], buf);
00534 
00535     name = buf;
00536 
00537 }
00538 
00539 // Specializations to build the mesh for each dimension
00540 template<>
00541 void
00542 Albany::TmplSTKMeshStruct<0>::buildMesh(const Teuchos::RCP<const Epetra_Comm>& comm)
00543 {
00544 
00545   stk::mesh::PartVector nodePartVec;
00546   stk::mesh::PartVector singlePartVec(1);
00547 
00548   singlePartVec[0] = partVec[0]; // Get the element block part to put the element in.
00549                                     // Only one block in 0D mesh
00550 
00551     // Declare element 1 is in that block
00552     stk::mesh::Entity& pt  = bulkData->declare_entity(metaData->element_rank(), 1, singlePartVec);
00553     // Declare node 1 is in the node part vector
00554     stk::mesh::Entity& node = bulkData->declare_entity(metaData->node_rank(), 1, nodePartVec);
00555     // Declare that the node belongs to the element "pt"
00556     // "node" is the zeroth node of this element
00557     bulkData->declare_relation(pt, node, 0);
00558 
00559     // No node sets or side sets in 0D
00560 
00561 }
00562 
00563 // Specialized for 0 D
00564 
00565 template<>
00566 void
00567 Albany::TmplSTKMeshStruct<0, Albany::albany_stk_mesh_traits<0> >::setFieldAndBulkData(
00568                   const Teuchos::RCP<const Epetra_Comm>& comm,
00569                   const Teuchos::RCP<Teuchos::ParameterList>& params,
00570                   const unsigned int neq_,
00571                   const AbstractFieldContainer::FieldContainerRequirements& req,
00572                   const Teuchos::RCP<Albany::StateInfoStruct>& sis,
00573                   const unsigned int worksetSize)
00574 {
00575 
00576   SetupFieldData(comm, neq_, req, sis, worksetSize);
00577 
00578   metaData->commit();
00579 
00580   // STK
00581   bulkData->modification_begin(); // Begin modifying the mesh
00582 
00583   TmplSTKMeshStruct<0, albany_stk_mesh_traits<0> >::buildMesh(comm);
00584 
00585   // STK
00586   bulkData->modification_end();
00587 
00588 }
00589 
00590 template<>
00591 void
00592 Albany::TmplSTKMeshStruct<1>::buildMesh(const Teuchos::RCP<const Epetra_Comm>& comm)
00593 {
00594 
00595   stk::mesh::PartVector nodePartVec;
00596   stk::mesh::PartVector singlePartVec(1);
00597 
00598   std::vector<int> elemNumber(1);
00599   unsigned int ebNo;
00600   unsigned int rightNode=0;
00601 
00602   AbstractSTKFieldContainer::VectorFieldType* coordinates_field = fieldContainer->getCoordinatesField();
00603 
00604   if (periodic_x) {
00605       this->PBCStruct.periodic[0] = true;
00606       this->PBCStruct.scale[0] = scale[0];
00607   }
00608 
00609   // Create elements and node IDs
00610   for (int i=0; i<elem_map->NumMyElements(); i++) {
00611     const unsigned int elem_GID = elem_map->GID(i);
00612     const unsigned int left_node  = elem_GID;
00613     unsigned int right_node = left_node+1;
00614     if (periodic_x) right_node %= elem_map->NumGlobalElements();
00615 //    if (rightNode < right_node) rightNode = right_node;
00616 
00617     stk::mesh::EntityId elem_id = (stk::mesh::EntityId) elem_GID;
00618 
00619     // The left node number is the same as the element number
00620     elemNumber[0] = elem_GID;
00621 
00622     // find out which EB the element is in
00623     
00624     if(numEB == 1) // assume all elements are in element block if there is only one
00625       ebNo = 0;
00626     else {
00627       for(ebNo = 0; ebNo < numEB; ebNo++)
00628        // Does the elemNumber lie in the EB?
00629        if(EBSpecs[ebNo].inEB(elemNumber))
00630          break;
00631 
00632       if(ebNo == numEB){ // error, we didn't find an element block that this element
00633                           // should fit in
00634 
00635           TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00636             std::endl << "Error: Could not place element " << elem_GID << 
00637             " in its corresponding element block." << std::endl);
00638 
00639       }
00640     }
00641 
00642     singlePartVec[0] = partVec[ebNo];
00643 
00644     // Build element "1+elem_id" and put it in the element block
00645     stk::mesh::Entity& edge  = bulkData->declare_entity(metaData->element_rank(), 1+elem_id, singlePartVec);
00646     // Build the left and right nodes of this element and put them in the node part Vec
00647     stk::mesh::Entity& lnode = bulkData->declare_entity(metaData->node_rank(), 1+left_node, nodePartVec);
00648     stk::mesh::Entity& rnode = bulkData->declare_entity(metaData->node_rank(), 1+right_node, nodePartVec);
00649     // node number 0 of this element
00650     bulkData->declare_relation(edge, lnode, 0);
00651     // node number 1 of this element
00652     bulkData->declare_relation(edge, rnode, 1);
00653 
00654     // set the coordinate values for these nodes
00655     double* lnode_coord = stk::mesh::field_data(*coordinates_field, lnode);
00656     lnode_coord[0] = x[0][left_node];
00657     double* rnode_coord = stk::mesh::field_data(*coordinates_field, rnode);
00658     rnode_coord[0] = x[0][right_node];
00659 
00660 /*
00661     if(proc_rank_field){
00662       int* p_rank = stk::mesh::field_data(*proc_rank_field, edge);
00663       p_rank[0] = comm->MyPID();
00664     }
00665 */
00666 
00667     // Set node sets. There are no side sets currently with 1D problems (only 2D and 3D)
00668     if (left_node==0) {
00669        singlePartVec[0] = nsPartVec["NodeSet0"];
00670        bulkData->change_entity_parts(lnode, singlePartVec);
00671 
00672     }
00673     if (right_node==(unsigned int)elem_map->NumGlobalElements()) {
00674       singlePartVec[0] = nsPartVec["NodeSet1"];
00675       bulkData->change_entity_parts(rnode, singlePartVec);
00676     }
00677     // Periodic case -- right node is wrapped to left side
00678     if (right_node==0) {
00679       singlePartVec[0] = nsPartVec["NodeSet0"];
00680       bulkData->change_entity_parts(rnode, singlePartVec);
00681     }
00682 
00683 // Note: Side_ranks are not currently registered for 1D elements, see 
00684 // $TRILINOS_DIR/packages/stk/stk_mesh/stk_mesh/fem/FEMMetaData.cpp line 104.
00685 // Skip sideset construction in 1D for this reason (GAH)
00686 
00687   }
00688 }
00689 
00690 template<>
00691 void
00692 Albany::TmplSTKMeshStruct<2>::buildMesh(const Teuchos::RCP<const Epetra_Comm>& comm)
00693 {
00694 
00695   // STK
00696   stk::mesh::PartVector nodePartVec;
00697   stk::mesh::PartVector singlePartVec(1);
00698   std::vector<int> elemNumber(2);
00699   unsigned int ebNo;
00700 
00701   // Create elements and node IDs
00702   
00703   const unsigned int nodes_x = periodic_x ? nelem[0] : nelem[0] + 1;
00704   const unsigned int mod_x   = periodic_x ? nelem[0] : std::numeric_limits<unsigned int>::max();
00705   const unsigned int mod_y   = periodic_y ? nelem[1] : std::numeric_limits<unsigned int>::max();
00706 
00707   AbstractSTKFieldContainer::VectorFieldType* coordinates_field = fieldContainer->getCoordinatesField();
00708 
00709   if (periodic_x) {
00710       this->PBCStruct.periodic[0] = true;
00711       this->PBCStruct.scale[0] = scale[0];
00712   }
00713   if (periodic_y) {
00714       this->PBCStruct.periodic[1] = true;
00715       this->PBCStruct.scale[1] = scale[1];
00716   }
00717 
00718   for (int i=0; i<elem_map->NumMyElements(); i++) {
00719 
00720     const unsigned int elem_GID = elem_map->GID(i);
00721     const unsigned int x_GID = elem_GID % nelem[0]; // mesh column number
00722     const unsigned int y_GID = elem_GID / nelem[0]; // mesh row number
00723 
00724     const unsigned  int x_GIDplus1 = (x_GID+1)%mod_x; // = x_GID+1 unless last element of periodic system
00725     const unsigned  int y_GIDplus1 = (y_GID+1)%mod_y; // = y_GID+1 unless last element of periodic system
00726 
00727     const unsigned int lower_left  =  x_GID      + nodes_x * y_GID;
00728     const unsigned int lower_right =  x_GIDplus1 + nodes_x * y_GID;
00729     const unsigned int upper_right =  x_GIDplus1 + nodes_x * y_GIDplus1;
00730     const unsigned int upper_left  =  x_GID      + nodes_x * y_GIDplus1;
00731 
00732     // get ID of quadrilateral -- will be doubled for trianlges below
00733     stk::mesh::EntityId elem_id = (stk::mesh::EntityId) elem_GID;
00734 
00735     // Calculate elemNumber of element
00736     elemNumber[0] = x_GID;
00737     elemNumber[1] = y_GID;
00738 
00739     // find out which EB the element is in
00740     
00741     if(numEB == 1) // assume all elements are in element block if there is only one
00742       ebNo = 0;
00743     else {
00744       for(ebNo = 0; ebNo < numEB; ebNo++){
00745        // Does the elemNumber lie in the EB?
00746 //std::cout << elem_GID << " " << i << " " << ebNo << std::endl;
00747        if(EBSpecs[ebNo].inEB(elemNumber))
00748          break;
00749       }
00750 
00751       if(ebNo == numEB){ // error, we didn't find an element block that this element
00752                           // should fit in
00753 
00754           TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00755             std::endl << "Error: Could not place element " << elem_GID << 
00756             " in its corresponding element block." << std::endl);
00757 
00758       }
00759     }
00760 
00761     singlePartVec[0] = partVec[ebNo];
00762 
00763 //if (x_GID==0 && y_GID==0) cout << " FOUND global node " << lower_left << endl;
00764 
00765     // Declare Nodes = (Add one to IDs because STK requires 1-based
00766     stk::mesh::Entity& llnode = bulkData->declare_entity(metaData->node_rank(), 1+lower_left, nodePartVec);
00767     stk::mesh::Entity& lrnode = bulkData->declare_entity(metaData->node_rank(), 1+lower_right, nodePartVec);
00768     stk::mesh::Entity& urnode = bulkData->declare_entity(metaData->node_rank(), 1+upper_right, nodePartVec);
00769     stk::mesh::Entity& ulnode = bulkData->declare_entity(metaData->node_rank(), 1+upper_left, nodePartVec);
00770 
00771     if (triangles) { // pair of 3-node triangles
00772 
00773       stk::mesh::Entity& elem  = bulkData->declare_entity(metaData->element_rank(), 1+2*elem_id, singlePartVec);
00774       bulkData->declare_relation(elem, llnode, 0);
00775       bulkData->declare_relation(elem, lrnode, 1);
00776       bulkData->declare_relation(elem, urnode, 2);
00777       stk::mesh::Entity& elem2 = bulkData->declare_entity(metaData->element_rank(), 1+2*elem_id+1, singlePartVec);
00778       bulkData->declare_relation(elem2, llnode, 0);
00779       bulkData->declare_relation(elem2, urnode, 1);
00780       bulkData->declare_relation(elem2, ulnode, 2);
00781 
00782       // Triangle sideset construction
00783       if (x_GID==0) { // left edge of mesh, elem2 has side 2 on left boundary
00784 
00785          singlePartVec[0] = ssPartVec["SideSet0"];
00786          stk::mesh::EntityId side_id = (stk::mesh::EntityId)(nelem[0] + (2 * y_GID));
00787 
00788          stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
00789          bulkData->declare_relation(elem2, side,  2 /*local side id*/); 
00790 
00791          bulkData->declare_relation(side, ulnode, 0); 
00792          bulkData->declare_relation(side, llnode, 1); 
00793 
00794       }
00795       if (x_GIDplus1==(unsigned int)nelem[0]) { // right edge of mesh, elem has side 1 on right boundary
00796 
00797          singlePartVec[0] = ssPartVec["SideSet1"];
00798          stk::mesh::EntityId side_id = (stk::mesh::EntityId)(nelem[0] + (2 * y_GID) + 1);
00799 
00800          stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
00801          bulkData->declare_relation(elem, side,  1 /*local side id*/); 
00802 
00803          bulkData->declare_relation(side, lrnode, 0); 
00804          bulkData->declare_relation(side, urnode, 1); 
00805 
00806       }
00807       if (y_GID==0) { // bottom edge of mesh, elem has side 0 on lower boundary
00808 
00809          singlePartVec[0] = ssPartVec["SideSet2"];
00810          stk::mesh::EntityId side_id = (stk::mesh::EntityId)(x_GID);
00811 
00812          stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
00813          bulkData->declare_relation(elem, side,  0 /*local side id*/); 
00814 
00815          bulkData->declare_relation(side, llnode, 0); 
00816          bulkData->declare_relation(side, lrnode, 1); 
00817 
00818       }
00819       if (y_GIDplus1==(unsigned int)nelem[1]) { // top edge of mesh, elem2 has side 1 on upper boundary
00820 
00821          singlePartVec[0] = ssPartVec["SideSet3"];
00822          stk::mesh::EntityId side_id = (stk::mesh::EntityId)(nelem[0] + (2 * nelem[1]) + x_GID);
00823 
00824          stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
00825          bulkData->declare_relation(elem2, side,  1 /*local side id*/); 
00826 
00827          bulkData->declare_relation(side, urnode, 0); 
00828          bulkData->declare_relation(side, ulnode, 1); 
00829 
00830       }
00831     } // end pair of triangles
00832   
00833     else {  //4-node quad
00834   
00835       stk::mesh::Entity& elem  = bulkData->declare_entity(metaData->element_rank(), 1+elem_id, singlePartVec);
00836       bulkData->declare_relation(elem, llnode, 0);
00837       bulkData->declare_relation(elem, lrnode, 1);
00838       bulkData->declare_relation(elem, urnode, 2);
00839       bulkData->declare_relation(elem, ulnode, 3);
00840   
00841       // Quad sideset construction
00842       if (x_GID==0) { // left edge of mesh, elem has side 3 on left boundary
00843 
00844          singlePartVec[0] = ssPartVec["SideSet0"];
00845 
00846          stk::mesh::EntityId side_id = (stk::mesh::EntityId)(nelem[0] + (2 * y_GID));
00847 
00848          stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
00849          bulkData->declare_relation(elem, side,  3 /*local side id*/); 
00850 
00851          bulkData->declare_relation(side, ulnode, 0); 
00852          bulkData->declare_relation(side, llnode, 1); 
00853 
00854       }
00855       if (x_GIDplus1==(unsigned int)nelem[0]) { // right edge of mesh, elem has side 1 on right boundary
00856 
00857          singlePartVec[0] = ssPartVec["SideSet1"];
00858 
00859          stk::mesh::EntityId side_id = (stk::mesh::EntityId)(nelem[0] + (2 * y_GID) + 1);
00860 
00861          stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
00862          bulkData->declare_relation(elem, side,  1 /*local side id*/); 
00863 
00864          bulkData->declare_relation(side, lrnode, 0); 
00865          bulkData->declare_relation(side, urnode, 1); 
00866 
00867       }
00868       if (y_GID==0) { // bottom edge of mesh, elem has side 0 on lower boundary
00869 
00870          singlePartVec[0] = ssPartVec["SideSet2"];
00871 
00872          stk::mesh::EntityId side_id = (stk::mesh::EntityId)(x_GID);
00873 
00874          stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
00875          bulkData->declare_relation(elem, side,  0 /*local side id*/); 
00876 
00877          bulkData->declare_relation(side, llnode, 0); 
00878          bulkData->declare_relation(side, lrnode, 1); 
00879 
00880       }
00881       if (y_GIDplus1==(unsigned int)nelem[1]) { // tope edge of mesh, elem has side 2 on upper boundary
00882 
00883          singlePartVec[0] = ssPartVec["SideSet3"];
00884 
00885          stk::mesh::EntityId side_id = (stk::mesh::EntityId)(nelem[0] + (2 * nelem[1]) + x_GID);
00886 
00887          stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
00888          bulkData->declare_relation(elem, side,  2 /*local side id*/); 
00889 
00890          bulkData->declare_relation(side, urnode, 0); 
00891          bulkData->declare_relation(side, ulnode, 1); 
00892 
00893       }
00894     } // end 4 node quad
00895 
00896     double* llnode_coord = stk::mesh::field_data(*coordinates_field, llnode);
00897     llnode_coord[0] = x[0][x_GID];   llnode_coord[1] = x[1][y_GID];
00898     double* lrnode_coord = stk::mesh::field_data(*coordinates_field, lrnode);
00899     lrnode_coord[0] = x[0][x_GIDplus1]; lrnode_coord[1] = x[1][y_GID];
00900     double* urnode_coord = stk::mesh::field_data(*coordinates_field, urnode);
00901     urnode_coord[0] = x[0][x_GIDplus1]; urnode_coord[1] = x[1][y_GIDplus1];
00902     double* ulnode_coord = stk::mesh::field_data(*coordinates_field, ulnode);
00903     ulnode_coord[0] = x[0][x_GID]; ulnode_coord[1] = x[1][y_GIDplus1];
00904 
00905     // Nodesets
00906 
00907     if (x_GID==0) { // left of elem is on left bdy
00908        singlePartVec[0] = nsPartVec["NodeSet0"];
00909        bulkData->change_entity_parts(llnode, singlePartVec);
00910        bulkData->change_entity_parts(ulnode, singlePartVec);
00911     }
00912     if ((x_GIDplus1)==(unsigned int)nelem[0]) { // right of elem is on right bdy
00913        singlePartVec[0] = nsPartVec["NodeSet1"];
00914        bulkData->change_entity_parts(lrnode, singlePartVec);
00915        bulkData->change_entity_parts(urnode, singlePartVec);
00916     }
00917     if (y_GID==0) { // bottom of elem is on bottom bdy
00918        singlePartVec[0] = nsPartVec["NodeSet2"];
00919        bulkData->change_entity_parts(llnode, singlePartVec);
00920        bulkData->change_entity_parts(lrnode, singlePartVec);
00921     }
00922     if ((y_GIDplus1)==(unsigned int)nelem[1]) { // top of elem is on top bdy
00923        singlePartVec[0] = nsPartVec["NodeSet3"];
00924        bulkData->change_entity_parts(ulnode, singlePartVec);
00925        bulkData->change_entity_parts(urnode, singlePartVec);
00926     }
00927 
00928     // Periodic cases -- last node wraps around to first
00929     if ((x_GIDplus1)==0) { // right of elem is on right bdy
00930        singlePartVec[0] = nsPartVec["NodeSet0"];
00931        bulkData->change_entity_parts(lrnode, singlePartVec);
00932        bulkData->change_entity_parts(urnode, singlePartVec);
00933     }
00934     if ((y_GIDplus1)==0) { // top of elem is on top bdy
00935        singlePartVec[0] = nsPartVec["NodeSet2"];
00936        bulkData->change_entity_parts(ulnode, singlePartVec);
00937        bulkData->change_entity_parts(urnode, singlePartVec);
00938     }
00939 
00940     // Single node at origin
00941     if (x_GID==0 && y_GID==0) {
00942 //cout << "EUREKA99 " << endl;
00943        singlePartVec[0] = nsPartVec["NodeSet99"];
00944        bulkData->change_entity_parts(llnode, singlePartVec);
00945     }
00946     // Periodic cases
00947     if (x_GIDplus1==0 && y_GIDplus1==0) {
00948 //cout << "EUREKA99 " << endl;
00949        singlePartVec[0] = nsPartVec["NodeSet99"];
00950        bulkData->change_entity_parts(urnode, singlePartVec);
00951     }
00952     if (x_GID==0 && y_GIDplus1==0)  {
00953 //cout << "EUREKA99 " << endl;
00954        singlePartVec[0] = nsPartVec["NodeSet99"];
00955        bulkData->change_entity_parts(ulnode, singlePartVec);
00956     }
00957     if (x_GIDplus1==0 && y_GID==0) { // single node at bottom corner
00958 //cout << "EUREKA99 " << endl;
00959        singlePartVec[0] = nsPartVec["NodeSet99"];
00960        bulkData->change_entity_parts(lrnode, singlePartVec);
00961     }
00962   }
00963 }
00964 
00965 template<>
00966 void
00967 Albany::TmplSTKMeshStruct<3>::buildMesh(const Teuchos::RCP<const Epetra_Comm>& comm)
00968 {
00969 
00970   stk::mesh::PartVector nodePartVec;
00971   stk::mesh::PartVector singlePartVec(1);
00972   std::vector<int> elemNumber(3);
00973   unsigned int ebNo;
00974 
00975   const unsigned int nodes_x  = periodic_x ? nelem[0] : nelem[0] + 1;
00976   const unsigned int nodes_xy = (periodic_y && periodic_y) ? nodes_x * nelem[1] : nodes_x*(nelem[1] + 1);
00977   const unsigned int mod_x    = periodic_x ? nelem[0] : std::numeric_limits<unsigned int>::max();
00978   const unsigned int mod_y    = periodic_y ? nelem[1] : std::numeric_limits<unsigned int>::max();
00979   const unsigned int mod_z    = periodic_z ? nelem[2] : std::numeric_limits<unsigned int>::max();
00980 
00981   AbstractSTKFieldContainer::VectorFieldType* coordinates_field = fieldContainer->getCoordinatesField();
00982 
00983   if (periodic_x) {
00984       this->PBCStruct.periodic[0] = true;
00985       this->PBCStruct.scale[0] = scale[0];
00986   }
00987   if (periodic_y) {
00988       this->PBCStruct.periodic[1] = true;
00989       this->PBCStruct.scale[1] = scale[1];
00990   }
00991   if (periodic_z) {
00992       this->PBCStruct.periodic[2] = true;
00993       this->PBCStruct.scale[2] = scale[2];
00994   }
00995 
00996   // Create elements and node IDs
00997   for (int i=0; i<elem_map->NumMyElements(); i++) {
00998     const unsigned int elem_GID = elem_map->GID(i);
00999     const unsigned int z_GID    = elem_GID / (nelem[0]*nelem[1]); // mesh column number
01000     const unsigned int xy_plane = elem_GID % (nelem[0]*nelem[1]); 
01001     const unsigned int x_GID    = xy_plane % nelem[0]; // mesh column number
01002     const unsigned int y_GID    = xy_plane / nelem[0]; // mesh row number
01003  
01004     const unsigned  int x_GIDplus1 = (x_GID+1)%mod_x; // = x_GID+1 unless last element of periodic system
01005     const unsigned  int y_GIDplus1 = (y_GID+1)%mod_y; // = y_GID+1 unless last element of periodic system
01006     const unsigned  int z_GIDplus1 = (z_GID+1)%mod_z; // = z_GID+1 unless last element of periodic system
01007 
01008     const unsigned int lower_left  =  x_GID      + nodes_x * y_GID      + nodes_xy*z_GID;
01009     const unsigned int lower_right =  x_GIDplus1 + nodes_x * y_GID      + nodes_xy*z_GID;
01010     const unsigned int upper_right =  x_GIDplus1 + nodes_x * y_GIDplus1 + nodes_xy*z_GID;
01011     const unsigned int upper_left  =  x_GID      + nodes_x * y_GIDplus1 + nodes_xy*z_GID;
01012 
01013     const unsigned int lower_left_back  =  x_GID      + nodes_x * y_GID      + nodes_xy * z_GIDplus1;
01014     const unsigned int lower_right_back =  x_GIDplus1 + nodes_x * y_GID      + nodes_xy * z_GIDplus1;
01015     const unsigned int upper_right_back =  x_GIDplus1 + nodes_x * y_GIDplus1 + nodes_xy * z_GIDplus1;
01016     const unsigned int upper_left_back  =  x_GID      + nodes_x * y_GIDplus1 + nodes_xy * z_GIDplus1;
01017 
01018     stk::mesh::EntityId elem_id = (stk::mesh::EntityId) elem_GID;
01019 
01020     // Calculate elemNumber of element
01021     elemNumber[0] = x_GID;
01022     elemNumber[1] = y_GID;
01023     elemNumber[2] = z_GID;
01024 
01025     // find out which EB the element is in
01026     
01027     if(numEB == 1) // assume all elements are in element block if there is only one
01028       ebNo = 0;
01029     else {
01030       for(ebNo = 0; ebNo < numEB; ebNo++)
01031        // Does the elemNumber lie in the EB?
01032        if(EBSpecs[ebNo].inEB(elemNumber))
01033          break;
01034 
01035       if(ebNo == numEB){ // error, we didn't find an element block that this element
01036                           // should fit in
01037 
01038           TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
01039             std::endl << "Error: Could not place element " << elem_GID << 
01040             " in its corresponding element block." << std::endl);
01041 
01042       }
01043     }
01044 
01045     singlePartVec[0] = partVec[ebNo];
01046 
01047     // Add one to IDs because STK requires 1-based
01048     stk::mesh::Entity& elem  = bulkData->declare_entity(metaData->element_rank(), 1+elem_id, singlePartVec);
01049     stk::mesh::Entity& llnode = bulkData->declare_entity(metaData->node_rank(), 1+lower_left, nodePartVec);
01050     stk::mesh::Entity& lrnode = bulkData->declare_entity(metaData->node_rank(), 1+lower_right, nodePartVec);
01051     stk::mesh::Entity& urnode = bulkData->declare_entity(metaData->node_rank(), 1+upper_right, nodePartVec);
01052     stk::mesh::Entity& ulnode = bulkData->declare_entity(metaData->node_rank(), 1+upper_left, nodePartVec);
01053     stk::mesh::Entity& llnodeb = bulkData->declare_entity(metaData->node_rank(), 1+lower_left_back, nodePartVec);
01054     stk::mesh::Entity& lrnodeb = bulkData->declare_entity(metaData->node_rank(), 1+lower_right_back, nodePartVec);
01055     stk::mesh::Entity& urnodeb = bulkData->declare_entity(metaData->node_rank(), 1+upper_right_back, nodePartVec);
01056     stk::mesh::Entity& ulnodeb = bulkData->declare_entity(metaData->node_rank(), 1+upper_left_back, nodePartVec);
01057     bulkData->declare_relation(elem, llnode, 0);
01058     bulkData->declare_relation(elem, lrnode, 1);
01059     bulkData->declare_relation(elem, urnode, 2);
01060     bulkData->declare_relation(elem, ulnode, 3);
01061     bulkData->declare_relation(elem, llnodeb, 4);
01062     bulkData->declare_relation(elem, lrnodeb, 5);
01063     bulkData->declare_relation(elem, urnodeb, 6);
01064     bulkData->declare_relation(elem, ulnodeb, 7);
01065 
01066 /*
01067     if(proc_rank_field){
01068       int* p_rank = stk::mesh::field_data(*proc_rank_field, elem);
01069       p_rank[0] = comm->MyPID();
01070     }
01071 */
01072 
01073     double* coord;
01074     coord = stk::mesh::field_data(*coordinates_field, llnode);
01075     coord[0] = x[0][x_GID];   coord[1] = x[1][y_GID];   coord[2] = x[2][z_GID];
01076     coord = stk::mesh::field_data(*coordinates_field, lrnode);
01077     coord[0] = x[0][x_GIDplus1]; coord[1] = x[1][y_GID];   coord[2] = x[2][z_GID];
01078     coord = stk::mesh::field_data(*coordinates_field, urnode);
01079     coord[0] = x[0][x_GIDplus1]; coord[1] = x[1][y_GIDplus1]; coord[2] = x[2][z_GID];
01080     coord = stk::mesh::field_data(*coordinates_field, ulnode);
01081     coord[0] = x[0][x_GID];   coord[1] = x[1][y_GIDplus1]; coord[2] = x[2][z_GID];
01082 
01083     coord = stk::mesh::field_data(*coordinates_field, llnodeb);
01084     coord[0] = x[0][x_GID];   coord[1] = x[1][y_GID];   coord[2] = x[2][z_GIDplus1];
01085     coord = stk::mesh::field_data(*coordinates_field, lrnodeb);
01086     coord[0] = x[0][x_GIDplus1]; coord[1] = x[1][y_GID];   coord[2] = x[2][z_GIDplus1];
01087     coord = stk::mesh::field_data(*coordinates_field, urnodeb);
01088     coord[0] = x[0][x_GIDplus1]; coord[1] = x[1][y_GIDplus1]; coord[2] = x[2][z_GIDplus1];
01089     coord = stk::mesh::field_data(*coordinates_field, ulnodeb);
01090     coord[0] = x[0][x_GID];   coord[1] = x[1][y_GIDplus1]; coord[2] = x[2][z_GIDplus1];
01091 
01092 /*
01093  * Do sidesets
01094  */
01095 
01096     // Hex sideset construction
01097 
01098     if (x_GID==0) { // left edge of mesh, elem has side 3 on left boundary
01099 
01100       // Sideset construction
01101       // elem has side 3 (0473) on left boundary
01102 
01103      singlePartVec[0] = ssPartVec["SideSet0"];
01104 
01105      stk::mesh::EntityId side_id = (stk::mesh::EntityId)(nelem[0] + (2 * y_GID) + 
01106       (nelem[0] + nelem[1]) * 2 * z_GID);
01107 
01108      stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
01109      bulkData->declare_relation(elem, side,  3 /*local side id*/); 
01110 
01111      bulkData->declare_relation(side, llnode, 0); 
01112      bulkData->declare_relation(side, llnodeb, 4); 
01113      bulkData->declare_relation(side, ulnodeb, 7); 
01114      bulkData->declare_relation(side, ulnode, 3); 
01115 
01116     }
01117     if ((x_GIDplus1)==(unsigned int)nelem[0]) { // right edge of mesh, elem has side 1 on right boundary
01118 
01119 
01120       // elem has side 1 (1265) on right boundary
01121 
01122        singlePartVec[0] = ssPartVec["SideSet1"];
01123 
01124        stk::mesh::EntityId side_id = (stk::mesh::EntityId)(nelem[0] + (2 * y_GID) + 1 +
01125         (nelem[0] + nelem[1]) * 2 * z_GID);
01126 
01127        stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
01128        bulkData->declare_relation(elem, side,  1 /*local side id*/); 
01129 
01130        bulkData->declare_relation(side, lrnode, 1); 
01131        bulkData->declare_relation(side, urnode, 2); 
01132        bulkData->declare_relation(side, urnodeb, 6); 
01133        bulkData->declare_relation(side, lrnodeb, 5); 
01134 
01135     }
01136     if (y_GID==0) { // bottom edge of mesh, elem has side 0 on lower boundary
01137 
01138     // elem has side 0 (0154) on bottom boundary
01139 
01140        singlePartVec[0] = ssPartVec["SideSet2"];
01141 
01142        stk::mesh::EntityId side_id = (stk::mesh::EntityId)(x_GID + (nelem[0] + nelem[1]) * 2 * z_GID);
01143 
01144        stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
01145        bulkData->declare_relation(elem, side,  0 /*local side id*/); 
01146 
01147        bulkData->declare_relation(side, llnode, 0); 
01148        bulkData->declare_relation(side, lrnode, 1); 
01149        bulkData->declare_relation(side, lrnodeb, 5); 
01150        bulkData->declare_relation(side, llnodeb, 4); 
01151 
01152     }
01153     if ((y_GIDplus1)==(unsigned int)nelem[1]) { // tope edge of mesh, elem has side 2 on upper boundary
01154 
01155      // elem has side 2 (2376) on top boundary
01156 
01157      singlePartVec[0] = ssPartVec["SideSet3"];
01158 
01159      stk::mesh::EntityId side_id = (stk::mesh::EntityId)(nelem[0] + (2 * nelem[1]) + x_GID +
01160       (nelem[0] + nelem[1]) * 2 * z_GID);
01161 
01162      stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
01163      bulkData->declare_relation(elem, side,  2 /*local side id*/); 
01164 
01165      bulkData->declare_relation(side, urnode, 2); 
01166      bulkData->declare_relation(side, ulnode, 3); 
01167      bulkData->declare_relation(side, ulnodeb, 7); 
01168      bulkData->declare_relation(side, urnodeb, 6); 
01169 
01170   }
01171   if (z_GID==0) {
01172 
01173       // elem has side 4 (0321) on front boundary
01174 
01175      singlePartVec[0] = ssPartVec["SideSet4"];
01176 
01177      stk::mesh::EntityId side_id = (stk::mesh::EntityId)((nelem[0] + nelem[1]) * 2 * nelem[2] +
01178       x_GID + (2 * nelem[0]) * y_GID);
01179 
01180      stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
01181      bulkData->declare_relation(elem, side,  4 /*local side id*/); 
01182 
01183      bulkData->declare_relation(side, llnode, 0); 
01184      bulkData->declare_relation(side, ulnode, 3); 
01185      bulkData->declare_relation(side, urnode, 2); 
01186      bulkData->declare_relation(side, lrnode, 1); 
01187 
01188   }
01189   if ((z_GIDplus1)==(unsigned int)nelem[2]) {
01190 
01191       // elem has side 5 (4567) on back boundary
01192 
01193      singlePartVec[0] = ssPartVec["SideSet5"];
01194      stk::mesh::EntityId side_id = (stk::mesh::EntityId)((nelem[0] + nelem[1]) * 2 * nelem[2] +
01195       x_GID + (2 * nelem[0]) * y_GID + nelem[0]);
01196 
01197      stk::mesh::Entity& side  = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
01198      bulkData->declare_relation(elem, side,  5 /*local side id*/); 
01199 
01200      bulkData->declare_relation(side, llnodeb, 4); 
01201      bulkData->declare_relation(side, lrnodeb, 5); 
01202      bulkData->declare_relation(side, urnodeb, 6); 
01203      bulkData->declare_relation(side, ulnodeb, 7); 
01204 
01205     }
01206 
01207 /*
01208  * Do Nodesets
01209  */
01210     
01211     if (x_GID==0) {
01212        singlePartVec[0] = nsPartVec["NodeSet0"];
01213        bulkData->change_entity_parts(llnode, singlePartVec); // node 0
01214        bulkData->change_entity_parts(ulnode, singlePartVec); // 3
01215        bulkData->change_entity_parts(llnodeb, singlePartVec); // 4
01216        bulkData->change_entity_parts(ulnodeb, singlePartVec); // 7
01217     }
01218     if ((x_GIDplus1)==(unsigned int)nelem[0]) {
01219        singlePartVec[0] = nsPartVec["NodeSet1"];
01220        bulkData->change_entity_parts(lrnode, singlePartVec); // 1
01221        bulkData->change_entity_parts(urnode, singlePartVec); // 2
01222        bulkData->change_entity_parts(lrnodeb, singlePartVec); // 5
01223        bulkData->change_entity_parts(urnodeb, singlePartVec); // 6
01224     }
01225     if (y_GID==0) {
01226        singlePartVec[0] = nsPartVec["NodeSet2"];
01227        bulkData->change_entity_parts(llnode, singlePartVec); // 0
01228        bulkData->change_entity_parts(lrnode, singlePartVec); // 1
01229        bulkData->change_entity_parts(llnodeb, singlePartVec); // 4
01230        bulkData->change_entity_parts(lrnodeb, singlePartVec); // 5
01231     }
01232     if ((y_GIDplus1)==(unsigned int)nelem[1]) {
01233        singlePartVec[0] = nsPartVec["NodeSet3"];
01234        bulkData->change_entity_parts(ulnode, singlePartVec); // 3
01235        bulkData->change_entity_parts(urnode, singlePartVec); // 2
01236        bulkData->change_entity_parts(ulnodeb, singlePartVec); // 7
01237        bulkData->change_entity_parts(urnodeb, singlePartVec); // 6
01238     }
01239     if (z_GID==0) {
01240        singlePartVec[0] = nsPartVec["NodeSet4"];
01241        bulkData->change_entity_parts(llnode, singlePartVec); // 0
01242        bulkData->change_entity_parts(lrnode, singlePartVec); // 1
01243        bulkData->change_entity_parts(ulnode, singlePartVec); // 3
01244        bulkData->change_entity_parts(urnode, singlePartVec); // 2
01245     }
01246     if ((z_GIDplus1)==(unsigned int)nelem[2]) {
01247        singlePartVec[0] = nsPartVec["NodeSet5"];
01248        bulkData->change_entity_parts(llnodeb, singlePartVec); // 4
01249        bulkData->change_entity_parts(lrnodeb, singlePartVec); // 5
01250        bulkData->change_entity_parts(ulnodeb, singlePartVec); // 7
01251        bulkData->change_entity_parts(urnodeb, singlePartVec); // 6
01252     }
01253 
01254 
01255     // Periodic cases -- last node wraps around to first
01256     if ((x_GIDplus1)==0) {
01257        singlePartVec[0] = nsPartVec["NodeSet0"];
01258        bulkData->change_entity_parts(lrnode, singlePartVec); // 1
01259        bulkData->change_entity_parts(urnode, singlePartVec); // 2
01260        bulkData->change_entity_parts(lrnodeb, singlePartVec); // 5
01261        bulkData->change_entity_parts(urnodeb, singlePartVec); // 6
01262     }
01263     if ((y_GIDplus1)==0) {
01264        singlePartVec[0] = nsPartVec["NodeSet2"];
01265        bulkData->change_entity_parts(ulnode, singlePartVec); // 3
01266        bulkData->change_entity_parts(urnode, singlePartVec); // 2
01267        bulkData->change_entity_parts(ulnodeb, singlePartVec); // 7
01268        bulkData->change_entity_parts(urnodeb, singlePartVec); // 6
01269     }
01270     if ((z_GIDplus1)==0) {
01271        singlePartVec[0] = nsPartVec["NodeSet4"];
01272        bulkData->change_entity_parts(llnodeb, singlePartVec); // 4
01273        bulkData->change_entity_parts(lrnodeb, singlePartVec); // 5
01274        bulkData->change_entity_parts(ulnodeb, singlePartVec); // 7
01275        bulkData->change_entity_parts(urnodeb, singlePartVec); // 6
01276     }
01277 
01278     // Single node at origin
01279     if (x_GID==0 && y_GID==0 && z_GID==0) {
01280        singlePartVec[0] = nsPartVec["NodeSet99"];
01281        bulkData->change_entity_parts(llnode, singlePartVec); // node 0
01282     }
01283     // Seven Periodic cases
01284     if (x_GIDplus1==0 && y_GID==0 && z_GID==0) {
01285        singlePartVec[0] = nsPartVec["NodeSet99"];
01286        bulkData->change_entity_parts(lrnode, singlePartVec); // node 0
01287     }
01288     if (x_GID==0 && y_GIDplus1==0 && z_GID==0) {
01289        singlePartVec[0] = nsPartVec["NodeSet99"];
01290        bulkData->change_entity_parts(ulnode, singlePartVec); // node 0
01291     }
01292     if (x_GIDplus1==0 && y_GIDplus1==0 && z_GID==0) {
01293        singlePartVec[0] = nsPartVec["NodeSet99"];
01294        bulkData->change_entity_parts(urnode, singlePartVec); // node 0
01295     }
01296     if (x_GID==0 && y_GID==0 && z_GIDplus1==0) {
01297        singlePartVec[0] = nsPartVec["NodeSet99"];
01298        bulkData->change_entity_parts(llnodeb, singlePartVec); // node 0
01299     }
01300     if (x_GIDplus1==0 && y_GID==0 && z_GIDplus1==0) {
01301        singlePartVec[0] = nsPartVec["NodeSet99"];
01302        bulkData->change_entity_parts(lrnodeb, singlePartVec); // node 0
01303     }
01304     if (x_GID==0 && y_GIDplus1==0 && z_GIDplus1==0) {
01305        singlePartVec[0] = nsPartVec["NodeSet99"];
01306        bulkData->change_entity_parts(ulnodeb, singlePartVec); // node 0
01307     }
01308     if (x_GIDplus1==0 && y_GIDplus1==0 && z_GIDplus1==0) {
01309        singlePartVec[0] = nsPartVec["NodeSet99"];
01310        bulkData->change_entity_parts(urnodeb, singlePartVec); // node 0
01311     }
01312 
01313   } // end element loop
01314 }
01315 
01316 template<>
01317 Teuchos::RCP<const Teuchos::ParameterList>
01318 Albany::TmplSTKMeshStruct<0>::getValidDiscretizationParameters() const
01319 {
01320   Teuchos::RCP<Teuchos::ParameterList> validPL =
01321     this->getValidGenericSTKParameters("ValidSTK0D_DiscParams");
01322 
01323   return validPL;
01324 }
01325 
01326 template<>
01327 Teuchos::RCP<const Teuchos::ParameterList>
01328 Albany::TmplSTKMeshStruct<1>::getValidDiscretizationParameters() const
01329 {
01330   Teuchos::RCP<Teuchos::ParameterList> validPL =
01331     this->getValidGenericSTKParameters("ValidSTK1D_DiscParams");
01332   validPL->set<bool>("Periodic_x BC", false, "Flag to indicate periodic mesh in x-dimesnsion");
01333   validPL->set<int>("1D Elements", 0, "Number of Elements in X discretization");
01334   validPL->set<double>("1D Scale", 1.0, "Width of X discretization");
01335 
01336   // Multiple element blocks parameters
01337   validPL->set<int>("Element Blocks", 1, "Number of elements blocks that span the X domain");
01338 
01339   for(unsigned int i = 0; i < numEB; i++){
01340 
01341     std::stringstream ss;
01342     ss << "Block " << i;
01343 
01344     validPL->set<std::string>(ss.str(), "begins at 0 ends at 100 length 1.0 named Bck0", 
01345          "Beginning and ending parametric coordinates of block, block name");
01346 
01347   }
01348 
01349   return validPL;
01350 }
01351 
01352 template<>
01353 Teuchos::RCP<const Teuchos::ParameterList>
01354 Albany::TmplSTKMeshStruct<2>::getValidDiscretizationParameters() const
01355 {
01356   Teuchos::RCP<Teuchos::ParameterList> validPL = 
01357     this->getValidGenericSTKParameters("ValidSTK2D_DiscParams");
01358 
01359   validPL->set<bool>("Periodic_x BC", false, "Flag to indicate periodic mesh in x-dimesnsion");
01360   validPL->set<bool>("Periodic_y BC", false, "Flag to indicate periodic mesh in y-dimesnsion");
01361   validPL->set<int>("1D Elements", 0, "Number of Elements in X discretization");
01362   validPL->set<int>("2D Elements", 0, "Number of Elements in Y discretization");
01363   validPL->set<double>("1D Scale", 1.0, "Width of X discretization");
01364   validPL->set<double>("2D Scale", 1.0, "Height of Y discretization");
01365   validPL->set<std::string>("Cell Topology", "Quad" , "Quad or Tri Cell Topology");
01366  
01367   // Multiple element blocks parameters
01368   validPL->set<int>("Element Blocks", 1, "Number of elements blocks that span the X-Y domain");
01369 
01370   for(unsigned int i = 0; i < numEB; i++){
01371 
01372     std::stringstream ss;
01373     ss << "Block " << i;
01374 
01375     validPL->set<std::string>(ss.str(), "begins at (0, 0) ends at (100, 100) length (1.0, 1.0) named Bck0", 
01376          "Beginning and ending parametric coordinates of block, block name");
01377 
01378   }
01379 
01380   return validPL;
01381 }
01382 
01383 template<>
01384 Teuchos::RCP<const Teuchos::ParameterList>
01385 Albany::TmplSTKMeshStruct<3>::getValidDiscretizationParameters() const
01386 {
01387   Teuchos::RCP<Teuchos::ParameterList> validPL =
01388     this->getValidGenericSTKParameters("ValidSTK3D_DiscParams");
01389 
01390   validPL->set<bool>("Periodic_x BC", false, "Flag to indicate periodic mesh in x-dimesnsion");
01391   validPL->set<bool>("Periodic_y BC", false, "Flag to indicate periodic mesh in y-dimesnsion");
01392   validPL->set<bool>("Periodic_z BC", false, "Flag to indicate periodic mesh in z-dimesnsion");
01393   validPL->set<int>("1D Elements", 0, "Number of Elements in X discretization");
01394   validPL->set<int>("2D Elements", 0, "Number of Elements in Y discretization");
01395   validPL->set<int>("3D Elements", 0, "Number of Elements in Z discretization");
01396   validPL->set<double>("1D Scale", 1.0, "Width of X discretization");
01397   validPL->set<double>("2D Scale", 1.0, "Depth of Y discretization");
01398   validPL->set<double>("3D Scale", 1.0, "Height of Z discretization");
01399  
01400   // Multiple element blocks parameters
01401   validPL->set<int>("Element Blocks", 1, "Number of elements blocks that span the X-Y-Z domain");
01402 
01403   for(unsigned int i = 0; i < numEB; i++){
01404 
01405     std::stringstream ss;
01406     ss << "Block " << i;
01407 
01408     validPL->set<std::string>(ss.str(), 
01409           "begins at (0, 0, 0) ends at (100, 100, 100) length (1.0, 1.0, 1.0) named Bck0", 
01410           "Beginning and ending parametric coordinates of block, block name");
01411 
01412   }
01413 
01414   return validPL;
01415 }

Generated on Wed Mar 26 2014 18:36:36 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1