00001
00002
00003
00004
00005
00006
00007 #include <iostream>
00008
00009 #include "Albany_AsciiSTKMesh2D.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 #include <boost/algorithm/string/predicate.hpp>
00026
00027 #include "Albany_Utils.hpp"
00028
00029 Albany::AsciiSTKMesh2D::AsciiSTKMesh2D(
00030 const Teuchos::RCP<Teuchos::ParameterList>& params,
00031 const Teuchos::RCP<const Epetra_Comm>& comm) :
00032 GenericSTKMeshStruct(params, Teuchos::null, 2), out(
00033 Teuchos::VerboseObjectBase::getDefaultOStream()), periodic(false), sh(0) {
00034 std::string fname = params->get("Ascii Input Mesh File Name",
00035 "greenland.msh");
00036
00037 std::string shape;
00038 if (comm->MyPID() == 0) {
00039 std::ifstream ifile;
00040
00041 NumElemNodes = 0;
00042 ifile.open(fname.c_str());
00043 if (ifile.is_open()) {
00044 ifile >> shape >> NumElemNodes;
00045 if(shape == "Triangle") {
00046 TEUCHOS_TEST_FOR_EXCEPTION(NumElemNodes != 3, Teuchos::Exceptions::InvalidParameter,
00047 std::endl << "Error in AsciiSTKMesh2D: Triangles must be linear. Number of nodes per element in file " << fname << " is: " << NumElemNodes << ". Should be 3!" << std::endl);
00048 }
00049 else if(shape == "Quadrilateral") {
00050 TEUCHOS_TEST_FOR_EXCEPTION(NumElemNodes != 4, Teuchos::Exceptions::InvalidParameter,
00051 std::endl << "Error in AsciiSTKMesh2D: Quadrilaterals must be bilinear. Number of nodes per element in file " << fname << " is: " << " is: " << NumElemNodes << ". Should be 4!" << std::endl);
00052 }
00053 else
00054 TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00055 std::endl << "Error in AsciiSTKMesh2D: Only Triangle or Quadrilateral grids can be imported. Shape in in file " << fname << " is: " << shape << ". Should be Triangle or Quadrialteral" << std::endl);
00056
00057
00058 ifile >> NumNodes >> NumEles >> NumBdEdges;
00059
00060 xyz = new double[NumNodes][3];
00061 for (int i = 0; i < NumNodes; i++) {
00062 ifile >> xyz[i][0] >> xyz[i][1] >> xyz[i][2];
00063 }
00064
00065
00066 eles = new int[NumEles][4];
00067 int temp;
00068
00069 if(shape == "Triangle")
00070 for (int i = 0; i < NumEles; i++) {
00071 ifile >> eles[i][0] >> eles[i][1] >> eles[i][2] >> temp;
00072 }
00073 else
00074 for (int i = 0; i < NumEles; i++) {
00075 ifile >> eles[i][0] >> eles[i][1] >> eles[i][2] >> eles[i][3] >> temp;
00076 }
00077
00078
00079 be = new int[NumBdEdges][2];
00080 for (int i = 0; i < NumBdEdges; i++) {
00081 ifile >> be[i][0] >> be[i][1] >> temp;
00082 }
00083 ifile.close();
00084 } else {
00085 TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00086 std::endl << "Error in AsciiSTKMesh2D: Input Mesh File " << fname << " not found!"<< std::endl);
00087 }
00088 }
00089
00090 comm->Broadcast(&NumElemNodes, 1, 0);
00091
00092 params->validateParameters(*getValidDiscretizationParameters(), 0);
00093
00094 std::string ebn = "Element Block 0";
00095 partVec[0] = &metaData->declare_part(ebn, metaData->element_rank());
00096 ebNameToIndex[ebn] = 0;
00097
00098 #ifdef ALBANY_SEACAS
00099
00100 stk::io::put_io_part_attribute(*partVec[0]);
00101 #endif
00102
00103 std::vector < std::string > nsNames;
00104 std::string nsn = "Node";
00105 nsNames.push_back(nsn);
00106 nsPartVec[nsn] = &metaData->declare_part(nsn, metaData->node_rank());
00107 #ifdef ALBANY_SEACAS
00108 stk::io::put_io_part_attribute(*nsPartVec[nsn]);
00109 #endif
00110
00111 std::vector < std::string > ssNames;
00112 std::string ssn = "LateralSide";
00113 ssNames.push_back(ssn);
00114 ssPartVec[ssn] = &metaData->declare_part(ssn, metaData->side_rank());
00115 #ifdef ALBANY_SEACAS
00116 stk::io::put_io_part_attribute(*ssPartVec[ssn]);
00117 stk::io::put_io_part_attribute(metaData->universal_part());
00118 #endif
00119
00120 if(NumElemNodes == 3)
00121 stk::mesh::fem::set_cell_topology<shards::Triangle<3> >(*partVec[0]);
00122 else
00123 stk::mesh::fem::set_cell_topology<shards::Quadrilateral<4> >(*partVec[0]);
00124
00125 stk::mesh::fem::set_cell_topology<shards::Line<2> >(*ssPartVec[ssn]);
00126 numDim = 2;
00127 int cub = params->get("Cubature Degree", 3);
00128 int worksetSizeMax = params->get("Workset Size", 50);
00129 int worksetSize = this->computeWorksetSize(worksetSizeMax, NumEles);
00130 *out << __LINE__ << std::endl;
00131 const CellTopologyData& ctd =
00132 *metaData->get_cell_topology(*partVec[0]).getCellTopologyData();
00133 cullSubsetParts(ssNames, ssPartVec);
00134 this->meshSpecs[0] = Teuchos::rcp(
00135 new Albany::MeshSpecsStruct(ctd, numDim, cub, nsNames, ssNames,
00136 worksetSize, partVec[0]->name(), ebNameToIndex,
00137 this->interleavedOrdering));
00138 std::cout << "Spatial dim: " << metaData->spatial_dimension() << std::endl;
00139 }
00140
00141 Albany::AsciiSTKMesh2D::~AsciiSTKMesh2D() {
00142 delete[] xyz;
00143 delete[] be;
00144 delete[] eles;
00145 }
00146
00147 void Albany::AsciiSTKMesh2D::setFieldAndBulkData(
00148 const Teuchos::RCP<const Epetra_Comm>& comm,
00149 const Teuchos::RCP<Teuchos::ParameterList>& params, const unsigned int neq_,
00150 const AbstractFieldContainer::FieldContainerRequirements& req,
00151 const Teuchos::RCP<Albany::StateInfoStruct>& sis,
00152 const unsigned int worksetSize) {
00153 this->SetupFieldData(comm, neq_, req, sis, worksetSize);
00154
00155 metaData->commit();
00156
00157 bulkData->modification_begin();
00158
00159 stk::mesh::PartVector nodePartVec;
00160 stk::mesh::PartVector singlePartVec(1);
00161 std::cout << "elem_map # elments: " << NumEles << std::endl;
00162 unsigned int ebNo = 0;
00163 int sideID = 0;
00164
00165 AbstractSTKFieldContainer::IntScalarFieldType* proc_rank_field =
00166 fieldContainer->getProcRankField();
00167 AbstractSTKFieldContainer::VectorFieldType* coordinates_field =
00168 fieldContainer->getCoordinatesField();
00169
00170 singlePartVec[0] = nsPartVec["Node"];
00171
00172 for (int i = 0; i < NumNodes; i++) {
00173 stk::mesh::Entity& node = bulkData->declare_entity(metaData->node_rank(),
00174 i + 1, singlePartVec);
00175
00176 double* coord;
00177 coord = stk::mesh::field_data(*coordinates_field, node);
00178 coord[0] = xyz[i][0];
00179 coord[1] = xyz[i][1];
00180 coord[2] = 0.;
00181 }
00182
00183 for (int i = 0; i < NumEles; i++) {
00184
00185 singlePartVec[0] = partVec[ebNo];
00186 stk::mesh::Entity& elem = bulkData->declare_entity(metaData->element_rank(),
00187 i + 1, singlePartVec);
00188
00189 for (int j = 0; j < NumElemNodes; j++) {
00190 stk::mesh::Entity& node = *bulkData->get_entity(metaData->node_rank(),
00191 eles[i][j]);
00192 bulkData->declare_relation(elem, node, j);
00193 }
00194
00195
00196
00197 }
00198
00199 std::map<std::pair<int, int>, int> edgeMap;
00200 for (int i = 0; i < NumBdEdges; i++)
00201 edgeMap.insert(
00202 std::pair<std::pair<int, int>, int>(std::make_pair(be[i][0], be[i][1]),
00203 i + 1));
00204
00205 singlePartVec[0] = ssPartVec["LateralSide"];
00206 for (int i = 0; i < NumEles; i++) {
00207 for (int j = 0; j < NumElemNodes; j++) {
00208 std::map<std::pair<int, int>, int>::iterator it = edgeMap.find(
00209 std::make_pair(eles[i][j], eles[i][(j + 1) % NumElemNodes]));
00210 if (it != edgeMap.end()) {
00211 stk::mesh::Entity& side = bulkData->declare_entity(
00212 metaData->side_rank(), it->second, singlePartVec);
00213 stk::mesh::Entity& elem = *bulkData->get_entity(
00214 metaData->element_rank(), i + 1);
00215 bulkData->declare_relation(elem, side, j );
00216 stk::mesh::PairIterRelation rel_elemNodes = elem.relations(metaData->node_rank());
00217 for (int k = 0; k < 2; k++) {
00218 stk::mesh::Entity& node = *rel_elemNodes[this->meshSpecs[0]->ctd.side[j].node[k]].entity();
00219 bulkData->declare_relation(side, node, k);
00220 }
00221 edgeMap.erase(it);
00222 }
00223 }
00224 }
00225
00226 bulkData->modification_end();
00227
00228 #ifdef ALBANY_ZOLTAN
00229
00230
00231
00232
00233
00234
00235
00236 #endif
00237
00238 }
00239
00240 Teuchos::RCP<const Teuchos::ParameterList> Albany::AsciiSTKMesh2D::getValidDiscretizationParameters() const {
00241 Teuchos::RCP<Teuchos::ParameterList> validPL =
00242 this->getValidGenericSTKParameters("Valid ASCII_DiscParams");
00243 validPL->set<std::string>("Ascii Input Mesh File Name", "greenland.msh",
00244 "Name of the file containing the 2D mesh, with list of coordinates, elements' connectivity and boundary edges' connectivity");
00245
00246 return validPL;
00247 }