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";
}
Exemple #2
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;
}
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);
}