// ===========================================================================
//
// Filename: utFEM4EllipticPDE.cpp
//
// Created: 08/16/12 19:49:10
// Compiler: Tested with g++, icpc, and MSVC 2010
//
// Author: Trevor Irons (ti)
//
// Organisation: Colorado School of Mines (CSM)
// United States Geological Survey (USGS)
//
// Email: tirons@mines.edu, tirons@usgs.gov
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// ===========================================================================
/**
@file
@author Trevor Irons
@date 08/16/12
@version 0.0
**/
#include "FEM4EllipticPDE.h"
#include "vtkSphere.h"
#include "vtkRectilinearGrid.h"
#include "vtkFloatArray.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// debugging stuff
#include
#include
#include
#include
#include
#define RENDERTEST
//#define CONNECTTEST
#ifdef RENDERTEST
#include "vtkRectilinearGridGeometryFilter.h"
#include "vtkRectilinearGridOutlineFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkCamera.h"
#include "vtkProperty.h"
#include
#include
#include
#include
#include
#include
#include
#include
#endif
#ifdef CONNECTTEST
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#endif
vtkSmartPointer GetConnectedVertices(vtkSmartPointer mesh, int id);
vtkSmartPointer GetConnectedVertices2(vtkSmartPointer mesh, int id);
// This function is copyright (C) 2012 Joeseph Cappriotti
vtkSmartPointer GetConnectedPoints(int id0, vtkSmartPointer grid);
using namespace Lemma;
int main() {
// Define Sigma term
// Defaults to 1, (Poisson equation)
// Define source (G) term
//vtkSphere *Sphere = vtkSphere::New();
vtkImplicitHalo *Sphere = vtkImplicitHalo::New();
Sphere->SetCenter (0, 0, 0);
Sphere->SetRadius (60);
Sphere->SetFadeOut(.95);
////////////////////////////////////////////
// Define solution mesh
// Create a rectilinear grid by defining three arrays specifying the
// coordinates in the x-y-z directions.
int nx = 160;
double dx = 2.5;
double ox = -200;
vtkFloatArray *xCoords = vtkFloatArray::New();
for (int i=0; iInsertNextValue(ox + i*dx);
int ny = 160;
double dy = 2.5;
double oy = -200;
vtkFloatArray *yCoords = vtkFloatArray::New();
for (int i=0; iInsertNextValue(oy + i*dy);
int nz = 160;
double dz = 2.5;
double oz = -200;
vtkFloatArray *zCoords = vtkFloatArray::New();
for (int i=0; iInsertNextValue(oz + i*dz);
vtkRectilinearGrid *rGrid = vtkRectilinearGrid::New();
rGrid->SetDimensions(nx+1, ny+1, nz+1);
rGrid->SetExtent(0, nx, 0, ny, 0, nz);
rGrid->SetXCoordinates(xCoords);
rGrid->SetYCoordinates(yCoords);
rGrid->SetZCoordinates(zCoords);
vtkRectilinearGrid *sigGrid = vtkRectilinearGrid::New();
sigGrid->SetDimensions(nx+1, ny+1, nz+1);
sigGrid->SetExtent(0, nx, 0, ny, 0, nz);
sigGrid->SetXCoordinates(xCoords);
sigGrid->SetYCoordinates(yCoords);
sigGrid->SetZCoordinates(zCoords);
vtkDoubleArray *sigArray = vtkDoubleArray::New();
sigArray->SetNumberOfComponents(1);
for (int ii=0; ii<(nx+1)*(ny+1)*(nz+1); ++ii) {
sigArray->InsertTuple1(ii, 1.);
}
sigArray->SetName("sigma");
sigGrid->GetPointData()->AddArray(sigArray);
sigGrid->GetPointData()->SetScalars(sigArray);
vtkImplicitDataSet* implSigma = vtkImplicitDataSet::New();
implSigma->SetDataSet(sigGrid);
implSigma->SetOutValue(0.);
implSigma->SetOutGradient(0., 0., 0.);
FEM4EllipticPDE *Solver = FEM4EllipticPDE::New();
Solver->SetGFunction(Sphere);
//Solver->SetSigmaFunction(implSigma);
Solver->SetBoundaryStep(.5);
Solver->SetGrid(rGrid);
Solver->Solve("FEM_results.vtr");
vtkXMLDataSetWriter *Writer = vtkXMLDataSetWriter::New();
Writer->SetInputData(sigGrid);
std::string fname("sigma.vtr");
//Writer->Update();
//fname.append( Writer->GetDefaultFileExtension() );
Writer->SetFileName(fname.c_str());
Writer->Write();
Writer->Delete();
// Clean up
Sphere->Delete();
Solver->Delete();
rGrid->Delete();
xCoords->Delete();
yCoords->Delete();
zCoords->Delete();
}
// This function is copyright (C) 2012 Joeseph Cappriotti
vtkSmartPointer GetConnectedPoints(int id0, vtkSmartPointer grid){
vtkSmartPointer pointIds = vtkSmartPointer::New();
vtkSmartPointer cellList = vtkSmartPointer::New();
grid->GetPointCells(id0, cellList);
for(int i=0;iGetNumberOfIds();++i){
vtkCell* cell = grid->GetCell(cellList->GetId(i));
if(cell->GetNumberOfEdges() > 0){
for(int j=0; jGetNumberOfEdges(); ++j){
vtkCell* edge = cell->GetEdge(j);
vtkIdList* edgePoints=edge->GetPointIds();
if(edgePoints->GetId(0)==id0){
pointIds->InsertUniqueId(edgePoints->GetId(1));
}else if(edgePoints->GetId(1)==id0){
pointIds->InsertUniqueId(edgePoints->GetId(0));
}
}
}
}
return pointIds;
}
vtkSmartPointer GetConnectedVertices(vtkSmartPointer mesh, int id) {
std::cout << "number of points " << mesh->GetNumberOfPoints() << std::endl;
std::cout << "number of cells " << mesh->GetNumberOfCells() << std::endl;
vtkSmartPointer connectedVertices = vtkSmartPointer::New();
//get all cells that vertex 'id' is a part of
vtkSmartPointer cellIdList = vtkSmartPointer::New();
mesh->GetPointCells(id, cellIdList); // cells using point
//mesh->GetCellPoints(id, cellIdList); // points defining cell
cout << "Vertex " << id << " is used in cell(s) ";
for(vtkIdType i = 0; i < cellIdList->GetNumberOfIds(); i++) {
cout << cellIdList->GetId(i) << ", ";
}
cout << endl;
// TODO this is where things don't work
// for each cell, figure out what vertices are connected
for(vtkIdType i = 0; i < cellIdList->GetNumberOfIds(); i++) {
cout << "\tcell id " << i << " : " << cellIdList->GetId(i) << endl;
std::cout << "\tcell has " << mesh->GetCell(i)->GetNumberOfPoints() << " points\n";
vtkExtractCells *Cell = vtkExtractCells::New();
Cell->SetInputData(mesh);
Cell->AddCellRange(i, i);
Cell->Update();
//std::cout << *Cell->GetOutput() << std::endl;
// extract surface
vtkDataSetSurfaceFilter *surf = vtkDataSetSurfaceFilter::New();
surf->UseStripsOn();
surf->SetInputData(Cell->GetOutput());
surf->Update();
//std::cout << *surf->GetOutput() << std::endl;
vtkSmartPointer triangleFilter =
vtkSmartPointer::New();
triangleFilter->SetInputData( surf->GetOutput() );
triangleFilter->Update();
vtkSmartPointer extractEdges =
vtkSmartPointer::New();
extractEdges->SetInputConnection(triangleFilter->GetOutputPort());
extractEdges->Update();
vtkSmartPointer pmesh = extractEdges->GetOutput();
//vtkSmartPointer pmesh = triangleFilter->GetOutput();
//vtkSmartPointer pconnectedVertices = GetConnectedVertices2(surf->GetOutput(), id);
//
// //vtkSmartPointer ids =
// //vtkSmartPointer::New();
// //ids->SetNumberOfComponents(1);
//
vtkSmartPointer pointIdList = vtkSmartPointer::New();
//mesh->GetPointCells(cellIdList->GetId(i), pointIdList); // returns cells using point
mesh->GetCellPoints(cellIdList->GetId(i), pointIdList); // points defining cell
//vtkSmartPointer pconnectedVertices = GetConnectedVertices2(pmesh, id);
vtkSmartPointer pconnectedVertices = GetConnectedVertices2(surf->GetOutput(), id);
//vtkSmartPointer pconnectedVertices = GetConnectedVertices2(triangleFilter->GetOutput(), 1);
std::cout << "\tPoly Connected vertices: ";
for(vtkIdType ip = 0; ip < pconnectedVertices->GetNumberOfIds(); ip++) {
std::cout << pconnectedVertices->GetId(ip) << " ";
//ids->InsertNextValue(connectedVertices->GetId(i));
connectedVertices->InsertNextId( pointIdList->GetId( pconnectedVertices->GetId(ip) ) );
}
std::cout << std::endl;
cout << "\tcell " << i << " contains these points ";
for(vtkIdType ii = 0; ii < pointIdList->GetNumberOfIds(); ii++) {
cout << pointIdList->GetId(ii) << ", ";
}
cout << endl;
/*
cout << "\tEnd points are " << pointIdList->GetId(0) << " and " << pointIdList->GetId(1) << endl;
if(pointIdList->GetId(0) != id) {
//cout << "Connected to " << pointIdList->GetId(0) << endl;
connectedVertices->InsertNextId(pointIdList->GetId(0));
} else {
//cout << "Connected to " << pointIdList->GetId(1) << endl;
connectedVertices->InsertNextId(pointIdList->GetId(1));
}
*/
#ifdef RENDERTEST
vtkSmartPointer sphereMapper =
vtkSmartPointer::New();
sphereMapper->SetInputConnection(extractEdges->GetOutputPort());
vtkSmartPointer sphereActor =
vtkSmartPointer::New();
sphereActor->SetMapper(sphereMapper);
vtkSmartPointer ids =
vtkSmartPointer::New();
ids->SetNumberOfComponents(1);
std::cout << "RENDERTEST Connected vertices: ";
for(vtkIdType i = 0; i < connectedVertices->GetNumberOfIds(); i++) {
std::cout << connectedVertices->GetId(i) << " ";
ids->InsertNextValue(connectedVertices->GetId(i));
}
std::cout << std::endl;
vtkSmartPointer connectedVertexMapper =
vtkSmartPointer::New();
{
vtkSmartPointer selectionNode =
vtkSmartPointer::New();
selectionNode->SetFieldType(vtkSelectionNode::POINT);
selectionNode->SetContentType(vtkSelectionNode::INDICES);
selectionNode->SetSelectionList(ids);
vtkSmartPointer selection =
vtkSmartPointer::New();
selection->AddNode(selectionNode);
vtkSmartPointer extractSelection =
vtkSmartPointer::New();
extractSelection->SetInputConnection(0, extractEdges->GetOutputPort());
extractSelection->SetInputData(1, selection);
extractSelection->Update();
vtkSmartPointer glyphFilter =
vtkSmartPointer::New();
glyphFilter->SetInputConnection(extractSelection->GetOutputPort());
glyphFilter->Update();
connectedVertexMapper->SetInputConnection(glyphFilter->GetOutputPort());
}
vtkSmartPointer connectedVertexActor =
vtkSmartPointer::New();
connectedVertexActor->SetMapper(connectedVertexMapper);
connectedVertexActor->GetProperty()->SetColor(1,0,0);
connectedVertexActor->GetProperty()->SetPointSize(5);
vtkSmartPointer queryVertexMapper =
vtkSmartPointer::New();
{
vtkSmartPointer ids =
vtkSmartPointer::New();
ids->SetNumberOfComponents(1);
ids->InsertNextValue(id);
vtkSmartPointer selectionNode =
vtkSmartPointer::New();
selectionNode->SetFieldType(vtkSelectionNode::POINT);
selectionNode->SetContentType(vtkSelectionNode::INDICES);
selectionNode->SetSelectionList(ids);
vtkSmartPointer selection =
vtkSmartPointer::New();
selection->AddNode(selectionNode);
vtkSmartPointer extractSelection =
vtkSmartPointer::New();
extractSelection->SetInputConnection(0, extractEdges->GetOutputPort());
extractSelection->SetInputData(1, selection);
extractSelection->Update();
vtkSmartPointer glyphFilter =
vtkSmartPointer::New();
glyphFilter->SetInputConnection(extractSelection->GetOutputPort());
glyphFilter->Update();
queryVertexMapper->SetInputConnection(glyphFilter->GetOutputPort());
}
vtkSmartPointer queryVertexActor =
vtkSmartPointer::New();
queryVertexActor->SetMapper(queryVertexMapper);
queryVertexActor->GetProperty()->SetColor(0,1,0);
queryVertexActor->GetProperty()->SetPointSize(5);
// Create the usual rendering stuff.
vtkRenderer *renderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
renderer->AddActor(queryVertexActor);
renderer->AddActor(connectedVertexActor);
renderer->AddActor(sphereActor);
//renderer->AddActor(wireActor);
//renderer->AddActor(owireActor);
renderer->SetBackground(.3,.2,.1);
renderer->ResetCamera();
renderer->GetActiveCamera()->Elevation(-150.0);
renderer->GetActiveCamera()->Azimuth(0.0);
renderer->GetActiveCamera()->Roll(0.0);
//renderer->GetActiveCamera()->Pitch(-45.0);
renderer->GetActiveCamera()->Zoom(1.0);
renWin->SetSize(300,300);
// interact with data
renWin->Render();
iren->Start();
// clean up rendering stuff
//plane->Delete();
//rgridMapper->Delete();
//wireActor->Delete();
//owireActor->Delete();
//outline->Delete();
//outlineMapper->Delete();
renderer->Delete();
renWin->Delete();
iren->Delete();
#endif // RENDERTEST
surf->Delete();
Cell->Delete();
}
return connectedVertices;
}
// from http://www.vtk.org/Wiki/VTK/Examples/Cxx/PolyData/VertexConnectivity
vtkSmartPointer GetConnectedVertices2(vtkSmartPointer mesh, int id) {
std::cout << "mesh points " << mesh->GetNumberOfPoints() << std::endl;
vtkSmartPointer connectedVertices =
vtkSmartPointer::New();
//get all cells that vertex 'id' is a part of
vtkSmartPointer cellIdList =
vtkSmartPointer::New();
mesh->GetPointCells(id, cellIdList);
/*
for(vtkIdType i = 0; i < cellIdList->GetNumberOfIds(); i++) {
cout << cellIdList->GetId(i) << ", ";
}
cout << endl;
*/
for(vtkIdType i = 0; i < cellIdList->GetNumberOfIds(); i++) {
//cout << "id " << i << " : " << cellIdList->GetId(i) << endl;
vtkSmartPointer pointIdList =
vtkSmartPointer::New();
mesh->GetCellPoints(cellIdList->GetId(i), pointIdList);
//cout << "End points are " << pointIdList->GetId(0) << " and " << pointIdList->GetId(1) << endl;
if(pointIdList->GetId(0) != id) {
//cout << "Connected to " << pointIdList->GetId(0) << endl;
connectedVertices->InsertNextId(pointIdList->GetId(0));
} else {
//cout << "Connected to " << pointIdList->GetId(1) << endl;
connectedVertices->InsertNextId(pointIdList->GetId(1));
}
}
return connectedVertices;
}