// Costing Analysis
// LCC cleaned up formatting 8/2010

// this file contains data for ARIES-ACT-1d, provided by El-Guebaly and Wang
// May 15, 2012

#include <cstdlib>
#include <iostream>
#include <math.h>

using namespace std;
#include <string>
using std::string;

#include "Part.h"
#include "DesignPoint.h"
#include "CostingAccount.h"
#include "Geometry.h"
#include "Cost.h"

// Declare global variables from Aries.cpp
extern string blanketmode, dispmode, manifold;

// ====================================================================================
// These materical characteristics are all defined in Part.cpp
// This Cost.cpp module calls the material components based on: 
// (1) material name, (2) volume fraction, (3) density fraction, and (4) the material number.
// Volume frac is determined by the component in use (SCLL vs DCLL blanket).
// ALL costs are 1/16th sections.  Need to multiply by 16 in CA.cpp
// ====================================================================================


// NEED to check these for DCLL compatibility, add stabilizing shell? thermal insulation?

// First Wall, Inboard
void cost_first_wall_inboard(Part * Wall, int Year) { // base year, not current year
if(blanketmode == "dcll") {
   (*Wall).get_number_of_material_components(3);
   (*Wall).get_material_component("FS", 0.27, 0.95, 0); // #0 material
   (*Wall).get_material_component("FS", 0.08, 0.95, 1); // #1 material
   (*Wall).get_material_component("He", 0.65, 0.00, 2); // #2 material
   (*Wall).get_cost(Year); 
//cout << (*Wall).mass() << "\n";
//cout << (*Wall).cost() << "\n";
//cout << Year << "\n";
   }
else {
   (*Wall).get_number_of_material_components(2);
   (*Wall).get_material_component("SiC-comp", 0.545, 0.95, 0);
   (*Wall).get_material_component("PbLi",     0.455, 0.00, 1);
   (*Wall).get_cost(Year); } // calls algorithm line ~892 in Part.cpp
   //cout << (*Wall).cost() << "\n";
}


// First Wall, Outboard
void cost_first_wall_outboard(Part * Wall, int Year) {
if(blanketmode == "dcll") {
   (*Wall).get_number_of_material_components(3);
   (*Wall).get_material_component("FS", 0.27, 0.95, 0);
   (*Wall).get_material_component("FS", 0.08, 0.95, 1); 
   (*Wall).get_material_component("He", 0.65, 0.00, 2); 
   (*Wall).get_cost(Year); }
else {
   (*Wall).get_number_of_material_components(2);
   (*Wall).get_material_component("SiC-comp", 0.557, 0.95, 0);
   (*Wall).get_material_component("PbLi",     0.443, 0.00, 1);
   (*Wall).get_cost(Year); }
}


// Back Wall, Inboard - DCLL (also called front wall, same composition)
void cost_back_wall_inboard(Part * Wall, int Year) {
   (*Wall).get_number_of_material_components(2);
   (*Wall).get_material_component("FS", 0.8, 1.0, 0);
   (*Wall).get_material_component("He", 0.2, 0.0, 1);
   (*Wall).get_cost(Year);
}


// Back Wall, Outboard - DCLL
void cost_back_wall_outboard(Part * Wall, int Year) {
   (*Wall).get_number_of_material_components(2);
   (*Wall).get_material_component("FS", 0.8, 1.0, 0);
   (*Wall).get_material_component("He", 0.2, 0.0, 1);
   (*Wall).get_cost(Year);
}


// Blanket, Inboard
void cost_blanket_inboard(Part * Blanket, int Year) {
if(blanketmode == "dcll") {
   (*Blanket).get_number_of_material_components(4);
   (*Blanket).get_material_component("FS",			0.07,  1.00, 0);
   (*Blanket).get_material_component("PbLi",    	0.77,  0.00, 1);
   (*Blanket).get_material_component("He",	    	0.12,  0.00, 2);
   (*Blanket).get_material_component("SiC-comp",	0.037, 0.95, 3);
   (*Blanket).get_cost(Year); }
else{
   (*Blanket).get_number_of_material_components(3);
   (*Blanket).get_material_component("SiC-comp", 0.129, 0.95, 0);
   (*Blanket).get_material_component("PbLi",     0.839, 0.00, 1);
   (*Blanket).get_material_component("W",        0.032, 1.00, 2);
   (*Blanket).get_cost(Year); }
}


