// File: /workspace/github_cpp_makefile_star2_O3/JRLamontagne[P]cdice_sa/CDICEInit.cpp
// Function: populateDICE(DICE*, std::vector<double, std::allocator<double>>)
void populateDICE(DICE *dice, vector<double> parms)
{
	// Parameter index variable
	int ipar = 0;

	// Preferences ---------------------------------
	dice->econ.elasmu = (parms[ipar++]);		// Elasticity of marginal utility of consumption
  dice->econ.prstp = (parms[ipar++]);		// Initial rate of social time preference (per year)
  
  // Population and Technology -------------------
  dice->econ.gama = (parms[ipar++]);		// Capital elasticity in production function
  dice->econ.pop0 = (parms[ipar++]);		// Initial world population [Millions]
  dice->econ.popadj = (parms[ipar++]);		// Growth rate to calibrate to 2050 population projection
  dice->econ.popasym = (parms[ipar++]);	// Asymptotic world population [Millions]
  dice->econ.dk = (parms[ipar++]);			// Depreciation rate on capital (per year)
  dice->econ.q0 = (parms[ipar++]);			// Initial world gross output [Trillions 2005 US $]
  dice->econ.k0 = (parms[ipar++]);			// Initial capital value [Trillions 2005 US $]
  dice->econ.a0 = (parms[ipar++]);			// Initial level of total factor productivity (TFP)
  dice->econ.ga0 = (parms[ipar++]);		// Initial growth rate for TFP (per 5 years)
  dice->econ.dela = (parms[ipar++]);		// Decline rate of TFP (per 5 years)
	dice->lims.optlrsav = (dice->econ.dk + 0.004) / (dice->econ.dk + 0.004 * dice->econ.elasmu + dice->econ.prstp) * dice->econ.gama;
	
	// Emissions parameters ------------------------
	dice->econ.gsigma1 = (parms[ipar++]);		// Initial growth of sigma (per year)
  dice->econ.dsig = (parms[ipar++]);		// Decline rate of decarbonization (per period)
  dice->econ.eland0 = (parms[ipar++]);		// Carbon emissions from land 2010 [GtCO2 per year]
  dice->econ.deland = (parms[ipar++]);		// Decline rate of land emissions (per period)
  dice->econ.e0 = (parms[ipar++]);		// Industrial emissions 2010 [GtCO2 per year]
  dice->dvars.miu0 = (parms[ipar++]);		// Initial emissions control rate for base case 2010
  //dice->econ.sig0 = dice->carb.e0 / (dice->econ.q0 * (1 - dice->econ.miu0));
						// Carbon Intensity 2010 [kgCO2 per output 2005 USD 2010]

	// Carbon cycle ---------------------------------
	// Initial conditions	
	dice->carb.mat0 = (parms[ipar++]);		// Initial concentration in atmosphere 2010 [GtC]
  dice->carb.mu0 = (parms[ipar++]);		// Initial concentration in upper strata [GtC]
  dice->carb.ml0 = (parms[ipar++]);		// Initial concentration in lower strata [GtC]
  dice->carb.mateq = (parms[ipar++]);		// Equilibrium concentration in atmosphere [GtC]
  dice->carb.mueq = (parms[ipar++]);		// Equilibrium concentration in upper strata [GtC]
  dice->carb.mleq = (parms[ipar++]);		// Equilibrium concentration in lower strata [GtC]
  
  // Flow parameters (Carbon cycle transition matricies)
  dice->carb.b12 = (parms[ipar++]);
  dice->carb.b23 = (parms[ipar++]);
  dice->carb.b11 = 1 - dice->carb.b12;
  dice->carb.b21 = dice->carb.b12 * dice->carb.mateq / dice->carb.mueq;
  dice->carb.b22 = 1 - dice->carb.b21 - dice->carb.b23;
  dice->carb.b32 = dice->carb.b23 * dice->carb.mueq / dice->carb.mleq;
  dice->carb.b33 = 1 - dice->carb.b32;

	// Climate model parameters ---------------------
	if(dice->ctrl.use_doeclim == 1) {
	  dice->clim.t2co = (parms[ipar++]);
  	apply_calibration(dice, dice->clim.t2co);
  }
  else {
  	dice->clim.t2xco2 = (parms[ipar++]);	// Equilibrium temperature impact [dC per doubling CO2]
  }
  dice->carb.fex0 = (parms[ipar++]);	// 2010 forcings of non-CO2 greenhouse gases (GHG) [Wm-2]
  dice->carb.fex1 = (parms[ipar++]);	// 2100 forcings of non-CO2 GHG [Wm-2]
	if(dice->ctrl.use_doeclim == 0) {
    dice->clim.tocean0 = (parms[ipar++]);	// Initial lower stratum temperature change [dC from 1900]
    dice->clim.tatm0 = (parms[ipar++]);	// Initial atmospheric temperature change [dC from 1900]
    dice->clim.c1 = (parms[ipar++]);	// Climate equation coefficient for upper level
    dice->clim.c3 = (parms[ipar++]);	// Transfer coefficient upper to lower stratum
    dice->clim.c4 = (parms[ipar++]);	// Transfer coefficient for lower level
  }
  dice->carb.fco22x = (parms[ipar++]);	// Forcings of equilibrium CO2 doubling [Wm-2]
  if(dice->ctrl.use_doeclim == 0) {
  	dice->clim.lam = dice->carb.fco22x / dice->clim.t2xco2;	// Climate model parameter
  }
  
  // Climate damage parameters ---------------------
  dice->econ.a10 = (parms[ipar++]);			// Initial damage intercept
  dice->econ.a20 = (parms[ipar++]);		// Initial damage quadratic term
  dice->econ.a1 = (parms[ipar++]);			// Damage intercept
  dice->econ.a2 = (parms[ipar++]);		// Damage quadratic term
  dice->econ.a3 = (parms[ipar++]);			// Damage exponent
  
  // Abatement cost --------------------------------
  dice->econ.expcost2 = (parms[ipar++]);		// Exponent of control cost function
  dice->econ.pback = (parms[ipar++]);		// Cost of backstop [2005$ per tCO2 2010]
  dice->econ.gback = (parms[ipar++]);		// Initial cost decline backstop [cost per period]
  dice->dvars.limmiu = (parms[ipar++]);		// Upper limit on control rate after 2150
  dice->econ.tnopol = (parms[ipar++]);		// Period before which no emissions controls base
  dice->econ.cprice0 = (parms[ipar++]);		// Initial base carbon price [2005$ per tCO2]
  dice->econ.gcprice = (parms[ipar++]);		// Growth rate of base carbon price (per year)
  
  // Availability of fossil fuels ------------------
  dice->carb.fosslim = (parms[ipar++]);	// Maximum cummulative extraction fossil fuels [GtC]
  dice->lims.cca_up = dice->carb.fosslim;
  
  
  // Scaling and inessential parameters ------------
	// "Note that these are unnecessary for the calculations but are for convenience"
	// Quoted directly from comments in original GAMS code
  dice->econ.scale1 = 0.0302455265681763;	// Multiplicitive scaling coefficient
  dice->econ.scale2 = -10993.704;     // Additive scaling coefficient
  
  // Objective
  dice->econ.utility = 0.0;		// Welfare function (Sum of discounted utility of per capita consumption)


	// Decision variables
 	for (int i=0; i<dice->config.nPeriods; i++) {
		if(i > 0) {
		  dice->dvars.miu[i] = parms[ipar++];
		} else {
			dice->dvars.miu[i] = dice->dvars.miu0;
		}
	}
	for (int i=0; i<dice->config.nPeriods; i++) {
		if (i < dice->config.nPeriods - 10) {
		  dice->dvars.s[i] = parms[ipar++];
		}	else {
			dice->dvars.s[i] = dice->lims.optlrsav;
		}
	}

	
	return;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
movq (%rsi), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x190(%rdi)
movsd 0x8(%rax), %xmm2
movsd %xmm2, 0x198(%rdi)
movsd 0x10(%rax), %xmm1
movsd %xmm1, 0x1a0(%rdi)
movsd 0x18(%rax), %xmm3
movsd %xmm3, 0x1a8(%rdi)
movsd 0x20(%rax), %xmm3
movsd %xmm3, 0x1b0(%rdi)
movsd 0x28(%rax), %xmm3
movsd %xmm3, 0x1b8(%rdi)
movsd 0x30(%rax), %xmm3
movsd %xmm3, 0x1c0(%rdi)
movsd 0x38(%rax), %xmm4
movsd %xmm4, 0x1c8(%rdi)
movsd 0x40(%rax), %xmm4
movsd %xmm4, 0x1d0(%rdi)
movsd 0x48(%rax), %xmm4
movsd %xmm4, 0x1d8(%rdi)
movsd 0x50(%rax), %xmm4
movsd %xmm4, 0x1e0(%rdi)
movsd 0x58(%rax), %xmm4
movsd %xmm4, 0x1e8(%rdi)
movsd 0x3e3b(%rip), %xmm4     # 0x80d8
mulsd %xmm4, %xmm0
addsd %xmm3, %xmm0
addsd %xmm4, %xmm3
addsd %xmm2, %xmm0
divsd %xmm0, %xmm3
mulsd %xmm1, %xmm3
movsd %xmm3, 0x4a8(%rdi)
movsd 0x60(%rax), %xmm0
movsd %xmm0, 0x248(%rdi)
movsd 0x68(%rax), %xmm0
movsd %xmm0, 0x250(%rdi)
movsd 0x70(%rax), %xmm0
movsd %xmm0, 0x260(%rdi)
movsd 0x78(%rax), %xmm0
movsd %xmm0, 0x268(%rdi)
movsd 0x80(%rax), %xmm0
movsd %xmm0, 0x270(%rdi)
movsd 0x88(%rax), %xmm0
movsd %xmm0, 0x40(%rdi)
movsd 0x90(%rax), %xmm0
movsd %xmm0, 0x3e0(%rdi)
movsd 0x98(%rax), %xmm0
movsd %xmm0, 0x3e8(%rdi)
movsd 0xa0(%rax), %xmm0
movsd %xmm0, 0x3f0(%rdi)
movsd 0xa8(%rax), %xmm0
movsd %xmm0, 0x3f8(%rdi)
movsd 0xb0(%rax), %xmm1
movsd %xmm1, 0x400(%rdi)
movsd 0xb8(%rax), %xmm2
movsd %xmm2, 0x408(%rdi)
movsd 0xc0(%rax), %xmm3
movsd %xmm3, 0x410(%rdi)
movsd 0xc8(%rax), %xmm4
movsd %xmm4, 0x418(%rdi)
movsd 0x3c72(%rip), %xmm5     # 0x8008
movapd %xmm5, %xmm6
subsd %xmm3, %xmm6
movsd %xmm6, 0x420(%rdi)
mulsd %xmm3, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x428(%rdi)
movapd %xmm5, %xmm3
subsd %xmm0, %xmm3
subsd %xmm4, %xmm3
movsd %xmm3, 0x430(%rdi)
mulsd %xmm4, %xmm1
divsd %xmm2, %xmm1
movsd %xmm1, 0x438(%rdi)
subsd %xmm1, %xmm5
movsd %xmm5, 0x440(%rdi)
movl 0x58(%rdi), %ecx
movsd 0xd0(%rax), %xmm0
cmpl $0x1, %ecx
jne 0x440b
movsd %xmm0, 0x98(%rbx)
movq %rbx, %rdi
callq 0x7a72
movl 0x58(%rbx), %ecx
jmp 0x4410
movsd %xmm0, 0x60(%rbx)
movq (%r14), %rax
movsd 0xd8(%rax), %xmm0
movsd %xmm0, 0x450(%rbx)
movsd 0xe0(%rax), %xmm0
movsd %xmm0, 0x458(%rbx)
movsd 0xe8(%rax), %xmm0
testl %ecx, %ecx
je 0x444b
movl $0x1d, %ecx
movl $0x1e, %edx
jmp 0x44ad
movsd %xmm0, 0x68(%rbx)
movsd 0xf0(%rax), %xmm0
movsd %xmm0, 0x70(%rbx)
movsd 0xf8(%rax), %xmm0
movsd %xmm0, 0x78(%rbx)
movsd 0x100(%rax), %xmm0
movsd %xmm0, 0x80(%rbx)
movsd 0x108(%rax), %xmm0
movsd %xmm0, 0x88(%rbx)
movsd 0x110(%rax), %xmm0
movapd %xmm0, %xmm1
divsd 0x60(%rbx), %xmm1
movsd %xmm1, 0x90(%rbx)
movl $0x22, %ecx
movl $0x23, %edx
movsd %xmm0, 0x448(%rbx)
movsd (%rax,%rdx,8), %xmm0
movsd %xmm0, 0x1f0(%rbx)
movl %ecx, %edx
movsd 0x10(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x1f8(%rbx)
movsd 0x18(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x200(%rbx)
movsd 0x20(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x208(%rbx)
movsd 0x28(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x210(%rbx)
movsd 0x30(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x218(%rbx)
movsd 0x38(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x220(%rbx)
movsd 0x40(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x228(%rbx)
movsd 0x48(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x38(%rbx)
movsd 0x50(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x230(%rbx)
movsd 0x58(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x238(%rbx)
movsd 0x60(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x240(%rbx)
movsd 0x68(%rax,%rdx,8), %xmm0
movsd %xmm0, 0x460(%rbx)
movsd %xmm0, 0x518(%rbx)
movaps 0x3b48(%rip), %xmm0     # 0x80c0
movups %xmm0, 0x278(%rbx)
movq $0x0, 0x380(%rbx)
movslq (%rbx), %rdx
testq %rdx, %rdx
jle 0x460a
leaq 0x4a8(%rbx), %rsi
addl $0xe, %ecx
xorl %edi, %edi
testq %rdi, %rdi
je 0x45ba
movslq %ecx, %r8
incl %ecx
movsd (%rax,%r8,8), %xmm0
movq 0x48(%rbx), %r8
movsd %xmm0, (%r8,%rdi,8)
jmp 0x45c8
movsd 0x40(%rbx), %xmm0
movq 0x48(%rbx), %r8
movsd %xmm0, (%r8)
incq %rdi
cmpq %rdi, %rdx
jne 0x459e
testl %edx, %edx
jle 0x460a
leaq -0xa(%rdx), %rdi
movq 0x50(%rbx), %r8
xorl %r9d, %r9d
xorl %r10d, %r10d
cmpq %rdi, %r9
setl %r10b
movslq %ecx, %rcx
leaq (%rax,%rcx,8), %r11
cmovgeq %rsi, %r11
addl %r10d, %ecx
movsd (%r11), %xmm0
movsd %xmm0, (%r8,%r9,8)
incq %r9
cmpq %r9, %rdx
jne 0x45df
addq $0x8, %rsp
popq %rbx
popq %r14
retq