Skip to main content

DPF C++ client library 2023 R2

OperatorsApis

Last update: 10.07.2023

Examples showing how to use the DPF operators to compute the data.

//
// COPYRIGHT ANSYS. ALL RIGHTS RESERVED.
//
#include "dpf_api.h"
#include <limits>
#ifdef EXAMPLE
#include "Example.h"
#else
#include <gtest/gtest.h>
#endif
TEST(Operator, ImportAndReadData)
{
// Those operators allow to read data from solver files or from standard file types.
// Different solver format are handled by DPF like rst/mode/rfrq/rdsp.. for MAPDL, d3plot
// for LsDyna, cas.h5/dat.h5/res/flprj for CFX and Fluent, odb for Abaqus... To read those,
// different readers have been implemented in plugins. Plugins can be loaded on demand in
// any dpf's scripting language with the "load library" methods. File readers can be used
// generically thanks to dpf's result providers, which means that the same operators can
// be used for any file types. For example, reading a displacement or a stress for any files
// will be done with the following code.
// set the result file path to the right path
std::string fileName("../../../testfiles/mapdl_files/TwoSolids.rst");
ansys::dpf::DataSources my_data_sources;
my_data_sources.addResultFile(fileName);
//displacement for any solver file
u_op.connect(ansys::dpf::eDataSourcesPin, my_data_sources);
//stress for any solver file
s_op.connect(ansys::dpf::eDataSourcesPin, my_data_sources);
}
TEST(Operator, ImportAndReadDataCustom)
{
// Result providers can be customized to read a specific time frequency or to provide
// results on a subset of the mesh.
// set the result file path to the right path
std::string fileName("../../../testfiles/mapdl_files/TwoSolids.rst");
ansys::dpf::DataSources my_data_sources;
my_data_sources.addResultFile(fileName);
//displacement for any solver file
u_op.connect(ansys::dpf::eDataSourcesPin, my_data_sources);
// Different ways to set the time scoping
// Select one time/frequency
u_op.connect(ansys::dpf::eTimeScopPin, 2); // Int : Select second time/freq set in the time freq support
u_op.connect(ansys::dpf::eTimeScopPin, 0.002); // Double : Gives a field interpolated at the given time/freq value
// Select multiple times/frequencies
std::vector<int> time_sets = { 1,2,3 };
u_op.connect(ansys::dpf::eTimeScopPin, time_sets); // Vec Int: Select time/freq sets in the time freq support
std::vector<double> times = { 0.002, 0.003 };
u_op.connect(ansys::dpf::eTimeScopPin, times); // Vec Double : Gives fields interpolated at the given time/freq values
// Select all the time/frequencies of a load step
u_op.connect(ansys::dpf::eTimeScopPin, load_step);
u_op.connect(ansys::dpf::eMeshScopPin, node_scoping);
u_op.connect(ansys::dpf::eMeshScopPin, element_scoping);
// uncomment this line to compute the fields container.
// this requires a license.
// ansys::dpf::FieldsContainer my_u = u_op.getOutputFieldsContainer(0);;
}
TEST(Operator, ReadExportedData)
{
// Standards file formats reader are also supported to import custom data.
// Fields can be imported from csv, vtk or hdf5 files
std::string my_path = "c:/temp/file.csv";
ansys::dpf::DataSources my_data_sources;
my_data_sources.addResultFile(my_path);
ansys::dpf::Operator csv("csv_to_field");
csv.connect(ansys::dpf::eDataSourcesPin, my_data_sources);
// uncomment this line to compute the fields container.
// this requires a license.
// ansys::dpf::FieldsContainer my_fields = csv.getOutputFieldsContainer(0);
}
TEST(Operator, TransformingExistingData)
{
// The field being the main data container in DPF, most of the operator transforming the data
// take a field or fields container as input and return a transformed field or fields container
// in output. Analytic, averaging or filtering operations can be performed on the simulation data
field1.setData({ 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0 });
field1.scoping().setIds({ 1,2,3 });
// using analytic operator: scale operator
ansys::dpf::Operator op1("scale");
op1.connect(0, field1);
op1.connect(1, 2.0);
ansys::dpf::Field out = op1.getOutputField(0);
int size = 0;
ansys::dpf::dp_double* const data = out.data(size);
// returns:
// { 2., 4., 6., 8., 10., 12., 14., 16., 18.}
}
TEST(Operator, ExportingData)
{
// After transforming or reading simulation data with DPF, the user might want to export the
// results in a given format to use it in another environment or to save it for future use with
// dpf. Vtk, h5, csv and txt (serializer operator) are examples of supported exports. Export
// operators often match with import operators allowing user to reuse their data. The
// "serialization" operators menu lists the available import/export operators.
// set the result file path to the right path
std::string fileName("../../../testfiles/mapdl_files/TwoSolids.rst");
ansys::dpf::DataSources my_data_sources;
my_data_sources.addResultFile(fileName);
//displacement for any solver file
u_op.connect(ansys::dpf::eDataSourcesPin, my_data_sources);
ansys::dpf::FieldsContainer my_fields = u_op.getOutputFieldsContainer(0);
//scale it by 2.0
ansys::dpf::Operator my_scale_op("scale_fc");
my_scale_op.connect(0, my_fields);
my_scale_op.connect(1, 2.0);
//get the mesh
ansys::dpf::Operator my_mesh_op("MeshProvider");
my_mesh_op.connect(ansys::dpf::eDataSourcesPin, my_data_sources);
// export the result in vtk
// uncomment the following code to enable the export operations
// this requires a license.
//ansys::dpf::Operator my_export("vtk_export");
//my_export.connect(0, std::string("C:/temp/fileNew.vtk"));
//my_export.connect(1, my_mesh_op, 0);
//my_export.connect(2, my_scale_op, 0);
// my_export.run();
}
TEST(Operator, ChainingOperators)
{
// To create more complex operations and customizable results, operators can be
// chained together to create workflows. This way a result can be read from a solver
// result file and directly transformed in a single workflow. Examples can be found
// in APIs/Workflow examples menu. 2 syntaxes can be used to create and connect
// operators together.
// set the result file path to the right path
std::string fileName("../../../testfiles/mapdl_files/TwoSolids.rst");
ansys::dpf::DataSources my_data_sources;
my_data_sources.addResultFile(fileName);
u_op.connect(ansys::dpf::eDataSourcesPin, my_data_sources);
ansys::dpf::Operator norm_op("norm_fc");
norm_op.connect(0, u_op, 0); //connect norm_op input pin 0 to u_op output pin 0
ansys::dpf::FieldsContainer my_u_norm = norm_op.getOutputFieldsContainer(0);
}
TEST(Operator, UsingConfigurations)
{
// Advanced user might want to configurate an operator's behavior during its running phase.
// This can be done through the "config". This option allows to choose if an operator can
// directly modify the input data container instead of creating a new one with the "inplace"
// configuration, to choose if an operation between to fields should use their indices or mesh
// ids with the "work_by_index" configuration... Each operator's description explains which
// configuration are supported.
field1.setData({ 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0 });
field1.scoping().setIds({ 1,2,3 });
field2.setData({ 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0 });
field2.scoping().setIds({ 3,4,5 });
bool current_value = config.getBoolValue("work_by_index");//returns current values of configuration
//modify work_by_index config (default is false)
config.set("work_by_index", true);
//instantiate the operator with the config
ansys::dpf::Operator op1("add", config);
op1.connect(0, field1);
op1.connect(1, field2);
ansys::dpf::Field out = op1.getOutputField(0);
int size = 0;
ansys::dpf::dp_double* const data = out.data(size);
// returns:
// { 2., 4., 6., 8., 10., 12., 14., 16., 18.}
//use default config value
config.set("work_by_index", false);
op1 = ansys::dpf::Operator("add", config);
op1.connect(0, field1);
op1.connect(1, field2);
out = op1.getOutputField(0);
ansys::dpf::dp_double* const data2 = out.data(size);
// returns:
// { 1., 2., 3., 4., 5., 6., 8., 10., 12., 4., 5., 6., 7., 8., 9.}
// changing the "permissive" config could allow to add fields of different homogeneities
// changing the "binary_operation" config could allow to keep only the intersection between fields ids and not the union
//...
}
Definition: dpf_api.h:1954
void addResultFile(std::string const &file_path, std::string const &key)
Data for an entity.
Definition: dpf_api.h:890
dp_double *const data(int &size) const
void setData(std::vector< double > const &data)
Contains a group of fields.
Definition: dpf_api.h:1566
Definition: dpf_api.h:3490
void set(std::string const &option, dp_int value)
bool getBoolValue(std::string const &option) const
Wrap an elementary operation.
Definition: dpf_api.h:2216
FieldsContainer getOutputFieldsContainer(dp_index pin_index)
Define a set of entities by ids.
Definition: dpf_api.h:736
static OperatorConfig defaultOperatorConfig(std::string const &op_identifier, Client const *const client=nullptr)
@ eDataSourcesPin
Definition: dpf_api.h:2150
@ eMeshScopPin
Definition: dpf_api.h:2144
@ eTimeScopPin
Definition: dpf_api.h:2142
double dp_double
Definition: dpf_api_base.h:54
static const Location elemental
Definition: dpf_api_base.h:168
static const Location nodal
Definition: dpf_api_base.h:166
static const Location time_step
Definition: dpf_api_base.h:190