Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
INode.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
18
19#include "shambase/WithUUID.hpp"
20#include "shambase/memory.hpp"
24#include <memory>
25#include <vector>
26
27namespace shamrock::solvergraph {
28
30 class INode : public std::enable_shared_from_this<INode>,
31 public shambase::WithUUID<INode, u64> {
32
34 std::vector<std::shared_ptr<IEdge>> ro_edges;
36 std::vector<std::shared_ptr<IEdge>> rw_edges;
37
38 public:
39 INode() = default;
40
41 INode(const INode &) = delete;
42 INode &operator=(const INode &) = delete;
43
45 INode(INode &&) noexcept = default;
46
48 INode &operator=(INode &&) noexcept = default;
49
51 inline std::shared_ptr<INode> getptr_shared() { return shared_from_this(); }
53 inline std::weak_ptr<INode> getptr_weak() { return weak_from_this(); }
54
56 inline std::vector<std::shared_ptr<IEdge>> &get_ro_edges() { return ro_edges; }
58 inline std::vector<std::shared_ptr<IEdge>> &get_rw_edges() { return rw_edges; }
59
61 inline void __internal_set_ro_edges(std::vector<std::shared_ptr<IEdge>> new_ro_edges);
63 inline void __internal_set_rw_edges(std::vector<std::shared_ptr<IEdge>> new_rw_edges);
64
66 template<class Func>
67 void on_edge_ro_edges(Func &&f);
68
70 template<class Func>
71 void on_edge_rw_edges(Func &&f);
72
74 virtual ~INode() {
77 }
78
80 template<class T>
81 inline const T &get_ro_edge(int slot) {
82 return shambase::get_check_ref(std::dynamic_pointer_cast<T>(ro_edges.at(slot)));
83 }
84
86 template<class T>
87 inline T &get_rw_edge(int slot) {
88 return shambase::get_check_ref(std::dynamic_pointer_cast<T>(rw_edges.at(slot)));
89 }
90
92 template<class T>
93 inline std::optional<std::reference_wrapper<const T>> get_ro_edge_optional(int slot) {
94 auto &edge = ro_edges.at(slot);
95
96 auto ptr = std::dynamic_pointer_cast<T>(edge);
97 if (ptr) {
98 return std::cref(*ptr);
99 }
100
101 if (is_null_opt_edge(edge)) {
102 return std::nullopt;
103 }
104
106 shambase::format("Edge is not from the requested type: {}", slot));
107 }
108
110 template<class T>
111 inline std::optional<std::reference_wrapper<T>> get_rw_edge_optional(int slot) {
112 auto &edge = rw_edges.at(slot);
113
114 auto ptr = std::dynamic_pointer_cast<T>(edge);
115 if (ptr) {
116 return std::cref(*ptr);
117 }
118
119 if (is_null_opt_edge(edge)) {
120 return std::nullopt;
121 }
122
124 shambase::format("Edge is not from the requested type: {}", slot));
125 }
126
128 inline const IEdge &get_ro_edge_base(int slot) {
129 return shambase::get_check_ref(ro_edges.at(slot));
130 }
131
132 inline const IEdge &get_ro_edge_base(int slot) const {
133 return shambase::get_check_ref(ro_edges.at(slot));
134 }
135
137 inline IEdge &get_rw_edge_base(int slot) {
138 return shambase::get_check_ref(rw_edges.at(slot));
139 }
140
141 inline const IEdge &get_rw_edge_base(int slot) const {
142 return shambase::get_check_ref(rw_edges.at(slot));
143 }
144
147
149 inline std::string get_dot_graph() { return get_dot_graph_partial(); };
150
152 inline std::string get_dot_graph_partial() { return _impl_get_dot_graph_partial(); };
153
157 inline std::string get_dot_graph_node_end() { return _impl_get_dot_graph_node_end(); };
158
160 inline std::string get_tex() { return _impl_get_tex(); };
162 inline std::string get_tex_partial() { return _impl_get_tex(); };
164 inline std::string get_label() const { return _impl_get_label(); };
165
167 inline virtual std::string print_node_info() const {
168 std::string node_info = shambase::format("Node info :\n");
169 node_info += shambase::format(" - Node type : {}\n", typeid(*this).name());
170 node_info += shambase::format(" - Node UUID : {}\n", get_uuid());
171 node_info += shambase::format(" - Node label : {}\n", _impl_get_label());
172
173 auto append_edges_info = [&](const char *title, const auto &edges) {
174 node_info += shambase::format(" - {}: {}\n", title, edges.size());
175 for (const auto &edge : edges) {
176 const auto &e = *edge; // necessary to avoid -Wpotentially-evaluated-expression
177 node_info += shambase::format(
178 " - Edge ptr = {}, uuid = {}, label = {},\n type = {} \n",
179 static_cast<void *>(edge.get()),
180 edge->get_uuid(),
181 edge->get_label(),
182 typeid(e).name());
183 }
184 };
185
186 append_edges_info("Node Read Only edges", ro_edges);
187 append_edges_info("Node Read Write edges", rw_edges);
188
189 return node_info;
190 };
191
192 protected:
194 virtual void _impl_evaluate_internal() = 0;
195
197 virtual std::string _impl_get_label() const = 0;
198
200 virtual std::string _impl_get_dot_graph_partial() const;
202 virtual std::string _impl_get_dot_graph_node_start() const;
204 virtual std::string _impl_get_dot_graph_node_end() const;
205
207 virtual std::string _impl_get_tex() const = 0;
208 };
209
210 inline void INode::__internal_set_ro_edges(std::vector<std::shared_ptr<IEdge>> new_ro_edges) {
211 for (auto e : ro_edges) {
212 // shambase::get_check_ref(e).parent = {};
213 }
214 this->ro_edges = new_ro_edges;
215 for (auto e : ro_edges) {
216 // shambase::get_check_ref(e).parent = getptr_weak();
217 }
218 }
219
220 inline void INode::__internal_set_rw_edges(std::vector<std::shared_ptr<IEdge>> new_rw_edges) {
221 for (auto e : rw_edges) {
222 // shambase::get_check_ref(e).child = {};
223 }
224 this->rw_edges = new_rw_edges;
225 for (auto e : rw_edges) {
226 // shambase::get_check_ref(e).child = getptr_weak();
227 }
228 }
229
230 template<class Func>
231 inline void INode::on_edge_ro_edges(Func &&f) {
232 for (auto &in : ro_edges) {
234 }
235 }
236
237 template<class Func>
238 inline void INode::on_edge_rw_edges(Func &&f) {
239 for (auto &out : rw_edges) {
241 }
242 }
243
244 inline std::string INode::_impl_get_dot_graph_partial() const {
245 std::string node_str
246 = shambase::format("n_{} [label=\"{}\"];\n", this->get_uuid(), _impl_get_label());
247
248 std::string edge_str = "";
249 for (auto &in : ro_edges) {
250 edge_str += shambase::format(
251 "e_{} -> n_{} [style=\"dashed\", color=green];\n",
252 in->get_uuid(),
253 this->get_uuid());
254 edge_str += shambase::format(
255 "e_{} [label=\"{}\",shape=rect, style=filled];\n", in->get_uuid(), in->get_label());
256 }
257 for (auto &out : rw_edges) {
258 edge_str += shambase::format(
259 "n_{} -> e_{} [style=\"dashed\", color=red];\n", this->get_uuid(), out->get_uuid());
260 edge_str += shambase::format(
261 "e_{} [label=\"{}\",shape=rect, style=filled];\n",
262 out->get_uuid(),
263 out->get_label());
264 }
265
266 return shambase::format("{}{}", node_str, edge_str);
267 };
268
269 inline std::string INode::_impl_get_dot_graph_node_start() const {
270 return shambase::format("n_{}", this->get_uuid());
271 }
272 inline std::string INode::_impl_get_dot_graph_node_end() const {
273 return shambase::format("n_{}", this->get_uuid());
274 }
275
276} // namespace shamrock::solvergraph
277
278#define INODE_DECL_RO(type, name) const type &name;
279#define INODE_DECL_RW(type, name) type & name;
280#define INODE_PARAM_RO(type, name) const std::shared_ptr<type> &name,
281#define INODE_PARAM_RW(type, name) const std::shared_ptr<type> &name,
282#define INODE_PUSH_RO1(type, name) name,
283#define INODE_PUSH_RW1(type, name)
284#define INODE_PUSH_RO2(type, name)
285#define INODE_PUSH_RW2(type, name) name,
286#define INODE_GET_RO(type, name) get_ro_edge<type>(ro++),
287#define INODE_GET_RW(type, name) get_rw_edge<type>(rw++),
288
289#define INODE_DECL_RO_OPTIONAL(type, name) \
290 const std::optional<std::reference_wrapper<const type>> name;
291#define INODE_DECL_RW_OPTIONAL(type, name) const std::optional<std::reference_wrapper<type>> name;
292#define INODE_PARAM_RO_OPTIONAL(type, name) const std::optional<std::shared_ptr<type>> &name,
293#define INODE_PARAM_RW_OPTIONAL(type, name) const std::optional<std::shared_ptr<type>> &name,
294#define INODE_PUSH_RO1_OPTIONAL(type, name) shamrock::solvergraph::obsfucate_null_opt_edge(name),
295#define INODE_PUSH_RW1_OPTIONAL(type, name)
296#define INODE_PUSH_RO2_OPTIONAL(type, name)
297#define INODE_PUSH_RW2_OPTIONAL(type, name) shamrock::solvergraph::obsfucate_null_opt_edge(name),
298#define INODE_GET_RO_OPTIONAL(type, name) get_ro_edge_optional<type>(ro++),
299#define INODE_GET_RW_OPTIONAL(type, name) get_rw_edge_optional<type>(rw++),
300
301#define EXPAND_NODE_EDGES(EDGES) \
302 \
303 struct Edges { \
304 EDGES(INODE_DECL_RO, INODE_DECL_RW) \
305 }; \
306 \
307 inline void set_edges( \
308 EDGES(INODE_PARAM_RO, INODE_PARAM_RW) SourceLocation loc = SourceLocation{}) { \
309 __shamrock_log_callsite(loc); \
310 \
311 __internal_set_ro_edges({EDGES(INODE_PUSH_RO1, INODE_PUSH_RW1)}); \
312 __internal_set_rw_edges({EDGES(INODE_PUSH_RO2, INODE_PUSH_RW2)}); \
313 } \
314 \
315 inline Edges get_edges() { \
316 int ro = 0; \
317 int rw = 0; \
318 return Edges{EDGES(INODE_GET_RO, INODE_GET_RW)}; \
319 }
320
321#define EXPAND_NODE_EDGES_OPTIONAL(EDGES) \
322 \
323 struct Edges { \
324 EDGES(INODE_DECL_RO, INODE_DECL_RW, INODE_DECL_RO_OPTIONAL, INODE_DECL_RW_OPTIONAL) \
325 }; \
326 \
327 inline void set_edges( \
328 EDGES(INODE_PARAM_RO, INODE_PARAM_RW, INODE_PARAM_RO_OPTIONAL, INODE_PARAM_RW_OPTIONAL) \
329 SourceLocation loc = SourceLocation{}) { \
330 __shamrock_log_callsite(loc); \
331 \
332 __internal_set_ro_edges({EDGES( \
333 INODE_PUSH_RO1, INODE_PUSH_RW1, INODE_PUSH_RO1_OPTIONAL, INODE_PUSH_RW1_OPTIONAL)}); \
334 __internal_set_rw_edges({EDGES( \
335 INODE_PUSH_RO2, INODE_PUSH_RW2, INODE_PUSH_RO2_OPTIONAL, INODE_PUSH_RW2_OPTIONAL)}); \
336 } \
337 \
338 inline Edges get_edges() { \
339 int ro = 0; \
340 int rw = 0; \
341 return Edges{ \
342 EDGES(INODE_GET_RO, INODE_GET_RW, INODE_GET_RO_OPTIONAL, INODE_GET_RW_OPTIONAL)}; \
343 }
A class that provides unique identifiers (UUID) to instances.
Definition WithUUID.hpp:37
void evaluate()
Evaluate the node.
Definition INode.hpp:146
INode & operator=(const INode &)=delete
would violate shared_from_this() & unique UUID
std::vector< std::shared_ptr< IEdge > > & get_ro_edges()
Get the read only edges.
Definition INode.hpp:56
virtual std::string _impl_get_dot_graph_node_start() const
get the dot graph of the node start
Definition INode.hpp:269
void on_edge_ro_edges(Func &&f)
Apply a function to the read only edges.
Definition INode.hpp:231
T & get_rw_edge(int slot)
Get a read write edge and cast it to the type T.
Definition INode.hpp:87
INode(INode &&) noexcept=default
would violate shared_from_this() & unique UUID
void __internal_set_rw_edges(std::vector< std::shared_ptr< IEdge > > new_rw_edges)
Set the read write edges.
Definition INode.hpp:220
virtual ~INode()
Destructor (virtual) & reset the edges.
Definition INode.hpp:74
std::string get_dot_graph_node_start()
Get the id of the node start in the dot graph.
Definition INode.hpp:155
std::string get_tex_partial()
Get the TeX of the node partial.
Definition INode.hpp:162
std::weak_ptr< INode > getptr_weak()
Get a weak pointer to this node.
Definition INode.hpp:53
std::optional< std::reference_wrapper< const T > > get_ro_edge_optional(int slot)
Get a read only edge and cast it to the type T, return an optional.
Definition INode.hpp:93
std::string get_tex()
Get the TeX of the node.
Definition INode.hpp:160
virtual void _impl_evaluate_internal()=0
evaluate the node
IEdge & get_rw_edge_base(int slot)
Get a reference to a read write edge and cast it to the type IEdge.
Definition INode.hpp:137
void on_edge_rw_edges(Func &&f)
Apply a function to the read write edges.
Definition INode.hpp:238
std::string get_dot_graph()
Get the dot graph of the node (Currently only an alias to get_dot_graph_partial).
Definition INode.hpp:149
std::shared_ptr< INode > getptr_shared()
Get a shared pointer to this node.
Definition INode.hpp:51
std::string get_label() const
Get the label of the node.
Definition INode.hpp:164
virtual std::string print_node_info() const
print the node info
Definition INode.hpp:167
void __internal_set_ro_edges(std::vector< std::shared_ptr< IEdge > > new_ro_edges)
Set the read only edges.
Definition INode.hpp:210
std::string get_dot_graph_partial()
Get the dot graph of the subgraph corresponding to the node.
Definition INode.hpp:152
std::string get_dot_graph_node_end()
Get the id of the node end in the dot graph.
Definition INode.hpp:157
std::optional< std::reference_wrapper< T > > get_rw_edge_optional(int slot)
Get a read write edge and cast it to the type T, return an optional.
Definition INode.hpp:111
virtual std::string _impl_get_label() const =0
get the label of the node
const T & get_ro_edge(int slot)
Get a read only edge and cast it to the type T.
Definition INode.hpp:81
virtual std::string _impl_get_dot_graph_partial() const
get the dot graph of the node partial
Definition INode.hpp:244
std::vector< std::shared_ptr< IEdge > > & get_rw_edges()
Get the read write edges.
Definition INode.hpp:58
virtual std::string _impl_get_tex() const =0
get the tex of the node
virtual std::string _impl_get_dot_graph_node_end() const
get the dot graph of the node end
Definition INode.hpp:272
const IEdge & get_ro_edge_base(int slot)
Get a reference to a read only edge.
Definition INode.hpp:128
T & get_check_ref(const std::unique_ptr< T > &ptr, SourceLocation loc=SourceLocation())
Takes a std::unique_ptr and returns a reference to the object it holds. It throws a std::runtime_erro...
Definition memory.hpp:110
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
This file contains the definition for the stacktrace related functionality.