// File: JRLamontagne[P]cdice_sa/CDICEMain.cpp
// Function: main
int main(int argc, char* argv[])
{
	// Initialize MPI
	MPI::Init(argc,argv);
	
  // Obtain the number of iterations, from the input	
  int N = atof(argv[2]);
  
  // Obtain the CDICE input file name, from the input
  string filename = argv[1];
  
  // Get the number of processes, and the id of this process
  int rank = MPI::COMM_WORLD.Get_rank();
  int nprocs = MPI::COMM_WORLD.Get_size();

  // Determine the chunk which each processor will need to do.
  int count = N/nprocs;
  
  // We use the rank of this processor to determine which chunk of iterations it
  // will perform
  int start;
  int stop;
  int rem = N%nprocs;
  
  if(rank<rem) {
		start = rank*(count+1);
		stop = start+count+1;
  }
  else {
		start = rem*(count+1)+(rank-rem)*count;
		stop = start+count;
  }


/*	// DEBUG -----------------------------------------------------------------------------
	string filename = argv[1];
	string name = "./output/CDICE_DOECLIM_output.txt";
	int stop = 1;
	int start = 0;
	// -----------------------------------------------------------------------------------
*/	
	
  // Load-in the data
  vector< vector <double> > params = readFile(filename, start, stop);
  vector<double> params_hold;
  
  // Initialize the DICE structures
  // Note: Allocating here allows us to test for
  // DOECLIM.  We can then adjust the output filename
  // accordingly.
  allocateDICE(dicePtr);
  allocateDICE(dice2Ptr);
  
  //This code generates the file name based on processor rank
  char rnk [50];
  int l = sprintf(rnk,"%d",rank);
  string name = "CDICE_";
  name += "output_";
  name += rnk;
  name +=".txt";

	
  // This code opens the output file.
  ofstream myfile;
  myfile.open(name.c_str());
  
  // Loop over params
  int param_len = stop - start;
  for(int j=0; j<param_len; j++) {
	  params_hold = params[j];
	  
	  // Populate the parameter values with this current parameter sample
	  populateDICE(dicePtr, params_hold);
	  populateDICE(dice2Ptr, params_hold);
	  
	  // Initialize DICE for this set of parameters (if needed)
	  initTS(dicePtr);
	  initTS(dice2Ptr);
	  if(dicePtr->ctrl.use_doeclim == 1){
	  	doeclim_load_hind_forc(dicePtr);
	  	doeclim_load_hind_forc(dice2Ptr);
		  doeclim_DICE_init(dicePtr);
		  doeclim_DICE_init(dice2Ptr);	  
		}

	  // Run the model
	  calc_CDICE(dicePtr, dice2Ptr);
	  
	  //myfile <<-99<< " " <<start+j<< endl;
	  // Print the index of the factor set
	  
	  // PRINT OUT MODEL VARIABLES-------------------------------------------
	  // These time-series variables will be printed out to stdout forming
	  // space-delimited columns.  The output can be considered a matrix of
	  // size (dicePtr->config.nPeriods x N) where N is the number of
	  // variables being output.  Time increases with each row, so row 1 would
	  // be the initial time-step and row dicePtr->config.nPeriods would be
	  // the last.
  
	  // Here's currently what is being output
	  // Column: Variable
	  // 1			Utility of per-capita consumption for a given period
	  // 2			Population
	  // 3			Discount Factor
	  // 4			NPV Damages
	  // 5			NPV Abatement
	  // 6			Social cost of carbon
	  // 7			Gross Atmospheric temperature
	  // 8			Gross GWP
	  // 9			Cumulative Carbon
  
	  // Time series variables
	  for(int i=0; i<dicePtr->config.nPeriods; i++) {
	  	
	  	// Figure out which temperature variable to use
	  	double this_temp = 0.0;
	  	if(dicePtr->ctrl.use_doeclim == 1){
	  		this_temp = dicePtr->clim.temp[(dicePtr->config.hind_ns -1) + (i * (int)dicePtr->config.tstep)];
	  	}
	  	else {
	  		this_temp = dicePtr->clim.tatm[i];
	  	}
	
			// Print each time step's econ parameters to file
		  myfile << start+j << " "
		  << i << " "
		  << dicePtr->econ.periodu[i] << " "
		  << dicePtr->econ.l[i] << " "
		  << dicePtr->econ.rr[i] << " "
		  << dicePtr->econ.ri[i] << " "
		  << dicePtr->econ.pv_damages[i] << " "
		  << dicePtr->econ.pv_abatecost[i] << " "
		  << dicePtr->econ.abatecost[i] << " "
		  << dicePtr->econ.damages[i] << " "
		  << dicePtr->econ.c[i] << " "
		  << dicePtr->econ.scc[i] << " "
		  << this_temp << " "
		  << dicePtr->carb.mat[i] << " "
		  << dicePtr->carb.forc[i] << " "
		  << dicePtr->econ.cca[i] << " "
		  << dicePtr->lims.cca_up_step << " " << endl;
	  }	
  }

  myfile.close();
  MPI::Finalize();

  return 0;

}

