Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
SolverGraph.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
19#include "shambase/memory.hpp"
22#include <unordered_map>
23#include <memory>
24
25namespace shamrock::solvergraph {
26
58 std::unordered_map<std::string, std::shared_ptr<INode>> nodes;
59
61 std::unordered_map<std::string, std::shared_ptr<IEdge>> edges;
62
63 public:
65 // base getters and setters
67
75 inline std::shared_ptr<INode> register_node_ptr_base(
76 const std::string &name, std::shared_ptr<INode> node) {
77 const auto [it, inserted] = nodes.try_emplace(name, std::move(node));
78 if (!inserted) {
80 shambase::format("Node already exists: {}", name));
81 }
82 return it->second;
83 }
84
92 inline std::shared_ptr<IEdge> register_edge_ptr_base(
93 const std::string &name, std::shared_ptr<IEdge> edge) {
94 const auto [it, inserted] = edges.try_emplace(name, std::move(edge));
95 if (!inserted) {
97 shambase::format("Edge already exists: {}", name));
98 }
99 return it->second;
100 }
101
109 inline std::shared_ptr<INode> &get_node_ptr_base(const std::string &name) {
110 auto it = nodes.find(name);
111 if (it == nodes.end()) {
113 shambase::format("Node does not exist: {}", name));
114 }
115 return it->second;
116 }
117
119 inline const std::shared_ptr<INode> &get_node_ptr_base(const std::string &name) const {
120 auto it = nodes.find(name);
121 if (it == nodes.end()) {
123 shambase::format("Node does not exist: {}", name));
124 }
125 return it->second;
126 }
127
135 inline std::shared_ptr<IEdge> &get_edge_ptr_base(const std::string &name) {
136 auto it = edges.find(name);
137 if (it == edges.end()) {
139 shambase::format("Edge does not exist: {}", name));
140 }
141 return it->second;
142 }
143
145 inline const std::shared_ptr<IEdge> &get_edge_ptr_base(const std::string &name) const {
146 auto it = edges.find(name);
147 if (it == edges.end()) {
149 shambase::format("Edge does not exist: {}", name));
150 }
151 return it->second;
152 }
153
155 // generic getters
157
165 inline INode &get_node_ref_base(const std::string &name) {
167 }
168
170 inline const INode &get_node_ref_base(const std::string &name) const {
172 }
173
181 inline IEdge &get_edge_ref_base(const std::string &name) {
183 }
184
186 inline const IEdge &get_edge_ref_base(const std::string &name) const {
188 }
189
191 // templated register and getters
193
206 template<class T>
207 inline std::shared_ptr<T> register_node(const std::string &name, T &&node) {
208 static_assert(std::is_base_of<INode, T>::value, "T must derive from INode");
209 register_node_ptr_base(name, std::make_shared<T>(std::forward<T>(node)));
210 return get_node_ptr<T>(name);
211 }
212
225 template<class T>
226 inline std::shared_ptr<T> register_edge(const std::string &name, T &&edge) {
227 static_assert(std::is_base_of<IEdge, T>::value, "T must derive from IEdge");
228 register_edge_ptr_base(name, std::make_shared<T>(std::forward<T>(edge)));
229 return get_edge_ptr<T>(name);
230 }
231
243 template<class T>
244 inline std::shared_ptr<T> get_node_ptr(const std::string &name) {
245 auto tmp = std::dynamic_pointer_cast<T>(get_node_ptr_base(name));
246 if (!bool(tmp)) {
248 shambase::format("Node exists but is not from the requested type: {}", name));
249 }
250 return tmp;
251 }
252
254 template<class T>
255 inline std::shared_ptr<T> get_node_ptr(const std::string &name) const {
256 auto tmp = std::dynamic_pointer_cast<T>(get_node_ptr_base(name));
257 if (!bool(tmp)) {
259 shambase::format("Node exists but is not from the requested type: {}", name));
260 }
261 return tmp;
262 }
263
275 template<class T>
276 inline std::shared_ptr<T> get_edge_ptr(const std::string &name) {
277 auto tmp = std::dynamic_pointer_cast<T>(get_edge_ptr_base(name));
278 if (!bool(tmp)) {
280 shambase::format("Edge exists but is not from the requested type: {}", name));
281 }
282 return tmp;
283 }
284
286 template<class T>
287 inline std::shared_ptr<T> get_edge_ptr(const std::string &name) const {
288 auto tmp = std::dynamic_pointer_cast<T>(get_edge_ptr_base(name));
289 if (!bool(tmp)) {
291 shambase::format("Edge exists but is not from the requested type: {}", name));
292 }
293 return tmp;
294 }
295
307 template<class T>
308 inline T &get_node_ref(const std::string &name) {
309 return shambase::get_check_ref(get_node_ptr<T>(name));
310 }
311
313 template<class T>
314 inline const T &get_node_ref(const std::string &name) const {
315 return shambase::get_check_ref(get_node_ptr<T>(name));
316 }
317
329 template<class T>
330 inline T &get_edge_ref(const std::string &name) {
331 return shambase::get_check_ref(get_edge_ptr<T>(name));
332 }
333
335 template<class T>
336 inline const T &get_edge_ref(const std::string &name) const {
337 return shambase::get_check_ref(get_edge_ptr<T>(name));
338 }
339 };
340
341} // namespace shamrock::solvergraph
Inode is node between data edges, takes multiple inputs, multiple outputs.
Definition INode.hpp:30
A graph container for managing solver nodes and edges with type-safe access.
std::shared_ptr< INode > & get_node_ptr_base(const std::string &name)
Retrieve a node by name as a shared pointer to the base interface.
T & get_edge_ref(const std::string &name)
Get a typed reference to an edge by name.
const std::shared_ptr< INode > & get_node_ptr_base(const std::string &name) const
const variant
std::shared_ptr< T > get_edge_ptr(const std::string &name)
Get a typed shared pointer to an edge by name.
IEdge & get_edge_ref_base(const std::string &name)
Get a reference to an edge by name through the base interface.
std::shared_ptr< T > get_edge_ptr(const std::string &name) const
const variant
std::shared_ptr< T > register_edge(const std::string &name, T &&edge)
Register an edge with automatic type deduction and shared pointer creation.
const std::shared_ptr< IEdge > & get_edge_ptr_base(const std::string &name) const
const variant
std::shared_ptr< T > get_node_ptr(const std::string &name)
Get a typed shared pointer to a node by name.
std::shared_ptr< INode > register_node_ptr_base(const std::string &name, std::shared_ptr< INode > node)
Register a node with the graph using a shared pointer.
const T & get_edge_ref(const std::string &name) const
const variant
std::shared_ptr< T > get_node_ptr(const std::string &name) const
const variant
const INode & get_node_ref_base(const std::string &name) const
const variant
std::shared_ptr< IEdge > & get_edge_ptr_base(const std::string &name)
Retrieve an edge by name as a shared pointer to the base interface.
std::shared_ptr< T > register_node(const std::string &name, T &&node)
Register a node with automatic type deduction and shared pointer creation.
const IEdge & get_edge_ref_base(const std::string &name) const
const variant
INode & get_node_ref_base(const std::string &name)
Get a reference to a node by name through the base interface.
const T & get_node_ref(const std::string &name) const
const variant
T & get_node_ref(const std::string &name)
Get a typed reference to a node by name.
std::shared_ptr< IEdge > register_edge_ptr_base(const std::string &name, std::shared_ptr< IEdge > edge)
Register an edge with the graph using a shared pointer.
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
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