Skip to main content

Post-processing tools 2025 R1

libuserd_interface

Last update: 16.07.2025
1/*
2 *
3 * *************************************************************
4 * Copyright 2024 ANSYS, Inc.
5 * All Rights Reserved.
6 *
7 * Restricted Rights Legend
8 *
9 * Use, duplication, or disclosure of this
10 * software and its documentation by the
11 * Government is subject to restrictions as
12 * set forth in subdivision [(b)(3)(ii)] of
13 * the Rights in Technical Data and Computer
14 * Software clause at 52.227-7013.
15 * *************************************************************
16 */
17
18#ifndef USERD_INTERFACE_H
19#define USERD_INTERFACE_H
20
21#ifdef __cplusplus
22
23#include <string>
24#include <vector>
25#include <map>
26#include <array>
27
46/* TODO
47 * - Add support for structured data
48 */
49
55namespace libuserd {
56
65 enum ElementType {
66 POINT,
67 POINT_GHOST,
68 BAR02,
69 BAR02_GHOST,
70 BAR03,
71 BAR03_GHOST,
72 TRI03,
73 TRI03_GHOST,
74 TRI06,
75 TRI06_GHOST,
76 QUAD04,
77 QUAD04_GHOST,
78 QUAD08,
79 QUAD08_GHOST,
80 TET04,
81 TET04_GHOST,
82 TET10,
83 TET10_GHOST,
84 PYR05,
85 PYR05_GHOST,
86 PYR13,
87 PYR13_GHOST,
88 PENT6,
89 PENT6_GHOST,
90 PENT15,
91 PENT15_GHOST,
92 HEX08,
93 HEX08_GHOST,
94 HEX20,
95 HEX20_GHOST,
96 NSIDED,
97 NSIDED_GHOST,
98 NFACED,
99 NFACED_GHOST,
100 MAX_ELEMENT_TYPE
101 };
102
108 enum VariableLocation {
109 DATASET,
110 PART,
111 NODE,
112 ELEMENT,
113 UNKNOWN_LOCATION
114 };
115
121 enum VariableType {
122 CONSTANT,
123 SCALAR,
124 VECTOR,
125 TENSOR,
126 TENSOR9,
127 UNKNOWN_VAR_TYPE
128 };
129
135 enum PartHints {
136 STATIC_COORDS = (1 << 0),
137 CHANGING_COOORDS = (1 << 1),
138 CHANGING_CONNECTIVITY = (1 << 2)
139 };
140
146 enum ErrorCode {
147 SUCCESS = 0,
148 UNAVAILABLE = 1,
149 IGNORED_AFTER_INITIALIZE = 2,
150 OUT_OF_MEMORY = 3,
151 IO = 4,
152 UNIMPLEMENTED = 5,
153 NOT_FOUND = 6,
154 UNKNOWN = 7,
155 SINGLE_READER_ALLOWED = 8
156 };
157
158 // The "options" structure
159 struct OptBoolean {
160 const std::string name;
161 int32_t value;
162 const int32_t default_value;
163
164 // Constructor to initialize the struct
165 OptBoolean(const std::string& _name, int32_t _value, int32_t _default_value)
166 : name(_name), value(_value), default_value(_default_value) {
167 }
168 };
169
170 struct OptOption {
171 const std::string name;
172 const std::vector<std::string> values;
173 uint32_t value_index;
174 const uint32_t default_value_index;
175
176 // Constructor to initialize the struct
177 OptOption(const std::string& _name, const std::vector<std::string>& _value, uint32_t _val_index, uint32_t _default_value_index)
178 : name(_name), values(_value), value_index(_val_index), default_value_index(_default_value_index) {
179 }
180 };
181
182 struct OptField {
183 const std::string name;
184 std::string value;
185 const std::string default_value;
186
187 // Constructor to initialize the struct
188 OptField(const std::string& _name, const std::string& _value, const std::string& _default_value)
189 : name(_name), value(_value), default_value(_default_value) {
190 }
191 };
192
197 struct Options {
198 std::vector<struct OptBoolean> booleans;
199 std::vector<struct OptOption> options;
200 std::vector<struct OptField> fields;
201 };
202
203 struct fileExtensions {
204 std::string name;
205 std::vector<std::string> file_1_extension;
206 std::vector<std::string> file_2_extension;
207 };
208
209 // Forward declaration
210 class ReaderInfo;
211 class LibUserd;
212 class Reader;
213
221 class Query {
222
223 public:
224 const uint32_t m_id;
225 const std::string m_name;
226 const std::string m_x_title;
227 const std::string m_y_title;
228 std::map<const std::string, std::string> m_metadata;
229
237 size_t num_points();
238
250 ErrorCode data(float* x, float* y);
251
257 std::string to_string();
258
259 private:
260 Query(const uint32_t id,
261 const uint32_t reader_id,
262 const std::string& name,
263 const std::string& x_title,
264 const std::string& y_title,
265 const std::map<const std::string, std::string>& metadata);
266 friend class Reader;
267 uint32_t m_reader_id;
268 float m_reader_version;
269 };
270
278 class Variable {
279
280 public:
281 const uint32_t id;
282 const std::string name;
283 const std::string unit_label;
284 const std::string unit_dims;
285 const VariableLocation location;
286 const VariableType type;
287 const bool time_varying;
288 const bool complex;
289 const bool interleave_flag;
290 const uint32_t number_of_components;
291 std::map<const std::string, std::string> metadata;
292
302 static std::string get_variable_type_string(VariableType vtype);
303
313 static std::string get_variable_location_string(VariableLocation location);
314
324 std::string is_true(bool val);
325
331 std::string to_string();
332
333 private:
334 Variable(const uint32_t _id,
335 const std::string& _name,
336 const std::string& _unit_label,
337 const std::string& _unit_dims,
338 const VariableLocation _location,
339 const VariableType _type,
340 const bool _time_varying,
341 const bool _complex,
342 const bool _interleave_flag,
343 const uint32_t _number_of_components,
344 const std::map<const std::string, std::string>& _metadata);
345
346 friend class Reader;
347 };
348
356 struct RigidBodyTransform {
357 float translation[3];
358 float euler_value[4];
359 float center_of_gravity[3];
360 float rotation_order;
361 float rotation_angles[3];
362 };
363
371 class Part {
372
373 public:
374 const uint32_t m_index;
375 const uint32_t m_id;
376 const uint32_t m_reader_id;
377 const std::string m_name;
378 std::map<const std::string, std::string> m_metadata;
379 const PartHints m_hints;
380 float m_reader_api_version;
381
390 ErrorCode num_nodes(std::size_t& num_coords);
391
402 ErrorCode nodes(float* xyz);
403
404
413 ErrorCode num_elements(std::map<ElementType, std::size_t>& elements);
414
415
416
432 ErrorCode element_conn(ElementType elem_type, uint32_t* connectivity);
433
446 ErrorCode element_conn_nsided_size(ElementType elem_type,
447 size_t& nodes_per_polygon_size, size_t& nodes_size);
448
459 ErrorCode element_conn_nsided(ElementType elem_type, uint32_t* nodes_per_polygon, uint32_t* nodes);
460
475 ErrorCode element_conn_nfaced_size(ElementType elem_type, size_t& faces_per_element_size,
476 size_t& nodes_per_face_size, size_t& indices_size);
477
489 ErrorCode element_conn_nfaced(ElementType elem_type,
490 uint32_t* faces_per_element, uint32_t* nodes_per_face, uint32_t* nodes);
491
507 ErrorCode variable_values(Variable* var, ElementType elem_type,
508 bool complex, uint32_t component, float* array);
509
518 ErrorCode rigid_body_transform(struct RigidBodyTransform& transform);
519
520 private:
521 Part(const uint32_t index,
522 const uint32_t id,
523 const uint32_t reader_id,
524 const std::string& name,
525 const std::map<const std::string, std::string>& metadata,
526 const PartHints hints);
527
528 friend class Reader;
529 };
530
531
541 class ReaderInfo {
542
543 public:
544 const uint32_t m_id;
545 const std::string m_name;
546 const std::string m_description;
547 const std::string m_file_labels[2];
548 struct Options m_options;
549
564 ErrorCode read_dataset(const std::string& file1, const std::string& file2, bool use_parallel, Reader*& reader);
565
571 std::string to_string();
572
573
584 static bool get_userd_xtra_gui_values(int reader_id, Options& userd_options);
585
586 private:
587 ReaderInfo(const uint32_t id,
588 const std::string name,
589 const std::string description,
590 const std::string file_labels[2],
591 struct Options options);
592 friend class LibUserd;
593 };
594
603 class Reader {
604
605 public:
606 const std::string m_unit_system;
607 std::map<const std::string, std::string> m_metadata;
608 std::string m_raw_metadata;
609
610 static uint32_t s_curr_time_step; // ToDo: Should be removed later
611 static uint32_t s_curr_time_set; // ToDo: Should be removed later
612
623 ErrorCode parts(std::vector<Part*>& part_list);
624
635 ErrorCode variables(std::vector<Variable*>& variable_list);
636
647 ErrorCode queries(std::vector<Query*>& query_list);
648
649
659 ErrorCode get_number_of_time_sets(uint32_t & number_of_time_sets);
660
671 ErrorCode timevalues(std::vector<float> & timevalues, uint32_t timeset_number = 0);
672
683 ErrorCode set_timevalue(float timevalue, uint32_t timeset_number = 0);
684
695 ErrorCode set_timestep(uint32_t timestep, uint32_t timeset_number = 0);
696
697
707 ErrorCode variable_value(const Variable* var, float& value);
708
709
717 bool is_geometry_changing();
718
726 const ReaderInfo* info();
727
728 // static helper methods
729 static ErrorCode get_geometry_info(int reader_id, int part_index, std::vector<int>& geoms_vector);
730 static ErrorCode number_of_geometries(int reader_id, int part_index, int& number_of_geoms);
731
732
733 private:
734 Reader(ReaderInfo info);
735 friend class ReaderInfo;
736 float m_reader_version;
737
738 ReaderInfo m_reader_info;
739
740 // Private helper methods
741 ErrorCode get_meta_data_string();
742 void parse_metatags(std::map<const std::string, std::string>& map, const char* section_name);
743 ErrorCode get_part_hints(int reader_id, int part_index, PartHints& part_hints);
744
745 std::map<const std::string, std::string> m_part_metatags;
746 std::map<const std::string, std::string> m_var_metatags;
747 std::map<const std::string, std::string> m_query_metatags;
748 };
749
750
759 class LibUserd {
760 public:
761
772 static LibUserd* library_interface();
773
774
782 static Reader* get_active_reader();
783
792 static std::string errorcode_as_string(ErrorCode code);
793
804 static size_t nodes_per_element(ElementType elem_type);
805
815 static bool element_is_ghost(ElementType elem_type);
816
825 static bool element_is_zoo(ElementType elem_type);
826
835 static bool element_is_nsided(ElementType elem_type);
836
845 static bool element_is_nfaced(ElementType elem_type);
846
858 static size_t number_of_simple_element_types();
859
871 static const std::string& library_version();
872
880 static const std::string& ansys_release_string();
881
889 static uint32_t ansys_release_number();
890
891
900 //ToDo: Will convert this to const & later (I need add a map or something inside the class to do this)
901 static const std::string element_type_to_string(ElementType type);
902
903 /*
904 * These functions need to be called before initialize() is called.
905 */
906
920 ErrorCode set_reader_path(const std::string& path);
921
922 /*
923 * EnSight USERD readers include a mechanism where they can exchange information between instances.
924 * This is used for parallel I/O operations, where each process reads an independent portion of the data.
925 * Since each Reader instance is in a different process a communications channel needs to be supplied
926 * by the host application to support this. When run this way, every process has a "rank". For example,
927 * if you want to read 5 way parallel, you will have 5 processes and they will be ranks: [0,1,2,3,4].
928 * It is not important which processes have which ranks, only that all of the ranks exist once and only
929 * once.
930 *
931 * To run libuserd in parallel one must call one of the set_reduction calls before calling initialize().
932 *
933 * Options include:
934 * 1) a custom proc that the application provide (e.g. an MPI implementation).
935 * 2) TCP/IP where rank 0 manages the operations and all other ranks connect to it.
936 * 3) a shared filesystem implementation where rank 0 manages operations and uses a
937 * common filesystem as the communication scheme.
938 */
939
940 enum ReduceOp {
941 SUM = 0,
942 MIN = 1,
943 MAX = 2,
944 ABSMIN = 3,
945 ABSMAX = 4,
946 BROADCAST = 5
947 } z_reduce_ops;
948
949 enum ReduceDataType {
950 FLOAT = 0,
951 DOUBLE = 1,
952 INT = 2,
953 UCHAR = 3
954 };
955
956 using ReduceProc = ErrorCode(*) (ReduceOp op, uint32_t number_of_values, ReduceDataType type, void* data, uint32_t count, void* userdata);
957
958 // redirection of error handling output
959
960 enum SeverityLevel {
961 LVL_INFO = 0,
962 LVL_WARN = 1,
963 LVL_ERROR = 2,
964 LVL_FATAL = 3,
965 LVL_UNKNOWN = 4
966 };
967
980 static const std::string severity_level_to_string(SeverityLevel level);
981
982 using ErrorProc = ErrorCode(*) (const char* message, SeverityLevel severity_level, void* userdata);
983
1000 ErrorCode set_reduction(ReduceProc func, uint32_t rank, uint32_t num_ranks, void* userdata);
1001
1002
1018 ErrorCode set_reduction(uint32_t rank_0_port, const std::string& rank_0_hostname,
1019 uint32_t rank, uint32_t num_ranks);
1020
1035 ErrorCode set_reduction(const std::string& directoryname, uint32_t rank, uint32_t num_ranks);
1036
1047 ErrorCode set_message_handler(ErrorProc, void* userdata);
1048
1057 ErrorCode initialize();
1058
1066 static size_t get_available_reader_count();
1067
1076 ErrorCode get_all_readers(std::vector<ReaderInfo>& info);
1077
1089 ErrorCode query_format(const std::string& name1, const std::string& name2, std::vector<ReaderInfo>& reader_info);
1090
1099 ErrorCode shutdown();
1100
1101
1109 bool is_initialized() const;
1110
1111 ~LibUserd();
1112
1113 private:
1114 LibUserd();
1115 LibUserd(const LibUserd&) = delete;
1116 bool m_is_initialized;
1117 static std::string s_libuserd_interface_version;
1118 static std::string s_ansys_release_version_string;
1119 static uint32_t s_ansys_release_version_number;
1120 static LibUserd* m_libuserd;
1121
1122 friend class ReaderInfo;
1123 static void set_active_reader(Reader* reader);
1124 static Reader* m_active_reader;
1125
1126 std::vector<fileExtensions> ReaderExtension;
1127 void initReaderExtensions();
1128 std::string processFilename(const std::string &filename);
1129 };
1130
1131}
1132
1133#endif
1134
1135#endif
@ UNKNOWN
Unknown type.
@ PART
This is a variable for an entire part.
@ ELEMENT
This is a field variable per each element of a part.
@ NODE
This is a field variable per each node of a part's mesh.
@ TENSOR9
NOT SUPPORTED YET.
@ VECTOR
XYZ Coordinates.
@ TENSOR
NOT SUPPORTED YET.

Connect with Ansys