Skip to content

Commit 8057a14

Browse files
committed
Addded the foundation of an advanced Cyclus Agent development tutorial using ChatGPT
1 parent e3ddbc3 commit 8057a14

File tree

5 files changed

+756
-0
lines changed

5 files changed

+756
-0
lines changed
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
2+
Advanced Agent Creation
3+
===============================
4+
5+
This chapter offers a comprehensive walkthrough of developing a fully functional and feature-rich **Cyclus Facility archetype**. It is intended for users who have completed the basic C++ agent tutorial and are ready to begin writing production-grade archetypes with more advanced capabilities.
6+
7+
By the end of this chapter, you will understand how to:
8+
9+
* Declare validated input parameters and manage internal state.
10+
* Interact with Cyclus's Dynamic Resource Exchange (DRE) to request and accept trades.
11+
* Use toolkit classes for material management, querying, and time series.
12+
* Implement lifecycle methods (`Tick`, `Tock`, `EnterNotify`) effectively.
13+
* Incorporate logging, testing, and optional output recording.
14+
15+
The concepts are demonstrated using a simplified but illustrative example facility: an **AdvancedReactor**, which consumes fuel, burns it for a defined residence time, and then discharges spent fuel.
16+
17+
---
18+
19+
1. Agent Structure and Metadata
20+
21+
---
22+
23+
Begin by defining the agent header file with proper Cyclus metadata and parameter declarations.
24+
25+
.. code-block:: cpp
26+
27+
// advanced\_reactor.h
28+
\#ifndef ADVANCED\_REACTOR\_H\_
29+
\#define ADVANCED\_REACTOR\_H\_
30+
31+
\#include <string>
32+
\#include <queue>
33+
\#include "cyclus.h"
34+
\#include "toolkit/resource\_buff.h"
35+
\#include "toolkit/mat\_query.h"
36+
\#include "toolkit/commod\_map\_inst.h"
37+
\#include "toolkit/time\_series.h"
38+
39+
class AdvancedReactor : public cyclus::Facility {
40+
public:
41+
AdvancedReactor(cyclus::Context\* ctx);
42+
virtual \~AdvancedReactor() {}
43+
44+
```
45+
#pragma cyclus note {
46+
"doc": "An advanced reactor facility that models fuel intake, burnup, and discharge."
47+
}
48+
49+
// Core parameters
50+
#pragma cyclus var {"tooltip": "Maximum fresh fuel inventory (kg)", "units": "kg"}
51+
double fresh_fuel_cap;
52+
53+
#pragma cyclus var {"tooltip": "Maximum spent fuel inventory (kg)", "units": "kg"}
54+
double spent_fuel_cap;
55+
56+
#pragma cyclus var {"tooltip": "Residence time in core (timesteps)", "default": 3, "lbound": 1}
57+
int residence_time;
58+
59+
#pragma cyclus var {"tooltip": "Input commodity for fresh fuel"}
60+
std::string in_commodity;
61+
62+
#pragma cyclus var {"tooltip": "Output commodity for spent fuel"}
63+
std::string out_commodity;
64+
65+
#pragma cyclus var {"tooltip": "Recipe for spent fuel"}
66+
std::string out_recipe;
67+
68+
virtual std::string str();
69+
virtual void EnterNotify();
70+
virtual void Tick();
71+
virtual void Tock();
72+
73+
virtual std::set<cyclus::RequestPortfolio<cyclus::Material>::Ptr> GetMatlRequests();
74+
virtual std::set<cyclus::BidPortfolio<cyclus::Material>::Ptr> GetMatlBids(
75+
cyclus::CommodMap<cyclus::Material>::type& commod_requests);
76+
virtual void AcceptMatlTrades(
77+
const std::map<cyclus::Trade<cyclus::Material>, cyclus::Material::Ptr>& responses);
78+
virtual cyclus::Material::Ptr OfferMatl(
79+
cyclus::Material::Ptr request);
80+
```
81+
82+
private:
83+
cyclus::toolkit::ResourceBuff fresh\_fuel\_; // buffer for incoming fuel
84+
cyclus::toolkit::ResourceBuff spent\_fuel\_; // buffer for outgoing waste
85+
86+
```
87+
std::queue<std::pair<int, cyclus::Material::Ptr>> core_; // (entry_time, material)
88+
89+
cyclus::toolkit::TimeSeries<double> power_output_; // optional logging
90+
```
91+
92+
};
93+
94+
\#endif // ADVANCED\_REACTOR\_H\_
95+
96+
---
97+
98+
2. Facility Behavior (Source)
99+
100+
---
101+
102+
Implement the lifecycle and DRE methods:
103+
104+
.. code-block:: cpp
105+
106+
\#include "advanced\_reactor.h"
107+
108+
using cyclus::Material;
109+
using cyclus::Trade;
110+
using cyclus::Context;
111+
112+
AdvancedReactor::AdvancedReactor(Context\* ctx)
113+
: cyclus::Facility(ctx),
114+
fresh\_fuel\_(), spent\_fuel\_(), power\_output\_("power\_output") {}
115+
116+
void AdvancedReactor::EnterNotify() {
117+
cyclus::Facility::EnterNotify();
118+
fresh\_fuel\_.capacity(fresh\_fuel\_cap);
119+
spent\_fuel\_.capacity(spent\_fuel\_cap);
120+
}
121+
122+
void AdvancedReactor::Tick() {
123+
// discharge spent fuel if residence time reached
124+
while (!core\_.empty() && context()->time() - core\_.front().first >= residence\_time) {
125+
cyclus::Material::Ptr m = core\_.front().second->Transmute(out\_recipe);
126+
spent\_fuel\_.Push(m);
127+
core\_.pop();
128+
}
129+
}
130+
131+
void AdvancedReactor::Tock() {
132+
// move fresh fuel to core if there's room
133+
while (!fresh\_fuel\_.empty()) {
134+
cyclus::Material::Ptr m = fresh\_fuel\_.Pop();
135+
core\_.push(std::make\_pair(context()->time(), m));
136+
}
137+
}
138+
139+
std::string AdvancedReactor::str() {
140+
std::stringstream ss;
141+
ss << Facility::str() << \n
142+
<< "Fresh fuel buffer: " << fresh\_fuel\_.quantity() << " / " << fresh\_fuel\_cap << " kg\n"
143+
<< "Spent fuel buffer: " << spent\_fuel\_.quantity() << " / " << spent\_fuel\_cap << " kg\n"
144+
<< "Core loading: " << core\_.size() << " assemblies";
145+
return ss.str();
146+
}
147+
148+
std::set\<RequestPortfolio<Material>::Ptr> AdvancedReactor::GetMatlRequests() {
149+
std::set\<RequestPortfolio<Material>::Ptr> ports;
150+
double qty = fresh\_fuel\_.space();
151+
if (qty > 0) {
152+
Material::Ptr dummy = cyclus::NewBlankMaterial(qty);
153+
RequestPortfolio<Material>::Ptr port(new RequestPortfolio<Material>());
154+
port->AddRequest(dummy, this, in\_commodity);
155+
ports.insert(port);
156+
}
157+
return ports;
158+
}
159+
160+
std::set\<cyclus::BidPortfolio<Material>::Ptr> AdvancedReactor::GetMatlBids(
161+
cyclus::CommodMap<Material>::type& commod\_requests) {
162+
std::set\<cyclus::BidPortfolio<Material>::Ptr> ports;
163+
if (spent\_fuel\_.quantity() <= 0) return ports;
164+
165+
```
166+
for (auto& pair : commod_requests[out_commodity]) {
167+
Material::Ptr offer = spent_fuel_.Peek();
168+
cyclus::BidPortfolio<Material>::Ptr port(new cyclus::BidPortfolio<Material>());
169+
port->AddBid(pair, offer, this);
170+
ports.insert(port);
171+
}
172+
return ports;
173+
```
174+
175+
}
176+
177+
void AdvancedReactor::AcceptMatlTrades(
178+
const std::map\<Trade<Material>, Material::Ptr>& responses) {
179+
for (auto& pair : responses) {
180+
fresh\_fuel\_.Push(pair.second);
181+
}
182+
}
183+
184+
Material::Ptr AdvancedReactor::OfferMatl(Material::Ptr request) {
185+
return spent\_fuel\_.PopQty(request->quantity());
186+
}
187+
188+
---
189+
190+
3. Advanced Features
191+
192+
---
193+
194+
**a. Material Inspection**
195+
196+
Use `cyclus::toolkit::MatQuery` to inspect isotopic makeup:
197+
198+
.. code-block:: cpp
199+
200+
cyclus::toolkit::MatQuery mq(mat);
201+
double u235 = mq.mass\_frac("U235");
202+
203+
This is helpful for tracking enrichment or decay over time.
204+
205+
**b. Time Series Logging**
206+
207+
Track performance over time:
208+
209+
.. code-block:: cpp
210+
211+
power\_output\_.Get(context())->AddValue("power\_output", current\_mw);
212+
213+
You can emit curves to the output database for later plotting.
214+
215+
**c. Error Handling and Validation**
216+
217+
Use assertions and logs to guard runtime logic:
218+
219+
.. code-block:: cpp
220+
221+
if (fresh\_fuel\_.space() <= 0) {
222+
LOG(cyclus::WARN) << "No room for new fuel";
223+
}
224+
225+
Use `lbound`, `ubound`, and `default` pragmas for robust schema validation.
226+
227+
---
228+
229+
4. Testing Notes
230+
231+
---
232+
233+
* Use Google Test (`gtest`) in the `tests/` directory.
234+
* Validate:
235+
236+
* Behavior under full/empty buffer conditions
237+
* Core loading and discharge timing
238+
* Material transformation into output recipe
239+
240+
---
241+
242+
5. Summary and Next Steps
243+
244+
---
245+
246+
This advanced tutorial walked through the full implementation of a robust Cyclus Facility agent with:
247+
248+
* Input validation and toolkit buffers
249+
* Core DRE interactions for both input and output commodities
250+
* Material transformation and storage logic
251+
* Optional logging and diagnostics
252+
253+
Continue on to the specialized chapters for:
254+
255+
.. toctree::
256+
dre\_interaction
257+
marquetry\_query
258+
custom\_institution

0 commit comments

Comments
 (0)