// Blanket I, Outboard
void cost_blanket_outboard(Part * Blanket, int Year) {
if(blanketmode == "dcll") {
   (*Blanket).get_number_of_material_components(4);
   (*Blanket).get_material_component("FS",			0.07,  1.00, 0);
   (*Blanket).get_material_component("PbLi",    	0.772, 0.00, 1);
   (*Blanket).get_material_component("He",	    	0.12,  0.00, 2);
   (*Blanket).get_material_component("SiC-comp",	0.042, 0.95, 3);
   (*Blanket).get_cost(Year); }
else {
   (*Blanket).get_number_of_material_components(2);
   (*Blanket).get_material_component("SiC-comp", 0.109, 0.95, 0);
   (*Blanket).get_material_component("PbLi",     0.891, 0.00, 1);
   (*Blanket).get_cost(Year); }
}


// Blanket II, Outboard
void cost_blanket_II(Part * Blanket, int Year) {
if(blanketmode == "dcll") {
   (*Blanket).get_number_of_material_components(4);
   (*Blanket).get_material_component("FS",			0.08,  1.00, 0);
   (*Blanket).get_material_component("PbLi",    	0.784, 0.00, 1);
   (*Blanket).get_material_component("He",	    	0.09,  0.00, 2);
   (*Blanket).get_material_component("SiC-comp",	0.039, 0.95, 3);
   (*Blanket).get_cost(Year); }
   else { 
   (*Blanket).get_number_of_material_components(3);
   (*Blanket).get_material_component("SiC-comp", 0.135, 0.95, 0);
   (*Blanket).get_material_component("PbLi",     0.835, 0.00, 1);
   (*Blanket).get_material_component("W",        0.030, 1.00, 2);
   (*Blanket).get_cost(Year); }
}


// Divertor Plates
// Setup.data input file tells which divertor is in use - plate. plate/finger, T-tube
// but so far compositions are the same...
void cost_divertor(Part (*Divertor)[6], int Year) {
for(int i=0; i<6; i++)
  { (*Divertor)[i].get_number_of_material_components(4);
    (*Divertor)[i].get_material_component("RAFS-div", 0.090, 1.0, 0); // special RAFS-div material, Laila says ODS-FS
    (*Divertor)[i].get_material_component("W",        0.407, 1.0, 1);
    (*Divertor)[i].get_material_component("He",       0.495, 0.0, 2); // make sure to change ~1491 in CA.cpp, He frac in div
    (*Divertor)[i].get_material_component("Void", 	  0.008, 0.0, 3);
    (*Divertor)[i].get_cost(Year); }
}


// Replaceable HT Shield (in divertor region)
// for ACT-1d, this includes He manifolding, breeding zone and skeleton ring
// 
void cost_replaceable_ht_shield(Part (*Shield)[2], int Year) {
for(int i=0; i<2; i++) {
if(blanketmode == "dcll") {
	(*Shield)[i].get_number_of_material_components(3);
	(*Shield)[i].get_material_component("FS",	0.20, 1.0, 0);
	(*Shield)[i].get_material_component("He",	0.20, 0.0, 1);
	(*Shield)[i].get_material_component("B-FS",	0.60, 1.0, 2);
	(*Shield)[i].get_cost(Year); }
else {
	(*Shield)[i].get_number_of_material_components(4);
	(*Shield)[i].get_material_component("FS",	    0.411, 1.0,  0);
	(*Shield)[i].get_material_component("SiC-comp", 0.351, 0.95, 1);
	(*Shield)[i].get_material_component("PbLi",     0.149, 0.0,  2);
	(*Shield)[i].get_material_component("He",       0.089, 0.0,  3);
	(*Shield)[i].get_cost(Year); }
} }


