<commit_before>#include <gtest/gtest.h>

#include <sstream>

#include "facility_tests.h"
#include "toolkit/mat_query.h"
#include "agent_tests.h"
#include "resource_helpers.h"
#include "infile_tree.h"
#include "env.h"

#include "enrichment_tests.h"

using cyclus::QueryResult;
using cyclus::Cond;
using cyclus::CompMap;
using cyclus::toolkit::MatQuery;
using pyne::nucname::id;
using cyclus::Material;

namespace cycamore {
  
Composition::Ptr c_nou235() {
  cyclus::CompMap m;
  m[922380000] = 1.0;
  return Composition::CreateFromMass(m);
};
Composition::Ptr c_natu1() {
  cyclus::CompMap m;
  m[922350000] = 0.007;
  m[922380000] = 0.993;
  return Composition::CreateFromMass(m);
};
Composition::Ptr c_natu2() {
  cyclus::CompMap m;
  m[922350000] = 0.01;
  m[922380000] = 0.99;
  return Composition::CreateFromMass(m);
};
Composition::Ptr c_leu() {
  cyclus::CompMap m;
  m[922350000] = 0.04;
  m[922380000] = 0.96;
  return Composition::CreateFromMass(m);
};
Composition::Ptr c_heu() {
  cyclus::CompMap m;
  m[922350000] = 0.20;
  m[922380000] = 0.80;
  return Composition::CreateFromMass(m);
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, RequestQty) {
  // this tests verifies that requests for input material are fulfilled
  // without providing any extra
  
  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <max_feed_inventory>1.0</max_feed_inventory> "
    "   <tails_assay>0.003</tails_assay> ";

  int simdur = 1;
  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);
  sim.AddRecipe("natu1", c_natu1());
  
  sim.AddSource("natu")
    .recipe("natu1")
    .Finalize();
  