// Assembly:
subq $0x4b8, %rsp            # imm = 0x4B8
movl $0x0, 0x4b4(%rsp)
movl %edi, 0x4b0(%rsp)
movq %rsi, 0x4a8(%rsp)
leaq 0x4b0(%rsp), %rdi
leaq 0x4a8(%rsp), %rsi
callq 0xb990
movq 0x4a8(%rsp), %rax
movq 0x10(%rax), %rdi
callq 0x9860
cvttsd2si %xmm0, %eax
movl %eax, 0x4a4(%rsp)
movq 0x4a8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x138(%rsp)
leaq 0x47f(%rsp), %rdi
movq %rdi, 0x140(%rsp)
callq 0x9c90
movq 0x138(%rsp), %rsi
movq 0x140(%rsp), %rdx
leaq 0x480(%rsp), %rdi
callq 0xb9c0
jmp 0xa54a
leaq 0x47f(%rsp), %rdi
callq 0x9720
movq 0x18a6a(%rip), %rdi     # 0x22fc8
callq 0xba80
movl %eax, 0x134(%rsp)
jmp 0xa56c
movl 0x134(%rsp), %eax
movl %eax, 0x468(%rsp)
movq 0x18a47(%rip), %rdi     # 0x22fc8
callq 0xbab0
movl %eax, 0x130(%rsp)
jmp 0xa58f
movl 0x130(%rsp), %eax
movl %eax, 0x464(%rsp)
movl 0x4a4(%rsp), %eax
cltd
idivl 0x464(%rsp)
movl %eax, 0x460(%rsp)
movl 0x4a4(%rsp), %eax
cltd
idivl 0x464(%rsp)
movl %edx, 0x454(%rsp)
movl 0x468(%rsp), %eax
cmpl 0x454(%rsp), %eax
jge 0xa650
movl 0x468(%rsp), %eax
movl 0x460(%rsp), %ecx
addl $0x1, %ecx
imull %ecx, %eax
movl %eax, 0x45c(%rsp)
movl 0x45c(%rsp), %eax
addl 0x460(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x458(%rsp)
jmp 0xa698
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x470(%rsp)
movl %eax, 0x46c(%rsp)
leaq 0x47f(%rsp), %rdi
callq 0x9720
jmp 0xb088
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x470(%rsp)
movl %eax, 0x46c(%rsp)
jmp 0xb07b
movl 0x454(%rsp), %eax
movl 0x460(%rsp), %ecx
addl $0x1, %ecx
imull %ecx, %eax
movl 0x468(%rsp), %ecx
subl 0x454(%rsp), %ecx
imull 0x460(%rsp), %ecx
addl %ecx, %eax
movl %eax, 0x45c(%rsp)
movl 0x45c(%rsp), %eax
addl 0x460(%rsp), %eax
movl %eax, 0x458(%rsp)
leaq 0x418(%rsp), %rdi
leaq 0x480(%rsp), %rsi
callq 0x9240
jmp 0xa6af
movl 0x45c(%rsp), %edx
movl 0x458(%rsp), %ecx
leaq 0x438(%rsp), %rdi
leaq 0x418(%rsp), %rsi
callq 0xa1e0
jmp 0xa6d4
leaq 0x418(%rsp), %rdi
callq 0x9390
leaq 0x400(%rsp), %rdi
callq 0xb7a0
movq 0x19023(%rip), %rdi     # 0x23718
callq 0x14b00
jmp 0xa6fc
movq 0x1901d(%rip), %rdi     # 0x23720
callq 0x14b00
jmp 0xa70a
movl 0x468(%rsp), %edx
leaq 0x11900(%rip), %rsi     # 0x1c018
xorl %eax, %eax
leaq 0x3c0(%rsp), %rdi
callq 0x90f0
movl %eax, 0x3bc(%rsp)
leaq 0x397(%rsp), %rdi
movq %rdi, 0x128(%rsp)
callq 0x9c90
movq 0x128(%rsp), %rdx
leaq 0x118c9(%rip), %rsi     # 0x1c01b
leaq 0x398(%rsp), %rdi
callq 0xb9c0
jmp 0xa761
leaq 0x397(%rsp), %rdi
callq 0x9720
leaq 0x118ad(%rip), %rsi     # 0x1c022
leaq 0x398(%rsp), %rdi
callq 0x9640
jmp 0xa784
leaq 0x398(%rsp), %rdi
leaq 0x3c0(%rsp), %rsi
callq 0x9640
jmp 0xa79b
leaq 0x11b94(%rip), %rsi     # 0x1c336
leaq 0x398(%rsp), %rdi
callq 0x9640
jmp 0xa7b1
leaq 0x190(%rsp), %rdi
callq 0x9c10
jmp 0xa7c0
leaq 0x398(%rsp), %rdi
callq 0x9220
movq %rax, %rsi
leaq 0x190(%rsp), %rdi
movl $0x10, %edx
callq 0x9040
jmp 0xa7e4
movl 0x458(%rsp), %eax
subl 0x45c(%rsp), %eax
movl %eax, 0x18c(%rsp)
movl $0x0, 0x188(%rsp)
movl 0x188(%rsp), %eax
cmpl 0x18c(%rsp), %eax
jge 0xafd6
movslq 0x188(%rsp), %rsi
leaq 0x438(%rsp), %rdi
callq 0xbae0
movq %rax, %rsi
leaq 0x400(%rsp), %rdi
callq 0xbb00
jmp 0xa83f
movq 0x18ed2(%rip), %rax     # 0x23718
movq %rax, 0x120(%rsp)
leaq 0x170(%rsp), %rdi
leaq 0x400(%rsp), %rsi
callq 0xbdc0
jmp 0xa865
movq 0x120(%rsp), %rdi
leaq 0x170(%rsp), %rsi
callq 0x13fa0
jmp 0xa87c
leaq 0x170(%rsp), %rdi
callq 0xb8d0
movq 0x18e90(%rip), %rax     # 0x23720
movq %rax, 0x118(%rsp)
leaq 0x158(%rsp), %rdi
leaq 0x400(%rsp), %rsi
callq 0xbdc0
jmp 0xa8af
movq 0x118(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x13fa0
jmp 0xa8c6
leaq 0x158(%rsp), %rdi
callq 0xb8d0
movq 0x18e3e(%rip), %rdi     # 0x23718
callq 0x138f0
jmp 0xa8e1
movq 0x18e38(%rip), %rdi     # 0x23720
callq 0x138f0
jmp 0xa8ef
movq 0x18e22(%rip), %rax     # 0x23718
cmpl $0x1, 0x58(%rax)
jne 0xaa20
movq 0x18e11(%rip), %rdi     # 0x23718
callq 0x1af50
jmp 0xa90e
movq 0x18e0b(%rip), %rdi     # 0x23720
callq 0x1af50
jmp 0xa91c
movq 0x18df5(%rip), %rdi     # 0x23718
callq 0x1a900
jmp 0xa92a
movq 0x18def(%rip), %rdi     # 0x23720
callq 0x1a900
jmp 0xa938
jmp 0xaa20
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x470(%rsp)
movl %eax, 0x46c(%rsp)
leaq 0x418(%rsp), %rdi
callq 0x9390
jmp 0xb07b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x470(%rsp)
movl %eax, 0x46c(%rsp)
jmp 0xb061
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x470(%rsp)
movl %eax, 0x46c(%rsp)
leaq 0x397(%rsp), %rdi
callq 0x9720
jmp 0xb061
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x470(%rsp)
movl %eax, 0x46c(%rsp)
jmp 0xb054
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x470(%rsp)
movl %eax, 0x46c(%rsp)
jmp 0xb047
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x470(%rsp)
movl %eax, 0x46c(%rsp)
leaq 0x170(%rsp), %rdi
callq 0xb8d0
jmp 0xb047
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x470(%rsp)
movl %eax, 0x46c(%rsp)
leaq 0x158(%rsp), %rdi
callq 0xb8d0
jmp 0xb047
movq 0x18cf1(%rip), %rdi     # 0x23718
movq 0x18cf2(%rip), %rsi     # 0x23720
callq 0xa010
jmp 0xaa35
movl $0x0, 0x154(%rsp)
movl 0x154(%rsp), %eax
movq 0x18cca(%rip), %rcx     # 0x23718
cmpl (%rcx), %eax
jge 0xafbe
xorps %xmm0, %xmm0
movsd %xmm0, 0x148(%rsp)
movq 0x18caf(%rip), %rax     # 0x23718
cmpl $0x1, 0x58(%rax)
jne 0xaab5
movq 0x18ca2(%rip), %rax     # 0x23718
movq 0x140(%rax), %rax
movq 0x18c94(%rip), %rcx     # 0x23718
movl 0x20(%rcx), %ecx
subl $0x1, %ecx
movl 0x154(%rsp), %edx
movq 0x18c80(%rip), %rsi     # 0x23718
cvttsd2si 0x8(%rsi), %esi
imull %esi, %edx
addl %edx, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x148(%rsp)
jmp 0xaad9
movq 0x18c5c(%rip), %rax     # 0x23718
movq 0x128(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x148(%rsp)
movl 0x45c(%rsp), %esi
movl 0x188(%rsp), %eax
addl %eax, %esi
leaq 0x190(%rsp), %rdi
callq 0x9c40
movq %rax, 0x110(%rsp)
jmp 0xab00
movq 0x110(%rsp), %rdi
leaq 0x1151b(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x108(%rsp)
jmp 0xab1e
movq 0x108(%rsp), %rdi
movl 0x154(%rsp), %esi
callq 0x9c40
movq %rax, 0x100(%rsp)
jmp 0xab3c
movq 0x100(%rsp), %rdi
leaq 0x114df(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0xf8(%rsp)
jmp 0xab5a
movq 0xf8(%rsp), %rdi
movq 0x18baf(%rip), %rax     # 0x23718
movq 0x368(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0xf0(%rsp)
jmp 0xab8c
movq 0xf0(%rsp), %rdi
leaq 0x1148f(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0xe8(%rsp)
jmp 0xabaa
movq 0xe8(%rsp), %rdi
movq 0x18b5f(%rip), %rax     # 0x23718
movq 0x288(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0xe0(%rsp)
jmp 0xabdc
movq 0xe0(%rsp), %rdi
leaq 0x1143f(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0xd8(%rsp)
jmp 0xabfa
movq 0xd8(%rsp), %rdi
movq 0x18b0f(%rip), %rax     # 0x23718
movq 0x2c8(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0xd0(%rsp)
jmp 0xac2c
movq 0xd0(%rsp), %rdi
leaq 0x113ef(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0xc8(%rsp)
jmp 0xac4a
movq 0xc8(%rsp), %rdi
movq 0x18abf(%rip), %rax     # 0x23718
movq 0x328(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0xc0(%rsp)
jmp 0xac7c
movq 0xc0(%rsp), %rdi
leaq 0x1139f(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0xb8(%rsp)
jmp 0xac9a
movq 0xb8(%rsp), %rdi
movq 0x18a6f(%rip), %rax     # 0x23718
movq 0x390(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0xb0(%rsp)
jmp 0xaccc
movq 0xb0(%rsp), %rdi
leaq 0x1134f(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0xa8(%rsp)
jmp 0xacea
movq 0xa8(%rsp), %rdi
movq 0x18a1f(%rip), %rax     # 0x23718
movq 0x398(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0xa0(%rsp)
jmp 0xad1c
movq 0xa0(%rsp), %rdi
leaq 0x112ff(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x98(%rsp)
jmp 0xad3a
movq 0x98(%rsp), %rdi
movq 0x189cf(%rip), %rax     # 0x23718
movq 0x358(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0x90(%rsp)
jmp 0xad6c
movq 0x90(%rsp), %rdi
leaq 0x112af(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x88(%rsp)
jmp 0xad8a
movq 0x88(%rsp), %rdi
movq 0x1897f(%rip), %rax     # 0x23718
movq 0x348(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0x80(%rsp)
jmp 0xadbc
movq 0x80(%rsp), %rdi
leaq 0x1125f(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x78(%rsp)
jmp 0xadd7
movq 0x78(%rsp), %rdi
movq 0x18935(%rip), %rax     # 0x23718
movq 0x308(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0x70(%rsp)
jmp 0xae03
movq 0x70(%rsp), %rdi
leaq 0x1121b(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x68(%rsp)
jmp 0xae1b
movq 0x68(%rsp), %rdi
movq 0x188f1(%rip), %rax     # 0x23718
movq 0x2b0(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0x60(%rsp)
jmp 0xae47
movq 0x60(%rsp), %rdi
leaq 0x111d7(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x58(%rsp)
jmp 0xae5f
movq 0x58(%rsp), %rdi
movsd 0x148(%rsp), %xmm0
callq 0x9d70
movq %rax, 0x50(%rsp)
jmp 0xae79
movq 0x50(%rsp), %rdi
leaq 0x111a5(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x48(%rsp)
jmp 0xae91
movq 0x48(%rsp), %rdi
movq 0x1887b(%rip), %rax     # 0x23718
movq 0x478(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0x40(%rsp)
jmp 0xaebd
movq 0x40(%rsp), %rdi
leaq 0x11161(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x38(%rsp)
jmp 0xaed5
movq 0x38(%rsp), %rdi
movq 0x18837(%rip), %rax     # 0x23718
movq 0x470(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0x30(%rsp)
jmp 0xaf01
movq 0x30(%rsp), %rdi
leaq 0x1111d(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x28(%rsp)
jmp 0xaf19
movq 0x28(%rsp), %rdi
movq 0x187f3(%rip), %rax     # 0x23718
movq 0x3c8(%rax), %rax
movslq 0x154(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
callq 0x9d70
movq %rax, 0x20(%rsp)
jmp 0xaf45
movq 0x20(%rsp), %rdi
leaq 0x110d9(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x18(%rsp)
jmp 0xaf5d
movq 0x18(%rsp), %rdi
movq 0x187af(%rip), %rax     # 0x23718
movl 0x520(%rax), %esi
callq 0x9c40
movq %rax, 0x10(%rsp)
jmp 0xaf7b
movq 0x10(%rsp), %rdi
leaq 0x110a3(%rip), %rsi     # 0x1c02a
callq 0x9660
movq %rax, 0x8(%rsp)
jmp 0xaf93
movq 0x8(%rsp), %rdi
movq 0x18019(%rip), %rsi     # 0x22fb8
callq 0x96b0
jmp 0xafa6
jmp 0xafa8
movl 0x154(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x154(%rsp)
jmp 0xaa40
jmp 0xafc0
movl 0x188(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x188(%rsp)
jmp 0xa804
leaq 0x190(%rsp), %rdi
callq 0x99e0
jmp 0xafe5
callq 0xbec0
jmp 0xafec
movl $0x0, 0x4b4(%rsp)
leaq 0x190(%rsp), %rdi
callq 0x9a50
leaq 0x398(%rsp), %rdi
callq 0x9390
leaq 0x400(%rsp), %rdi
callq 0xb8d0
leaq 0x438(%rsp), %rdi
callq 0xb930
leaq 0x480(%rsp), %rdi
callq 0x9390
movl 0x4b4(%rsp), %eax
addq $0x4b8, %rsp            # imm = 0x4B8
retq
leaq 0x190(%rsp), %rdi
callq 0x9a50
leaq 0x398(%rsp), %rdi
callq 0x9390
leaq 0x400(%rsp), %rdi
callq 0xb8d0
leaq 0x438(%rsp), %rdi
callq 0xb930
leaq 0x480(%rsp), %rdi
callq 0x9390
movq 0x470(%rsp), %rdi
callq 0x9c80
nopw %cs:(%rax,%rax)
nop