// HT Shield - SCLL, IB+OB separate
// for ACT-1d, this is the skeleton ring
// (breeding parts are found in the blanket)
void cost_ht_shield_sic(Part (*Shield)[2], int Year) {
// Inboard Shield
   (*Shield)[0].get_number_of_material_components(2);
   (*Shield)[0].get_material_component("FS", 0.8, 1.0, 0);
   (*Shield)[0].get_material_component("He", 0.2, 0.0, 1);
   (*Shield)[0].get_cost(Year);


// Outboard Shield
   (*Shield)[1].get_number_of_material_components(2);
   (*Shield)[1].get_material_component("FS", 0.8, 1.0, 0);
   (*Shield)[1].get_material_component("He", 0.2, 0.0, 1);
   (*Shield)[1].get_cost(Year);
}


// HT Shield - DCLL, IB+OB combined
void cost_ht_shield_dcll(Part *Shield, int Year) {
   (*Shield).get_number_of_material_components(3);
   (*Shield).get_material_component("FS",   0.15, 1.0, 0);
   (*Shield).get_material_component("He",   0.10, 0.0, 1);
   (*Shield).get_material_component("B-FS", 0.75, 1.0, 2);
   (*Shield).get_cost(Year); 
}


// Skeleton Ring - DCLL
// mst: not used for ACT-1d
void cost_skeleton_ring(Part *Ring, int Year) {
	(*Ring).get_number_of_material_components(3);
   
	(*Ring).get_material_component("FS",   0.20, 1.0, 0);
   
	(*Ring).get_material_component("He",   0.20, 0.0, 1);
   
	(*Ring).get_material_component("B-FS", 0.60, 1.0, 2);
	(*Ring).get_cost(Year); }


// Manifold - DCLL
void cost_manifold(Part *Manifold, int Year) {
	(*Manifold).get_number_of_material_components(4);
	(*Manifold).get_material_component("FS", 		0.34, 1.0, 	0);
	(*Manifold).get_material_component("PbLi", 		0.31, 0.0, 	1);
	(*Manifold).get_material_component("He", 		0.33, 0.0, 	2);
	(*Manifold).get_material_component("SiC-comp", 	0.02, 0.95, 3);
	(*Manifold).get_cost(Year);
}


// Manifolding - SCLL (New 2/2012)
// mst: not used for ACT-1d
void cost_manifolding(Part (*Manifolding)[2], int Year) {
for(int i=0; i<2; i++) {
	(*Manifolding)[i].get_number_of_material_components(4);
	(*Manifolding)[i].get_material_component("FS", 	 	 0.30, 1.0,  0);
// rough numbers from M. Tillack
	(*Manifolding)[i].get_material_component("PbLi", 	 0.50, 0.0,  1);
	(*Manifolding)[i].get_material_component("He", 	 	 0.10, 0.0,  2);
	(*Manifolding)[i].get_material_component("SiC-comp", 0.10, 0.95, 3); // not SiC, only SiC-comp
	(*Manifolding)[i].get_cost(Year); 
//cout << (*Manifolding)[i].cost() << "\n";
} }


