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

Albany_ExtrudedSTKMeshStruct.cpp

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 
00009 #include "Albany_ExtrudedSTKMeshStruct.hpp"
00010 #include "Albany_STKDiscretization.hpp"
00011 #include "Albany_IossSTKMeshStruct.hpp"
00012 #include "Teuchos_VerboseObject.hpp"
00013 
00014 #include <Shards_BasicTopologies.hpp>
00015 
00016 #include <stk_mesh/base/Entity.hpp>
00017 #include <stk_mesh/base/GetEntities.hpp>
00018 #include <stk_mesh/base/GetBuckets.hpp>
00019 #include <stk_mesh/base/FieldData.hpp>
00020 #include <stk_mesh/base/Selector.hpp>
00021 #include <Epetra_Import.h>
00022 
00023 #ifdef ALBANY_SEACAS
00024 #include <stk_io/IossBridge.hpp>
00025 #endif
00026 
00027 //#include <stk_mesh/fem/FEMHelpers.hpp>
00028 #include <boost/algorithm/string/predicate.hpp>
00029 
00030 #include "Albany_Utils.hpp"
00031 
00032 //TODO: Generalize the importer so that it can extrude quad meshes
00033 
00034 Albany::ExtrudedSTKMeshStruct::ExtrudedSTKMeshStruct(const Teuchos::RCP<Teuchos::ParameterList>& params, const Teuchos::RCP<const Epetra_Comm>& comm) :
00035     GenericSTKMeshStruct(params, Teuchos::null, 3), out(Teuchos::VerboseObjectBase::getDefaultOStream()), periodic(false) {
00036   params->validateParameters(*getValidDiscretizationParameters(), 0);
00037 
00038   std::string ebn = "Element Block 0";
00039   partVec[0] = &metaData->declare_part(ebn, metaData->element_rank());
00040   ebNameToIndex[ebn] = 0;
00041 
00042 #ifdef ALBANY_SEACAS
00043   stk::io::put_io_part_attribute(*partVec[0]);
00044 #endif
00045 
00046   std::vector<std::string> nsNames;
00047   std::string nsn = "Lateral";
00048   nsNames.push_back(nsn);
00049   nsPartVec[nsn] = &metaData->declare_part(nsn, metaData->node_rank());
00050 #ifdef ALBANY_SEACAS
00051   stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00052 #endif
00053   nsn = "Internal";
00054   nsNames.push_back(nsn);
00055   nsPartVec[nsn] = &metaData->declare_part(nsn, metaData->node_rank());
00056 #ifdef ALBANY_SEACAS
00057   stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00058 #endif
00059   nsn = "Bottom";
00060   nsNames.push_back(nsn);
00061   nsPartVec[nsn] = &metaData->declare_part(nsn, metaData->node_rank());
00062 #ifdef ALBANY_SEACAS
00063   stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00064 #endif
00065 
00066   std::vector<std::string> ssNames;
00067   std::string ssnLat = "lateralside";
00068   std::string ssnBottom = "basalside";
00069   std::string ssnTop = "upperside";
00070 
00071   ssNames.push_back(ssnLat);
00072   ssNames.push_back(ssnBottom);
00073   ssNames.push_back(ssnTop);
00074   ssPartVec[ssnLat] = &metaData->declare_part(ssnLat, metaData->side_rank());
00075   ssPartVec[ssnBottom] = &metaData->declare_part(ssnBottom, metaData->side_rank());
00076   ssPartVec[ssnTop] = &metaData->declare_part(ssnTop, metaData->side_rank());
00077 #ifdef ALBANY_SEACAS
00078   stk::io::put_io_part_attribute(*ssPartVec[ssnLat]);
00079   stk::io::put_io_part_attribute(*ssPartVec[ssnBottom]);
00080   stk::io::put_io_part_attribute(*ssPartVec[ssnTop]);
00081 #endif
00082 
00083   Teuchos::RCP<Teuchos::ParameterList> params2D(new Teuchos::ParameterList());
00084   params2D->set("Use Serial Mesh", params->get("Use Serial Mesh", false));
00085   params2D->set("Exodus Input File Name", params->get("Exodus Input File Name", "IceSheet.exo"));
00086   meshStruct2D = Teuchos::rcp(new Albany::IossSTKMeshStruct(params2D, adaptParams, comm));
00087   Teuchos::RCP<Albany::StateInfoStruct> sis = Teuchos::rcp(new Albany::StateInfoStruct);
00088   Albany::AbstractFieldContainer::FieldContainerRequirements req;
00089   meshStruct2D->setFieldAndBulkData(comm, params, 1, req, sis, meshStruct2D->getMeshSpecs()[0]->worksetSize);
00090 
00091   std::vector<stk::mesh::Entity *> cells;
00092   stk::mesh::Selector select_owned_in_part = stk::mesh::Selector(meshStruct2D->metaData->universal_part()) & stk::mesh::Selector(meshStruct2D->metaData->locally_owned_part());
00093   int numCells = stk::mesh::count_selected_entities(select_owned_in_part, meshStruct2D->bulkData->buckets(meshStruct2D->metaData->element_rank()));
00094 
00095   std::string shape = params->get("Element Shape", "Hexahedron");
00096   std::string basalside_name;
00097   if(shape == "Tetrahedron")  {
00098     ElemShape = Tetrahedron;
00099     basalside_name = shards::getCellTopologyData<shards::Triangle<3> >()->name;
00100   }
00101   else if (shape == "Wedge")  {
00102     ElemShape = Wedge;
00103     basalside_name = shards::getCellTopologyData<shards::Triangle<3> >()->name;
00104   }
00105   else if (shape == "Hexahedron") {
00106     ElemShape = Hexahedron;
00107     basalside_name = shards::getCellTopologyData<shards::Quadrilateral<4> >()->name;
00108   }
00109   else
00110     TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameterValue,
00111               std::endl << "Error in ExtrudedSTKMeshStruct: Element Shape " << shape << " not recognized. Possible values: Tetrahedron, Wedge, Hexahedron");
00112 
00113   std::string elem2d_name(meshStruct2D->getMeshSpecs()[0]->ctd.base->name);
00114   TEUCHOS_TEST_FOR_EXCEPTION(basalside_name != elem2d_name, Teuchos::Exceptions::InvalidParameterValue,
00115                 std::endl << "Error in ExtrudedSTKMeshStruct: Expecting topology name of elements of 2d mesh to be " <<  basalside_name << " but it is " << elem2d_name);
00116 
00117 
00118   switch (ElemShape) {
00119   case Tetrahedron:
00120     stk::mesh::fem::set_cell_topology<shards::Tetrahedron<4> >(*partVec[0]);
00121     stk::mesh::fem::set_cell_topology<shards::Triangle<3> >(*ssPartVec[ssnBottom]);
00122     stk::mesh::fem::set_cell_topology<shards::Triangle<3> >(*ssPartVec[ssnTop]);
00123     stk::mesh::fem::set_cell_topology<shards::Triangle<3> >(*ssPartVec[ssnLat]);
00124     NumBaseElemeNodes = 3;
00125     break;
00126   case Wedge:
00127     stk::mesh::fem::set_cell_topology<shards::Wedge<6> >(*partVec[0]);
00128     stk::mesh::fem::set_cell_topology<shards::Triangle<3> >(*ssPartVec[ssnBottom]);
00129     stk::mesh::fem::set_cell_topology<shards::Triangle<3> >(*ssPartVec[ssnTop]);
00130     stk::mesh::fem::set_cell_topology<shards::Quadrilateral<4> >(*ssPartVec[ssnLat]);
00131     NumBaseElemeNodes = 3;
00132     break;
00133   case Hexahedron:
00134     stk::mesh::fem::set_cell_topology<shards::Hexahedron<8> >(*partVec[0]);
00135     stk::mesh::fem::set_cell_topology<shards::Quadrilateral<4> >(*ssPartVec[ssnBottom]);
00136     stk::mesh::fem::set_cell_topology<shards::Quadrilateral<4> >(*ssPartVec[ssnTop]);
00137     stk::mesh::fem::set_cell_topology<shards::Quadrilateral<4> >(*ssPartVec[ssnLat]);
00138     NumBaseElemeNodes = 4;
00139     break;
00140   }
00141 
00142 
00143 
00144   numDim = 3;
00145   int cub = params->get("Cubature Degree", 3);
00146   int worksetSizeMax = params->get("Workset Size", 50);
00147   int worksetSize = this->computeWorksetSize(worksetSizeMax, numCells);
00148 
00149   const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[0]).getCellTopologyData();
00150 
00151   this->meshSpecs[0] = Teuchos::rcp(new Albany::MeshSpecsStruct(ctd, numDim, cub, nsNames, ssNames, worksetSize, partVec[0]->name(), ebNameToIndex, this->interleavedOrdering));
00152 
00153 }
00154 
00155 Albany::ExtrudedSTKMeshStruct::~ExtrudedSTKMeshStruct() {
00156 }
00157 
00158 void Albany::ExtrudedSTKMeshStruct::setFieldAndBulkData(const Teuchos::RCP<const Epetra_Comm>& comm, const Teuchos::RCP<Teuchos::ParameterList>& params, const unsigned int neq_, const AbstractFieldContainer::FieldContainerRequirements& req, const Teuchos::RCP<Albany::StateInfoStruct>& sis,
00159     const unsigned int worksetSize) {
00160 
00161   int numLayers = params->get("NumLayers", 10);
00162   bool useGlimmerSpacing = params->get("Use Glimmer Spacing", false);
00163   long long int maxGlobalElements2D = 0;
00164   long long int maxGlobalVertices2dId = 0;
00165   long long int numGlobalVertices2D = 0;
00166   long long int maxGlobalEdges2D = 0;
00167   bool Ordering = params->get("Columnwise Ordering", false);
00168   bool isTetra = true;
00169 
00170   std::vector<double> levelsNormalizedThickness(numLayers + 1), temperatureNormalizedZ;
00171 
00172   if(useGlimmerSpacing)
00173     for (int i = 0; i < numLayers+1; i++)
00174       levelsNormalizedThickness[numLayers-i] = 1.0- (1.0 - std::pow(double(i) / numLayers + 1.0, -2))/(1.0 - std::pow(2.0, -2));
00175   else  //uniform layers
00176     for (int i = 0; i < numLayers+1; i++)
00177       levelsNormalizedThickness[i] = double(i) / numLayers;
00178 
00179   /*std::cout<< "Levels: ";
00180   for (int i = 0; i < numLayers+1; i++)
00181     std::cout<< levelsNormalizedThickness[i] << " ";
00182   std::cout<< "\n";*/
00183 
00184   stk::mesh::Selector select_owned_in_part = stk::mesh::Selector(meshStruct2D->metaData->universal_part()) & stk::mesh::Selector(meshStruct2D->metaData->locally_owned_part());
00185 
00186   stk::mesh::Selector select_overlap_in_part = stk::mesh::Selector(meshStruct2D->metaData->universal_part()) & (stk::mesh::Selector(meshStruct2D->metaData->locally_owned_part()) | stk::mesh::Selector(meshStruct2D->metaData->globally_shared_part()));
00187 
00188   stk::mesh::Selector select_edges = stk::mesh::Selector(*meshStruct2D->metaData->get_part("LateralSide")) & (stk::mesh::Selector(meshStruct2D->metaData->locally_owned_part()) | stk::mesh::Selector(meshStruct2D->metaData->globally_shared_part()));
00189 
00190   std::vector<stk::mesh::Entity *> cells;
00191   stk::mesh::get_selected_entities(select_overlap_in_part, meshStruct2D->bulkData->buckets(meshStruct2D->metaData->element_rank()), cells);
00192 
00193   std::vector<stk::mesh::Entity *> nodes;
00194   stk::mesh::get_selected_entities(select_overlap_in_part, meshStruct2D->bulkData->buckets(meshStruct2D->metaData->node_rank()), nodes);
00195 
00196   std::vector<stk::mesh::Entity *> edges;
00197   stk::mesh::get_selected_entities(select_edges, meshStruct2D->bulkData->buckets(meshStruct2D->metaData->side_rank()), edges);
00198 
00199   long long int maxOwnedElements2D(0), maxOwnedNodes2D(0), maxOwnedSides2D(0), numOwnedNodes2D(0);
00200   for (int i = 0; i < cells.size(); i++)
00201     maxOwnedElements2D = std::max(maxOwnedElements2D, (long long int) cells[i]->identifier());
00202   for (int i = 0; i < nodes.size(); i++)
00203     maxOwnedNodes2D = std::max(maxOwnedNodes2D, (long long int) nodes[i]->identifier());
00204   for (int i = 0; i < edges.size(); i++)
00205     maxOwnedSides2D = std::max(maxOwnedSides2D, (long long int) edges[i]->identifier());
00206   numOwnedNodes2D = stk::mesh::count_selected_entities(select_owned_in_part, meshStruct2D->bulkData->buckets(meshStruct2D->metaData->node_rank()));
00207 
00208   comm->MaxAll(&maxOwnedElements2D, &maxGlobalElements2D, 1);
00209   comm->MaxAll(&maxOwnedNodes2D, &maxGlobalVertices2dId, 1);
00210   comm->MaxAll(&maxOwnedSides2D, &maxGlobalEdges2D, 1);
00211   comm->SumAll(&numOwnedNodes2D, &numGlobalVertices2D, 1);
00212 
00213 
00214   if (comm->MyPID() == 0) std::cout << "Importing ascii files ...";
00215 
00216   //std::cout << "Num Global Elements: " << maxGlobalElements2D<< " " << maxGlobalVertices2dId<< " " << maxGlobalEdges2D << std::endl;
00217 
00218   std::vector<int> indices(nodes.size()), serialIndices;
00219   for (int i = 0; i < nodes.size(); ++i)
00220     indices[i] = nodes[i]->identifier() - 1;
00221 
00222   const Epetra_Map nodes_map(-1, indices.size(), &indices[0], 0, *comm);
00223   int numMyElements = (comm->MyPID() == 0) ? numGlobalVertices2D : 0;
00224   const Epetra_Map serial_nodes_map(-1, numMyElements, 0, *comm);
00225   Epetra_Import importOperator(nodes_map, serial_nodes_map);
00226 
00227   Epetra_Vector temp(serial_nodes_map);
00228   Epetra_Vector sHeightVec(nodes_map);
00229   Epetra_Vector thickVec(nodes_map);
00230   Epetra_Vector bFrictionVec(nodes_map);
00231 
00232   std::string fname = params->get<std::string>("Surface Height File Name", "surface_height.ascii");
00233   read2DFileSerial(fname, temp, comm);
00234   sHeightVec.Import(temp, importOperator, Insert);
00235   fname = params->get<std::string>("Thickness File Name", "thickness.ascii");
00236   read2DFileSerial(fname, temp, comm);
00237   thickVec.Import(temp, importOperator, Insert);
00238   fname = params->get<std::string>("Basal Friction File Name", "basal_friction.ascii");
00239   read2DFileSerial(fname, temp, comm);
00240   bFrictionVec.Import(temp, importOperator, Insert);
00241 
00242   fname = params->get<std::string>("Temperature File Name", "temperature.ascii");
00243 
00244   std::vector<Epetra_Vector> temperatureVecInterp(numLayers + 1, Epetra_Vector(nodes_map)), temperatureVec;
00245 
00246 
00247   readFileSerial(fname, serial_nodes_map, nodes_map, importOperator, temperatureVec, temperatureNormalizedZ, comm);
00248 
00249 
00250   int il0, il1, verticalTSize(temperatureVec.size());
00251   double h0(0.0);
00252 
00253   for (int il = 0; il < numLayers + 1; il++) {
00254     if (levelsNormalizedThickness[il] <= temperatureNormalizedZ[0]) {
00255       il0 = 0;
00256       il1 = 0;
00257       h0 = 1.0;
00258     }
00259 
00260     else if (levelsNormalizedThickness[il] >= temperatureNormalizedZ[verticalTSize - 1]) {
00261       il0 = verticalTSize - 1;
00262       il1 = verticalTSize - 1;
00263       h0 = 0.0;
00264     }
00265 
00266     else {
00267       int k = 0;
00268       while (levelsNormalizedThickness[il] > temperatureNormalizedZ[++k])
00269         ;
00270       il0 = k - 1;
00271       il1 = k;
00272       h0 = (temperatureNormalizedZ[il1] - levelsNormalizedThickness[il]) / (temperatureNormalizedZ[il1] - temperatureNormalizedZ[il0]);
00273     }
00274 
00275     for (int i = 0; i < nodes_map.NumMyElements(); i++)
00276       temperatureVecInterp[il][i] = h0 * temperatureVec[il0][i] + (1.0 - h0) * temperatureVec[il1][i];
00277   }
00278 
00279   std::vector<Epetra_Vector> tempSV(neq_, Epetra_Vector(serial_nodes_map));
00280   std::vector<Epetra_Vector> sVelocityVec(neq_, Epetra_Vector(nodes_map));
00281   std::vector<Epetra_Vector> velocityRMSVec(neq_, Epetra_Vector(nodes_map));
00282   fname = params->get<std::string>("Surface Velocity File Name", "surface_velocity.ascii");
00283   readFileSerial(fname, tempSV, comm);
00284   for (int i = 0; i < tempSV.size(); i++)
00285     sVelocityVec[i].Import(tempSV[i], importOperator, Insert);
00286 
00287   fname = params->get<std::string>("Velocity RMS File Name", "velocity_RMS.ascii");
00288   readFileSerial(fname, tempSV, comm);
00289   for (int i = 0; i < tempSV.size(); i++)
00290     velocityRMSVec[i].Import(tempSV[i], importOperator, Insert);
00291 
00292   if (comm->MyPID() == 0) std::cout << " done." << std::endl;
00293 
00294   long long int elemColumnShift = (Ordering == 1) ? 1 : maxGlobalElements2D;
00295   int lElemColumnShift = (Ordering == 1) ? 1 : cells.size();
00296   int elemLayerShift = (Ordering == 0) ? 1 : numLayers;
00297 
00298   long long int vertexColumnShift = (Ordering == 1) ? 1 : maxGlobalVertices2dId;
00299   int lVertexColumnShift = (Ordering == 1) ? 1 : nodes.size();
00300   int vertexLayerShift = (Ordering == 0) ? 1 : numLayers + 1;
00301 
00302   long long int edgeColumnShift = (Ordering == 1) ? 1 : maxGlobalEdges2D;
00303   int lEdgeColumnShift = (Ordering == 1) ? 1 : edges.size();
00304   int edgeLayerShift = (Ordering == 0) ? 1 : numLayers;
00305 
00306   this->SetupFieldData(comm, neq_, req, sis, worksetSize);
00307 
00308   metaData->commit();
00309 
00310   bulkData->modification_begin(); // Begin modifying the mesh
00311 
00312   stk::mesh::PartVector nodePartVec;
00313   stk::mesh::PartVector singlePartVec(1);
00314   stk::mesh::PartVector emptyPartVec;
00315   unsigned int ebNo = 0; //element block #???
00316 
00317   singlePartVec[0] = nsPartVec["Bottom"];
00318 
00319   AbstractSTKFieldContainer::IntScalarFieldType* proc_rank_field = fieldContainer->getProcRankField();
00320   AbstractSTKFieldContainer::VectorFieldType* coordinates_field = fieldContainer->getCoordinatesField();
00321   AbstractSTKFieldContainer::ScalarFieldType* surfaceHeight_field = fieldContainer->getSurfaceHeightField();
00322   AbstractSTKFieldContainer::ScalarFieldType* thickness_field = fieldContainer->getThicknessField();
00323   AbstractSTKFieldContainer::VectorFieldType* surfaceVelocity_field = fieldContainer->getSurfaceVelocityField();
00324   AbstractSTKFieldContainer::VectorFieldType* velocityRMS_field = fieldContainer->getVelocityRMSField();
00325   AbstractSTKFieldContainer::ScalarFieldType* basal_friction_field = fieldContainer->getBasalFrictionField();
00326   AbstractSTKFieldContainer::ScalarFieldType* temperature_field = fieldContainer->getTemperatureField();
00327 
00328   std::vector<long long int> prismMpasIds(NumBaseElemeNodes), prismGlobalIds(2 * NumBaseElemeNodes);
00329 
00330   for (int i = 0; i < (numLayers + 1) * nodes.size(); i++) {
00331     int ib = (Ordering == 0) * (i % lVertexColumnShift) + (Ordering == 1) * (i / vertexLayerShift);
00332     int il = (Ordering == 0) * (i / lVertexColumnShift) + (Ordering == 1) * (i % vertexLayerShift);
00333     stk::mesh::Entity* node;
00334     stk::mesh::Entity* node2d = nodes[ib];
00335     stk::mesh::EntityId node2dId = node2d->identifier() - 1;
00336     if (il == 0)
00337       node = &bulkData->declare_entity(metaData->node_rank(), il * vertexColumnShift + vertexLayerShift * node2dId + 1, singlePartVec);
00338     else
00339       node = &bulkData->declare_entity(metaData->node_rank(), il * vertexColumnShift + vertexLayerShift * node2dId + 1, nodePartVec);
00340 
00341     double* coord = stk::mesh::field_data(*coordinates_field, *node);
00342     double* coord2d = stk::mesh::field_data(*coordinates_field, *node2d);
00343     coord[0] = coord2d[0];
00344     coord[1] = coord2d[1];
00345 
00346 #ifdef ALBANY_FELIX
00347     int lid = nodes_map.LID((long long int)(node2dId));
00348     double* sHeight = stk::mesh::field_data(*surfaceHeight_field, *node);
00349     sHeight[0] = sHeightVec[lid];
00350 
00351     double* thick = stk::mesh::field_data(*thickness_field, *node);
00352     thick[0] = thickVec[lid];
00353 
00354     double* sVelocity = stk::mesh::field_data(*surfaceVelocity_field, *node);
00355     sVelocity[0] = sVelocityVec[0][lid];
00356     sVelocity[1] = sVelocityVec[1][lid];
00357 
00358     double* velocityRMS = stk::mesh::field_data(*velocityRMS_field, *node);
00359     velocityRMS[0] = velocityRMSVec[0][lid];
00360     velocityRMS[1] = velocityRMSVec[1][lid];
00361 
00362     double* bFriction = stk::mesh::field_data(*basal_friction_field, *node);
00363     bFriction[0] = bFrictionVec[lid];
00364     coord[2] = sHeight[0] - thick[0] * (1. - levelsNormalizedThickness[il]);
00365 #else
00366     coord[2] = 0;
00367 #endif
00368   }
00369 
00370   long long int tetrasLocalIdsOnPrism[3][4];
00371 
00372   for (int i = 0; i < cells.size() * numLayers; i++) {
00373 
00374     int ib = (Ordering == 0) * (i % lElemColumnShift) + (Ordering == 1) * (i / elemLayerShift);
00375     int il = (Ordering == 0) * (i / lElemColumnShift) + (Ordering == 1) * (i % elemLayerShift);
00376 
00377     int shift = il * vertexColumnShift;
00378 
00379     singlePartVec[0] = partVec[ebNo];
00380 
00381     //TODO: this could be done only in the first layer and then copied into the other layers
00382 
00383     stk::mesh::PairIterRelation rel = cells[ib]->relations(meshStruct2D->metaData->node_rank());
00384     double tempOnPrism = 0; //Set temperature constant on each prism/Hexa
00385     for (int j = 0; j < NumBaseElemeNodes; j++) {
00386       stk::mesh::EntityId node2dId = rel[j].entity()->identifier() - 1;
00387       int node2dLId = nodes_map.LID((long long int)(node2dId));
00388       stk::mesh::EntityId mpasLowerId = vertexLayerShift * node2dId;
00389       stk::mesh::EntityId lowerId = shift + vertexLayerShift * node2dId;
00390       prismMpasIds[j] = mpasLowerId;
00391       prismGlobalIds[j] = lowerId;
00392       prismGlobalIds[j + NumBaseElemeNodes] = lowerId + vertexColumnShift;
00393       tempOnPrism += 1. / NumBaseElemeNodes / 2. * (temperatureVecInterp[il][node2dLId] + temperatureVecInterp[il + 1][node2dLId]);
00394     }
00395 
00396     switch (ElemShape) {
00397     case Tetrahedron: {
00398       tetrasFromPrismStructured(&prismMpasIds[0], &prismGlobalIds[0], tetrasLocalIdsOnPrism);
00399 
00400       stk::mesh::EntityId prismId = il * elemColumnShift + elemLayerShift * (cells[ib]->identifier() - 1);
00401       for (int iTetra = 0; iTetra < 3; iTetra++) {
00402         stk::mesh::Entity& elem = bulkData->declare_entity(metaData->element_rank(), 3 * prismId + iTetra + 1, singlePartVec);
00403         for (int j = 0; j < 4; j++) {
00404           stk::mesh::Entity& node = *bulkData->get_entity(metaData->node_rank(), tetrasLocalIdsOnPrism[iTetra][j] + 1);
00405           bulkData->declare_relation(elem, node, j);
00406         }
00407         int* p_rank = (int*) stk::mesh::field_data(*proc_rank_field, elem);
00408         p_rank[0] = comm->MyPID();
00409 #ifdef ALBANY_FELIX
00410         double* temperature = stk::mesh::field_data(*temperature_field,
00411             elem);
00412         temperature[0] = tempOnPrism;
00413 #endif
00414       }
00415     }
00416       break;
00417     case Wedge:
00418     case Hexahedron: {
00419       stk::mesh::EntityId prismId = il * elemColumnShift + elemLayerShift * (cells[ib]->identifier() - 1);
00420       stk::mesh::Entity& elem = bulkData->declare_entity(metaData->element_rank(), prismId + 1, singlePartVec);
00421       for (int j = 0; j < 2 * NumBaseElemeNodes; j++) {
00422         stk::mesh::Entity& node = *bulkData->get_entity(metaData->node_rank(), prismGlobalIds[j] + 1);
00423         bulkData->declare_relation(elem, node, j);
00424       }
00425       int* p_rank = (int*) stk::mesh::field_data(*proc_rank_field, elem);
00426       p_rank[0] = comm->MyPID();
00427 #ifdef ALBANY_FELIX
00428       double* temperature = stk::mesh::field_data(*temperature_field,
00429           elem);
00430       temperature[0] = tempOnPrism;
00431 #endif
00432     }
00433     }
00434   }
00435 
00436   int numSubelemOnPrism, numBasalSidePoints;
00437   int basalSideLID, upperSideLID;
00438 
00439   switch (ElemShape) {
00440   case Tetrahedron:
00441     numSubelemOnPrism = 3;
00442     numBasalSidePoints = 3;
00443     basalSideLID = 3;  //depends on how the tetrahedron is located in the Prism, see tetraFaceIdOnPrismFaceId below.
00444     upperSideLID = 1;
00445     break;
00446   case Wedge:
00447     numSubelemOnPrism = 1;
00448     numBasalSidePoints = 3;
00449     basalSideLID = 3;  //depends on how the tetrahedron is located in the Prism.
00450     upperSideLID = 4;
00451     break;
00452   case Hexahedron:
00453     numSubelemOnPrism = 1;
00454     numBasalSidePoints = 4;
00455     basalSideLID = 4;  //depends on how the tetrahedron is located in the Prism.
00456     upperSideLID = 5;
00457     break;
00458   }
00459 
00460   singlePartVec[0] = ssPartVec["lateralside"];
00461 
00462   //The following two arrays have being computed offline using the computeMap function in .hpp file.
00463 
00464   //tetraFaceIdOnPrismFaceId[ minIndex ][ PrismFaceID ]
00465   int tetraFaceIdOnPrismFaceId[6][5] = {{0, 1, 2, 3, 1}, {2, 0, 1, 3, 1}, {1, 2, 0, 3, 1}, {2, 1, 0, 1 ,3}, {0, 2, 1, 1, 3}, {1, 0, 2, 1, 3}};
00466 
00467   //tetraAdjacentToPrismLateralFace[ minIndex ][ prismType ][ PrismFaceID ][ iTetra ]. There are to Terahedra adjacent to a Prism face. iTetra in {0,1}
00468   int tetraAdjacentToPrismLateralFace[6][2][3][2] = { { { { 1, 2 }, { 0, 1 }, { 0, 2 } }, { { 0, 2 }, { 0, 1 }, { 1, 2 } } },
00469                                                       { { { 0, 2 }, { 1, 2 }, { 0, 1 } }, { { 1, 2 }, { 0, 2 }, { 0, 1 } } },
00470                                                       { { { 0, 1 }, { 0, 2 }, { 1, 2 } }, { { 0, 1 }, { 1, 2 }, { 0, 2 } } },
00471                                                       { { { 0, 2 }, { 0, 1 }, { 1, 2 } }, { { 1, 2 }, { 0, 1 }, { 0, 2 } } },
00472                                                       { { { 1, 2 }, { 0, 2 }, { 0, 1 } }, { { 0, 2 }, { 1, 2 }, { 0, 1 } } },
00473                                                       { { { 0, 1 }, { 1, 2 }, { 0, 2 } }, { { 0, 1 }, { 0, 2 }, { 1, 2 } } } };
00474 
00475   for (int i = 0; i < edges.size() * numLayers; i++) {
00476     int ib = (Ordering == 0) * (i % lEdgeColumnShift) + (Ordering == 1) * (i / edgeLayerShift);
00477     // if(!isBoundaryEdge[ib]) continue; //WARNING: assuming that all the edges stored are boundary edges!!
00478 
00479     stk::mesh::Entity* edge2d = edges[ib];
00480     stk::mesh::PairIterRelation rel = edge2d->relations(meshStruct2D->metaData->element_rank());
00481     int il = (Ordering == 0) * (i / lEdgeColumnShift) + (Ordering == 1) * (i % edgeLayerShift);
00482     stk::mesh::Entity* elem2d = rel[0].entity();
00483     stk::mesh::EntityId edgeLID = rel[0].identifier();
00484 
00485     stk::mesh::EntityId basalElemId = elem2d->identifier() - 1;
00486     stk::mesh::EntityId Edge2dId = edge2d->identifier() - 1;
00487     switch (ElemShape) {
00488     case Tetrahedron: {
00489       rel = elem2d->relations(meshStruct2D->metaData->node_rank());
00490       for (int j = 0; j < NumBaseElemeNodes; j++) {
00491         stk::mesh::EntityId node2dId = rel[j].entity()->identifier() - 1;
00492         prismMpasIds[j] = vertexLayerShift * node2dId;
00493       }
00494       int minIndex;
00495       int pType = prismType(&prismMpasIds[0], minIndex);
00496       stk::mesh::EntityId tetraId = 3 * il * elemColumnShift + 3 * elemLayerShift * basalElemId;
00497 
00498       stk::mesh::Entity& elem0 = *bulkData->get_entity(metaData->element_rank(), tetraId + tetraAdjacentToPrismLateralFace[minIndex][pType][edgeLID][0] + 1);
00499       stk::mesh::Entity& elem1 = *bulkData->get_entity(metaData->element_rank(), tetraId + tetraAdjacentToPrismLateralFace[minIndex][pType][edgeLID][1] + 1);
00500 
00501       stk::mesh::Entity& side0 = bulkData->declare_entity(metaData->side_rank(), 2 * edgeColumnShift * il +  2 * Edge2dId * edgeLayerShift + 1, singlePartVec);
00502       stk::mesh::Entity& side1 = bulkData->declare_entity(metaData->side_rank(), 2 * edgeColumnShift * il +  2 * Edge2dId * edgeLayerShift + 1 + 1, singlePartVec);
00503 
00504       bulkData->declare_relation(elem0, side0, tetraFaceIdOnPrismFaceId[minIndex][edgeLID]);
00505       bulkData->declare_relation(elem1, side1, tetraFaceIdOnPrismFaceId[minIndex][edgeLID]);
00506 
00507       stk::mesh::PairIterRelation rel_elemNodes0 = elem0.relations(metaData->node_rank());
00508       stk::mesh::PairIterRelation rel_elemNodes1 = elem1.relations(metaData->node_rank());
00509       for (int j = 0; j < 3; j++) {
00510         stk::mesh::Entity& node0 = *rel_elemNodes0[this->meshSpecs[0]->ctd.side[tetraFaceIdOnPrismFaceId[minIndex][edgeLID]].node[j]].entity();
00511         bulkData->declare_relation(side0, node0, j);
00512         stk::mesh::Entity& node1 = *rel_elemNodes1[this->meshSpecs[0]->ctd.side[tetraFaceIdOnPrismFaceId[minIndex][edgeLID]].node[j]].entity();
00513         bulkData->declare_relation(side1, node1, j);
00514       }
00515     }
00516 
00517       break;
00518     case Wedge:
00519     case Hexahedron: {
00520       stk::mesh::EntityId prismId = il * elemColumnShift + elemLayerShift * basalElemId;
00521       stk::mesh::Entity& elem = *bulkData->get_entity(metaData->element_rank(), prismId + 1);
00522       stk::mesh::Entity& side = bulkData->declare_entity(metaData->side_rank(), edgeColumnShift * il +Edge2dId * edgeLayerShift + 1, singlePartVec);
00523       bulkData->declare_relation(elem, side, edgeLID);
00524 
00525       stk::mesh::PairIterRelation rel_elemNodes = elem.relations(metaData->node_rank());
00526       for (int j = 0; j < 4; j++) {
00527         stk::mesh::Entity& node = *rel_elemNodes[this->meshSpecs[0]->ctd.side[edgeLID].node[j]].entity();
00528         bulkData->declare_relation(side, node, j);
00529       }
00530     }
00531     break;
00532     }
00533   }
00534   
00535   //then we store the lower and upper faces of prisms, which corresponds to triangles of the basal mesh
00536   edgeLayerShift = (Ordering == 0) ? 1 : numLayers + 1;
00537   edgeColumnShift = elemColumnShift;
00538 
00539   singlePartVec[0] = ssPartVec["basalside"];
00540 
00541 
00542   long long int edgeOffset = maxGlobalEdges2D * numLayers;
00543   if(ElemShape == Tetrahedron) edgeOffset *= 2;
00544 
00545   for (int i = 0; i < cells.size(); i++) {
00546     stk::mesh::Entity& elem2d = *cells[i];
00547     stk::mesh::EntityId elem2d_id = elem2d.identifier() - 1;
00548     stk::mesh::Entity& side = bulkData->declare_entity(metaData->side_rank(), elem2d_id + edgeOffset + 1, singlePartVec);
00549     stk::mesh::Entity& elem = *bulkData->get_entity(metaData->element_rank(), elem2d_id * numSubelemOnPrism * elemLayerShift + 1);
00550     bulkData->declare_relation(elem, side, basalSideLID);
00551 
00552     stk::mesh::PairIterRelation rel_elemNodes = elem.relations(metaData->node_rank());
00553     for (int j = 0; j < numBasalSidePoints; j++) {
00554       stk::mesh::Entity& node = *rel_elemNodes[this->meshSpecs[0]->ctd.side[basalSideLID].node[j]].entity();
00555       bulkData->declare_relation(side, node, j);
00556     }
00557   }
00558 
00559   singlePartVec[0] = ssPartVec["upperside"];
00560 
00561   edgeOffset += maxGlobalElements2D;
00562 
00563   for (int i = 0; i < cells.size(); i++) {
00564     stk::mesh::Entity& elem2d = *cells[i];
00565     stk::mesh::EntityId elem2d_id = elem2d.identifier() - 1;
00566     stk::mesh::Entity& side = bulkData->declare_entity(metaData->side_rank(), elem2d_id  + edgeOffset + 1, singlePartVec);
00567     stk::mesh::Entity& elem = *bulkData->get_entity(metaData->element_rank(), elem2d_id * numSubelemOnPrism * elemLayerShift + (numLayers - 1) * numSubelemOnPrism * elemColumnShift + 1 + (numSubelemOnPrism - 1));
00568     bulkData->declare_relation(elem, side, upperSideLID);
00569 
00570     stk::mesh::PairIterRelation rel_elemNodes = elem.relations(metaData->node_rank());
00571     for (int j = 0; j < numBasalSidePoints; j++) {
00572       stk::mesh::Entity& node = *rel_elemNodes[this->meshSpecs[0]->ctd.side[upperSideLID].node[j]].entity();
00573       bulkData->declare_relation(side, node, j);
00574     }
00575   }
00576 
00577   bulkData->modification_end();
00578 
00579 }
00580 
00581 Teuchos::RCP<const Teuchos::ParameterList> Albany::ExtrudedSTKMeshStruct::getValidDiscretizationParameters() const {
00582   Teuchos::RCP<Teuchos::ParameterList> validPL = this->getValidGenericSTKParameters("Valid Extruded_DiscParams");
00583   validPL->set<std::string>("Exodus Input File Name", "", "File Name For Exodus Mesh Input");
00584   validPL->set<std::string>("Surface Height File Name", "surface_height.ascii", "Name of the file containing the surface height data");
00585   validPL->set<std::string>("Thickness File Name", "thickness.ascii", "Name of the file containing the thickness data");
00586   validPL->set<std::string>("Surface Velocity File Name", "surface_velocity.ascii", "Name of the file containing the surface velocity data");
00587   validPL->set<std::string>("Velocity RMS File Name", "velocity_RMS.ascii", "Name of the file containing the surface velocity RMS data");
00588   validPL->set<std::string>("Basal Friction File Name", "basal_friction.ascii", "Name of the file containing the basal friction data");
00589   validPL->set<std::string>("Temperature File Name", "temperature.ascii", "Name of the file containing the temperature data");
00590   validPL->set<std::string>("Element Shape", "Hexahedron", "Shape of the Element: Tetrahedron, Wedge, Hexahedron");
00591   validPL->set<int>("NumLayers", 10, "Number of vertical Layers of the extruded mesh. In a vertical column, the mesh will have numLayers+1 nodes");
00592   validPL->set<bool>("Use Glimmer Spacing", false, "When true, the layer spacing is computed according to Glimmer formula (layers are denser close to the bedrock)");
00593   validPL->set<bool>("Columnwise Ordering", false, "True for Columnwise ordering, false for Layerwise ordering");
00594   return validPL;
00595 }
00596 
00597 void Albany::ExtrudedSTKMeshStruct::read2DFileSerial(std::string &fname, Epetra_Vector& content, const Teuchos::RCP<const Epetra_Comm>& comm) {
00598   long long int numNodes;
00599   if (comm->MyPID() == 0) {
00600     std::ifstream ifile;
00601     ifile.open(fname.c_str());
00602     if (ifile.is_open()) {
00603       ifile >> numNodes;
00604       TEUCHOS_TEST_FOR_EXCEPTION(numNodes != content.MyLength(), Teuchos::Exceptions::InvalidParameterValue, std::endl << "Error in ExtrudedSTKMeshStruct: Number of nodes in file " << fname << " (" << numNodes << ") is different from the number expected (" << content.MyLength() << ")" << std::endl);
00605 
00606       for (long long int i = 0; i < numNodes; i++)
00607         ifile >> content[i];
00608       ifile.close();
00609     } else {
00610       std::cout << "Warning in ExtrudedSTKMeshStruct: Unable to open the file " << fname << std::endl;
00611     }
00612   }
00613 }
00614 
00615 void Albany::ExtrudedSTKMeshStruct::readFileSerial(std::string &fname, std::vector<Epetra_Vector>& contentVec, const Teuchos::RCP<const Epetra_Comm>& comm) {
00616   long long int numNodes, numComponents;
00617   if (comm->MyPID() == 0) {
00618     std::ifstream ifile;
00619     ifile.open(fname.c_str());
00620     if (ifile.is_open()) {
00621       ifile >> numNodes >> numComponents;
00622       TEUCHOS_TEST_FOR_EXCEPTION(numNodes != contentVec[0].MyLength(), Teuchos::Exceptions::InvalidParameterValue,
00623           std::endl << "Error in ExtrudedSTKMeshStruct: Number of nodes in file " << fname << " (" << numNodes << ") is different from the number expected (" << contentVec[0].MyLength() << ")" << std::endl);
00624       TEUCHOS_TEST_FOR_EXCEPTION(numComponents != contentVec.size(), Teuchos::Exceptions::InvalidParameterValue,
00625           std::endl << "Error in ExtrudedSTKMeshStruct: Number of components in file " << fname << " (" << numComponents << ") is different from the number expected (" << contentVec.size() << ")" << std::endl);
00626       for (int il = 0; il < numComponents; ++il)
00627         for (long long int i = 0; i < numNodes; i++)
00628           ifile >> contentVec[il][i];
00629       ifile.close();
00630     } else {
00631       std::cout << "Warning in ExtrudedSTKMeshStruct: Unable to open input file " << fname << std::endl;
00632       //  TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00633       //      std::endl << "Error in ExtrudedSTKMeshStruct: Unable to open input file " << fname << std::endl);
00634     }
00635   }
00636 }
00637 
00638 void Albany::ExtrudedSTKMeshStruct::readFileSerial(std::string &fname, const Epetra_Map& map_serial, const Epetra_Map& map, const Epetra_Import& importOperator, std::vector<Epetra_Vector>& temperatureVec, std::vector<double>& zCoords, const Teuchos::RCP<const Epetra_Comm>& comm) {
00639   long long int numNodes;
00640   int numComponents;
00641   std::ifstream ifile;
00642   if (comm->MyPID() == 0) {
00643     ifile.open(fname.c_str());
00644     if (ifile.is_open()) {
00645       ifile >> numNodes >> numComponents;
00646 
00647     //  std::cout << "numNodes >> numComponents: " << numNodes << " " << numComponents << std::endl;
00648 
00649       TEUCHOS_TEST_FOR_EXCEPTION(numNodes != map_serial.NumMyElements(), Teuchos::Exceptions::InvalidParameterValue,
00650           std::endl << "Error in ExtrudedSTKMeshStruct: Number of nodes in file " << fname << " (" << numNodes << ") is different from the number expected (" << map_serial.NumMyElements() << ")" << std::endl);
00651     } else {
00652       std::cout << "Warning in ExtrudedSTKMeshStruct: Unable to open input file " << fname << std::endl;
00653       //  TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00654       //      std::endl << "Error in ExtrudedSTKMeshStruct: Unable to open input file " << fname << std::endl);
00655     }
00656   }
00657   comm->Broadcast(&numComponents, 1, 0);
00658   zCoords.resize(numComponents);
00659   Epetra_Vector tempT(map_serial);
00660 
00661   if (comm->MyPID() == 0) {
00662     for (int i = 0; i < numComponents; ++i)
00663       ifile >> zCoords[i];
00664   }
00665   comm->Broadcast(&zCoords[0], numComponents, 0);
00666 
00667   temperatureVec.resize(numComponents, Epetra_Vector(map));
00668 
00669   for (int il = 0; il < numComponents; ++il) {
00670     if (comm->MyPID() == 0)
00671       for (long long int i = 0; i < numNodes; i++)
00672         ifile >> tempT[i];
00673     temperatureVec[il].Import(tempT, importOperator, Insert);
00674   }
00675 
00676   if (comm->MyPID() == 0)
00677     ifile.close();
00678 
00679 }
00680 

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