Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/material.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ void Material::Absorb(Material::Ptr mat) {

// force both mateiral objects to advance to the same decay time
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// force both mateiral objects to advance to the same decay time
// force both material objects to advance to the same decay time

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, whoops!

int common_decay_time = std::max(this->prev_decay_time_, mat->prev_decay_time_);
if (ctx_ != NULL && ctx_->sim_info().decay != "never") {
common_decay_time = ctx_->time();
if (HasContext() && mat->HasContext() && ctx_->sim_info().decay != "never") {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to understand why we care if the material has a context here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I misinterpreted something, but didn't we have a whole conversation about these needing a context above?

common_decay_time = std::max(ctx_->time(), common_decay_time);
}
Comment on lines +109 to 111
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I agree with this choice. I guess we haven't thought through all the possible permutations of the state of each material and what we should do in those states...

mat->Decay(common_decay_time);
this->Decay(common_decay_time);
Expand All @@ -128,7 +128,11 @@ void Material::Absorb(Material::Ptr mat) {
comp_ = Composition::CreateFromMass(compmath::Add(v, otherv));
}

qty_ += mat->qty_;
double tot_mass = qty_ + mat->quantity();
double avg_unit_value =
(qty_ * UnitValue() + mat->quantity() * mat->UnitValue()) / tot_mass;
SetUnitValue(avg_unit_value);
qty_ = tot_mass;
mat->qty_ = 0;
tracker_.Absorb(&mat->tracker_);
}
Expand Down Expand Up @@ -204,7 +208,8 @@ void Material::Decay(int curr_time) {
curr_time = ctx_->time();
}

int dt = curr_time - prev_decay_time_;
// Block backwards decay with std::max
int dt = std::max(curr_time - prev_decay_time_, 0);
Comment on lines +211 to +212
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change necessary to fix the problems we're experiencing?

Is it possible for this to occur? and might there be cases where we want to see where a material came from?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I think you suggested we do this?

Regarding backward decay:

  • I don't think it's every been considered a normal behavior

  • if we always want to force decay to move forward we need to not just use the context time, but take the max of >the previous decay times and the context time to determine the new time

  • we can also fail/warn if the previous decay times are ever beyond the current context time

  • if we leave it as is, it's possible that we cause decay to go backwards

whatever we choose, we need to test it appropriately

if (dt == 0) {
return;
}
Expand Down Expand Up @@ -242,7 +247,8 @@ void Material::Decay(int curr_time) {
}
}

prev_decay_time_ = curr_time; // this must go before Transmute call
// Need to set prev_decay_time before Transmute. Block setting it backwards.
prev_decay_time_ = std::max(curr_time, prev_decay_time_);
Composition::Ptr decayed = comp_->Decay(dt, secs_per_timestep);
Transmute(decayed);
}
Expand Down
3 changes: 3 additions & 0 deletions src/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ class Material : public Resource {
/// Returns the mass of this material in kg.
virtual double quantity() const;

/// Returns true if the material has a context, false otherwise.
virtual bool HasContext() const {return ctx_ != NULL;}

virtual Resource::Ptr ExtractRes(double qty);

/// Same as ExtractComp with c = this->comp().
Expand Down
61 changes: 52 additions & 9 deletions tests/material_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,38 @@ TEST_F(MaterialTest, AbsorbIntoZeroMaterial) {
EXPECT_FLOAT_EQ(test_size_, same_as_test_mat->quantity());
}

TEST_F(MaterialTest, AbsorbMatlWithoutContext) {
Material::Ptr no_ctx_mat = Material::CreateUntracked(0, test_comp_);
EXPECT_FALSE(no_ctx_mat->HasContext());
EXPECT_NO_THROW(test_mat_->Absorb(no_ctx_mat));
}

TEST_F(MaterialTest, BackwardsDecay) {
FakeContext* fake_ctx = new FakeContext(&ti, &rec);
TestFacility* fake_fac = new TestFacility(fake_ctx);

Material::Ptr m1 = Material::Create(fake_fac, 1, diff_comp_);
Material::Ptr m2 = Material::Create(fake_fac, 1, diff_comp_);

// Set context time to 10 to match the decay time
fake_ctx->time(10);

m2->Decay(); // decay m2 to time 10
EXPECT_EQ(0, m1->prev_decay_time());
EXPECT_EQ(10, m2->prev_decay_time());

fake_ctx->time(9);

// After manually setting the ctx time backwards, common_decay_time is 10,
// and ctx->time() is 9, meaning decay will set dt = 0 with std::max, and
// prev_decay_time for the combined mat should remain at 10.
m1->Absorb(m2);
EXPECT_EQ(10, m1->prev_decay_time());

delete fake_fac;
delete fake_ctx;
}

TEST_F(MaterialTest, ExtractMass) {
double amt = test_size_ / 3;
double diff = test_size_ - amt;
Expand Down Expand Up @@ -408,23 +440,34 @@ TEST_F(MaterialTest, TransmutePrevDecay) {
// as coded. We may decide to change the behavior in the future breaking
// this test; the test will need to be modified accordingly.
//
// This test checks to see that, when materials are absorbed together, the
// previous decay time for the larger quantity material is used as the value
// for the new, combined material.
// This test checks to see that, when materials are absorbed together, both
// materials are decayed prior to the absorption.

TEST_F(MaterialTest, AbsorbPrevDecay) {
Material::Ptr m1 = Material::Create(fac, 1, diff_comp_);
Material::Ptr m2 = Material::Create(fac, 1, diff_comp_);
Material::Ptr m3 = Material::Create(fac, 1000, diff_comp_);
m3->Decay(10);
FakeContext* fake_ctx = new FakeContext(&ti, &rec);
TestFacility* fake_fac = new TestFacility(fake_ctx);

Material::Ptr m1 = Material::Create(fake_fac, 1, diff_comp_);
Material::Ptr m2 = Material::Create(fake_fac, 1, diff_comp_);
Material::Ptr m3 = Material::Create(fake_fac, 1000, diff_comp_);

// Set context time to 10 to match the decay time
fake_ctx->time(10);

m3->Decay(); // decay m3 to time 10
EXPECT_EQ(0, m1->prev_decay_time());
EXPECT_EQ(0, m2->prev_decay_time());
EXPECT_EQ(10, m3->prev_decay_time());

fake_ctx->time(11);

m1->Absorb(m3);
EXPECT_EQ(10, m1->prev_decay_time());
EXPECT_EQ(11, m1->prev_decay_time());
m1->Absorb(m2);
EXPECT_EQ(10, m1->prev_decay_time());
EXPECT_EQ(11, m1->prev_decay_time());
Comment on lines 464 to +467
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should test that decay actually occurs? Or do we consider it covered by other tests?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We test the actual decay behavior in a few places, typically by calling decay and then checking that it's done something (using the EXPECT_NE test) but specifically in DecayCustomTimeStep we check that 1/2 of Cs-137 decays in one halflife of Cs-137, so I'd consider that "tested"


delete fake_fac;
delete fake_ctx;
}

TEST_F(MaterialTest, DecayHeatTest) {
Expand Down
1 change: 1 addition & 0 deletions tests/material_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "test_agents/test_facility.h"
#include "recorder.h"
#include "timer.h"
#include "test_context.h"


namespace cyclus {
Expand Down
Loading