// Vacuum Vessel - SCLL
// in ACT-1d, this includes both the actual vessel and the LT shield
void cost_vacuum_vessel(Part (*Vessel)[4], int Year) {

// Inboard (SCLL)

   (*Vessel)[0].get_number_of_material_components(4);
   (*Vessel)[0].get_material_component("RAFS", 0.197, 1.00, 0);
   (*Vessel)[0].get_material_component("WC",   0.576, 0.95, 1);
   (*Vessel)[0].get_material_component("He",   0.020, 0.00, 2);
   (*Vessel)[0].get_material_component("H2O",  0.207, 0.00, 3);
   (*Vessel)[0].get_cost(Year);

// Outboard (SCLL)

   (*Vessel)[1].get_number_of_material_components(4);
   (*Vessel)[1].get_material_component("RAFS", 0.413, 1.00, 0);
   (*Vessel)[1].get_material_component("B-FS", 0.233, 1.00, 1);
   (*Vessel)[1].get_material_component("He",   0.029, 0.00, 2);
   (*Vessel)[1].get_material_component("H2O",  0.325, 0.00, 3);
   (*Vessel)[1].get_cost(Year);

// Top (SCLL)

   (*Vessel)[2].get_number_of_material_components(4);
   (*Vessel)[2].get_material_component("RAFS", 0.252, 1.0, 0);
   (*Vessel)[2].get_material_component("WC",   0.524, 1.0, 1);
   (*Vessel)[2].get_material_component("He",   0.036, 0.0, 2);
   (*Vessel)[2].get_material_component("H2O",  0.188, 0.0, 3);
   (*Vessel)[2].get_cost(Year);

// Bottom (SCLL)

   (*Vessel)[3].get_number_of_material_components(4);
   (*Vessel)[3].get_material_component("RAFS", 0.252, 1.0, 0);
   (*Vessel)[3].get_material_component("WC",   0.524, 1.0, 1);
   (*Vessel)[3].get_material_component("He",   0.036, 0.0, 2);
   (*Vessel)[3].get_material_component("H2O",  0.188, 0.0, 3);
   (*Vessel)[3].get_cost(Year);

}


// Vacuum Vessel - DCLL
void cost_vacuum_vessel_dcll(Part (*Vessel)[4], int Year) {

// Inboard (DCLL)

   (*Vessel)[0].get_number_of_material_components(3);
   (*Vessel)[0].get_material_component("FS",   0.15, 1.0, 0);
   (*Vessel)[0].get_material_component("B-FS", 0.25, 1.0, 1);
   (*Vessel)[0].get_material_component("H2O",  0.60, 0.0, 2); 
   (*Vessel)[0].get_cost(Year);

// Outboard (DCLL)

   (*Vessel)[1].get_number_of_material_components(3);
   (*Vessel)[1].get_material_component("FS",   0.15, 1.0, 0);
   (*Vessel)[1].get_material_component("B-FS", 0.25, 1.0, 1);
   (*Vessel)[1].get_material_component("H2O",  0.60, 0.0, 2);
   (*Vessel)[1].get_cost(Year);

// Top (DCLL)

   (*Vessel)[2].get_number_of_material_components(3);
   (*Vessel)[2].get_material_component("FS",   0.15, 1.0, 0);
   (*Vessel)[2].get_material_component("B-FS", 0.25, 1.0, 1);
   (*Vessel)[2].get_material_component("H2O",  0.60, 0.0, 2);
   (*Vessel)[2].get_cost(Year);

// Bottom (DCLL)

   (*Vessel)[3].get_number_of_material_components(3);
   (*Vessel)[3].get_material_component("FS",   0.15, 1.0, 0);
   (*Vessel)[3].get_material_component("B-FS", 0.25, 1.0, 1);
   (*Vessel)[3].get_material_component("H2O",  0.60, 0.0, 2);
   (*Vessel)[3].get_cost(Year);
}


// 1/2 TF Coil
// ... unit mass and cable length based, conservative cost estimate
void cost_tf_coil_conservative(Part * Magnet, DesignPoint * Machine, int Year) {
   (*Magnet).get_number_of_material_components(1);
   (*Magnet).get_cost(Year);
   double StructureCost = (*Magnet).cost();

// Total length of the TF magnet cable:
    double tfPerimeter = 0.5*((*Magnet).perimeter("inner") + (*Magnet).perimeter("outer"));
    double cableLength = (*Machine).tf_magnet_cable_turns()*tfPerimeter;

// Costs per unit length in 2008 dollars:
   double c_cable   = 260.0*(*Magnet).inflation(2008, Year); // ref?
   double CableCost = c_cable*cableLength;
   (*Magnet).add_to_cost(CableCost);
//cout << "TF magnet cost conserv = " << CableCost << "\n";

// Sub-cost of the TF Magnet:
   (*Magnet).get_sub_cost(0, CableCost);
   (*Magnet).get_sub_cost(1, StructureCost);   
}


