00001
00002
00003
00004
00005
00006
00007 #include <iostream>
00008
00009 #include "Albany_CismSTKMeshStruct.hpp"
00010 #include "Teuchos_VerboseObject.hpp"
00011
00012 #include <Shards_BasicTopologies.hpp>
00013
00014 #include <stk_mesh/base/Entity.hpp>
00015 #include <stk_mesh/base/GetEntities.hpp>
00016 #include <stk_mesh/base/GetBuckets.hpp>
00017 #include <stk_mesh/base/FieldData.hpp>
00018 #include <stk_mesh/base/Selector.hpp>
00019
00020 #ifdef ALBANY_SEACAS
00021 #include <stk_io/IossBridge.hpp>
00022 #endif
00023
00024
00025
00026 #include <boost/algorithm/string/predicate.hpp>
00027
00028 #include "Albany_Utils.hpp"
00029
00030
00031 Albany::CismSTKMeshStruct::CismSTKMeshStruct(
00032 const Teuchos::RCP<Teuchos::ParameterList>& params,
00033 const Teuchos::RCP<const Epetra_Comm>& comm,
00034 const double * xyz_at_nodes_Ptr,
00035 const int * global_node_id_owned_map_Ptr,
00036 const int * global_element_id_active_owned_map_Ptr,
00037 const int * global_element_conn_active_Ptr,
00038 const int *global_basal_face_active_owned_map_Ptr,
00039 const int * global_basal_face_conn_active_Ptr,
00040 const double * beta_at_nodes_Ptr,
00041 const double * surf_height_at_nodes_Ptr,
00042 const double * flwa_at_active_elements_Ptr,
00043 const int nNodes, const int nElementsActive, const int nCellsActive) :
00044 GenericSTKMeshStruct(params,Teuchos::null,3),
00045 out(Teuchos::VerboseObjectBase::getDefaultOStream()),
00046 hasRestartSol(false),
00047 restartTime(0.0),
00048 periodic(false)
00049 {
00050 if (comm->MyPID() == 0) std::cout <<"In Albany::CismSTKMeshStruct - double * array inputs!" << std::endl;
00051 NumNodes = nNodes;
00052 NumEles = nElementsActive;
00053 NumBasalFaces = nCellsActive;
00054 std::cout <<"NumNodes = " << NumNodes << ", NumEles = "<< NumEles << ", NumBasalFaces = " << NumBasalFaces << std::endl;
00055 xyz = new double[NumNodes][3];
00056 eles = new int[NumEles][8];
00057 bf = new int[NumBasalFaces][5];
00058 sh = new double[NumNodes];
00059 globalNodesID = new int[NumNodes];
00060 globalElesID = new int[NumEles];
00061 basalFacesID = new int[NumBasalFaces];
00062 flwa = new double[NumEles];
00063 beta = new double[NumNodes];
00064
00065
00066
00067
00068 if (surf_height_at_nodes_Ptr != NULL) have_sh = true;
00069 else have_sh = false;
00070 if (global_basal_face_active_owned_map_Ptr != NULL) have_bf = true;
00071 else have_bf = false;
00072 if (flwa_at_active_elements_Ptr != NULL) have_flwa = true;
00073 else have_flwa = false;
00074 if (beta_at_nodes_Ptr != NULL) have_beta = true;
00075 else have_beta = false;
00076
00077 have_temp = false;
00078
00079 for (int i=0; i<NumNodes; i++){
00080 globalNodesID[i] = global_node_id_owned_map_Ptr[i]-1;
00081 for (int j=0; j<3; j++)
00082 xyz[i][j] = xyz_at_nodes_Ptr[i + NumNodes*j];
00083
00084 }
00085 if (have_sh) {
00086 for (int i=0; i<NumNodes; i++)
00087 sh[i] = surf_height_at_nodes_Ptr[i];
00088 }
00089 if (have_beta) {
00090 for (int i=0; i<NumNodes; i++)
00091 beta[i] = beta_at_nodes_Ptr[i];
00092 }
00093
00094 for (int i=0; i<NumEles; i++) {
00095 globalElesID[i] = global_element_id_active_owned_map_Ptr[i]-1;
00096 for (int j = 0; j<8; j++)
00097 eles[i][j] = global_element_conn_active_Ptr[i + nElementsActive*j];
00098
00099
00100 }
00101 if (have_flwa) {
00102 for (int i=0; i<NumEles; i++)
00103 flwa[i] = flwa_at_active_elements_Ptr[i];
00104 }
00105 if (have_bf) {
00106 for (int i=0; i<NumBasalFaces; i++) {
00107 basalFacesID[i] = global_basal_face_active_owned_map_Ptr[i]-1;
00108 for (int j=0; j<5; j++)
00109 bf[i][j] = global_basal_face_conn_active_Ptr[i + nCellsActive*j];
00110
00111 }
00112 }
00113
00114 elem_map = Teuchos::rcp(new Epetra_Map(-1, NumEles, globalElesID, 0, *comm));
00115 node_map = Teuchos::rcp(new Epetra_Map(-1, NumNodes, globalNodesID, 0, *comm));
00116 basal_face_map = Teuchos::rcp(new Epetra_Map(-1, NumBasalFaces, basalFacesID, 0, *comm));
00117
00118
00119 params->validateParameters(*getValidDiscretizationParameters(),0);
00120
00121
00122 std::string ebn="Element Block 0";
00123 partVec[0] = & metaData->declare_part(ebn, metaData->element_rank() );
00124 ebNameToIndex[ebn] = 0;
00125
00126 #ifdef ALBANY_SEACAS
00127 stk::io::put_io_part_attribute(*partVec[0]);
00128 #endif
00129
00130
00131 std::vector<std::string> nsNames;
00132 std::string nsn="Bottom";
00133 nsNames.push_back(nsn);
00134 nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
00135 #ifdef ALBANY_SEACAS
00136 stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00137 #endif
00138 nsn="NodeSet0";
00139 nsNames.push_back(nsn);
00140 nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
00141 #ifdef ALBANY_SEACAS
00142 stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00143 #endif
00144 nsn="NodeSet1";
00145 nsNames.push_back(nsn);
00146 nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
00147 #ifdef ALBANY_SEACAS
00148 stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00149 #endif
00150 nsn="NodeSet2";
00151 nsNames.push_back(nsn);
00152 nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
00153 #ifdef ALBANY_SEACAS
00154 stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00155 #endif
00156 nsn="NodeSet3";
00157 nsNames.push_back(nsn);
00158 nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
00159 #ifdef ALBANY_SEACAS
00160 stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00161 #endif
00162 nsn="NodeSet4";
00163 nsNames.push_back(nsn);
00164 nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
00165 #ifdef ALBANY_SEACAS
00166 stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00167 #endif
00168 nsn="NodeSet5";
00169 nsNames.push_back(nsn);
00170 nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
00171 #ifdef ALBANY_SEACAS
00172 stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00173 #endif
00174
00175
00176 std::vector<std::string> ssNames;
00177 std::string ssn="Basal";
00178 ssNames.push_back(ssn);
00179 ssPartVec[ssn] = & metaData->declare_part(ssn, metaData->side_rank() );
00180 #ifdef ALBANY_SEACAS
00181 stk::io::put_io_part_attribute(*ssPartVec[ssn]);
00182 #endif
00183
00184 stk::mesh::fem::set_cell_topology<shards::Hexahedron<8> >(*partVec[0]);
00185 stk::mesh::fem::set_cell_topology<shards::Quadrilateral<4> >(*ssPartVec[ssn]);
00186
00187 numDim = 3;
00188 int cub = params->get("Cubature Degree",3);
00189 int worksetSizeMax = params->get("Workset Size",50);
00190 int worksetSize = this->computeWorksetSize(worksetSizeMax, elem_map->NumMyElements());
00191
00192 const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[0]).getCellTopologyData();
00193
00194 this->meshSpecs[0] = Teuchos::rcp(new Albany::MeshSpecsStruct(ctd, numDim, cub,
00195 nsNames, ssNames, worksetSize, partVec[0]->name(),
00196 ebNameToIndex, this->interleavedOrdering));
00197
00198 }
00199
00200
00201 Albany::CismSTKMeshStruct::~CismSTKMeshStruct()
00202 {
00203 delete [] xyz;
00204 if (have_sh) delete [] sh;
00205 if (have_bf) delete [] bf;
00206 delete [] eles;
00207 delete [] globalElesID;
00208 delete [] globalNodesID;
00209 delete [] basalFacesID;
00210 }
00211
00212 void
00213 Albany::CismSTKMeshStruct::constructMesh(
00214 const Teuchos::RCP<const Epetra_Comm>& comm,
00215 const Teuchos::RCP<Teuchos::ParameterList>& params,
00216 const unsigned int neq_,
00217 const AbstractFieldContainer::FieldContainerRequirements& req,
00218 const Teuchos::RCP<Albany::StateInfoStruct>& sis,
00219 const unsigned int worksetSize)
00220 {
00221 this->SetupFieldData(comm, neq_, req, sis, worksetSize);
00222
00223 metaData->commit();
00224
00225 bulkData->modification_begin();
00226
00227 stk::mesh::PartVector nodePartVec;
00228 stk::mesh::PartVector singlePartVec(1);
00229 stk::mesh::PartVector emptyPartVec;
00230 std::cout << "elem_map # elements: " << elem_map->NumMyElements() << std::endl;
00231 std::cout << "node_map # elements: " << node_map->NumMyElements() << std::endl;
00232 unsigned int ebNo = 0;
00233 int sideID = 0;
00234
00235 AbstractSTKFieldContainer::VectorFieldType* coordinates_field = fieldContainer->getCoordinatesField();
00236 AbstractSTKFieldContainer::ScalarFieldType* surfaceHeight_field = fieldContainer->getSurfaceHeightField();
00237 AbstractSTKFieldContainer::ScalarFieldType* flowFactor_field = fieldContainer->getFlowFactorField();
00238 AbstractSTKFieldContainer::ScalarFieldType* temperature_field = fieldContainer->getTemperatureField();
00239 AbstractSTKFieldContainer::ScalarFieldType* basal_friction_field = fieldContainer->getBasalFrictionField();
00240
00241 if(!surfaceHeight_field)
00242 have_sh = false;
00243 if(!flowFactor_field)
00244 have_flwa = false;
00245 if(!temperature_field)
00246 have_temp = false;
00247 if(!basal_friction_field)
00248 have_beta = false;
00249
00250 for (int i=0; i<elem_map->NumMyElements(); i++) {
00251 const unsigned int elem_GID = elem_map->GID(i);
00252 stk::mesh::EntityId elem_id = (stk::mesh::EntityId) elem_GID;
00253 singlePartVec[0] = partVec[ebNo];
00254 stk::mesh::Entity& elem = bulkData->declare_entity(metaData->element_rank(), 1+elem_id, singlePartVec);
00255
00256 stk::mesh::Entity& llnode = bulkData->declare_entity(metaData->node_rank(), eles[i][0], nodePartVec);
00257 stk::mesh::Entity& lrnode = bulkData->declare_entity(metaData->node_rank(), eles[i][1], nodePartVec);
00258 stk::mesh::Entity& urnode = bulkData->declare_entity(metaData->node_rank(), eles[i][2], nodePartVec);
00259 stk::mesh::Entity& ulnode = bulkData->declare_entity(metaData->node_rank(), eles[i][3], nodePartVec);
00260 stk::mesh::Entity& llnodeb = bulkData->declare_entity(metaData->node_rank(), eles[i][4], nodePartVec);
00261 stk::mesh::Entity& lrnodeb = bulkData->declare_entity(metaData->node_rank(), eles[i][5], nodePartVec);
00262 stk::mesh::Entity& urnodeb = bulkData->declare_entity(metaData->node_rank(), eles[i][6], nodePartVec);
00263 stk::mesh::Entity& ulnodeb = bulkData->declare_entity(metaData->node_rank(), eles[i][7], nodePartVec);
00264 bulkData->declare_relation(elem, llnode, 0);
00265 bulkData->declare_relation(elem, lrnode, 1);
00266 bulkData->declare_relation(elem, urnode, 2);
00267 bulkData->declare_relation(elem, ulnode, 3);
00268 bulkData->declare_relation(elem, llnodeb, 4);
00269 bulkData->declare_relation(elem, lrnodeb, 5);
00270 bulkData->declare_relation(elem, urnodeb, 6);
00271 bulkData->declare_relation(elem, ulnodeb, 7);
00272
00273
00274 double* coord;
00275 int node_GID;
00276 unsigned int node_LID;
00277
00278 node_GID = eles[i][0]-1;
00279 node_LID = node_map->LID(node_GID);
00280 coord = stk::mesh::field_data(*coordinates_field, llnode);
00281 coord[0] = xyz[node_LID][0]; coord[1] = xyz[node_LID][1]; coord[2] = xyz[node_LID][2];
00282
00283 node_GID = eles[i][1]-1;
00284 node_LID = node_map->LID(node_GID);
00285 coord = stk::mesh::field_data(*coordinates_field, lrnode);
00286 coord[0] = xyz[node_LID][0]; coord[1] = xyz[node_LID][1]; coord[2] = xyz[node_LID][2];
00287
00288 node_GID = eles[i][2]-1;
00289 node_LID = node_map->LID(node_GID);
00290 coord = stk::mesh::field_data(*coordinates_field, urnode);
00291 coord[0] = xyz[node_LID][0]; coord[1] = xyz[node_LID][1]; coord[2] = xyz[node_LID][2];
00292
00293 node_GID = eles[i][3]-1;
00294 node_LID = node_map->LID(node_GID);
00295 coord = stk::mesh::field_data(*coordinates_field, ulnode);
00296 coord[0] = xyz[node_LID][0]; coord[1] = xyz[node_LID][1]; coord[2] = xyz[node_LID][2];
00297
00298 coord = stk::mesh::field_data(*coordinates_field, llnodeb);
00299 node_GID = eles[i][4]-1;
00300 node_LID = node_map->LID(node_GID);
00301 coord[0] = xyz[node_LID][0]; coord[1] = xyz[node_LID][1]; coord[2] = xyz[node_LID][2];
00302
00303 node_GID = eles[i][5]-1;
00304 node_LID = node_map->LID(node_GID);
00305 coord = stk::mesh::field_data(*coordinates_field, lrnodeb);
00306 coord[0] = xyz[node_LID][0]; coord[1] = xyz[node_LID][1]; coord[2] = xyz[node_LID][2];
00307
00308 coord = stk::mesh::field_data(*coordinates_field, urnodeb);
00309 node_GID = eles[i][6]-1;
00310 node_LID = node_map->LID(node_GID);
00311 coord[0] = xyz[node_LID][0]; coord[1] = xyz[node_LID][1]; coord[2] = xyz[node_LID][2];
00312
00313 coord = stk::mesh::field_data(*coordinates_field, ulnodeb);
00314 node_GID = eles[i][7]-1;
00315 node_LID = node_map->LID(node_GID);
00316 coord[0] = xyz[node_LID][0]; coord[1] = xyz[node_LID][1]; coord[2] = xyz[node_LID][2];
00317
00318 #ifdef ALBANY_FELIX
00319 if (have_sh) {
00320 double* sHeight;
00321 sHeight = stk::mesh::field_data(*surfaceHeight_field, llnode);
00322 node_GID = eles[i][0]-1;
00323 node_LID = node_map->LID(node_GID);
00324 sHeight[0] = sh[node_LID];
00325
00326 sHeight = stk::mesh::field_data(*surfaceHeight_field, lrnode);
00327 node_GID = eles[i][1]-1;
00328 node_LID = node_map->LID(node_GID);
00329 sHeight[0] = sh[node_LID];
00330
00331 sHeight = stk::mesh::field_data(*surfaceHeight_field, urnode);
00332 node_GID = eles[i][2]-1;
00333 node_LID = node_map->LID(node_GID);
00334 sHeight[0] = sh[node_LID];
00335
00336 sHeight = stk::mesh::field_data(*surfaceHeight_field, ulnode);
00337 node_GID = eles[i][3]-1;
00338 node_LID = node_map->LID(node_GID);
00339 sHeight[0] = sh[node_LID];
00340
00341 sHeight = stk::mesh::field_data(*surfaceHeight_field, llnodeb);
00342 node_GID = eles[i][4]-1;
00343 node_LID = node_map->LID(node_GID);
00344 sHeight[0] = sh[node_LID];
00345
00346 sHeight = stk::mesh::field_data(*surfaceHeight_field, lrnodeb);
00347 node_GID = eles[i][5]-1;
00348 node_LID = node_map->LID(node_GID);
00349 sHeight[0] = sh[node_LID];
00350
00351 sHeight = stk::mesh::field_data(*surfaceHeight_field, urnodeb);
00352 node_GID = eles[i][6]-1;
00353 node_LID = node_map->LID(node_GID);
00354 sHeight[0] = sh[node_LID];
00355
00356 sHeight = stk::mesh::field_data(*surfaceHeight_field, ulnodeb);
00357 node_GID = eles[i][7]-1;
00358 node_LID = node_map->LID(node_GID);
00359 sHeight[0] = sh[node_LID];
00360 }
00361 if (have_flwa) {
00362 double *flowFactor = stk::mesh::field_data(*flowFactor_field, elem);
00363
00364
00365 flowFactor[0] = flwa[i];
00366 }
00367 if (have_temp) {
00368 double *temperature = stk::mesh::field_data(*temperature_field, elem);
00369
00370
00371 temperature[0] = temper[i];
00372 }
00373 if (have_beta) {
00374 double* bFriction;
00375 bFriction = stk::mesh::field_data(*basal_friction_field, llnode);
00376 node_GID = eles[i][0]-1;
00377 node_LID = node_map->LID(node_GID);
00378 bFriction[0] = beta[node_LID];
00379
00380 bFriction = stk::mesh::field_data(*basal_friction_field, lrnode);
00381 node_GID = eles[i][1]-1;
00382 node_LID = node_map->LID(node_GID);
00383 bFriction[0] = beta[node_LID];
00384
00385 bFriction = stk::mesh::field_data(*basal_friction_field, urnode);
00386 node_GID = eles[i][2]-1;
00387 node_LID = node_map->LID(node_GID);
00388 bFriction[0] = beta[node_LID];
00389
00390 bFriction = stk::mesh::field_data(*basal_friction_field, ulnode);
00391 node_GID = eles[i][3]-1;
00392 node_LID = node_map->LID(node_GID);
00393 bFriction[0] = beta[node_LID];
00394
00395 bFriction = stk::mesh::field_data(*basal_friction_field, llnodeb);
00396 node_GID = eles[i][4]-1;
00397 node_LID = node_map->LID(node_GID);
00398 bFriction[0] = beta[node_LID];
00399
00400 bFriction = stk::mesh::field_data(*basal_friction_field, lrnodeb);
00401 node_GID = eles[i][5]-1;
00402 node_LID = node_map->LID(node_GID);
00403 bFriction[0] = beta[node_LID];
00404
00405 bFriction = stk::mesh::field_data(*basal_friction_field, urnodeb);
00406 node_GID = eles[i][6]-1;
00407 node_LID = node_map->LID(node_GID);
00408 bFriction[0] = beta[node_LID];
00409
00410 bFriction = stk::mesh::field_data(*basal_friction_field, ulnodeb);
00411 node_GID = eles[i][7]-1;
00412 node_LID = node_map->LID(node_GID);
00413 bFriction[0] = beta[node_LID];
00414 }
00415 #endif
00416
00417
00418 if (have_bf == false) {
00419 std::cout <<"No bf file specified... setting basal boundary to z=0 plane..." << std::endl;
00420 if ( xyz[eles[i][0]][2] == 0.0) {
00421
00422 singlePartVec[0] = ssPartVec["Basal"];
00423 stk::mesh::EntityId side_id = (stk::mesh::EntityId)(sideID);
00424 sideID++;
00425
00426 stk::mesh::Entity& side = bulkData->declare_entity(metaData->side_rank(), 1 + side_id, singlePartVec);
00427 bulkData->declare_relation(elem, side, 4 );
00428
00429 bulkData->declare_relation(side, llnode, 0);
00430 bulkData->declare_relation(side, ulnode, 3);
00431 bulkData->declare_relation(side, urnode, 2);
00432 bulkData->declare_relation(side, lrnode, 1);
00433 }
00434 }
00435 }
00436
00437 if (have_bf == true) {
00438 *out << "Setting basal surface connectivity from bf file provided..." << std::endl;
00439 for (int i=0; i<basal_face_map->NumMyElements(); i++) {
00440 singlePartVec[0] = ssPartVec["Basal"];
00441 sideID = basal_face_map->GID(i);
00442 stk::mesh::EntityId side_id = (stk::mesh::EntityId)(sideID);
00443 stk::mesh::Entity& side = bulkData->declare_entity(metaData->side_rank(),side_id+1, singlePartVec);
00444 const unsigned int elem_GID = bf[i][0];
00445 stk::mesh::EntityId elem_id = (stk::mesh::EntityId) elem_GID;
00446 stk::mesh::Entity& elem = bulkData->declare_entity(metaData->element_rank(), elem_id, emptyPartVec);
00447 bulkData->declare_relation(elem, side, 4 );
00448 stk::mesh::Entity& llnode = bulkData->declare_entity(metaData->node_rank(), bf[i][1], nodePartVec);
00449 stk::mesh::Entity& lrnode = bulkData->declare_entity(metaData->node_rank(), bf[i][2], nodePartVec);
00450 stk::mesh::Entity& urnode = bulkData->declare_entity(metaData->node_rank(), bf[i][3], nodePartVec);
00451 stk::mesh::Entity& ulnode = bulkData->declare_entity(metaData->node_rank(), bf[i][4], nodePartVec);
00452
00453 bulkData->declare_relation(side, llnode, 0);
00454 bulkData->declare_relation(side, ulnode, 3);
00455 bulkData->declare_relation(side, urnode, 2);
00456 bulkData->declare_relation(side, lrnode, 1);
00457 }
00458 }
00459 bulkData->modification_end();
00460 }
00461
00462 Teuchos::RCP<const Teuchos::ParameterList>
00463 Albany::CismSTKMeshStruct::getValidDiscretizationParameters() const
00464 {
00465 Teuchos::RCP<Teuchos::ParameterList> validPL =
00466 this->getValidGenericSTKParameters("Valid ASCII_DiscParams");
00467
00468 return validPL;
00469 }