1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
// SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
// SPDX-License-Identifier: BSD-3-Clause
#ifndef CatalystAdaptor_h
#define CatalystAdaptor_h
#include "FEDataStructures.h"
#include <catalyst.hpp>
#include <iostream>
#include <string>
namespace CatalystAdaptor
{
/**
* In this example, we show how we can use Catalysts's C++
* wrapper around conduit's C API to create Conduit nodes.
* This is not required. A C++ adaptor can just as
* conveniently use the Conduit C API to setup the
* `conduit_node`. However, this example shows that one can
* indeed use Catalyst's C++ API, if the developer so chooses.
*/
void Initialize(int argc, char* argv[])
{
conduit_cpp::Node node;
for (int cc = 1; cc < argc; ++cc)
{
node["catalyst/scripts/script" + std::to_string(cc - 1)].set_string(argv[cc]);
}
node["catalyst_load/implementation"] = "paraview";
node["catalyst_load/search_paths/paraview"] = PARAVIEW_IMPL_DIR;
catalyst_status err = catalyst_initialize(conduit_cpp::c_node(&node));
if (err != catalyst_status_ok)
{
std::cerr << "Failed to initialize Catalyst: " << err << std::endl;
}
}
void Execute(int cycle, double time, Grid& grid, Attributes& attribs)
{
conduit_cpp::Node exec_params;
// add time/cycle information
auto state = exec_params["catalyst/state"];
state["timestep"].set(cycle);
state["time"].set(time);
// Add channels.
// We only have 1 channel here. Let's name it 'grid'.
auto channel = exec_params["catalyst/channels/grid"];
// Since this example is using Conduit Mesh Blueprint to define the mesh,
// we set the channel's type to "mesh".
channel["type"].set("mesh");
// now create the mesh.
auto mesh = channel["data"];
// start with coordsets (of course, the sequence is not important, just make
// it easier to think in this order).
mesh["coordsets/coords/type"].set("explicit");
mesh["coordsets/coords/values/x"].set_external(const_cast<double*>(&grid.GetPoints()[0]),
grid.GetNumberOfPoints(), /*offset=*/0, /*stride=*/3 * sizeof(double));
mesh["coordsets/coords/values/y"].set_external(const_cast<double*>(&grid.GetPoints()[0]),
grid.GetNumberOfPoints(),
/*offset=*/sizeof(double), /*stride=*/3 * sizeof(double));
mesh["coordsets/coords/values/z"].set_external(const_cast<double*>(&grid.GetPoints()[0]),
grid.GetNumberOfPoints(),
/*offset=*/2 * sizeof(double), /*stride=*/3 * sizeof(double));
// Next, add topology
mesh["topologies/mesh/type"].set("unstructured");
mesh["topologies/mesh/coordset"].set("coords");
// add elements
using VecT = std::vector<unsigned int>;
mesh["topologies/mesh/elements/shape"].set("polygonal");
mesh["topologies/mesh/elements/connectivity"].set_external(
const_cast<VecT&>(grid.GetPolygonalCells().Connectivity));
mesh["topologies/mesh/elements/sizes"].set_external(
const_cast<VecT&>(grid.GetPolygonalCells().Sizes));
mesh["topologies/mesh/elements/offsets"].set_external(
const_cast<VecT&>(grid.GetPolygonalCells().Offsets));
// Finally, add fields.
auto fields = mesh["fields"];
fields["velocity/association"].set("vertex");
fields["velocity/topology"].set("mesh");
fields["velocity/volume_dependent"].set("false");
// velocity is stored in non-interlaced form (unlike points).
fields["velocity/values/x"].set_external(
attribs.GetVelocityArray(), grid.GetNumberOfPoints(), /*offset=*/0);
fields["velocity/values/y"].set_external(attribs.GetVelocityArray(), grid.GetNumberOfPoints(),
/*offset=*/grid.GetNumberOfPoints() * sizeof(double));
fields["velocity/values/z"].set_external(attribs.GetVelocityArray(), grid.GetNumberOfPoints(),
/*offset=*/grid.GetNumberOfPoints() * sizeof(double) * 2);
// pressure is cell-data.
fields["pressure/association"].set("element");
fields["pressure/topology"].set("mesh");
fields["pressure/volume_dependent"].set("false");
fields["pressure/values"].set_external(attribs.GetPressureArray(), grid.GetNumberOfCells());
catalyst_status err = catalyst_execute(conduit_cpp::c_node(&exec_params));
if (err != catalyst_status_ok)
{
std::cerr << "Failed to execute Catalyst: " << err << std::endl;
}
}
void Finalize()
{
conduit_cpp::Node node;
catalyst_status err = catalyst_finalize(conduit_cpp::c_node(&node));
if (err != catalyst_status_ok)
{
std::cerr << "Failed to finalize Catalyst: " << err << std::endl;
}
}
}
#endif
|