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