MeshLib::CFEMesh* GMSInterface::readGMS3DMMesh(std::string filename) { std::string buffer(""); std::ifstream in(filename.c_str()); if (!in.is_open()) { std::cout << "GMSInterface::readGMS3DMMesh() - Could not open file..." << "\n"; return NULL; } // Read data from file getline(in, buffer); // "MESH3D" if (buffer.compare("MESH3D") != 0) { std::cout << "GMSInterface::readGMS3DMMesh() - Could not read expected file header..." << "\n"; return NULL; } std::cout << "Read GMS-3DM data..."; MeshLib::CFEMesh* mesh (new MeshLib::CFEMesh()); while (!in.eof()) { MeshLib::CElem* elem = new MeshLib::CElem(); std::string element_id(""); in >> element_id; if (element_id.compare("E6W") == 0) { elem->SetElementType(MshElemType::PRISM); elem->Read(in, 8); mesh->ele_vector.push_back(elem); } else if (element_id.compare("E4T") == 0) { elem->SetElementType(MshElemType::TETRAHEDRON); elem->Read(in, 8); mesh->ele_vector.push_back(elem); } else if ((element_id.compare("E4P") == 0) || (element_id.compare("E5P") == 0)) // KR both versions exist! { size_t i(0); long node_index[5]; elem->SetElementType(MshElemType::TETRAHEDRON); elem->Read(in, 8); mesh->ele_vector.push_back(elem); for (size_t j = 0; j < 4; j++) node_index[j] = elem->GetNodeIndex(j); in >> node_index[4]; i = elem->GetPatchIndex(); elem->SetPatchIndex(node_index[4] - 1); node_index[4] = i; elem->SetNodeIndex(0, node_index[0]); elem->SetNodeIndex(1, node_index[1]); elem->SetNodeIndex(2, node_index[3]); elem->SetNodeIndex(3, node_index[4]); MeshLib::CElem* elem2 = new MeshLib::CElem( mesh->ele_vector.size() - 1, elem); elem2->SetNodeIndex(0, node_index[1]); elem2->SetNodeIndex(1, node_index[2]); elem2->SetNodeIndex(2, node_index[3]); elem2->SetNodeIndex(3, node_index[4]); mesh->ele_vector.push_back(elem2); } else if (element_id.compare("ND") == 0)
MeshLib::CFEMesh* MshEditor::removeMeshNodes(MeshLib::CFEMesh* mesh, const std::vector<size_t>& nodes) { MeshLib::CFEMesh* new_mesh(new MeshLib::CFEMesh(*mesh)); // delete nodes and their connected elements and replace them with null // pointers size_t delNodes = nodes.size(); for (size_t i = 0; i < delNodes; i++) { MeshLib::CNode* node = new_mesh->nod_vector[nodes[i]]; std::vector<size_t> conn_elems = node->getConnectedElementIDs(); for (size_t j = 0; j < conn_elems.size(); j++) { delete new_mesh->ele_vector[conn_elems[j]]; new_mesh->ele_vector[conn_elems[j]] = NULL; } delete new_mesh->nod_vector[nodes[i]]; new_mesh->nod_vector[nodes[i]] = NULL; } // create map to adjust node indices in element vector size_t nNodes = new_mesh->nod_vector.size(); std::vector<int> id_map; size_t count = 0; for (size_t i = 0; i < nNodes; i++) { if (new_mesh->nod_vector[i]) { new_mesh->nod_vector[i]->SetIndex(count); id_map.push_back(count); count++; } else id_map.push_back(-1); } // erase null pointers from node- and element vectors for (std::vector<MeshLib::CElem*>::iterator it = new_mesh->ele_vector.begin(); it != new_mesh->ele_vector.end();) { if (*it) ++it; else it = new_mesh->ele_vector.erase(it); } for (std::vector<MeshLib::CNode*>::iterator it = new_mesh->nod_vector.begin(); it != new_mesh->nod_vector.end();) { if (*it) ++it; else it = new_mesh->nod_vector.erase(it); } // re-adjust node indices size_t nElems = new_mesh->ele_vector.size(); for (size_t i = 0; i < nElems; i++) { MeshLib::CElem* elem = new_mesh->ele_vector[i]; size_t nElemNodes = elem->GetNodesNumber(false); for (size_t j = 0; j < nElemNodes; j++) elem->SetNodeIndex(j, id_map[elem->GetNodeIndex(j)]); } return new_mesh; }
/************************************************************************** FEMLib-Method: Task: Programing: 04/2006 kg44 Implementation 10/2006 WW Output secondary variables 08/2008 OK MAT values 06/2009 WW/OK WriteELEVelocity for different coordinate systems 11/2012 WW Rewrite this fucntion in order to have a correct vec/teosor output **************************************************************************/ void LegacyVtkInterface::WriteVTKDataArrays(fstream& vtk_file) const { long numNodes = _mesh->GetNodesNumber(false); // For components of vectors and tensors. //11.2012. WW const int space_dim = _mesh->GetMaxElementDim(); int vec_val_idx[3]; int tensor_val_idx[6]; int tensor_com = 4; if (space_dim == 3) tensor_com = 6; // NODAL DATA vtk_file << "POINT_DATA " << numNodes << "\n"; const size_t numPointArrays = _pointArrayNames.size(); for (size_t k = 0; k < numPointArrays; k++) { bool toNext = false; // Write X, Y and Z arrays as vectors // WW. 11.2012. if(k + 1 < numPointArrays) { if (_pointArrayNames[k].find("_X") != string::npos && _pointArrayNames[k + 1].find("_Y") != string::npos) { string arrayName = _pointArrayNames[k]; CRFProcess* pcs = PCSGet(arrayName, true); if (!pcs) continue; if (pcs->getProcessType() == FiniteElement::FLUID_MOMENTUM) // 23.11.2012. WW { vec_val_idx[0] = pcs->GetNodeValueIndex(arrayName) + 1; for (int kk = 1; kk < space_dim; kk++) { vec_val_idx[kk] = vec_val_idx[kk - 1] + 2; } } else { vec_val_idx[0] = pcs->GetNodeValueIndex(arrayName); for (int kk = 1; kk < space_dim; kk++) { vec_val_idx[kk] = vec_val_idx[0] + kk; } } std::cout << "ArrayName: " << arrayName << "\n"; vtk_file << "VECTORS " << arrayName.substr(0, arrayName.size() - 2) << " double" << "\n"; for (long j = 0l; j < numNodes; j++) { const long node_id = _mesh->nod_vector[j]->GetIndex(); for (int kk = 0; kk < space_dim; kk++) { vtk_file << pcs->GetNodeValue(node_id, vec_val_idx[kk]) << " "; } for (int kk = space_dim; kk < 3; kk++) { vtk_file << "0.0 "; } vtk_file << "\n"; } k += space_dim; toNext = true; } // Write tensors as Eigenvectors // XX, XY, YY, ZZ, XZ, YZ must be present in that order else if (_pointArrayNames[k].find("_XX") != string::npos) { string arrayName = _pointArrayNames[k]; CRFProcess* pcs = PCSGet(arrayName, true); if (!pcs) continue; tensor_val_idx[0] = pcs->GetNodeValueIndex(arrayName); for (int kk = 1; kk < tensor_com; kk++) { tensor_val_idx[kk] = tensor_val_idx[0] + kk; } { #if defined(VTK_FOUND) && defined(OGS_USE_QT) vector<vector<double> > eigenvectors_1, eigenvectors_2, eigenvectors_3; // Iterate over nodes for (long j = 0l; j < numNodes; j++) { const long node_id = _mesh->nod_vector[j]->GetIndex(); double vector6[6]; // Iterate over the tensor 6 arrays for (size_t component = 0; component < tensor_com; ++component) { vector6[component] = pcs->GetNodeValue( node_id, tensor_val_idx[component]); // std::cout << "vector " << component << " : " << // vector6[component] << "\n"; } double* tensor[3]; double tensor0[3]; double tensor1[3]; double tensor2[3]; tensor[0] = tensor0; tensor[1] = tensor1; tensor[2] = tensor2; if (tensor_com == 6) { tensor0[0] = vector6[0]; tensor0[1] = vector6[1]; tensor0[2] = vector6[4]; tensor1[0] = vector6[1]; tensor1[1] = vector6[2]; tensor1[2] = vector6[5]; tensor2[0] = vector6[4]; tensor2[1] = vector6[5]; tensor2[2] = vector6[3]; } else { continue; // std::cout << " To be finished / " << "\n"; } // std::cout << "TensorMat:" << "\n"; // std::cout << tensor0[0] << " " << tensor0[1] << " " // << tensor0[2] << "\n"; // std::cout << tensor1[0] << " " << tensor1[1] << " " // << tensor1[2] << "\n"; // std::cout << tensor2[0] << " " << tensor2[1] << " " // << tensor2[2] << "\n"; // std::cout << "\n" << "\n"; double* eigenvectors[3]; double eigenvectors0[3]; double eigenvectors1[3]; double eigenvectors2[3]; eigenvectors[0] = eigenvectors0; eigenvectors[1] = eigenvectors1; eigenvectors[2] = eigenvectors2; double eigenvalues[3]; vtkMath::Jacobi(tensor, eigenvalues, eigenvectors); // Multiply normalized eigenvector with eigenvalues std::vector<double> eigenvector_1, eigenvector_2, eigenvector_3; eigenvector_1.push_back(eigenvectors[0][0] * eigenvalues[0]); eigenvector_1.push_back(eigenvectors[0][1] * eigenvalues[1]); eigenvector_1.push_back(eigenvectors[0][2] * eigenvalues[2]); eigenvectors_1.push_back(eigenvector_1); eigenvector_2.push_back(eigenvectors[1][0] * eigenvalues[0]); eigenvector_2.push_back(eigenvectors[1][1] * eigenvalues[1]); eigenvector_2.push_back(eigenvectors[1][2] * eigenvalues[2]); eigenvectors_2.push_back(eigenvector_2); eigenvector_3.push_back(eigenvectors[2][0] * eigenvalues[0]); eigenvector_3.push_back(eigenvectors[2][1] * eigenvalues[1]); eigenvector_3.push_back(eigenvectors[2][2] * eigenvalues[2]); eigenvectors_3.push_back(eigenvector_3); } vtk_file << "VECTORS " << arrayName.substr(0, arrayName.size() - 3) << "_Eigenvector_1" << " double" << "\n"; for (vector<vector<double> >::iterator it = eigenvectors_1.begin(); it != eigenvectors_1.end(); ++it) vtk_file << (*it)[0] << " " << (*it)[1] << " " << (*it)[2] << "\n"; vtk_file << "VECTORS " << arrayName.substr(0, arrayName.size() - 3) << "_Eigenvector_2" << " double" << "\n"; for (vector<vector<double> >::iterator it = eigenvectors_2.begin(); it != eigenvectors_2.end(); ++it) vtk_file << (*it)[0] << " " << (*it)[1] << " " << (*it)[2] << "\n"; vtk_file << "VECTORS " << arrayName.substr(0, arrayName.size() - 3) << "_Eigenvector_3" << " double" << "\n"; for (vector<vector<double> >::iterator it = eigenvectors_3.begin(); it != eigenvectors_3.end(); ++it) vtk_file << (*it)[0] << " " << (*it)[1] << " " << (*it)[2] << "\n"; k += tensor_com; toNext = true; #else // TBD #endif } } } if (!toNext) printScalarArray(_pointArrayNames[k], vtk_file); } //====================================================================== // Saturation 2 for 1212 pp - scheme. 01.04.2009. WW // --------------------------------------------------------------------- CRFProcess* pcs = NULL; if (!_pointArrayNames.empty()) // SB added pcs = PCSGet(_pointArrayNames[0], true); if (pcs && pcs->type == 1212) { size_t i = pcs->GetNodeValueIndex("SATURATION1", true); // JT: Latest vtk_file << "SCALARS SATURATION2 double 1" << "\n"; vtk_file << "LOOKUP_TABLE default" << "\n"; for (long j = 0l; j < numNodes; j++) { double val_n = pcs->GetNodeValue(_mesh->nod_vector[j]->GetIndex(), i); vtk_file << 1.0 - val_n << "\n"; } } // kg44 GEM node data #ifdef GEM_REACT m_vec_GEM->WriteVTKGEMValues(vtk_file); // kg44 export GEM internal // variables like speciateion // vector , phases etc #endif // ELEMENT DATA // --------------------------------------------------------------------- bool wroteAnyEleData = false; // NW if (!_cellArrayNames.empty()) { CRFProcess* pcs = this->GetPCS_ELE(_cellArrayNames[0]); std::vector<int> ele_value_index_vector(_cellArrayNames.size()); if (_cellArrayNames[0].size() > 0) for (size_t i = 0; i < _cellArrayNames.size(); i++) ele_value_index_vector[i] = pcs->GetElementValueIndex(_cellArrayNames[i]); vtk_file << "CELL_DATA " << (long)_mesh->ele_vector.size() << "\n"; wroteAnyEleData = true; //.................................................................... // for (size_t k = 0; k < _cellArrayNames.size(); k++) { // JTARON 2010, "VELOCITY" should only write as vector, scalars // handled elswhere if (_cellArrayNames[k].compare("VELOCITY") == 0) { vtk_file << "VECTORS velocity double " << "\n"; this->WriteELEVelocity(vtk_file); // WW/OK } // PRINT CHANGING (OR CONSTANT) PERMEABILITY TENSOR? // JTARON // 2010 else if (_cellArrayNames[k].compare("PERMEABILITY") == 0) { vtk_file << "TENSORS permeability double " << endl; for (long j = 0; j < (long)_mesh->ele_vector.size(); j++) { MeshLib::CElem* ele = _mesh->ele_vector[j]; CMediumProperties* MediaProp = mmp_vector[ele->GetPatchIndex()]; // KG44 22.2.2013 this is not working as expected...we need // to differenciate for type of permeability_tensor for (size_t i = 0; i < 9; i++) vtk_file << MediaProp->PermeabilityTensor(j)[i] << " "; // KG44 this is buggy // MediaProp->PermeabilityTensor(j)[i * 3 + i] << " "; vtk_file << "\n"; } } else if (ele_value_index_vector[k] > -1) { // NOW REMAINING SCALAR DATA // JTARON 2010, reconfig vtk_file << "SCALARS " << _cellArrayNames[k] << " double 1" << "\n"; vtk_file << "LOOKUP_TABLE default" << "\n"; for (size_t i = 0; i < _mesh->ele_vector.size(); i++) vtk_file << pcs->GetElementValue( i, ele_value_index_vector[k]) << "\n"; } } //-------------------------------------------------------------------- ele_value_index_vector.clear(); } //====================================================================== // MAT data if (!_materialPropertyArrayNames.empty()) { int mmp_id = -1; if (_materialPropertyArrayNames[0].compare("POROSITY") == 0) mmp_id = 0; // Let's say porosity // write header for cell data if (!wroteAnyEleData) vtk_file << "CELL_DATA " << _mesh->ele_vector.size() << "\n"; wroteAnyEleData = true; for (size_t i = 0; i < _mesh->ele_vector.size(); i++) { MeshLib::CElem* ele = _mesh->ele_vector[i]; double mat_value = 0.0; switch (mmp_id) { case 0: mat_value = mmp_vector[ele->GetPatchIndex()]->Porosity(i, 0.0); break; default: cout << "COutput::WriteVTKValues: no MMP values specified" << "\n"; break; } vtk_file << mat_value << "\n"; } } // PCH: Material groups from .msh just for temparary purpose if (mmp_vector.size() > 1) { // write header for cell data if (!wroteAnyEleData) // NW: check whether the header has been already // written vtk_file << "CELL_DATA " << _mesh->ele_vector.size() << "\n"; wroteAnyEleData = true; vtk_file << "SCALARS " << "MatGroup" << " int 1" << "\n"; vtk_file << "LOOKUP_TABLE default" << "\n"; for (size_t i = 0; i < _mesh->ele_vector.size(); i++) { MeshLib::CElem* ele = _mesh->ele_vector[i]; vtk_file << ele->GetPatchIndex() << "\n"; } } }
void LegacyVtkInterface::WriteVTKCellData(fstream& vtk_file) const { size_t numCells = _mesh->ele_vector.size(); // count overall length of element vector long numAllPoints = 0; for (size_t i = 0; i < numCells; i++) { MeshLib::CElem* ele = _mesh->ele_vector[i]; numAllPoints = numAllPoints + (ele->GetNodesNumber(false)) + 1; } // write elements vtk_file << "CELLS " << numCells << " " << numAllPoints << "\n"; for (size_t i = 0; i < numCells; i++) { MeshLib::CElem* ele = _mesh->ele_vector[i]; // Write number of points per cell switch (ele->GetElementType()) { case MshElemType::LINE: vtk_file << "2"; break; case MshElemType::QUAD: vtk_file << "4"; break; case MshElemType::HEXAHEDRON: vtk_file << "8"; break; case MshElemType::TRIANGLE: vtk_file << "3"; break; case MshElemType::TETRAHEDRON: vtk_file << "4"; break; case MshElemType::PRISM: vtk_file << "6"; break; case MshElemType::PYRAMID: vtk_file << "5"; break; default: cerr << "COutput::WriteVTKElementData MshElemType not handled" << "\n"; break; } for (size_t j = 0; j < ele->GetNodesNumber(false); j++) vtk_file << " " << ele->getNodeIndices()[j]; vtk_file << "\n"; } vtk_file << "\n"; // write cell types vtk_file << "CELL_TYPES " << numCells << "\n"; for (size_t i = 0; i < numCells; i++) { MeshLib::CElem* ele = _mesh->ele_vector[i]; // Write vtk cell type number (see vtkCellType.h) switch (ele->GetElementType()) { case MshElemType::LINE: vtk_file << "3" << "\n"; break; case MshElemType::QUAD: vtk_file << "9" << "\n"; break; case MshElemType::HEXAHEDRON: vtk_file << "12" << "\n"; break; case MshElemType::TRIANGLE: vtk_file << "5" << "\n"; break; case MshElemType::TETRAHEDRON: vtk_file << "10" << "\n"; break; case MshElemType::PRISM: // VTK_WEDGE vtk_file << "13" << "\n"; break; case MshElemType::PYRAMID: vtk_file << "14" << "\n"; break; default: cerr << "COutput::WriteVTKElementData MshElemType not handled" << "\n"; break; } } vtk_file << "\n"; }
/************************************************************************** FEMLib-Method: Task: Programing: 03/2013 kg44 Implementation this routine is not a exact copy of the corresponding routine for !USE_PETSC the functionality in terms of array data output needs to be done **************************************************************************/ void LegacyVtkInterface::WriteVTKDataArraysPETSC(PetscViewer viewer) const { PetscScalar* xp; // used for pointer PetscInt low, high; PetscInt count; MeshLib::CFEMesh* _mesh = fem_msh_vector[0]; long numNodes = _mesh->GetNodesNumber(false); // const int nn = mesh->getNumNodesGlobal(); //global number of nodes // ..without shadow nodes // cout << "DEBUG nNodes nn" << nNodes << " " << nn <<" \n"; // test vtk output PETSc_Vec x; // VecCreate(PETSC_COMM_WORLD, &x); VecSetSizes(x, numNodes, PETSC_DECIDE); VecSetFromOptions(x); // // get range of local variables VecGetOwnershipRange(x, &low, &high); VecGetLocalSize(x, &count); // get local part of vectors VecGetArray(x, &xp); // NODAL DATA // vtk_file << "POINT_DATA " << numNodes << "\n"; const size_t numPointArrays = _pointArrayNames.size(); for (size_t k = 0; k < numPointArrays; k++) { bool toNext = false; // Write X, Y and Z arrays as vectors // KG44 needs to be re-done ...no array output so far { if (_pointArrayNames[k].find("_X") != string::npos && _pointArrayNames[k + 1].find("_Y") != string::npos) { toNext = true; } // Write tensors as Eigenvectors // XX, XY, YY, ZZ, XZ, YZ must be present in that order } // print normal scalar fields if (!toNext) { string arrayName = _pointArrayNames[k]; CRFProcess* pcs = PCSGet(arrayName, true); if (!pcs) { } else { const char* carrayName = arrayName.c_str(); int indexDataArray = pcs->GetNodeValueIndex(arrayName); PetscObjectSetName((PetscObject)x, carrayName); for (long j = 0; j < count; j++) xp[j] = pcs->GetNodeValue(_mesh->nod_vector[j]->GetIndex(), indexDataArray); VecView(x, viewer); } } } // here is the place to add the GEMS node data #ifdef GEM_REACT m_vec_GEM->WriteVTKGEMValuesPETSC(viewer); // kg44 export GEM internal // variables like speciateion // vector , phases etc #endif // ELEMENT DATA // first create a PETSC vector for storing the data PetscScalar* ep; // used for pointer // MeshLib::CFEMesh *_mesh = fem_msh_vector[0]; long numElem = _mesh->ele_vector.size(); // const int nn = mesh->getNumNodesGlobal(); //global number of nodes // ..without shadow nodes // cout << "DEBUG nNodes nn" << nNodes << " " << nn <<" \n"; // test vtk output PETSc_Vec e; // VecCreate(PETSC_COMM_WORLD, &e); VecSetSizes(e, numElem, PETSC_DECIDE); VecSetFromOptions(e); // // get range of local variables VecGetOwnershipRange(e, &low, &high); // reuse low and high from before VecGetLocalSize(e, &count); // reuse count // get local part of vectors VecGetArray(e, &ep); // from now on we write cell data PetscViewerSetFormat(viewer, PETSC_VIEWER_ASCII_VTK_CELL); // --------------------------------------------------------------------- if (!_cellArrayNames.empty()) { CRFProcess* pcs = this->GetPCS_ELE(_cellArrayNames[0]); std::vector<int> ele_value_index_vector(_cellArrayNames.size()); if (_cellArrayNames[0].size() > 0) for (size_t i = 0; i < _cellArrayNames.size(); i++) ele_value_index_vector[i] = pcs->GetElementValueIndex(_cellArrayNames[i]); //.................................................................... // for (size_t k = 0; k < _cellArrayNames.size(); k++) { // JTARON 2010, "VELOCITY" should only write as vector, scalars // handled elswhere if (_cellArrayNames[k].compare("VELOCITY") == 0) { // kg44 to be done vtk_file << "VECTORS velocity double " // << // "\n"; // this->WriteELEVelocity(vtk_file); //WW/OK } // PRINT CHANGING (OR CONSTANT) PERMEABILITY TENSOR? // JTARON // 2010 else if (_cellArrayNames[k].compare("PERMEABILITY") == 0) { /* kg44 to be done vtk_file << "TENSORS permeability double " << endl; for (long j = 0; j < (long) _mesh->ele_vector.size(); j++) { MeshLib::CElem* ele = _mesh->ele_vector[j]; CMediumProperties* MediaProp = mmp_vector[ele->GetPatchIndex()]; // KG44 22.2.2013 this is not working as expected...we need to differenciate for type of permeability_tensor for (size_t i = 0; i < 9; i++) vtk_file << MediaProp->PermeabilityTensor(j)[i] << " "; //KG44 this is buggy MediaProp->PermeabilityTensor(j)[i * 3 + i] << " "; vtk_file << "\n"; } */ } else if (ele_value_index_vector[k] > -1) { const char* carrayName = _cellArrayNames[k].c_str(); PetscObjectSetName((PetscObject)e, carrayName); const int ele_val_id = ele_value_index_vector[k]; for (long j = 0; j < count; j++) ep[j] = pcs->GetElementValue(j, ele_val_id); VecView(e, viewer); } } //-------------------------------------------------------------------- ele_value_index_vector.clear(); } //====================================================================== // MAT data if (!_materialPropertyArrayNames.empty()) { int mmp_id = -1; if (_materialPropertyArrayNames[0].compare("POROSITY") == 0) mmp_id = 0; // Let's say porosity // write header for cell data // if (!wroteAnyEleData) // vtk_file << "CELL_DATA " << _mesh->ele_vector.size() // << "\n"; const char* carrayName = _materialPropertyArrayNames[0].c_str(); PetscObjectSetName((PetscObject)e, carrayName); for (size_t i = 0; i < (size_t)count; i++) { MeshLib::CElem* ele = _mesh->ele_vector[i]; switch (mmp_id) { case 0: ep[i] = mmp_vector[ele->GetPatchIndex()]->Porosity(i, 0.0); break; default: cout << "COutput::WriteVTKValues: no MMP values specified" << "\n"; break; } } VecView(e, viewer); } // PCH: Material groups from .msh just for temparary purpose if (mmp_vector.size() > 1) { // write header for cell data // if (!wroteAnyEleData) //NW: check whether the // header has been already written // vtk_file << "CELL_DATA " << _mesh->ele_vector.size() // << "\n"; const char* carrayName = "MatGroup"; PetscObjectSetName((PetscObject)e, carrayName); // vtk_file << "SCALARS " << "MatGroup" << " int 1" << "\n"; // vtk_file << "LOOKUP_TABLE default" << "\n"; for (size_t i = 0; i < (size_t)count; i++) { MeshLib::CElem* ele = _mesh->ele_vector[i]; ep[i] = ele->GetPatchIndex(); // vtk_file << ele->GetPatchIndex() << "\n"; } VecView(e, viewer); const char* carrayNameD = "Domain"; PetscObjectSetName((PetscObject)e, carrayNameD); // vtk_file << "SCALARS " << "MatGroup" << " int 1" << "\n"; // vtk_file << "LOOKUP_TABLE default" << "\n"; int myrank; MPI_Comm_rank(PETSC_COMM_WORLD, &myrank); for (size_t i = 0; i < (size_t)count; i++) { ep[i] = myrank; } VecView(e, viewer); } VecRestoreArray(x, &xp); VecRestoreArray(e, &ep); VecDestroy(&x); VecDestroy(&e); return; }
void LegacyVtkInterface::WriteVTKCellDataPETSC(PetscViewer viewer) const { size_t nelocal = _mesh->ele_vector.size(); // local size // count overall length of element vector long numAllPoints = 0; for (size_t i = 0; i < nelocal; i++) { MeshLib::CElem* ele = _mesh->ele_vector[i]; numAllPoints = numAllPoints + (ele->GetNodesNumber(false)) + 1; } PetscScalar* ep, *eglobp; // used for pointer PetscInt low, high, neglob, nn; int i; VecScatter ctx; // get my petsc rank int myrank; MPI_Comm_rank(PETSC_COMM_WORLD, &myrank); // test vtk output PETSc_Vec e, eglob, x; // // vector for elements ...contains number of nodes connected to form a // element in first entry and then the node numbers VecCreate(PETSC_COMM_WORLD, &e); VecSetSizes( e, numAllPoints, PETSC_DECIDE); // nummAllPoints is local lenght of the vector we need VecSetFromOptions(e); // // get range of local variables VecGetOwnershipRange(e, &low, &high); VecGetSize(e, &neglob); // get local part of vector VecGetArray(e, &ep); // in order to get a global mesh the node numbers have to be corrected.. // we have to get the position in the global node vector in order to get // the correct additive value // is there a simpler way to do it (as below)? MeshLib::CFEMesh* mesh = fem_msh_vector[0]; // const int nn = mesh->getNumNodesGlobal(); //global number of nodes // without shadow nodes const size_t n_linear_pnts(mesh->GetNodesNumber(false)); VecCreate(PETSC_COMM_WORLD, &x); VecSetSizes(x, n_linear_pnts, PETSC_DECIDE); VecSetFromOptions(x); // // get range of local variables VecGetOwnershipRange(x, &low, &high); VecGetSize(x, &nn); // cout << " " << low << " " << high << " \n"; // low is now the first node number // now we can fill the element vector size_t anz_elem = 0; // here a local value for (size_t i = 0; i < nelocal; i++) { MeshLib::CElem* ele = _mesh->ele_vector[i]; // cout << ele->GetNodesNumber(false)<< " " ; switch (ele->GetElementType()) // first entry: type of element as // defined for vtk ..better than number // of nodes { case MshElemType::LINE: ep[anz_elem] = 3; break; case MshElemType::QUAD: ep[anz_elem] = 9; break; case MshElemType::HEXAHEDRON: ep[anz_elem] = 12; break; case MshElemType::TRIANGLE: ep[anz_elem] = 5; break; case MshElemType::TETRAHEDRON: ep[anz_elem] = 10; break; case MshElemType::PRISM: // VTK_WEDGE ep[anz_elem] = 13; break; case MshElemType::PYRAMID: ep[anz_elem] = 14; break; default: cerr << "PETSC VTK output::WriteVTKElementData MshElemType not " "recogniced" << "\n"; break; } // cout << ele->GetNodesNumber(false)<< " " ; for (size_t j = 0; j < ele->GetNodesNumber(false); j++) { ep[anz_elem + j + 1] = ele->GetNodeIndeces()[j] + low; // this are the nodes // cout << "DEBUG " << ele->GetNodeIndeces()[j] << " " ; } // cout << " \n"; anz_elem = anz_elem + (ele->GetNodesNumber(false)) + 1; } // now scatter the vectors to process rank 0 VecScatterCreateToZero(e, &ctx, &eglob); VecScatterBegin(ctx, e, eglob, INSERT_VALUES, SCATTER_FORWARD); VecScatterEnd(ctx, e, eglob, INSERT_VALUES, SCATTER_FORWARD); // count number of elements if (myrank == 0) { VecGetArray(eglob, &eglobp); anz_elem = 0; // here this es global number of elements i = 0; while (i < neglob) { anz_elem += 1; // add one for the element int mswitch = (int)eglobp[i]; switch (mswitch) // first entry: type of element as defined for vtk // ..better than number of nodes { case 3: // LINE i += 2 + 1; break; case 9: // QUAD i += 4 + 1; break; case 12: // HEXAHEDRON: i += 6 + 1; break; case 5: // TRIANGLE: i += 3 + 1; break; case 10: // TETRAHEDRON: i += 4 + 1; break; case 13: // PRISM: // VTK_WEDGE i += 6 + 1; break; case 14: // PYRAMID: i += 5 + 1; break; default: cerr << "PETSC VTK Output 1::WriteVTKElementData " "MshElemType not handled, i. anz_elem. ep[i] type " << i << " " << anz_elem << " " << eglobp[i] << "\n"; exit(1); break; } } // write elements // vtk_file << "CELLS " << numCells << " " << numAllPoints << "\n"; PetscViewerASCIIPrintf(viewer, "CELLS %d %d\n", anz_elem, neglob); i = 0; std::stringstream ss; while (i < neglob) { switch ((int)eglobp[i]) // first entry: type of element as defined // for vtk ..better than number of nodes { case 3: // LINE ss << " 2 "; // PetscViewerASCIIPrintf(viewer," 2 "); for (size_t j = 0; j < 2; j++) ss << eglobp[i + j + 1] << " "; // PetscViewerASCIIPrintf(viewer," %d // ",(long) eglobp[i+j+1]); i += 2 + 1; break; case 9: // QUAD ss << " 4 "; // PetscViewerASCIIPrintf(viewer," 4 "); for (size_t j = 0; j < 4; j++) ss << eglobp[i + j + 1] << " "; // PetscViewerASCIIPrintf(viewer," %d // ",(long) eglobp[i+j+1]); i += 4 + 1; break; case 12: // HEXAHEDRON: ss << " 6 "; // PetscViewerASCIIPrintf(viewer," 6 "); for (size_t j = 0; j < 6; j++) ss << eglobp[i + j + 1] << " "; // PetscViewerASCIIPrintf(viewer," %d ",(long) // eglobp[i+j+1]); i += 6 + 1; break; case 5: // TRIANGLE: ss << " 3 "; // PetscViewerASCIIPrintf(viewer," 3 "); for (size_t j = 0; j < 3; j++) ss << eglobp[i + j + 1] << " "; // PetscViewerASCIIPrintf(viewer," %d ",(long) // eglobp[i+j+1]); i += 3 + 1; break; case 10: // TETRAHEDRON: ss << " 4 "; // PetscViewerASCIIPrintf(viewer," 4 "); for (size_t j = 0; j < 4; j++) ss << eglobp[i + j + 1] << " "; // PetscViewerASCIIPrintf(viewer," %d ",(long) // eglobp[i+j+1]); i += 4 + 1; break; case 13: // PRISM: // VTK_WEDGE ss << " 6 "; // PetscViewerASCIIPrintf(viewer," 6 "); for (size_t j = 0; j < 6; j++) ss << eglobp[i + j + 1] << " "; // PetscViewerASCIIPrintf(viewer," %d ",(long) // eglobp[i+j+1]); i += 6 + 1; break; case 14: // PYRAMID: ss << " 5 "; // PetscViewerASCIIPrintf(viewer," 5 "); for (size_t j = 0; j < 5; j++) ss << eglobp[i + j + 1] << " "; // PetscViewerASCIIPrintf(viewer," %d ",(long) // eglobp[i+j+1]); i += 5 + 1; break; default: cerr << "PETSC VTK Output 2::WriteVTKElementData " "MshElemType not handled" << "\n"; break; } ss << "\n"; // PetscViewerASCIIPrintf(viewer," \n "); if (i % 1000 == 0) { PetscViewerASCIIPrintf(viewer, ss.str().c_str()); ss.str(""); ss.clear(); } } if (!ss.str().empty()) { PetscViewerASCIIPrintf(viewer, ss.str().c_str()); } ss.str(""); ss.clear(); // write cell types // vtk_file << "CELL_TYPES " << numCells << "\n"; PetscViewerASCIIPrintf(viewer, "CELL_TYPES %d \n", anz_elem); i = 0; while (i < neglob) { switch ((int)eglobp[i]) // first entry: type of element as defined // for vtk ..better than number of nodes { case 3: // LINE ss << " 3 \n"; // PetscViewerASCIIPrintf(viewer," 3 \n"); i += 2 + 1; break; case 9: // QUAD ss << " 9 \n"; // PetscViewerASCIIPrintf(viewer," 9 \n"); i += 4 + 1; break; case 12: // HEXAHEDRON: ss << " 12 \n"; // PetscViewerASCIIPrintf(viewer," 12 \n"); i += 6 + 1; break; case 5: // TRIANGLE: ss << " 5 \n"; // PetscViewerASCIIPrintf(viewer," 5 \n"); i += 3 + 1; break; case 10: // TETRAHEDRON: ss << " 10 \n"; // PetscViewerASCIIPrintf(viewer," 10 \n"); i += 4 + 1; break; case 13: // PRISM: // VTK_WEDGE ss << " 13 \n"; // PetscViewerASCIIPrintf(viewer," 13 \n"); i += 6 + 1; break; case 14: // PYRAMID: ss << " 14 \n"; // PetscViewerASCIIPrintf(viewer," 14 \n");; i += 5 + 1; break; default: cerr << "COutput::WriteVTKElementData MshElemType not " "handled" << "\n"; break; } if (i % 1000 == 0) { PetscViewerASCIIPrintf(viewer, ss.str().c_str()); ss.str(""); ss.clear(); } // PetscViewerASCIIPrintf(viewer," \n "); } if (!ss.str().empty()) { PetscViewerASCIIPrintf(viewer, ss.str().c_str()); } ss.str(""); ss.clear(); VecRestoreArray(eglob, &eglobp); } // end myrank == 0 VecRestoreArray(e, &ep); VecDestroy(&e); VecDestroy(&eglob); VecDestroy(&x); }
bool TetGenInterface::parseElements(std::ifstream& ins, size_t n_tets, size_t n_nodes_per_tet, bool region_attribute) { size_t pos_beg, pos_end; std::string line; size_t* ids (static_cast<size_t*>(alloca (sizeof (size_t) * n_nodes_per_tet))); for (size_t k(0); k < n_tets && !ins.fail(); k++) { getline (ins, line); if (!ins.fail()) { if (!line.empty()) { pos_end = 0; // read id size_t id; pos_beg = line.find_first_not_of(" ", pos_end); pos_end = line.find_first_of(" \n", pos_beg); if (pos_beg != std::string::npos && pos_end != std::string::npos) id = str2number<size_t>(line.substr(pos_beg, pos_end - pos_beg)); else { std::cout << "error reading id of tetrahedra " << k << " in TetGenInterface::parseElements" << "\n"; return false; } // read node ids for (size_t i(0); i < n_nodes_per_tet; i++) { pos_beg = line.find_first_not_of(" ", pos_end); pos_end = line.find_first_of(" ", pos_beg); if (pos_end == std::string::npos) pos_end = line.size(); if (pos_beg != std::string::npos && pos_end != std::string::npos) ids[i] = str2number<size_t>(line.substr(pos_beg, pos_end - pos_beg)); else { std::cout << "error reading node " << i << " of tetrahedra " << k << " in TetGenInterface::parseElements" << "\n"; return false; } } if (!_zero_based_idx) { id--; for (size_t i(0); i < n_nodes_per_tet; i++) ids[i]--; } // since CFEMesh is our friend we can access private data of mesh MeshLib::CElem* elem (new MeshLib::CElem(id)); elem->setElementProperties (MshElemType::TETRAHEDRON, false); std::vector<MeshLib::CNode*> ele_nodes(n_nodes_per_tet); for (size_t i(0); i < n_nodes_per_tet; i++) { ele_nodes[i] = _mesh->nod_vector[ids[i]]; } elem->setNodes (ele_nodes); _mesh->ele_vector.push_back(elem); // read region attribute - this is something like material group if (region_attribute) { pos_beg = line.find_first_not_of(" ", pos_end); pos_end = line.find_first_of(" ", pos_beg); if (pos_end == std::string::npos) pos_end = line.size(); if (pos_beg != std::string::npos && pos_end != std::string::npos) elem->setPatchIndex (str2number<int>(line.substr( pos_beg, pos_end - pos_beg))); else { std::cout << "error reading region attribute of tetrahedra " << k << " in TetGenInterface::parseElements" << "\n"; return false; } } } } else { std::cout << "error reading node " << k << " in TetGenInterface::parseElements" << "\n"; return false; } } return true; }