00001
00002
00003
00004
00005
00006
00007 #include "Albany_Catalyst_Grid.hpp"
00008
00009 #include "Shards_BasicTopologies.hpp"
00010
00011 #include "Teuchos_VerboseObject.hpp"
00012 #include "Teuchos_TestForException.hpp"
00013
00014 #include <vtkIdTypeArray.h>
00015
00016 #include <cassert>
00017 #include <string>
00018 #include <vector>
00019
00020 using Teuchos::RCP;
00021 using Teuchos::ArrayRCP;
00022
00023 namespace Albany {
00024 namespace Catalyst {
00025
00026 vtkStandardNewMacro(Grid)
00027 vtkStandardNewMacro(GridImplementation)
00028
00029 GridImplementation::GridImplementation()
00030 : Discretization(NULL),
00031 DegreesOfFreedom(0),
00032 ElementsWsLid(NULL),
00033 ElementOffset(0)
00034 {
00035 }
00036
00037 GridImplementation::~GridImplementation()
00038 {
00039 }
00040
00041 void GridImplementation::PrintSelf(ostream &os, vtkIndent indent)
00042 {
00043 this->Superclass::PrintSelf(os, indent);
00044 }
00045
00046 bool GridImplementation::SetDecorator(Decorator *decorator)
00047 {
00048 this->Discretization = decorator;
00049 this->DegreesOfFreedom = decorator->getNumEq();
00050 this->NodeLookup = decorator->getWsElNodeEqID();
00051
00052 this->ElementsWsLid = &decorator->getElemGIDws();
00053
00054
00055 if (this->ElementsWsLid->size() > 0) {
00056 WsLIDList::const_iterator first = this->ElementsWsLid->begin();
00057 this->ElementOffset = first->first;
00058 }
00059 else {
00060 this->ElementOffset = 0;
00061 }
00062
00063
00064 typedef ArrayRCP<RCP<Albany::MeshSpecsStruct> > MeshSpecsT;
00065 typedef MeshSpecsT::const_iterator MeshSpecsIter;
00066 const MeshSpecsT &meshSpecs(decorator->getMeshStruct()->getMeshSpecs());
00067
00068 typedef ArrayRCP<std::string> RCPStringsT;
00069 const RCPStringsT &ebNames(decorator->getWsEBNames());
00070
00071 this->CellTypeLookup.resize(ebNames.size(), VTK_EMPTY_CELL);
00072
00073 for (size_t wsId = 0; wsId < ebNames.size(); ++wsId) {
00074 const std::string &elName(ebNames[wsId]);
00075 for (MeshSpecsIter it = meshSpecs.begin(), itEnd = meshSpecs.end();
00076 it != itEnd; ++it) {
00077 if ((*it)->ebName == elName) {
00078 this->CellTypeLookup[wsId] = TopologyToCellType(&(*it)->ctd);
00079 break;
00080 }
00081 }
00082 TEUCHOS_TEST_FOR_EXCEPTION(this->CellTypeLookup[wsId] == VTK_EMPTY_CELL,
00083 std::runtime_error,
00084 "No CellTopologyData instance found for element "
00085 "block " << elName);
00086 }
00087
00088 return true;
00089 }
00090
00091 vtkIdType GridImplementation::GetNumberOfCells()
00092 {
00093 return static_cast<vtkIdType>(this->ElementsWsLid->size());
00094 }
00095
00096 int GridImplementation::GetCellType(vtkIdType cellId)
00097 {
00098 int ws = -1;
00099 int unused = -1;
00100 this->GetWorksetFromCellId(cellId, ws, unused);
00101 return this->GetCellTypeFromWorkset(ws);
00102 }
00103
00104 void GridImplementation::GetCellPoints(vtkIdType cellId, vtkIdList *ptIds)
00105 {
00106 int ws = -1;
00107 int lid = -1;
00108 this->GetWorksetFromCellId(cellId, ws, lid);
00109 typedef Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> > NodesType;
00110 const NodesType &nodes = this->NodeLookup[ws][lid];
00111 vtkIdType cellSize = static_cast<vtkIdType>(nodes.size());
00112 ptIds->SetNumberOfIds(cellSize);
00113
00114 NodesType::const_iterator nodesIter = nodes.begin();
00115 vtkIdType *ptIdIter = ptIds->GetPointer(0);
00116
00117 while ((cellSize--) > 0) {
00118 *(ptIdIter++) =
00119 static_cast<vtkIdType>(*(nodesIter++)[0] / this->DegreesOfFreedom);
00120 }
00121
00122
00123
00124 if (this->GetCellTypeFromWorkset(ws) == VTK_WEDGE) {
00125 using namespace std;
00126 vtkIdType *pts = ptIds->GetPointer(0);
00127 swap(pts[0], pts[1]);
00128 swap(pts[3], pts[4]);
00129 }
00130 }
00131
00132 namespace {
00133
00134 struct WsLidMatcher {
00135 wsLid needle;
00136 WsLidMatcher() { needle.ws = 0; needle.LID = 0; }
00137 bool operator()(const WsLIDList::value_type &val) const
00138 {
00139 return (val.second.ws == needle.ws && val.second.LID== needle.LID);
00140 }
00141 };
00142 }
00143
00144 void GridImplementation::GetPointCells(vtkIdType ptId, vtkIdList *cellIds)
00145 {
00146
00147 using Teuchos::ArrayRCP;
00148 typedef ArrayRCP<ArrayRCP<int> > NodeLevel;
00149 typedef ArrayRCP<NodeLevel> LidLevel;
00150
00151 cellIds->Reset();
00152
00153
00154 WsLidMatcher matcher;
00155 int &ws = matcher.needle.ws;
00156 int &lid = matcher.needle.LID;
00157
00158
00159 WsLIDList::const_iterator haystackBegin = this->ElementsWsLid->begin();
00160 WsLIDList::const_iterator haystackEnd = this->ElementsWsLid->end();
00161 WsLIDList::const_iterator result;
00162
00163
00164 for (ws = 0; ws < this->NodeLookup.size(); ++ws) {
00165 const LidLevel &lids(this->NodeLookup[ws]);
00166 for (lid = 0; lid < lids.size(); ++lid) {
00167 const NodeLevel &nodes(lids[lid]);
00168 for (int node = 0; node < nodes.size(); ++node) {
00169 if (static_cast<vtkIdType>(nodes[node][0] / this->DegreesOfFreedom)
00170 == ptId) {
00171 result = std::find_if(haystackBegin, haystackEnd, matcher);
00172 if (result != haystackEnd)
00173 cellIds->InsertNextId(static_cast<vtkIdType>(result->first));
00174 }
00175 }
00176 }
00177 }
00178 }
00179
00180 int GridImplementation::GetMaxCellSize()
00181 {
00182 int size = 0;
00183 for (std::vector<VTKCellType>::const_iterator it = CellTypeLookup.begin(),
00184 itEnd = CellTypeLookup.end(); it != itEnd; ++it)
00185 size = std::max(size, static_cast<int>(GetCellSize(*it)));
00186 return size;
00187 }
00188
00189 void GridImplementation::GetIdsOfCellsOfType(int type, vtkIdTypeArray *array)
00190 {
00191
00192
00193
00194
00195
00196 std::vector<int> worksets;
00197 {
00198 typedef std::vector<VTKCellType>::const_iterator TypeIterT;
00199 TypeIterT begin(this->CellTypeLookup.begin());
00200 TypeIterT end = this->CellTypeLookup.end();
00201 TypeIterT typeIter = begin;
00202 while (typeIter != end) {
00203 if (*typeIter == static_cast<VTKCellType>(type))
00204 worksets.push_back(typeIter - begin);
00205 ++typeIter;
00206 }
00207 }
00208
00209
00210 array->SetNumberOfComponents(1);
00211 array->Allocate(static_cast<vtkIdType>(50 * worksets.size()));
00212
00213
00214 {
00215 WsLIDList::const_iterator iter = this->ElementsWsLid->begin();
00216 WsLIDList::const_iterator end = this->ElementsWsLid->end();
00217
00218 typedef std::vector<int>::iterator WsIterT;
00219 WsIterT wsBegin = worksets.begin();
00220 WsIterT wsEnd = worksets.end();
00221
00222 std::sort(wsBegin, wsEnd);
00223
00224 while (iter != end) {
00225 if (std::binary_search(wsBegin, wsEnd, iter->second.ws))
00226 array->InsertNextValue(static_cast<vtkIdType>(iter->second.ws));
00227 }
00228 }
00229 }
00230
00231 int GridImplementation::IsHomogeneous()
00232 {
00233 if (!this->CellTypeLookup.empty()) {
00234 typedef std::vector<VTKCellType>::const_iterator CTIterT;
00235 CTIterT begin = this->CellTypeLookup.begin();
00236 CTIterT end = this->CellTypeLookup.end();
00237 VTKCellType type = *(begin++);
00238 while (begin != end) {
00239 if (*(begin++) != type)
00240 return false;
00241 }
00242 }
00243 return true;
00244 }
00245
00246 void GridImplementation::Allocate(vtkIdType, int)
00247 {
00248 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00249 "Read-only container.");
00250 }
00251
00252 vtkIdType GridImplementation::InsertNextCell(int, vtkIdList*)
00253 {
00254 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00255 "Read-only container.");
00256 return -1;
00257 }
00258
00259 vtkIdType GridImplementation::InsertNextCell(int, vtkIdType, vtkIdType*)
00260 {
00261 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00262 "Read-only container.");
00263 return -1;
00264 }
00265
00266 vtkIdType GridImplementation::InsertNextCell(int, vtkIdType, vtkIdType*,
00267 vtkIdType, vtkIdType*)
00268 {
00269 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00270 "Read-only container.");
00271 return -1;
00272 }
00273
00274 void GridImplementation::ReplaceCell(vtkIdType cellId, int npts, vtkIdType *pts)
00275 {
00276 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00277 "Read-only container.");
00278 }
00279
00280 inline VTKCellType GridImplementation::TopologyToCellType(const CellTopologyData *ctd)
00281 {
00285 switch (ctd->key) {
00286 default:
00287 *Teuchos::VerboseObjectBase::getDefaultOStream()
00288 << "Unrecognized key for CellTopologyData name '" << ctd->name << "'.";
00289 return VTK_EMPTY_CELL;
00290 case shards::Particle::key:
00291 return VTK_VERTEX;
00292 case shards::Line<2>::key:
00293 return VTK_LINE;
00294 case shards::Triangle<3>::key:
00295 return VTK_TRIANGLE;
00296 case shards::Quadrilateral<4>::key:
00297 return VTK_QUAD;
00298 case shards::Tetrahedron<4>::key:
00299 return VTK_TETRA;
00300 case shards::Hexahedron<8>::key:
00301 return VTK_HEXAHEDRON;
00302 case shards::Wedge<6>::key:
00303 return VTK_WEDGE;
00304 case shards::Pyramid<5>::key:
00305 return VTK_PYRAMID;
00306 }
00307 }
00308
00309 inline vtkIdType GridImplementation::GetCellSize(VTKCellType cellType)
00310 {
00311 switch (cellType) {
00312 case VTK_TRIANGLE:
00313 return 3;
00314 case VTK_QUAD:
00315 return 4;
00316 case VTK_LINE:
00317 return 2;
00318 case VTK_TETRA:
00319 return 4;
00320 case VTK_VERTEX:
00321 return 1;
00322 case VTK_HEXAHEDRON:
00323 return 8;
00324 case VTK_WEDGE:
00325 return 6;
00326 case VTK_PYRAMID:
00327 return 5;
00328 default:
00329 *Teuchos::VerboseObjectBase::getDefaultOStream()
00330 << "Unhandled cell type: " << cellType;
00331 case VTK_EMPTY_CELL:
00332 return 0;
00333 }
00334 }
00335
00336 inline void GridImplementation::GetWorksetFromCellId(vtkIdType cellId,
00337 int &ws, int &lid)
00338 {
00339 WsLIDList::const_iterator match =
00340 this->ElementsWsLid->find(static_cast<int>(cellId) + this->ElementOffset);
00341 if (match != this->ElementsWsLid->end()) {
00342 const wsLid &result = match->second;
00343 ws = result.ws;
00344 lid = result.LID;
00345 }
00346 else {
00347 ws = -1;
00348 lid = -1;
00349 }
00350 }
00351
00352 VTKCellType GridImplementation::GetCellTypeFromWorkset(int ws)
00353 {
00354 return (ws >= 0 && ws < this->CellTypeLookup.size())
00355 ? this->CellTypeLookup[ws] : VTK_EMPTY_CELL;
00356 }
00357
00358 }
00359 }