You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
316 lines
7.4 KiB
316 lines
7.4 KiB
2 years ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: $RCSfile: vtkInterpolatedVelocityField.cxx,v $
|
||
|
|
||
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
||
|
All rights reserved.
|
||
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
||
|
|
||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||
|
PURPOSE. See the above copyright notice for more information.
|
||
|
|
||
|
=========================================================================*/
|
||
|
#include "vtkInterpolatedVelocityField.h"
|
||
|
|
||
|
#include "vtkDataArray.h"
|
||
|
#include "vtkDataSet.h"
|
||
|
#include "vtkGenericCell.h"
|
||
|
#include "vtkObjectFactory.h"
|
||
|
#include "vtkPointData.h"
|
||
|
|
||
|
#include <vtkstd/vector>
|
||
|
|
||
|
vtkCxxRevisionMacro(vtkInterpolatedVelocityField, "$Revision: 1.2 $");
|
||
|
vtkStandardNewMacro(vtkInterpolatedVelocityField);
|
||
|
|
||
|
typedef vtkstd::vector< vtkDataSet* > DataSetsTypeBase;
|
||
|
class vtkInterpolatedVelocityFieldDataSetsType: public DataSetsTypeBase {};
|
||
|
|
||
|
vtkInterpolatedVelocityField::vtkInterpolatedVelocityField()
|
||
|
{
|
||
|
this->NumFuncs = 3; // u, v, w
|
||
|
this->NumIndepVars = 4; // x, y, z, t
|
||
|
this->Weights = 0;
|
||
|
this->WeightsSize = 0;
|
||
|
this->GenCell = vtkGenericCell::New();
|
||
|
this->LastCellId = -1;
|
||
|
this->CacheHit = 0;
|
||
|
this->CacheMiss = 0;
|
||
|
this->Caching = 1; // Caching on by default
|
||
|
|
||
|
this->Cell = vtkGenericCell::New();
|
||
|
this->VectorsSelection = 0;
|
||
|
|
||
|
this->DataSets = new vtkInterpolatedVelocityFieldDataSetsType;
|
||
|
this->LastDataSet = 0;
|
||
|
}
|
||
|
|
||
|
vtkInterpolatedVelocityField::~vtkInterpolatedVelocityField()
|
||
|
{
|
||
|
this->NumFuncs = 0;
|
||
|
this->NumIndepVars = 0;
|
||
|
this->GenCell->Delete();
|
||
|
delete[] this->Weights;
|
||
|
this->Weights = 0;
|
||
|
|
||
|
this->Cell->Delete();
|
||
|
this->SetVectorsSelection(0);
|
||
|
|
||
|
delete this->DataSets;
|
||
|
}
|
||
|
|
||
|
static int tmp_count=0;
|
||
|
// Evaluate u,v,w at x,y,z,t
|
||
|
int vtkInterpolatedVelocityField::FunctionValues(double* x, double* f)
|
||
|
{
|
||
|
vtkDataSet* ds;
|
||
|
if(!this->LastDataSet && !this->DataSets->empty())
|
||
|
{
|
||
|
ds = (*this->DataSets)[0];
|
||
|
this->LastDataSet = ds;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ds = this->LastDataSet;
|
||
|
}
|
||
|
int retVal = this->FunctionValues(ds, x, f);
|
||
|
if (!retVal)
|
||
|
{
|
||
|
tmp_count = 0;
|
||
|
for(DataSetsTypeBase::iterator i = this->DataSets->begin();
|
||
|
i != this->DataSets->end(); ++i)
|
||
|
{
|
||
|
ds = *i;
|
||
|
if(ds && ds != this->LastDataSet)
|
||
|
{
|
||
|
this->ClearLastCellId();
|
||
|
retVal = this->FunctionValues(ds, x, f);
|
||
|
if (retVal)
|
||
|
{
|
||
|
this->LastDataSet = ds;
|
||
|
return retVal;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
this->ClearLastCellId();
|
||
|
return 0;
|
||
|
}
|
||
|
tmp_count++;
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
const double vtkInterpolatedVelocityField::TOLERANCE_SCALE = 1.0E-8;
|
||
|
|
||
|
// Evaluate u,v,w at x,y,z,t
|
||
|
int vtkInterpolatedVelocityField::FunctionValues(vtkDataSet* dataset,
|
||
|
double* x,
|
||
|
double* f)
|
||
|
{
|
||
|
int i, j, subId , numPts, id;
|
||
|
vtkDataArray* vectors;
|
||
|
double vec[3];
|
||
|
double dist2;
|
||
|
int ret;
|
||
|
|
||
|
for(i=0; i<3; i++)
|
||
|
{
|
||
|
f[i] = 0;
|
||
|
}
|
||
|
|
||
|
// See if a dataset has been specified and if there are input vectors
|
||
|
if (!dataset ||
|
||
|
!(vectors = dataset->GetPointData()->GetVectors(this->VectorsSelection)))
|
||
|
{
|
||
|
vtkErrorMacro(<<"Can't evaluate dataset!");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
double tol2 =
|
||
|
dataset->GetLength() * vtkInterpolatedVelocityField::TOLERANCE_SCALE;
|
||
|
|
||
|
int found = 0;
|
||
|
|
||
|
if (this->Caching)
|
||
|
{
|
||
|
// See if the point is in the cached cell
|
||
|
if (this->LastCellId == -1 ||
|
||
|
!(ret=this->GenCell->EvaluatePosition(x, 0, subId,
|
||
|
this->LastPCoords, dist2,
|
||
|
this->Weights))
|
||
|
|| ret == -1)
|
||
|
{
|
||
|
// if not, find and get it
|
||
|
if (this->LastCellId != - 1 )
|
||
|
{
|
||
|
this->CacheMiss++;
|
||
|
|
||
|
dataset->GetCell(this->LastCellId, this->Cell);
|
||
|
|
||
|
this->LastCellId =
|
||
|
dataset->FindCell(x, this->Cell, this->GenCell, -1, tol2,
|
||
|
subId, this->LastPCoords, this->Weights);
|
||
|
if (this->LastCellId != - 1)
|
||
|
{
|
||
|
dataset->GetCell(this->LastCellId, this->GenCell);
|
||
|
found = 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->CacheHit++;
|
||
|
found = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!found)
|
||
|
{
|
||
|
// if the cell is not found, do a global search (ignore initial
|
||
|
// cell if there is one)
|
||
|
this->LastCellId =
|
||
|
dataset->FindCell(x, 0, this->GenCell, -1, tol2,
|
||
|
subId, this->LastPCoords, this->Weights);
|
||
|
if (this->LastCellId != - 1)
|
||
|
{
|
||
|
dataset->GetCell(this->LastCellId, this->GenCell);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// if the cell is valid
|
||
|
if (this->LastCellId >= 0)
|
||
|
{
|
||
|
numPts = this->GenCell->GetNumberOfPoints();
|
||
|
// interpolate the vectors
|
||
|
for (j=0; j < numPts; j++)
|
||
|
{
|
||
|
id = this->GenCell->PointIds->GetId(j);
|
||
|
vectors->GetTuple(id, vec);
|
||
|
for (i=0; i < 3; i++)
|
||
|
{
|
||
|
f[i] += vec[i] * this->Weights[j];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// if not, return false
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
void vtkInterpolatedVelocityField::AddDataSet(vtkDataSet* dataset)
|
||
|
{
|
||
|
if (!dataset)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->DataSets->push_back(dataset);
|
||
|
|
||
|
int size = dataset->GetMaxCellSize();
|
||
|
if (size > this->WeightsSize)
|
||
|
{
|
||
|
this->WeightsSize = size;
|
||
|
delete[] this->Weights;
|
||
|
this->Weights = new double[size];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int vtkInterpolatedVelocityField::GetLastWeights(double* w)
|
||
|
{
|
||
|
int j, numPts;
|
||
|
|
||
|
// If last cell is valid, fill w with the interpolation weights
|
||
|
// and return true
|
||
|
if (this->LastCellId >= 0)
|
||
|
{
|
||
|
numPts = this->GenCell->GetNumberOfPoints();
|
||
|
for (j=0; j < numPts; j++)
|
||
|
{
|
||
|
w[j] = this->Weights[j];
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
// otherwise, return false
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int vtkInterpolatedVelocityField::GetLastLocalCoordinates(double pcoords[3])
|
||
|
{
|
||
|
int j;
|
||
|
|
||
|
// If last cell is valid, fill p with the local coordinates
|
||
|
// and return true
|
||
|
if (this->LastCellId >= 0)
|
||
|
{
|
||
|
for (j=0; j < 3; j++)
|
||
|
{
|
||
|
pcoords[j] = this->LastPCoords[j];
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
// otherwise, return false
|
||
|
else
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void vtkInterpolatedVelocityField::CopyParameters(
|
||
|
vtkInterpolatedVelocityField* from)
|
||
|
{
|
||
|
this->Caching = from->Caching;
|
||
|
}
|
||
|
|
||
|
void vtkInterpolatedVelocityField::PrintSelf(ostream& os, vtkIndent indent)
|
||
|
{
|
||
|
this->Superclass::PrintSelf(os, indent);
|
||
|
if ( this->VectorsSelection )
|
||
|
{
|
||
|
os << indent << "VectorsSelection: " << this->VectorsSelection << endl;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
os << indent << "VectorsSelection: (none)" << endl;
|
||
|
}
|
||
|
if ( this->GenCell )
|
||
|
{
|
||
|
os << indent << "Last cell: " << this->GenCell << endl;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
os << indent << "Last cell: (none)" << endl;
|
||
|
}
|
||
|
os << indent << "Weights: " << this->Weights << endl;
|
||
|
os << indent << "Last cell Id: " << this->LastCellId << endl;
|
||
|
os << indent << "Cache hit: " << this->CacheHit << endl;
|
||
|
os << indent << "Cache miss: " << this->CacheMiss << endl;
|
||
|
os << indent << "Caching: ";
|
||
|
if ( this->Caching )
|
||
|
{
|
||
|
os << "on." << endl;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
os << "off." << endl;
|
||
|
}
|
||
|
|
||
|
os << indent << "VectorsSelection: "
|
||
|
<< (this->VectorsSelection?this->VectorsSelection:"(none)") << endl;
|
||
|
os << indent << "LastDataSet : "
|
||
|
<< this->LastDataSet << endl;
|
||
|
|
||
|
}
|
||
|
|