// 2/2 TF Coil
// ... cost per unit mass based combined with cable length based (not in use)
void cost_tf_coil(Part * Magnet, DesignPoint * Machine, int Year) {
   (*Magnet).get_number_of_material_components(2);
   (*Magnet).get_cost(Year); 

   
// Total length of the TF magnet cable:
   double tfPerimeter = 0.5*((*Magnet).perimeter("inner") + (*Magnet).perimeter("outer"));
   double cableLength = (*Machine).tf_magnet_cable_turns()*tfPerimeter;
   
   
// Costs per unit length in 2007 dollars:
   double c_stabilizer = 8.00*(*Magnet).inflation(2007, Year); // ref?
   double c_diffusion  = 1.65*(*Magnet).inflation(2007, Year); // ref?
   double c_insulation_and_cabling = 100.0*(*Magnet).inflation(2007, Year); // ref?
   double c_cable   = c_stabilizer + c_diffusion + c_insulation_and_cabling;
   double CableCost = c_cable*cableLength;
   (*Magnet).add_to_cost(CableCost);
}


// Maintenance Port Window
void cost_mpw(Part * Window, int Year) {
   (*Window).get_number_of_material_components(1);
   (*Window).get_material_component("TF-coil", 1.0, 1.0, 0);
// cost is "TF Coil" because that is what it is a window between
// mst: I don't understand this at all
   (*Window).get_cost(Year);
}


// PF Coil
void cost_pf_coil(Part (*Magnet)[36], int Year) {
for(int i=0; i<36; i++) {
   (*Magnet)[i].get_number_of_material_components(1);
   (*Magnet)[i].get_material_component("PF-coil", 1.0, 1.0, 0);
   (*Magnet)[i].get_cost(Year); 
} }



// Bucking Cylinder
void cost_bucking_cylinder(Part * BuckingCylinder, int Year) {
   (*BuckingCylinder).get_number_of_material_components(1);
   (*BuckingCylinder).get_material_component("RAFS", 1.0, 1.0, 0);
   (*BuckingCylinder).get_cost(Year);
}


// Upper cap
void cost_upper_cap(Part * UpperCap, int Year) {
   (*UpperCap).get_number_of_material_components(1);
   (*UpperCap).get_material_component("RAFS", 1.0, 1.0, 0);
   (*UpperCap).get_cost(Year);
}


// Lower cap
void cost_lower_cap(Part * LowerCap, int Year) {
   (*LowerCap).get_number_of_material_components(1);
   (*LowerCap).get_material_component("RAFS", 1.0, 1.0, 0);
   (*LowerCap).get_cost(Year);
}


// Cryogenic Dome or "cryodome, cryostat"
void cost_cryogenic_dome(Part * Cryo, int Year) {
   (*Cryo).get_number_of_material_components(2);
   (*Cryo).get_material_component("RAFS-cryost",  	0.18, 1.0, 0);
   (*Cryo).get_material_component("Void",			0.82, 0.0, 1);
   (*Cryo).get_cost(Year); // for 1/16th unit ~7.5 M$
}


// Maintenance Port

void cost_maintenance_port(Part * MaintenancePort, int Year) {
   (*MaintenancePort).get_number_of_material_components(2);
   (*MaintenancePort).get_material_component("RAFS", 0.9, 1.0,  0);
   (*MaintenancePort).get_material_component("He",   0.1, 0.0,  1);
   (*MaintenancePort).get_cost(Year);
}


// Upper Vacuum Vessel Duct

void cost_upper_vv_duct(Part (*Duct)[3], int Year) {
for(int i=0; i<3; i++) {
   (*Duct)[i].get_number_of_material_components(2);
   (*Duct)[i].get_material_component("RAFS", 0.9, 1.0,  0);
   (*Duct)[i].get_material_component("He",   0.1, 0.0,  1);
   (*Duct)[i].get_cost(Year); 
} }
