00001
00002
00003
00004
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
00028 #include <boost/algorithm/string/predicate.hpp>
00029
00030 #include "Albany_Utils.hpp"
00031
00032
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
00176 for (int i = 0; i < numLayers+1; i++)
00177 levelsNormalizedThickness[i] = double(i) / numLayers;
00178
00179
00180
00181
00182
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
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();
00311
00312 stk::mesh::PartVector nodePartVec;
00313 stk::mesh::PartVector singlePartVec(1);
00314 stk::mesh::PartVector emptyPartVec;
00315 unsigned int ebNo = 0;
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
00382
00383 stk::mesh::PairIterRelation rel = cells[ib]->relations(meshStruct2D->metaData->node_rank());
00384 double tempOnPrism = 0;
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;
00444 upperSideLID = 1;
00445 break;
00446 case Wedge:
00447 numSubelemOnPrism = 1;
00448 numBasalSidePoints = 3;
00449 basalSideLID = 3;
00450 upperSideLID = 4;
00451 break;
00452 case Hexahedron:
00453 numSubelemOnPrism = 1;
00454 numBasalSidePoints = 4;
00455 basalSideLID = 4;
00456 upperSideLID = 5;
00457 break;
00458 }
00459
00460 singlePartVec[0] = ssPartVec["lateralside"];
00461
00462
00463
00464
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
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
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
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
00633
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
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
00654
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