Example #1
0
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)
Example #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;
}
/**************************************************************************
   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);
}
Example #7
0
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;
}