bool AdvData::Open(const std::string &filename) { const char *mName = "AdvData::Open: "; ReleaseData(); // If the file is an ".inp" file then we may have more than 1 domain file. if(filename.size() >= 3 && filename.substr(filename.size()-3, filename.size()) == "inp") { // Open the file. ifstream ifile(filename.c_str()); if (ifile.fail()) { return false; } // Process the .inp file char line[1024]; ifile.getline(line, 1024); int nDomains = 0; int tmp[4]; if(sscanf(line, "%d %d %d %d", &tmp[0], &tmp[1], &tmp[2], &tmp[3]) == 4) { // This is not a .inp file. Assume it is PATRAN and skip it. EXCEPTION1(InvalidDBTypeException, "This is not an Adventure \".inp\" file"); } if(sscanf(line, "%d", &nDomains) != 1) { // This is not a .inp file EXCEPTION1(InvalidDBTypeException, "This is not an Adventure \".inp\" file"); } domainRecords.reserve(nDomains); for(int i = 0; i < nDomains; ++i) { AdvDataSet domain; ifile.getline(line, 1024); domain.modelFile = FixupPath(filename, line); ifile.getline(line, 1024); domain.resultFile = FixupPath(filename, line); debug4 << "Domain " << i << endl; debug4 << "\tmodelFile=" << domain.modelFile << endl; debug4 << "\tresultFile=" << domain.resultFile << endl; domainRecords.push_back(domain); } ifile.close(); } else { AdvDataSet domain; domain.modelFile = filename; domainRecords.push_back(domain); } // Now that we have a set of model and result files, open each of the // model files and determine how many subdomains are in them. int domainID = 0; for(size_t i = 0; i < domainRecords.size(); ++i) { AdvDocFile *f = adv_dio_file_open(domainRecords[i].modelFile.c_str(), "r"); if(f == 0) { debug4 << mName << "Could not open " << domainRecords[i].modelFile << " to determine its domain count." << endl; EXCEPTION1(InvalidDBTypeException, "Could not open Adventure file"); } AdvDocument *doc = adv_dio_open_by_property(f, 0, "label", "HDDM_FEA_Model", 0); if(doc == 0) { debug4 << mName << "Could not get HDDM_FEA_Model" << endl; EXCEPTION1(InvalidDBTypeException, "Adventure file missing HDDM_FEA_Model"); } #ifdef TREAT_SUBDOMAINS_INDIVIDUALLY // We're not currently doing this but if we were, we'd need to change how // we read data in AdvDataSet. int nSubDomains = 0; if(!adv_dio_get_property_int32(doc, "num_subdomains", &nSubDomains)) { debug4 << mName << "Could not get num_subdomains" << endl; EXCEPTION1(InvalidDBTypeException, "Adventure file missing " "num_subdomains property"); } for(int s = 0; s < nSubDomains; ++s) { domainToRecord[domainID] = i; domainRecords[i].SetDomainToSubDomain(domainID, s); domainID++; } #else // Treat all subdomains as one domain domainToRecord[domainID] = i; domainRecords[i].SetDomainToSubDomain(domainID, 0); domainID++; #endif adv_dio_close(doc); adv_dio_file_close(f); } // Read the file metadata. AdvDocFile *f = OpenFile(domainRecords[0].modelFile); if(f != 0) { ReadMetaDataFromFile(f, modelVars, elementType); f = OpenFile(domainRecords[0].resultFile); if(f != 0) { AdvDataSet::AdvElementType et; ReadMetaDataFromFile(f, resultVars, et); } } return true; }
vtkDataSet * AdvDataSet::GetMesh(AdvDocFile *f, int d, AdvDataSet::AdvElementType elementType) { const char *mName = "AdvDataSet::GetMesh: "; AdvDocument *doc = 0; // ************************************************************************ // Read nodes // ************************************************************************ if ( (doc = adv_dio_open_by_property(f, 0, "content_type", "Node", 0)) == 0) { debug5 << mName << "No content_type[Node]" << endl; return 0; } this->nnodes = 0; if ( !adv_dio_get_property_int32(doc, "num_items", &this->nnodes)) { debug4 << mName << "No property num_items" << endl; return 0; } debug4 << mName << "There are " << this->nnodes << " nodes. " << endl; vtkPoints *points = vtkPoints::New(); points->SetDataTypeToDouble(); points->SetNumberOfPoints(this->nnodes); double *pts = (double *) points->GetVoidPointer(0); adv_off_t offset = 0; for(int i = 0; i < this->nnodes; ++i) { offset += adv_dio_read_float64(doc, offset, pts); offset += adv_dio_read_float64(doc, offset, pts+1); offset += adv_dio_read_float64(doc, offset, pts+2); pts += 3; } adv_dio_close(doc); // ************************************************************************ // Read connectivity // ************************************************************************ AdvDocument *nodeIndexDoc = 0; if ((nodeIndexDoc = adv_dio_open_by_property(f, 0, "content_type", "HDDM_FEGenericAttribute", "label", "NodeIndex_SubdomainToPart", 0)) == 0) { points->Delete(); return 0; } if ((doc = adv_dio_open_by_property(f, 0, "content_type", "HDDM_Element", 0)) == 0) { points->Delete(); debug4 << mName << "No content_type[HDDM_Element]" << endl; return 0; } int num_subdomains = 0; if (!adv_dio_get_property_int32(doc, "num_subdomains", &num_subdomains)) { points->Delete(); debug4 << "No property num_subdomains" << endl; return 0; } int num_nodes_per_element = 0; if (!adv_dio_get_property_int32(doc, "num_nodes_per_element", &num_nodes_per_element)) { points->Delete(); debug4 << "No property num_nodes_per_element" << endl; return 0; } this->ncells = 0; if (!adv_dio_get_property_int32(doc, "sum_items", &this->ncells)) { points->Delete(); debug4 << "No property num_nodes_per_element" << endl; return 0; } debug4 << mName << "ncells = " << this->ncells << endl; vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::New(); ugrid->SetPoints(points); points->Delete(); ugrid->Allocate(this->ncells); vtkIdType verts[10]; offset = 0; adv_off_t nodeOffset = 0; for (int nd = 0; nd < num_subdomains; nd++) { // Read the mapping of subdomain nodeids to part nodeids. int nnode = 0; nodeOffset += adv_dio_read_int32(nodeIndexDoc, nodeOffset, &nnode); int *subDomainNodeID2PartNodeID = new int[nnode]; // debug4 << "Subdomain " << nd << " nodeid to part nodeid mapping." << endl; for (int i = 0; i < nnode; i++) { nodeOffset += adv_dio_read_int32(nodeIndexDoc, nodeOffset, &subDomainNodeID2PartNodeID[i]); // debug4 << i << " -> " << subDomainNodeID2PartNodeID[i] << endl; } // This is the number of cells in the sub_domain but we can // skip over it since we're grouping subdomains for now. int element_num_items = 0; offset += adv_dio_read_int32(doc, offset, &element_num_items); // Read the nodeids for the cell and add the cell to the ugrid. debug4 << "Subdomain " << nd << " has " << element_num_items << " cells" << endl; for (int i = 0; i < element_num_items; i++) { // debug4 << " cell " << i << " ("; for (int j = 0; j < num_nodes_per_element; j++) { int tmp; offset += adv_dio_read_int32(doc, offset, &tmp); verts[j] = subDomainNodeID2PartNodeID[tmp]; // debug4 << " " << verts[j]; } // debug4 << ")\n"; if(elementType == ADVENTURE_ELEMENT_TET4) ugrid->InsertNextCell(VTK_TETRA, 4, verts); else if(elementType == ADVENTURE_ELEMENT_TET10) { // Reorder the connectivity since Adv and VTK use different node ordering. vtkIdType conn[10]; conn[0] = verts[0]; conn[1] = verts[1]; conn[2] = verts[2]; conn[3] = verts[3]; conn[4] = verts[4]; conn[5] = verts[7]; conn[6] = verts[5]; conn[7] = verts[6]; conn[8] = verts[9]; conn[9] = verts[8]; ugrid->InsertNextCell(VTK_QUADRATIC_TETRA, 10, conn); } else if(elementType == ADVENTURE_ELEMENT_HEX8) { // NOTE: There could be vertex ordering issues here. I need test data. ugrid->InsertNextCell(VTK_HEXAHEDRON, 8, verts); } } delete [] subDomainNodeID2PartNodeID; } adv_dio_close(nodeIndexDoc); adv_dio_close(doc); // Add global node ids if they are available. AddGlobalNodeIds(ugrid, f); return ugrid; }