CYCLUS
Loading...
Searching...
No Matches
material.cc
Go to the documentation of this file.
1#include "material.h"
2
3#include <math.h>
4
5#include "comp_math.h"
6#include "context.h"
7#include "decayer.h"
8#include "error.h"
9#include "logger.h"
10
11namespace cyclus {
12
13const ResourceType Material::kType = "Material";
14
16
18 Composition::Ptr c, std::string package_name,
19 double unit_value) {
21 new Material(creator->context(), quantity, c, package_name, unit_value));
22 m->tracker_.Create(creator);
23 return m;
24}
25
27 double unit_value) {
29 new Material(NULL, quantity, c, Package::unpackaged_name(), unit_value));
30 return m;
31}
32
33int Material::qual_id() const {
34 return comp_->id();
35}
36
38 return Material::kType;
39}
40
42 Material* m = new Material(*this);
43 Resource::Ptr c(m);
44 m->tracker_.DontTrack();
45 return c;
46}
47
48void Material::Record(Context* ctx) const {
49 // Note that no time field is needed because the resource ID changes
50 // every time the resource changes - state_id by itself is already unique.
51 ctx_->NewDatum("MaterialInfo")
52 ->AddVal("ResourceId", state_id())
53 ->AddVal("PrevDecayTime", prev_decay_time_)
54 ->Record();
55
56 comp_->Record(ctx);
57}
58
59std::string Material::units() const {
60 return "kg";
61}
62
63double Material::quantity() const {
64 return qty_;
65}
66
68 return boost::static_pointer_cast<Resource>(ExtractQty(qty));
69}
70
72 return ExtractComp(qty, comp_);
73}
74
76 double threshold) {
77 if (qty_ < qty) {
78 throw ValueError("mass extraction causes negative quantity");
79 }
80
81 // TODO: decide if ExtractComp should force lazy-decay by calling comp()
82 if (comp_ != c) {
83 CompMap v(comp_->mass());
84 compmath::Normalize(&v, qty_);
85 CompMap otherv(c->mass());
86 compmath::Normalize(&otherv, qty);
87 CompMap newv = compmath::Sub(v, otherv);
88 compmath::ApplyThreshold(&newv, threshold);
89 comp_ = Composition::CreateFromMass(newv);
90 }
91
92 qty_ -= qty;
93 Material::Ptr other(
94 new Material(ctx_, qty, c, Package::unpackaged_name(), UnitValue()));
95
96 // Decay called on the extracted material should have the same dt as for
97 // this material regardless of composition.
98 other->prev_decay_time_ = prev_decay_time_;
99
100 tracker_.Extract(&other->tracker_);
101
102 return other;
103}
104
106 // these calls force lazy evaluation if in lazy decay mode
107 Composition::Ptr c0 = comp();
108 Composition::Ptr c1 = mat->comp();
109
110 if (c0 != c1) {
111 CompMap v(c0->mass());
112 compmath::Normalize(&v, qty_);
113 CompMap otherv(c1->mass());
114 compmath::Normalize(&otherv, mat->qty_);
115 comp_ = Composition::CreateFromMass(compmath::Add(v, otherv));
116 }
117
118 // Set the decay time to the value of the material that had the larger
119 // quantity. This helps avoid inheriting erroneous prev decay times if, for
120 // example, you absorb a material into a zero-quantity material that had a
121 // prev decay time prior to the current simulation time step.
122 if (qty_ < mat->qty_) {
123 prev_decay_time_ = mat->prev_decay_time_;
124 }
125 double tot_mass = qty_ + mat->quantity();
126 double avg_unit_value =
127 (qty_ * UnitValue() + mat->quantity() * mat->UnitValue()) / tot_mass;
128 SetUnitValue(avg_unit_value);
129 qty_ = tot_mass;
130 mat->qty_ = 0;
131 tracker_.Absorb(&mat->tracker_);
132}
133
135 comp_ = c;
136 tracker_.Modify();
137
138 // Presumably the user has chosen the new composition to be accurate for
139 // the current simulation time. The next call to decay should not include
140 // accumulated decay delta t from a composition that no longer exists in
141 // this material. This ---------+ condition allows testing to work.
142 // |
143 // |
144 // V
145 if (ctx_ != NULL && ctx_->time() > prev_decay_time_) {
146 prev_decay_time_ = ctx_->time();
147 }
148}
149
151 std::string new_package_name) {
152 if ((qty - qty_) > eps_rsrc()) {
153 throw ValueError("Attempted to extract more quantity than exists.");
154 }
155
156 qty_ -= qty;
157 Material::Ptr other(
158 new Material(ctx_, qty, comp_, new_package_name, UnitValue()));
159
160 // Decay called on the extracted material should have the same dt as for
161 // this material regardless of composition.
162 other->prev_decay_time_ = prev_decay_time_;
163
164 // this call to res_tracker must come first before the parent resource
165 // state id gets modified
166 other->tracker_.Package(&tracker_);
167 if (qty_ > eps_rsrc()) {
168 tracker_.Modify();
169 }
170 return boost::static_pointer_cast<Resource>(other);
171}
172
173void Material::ChangePackage(std::string new_package_name) {
174 if (ctx_ == NULL) {
175 // no change needed
176 return;
177 } else if (new_package_name == Package::unpackaged_name()) {
178 // unpackaged has functionally no restrictions
179 package_name_ = new_package_name;
180 return;
181 }
182
183 Package::Ptr p = ctx_->GetPackage(package_name_);
184 double min = p->fill_min();
185 double max = p->fill_max();
186 if (qty_ >= min && qty_ <= max) {
187 package_name_ = new_package_name;
188 } else {
189 throw ValueError("Material quantity is outside of package fill limits.");
190 }
191 tracker_.Package();
192}
193
194void Material::Decay(int curr_time) {
195 if (ctx_ != NULL && ctx_->sim_info().decay == "never") {
196 return;
197 } else if (curr_time < 0 && ctx_ == NULL) {
198 throw ValueError("decay cannot use default time with NULL context");
199 }
200
201 if (curr_time < 0) {
202 curr_time = ctx_->time();
203 }
204
205 int dt = curr_time - prev_decay_time_;
206 if (dt == 0) {
207 return;
208 }
209
210 double eps = 1e-3;
211 const CompMap c = comp_->atom();
212
213 // If composition has too many nuclides (i.e. > 100), it is cheaper to
214 // just do the decay rather than check all the decay constants.
215 bool decay = c.size() > 100;
216
217 uint64_t secs_per_timestep = kDefaultTimeStepDur;
218 if (ctx_ != NULL) {
219 secs_per_timestep = ctx_->sim_info().dt;
220 }
221
222 if (!decay) {
223 // Only do the decay calc if one of the nuclides would change in number
224 // density more than fraction eps.
225 // i.e. decay if (1 - eps) > exp(-lambda*dt)
226 CompMap::const_reverse_iterator it;
227 for (it = c.rbegin(); it != c.rend(); ++it) {
228 int nuc = it->first;
229 double lambda_timesteps =
230 pyne::decay_const(nuc) * static_cast<double>(secs_per_timestep);
231 double change =
232 1.0 - std::exp(-lambda_timesteps * static_cast<double>(dt));
233 if (change >= eps) {
234 decay = true;
235 break;
236 }
237 }
238 if (!decay) {
239 return;
240 }
241 }
242
243 prev_decay_time_ = curr_time; // this must go before Transmute call
244 Composition::Ptr decayed = comp_->Decay(dt, secs_per_timestep);
245 Transmute(decayed);
246}
247
249 double decay_heat = 0.;
250 // Pyne decay heat operates with grams, cyclus generally in kilograms.
251 pyne::Material p_map = pyne::Material(comp_->mass(), qty_ * 1000);
252 std::map<int, double> dec_heat = p_map.decay_heat();
253 for (auto nuc : dec_heat) {
254 if (!std::isnan(nuc.second)) {
255 decay_heat += nuc.second;
256 }
257 }
258 return decay_heat;
259}
260
262 throw Error(
263 "comp() const is deprecated - use non-const comp() function."
264 " Recompilation should fix the problem.");
265}
266
268 if (ctx_ != NULL && ctx_->sim_info().decay == "lazy") {
269 Decay(-1);
270 }
271 return comp_;
272}
273
275 std::string package_name, double unit_value)
276 : qty_(quantity),
277 comp_(c),
278 tracker_(ctx, this),
279 ctx_(ctx),
280 prev_decay_time_(0),
281 package_name_(package_name) {
282 SetUnitValue(unit_value);
283 if (ctx != NULL) {
284 prev_decay_time_ = ctx->time();
285 } else {
286 tracker_.DontTrack();
287 }
288}
289
292 return Material::CreateUntracked(quantity, comp);
293}
294
296 return package_name_;
297}
298
299} // namespace cyclus
The abstract base class used by all types of agents that live and interact in a simulation.
Definition agent.h:50
Context * context() const
Returns this agent's simulation context.
Definition agent.h:364
static Ptr CreateFromMass(CompMap v)
Creates a new composition from v with its components having appropriate mass-based ratios.
boost::shared_ptr< Composition > Ptr
Definition composition.h:43
A simulation context provides access to necessary simulation-global functions and state.
Definition context.h:146
virtual int time()
Returns the current simulation timestep.
Definition context.cc:314
A generic mechanism to manually manage exceptions.
Definition error.h:12
virtual std::string package_name()
Returns the package id.
Definition material.cc:295
virtual Resource::Ptr Clone() const
Creates an untracked copy of this material object.
Definition material.cc:41
virtual void Decay(int curr_time=-1)
Updates the material's composition by performing a decay calculation.
Definition material.cc:194
Ptr ExtractQty(double qty)
Same as ExtractComp with c = this->comp().
Definition material.cc:71
static const ResourceType kType
Definition material.h:76
double DecayHeat()
Returns a double with the decay heat of the material in units of W/kg.
Definition material.cc:248
virtual void Record(Context *ctx) const
Records the internal nuclide composition of this resource.
Definition material.cc:48
virtual Resource::Ptr ExtractRes(double qty)
Splits the resource and returns the extracted portion as a new resource object.
Definition material.cc:67
Composition::Ptr comp()
Returns the nuclide composition of this material.
Definition material.cc:267
virtual int qual_id() const
Returns the id of the material's internal nuclide composition.
Definition material.cc:33
static Ptr CreateUntracked(double quantity, Composition::Ptr c, double unit_value=kUnsetUnitValue)
Creates a new material resource that does not actually exist as part of the simulation and is untrack...
Definition material.cc:26
virtual std::string units() const
Returns "kg".
Definition material.cc:59
virtual void ChangePackage(std::string new_package_name=Package::unpackaged_name())
Changes the package id.
Definition material.cc:173
void Transmute(Composition::Ptr c)
Changes the material's composition to c without changing its mass.
Definition material.cc:134
virtual double quantity() const
Returns the mass of this material in kg.
Definition material.cc:63
static Ptr Create(Agent *creator, double quantity, Composition::Ptr c, std::string package_name=Package::unpackaged_name(), double unit_value=kUnsetUnitValue)
Creates a new material resource that is "live" and tracked.
Definition material.cc:17
virtual Resource::Ptr PackageExtract(double qty, std::string new_package_name=Package::unpackaged_name())
Definition material.cc:150
boost::shared_ptr< Material > Ptr
Definition material.h:75
virtual ~Material()
Definition material.cc:15
virtual void Absorb(Ptr mat)
Combines material mat with this one. mat's quantity becomes zero.
Definition material.cc:105
Material(Context *ctx, double quantity, Composition::Ptr c, std::string package_name=Package::unpackaged_name(), double unit_value=kUnsetUnitValue)
Definition material.cc:274
Ptr ExtractComp(double qty, Composition::Ptr c, double threshold=eps_rsrc())
Creates a new material by extracting from this one.
Definition material.cc:75
virtual const ResourceType type() const
Returns Material::kType.
Definition material.cc:37
boost::shared_ptr< Package > Ptr
Definition package.h:21
static std::string unpackaged_name()
Definition package.h:68
void DontTrack()
Prevent a resource's heritage from being tracked and recorded.
double UnitValue() const
Returns the unit value of this resource.
Definition resource.h:40
const int state_id() const
Returns the unique id corresponding to this resource and its current state.
Definition resource.h:49
boost::shared_ptr< Resource > Ptr
Definition resource.h:27
void SetUnitValue(double unit_value)
Sets the unit value of this resource.
Definition resource.h:43
For values that are too big, too small, etc.
Definition error.h:37
Material composed of nuclides.
Definition pyne.h:4575
comp_map decay_heat()
Calculates the decay heat of a material based on the composition and each nuclide's mass,...
Definition pyne.cc:15183
const uint64_t kDefaultTimeStepDur
Definition context.h:27
Code providing rudimentary logging capability for the Cyclus core.
CompMap Sub(const CompMap &v1, const CompMap &v2)
Does component-wise subtraction of the nuclide quantities of v1 and v2 and returns the result.
Definition comp_math.cc:27
void ApplyThreshold(CompMap *v, double threshold)
All nuclides with quantities below threshold will have their quantity set to zero.
Definition comp_math.cc:45
CompMap Add(const CompMap &v1, const CompMap &v2)
Does component-wise subtraction of the nuclide quantities of v1 and v2 and returns the result.
Definition comp_math.cc:18
void Normalize(CompMap *v, double val)
The sum of quantities of all nuclides of v is normalized to val.
Definition comp_math.cc:63
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
Definition agent.cc:14
double eps_rsrc()
an epsilon value to be used by resources
Definition cyc_limits.h:19
std::map< Nuc, double > CompMap
a raw definition of nuclides and corresponding (dimensionless quantities).
Definition composition.h:17
double eps()
a generic epsilon value
Definition cyc_limits.h:12
std::string ResourceType
Definition resource.h:17
Material::Ptr NewBlankMaterial(double quantity)
Creates and returns a new material with the specified quantity and a default, meaningless composition...
Definition material.cc:290
double decay_const(int nuc)
Returns the decay constant for a nuclide nuc.
Definition pyne.cc:9528