  int id = sim.Run();

  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("natu")));
  QueryResult qr = sim.db().Query("Transactions", &conds);
  Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
  
  // Should be only one transaction into the EF,
  // and it should be exactly 1kg of natu
  EXPECT_EQ(1.0, qr.rows.size());
  EXPECT_NEAR(1.0, m->quantity(), 1e-10) <<
    "matched trade provides the wrong quantity of material";
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, CheckSWUConstraint) {
  // Tests that request for enrichment that exceeds the SWU constraint
  // fulfilled only up to the available SWU.
  // Also confirms that initial_feed flag works.
  // 388 SWU = 10kg 80% enriched HEU from 486kg feed matl

  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <tails_assay>0.003</tails_assay> "
    "   <initial_feed>1000</initial_feed> "
    "   <swu_capacity>195</swu_capacity> ";

  int simdur = 1;
  
  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);
   
  sim.AddRecipe("natu1", c_natu1());
  sim.AddRecipe("heu", c_heu());
  
  sim.AddSink("enr_u")
    .recipe("heu")
    .capacity(10)
    .Finalize();
  
  int id = sim.Run();

  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("enr_u")));
  QueryResult qr = sim.db().Query("Transactions", &conds);
  Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));

  EXPECT_EQ(1.0, qr.rows.size());
  EXPECT_NEAR(5.0, m->quantity(), 0.1) <<
    "traded quantity exceeds SWU constraint";
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, CheckCapConstraint) {
  // Tests that a request for more material than is available in
  // inventory is partially filled with only the inventory quantity.

  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <tails_assay>0.003</tails_assay> "
    "   <initial_feed>243</initial_feed> ";

  int simdur = 1;

  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);


  sim.AddRecipe("natu1", c_natu1());
  sim.AddRecipe("heu", c_heu());
   
  sim.AddSink("enr_u")
    .recipe("heu")
    .capacity(10)
    .Finalize();
  
  int id = sim.Run();
  
  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("enr_u")));
  QueryResult qr = sim.db().Query("Transactions", &conds);
  Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));

  EXPECT_EQ(1.0, qr.rows.size());
  EXPECT_NEAR(5.0, m->quantity(), 0.01) <<
    "traded quantity exceeds capacity constraint";
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, RequestEnrich) {
  // this tests verifies that requests for output material exceeding
  // the maximum allowed enrichment are not fulfilled.
  
  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <tails_assay>0.003</tails_assay> "
    "   <max_enrich>0.20</max_enrich> ";

  int simdur = 2;
  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);
  sim.AddRecipe("natu1", c_natu1());
  sim.AddRecipe("leu", c_leu());
  sim.AddRecipe("heu", c_heu());
  
  sim.AddSource("natu")
    .recipe("natu1")
    .Finalize();
  sim.AddSink("enr_u")
    .recipe("leu")
    .capacity(1.0)
    .Finalize();
  sim.AddSink("enr_u")
    .recipe("heu")
    .Finalize();
  
  int id = sim.Run();

  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("enr_u")));
  QueryResult qr = sim.db().Query("Transactions", &conds);
  Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
   
  // Should be only one transaction out of the EF,
  // and it should be 1kg of LEU
  EXPECT_EQ(1.0, qr.rows.size());
  EXPECT_NEAR(1.0, m->quantity(), 0.01) <<
    "Not providing the requested quantity" ;

  CompMap got = m->comp()->mass();
  CompMap want = c_leu()->mass();
  cyclus::compmath::Normalize(&got);
  cyclus::compmath::Normalize(&want);

  CompMap::iterator it;
  for (it = want.begin(); it != want.end(); ++it) {
    EXPECT_DOUBLE_EQ(it->second, got[it->first]) <<
      "nuclide qty off: " << pyne::nucname::name(it->first);
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, TradeTails) {
  // this tests whether tails are being traded.

  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <tails_assay>0.003</tails_assay> ";

  // 1-source to EF, 2-Enrich, add to tails, 3-tails avail. for trade
  int simdur = 3;
  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);
  sim.AddRecipe("natu1", c_natu1());
  sim.AddRecipe("leu", c_leu());
  
  sim.AddSource("natu")
    .recipe("natu1")
    .Finalize();
  sim.AddSink("enr_u")
    .recipe("leu")
    .Finalize();
   sim.AddSink("tails")
    .Finalize();
  
  int id = sim.Run();

  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("tails")));
  QueryResult qr = sim.db().Query("Transactions", &conds);

  // Should be exactly one tails transaction
  EXPECT_EQ(1, qr.rows.size());
  
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, BidPrefs) {
  // This tests that natu sources are preference-ordered by
  // U235 content

  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "<commit_msg>added test to illustrate the bug.<commit_after>#include <gtest/gtest.h>

#include <sstream>

#include "facility_tests.h"
#include "toolkit/mat_query.h"
#include "agent_tests.h"
#include "resource_helpers.h"
#include "infile_tree.h"
#include "env.h"

#include "enrichment_tests.h"

using cyclus::QueryResult;
using cyclus::Cond;
using cyclus::CompMap;
using cyclus::toolkit::MatQuery;
using pyne::nucname::id;
using cyclus::Material;

namespace cycamore {
  
Composition::Ptr c_nou235() {
  cyclus::CompMap m;
  m[922380000] = 1.0;
  return Composition::CreateFromMass(m);
};
Composition::Ptr c_natu1() {
  cyclus::CompMap m;
  m[922350000] = 0.007;
  m[922380000] = 0.993;
  return Composition::CreateFromMass(m);
};
Composition::Ptr c_natu2() {
  cyclus::CompMap m;
  m[922350000] = 0.01;
  m[922380000] = 0.99;
  return Composition::CreateFromMass(m);
};
Composition::Ptr c_leu() {
  cyclus::CompMap m;
  m[922350000] = 0.04;
  m[922380000] = 0.96;
  return Composition::CreateFromMass(m);
};
Composition::Ptr c_heu() {
  cyclus::CompMap m;
  m[922350000] = 0.20;
  m[922380000] = 0.80;
  return Composition::CreateFromMass(m);
};

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, RequestQty) {
  // this tests verifies that requests for input material are fulfilled
  // without providing any extra
  
  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <max_feed_inventory>1.0</max_feed_inventory> "
    "   <tails_assay>0.003</tails_assay> ";

  int simdur = 1;
  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);
  sim.AddRecipe("natu1", c_natu1());
  
  sim.AddSource("natu")
    .recipe("natu1")
    .Finalize();
  
  int id = sim.Run();

  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("natu")));
  QueryResult qr = sim.db().Query("Transactions", &conds);
  Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
  
  // Should be only one transaction into the EF,
  // and it should be exactly 1kg of natu
  EXPECT_EQ(1.0, qr.rows.size());
  EXPECT_NEAR(1.0, m->quantity(), 1e-10) <<
    "matched trade provides the wrong quantity of material";
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, CheckSWUConstraint) {
  // Tests that request for enrichment that exceeds the SWU constraint
  // fulfilled only up to the available SWU.
  // Also confirms that initial_feed flag works.
  // 388 SWU = 10kg 80% enriched HEU from 486kg feed matl

  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <tails_assay>0.003</tails_assay> "
    "   <initial_feed>1000</initial_feed> "
    "   <swu_capacity>195</swu_capacity> ";

  int simdur = 1;
  
  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);
   
  sim.AddRecipe("natu1", c_natu1());
  sim.AddRecipe("heu", c_heu());
  
  sim.AddSink("enr_u")
    .recipe("heu")
    .capacity(10)
    .Finalize();
  
  int id = sim.Run();

  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("enr_u")));
  QueryResult qr = sim.db().Query("Transactions", &conds);
  Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));

  EXPECT_EQ(1.0, qr.rows.size());
  EXPECT_NEAR(5.0, m->quantity(), 0.1) <<
    "traded quantity exceeds SWU constraint";
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, CheckCapConstraint) {
  // Tests that a request for more material than is available in
  // inventory is partially filled with only the inventory quantity.

  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <tails_assay>0.003</tails_assay> "
    "   <initial_feed>243</initial_feed> ";

  int simdur = 1;

  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);


  sim.AddRecipe("natu1", c_natu1());
  sim.AddRecipe("heu", c_heu());
   
  sim.AddSink("enr_u")
    .recipe("heu")
    .capacity(10)
    .Finalize();
  
  int id = sim.Run();
  
  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("enr_u")));
  QueryResult qr = sim.db().Query("Transactions", &conds);
  Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));

  EXPECT_EQ(1.0, qr.rows.size());
  EXPECT_NEAR(5.0, m->quantity(), 0.01) <<
    "traded quantity exceeds capacity constraint";
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, RequestEnrich) {
  // this tests verifies that requests for output material exceeding
  // the maximum allowed enrichment are not fulfilled.
  
  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <tails_assay>0.003</tails_assay> "
    "   <max_enrich>0.20</max_enrich> ";

  int simdur = 2;
  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);
  sim.AddRecipe("natu1", c_natu1());
  sim.AddRecipe("leu", c_leu());
  sim.AddRecipe("heu", c_heu());
  
  sim.AddSource("natu")
    .recipe("natu1")
    .Finalize();
  sim.AddSink("enr_u")
    .recipe("leu")
    .capacity(1.0)
    .Finalize();
  sim.AddSink("enr_u")
    .recipe("heu")
    .Finalize();
  
  int id = sim.Run();

  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("enr_u")));
  QueryResult qr = sim.db().Query("Transactions", &conds);
  Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
   
  // Should be only one transaction out of the EF,
  // and it should be 1kg of LEU
  EXPECT_EQ(1.0, qr.rows.size());
  EXPECT_NEAR(1.0, m->quantity(), 0.01) <<
    "Not providing the requested quantity" ;

  CompMap got = m->comp()->mass();
  CompMap want = c_leu()->mass();
  cyclus::compmath::Normalize(&got);
  cyclus::compmath::Normalize(&want);

  CompMap::iterator it;
  for (it = want.begin(); it != want.end(); ++it) {
    EXPECT_DOUBLE_EQ(it->second, got[it->first]) <<
      "nuclide qty off: " << pyne::nucname::name(it->first);
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, TradeTails) {
  // this tests whether tails are being traded.

  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <tails_assay>0.003</tails_assay> ";

  // time 1-source to EF, 2-Enrich, add to tails, 3-tails avail. for trade
  int simdur = 3;
  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);
  sim.AddRecipe("natu1", c_natu1());
  sim.AddRecipe("leu", c_leu());
  
  sim.AddSource("natu")
    .recipe("natu1")
    .Finalize();
  sim.AddSink("enr_u")
    .recipe("leu")
    .Finalize();
   sim.AddSink("tails")
    .Finalize();
  
  int id = sim.Run();

  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("tails")));
  QueryResult qr = sim.db().Query("Transactions", &conds);

  // Should be exactly one tails transaction
  EXPECT_EQ(1, qr.rows.size());
  
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, TailsQty) {
  // this tests whether tails are being traded at correct quantity when
  // requested amount is larger than single element buffer size.

  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
    "   <tails_commod>tails</tails_commod> "
    "   <tails_assay>0.003</tails_assay> ";

  // time 1-source to EF, 2-Enrich, add to tails, 3-tails avail. for trade
  int simdur = 4;
  cyclus::MockSim sim(cyclus::AgentSpec
		      (":cycamore:Enrichment"), config, simdur);
  sim.AddRecipe("natu1", c_natu1());
  sim.AddRecipe("leu", c_leu());
  
  sim.AddSource("natu")
    .recipe("natu1")
    .Finalize();
  sim.AddSink("enr_u")
    .recipe("leu")
    .capacity(0.5)
    .Finalize();
  sim.AddSink("enr_u")
    .recipe("leu")
    .capacity(0.5)
    .Finalize();
  sim.AddSink("tails")
    .Finalize();

  int id = sim.Run();

  std::vector<Cond> conds;
  conds.push_back(Cond("Commodity", "==", std::string("tails")));
  QueryResult qr = sim.db().Query("Transactions", &conds);
  Material::Ptr m = sim.GetMaterial(qr.GetVal<int>("ResourceId"));
  
  // Total tails should be 8.168 for a capacity of 1.0 (half from each LEU sink)
  EXPECT_NEAR(8.168, m->quantity(), 0.1) <<
     //  EXPECT_NEAR(one_sink_qty * 2, m1->quantity(), 0.1) <<
    "Not providing the requested quantity" ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TEST_F(EnrichmentTest, BidPrefs) {
  // This tests that natu sources are preference-ordered by
  // U235 content

  std::string config = 
    "   <feed_commod>natu</feed_commod> "
    "   <feed_recipe>natu1</feed_recipe> "
    "   <product_commod>enr_u</product_commod> "
{'fraction_non_alphanumeric': 0.18721696761249643, 'fraction_numerical': 0.02762969332186873, 'mean_word_length': 3.0431054461181923, 'pattern_counts': {'":': 11, '<': 197, '<?xml version=': 0, '>': 191, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 52, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '777537', 'n_tokens_mistral': 7290, 'n_tokens_neox': 6869, 'n_words': 1131}