void AdvDataSet::AddGlobalNodeIds(vtkDataSet *ds, AdvDocFile *f) { AdvDocument *doc = 0; if ((doc = adv_dio_open_by_property(f, 0, "content_type", "FEGenericAttribute", "label", "NodeIndex_PartToGlobal", 0)) != 0) { const char *format = adv_dio_get_property(doc, "format"); if(format != 0 && strcmp(format, "i4") == 0) { vtkIntArray *arr = vtkIntArray::New(); arr->SetNumberOfTuples(nnodes); arr->SetName("avtGlobalNodeId"); int *ptr = (int *)arr->GetVoidPointer(0); adv_off_t offset = 0; for(int i = 0; i < nnodes; i++, ptr++) offset += adv_dio_read_int32(doc, offset, ptr); ds->GetPointData()->AddArray(arr); debug5 << "Added global node ids to mesh" << endl; } adv_dio_close(doc); } }
void AdvData::ReadMetaDataFromFile(AdvDocFile *f, AdvDataSet::VarInfoVector &vars, AdvDataSet::AdvElementType &elementType) { // Now, let's iterate over the documents and add ones that look like variables. AdvDocument *doc = 0; int i = 0; while( (doc = adv_dio_open_nth(f, i++)) != 0) { const char *content_type = adv_dio_get_property(doc, "content_type"); if(content_type != 0) { if(strcmp(content_type, "FEGenericAttribute") == 0 || strcmp(content_type, "HDDM_FEGenericAttribute") == 0) { const char *fega_type = adv_dio_get_property(doc, "fega_type"); const char *label = adv_dio_get_property(doc, "label"); const char *format = adv_dio_get_property(doc, "format"); if(fega_type != 0 && label != 0 && format != 0) { AdvDataSet::VarInfo v; v.label = label; v.fega_type = fega_type; v.format = format; vars.push_back(v); } } else if(strcmp(content_type, "HDDM_Element") == 0) { const char *element_type = adv_dio_get_property(doc, "element_type"); if(element_type != 0) { if(strcmp("3DLinearTetrahedron", element_type) == 0 ) elementType = AdvDataSet::ADVENTURE_ELEMENT_TET4; else if ( strcmp("3DQuadraticTetrahedron", element_type) == 0 ) elementType = AdvDataSet::ADVENTURE_ELEMENT_TET10; else if ( strcmp("3DLinearHexahedron", element_type) == 0 ) elementType = AdvDataSet::ADVENTURE_ELEMENT_HEX8; } } } adv_dio_close(doc); } }
vtkDataArray * AdvData::GetVar(int domain, const std::string &var) { vtkDataArray *retval = 0; if(domainToRecord.find(domain) != domainToRecord.end()) { int recordIndex = domainToRecord[domain]; // Determine the centering. bool nodal = false; for(size_t i = 0; i < modelVars.size(); ++i) { if(modelVars[i].label == var) nodal |= modelVars[i].fega_type.find("NodeVar") != std::string::npos; } for(size_t i = 0; i < resultVars.size(); ++i) { if(resultVars[i].label == var) nodal |= resultVars[i].fega_type.find("NodeVar") != std::string::npos; } // For nodal variables, we need to also pass the NodeIndex_SubdomainToPart // document so we can map from subdomain to part. AdvDocument *nodeIndexDoc = 0; if(nodal) { AdvDocFile *f = OpenFile(domainRecords[recordIndex].modelFile); if (f == 0 || (nodeIndexDoc = adv_dio_open_by_property(f, 0, "content_type", "HDDM_FEGenericAttribute", "label", "NodeIndex_SubdomainToPart", 0)) == 0) { EXCEPTION1(InvalidVariableException, var.c_str()); } } TRY { for(size_t i = 0; i < modelVars.size() && retval == 0; ++i) { if(modelVars[i].label == var) { // Okay, we need to open the model file AdvDocFile *f = OpenFile(domainRecords[recordIndex].modelFile); // Get the var if(f != 0) { if(nodal) retval = domainRecords[recordIndex].GetNodeVar(f, nodeIndexDoc, domain, modelVars[i]); else retval = domainRecords[recordIndex].GetElementVar(f, domain, modelVars[i]); } } } for(size_t i = 0; i < resultVars.size() && retval == 0; ++i) { if(resultVars[i].label == var) { // Okay, we need to open the result file AdvDocFile *f = OpenFile(domainRecords[recordIndex].resultFile); // Get the var if(f != 0) { if(nodal) retval = domainRecords[recordIndex].GetNodeVar(f, nodeIndexDoc, domain, resultVars[i]); else retval = domainRecords[recordIndex].GetElementVar(f, domain, resultVars[i]); } } } if(nodal) adv_dio_close(nodeIndexDoc); } CATCHALL { if(nodal) adv_dio_close(nodeIndexDoc); RETHROW; } ENDTRY }
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; }
vtkDataArray * AdvDataSet::GetAllNodeVariable(AdvDocFile *f, AdvDocument *nodeIndexDoc, int subDomain, const AdvDataSet::VarInfo &var) { AdvDocument *doc = GetDocument(f, var.label); vtkDataArray *retval = 0; adv_off_t offset = 0; adv_off_t nodeOffset = 0; int ncomp = 1; var.CheckFormat(ncomp); std::string format(var.format.substr(0,2)); if(format == "f8") { vtkDoubleArray *arr = vtkDoubleArray::New(); arr->SetNumberOfComponents(ncomp); arr->SetNumberOfTuples(nnodes); double *ptr = (double *)arr->GetVoidPointer(0); memset(ptr, 0, sizeof(double) * nnodes * ncomp); double *tmp = new double[ncomp]; for(int i = 0; i < GetNumSubDomains(); ++i) { int *subDomainNodeID2PartNodeID = ReadSubDomainNodeID2PartNodeID(nodeIndexDoc, nodeOffset); int nnodesInSubDomain = 0; offset += adv_dio_read_int32(doc, offset, &nnodesInSubDomain); for(int nodeid = 0; nodeid < nnodesInSubDomain; ++nodeid) { offset += adv_dio_read_float64v(doc, offset, ncomp, tmp); int partnodeid = subDomainNodeID2PartNodeID[nodeid]; memcpy(ptr + partnodeid * ncomp, tmp, ncomp * sizeof(double)); } delete [] subDomainNodeID2PartNodeID; } delete [] tmp; retval = arr; } else if(format == "f4") { vtkFloatArray *arr = vtkFloatArray::New(); arr->SetNumberOfComponents(ncomp); arr->SetNumberOfTuples(nnodes); float *ptr = (float *)arr->GetVoidPointer(0); memset(ptr, 0, sizeof(float) * nnodes * ncomp); float *tmp = new float[ncomp]; for(int i = 0; i < GetNumSubDomains(); ++i) { int *subDomainNodeID2PartNodeID = ReadSubDomainNodeID2PartNodeID(nodeIndexDoc, nodeOffset); int nnodesInSubDomain = 0; offset += adv_dio_read_int32(doc, offset, &nnodesInSubDomain); for(int nodeid = 0; nodeid < nnodesInSubDomain; ++nodeid) { offset += adv_dio_read_float32v(doc, offset, ncomp, tmp); int partnodeid = subDomainNodeID2PartNodeID[nodeid]; memcpy(ptr + partnodeid * ncomp, tmp, ncomp * sizeof(float)); } delete [] subDomainNodeID2PartNodeID; } delete [] tmp; retval = arr; } else if(format == "i4") { vtkIntArray *arr = vtkIntArray::New(); arr->SetNumberOfComponents(ncomp); arr->SetNumberOfTuples(nnodes); int *ptr = (int *)arr->GetVoidPointer(0); memset(ptr, 0, sizeof(int) * nnodes * ncomp); int *tmp = new int[ncomp]; for(int i = 0; i < GetNumSubDomains(); ++i) { int *subDomainNodeID2PartNodeID = ReadSubDomainNodeID2PartNodeID(nodeIndexDoc, nodeOffset); int nnodesInSubDomain = 0; offset += adv_dio_read_int32(doc, offset, &nnodesInSubDomain); for(int nodeid = 0; nodeid < nnodesInSubDomain; ++nodeid) { offset += adv_dio_read_int32v(doc, offset, ncomp, tmp); int partnodeid = subDomainNodeID2PartNodeID[nodeid]; memcpy(ptr + partnodeid * ncomp, tmp, ncomp * sizeof(int)); } delete [] subDomainNodeID2PartNodeID; } delete [] tmp; retval = arr; } else { adv_dio_close(doc); EXCEPTION1(InvalidVariableException, var.label.c_str()); } adv_dio_close(doc); return retval; }
vtkDataArray * AdvDataSet::GetAllConstant(AdvDocFile *f, int subDomain, const AdvDataSet::VarInfo &var, int ntuples) { AdvDocument *doc = GetDocument(f, var.label); vtkDataArray *retval = 0; adv_off_t offset = 0; int ncomp = 1; var.CheckFormat(ncomp); std::string format(var.format.substr(0,2)); if(format == "f8") { vtkDoubleArray *arr = vtkDoubleArray::New(); arr->SetNumberOfComponents(ncomp); arr->SetNumberOfTuples(ntuples); double *ptr = (double *)arr->GetVoidPointer(0); // Read the 1 data value. adv_dio_read_float64v(doc, offset, ncomp, ptr); // Replicate it over all cells. double *cell0 = ptr; ptr += ncomp; for(int j = 1; j < ntuples; ++j) { memcpy(ptr, cell0, ncomp * sizeof(double)); ptr += ncomp; } retval = arr; } else if(format == "f4") { vtkFloatArray *arr = vtkFloatArray::New(); arr->SetNumberOfComponents(ncomp); arr->SetNumberOfTuples(ntuples); float *ptr = (float *)arr->GetVoidPointer(0); // Read the 1 data value. adv_dio_read_float32v(doc, offset, ncomp, ptr); // Replicate it over all cells. float *cell0 = ptr; ptr += ncomp; for(int j = 1; j < ntuples; ++j) { memcpy(ptr, cell0, ncomp * sizeof(float)); ptr += ncomp; } retval = arr; } else if(format == "i4") { vtkIntArray *arr = vtkIntArray::New(); arr->SetNumberOfComponents(ncomp); arr->SetNumberOfTuples(ntuples); int *ptr = (int *)arr->GetVoidPointer(0); // Read the 1 data value. adv_dio_read_int32v(doc, offset, ncomp, ptr); // Replicate it over all cells. int *cell0 = ptr; ptr += ncomp; for(int j = 1; j < ntuples; ++j) { memcpy(ptr, cell0, ncomp * sizeof(int)); ptr += ncomp; } retval = arr; } else { adv_dio_close(doc); EXCEPTION1(InvalidVariableException, var.label.c_str()); } adv_dio_close(doc); return retval; }
vtkDataArray * AdvDataSet::GetAllElementVariable(AdvDocFile *f, int subDomain, const AdvDataSet::VarInfo &var) { AdvDocument *doc = GetDocument(f, var.label); vtkDataArray *retval = 0; adv_off_t offset = 0; int ncomp = 1; var.CheckFormat(ncomp); std::string format(var.format.substr(0,2)); if(format == "f8") { vtkDoubleArray *arr = vtkDoubleArray::New(); arr->SetNumberOfComponents(ncomp); arr->SetNumberOfTuples(ncells); double *ptr = (double *)arr->GetVoidPointer(0); for(int i = 0; i < GetNumSubDomains(); ++i) { int valuesPerDomain = 0; offset += adv_dio_read_int32(doc, offset, &valuesPerDomain); for(int j = 0; j < valuesPerDomain; ++j, ptr += ncomp) offset += adv_dio_read_float64v(doc, offset, ncomp, ptr); } retval = arr; } else if(format == "f4") { vtkFloatArray *arr = vtkFloatArray::New(); arr->SetNumberOfComponents(ncomp); arr->SetNumberOfTuples(ncells); float *ptr = (float *)arr->GetVoidPointer(0); for(int i = 0; i < GetNumSubDomains(); ++i) { int valuesPerDomain = 0; offset += adv_dio_read_int32(doc, offset, &valuesPerDomain); for(int j = 0; j < valuesPerDomain; ++j, ptr += ncomp) offset += adv_dio_read_float32v(doc, offset, ncomp, ptr); } retval = arr; } else if(format == "i4") { vtkIntArray *arr = vtkIntArray::New(); arr->SetNumberOfComponents(ncomp); arr->SetNumberOfTuples(ncells); int *ptr = (int *)arr->GetVoidPointer(0); for(int i = 0; i < GetNumSubDomains(); ++i) { int valuesPerDomain = 0; offset += adv_dio_read_int32(doc, offset, &valuesPerDomain); for(int j = 0; j < valuesPerDomain; ++j, ptr += ncomp) offset += adv_dio_read_int32v(doc, offset, ncomp, ptr); } retval = arr; } else { adv_dio_close(doc); EXCEPTION1(InvalidVariableException, var.label.c_str()); } adv_dio_close(doc); return retval; }
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; }