CYCLUS
composition.cc
Go to the documentation of this file.
1 #include "composition.h"
2 
3 #include "comp_math.h"
4 #include "context.h"
5 #include "decayer.h"
6 #include "error.h"
7 #include "recorder.h"
8 
9 extern "C" {
10 #include "cram.hpp"
11 }
12 
13 namespace cyclus {
14 
15 int Composition::next_id_ = 1;
16 
18  if (!compmath::ValidNucs(v))
19  throw ValueError("invalid nuclide in CompMap");
20 
21  if (!compmath::AllPositive(v))
22  throw ValueError("negative quantity in CompMap");
23 
25  c->atom_ = v;
26  return c;
27 }
28 
30  if (!compmath::ValidNucs(v))
31  throw ValueError("invalid nuclide in CompMap");
32 
33  if (!compmath::AllPositive(v))
34  throw ValueError("negative quantity in CompMap");
35 
37  c->mass_ = v;
38  return c;
39 }
40 
42  return id_;
43 }
44 
46  if (atom_.size() == 0) {
47  CompMap::iterator it;
48  for (it = mass_.begin(); it != mass_.end(); ++it) {
49  Nuc nuc = it->first;
50  atom_[nuc] = it->second / pyne::atomic_mass(nuc);
51  }
52  }
53  return atom_;
54 }
55 
57  if (mass_.size() == 0) {
58  CompMap::iterator it;
59  for (it = atom_.begin(); it != atom_.end(); ++it) {
60  Nuc nuc = it->first;
61  mass_[nuc] = it->second * pyne::atomic_mass(nuc);
62  }
63  }
64  return mass_;
65 }
66 
67 Composition::Ptr Composition::Decay(int delta, uint64_t secs_per_timestep) {
68  int tot_decay = prev_decay_ + delta;
69  if (decay_line_->count(tot_decay) == 1) {
70  // decay_line_ has cached, pre-computed result of this decay
71  return (*decay_line_)[tot_decay];
72  }
73 
74  // Calculate a new decayed composition and insert it into the decay chain.
75  // It will automagically appear in the decay chain for all other compositions
76  // that are a part of this decay chain because decay_line_ is a pointer that
77  // all compositions in the chain share.
78  Composition::Ptr decayed = NewDecay(delta, secs_per_timestep);
79  (*decay_line_)[tot_decay] = decayed;
80  return decayed;
81 }
82 
84  return Decay(delta, kDefaultTimeStepDur);
85 }
86 
88  if (recorded_) {
89  return;
90  }
91  recorded_ = true;
92 
93  CompMap::const_iterator it;
94  CompMap cm = mass(); // force lazy evaluation now
95  compmath::Normalize(&cm, 1);
96  for (it = cm.begin(); it != cm.end(); ++it) {
97  ctx->NewDatum("Compositions")
98  ->AddVal("QualId", id())
99  ->AddVal("NucId", it->first)
100  ->AddVal("MassFrac", it->second)
101  ->Record();
102  }
103 }
104 
105 Composition::Composition() : prev_decay_(0), recorded_(false) {
106  id_ = next_id_;
107  next_id_++;
108  decay_line_ = ChainPtr(new Chain());
109 }
110 
111 Composition::Composition(int prev_decay, ChainPtr decay_line)
112  : recorded_(false),
113  prev_decay_(prev_decay),
114  decay_line_(decay_line) {
115  id_ = next_id_;
116  next_id_++;
117 }
118 
119 Composition::Ptr Composition::NewDecay(int delta, uint64_t secs_per_timestep) {
120  int tot_decay = prev_decay_ + delta;
121  atom(); // force evaluation of atom-composition if not calculated already
122 
123  // the new composition is a part of this decay chain and so is created with a
124  // pointer to the exact same decay_line_.
125  Composition::Ptr decayed(new Composition(tot_decay, decay_line_));
126 
127  // FIXME this is only here for testing, see issue #761
128  if (atom_.size() == 0)
129  return decayed;
130 
131  // Get intial condition vector
132  std::vector<double> n0 (pyne_cram_transmute_info.n, 0.0);
133  CompMap::const_iterator it;
134  int i = -1;
135  for (it = atom_.begin(); it != atom_.end(); ++it) {
136  i = pyne_cram_transmute_nucid_to_i(it->first);
137  if (i < 0) {
138  continue;
139  }
140  n0[i] = it->second;
141  }
142 
143  // get decay matrix
144  double t = static_cast<double>(secs_per_timestep) * delta;
145  std::vector<double> decay_matrix (pyne_cram_transmute_info.nnz);
146  for (i=0; i < pyne_cram_transmute_info.nnz; ++i) {
147  decay_matrix[i] = -pyne_cram_transmute_info.decay_matrix[i] * t;
148  }
149 
150  // perform decay
151  std::vector<double> n1 (pyne_cram_transmute_info.n);
152  pyne_cram_expm_multiply14(decay_matrix.data(), n0.data(), n1.data());
153 
154  // convert back to map
155  CompMap cm;
156  for (i=0; i < pyne_cram_transmute_info.n; ++i) {
157  if (n1[i] > 0.0) {
158  cm[(pyne_cram_transmute_info.nucids)[i]] = n1[i];
159  }
160  }
161  decayed->atom_ = cm;
162  return decayed;
163 }
164 
165 } // namespace cyclus
boost::shared_ptr< Composition > Ptr
Definition: composition.h:43
bool AllPositive(const CompMap &v)
Returns true if all nuclides in v have quantities greater than or equal to zero.
Definition: comp_math.cc:83
For values that are too big, too small, etc.
Definition: error.h:41
int id()
Returns a unique id associated with this composition.
Definition: composition.cc:41
bool ValidNucs(const CompMap &v)
Returns true if all nuclide keys in v are valid.
Definition: comp_math.cc:73
ChainPtr decay_line_
Definition: composition.h:90
Ptr Decay(int delta)
Returns a decayed version of this composition (decayed delta timesteps) assuming a time step is 1/12 ...
Definition: composition.cc:83
std::map< Nuc, double > CompMap
a raw definition of nuclides and corresponding (dimensionless quantities).
Definition: composition.h:17
std::map< int, Composition::Ptr > Chain
a chain containing compositions that are a result of decay from a common ancestor composition...
Definition: composition.h:84
void pyne_cram_expm_multiply14(double *A, double *b, double *x)
Definition: cram.c:242901
pyne_cram_transmute_info_t pyne_cram_transmute_info
Definition: cram.c:26
const uint64_t kDefaultTimeStepDur
Definition: context.h:22
void Record(Context *ctx)
Records the composition in output database Compositions table (if not done previously).
Definition: composition.cc:87
Datum * AddVal(const char *field, boost::spirit::hold_any val, std::vector< int > *shape=NULL)
Add an arbitrary field-value pair to the datum.
Definition: datum.cc:22
A simulation context provides access to necessary simulation-global functions and state...
Definition: context.h:130
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or.org/Osi/browser/trunk.
Definition: agent.cc:14
const CompMap & mass()
Returns the unnormalized mass composition.
Definition: composition.cc:56
void Record()
Record this datum to its Recorder.
Definition: datum.cc:35
double atomic_mass(int nuc)
Returns the atomic mass of a nuclide nuc.
Definition: pyne.cc:10440
static Ptr CreateFromAtom(CompMap v)
Creates a new composition from v with its components having appropriate atom-based ratios...
Definition: composition.cc:17
Datum * NewDatum(std::string title)
See Recorder::NewDatum documentation.
Definition: context.cc:239
void Normalize(CompMap *v, double val)
The sum of quantities of all nuclides of v is normalized to val.
Definition: comp_math.cc:63
boost::shared_ptr< Chain > ChainPtr
Definition: composition.h:86
const CompMap & atom()
Returns the unnormalized atom composition.
Definition: composition.cc:45
int pyne_cram_transmute_nucid_to_i(int nucid)
Definition: cram.c:30168
static Ptr CreateFromMass(CompMap v)
Creates a new composition from v with its components having appropriate mass-based ratios...
Definition: composition.cc:29
int Nuc
Definition: composition.h:12