Commit 9d1fbf82 authored by Mathieu Westphal's avatar Mathieu Westphal Committed by Kitware Robot
Browse files

Merge topic 'AddingLagrangianParticleTracker'

4e115c2e LagrangianParticleTracker Plugin
92a149c1 Make CreatePrettyLabel a static public method
92544da1 Adding DisableSubTrace member to SMProperty
ad4efa94 Correcting GhostLevel for Polydata
52c75931 Correcting selected_proxy_panel_visibility management
40866b7c

 Adding Integrators and Locators in utilities.xml
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Reviewed-by: default avatarJoachim Pouderoux <joachim.pouderoux@kitware.com>
Merge-request: !1254
parents aacadbcd 4e115c2e
cmake_minimum_required(VERSION 2.8)
IF (NOT ParaView_BINARY_DIR)
FIND_PACKAGE(ParaView REQUIRED)
INCLUDE(${PARAVIEW_USE_FILE})
ENDIF ()
add_paraview_plugin(LagrangianIntegrationModelExample "1.0"
SERVER_MANAGER_XML LagrangianIntegrationModelExample.xml
SERVER_MANAGER_SOURCES vtkLagrangianIntegrationModelExample.cxx
)
target_link_libraries(LagrangianIntegrationModelExample ${ParaView_LIBRARIES})
<ServerManagerConfiguration>
<ProxyGroup name="lagrangian_integration_models">
<Proxy base_proxygroup="lagrangian_integration_models_abstract"
base_proxyname="BasicIntegrationModel"
class="vtkLagrangianIntegrationModelExample"
name="LagrangianIntegrationModelExample"
label="Integration Model Example">
<StringVectorProperty animateable="0"
command="SetInputArrayToProcess"
default_values_delimiter=";"
default_values="1;0;0;3;FlowVelocity"
element_types="0 0 0 0 2"
label="Flow Velocity"
name="FlowVelocity"
number_of_elements="5">
<ArrayListDomain name="array_list"
attribute_type="Vectors"
input_domain_name="input_array_3">
<RequiredProperties>
<Property function="Input"
name="DummyInput" />
</RequiredProperties>
</ArrayListDomain>
<FieldDataDomain name="field_list">
<RequiredProperties>
<Property function="Input"
name="DummyInput" />
</RequiredProperties>
</FieldDataDomain>
<Documentation>This property contains the name of
the array to use as flow velocity.</Documentation>
</StringVectorProperty>
<StringVectorProperty animateable="0"
command="SetInputArrayToProcess"
default_values_delimiter=";"
default_values="2;0;0;3;FlowDensity"
element_types="0 0 0 0 2"
label="Flow Density"
name="FlowDensity"
number_of_elements="5">
<ArrayListDomain name="array_list"
attribute_type="Scalars"
input_domain_name="input_array_1">
<RequiredProperties>
<Property function="Input"
name="DummyInput" />
</RequiredProperties>
</ArrayListDomain>
<FieldDataDomain name="field_list">
<RequiredProperties>
<Property function="Input"
name="DummyInput" />
</RequiredProperties>
</FieldDataDomain>
<Documentation>This property contains the name of
the array to use as flow density.</Documentation>
</StringVectorProperty>
<StringVectorProperty animateable="0"
command="SetInputArrayToProcess"
default_values_delimiter=";"
default_values="3;0;0;3;FlowDynamicViscosity"
element_types="0 0 0 0 2"
label="Flow Dynamic Viscosity"
name="FlowDynamicViscosity"
number_of_elements="5">
<ArrayListDomain name="array_list"
input_domain_name="input_array_1">
<RequiredProperties>
<Property function="Input"
name="DummyInput" />
</RequiredProperties>
</ArrayListDomain>
<FieldDataDomain name="field_list">
<RequiredProperties>
<Property function="Input"
name="DummyInput" />
</RequiredProperties>
</FieldDataDomain>
<Documentation>This property contains the name of
the array to use as flow dynamic viscosity.</Documentation>
</StringVectorProperty>
<StringVectorProperty animateable="0"
command="SetInputArrayToProcess"
default_values_delimiter=";"
default_values="4;1;0;0;ParticleDiameter"
element_types="0 0 0 0 2"
label="ParticleDiameter"
name="Particle Diameter"
number_of_elements="5">
<ArrayListDomain name="array_list"
input_domain_name="source_array_point_1">
<RequiredProperties>
<Property function="Input"
name="DummySource" />
</RequiredProperties>
</ArrayListDomain>
<FieldDataDomain name="field_list">
<RequiredProperties>
<Property function="Input"
name="DummySource" />
</RequiredProperties>
</FieldDataDomain>
<Documentation>This property contains the name of
the array to use from seeds as particle diameter.</Documentation>
</StringVectorProperty>
<StringVectorProperty animateable="0"
command="SetInputArrayToProcess"
default_values_delimiter=";"
default_values="5;1;0;0;ParticleDensity"
element_types="0 0 0 0 2"
label="ParticleDensity"
name="Particle Density"
number_of_elements="5">
<ArrayListDomain name="array_list"
input_domain_name="source_array_point_1">
<RequiredProperties>
<Property function="Input"
name="DummySource" />
</RequiredProperties>
</ArrayListDomain>
<FieldDataDomain name="field_list">
<RequiredProperties>
<Property function="Input"
name="DummySource" />
</RequiredProperties>
</FieldDataDomain>
<Documentation>This property contains the name of
the array to use from seeds as particle density.</Documentation>
</StringVectorProperty>
<StringVectorProperty animateable="0"
command="SetInputArrayToProcess"
default_values_delimiter=";"
default_values="6;0;0;2;GravityConstant"
element_types="0 0 0 0 2"
label="GravityConstant"
name="Gravity Constant"
number_of_elements="5">
<ArrayListDomain name="array_list"
input_domain_name="input_array_field">
<RequiredProperties>
<Property function="Input"
name="DummyInput" />
</RequiredProperties>
</ArrayListDomain>
<Documentation>This property contains the name of
the array to use from flow input as gravity constant.</Documentation>
</StringVectorProperty>
</Proxy>
</ProxyGroup>
</ServerManagerConfiguration>
Introduction
============
This is an example plugin for implementing
your own LagrangianIntegrationModel to be used in
the LagrangianParticleTracker
For more information about these classes please consult
vtkLagrangianParticleTracker.h and vtkLagrangianBasicIntegrationModel.h
Each example class is self-documented.
Notes about Integration Model XML
=================================
This is a line by line explanation for LagrangianIntegrationModelExample.xml
<ServerManagerConfiguration> // Mandatory
<ProxyGroup name="lagrangian_integration_models"> // Name is very important, mandatory
<Proxy base_proxygroup="lagrangian_integration_models_abstract" // Mandatory
base_proxyname="BasicIntegrationModel" // Mandatory
class="vtkLagrangianMatidaIntegrationModel" // the name of one own class, inherited from vtkLagrangianBasicIntegrationModel
name="MatidaIntegrationModel" // Shorter name, your choice
label="Matida Integration Model"> // Display name, your choice
// Use a property like this to add a selectable input array in the gui of the filter when using one own integration model
<StringVectorProperty animateable="0" // Mandatory, no animation support
command="SetInputArrayToProcess" // Mandatory, this method has 5
// arguments : SetInputArrayToProcess(index, port, connection, fieldAssociation, arrayName)
// index : a user index in order to identify the array, define it in default values, start at 1, index 0 is reserved.
// port : the port number , define it in default values
// connection : the connection in the port, define it in default values but should not be needed in tracker context
// fieldAssociaction : point data or cell data, defined in FieldDataDomain
// arrayName : actual array name, passed be paraview.
default_values_delimiter=";" // Only when using default values for multiples args, ie more than just the index
default_values="2;1;0;0:ParticleDiameter" // Default values, here it is port 1 with index 2, connection 0, type is PointData
// (use 1 for CellData , 2 for fieldData, 3 for any), and default name of the array if available
element_types="0 0 0 0 2" // argument type, mandatory with SetInputArrayToProcess
label="FlowVelocity" // Label shown in the UI ( with space before high case char )
name="SelectFlowVelocity" // Name of the property
number_of_elements="5"> // Mandatory with SetInputArrayToProcess
<ArrayListDomain name="array_list" // mandatory
input_domain_name="input_array_3" // To select only certain available array for the user,
// here it is input array with 3 component. see vtkLagrangianBasicIntegrationModel in utilities.xml for a list of available domain.
// FieldData are supported as well
// not setting an input_domain_name is allright and will let the user choose between all available arrays
attribute_type="Scalars"> // Not mandatory, this will change the default array selected, allowing one to have the "Scalars" or the "Vectors" selected by defaylt in the gui
<RequiredProperties> // Mandatory
<Property function="Input" // Mandatory
name="DummySource" /> // a Named property is Mandatory, but ont need to choose the correct one
// the flow input is called DummyInput
// the seed are called DummySource
// the surfaces are called DummySurface
</RequiredProperties>
</ArrayListDomain>
<FieldDataDomain name="field_list"> // Needed if one want to be able to recover the field association, recommended.
<RequiredProperties> // Should be the same as above RequiredProperties
<Property function="Input"
name="DummyInput" />
</RequiredProperties>
</FieldDataDomain>
<Documentation>This property contains the name of // Documentation for the property
the array to use as flow velocity.</Documentation>
</StringVectorProperty>
// And any other kinds of property one may want, like in any vtk/paraview filter.
</Proxy>
</ProxyGroup>
</ServerManagerConfiguration>
#include "vtkLagrangianIntegrationModelExample.h"
#include "vtkDataSet.h"
#include "vtkDoubleArray.h"
#include "vtkIntArray.h"
#include "vtkLagrangianParticle.h"
#include "vtkMath.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkStringArray.h"
#include <cstring>
vtkObjectFactoryNewMacro(vtkLagrangianIntegrationModelExample)
vtkLagrangianIntegrationModelExample::vtkLagrangianIntegrationModelExample()
{
// Fill the helper array
// Here one should set the seed and surface array name and components
// It will enable the uses of helper filters
this->SeedArrayNames->InsertNextValue("Particle Diameter");
this->SeedArrayComps->InsertNextValue(1);
this->SeedArrayTypes->InsertNextValue(VTK_DOUBLE);
this->SeedArrayNames->InsertNextValue("Particle Density");
this->SeedArrayComps->InsertNextValue(1);
this->SeedArrayTypes->InsertNextValue(VTK_DOUBLE);
// No Enum surface entry
SurfaceArrayDescription surfaceType2Description;
surfaceType2Description.nComp = 1;
surfaceType2Description.type = VTK_CHAR;
this->SurfaceArrayDescriptions["SurfaceType2"] = surfaceType2Description;
// More enum surface entry, use a reference "&" !
SurfaceArrayDescription& surfaceTypeDescription = this->SurfaceArrayDescriptions["SurfaceType"];
surfaceTypeDescription.enumValues.push_back(std::make_pair(101, "SpecificModel"));
this->NumIndepVars = 8; // x, y, z, u, v, w, diameter, t
this->NumFuncs = this->NumIndepVars - 1;
}
vtkLagrangianIntegrationModelExample::~vtkLagrangianIntegrationModelExample()
{
}
void vtkLagrangianIntegrationModelExample::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
int vtkLagrangianIntegrationModelExample::FunctionValues(
vtkDataSet* dataSet, vtkIdType cellId, double* weights, double* x, double* f)
{
// Initialize output
std::fill(f, f + this->NumFuncs, 0.0);
// Check for a particle
if (this->CurrentParticle == NULL)
{
vtkErrorMacro(<< "No Particle to integrate");
return 0;
}
// Sanity Check
if (dataSet == NULL || cellId == -1)
{
vtkErrorMacro(<< "No cell or dataset to integrate the Particle on : Dataset: " << dataSet
<< " CellId:" << cellId);
return 0;
}
// Recover Flow Properties
int nComponent;
double* tmp;
// Fetch each array at correct indexes, as defined in the xml.
// Fetch flowVelocity at index 3
if (!this->GetFlowOrSurfaceData(3, dataSet, cellId, weights, tmp, nComponent) || nComponent != 3)
{
vtkErrorMacro("Flow velocity is not set in source flow dataset or "
"have incorrect number of components, cannot use Matida equations");
return 0;
}
// do not forget to copy the data
double flowVelocity[3];
std::memcpy(flowVelocity, tmp, sizeof(double) * nComponent);
// Fetch flowDensity at index 4
if (!this->GetFlowOrSurfaceData(4, dataSet, cellId, weights, tmp, nComponent) || nComponent != 1)
{
vtkErrorMacro("Flow density is not set in source flow dataset or "
"have incorrect number of components, cannot use Matida equations");
return 0;
}
double flowDensity = *tmp;
// Fetch flowDynamicViscosity at index 5
if (!this->GetFlowOrSurfaceData(5, dataSet, cellId, weights, tmp, nComponent) || nComponent != 1)
{
vtkErrorMacro("Flow dynamic viscosity is not set in source flow dataset or "
"have incorrect number of components, cannot use Matida equations");
return 0;
}
double flowDynamicViscosity = *tmp;
// Fetch Particle Properties
vtkIdType tupleIndex = this->CurrentParticle->GetSeedArrayTupleIndex();
// Fetch Particle Diameter as the first user variables
double particleDiameter = this->CurrentParticle->GetUserVariables()[0];
// Fetch Particle Density at index 7
vtkDataArray* particleDensities =
vtkDataArray::SafeDownCast(this->GetSeedArray(7, this->CurrentParticle));
if (particleDensities == NULL)
{
vtkErrorMacro("Particle density is not set in particle data, "
"cannot use Matida equations");
return 0;
}
double particleDensity = particleDensities->GetTuple1(tupleIndex);
// Recover Gravity constant, idx 8, FieldData, as defined in the xml.
// We read at a index 0 because these is the only tuple in the fieldData
if (!this->GetFlowOrSurfaceData(8, dataSet, 0, weights, tmp, nComponent) || nComponent != 1)
{
vtkErrorMacro("GravityConstant is not set in source flow dataset or have"
"incorrect number of components, cannot use Matida Equations");
return 0;
}
double gravityConstant = *tmp;
// Compute function values
for (int i = 0; i < 3; i++)
{
// Matida Equation
f[i + 3] = (flowVelocity[i] - x[i + 3]) *
this->GetDragCoefficient(flowVelocity, this->CurrentParticle->GetVelocity(),
flowDynamicViscosity, particleDiameter, flowDensity) /
(this->GetRelaxationTime(flowDynamicViscosity, particleDiameter, particleDensity));
f[i] = x[i + 3];
}
// Use the read gravity constant instead of G
f[5] -= gravityConstant * (1 - (flowDensity / particleDensity));
// Compute the supplementary variable diameter
f[6] = -particleDiameter * 1 / 10;
return 1;
}
//---------------------------------------------------------------------------
double vtkLagrangianIntegrationModelExample::GetRelaxationTime(
const double& dynVisc, const double& diameter, const double& density)
{
if (dynVisc == 0)
{
return std::numeric_limits<double>::infinity();
}
else
{
return (density * diameter * diameter) / (18.0 * dynVisc);
}
}
//---------------------------------------------------------------------------
double vtkLagrangianIntegrationModelExample::GetDragCoefficient(const double* flowVelocity,
const double* particleVelocity, const double& dynVisc, const double& particleDiameter,
const double& flowDensity)
{
if (dynVisc == 0)
{
return -1.0 * std::numeric_limits<double>::infinity();
}
else
{
double relativeVelocity[3];
for (int i = 0; i < 3; i++)
{
relativeVelocity[i] = particleVelocity[i] - flowVelocity[i];
}
double relativeSpeed = vtkMath::Norm(relativeVelocity);
double reynolds = flowDensity * relativeSpeed * particleDiameter / dynVisc;
return (1 + 0.15 * pow(reynolds, 0.687));
}
}
//----------------------------------------------------------------------------
void vtkLagrangianIntegrationModelExample::InitializeParticle(vtkLagrangianParticle* particle)
{
double* diameter = particle->GetUserVariables();
// Recover Particle Diameter, idx 6, see xml file
vtkDoubleArray* particleDiameters = vtkDoubleArray::SafeDownCast(this->GetSeedArray(6, particle));
if (particleDiameters == NULL)
{
vtkErrorMacro("ParticleDiameter is not set in particle data, variable not set");
}
else
{
// Copy seed data to user variables
*diameter = particleDiameters->GetTuple1(particle->GetSeedArrayTupleIndex());
}
}
//----------------------------------------------------------------------------
void vtkLagrangianIntegrationModelExample::InitializeVariablesParticleData(
vtkPointData* variablesParticleData, int maxTuples)
{
// Create a double array
vtkNew<vtkDoubleArray> diameterArray;
// Name it
diameterArray->SetName("VariableDiameter");
// Set the number of component
int nComp = 1;
diameterArray->SetNumberOfComponents(nComp);
// Allocate a default number of tuple, multiplied
// by the number of components
diameterArray->Allocate(maxTuples * nComp);
variablesParticleData->AddArray(diameterArray.Get());
}
//----------------------------------------------------------------------------
void vtkLagrangianIntegrationModelExample::InsertVariablesParticleData(
vtkLagrangianParticle* particle, vtkPointData* data, int stepEnum)
{
vtkDataArray* diameterArray = data->GetArray("VariableDiameter");
// Add the correct data depending of the step enum
// Previous, Current or Next
switch (stepEnum)
{
case (vtkLagrangianBasicIntegrationModel::VARIABLE_STEP_PREV):
{
// Always use InsertNextTuple methods to add data
diameterArray->InsertNextTuple1(particle->GetPrevUserVariables()[0]);
break;
}
case (vtkLagrangianBasicIntegrationModel::VARIABLE_STEP_CURRENT):
{
diameterArray->InsertNextTuple1(particle->GetUserVariables()[0]);
break;
}
case (vtkLagrangianBasicIntegrationModel::VARIABLE_STEP_NEXT):
{
diameterArray->InsertNextTuple1(particle->GetNextUserVariables()[0]);
break;
}
}
}
//----------------------------------------------------------------------------
bool vtkLagrangianIntegrationModelExample::CheckFreeFlightTermination(
vtkLagrangianParticle* particle)
{
// Free Flight example, depending of the variable diameter of the particle we
// choose to terminate the particle or not
return (particle->GetUserVariables()[0] < 0.07);
}
//----------------------------------------------------------------------------
bool vtkLagrangianIntegrationModelExample::InteractWithSurface(vtkLagrangianParticle* particle,
vtkDataSet* surface, vtkIdType cellId, std::queue<vtkLagrangianParticle*>& vtkNotUsed(particles))
{
// Surface Interaction example, depending of the variable diameter of the
// particle we choose to do one thing or the other
if (particle->GetUserVariables()[0] > 0.075)
{
// One could even redefine its own way to bounce, eg BounceSpecific(particle...)
// Or even redefine BounceParticle for all bounce surface
return this->BounceParticle(particle, surface, cellId);
}
else
{
return this->TerminateParticle(particle);
}
}
//----------------------------------------------------------------------------
bool vtkLagrangianIntegrationModelExample::IntersectWithLine(
vtkCell* cell, double p1[3], double p2[3], double tol, double& t, double x[3])
{
// Here one could implement its own intersection code
return this->Superclass::IntersectWithLine(cell, p1, p2, tol, t, x);
}
//----------------------------------------------------------------------------
void vtkLagrangianIntegrationModelExample::ComputeSurfaceDefaultValues(
const char* arrayName, vtkDataSet* dataset, int nComponents, double* defaultValues)
{
if (strcmp(arrayName, "SurfaceType2") == 0)
{
for (int i = 0; i < nComponents; i++)
{
defaultValues[i] = 3;
}
return;
}
else if (strcmp(arrayName, "SurfaceType") == 0)
{
for (int i = 0; i < nComponents; i++)
{
defaultValues[i] = 2;
}
return;
}
else
{
this->Superclass::ComputeSurfaceDefaultValues(arrayName, dataset, nComponents, defaultValues);
}
}
/*=========================================================================
Program: ParaView
Module: vtkLagrangianIntegrationModelExample.h
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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.
=========================================================================*/
/**
* @class vtkLagrangianIntegrationModelExample
* @brief Integration model example
*
* Similar to vtkLagrangianMatidaIntegrationModel
* this integration model demonstrates the capabilities
* of Lagrangian Integration Models
* The mains differences with Matida version are