

// Refer to  "Roberts_BDFM_dissertation_2005-(Modified).pdf".
//
// We are modeling a single stator induction motor here. We will lump the mutual inductances of the stator and rotor into simple representations of windings
// without regard to physical layout.
//
// The machine will be reduced to:
//
//     p1 = 1, p2 = 0   (This is a 2 pole machine traditional induction motor)
//     S = 2  (With a single set of windings, the meaning of S has changed. However in Robert's, S = p1 + p2 = 2 + 4 = 6. Six circuits defined the requirement
//             that for a 4/8 pole BDFM, there must always be a point in rotation that any two of the six rotor bars line up with the "pitch" of a 4 pole or
//             8 pole stator. With this in mind, we define S = 2.
//
//     This reduces the mutual inductance matrix to the following (from Eq 2.30 and Eq. 2.56)
//
//
//      | Ms     Msr |
//      | Msr_T  Mr  |
//
//      where Ms is a 3 x 3 matrix, Ms is a 2 x 2 matrix, Msr is a 3 x 2 matrix and Msr_T is a 2 x 3 matrix.
//
//
//      We will use the top left block of Equation B.9 on age 256 for Ms.
//
//				| 210.0e-3    -96.3e-3   -96.3e-3 |
//              | -96.3e-3    210.0e-3   -96.3e-3 |
//              | -96.3e-3    -96.3e-3   210.0e-3 |
//
//      Msr of Equation 2.53 on page 63 reduces to this (for S = 2).
//
//
//              | Sum{M*cos(theta_r 		- B)        Sum{M*cos(theta_r 		  - PI -  B) |
//				| Sum{M*cos(theta_r - 2PI/3 - B)        Sum{M*cos(theta_r - 2PI/3 - PI -  B) |
//				| Sum{M*cos(theta_r - 4PI/3 - B)        Sum{M*cos(theta_r - 4PI/3 - PI -  B) |
//
//
//      For S = 2, Mr will be interperted from the "Rotor 5: 6 bar cage rotor design", Section B.7, Equation B.29
//
//
//      		|  271.0e-7  -271.0e-7 |
//              | -271.0e-7   271.0e-7 |
//
//

	//Define for "physical" reference plane, comment out for synchronous reference plane.
#define TERMINAL_REF_PLANE_SIMULATION

#ifdef TERMINAL_REF_PLANE_SIMULATION

typedef enum {
  SRC_FUNC_NULL = -1,
  SRC_FUNC_TriangleWave,
  SRC_FUNC_PwmA,
  SRC_FUNC_PwmB,
  SRC_FUNC_PwmC,

} SRC_FUNCTION;

	// ODE Functions based on Equations 2.56 and 2.59 on page 65 of "Roberts_BDFM_dissertation_2005-(Modified).pdf"
typedef enum {
  ODE_FUNC_NULL = -1,
  ODE_FUNC_Is3_Ir6_1,
  ODE_FUNC_Is3_Ir6_2,
  ODE_FUNC_Is3_Ir6_3,
  ODE_FUNC_Is3_Ir6_4,
  ODE_FUNC_Is3_Ir6_5,
  ODE_FUNC_Is3_Ir6_6,
  ODE_FUNC_Omega,
  ODE_FUNC_Theta
  
} ODE_FUNCTION;

#else

typedef enum {
  SRC_FUNC_NULL = -1,
  SRC_FUNC_src_dummy,			//There is a problem with the initialization. Simulator expects at least one SrcObject. Create a dummy for now.

} SRC_FUNCTION;

typedef enum {
  ODE_FUNC_NULL = -1,
  ODE_FUNC_Is_Ir_sdq_1,
  ODE_FUNC_Is_Ir_sdq_2,
  ODE_FUNC_Is_Ir_sdq_3,
  ODE_FUNC_Is_Ir_sdq_4,
  ODE_FUNC_Ir_sdq_z,
  ODE_FUNC_Omega,
  ODE_FUNC_Theta

} ODE_FUNCTION;

#endif


//(NOTE: As of 6/12/08, "pTranslationList" and "pTrajectoryList" CTRL's have been 
//       deprecated and replaced with a "group" structure. However, we still maintain
//       only one "CTRL_FUNCTION" enumeration for all groups)
typedef enum {
  CTRL_FUNC_NULL = -1,
  CTRL_FUNC_RefGen,
  CTRL_FUNC_VDqCmd,


} CTRL_FUNCTION;


#ifdef TERMINAL_REF_PLANE_SIMULATION

typedef enum {
  COEF_FUNC_NULL = -1,
  COEF_FUNC_ir_Msr_0_0_theta_r,
  COEF_FUNC_ir_Msr_0_1_theta_r,
  COEF_FUNC_ir_Msr_0_2_theta_r,
  COEF_FUNC_ir_Msr_1_0_theta_r,
  COEF_FUNC_ir_Msr_1_1_theta_r,
  COEF_FUNC_ir_Msr_1_2_theta_r,
  COEF_FUNC_ir_Msr_2_0_theta_r,
  COEF_FUNC_ir_Msr_2_1_theta_r,
  COEF_FUNC_ir_Msr_2_2_theta_r,
  COEF_FUNC_is_Msr_0_0_theta_r,
  COEF_FUNC_is_Msr_1_0_theta_r,
  COEF_FUNC_is_Msr_2_0_theta_r,
  COEF_FUNC_is_Msr_0_1_theta_r,
  COEF_FUNC_is_Msr_1_1_theta_r,
  COEF_FUNC_is_Msr_2_1_theta_r,
  COEF_FUNC_is_Msr_0_2_theta_r,
  COEF_FUNC_is_Msr_1_2_theta_r,
  COEF_FUNC_is_Msr_2_2_theta_r,
} COEF_FUNCTION;

#else
typedef enum {
  COEF_FUNC_NULL = -1,
} COEF_FUNCTION;

#endif


typedef enum {
  SWITCH_FUNC_NULL = -1,

} SWITCH_FUNCTION;

typedef enum {
  SPICE_FUNC_NULL = -1,

} SPICE_FUNCTION;



#include "../Simulation/Simulation.hpp"





     // un-comment to plot all probes and object outputs.
//#define RECORD_ALL_PROBES


//Parameters....

// Inductance matrix's calculated from test "Section_2_7_2", "Section_B_2", and "Section_B_7"
#define Msr 		 0  //(This flag replaces lookup in file "../BDFM-Dissertation-2005-Tests/Section_2_7_2/Stator_Rotor_Mutual_Inductance.h")
#define d_Msr 	 1 //(This flag replaces lookup in file "../BDFM-Dissertation-2005-Tests/Section_2_7_2/Stator_Rotor_Derivative_Mutual_Inductance.h")

#define INTERPOLATE_USING_TABLE
#ifdef INTERPOLATE_USING_TABLE
#include "../BDFM-Dissertation-2005-Tests/Section_2_7_2/Stator_Rotor_Mutual_Inductance_ideal.h"
#include "../BDFM-Dissertation-2005-Tests/Section_2_7_2/Stator_Rotor_Derivative_Mutual_Inductance_ideal.h"
#else
#define M1_inductance_value 0.00157253   //(Derived from file "../BDFM-Dissertation-2005-Tests/Section_2_7_2/Stator_Rotor_Mutual_Inductance_Value_M1.h")
#endif

//Derived from  "../BDFM-Dissertation-2005-Tests/Section_B_2/Stator_Stator_Mutual_Inductance.h" but adjusted so as to provide a perfectly balanced stator winding.
double Mss[3][3] = {
								{0.278875		,-0.1394375	,-0.1394375},
								{-0.1394375	,0.278875		,-0.1394375},
								{-0.1394375	,-0.1394375	,0.278875},
							  };


//Derived from "../BDFM-Dissertation-2005-Tests/Section_B_7/Rotor_Rotor_Mutual_Inductance.h" but adjusted so as to provide a perfectly balanced rotor winding.
double Mrr[3][3] = {
								{2.71067e-05		,-9.035567e-6		,-9.035567e-6	},
								{-9.035567e-6		,2.71067e-05		,-9.035567e-6	},
								{-9.035567e-6		,-9.035567e-6		,2.71067e-05}
							};

	//This is the offset between Phase 1 of the stator and Phase 1 of the rotor as per Eq 2.53, page 63 of "Roberts...".
    //It validity is verified by locking the rotor (make Jm = 100), running the simulation and noting that "I_s1" should be
    //in phase with "I_r1" and both lagging by 90 degrees with respect to "V_s1"( assume low stator and rotor resistance).
	//We can produce the same result by"flipping" the sign of all elements in "Mrr" above (verified). The real reason for this 180
	//degree shift is that if one visualizes the machine, the sign of the values for Mss should be 180 shifted with respect to the values for Mrr..
#define Beta_1	  PI

// D/Q Inductance matrix's calculated from test "Verify_Eq_3_17", "Verify_Eq_3_19", "Verify_Eq_3_24", "Verify_Eq_3_26" and "Verify_Eq_3_28"
// See also, the auto-generated files produced by the programs created for each of these tests.
//			"../BDFM-Dissertation-2005-Tests/Verify_Eq_3_17/d_dq_Stator_Stator_Mutual_Inductance_ideal.h"

double Qdq0s[3][3] = {
									{0					,0.418313			,0},
									{-0.418313		,0						,0},
									{0					,0						,0},
								 };

//			"../BDFM-Dissertation-2005-Tests/Verify_Eq_3_19/dq_Stator_Stator_Mutual_Inductance_ideal.h"

double Mdq0s[3][3] = {
									{0.418313		,0						,0},
									{0					,0.418313			,0},
									{0					,0						,0},
								 };

//			"../BDFM-Dissertation-2005-Tests/Verify_Eq_3_24/dq_Rotor_Rotor_Mutual_Inductance_ideal.h"

double Mdqr[3][3] = {
									{3.61423e-05			,0						,0				   },
									{0							,3.61423e-05		,0				   },
									{0							,0						,9.03557e-06},
							   };


//			"../BDFM-Dissertation-2005-Tests/Verify_Eq_3_26/dq_Stator_Rotor_Mutual_Inductance_ideal.h"
//			  (NOTE: "Mdqsr_t" same as "Mdqsr". See  "../BDFM-Dissertation-2005-Tests/Verify_Eq_3_26_transpose/dq_Stator_Rotor_Mutual_Inductance_ideal_transpose.h"  )
double Mdqsr[3][3] = {
									{0.002204475			,0						,0	},
									{0							,0.002204475		,0	},
									{0							,0						,0	},
								 };

double Mdqsr_t[3][3] = {
										{0.002204475			,0						,0	},
										{0							,0.002204475		,0	},
										{0							,0						,0	},
								    };



//			"../BDFM-Dissertation-2005-Tests/Verify_Eq_3_28/d_dq_Stator_Rotor_Mutual_Inductance_ideal.h"

double Qdqsr[3][3] = {
									{0							,0.002204475		,0	},
									{-0.002204475		,0						,0	},
									{0							,0						,0	},
								};


// 			"../BDFM-Dissertation-2005-Tests/Verify_Rr_dq_on_page_80/Verify_Rr_dq_on_page_80_ideal.h"

double Rdqr[3][3] =  {
									{0.000125				,0						,0			},
									{0							,0.000125			,0			},
									{0							,0						,5e-05	},
								};

// 			"../BDFM-Dissertation-2005-Tests/Verify_Rs_dq_on_page_80/Verify_Rr_dq_on_page_80_ideal.h"


double Rdq0s[3][3] = {
									{2.72855				,0						,0				},
									{0							,2.72855			,0				},
									{0							,0						,2.72855	},
								};


// Synchronous D/Q reference frame (see Eq. 3.35 and Eq. 7.3, Eq. 7.7, Eq. 7.8, Eq. 7.9 and Eq. 7.10)

// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_7_for_Rsyncr_and_Rsync0s"

double Rsync0s[3][3] = {
										{2.72855			,0						,0				},
										{0						,2.72855			,0				},
										{0						,0						,2.72855	},
								    };

double Rsyncr[3][3] = {
										{0.000125			,0						,0				},
										{0						,0.000125			,0				},
										{0						,0						,5e-05		},
								   };

// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_8_for_Qsync0s"

double Qsync0s[3][3] = {
										{0						,0.418313			,0				},
										{-0.418313			,0						,0				},
										{0						,0						,0				},
									 };


// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_8_for_Qsyncsr"

double Qsyncsr[3][3] = {
										{0						,0.00220448		,0				},
										{-0.00220448		,0						,0				},
										{0						,0						,0				},
									};

// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_8_for_Qsyncd0s"

double Qsyncd0s[3][3] = {
										{0						,-0.418313			,0				},
										{0.418313			,0						,0				},
										{0						,0						,0				},
									  };

// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_8_for_Qsyncdsr"
//			(Note: "Qsyncdsr_t" is the same as 'Qsyncdsr" (see directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_8_for_Qsyncdsr_transpose")
//          (Remember, the transpose for "Qsyncdsr_t" is taken BEFORE operation by Tsync and dTsync-1.  "Qsyncdsr_t"  as defined here is NOT
//           the "transpose_of(Qsyncdsr)" before. See Eq. 3.15 on page 75 for clarification).
//			There is one more important observation here. The form of the transformation done in Eq. 3.6 of page 76 is different then that done in Eq. 7.5 page 179.
//          If we assume "phi" is zero for the Eq. 7.4, then all the elements on the diagonal are the same. If we ultimately want to use "phi" in the control, then
//			Is the statement  "Qsyncdsr_t" the same as 'Qsyncdsr" true. It still maybe true. We have to work it out in long-hand.  Again this is observable by viewing Eq. 3.6 of page 76.

double Qsyncdsr[3][3] = {
										{0						,-0.00220448		,0				},
										{0.00220448		,0						,0				},
										{0						,0						,0				},
									};

double Qsyncdsr_t[3][3] = {
											{0						,-0.00220448		,0				},
											{0.00220448		,0						,0				},
											{0						,0						,0				},
										};

// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_8_for_Qsyncdr"

double Qsyncdr[3][3] = {
										{0						,-3.61423e-05		,0				},
										{3.61423e-05		,0						,0				},
										{0						,0						,0				},
									};


// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_9_for_Msync0s"

double Msync0s[3][3] = {
										{0.418313			,0						,0				},
										{0						,0.418313			,0				},
										{0						,0						,0				},
									 };

// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_9_for_Msyncsr"
//			(Note: "Msyncsr_t" is the same as 'Msyncsr" (see directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_9_for_Msyncsr_transpose")

double Msyncsr[3][3] = {
										{0.00220448		,0						,0				},
										{0						,0.00220448		,0				},
										{0						,0						,0				},
									};

double Msyncsr_t[3][3] = {
											{0.00220448		,0						,0				},
											{0						,0.00220448		,0				},
											{0						,0						,0				},
									   };



// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_9_for_Msyncr"

double Msyncr[3][3] = {
										{3.61423e-05		,0						,0					},
										{0						,3.61423e-05		,0					},
										{0						,0						,9.03557e-06	},
								   };
// 			See directory "..\BDFM-Dissertation-2005-Tests\Verify_Eq_7_10_for_Ssyncsr
//          (Note: Unlike Qsyncdsr above, the transpose here flips the signs.)

double Ssyncsr[3][3] = {
										{0						,0.00220448		,0					},
										{-0.00220448		,0						,0					},
										{0						,0						,0					},
									};

double Ssyncsr_t[3][3] = {
											{0						,-0.00220448		,0					},
											{0.00220448		,0						,0					},
											{0						,0						,0					},
									  };


#define PI 3.1415926535897932384626433832795






// Form "Roberts..."  Section 2.5.3, Equation 2.31 and Equation 2.32, page 49.
//
//    R = rho * l / A    (length in meters, area in square meters)
//
//    l_stator = 2.0 * _winding_factor_ * N *((_coil_pitch_ * d / 2.0) + w)             //(used to calculate the stator winding resistance. All distances in meters)
//

//
//
//
// From "Section_2_7_2" experiment....
//
//
//	w = .1955 m
//  d = .175065 m
//  N = 10 * 16    //(For stator calculation, actually from Table B.1 page and Table B.3 page 252 of "Roberts..." for 4 pole winding (2 pole pairs))
//
//  A = 1.13 mm**2    //(For stator calculation, also from Table B.3 page 252 of "Roberts..." )
// 							  From Table B.3, the wire diameter is 1.12 mm (Verify "A",      PI * (.0012/2.0)**2 = 1.13e-6.
//							  ** There is a mistake in the table for the wire diameter. **
//
//  _coil_pitch_  =  2.0 * PI * ( d / 2.0) * 10.0 / 48.0  //See "Ack" in "Section_2_7_2.c" for stator coil pitch)
//
// Stator 1 is comprised of 4 poles (2 pole pairs). This suggests that we must multiply the total turns by 2.0.
//
// From Table B.3 page 252, the winding factor is determined to be .9248
//
// Finally,      rho (copper) = 1.68e-8


// The value of Rs_matrix_elem is also verified by Table 5.1, page 152 of "Roberts..." to be 2.7 Ohms
#define Rs_matrix_elem  ((1.68e-8/1.13e-6) *  2.0 * .9248 * (10 * 16 * 2) * ((2.0 * PI * ( .175065 / 2.0) * 10.0 / 48.0)  + 0.1955))    //(Evaluates to 2.72855


double Rs_res[3][3] = {
							{Rs_matrix_elem,   0,				0				},
							{0,				   Rs_matrix_elem,	0				},
							{0,				   0,				Rs_matrix_elem	}
					  };




//
//
//
//  A = 205.84 mm**2   //(Rotor bar conductor area, see Table B.4, Section B.10 on page 274 of "Roberts...")
//
//
//
//  Interpertation for bar resistance from Section B.7.1, Figure B.8 page 267
//
//	  l_rotor_bar = d (approximate)
//    l_rotor_end = 2.0 * PI * (d / 2.0) / 6.0 (approximate)
//
//
//






//
//
//  From Section B.7.1, Figure B.8 page 267 calculate the  the elements of the resistor matrix for "6 bar cage rotor design"
//#define Rr_matrix_loop  ((1.68e-8 / (205.84 / 1.0e6)) * (2.0 * 0.1955 + 2.0 * (2.0 * PI * (0.175065 / 2.0) / 6.0)) )
//#define Rr_matrix_bar   (- 1.68e-8 * 0.1955 *(205.84 / 1.0e6))
#define Rr_matrix_loop  (.0001)
#define Rr_matrix_bar  (-.000025)


double Rr_res[3][3] = {
							{Rr_matrix_loop,    Rr_matrix_bar,    	Rr_matrix_bar },
							{Rr_matrix_bar,     	Rr_matrix_loop,   	Rr_matrix_bar },
							{Rr_matrix_bar,      Rr_matrix_bar,   	Rr_matrix_loop }
					  };








// Mechanical Parameters:
//
// 1 Newton = 1 kg * m / sec**2  (eg. F = mass * acceleration)
// T (torque) in units of Newton * meters (N*m)
// J (moment of interia) in units of kg * meter**2  (kg*m**2)
//
// Therefore:
// T / J = (m * kg * m / sec**2) / kg * m**2 = rad / sec**2


//#define Ti  50.0  //N*m, can be as high as 143 N*m, see Table B.2, Section B.1, page 250.
//**** For now, set to "0" ****
#define Ti (.5*omega_r)     //Use .01 as a minimum.
#define Bm  .5

#define Jm  .11   //kg * m**2 (Also from Table B.2, Section B.1, page 250.)
//#define Jm  10.0           //.00011

#define Nr 4   //(IMPORTANT: This  is used only in object VDqCmd. I beleive it should equate to "p1" pole pairs which is "4" for this example.)



// These modulus based on "QUARTER_PWM_CYCLE" time below
#define REF_GEN_QUANTUM_CNT       8
#define VDQ_CMD_QUANTUM_CNT       4
#define PWM_CYCLE_QUANTUM_CNT     4

#define QUANTUM_PERIOD .0000125   




#define QUARTER_PWM_CYCLE QUANTUM_PERIOD
 

#define SECTOR_ANGLE   (PI / 3.0)
#define T_Z            (QUARTER_PWM_CYCLE * (double) PWM_CYCLE_QUANTUM_CNT)
#define SQRT_3          1.7320508075688772935274463415059
   




#define  RT_TRAJ     4
#define  CT_TRAJ     2
#define  VO_TRAJ   100.0


//uncomment if triangle wave modulation or linear mode is to be used.
#define TRIANGLE_REF_MODE
#ifdef TRIANGLE_REF_MODE
//uncoment if linear mode....
#define LINEAR_AMP_MODE
//uncoment if frequency sweep mode..
#define FREQUENCY_SWEEP_MODE

#define PWM_GAIN    5.0
#define PWM_OFFSET  2.5

#else
// "Space Vector" mode....
#define PWM_GAIN    T_Z
#define PWM_OFFSET  (.5*T_Z)

#endif





	//Unlike the original "App_Observer.hpp" simulation, we are going to
    //keep all the state variables defined in Equation 2.59, page 66 of "Roberts..."
    //global to make debugging easier.
double is[3] = {0};
double ir[3] = {0};
double vs[3] = {0};
double v_n;
double theta_r = 0;
double omega_r = 0;

double pwm_sig[3] = {0};

double TriAngWave = 0;
double V_xo[3] = {0};

//The following variables are copies of the derivative of the intrinsic  "dydt" variable which is
//part of each OdeObject declaration and instance below.
double d_is[3] = {0};
double d_ir[3] = {0};
double d_theta_r = 0;
double d_omega_r = 0;

//This are used in "RefGen".
double betad;
double alphad;
double omegad;
double thetad;
double zetad;
double vdd;
double vqd;

//VdqCmd scales "thetad" and "omegad" when when generating the vs[0], vs[1], and vs[2].
//These are the scaled values applied to the synchronous D/Q equations.
double theta_s;
double omega_s;



// Indices for the Group ODE Vector to solve.

#ifdef TERMINAL_REF_PLANE_SIMULATION

#define Ind_d_is_0	0
#define Ind_d_is_1  	1
#define Ind_d_is_2 	2
#define Ind_v_n			3
#define Ind_d_ir_0		4
#define Ind_d_ir_1		5
#define Ind_d_ir_2		6

#else

#define Ind_d_is_sdq_d		 0
#define Ind_d_is_sdq_q		 1
#define Ind_d_ir_sdq_d		 2
#define Ind_d_ir_sdq_q      3

#endif




#define DC_BUS_VOLTAGE 600.0

#define SRC_SLEW_RATE  200000000.0   //volts/sec   (At 200 VDC bus, this is 1 uSec rise and fall time typical for a 30 amp IPM)



//Misc. definitions...

typedef enum {TIME_NONE,
	      TIME_T1,
	      TIME_T2,
	      TIME_T1_T2
} REFERENCE_CONSTRUCT;










// "Mss"      								  is defined in Stator_Stator_Mutual_Inductance.h
// "Msr"										  is defined in Stator_Rotor_Mutual_Inductance.h
// "d_Msr"   						 		  is defined in Stator_Rotor_Derivative_Mutual_Inductance.h
// "Mrr"										  is defined in Rotor_Rotor_Mutual_Inductance.h



// From Equation 2.56,  Equation 2.57 and Equation 2.58 page 65  and Equation 2.59 page 66  of "Roberts..."
//
//
//
//
//										| d_is[0] |           | vs[0] |      																				     | is[0] |
//		| Mss 		Msr 	|		| d_is[1] |           | vs[1] |		 	 {  | Rs       0  |                           |      0        d_Msr  | }   | is[1] |
//		| Msr_t      Mrr   |	   	| d_is[2] |    =     | vs[2] |  	-    {  |  0       Rr  |    -     omega_r  * | d_Msr_t       0     | }   | is[2] |									   					 Eq. (0)
//										| d_ir[0]  |           |   0    | 																							 | ir[0]  |
//										| d_ir[1]  |           |   0    |																						     | ir[1]  |
//			   				 			| d_ir[2]  |           |   0    |																						     | ir[2]  |
//
//
//																												    | is[0] |
//			    Te  = .5 *  | is[0]  is[1]  is[2]  ir[0]  ir[1]  ir[2]  |  |      0           d_Msr  |  | is[1] |
//																				   |  d_Msr_t         0     |  | is[2] |
//                                                                                                                  | ir[0]  |
//																													| ir[1]  |
//																													| ir[2]  |
//
//
//																					|				0							 																				ir[0] * d_Msr[theta][0][0] + ir[1] * d_Msr[theta][0][1]  +   ir[2] * d_Msr[theta][0][2]   |
//					= .5 *  | is[0]  is[1]  is[2]   ir[0]  ir[1]   ir[2] |	| 				0			                 																				ir[0] * d_Msr[theta][1][0] + ir[1] * d_Msr[theta][1][1]  +   ir[2] * d_Msr[theta][1][2]   |
//																					|				0				             																				ir[0] * d_Msr[theta][2][0] + ir[1] * d_Msr[theta][2][1]  +   ir[2] * d_Msr[theta][2][2]   |
//																					|  is[0] * d_Msr[theta][0][0] + is[1] * d_Msr[theta][1][0]  +   is[2] * d_Msr[theta][2][0]										0				  																      |
//																					|  is[0] * d_Msr[theta][0][1] + is[1] * d_Msr[theta][1][1]  +   is[2] * d_Msr[theta][2][1]		                   				0               																      |
//																					|  is[0] * d_Msr[theta][0][2] + is[1] * d_Msr[theta][1][2]  +   is[2] * d_Msr[theta][2][2]	                      				0            																	      |
//
//
//					= .5 * is[0] * (ir[0] * d_Msr[theta][0][0] + ir[1] * d_Msr[theta][0][1]  +   ir[2] * d_Msr[theta][0][2]) +
//                     .5 * is[1] * (ir[0] * d_Msr[theta][1][0] + ir[1] * d_Msr[theta][1][1]  +   ir[2] * d_Msr[theta][1][2]) +
//					   .5 * is[2] * (ir[0] * d_Msr[theta][2][0] + ir[1] * d_Msr[theta][2][1]  +   ir[2] * d_Msr[theta][2][2]) +
//					   .5 * ir[0] * (is[0] * d_Msr[theta][0][0] + is[1] * d_Msr[theta][1][0]  +   is[2] * d_Msr[theta][2][0]	) +
//					   .5 * ir[1] * (is[0] * d_Msr[theta][0][1] + is[1] * d_Msr[theta][1][1]  +   is[2] * d_Msr[theta][2][1]	) +
//					   .5 * ir[2] * (is[0] * d_Msr[theta][0][2] + is[1] * d_Msr[theta][1][2]  +   is[2] * d_Msr[theta][2][2])
//
//
//
//
//
//
//
//
//        d_is[0]*Mss[0][0] +
//	      d_is[1]*Mss[0][1] +
//	      d_is[2]*Mss[0][2] +  d_ir[0]*Msr[theta_r][0][0] +
//										d_ir[1]*Msr[theta_r][0][1] +
//										d_ir[2]*Msr[theta_r][0][2]
//																			   = vs[0] - v_n -  is[0]*Rs_res[0][0] - omega_r*(ir[0]*d_Msr[theta_r][0][0] +
//																																	    	    ir[1]*d_Msr[theta_r][0][1] +
//																																	            ir[2]*d_Msr[theta_r][0][2])       												Eq. (1)
//
//
//        d_is[0]*Mss[1][0] +
//	      d_is[1]*Mss[1][1] +
//	      d_is[2]*Mss[1][2] + d_ir[0]*Msr[theta_r][1][0] +
//									   d_ir[1]*Msr[theta_r][1][1] +
//									   d_ir[2]*Msr[theta_r][1][2]
//																				= vs[1] - v_n - is[1]*Rs_res[1][1] - omega_r*(ir[0]*d_Msr[theta_r][1][0] +
//																																		 		ir[1]*d_Msr[theta_r][1][1] +
//																																		 		ir[2]*d_Msr[theta_r][1][2])       										 		Eq. (2)
//
//        d_is[0]*Mss[2][0] +
//	      d_is[1]*Mss[2][1] +
//	      d_is[2]*Mss[2][2] + d_ir[0]*Msr[theta_r][2][0] +
//									   d_ir[1]*Msr[theta_r][2][1] +
//									   d_ir[2]*Msr[theta_r][2][2]
//																			   = vs[2] - v_n -  is[2]*Rs_res[2][2] - omega_r*(ir[0]*d_Msr[theta_r][2][0] +
//																																	    	   ir[1]*d_Msr[theta_r][2][1] +
//																																		       ir[2]*d_Msr[theta_r][2][2])														Eq. (3)
//
//
//
//
//		d_is[0] + d_is[1] + d_is[2] 	= 0																																													Eq. (4)
//
//

//
//
//     d_is[0]*Msr[theta_r][0][0]  +
//     d_is[1]*Msr[theta_r][1][0]  +
//     d_is[2]*Msr[theta_r][2][0]  + d_ir[0]*Mrr[0][0] +
//												d_ir[1]*Mrr[0][1] +
//												d_ir[2]*Mrr[0][2]
//																				=  0 - ir[0]*Rr_res[0][0] - ir[1]*Rr_res[0][1] -  ir[2]*Rr_res[0][2] - omega_r*(is[0]*d_Msr[theta_r][0][0] +
//																																														 is[1]*d_Msr[theta_r][1][0] +
//																																														 is[2]*d_Msr[theta_r][2][0])			Eq. (5)
//
//     d_is[0]*Msr[theta_r][0][1]  +
//     d_is[1]*Msr[theta_r][1][1]  +
//     d_is[2]*Msr[theta_r][2][1]  + d_ir[0]*Mrr[1][0] +
//												d_ir[1]*Mrr[1][1] +
//												d_ir[2]*Mrr[1][2]
//																				=  0 - ir[0]*Rr_res[1][0] - ir[1]*Rr_res[1][1] -  ir[2]*Rr_res[1][2] - omega_r*(is[0]*d_Msr[theta_r][0][1] +
//																																														 is[1]*d_Msr[theta_r][1][1] +
//																																														 is[2]*d_Msr[theta_r][2][1])			Eq. (6)
//
//     d_is[0]*Msr[theta_r][0][2]  +
//     d_is[1]*Msr[theta_r][1][2]  +
//     d_is[2]*Msr[theta_r][2][2]  + d_ir[0]*Mrr[2][0] +
//												d_ir[1]*Mrr[2][1] +
//												d_ir[2]*Mrr[2][2]
//																				=  0 - ir[0]*Rr_res[2][0] - ir[1]*Rr_res[2][1] -  ir[2]*Rr_res[2][2] - omega_r*(is[0]*d_Msr[theta_r][0][2] +
//																																														 is[1]*d_Msr[theta_r][1][2] +
//																																														 is[2]*d_Msr[theta_r][2][2])			Eq. (7)
//
//
//
//	   d_theta_r	 = omega_r																																																Eq. (8)
//
//
//
//
//
//	   d_omega_r  =  (is[0]*(ir[0]*d_Msr[theta_r][0][0] +
//							  		   ir[1]*d_Msr[theta_r][0][1] +
//							   		   ir[2]*d_Msr[theta_r][0][2] )   + is[1]*(ir[0]*d_Msr[theta_r][1][0] +
//							   											                   ir[1]*d_Msr[theta_r][1][1] +
//							                                                               ir[2]*d_Msr[theta_r][1][2] )   + is[2]*(ir[0]*d_Msr[theta_r][2][0] +
//							   											                                                                       ir[1]*d_Msr[theta_r][2][1] +
//							                                                                                                                   ir[2]*d_Msr[theta_r][2][2]  )  - Ti)  / Jm									Eq. (9)
//
//
//


//See "https://en.wikipedia.org/wiki/Direct%E2%80%93quadrature%E2%80%93zero_transformation"
//  	(Keywords: Wikipedia "Direct-quadrature-zero transformation"
//
// This shows the "dq" and inv_dq in what is called the power-invariant from. The "dq" defined here
// matches the form presented in "Roberts..." Eq. 3.1  on page 72 (with some minor translation in terms).
// Note that the form used by Bodson/Chaisson was not in the power-invariant form but was in the "Clarke" form
// as discussed at the bottom of this document.
//
// There is one exception to "Roberts..." regarding Eq. 3.1. This document and Bodson/Chaisson have "-" signs
// in front of the "sin()" functions. Normally this may mean that the Iq current would be negative for motoring
// and positive for regeneration. However, this is an induction motor so in this frame, we see the slip frequency
// on both Id and Iq (an AC signal). This might be the reason why "Roberts..." neglects the meaning of the sign.

#define is_dq_d_derived 		(sqrt(2.0/3.0) * (is[0]*cos(theta_r) + is[1]*cos(theta_r - 2.0*PI/3.0) + is[2]*cos(theta_r - 4.0*PI/3.0)))
#define is_dq_q_derived 		(sqrt(2.0/3.0) * (is[0]*sin(theta_r) + is[1]*sin(theta_r - 2.0*PI/3.0) + is[2]*sin(theta_r - 4.0*PI/3.0)))
#define is_dq_z_derived			(sqrt(2.0/3.0) * (is[0]/sqrt(2.0) + is[1]/sqrt(2.0) + is[2]/sqrt(2.0)))

#define is1_inv_derived 			(sqrt(2.0/3.0) * (is_dq_d*cos(theta_r) 					 + is_dq_q*sin(theta_r) 				    + is_dq_z/sqrt(2.0)))
#define is2_inv_derived 			(sqrt(2.0/3.0) * (is_dq_d*cos(theta_r - 2.0*PI/3.0)   + is_dq_q*sin(theta_r - 2.0*PI/3.0)  + is_dq_z/sqrt(2.0)))
#define is3_inv_derived			(sqrt(2.0/3.0) * (is_dq_d*cos(theta_r - 4.0*PI/3.0)   + is_dq_q*sin(theta_r - 4.0*PI/3.0)  + is_dq_z/sqrt(2.0)))

#define ir_dq_d_derived 		(sqrt(2.0/3.0) * (ir[0]*cos(0) + ir[1]*cos(0 + 2.0*PI/3.0) + ir[2]*cos(0 + 4.0*PI/3.0)))
#define ir_dq_q_derived 		(sqrt(2.0/3.0) * (ir[0]*sin(0) + ir[1]*sin(0 + 2.0*PI/3.0) + ir[2]*sin(0 + 4.0*PI/3.0)))
#define ir_dq_z_derived			(sqrt(2.0/3.0) * (ir[0]/sqrt(2.0) + ir[1]/sqrt(2.0) + ir[2]/sqrt(2.0)))

#define vs_dq_d_derived 		(sqrt(2.0/3.0) * (vs[0]*cos(theta_r) + vs[1]*cos(theta_r - 2.0*PI/3.0) + vs[2]*cos(theta_r - 4.0*PI/3.0)))
#define vs_dq_q_derived 		(sqrt(2.0/3.0) * (vs[0]*sin(theta_r) + vs[1]*sin(theta_r - 2.0*PI/3.0) + vs[2]*sin(theta_r - 4.0*PI/3.0)))
#define vs_dq_z_derived		(sqrt(2.0/3.0) * (vs[0]/sqrt(2.0) + vs[1]/sqrt(2.0) + vs[2]/sqrt(2.0)))

double is_dq_d = 0;
double is_dq_q = 0;
double is_dq_z = 0;

double ir_dq_d = 0;
double ir_dq_q = 0;
double ir_dq_z = 0;

double vs_dq_d = 0;
double vs_dq_q = 0;
double vs_dq_z = 0;

double d_is_dq_d = 0;
double d_is_dq_q = 0;
double d_is_dq_z = 0;

double d_ir_dq_d = 0;
double d_ir_dq_q = 0;
double d_ir_dq_z = 0;






// From Eq. 3.35 and Eq. 3.40 of "Roberts..." page 83, this is the equation for the motor in the D/Q frame.
//
//
//
//										| d_is_dq_d |           | vs_dq_d |      																						      | is_dq_d |
//		| Mdq0s 	Mdqsr |		| d_is_dq_q |           | vs_dq_q |		 {  | Rdq0s       0  |                          	  | Qdq0s    Qdqsr  | }   | is_dq_q |
//		| Mdqsr_t   Mdqr  |	   	| d_is_dq_z |    =     | vs_dq_z |  	-    {  |     0       Rdqr |    -     omega_r      * |      0          0      | }   | is_dq_z |									   Eq. (10)
//										| d_ir_dq_d |            |     0      | 																							      | ir_dq_d |
//										| d_ir_dq_q |            |     0      |																								      | ir_dq_q |
//			   				 			| d_ir_dq_z |            |     0      |																								      | ir_dq_z |
//
//
//
//																																				     | is_dq_d |
//			    Te  = .5 *  | is_dq_d 	is_dq_q   ir_dq_z   ir_dq_d 	ir_dq_q   ir_dq_z |  |      0            Qdqsr |  | is_dq_q |
//																						     	                    |  Qdqsr_t          0    |  | is_dq_z |
//                                                                                                                                                   | ir_dq_d  |
//																																					 | ir_dq_q  |
//																																					 | ir_dq_z  |
//
//
//																													|				0   						 ir_sdq_q * Qdqsr[0][1]   |
//					= .5 *  | is_dq_d    is_dq_q   is_dq_z   ir_dq_d  ir_dq_q   ir_dq_z |	|				0				 			 ir_sdq_d * Qdqsr[1][0]   |
//																													|				0				                             0                 |
//																													|  is_sdq_q * Qdqsr_t[0][1]						 0				    |
//																													|  is_sdq_d * Qdqsr_t[1][0]	                     0                 |
//																													|                  0                                        0                  |
//
//
//					= .5 * is_dq_d * ir_dq_q * Qdqsr[0][1] + .5 * is_dq_q *  ir_dq_d * Qdqsr[1][0] + .5 * ir_dq_d *  is_dq_q * Qdqsr_t[0][1] + .5 * ir_dq_q * is_dq_d * Qdqsr_t[1][0]






//
//
//
//
//		d_is_dq_d * Mdq0s[0][0]  + d_ir_dq_d * Mdqsr[0][0]  = vs_dq_d  -  is_dq_d * Rdq0s[0][0]  - omega_r    * ( is_dq_q * Qdq0s[0][1]  +  ir_dq_q * Qdqsr[0][1] )		Eq. (11)
//
//		d_is_dq_q * Mdq0s[1][1]  + d_ir_dq_q * Mdqsr[1][1]  = vs_dq_q  -  is_dq_q * Rdq0s[1][1]  - omega_r    * ( is_dq_d * Qdq0s[1][0]  +  ir_dq_d * Qdq0s[1][0] )		Eq. (12)
//
//																				0  = vs_dq_z  -  is_dq_z * Rdq0s[2][2]																										Eq. (13)
//
//		d_is_dq_d * Mdqsr_t[0][0]  + d_ir_dq_d * Mdqr[0][0]  = 0 -  ir_dq_d * Rdqr[0][0]																													Eq. (14)
//
//		d_is_dq_q * Mdqsr_t[1][1]  + d_ir_dq_q * Mdqr[1][1]	= 0 -  ir_dq_q * Rdqr[1][1]																													Eq. (15)
//
//											   d_ir_dq_z * Mdqr[2][2]		= 0 -  ir_dq_z * Rdqr[2][2]																													Eq. (16)
//
//	    d_theta_r	 = omega_r																																																	Eq, (17)
//
//	    d_omega_r  = (.5 * is_dq_d * ir_dq_q * Qdqsr[0][1] + .5 * is_dq_q *  ir_dq_d * Qdqsr[1][0] + .5 * ir_dq_d *  is_dq_q * Qdqsr_t[0][1] + .5 * ir_dq_q * is_dq_d * Qdqsr_t[1][0]  - Ti)  / Jm		Eq. (18)
//
//
//
//
//
//
//
//


//For the "Synchronous" D/Q plane, here are the voltage and current transformations (See Eq. 7.3 on page 177 and Table 7.1 on page 206 of "Roberts..."

double phi = 0;

#define is_sdq_d_derived 		(is_dq_d*cos(theta_r - theta_s + phi) + is_dq_q*sin(theta_r - theta_s  + phi))
#define is_sdq_q_derived 	 	(-is_dq_d*sin(theta_r - theta_s + phi) + is_dq_q*cos(theta_r - theta_s  + phi))
#define is_sdq_z_derived		(is_dq_z)

#define is_dq_d_inv_derived  		(is_sdq_d*cos(theta_r - theta_s + phi) - is_sdq_q*sin(theta_r - theta_s + phi))
#define is_dq_q_inv_derived   	(is_sdq_d*sin(theta_r - theta_s  + phi) + is_sdq_q*cos(theta_r - theta_s  + phi))
#define is_dq_z_inv_derived       (is_sdq_z)

#define ir_sdq_d_derived 		(ir_dq_d*cos(theta_r - theta_s + phi) + ir_dq_q*sin(theta_r - theta_s  + phi))
#define ir_sdq_q_derived 		(-ir_dq_d*sin(theta_r - theta_s + phi) + ir_dq_q*cos(theta_r - theta_s  + phi))
#define ir_sdq_z_derived		(ir_dq_z)

#define vs_sdq_d_derived 		(vs_dq_d*cos(theta_r - theta_s + phi) + vs_dq_q*sin(theta_r - theta_s  + phi))
#define vs_sdq_q_derived 		(-vs_dq_d*sin(theta_r - theta_s + phi) + vs_dq_q*cos(theta_r - theta_s  + phi))
#define vs_sdq_z_derived		( vs_dq_z)

double is_sdq_d = 0;
double is_sdq_q = 0;
double is_sdq_z = 0;

double ir_sdq_d = 0;
double ir_sdq_q = 0;
double ir_sdq_z = 0;

double vs_sdq_d = 0;
double vs_sdq_q = 0;
double vs_sdq_z = 0;

double d_is_sdq_d = 0;
double d_is_sdq_q = 0;
double d_is_sdq_z = 0;

double d_ir_sdq_d = 0;
double d_ir_sdq_q = 0;
double d_ir_sdq_z = 0;



// From Eq. 712 page 180, Eq. 7.7, 7.8, 7.9, 7.10 and 7.11 on page 179, and Eq. 3.35 page 83  of "Roberts..."


//												| d_is_sdq_d |           | vs_sdq_d |      																									 																			 		 	  | is_sdq_d |
//		| Msync0s 	Msyncsr |		| d_is_sdq_q |           | vs_sdq_q |		 {  | Rsync0s       0     |                                 | Qsync0s    Qsyncsr  |									         |Qsyncd0s   Qsyncdsr  |	  }   | is_sdq_q |
//		| Msyncsr_t   Msyncr   |	   	| d_is_sdq_z |    =     | vs_sdq_z |  	-    {  |     0          Rsyncr |    -    omega_r    	   *  |      0               0       |    -  (omega_r - omega_s) *  | Qsyncdsr_t	 Qsyncdr  |	  }   | is_sdq_z |
//												| d_ir_sdq_d |            |     0        | 																																													 		  	  | ir_sdq_d |     Eq. (19)
//												| d_ir_sdq_q |            |     0        |																																										                 		  	  | ir_sdq_q |
//			   				 					| d_ir_sdq_z |            |     0        |																																											              		  	  | ir_sdq_z |
//
//
//
//																						                                                                            | is_sdq_d |
//			    Te  = .5 *  | is_sdq_d 	is_sdq_q   is_sdq_z   ir_sdq_d 	ir_sdq_q   ir_sdq_z |  |       0           Ssyncsr |  | is_sdq_q |
//																						     	                               |  Ssyncsr_t        0      |   | is_sdq_z |
//                                                                                                                                                                  | ir_sdq_d  |
//																																								    | ir_sdq_q  |
//																																									| ir_sdq_z  |
//
//
//																																|				 0							 ir_sdq_q * Ssyncsr[0][1]   |
//					= .5 *  | is_sdq_d 	is_sdq_q   is_sdq_z   ir_sdq_d 	ir_sdq_q   ir_sdq_z |	|				 0				 			 ir_sdq_d * Ssyncsr[1][0]   |
//																																|				 0				                             0                    |
//																																|  is_sdq_q * Ssyncsr_t[0][1]					 0					   |
//																																|  is_sdq_d * Ssyncsr_t[1][0]	                 0                    |
//																																|                  0                                         0                    |
//
//
//					= .5 * is_sdq_d * ir_sdq_q * Ssyncsr[0][1] + .5 * is_sdq_q *  ir_sdq_d * Ssyncsr[1][0] + .5 * ir_sdq_d *  is_sdq_q * Ssyncsr_t[0][1] + .5 * ir_sdq_q * is_sdq_d * Ssyncsr_t[1][0]
//
//
//
//
//
//
//
//
//
//
//
//
//		d_is_sdq_d * Msync0s[0][0]  + d_ir_sdq_d * Msyncsr[0][0]  = vs_sdq_d  -  is_sdq_d * Rsync0s[0][0]  - omega_r * ( is_sdq_q * Qsync0s[0][1]  +  ir_sdq_q * Qsyncsr[0][1] )	- (omega_r - omega_s) * (is_sdq_q * Qsyncd0s[0][1] + ir_sdq_q * Qsyncdsr[0][1])    Eq. (20)
//
//		d_is_sdq_q * Msync0s[1][1]  + d_ir_sdq_q * Msyncsr[1][1]  = vs_sdq_q  -  is_sdq_q * Rsync0s[1][1]  - omega_r * ( is_sdq_d * Qsync0s[1][0]  +  ir_sdq_d * Qsyncsr[1][0] )  - (omega_r - omega_s) * (is_sdq_d * Qsyncd0s[1][0] + ir_sdq_d * Qsyncdsr[1][0])    Eq. (21)
//
//																				           0  = vs_sdq_z  -  is_sdq_z * Rsync0s[2][2]																																						    Eq. (22)
//
//		d_is_sdq_d * Msyncsr_t[0][0]  + d_ir_sdq_d * Msyncr[0][0]  = 0 -  ir_sdq_d * Rsyncr[0][0]    -   (omega_r - omega_s) *  (is_sdq_q * Qsyncdsr_t[0][1] + ir_sdq_q * Qsyncdr[0][1])												Eq. (23)
//
//		d_is_sdq_q * Msyncsr_t[1][1]  + d_ir_sdq_q * Msyncr[1][1]  = 0 -  ir_sdq_q * Rsyncr[1][1]    -   (omega_r - omega_s) *  (is_sdq_d * Qsyncdsr_t[1][0] + ir_sdq_d * Qsyncdr[1][0])												Eq. (24)
//
//														d_ir_sdq_z * Msyncr[2][2]  = 0 -  ir_sdq_z * Rsyncr[2][2]																																											Eq. (25)
//
//	    d_theta_r = omega_r																																																																		        Eq. (26)
//
//	    d_omega_r = (.5 * is_sdq_d * ir_sdq_q * Ssyncsr[0][1] + .5 * is_sdq_q *  ir_sdq_d * Ssyncsr[1][0] + .5 * ir_sdq_d *  is_sdq_q * Ssyncsr_t[0][1] + .5 * ir_sdq_q * is_sdq_d * Ssyncsr_t[1][0]  - Ti)  / Jm				Eq. (27)
//
//
//
//
//



// --------------------------------------------------------------------------------------------------------------------------------------------------------------
// IMPORTANT: The following variables are declared for CtrlObject "RefGen".
//					 Variables with a "_r" suffix (meaning "reference") help to differenciate there counterparts
//				     used in other objects of this simulation.



double is_sdq_d_r;
double is_sdq_q_r;

double ir_sdq_d_r;
double ir_sdq_q_r;

double vs_sdq_d_r;
double vs_sdq_q_r;

double d_is_sdq_d_r;
double d_is_sdq_q_r;

double d_ir_sdq_d_r;
double d_ir_sdq_q_r;

double omega_r_r;
double omega_s_r;



double domega_r_dt;
double d2omega_r_dt2;

double k1;
double k2;
double k3;
double k4;

double vs_sdq_d_r_prev;
double omega_s_r_prev;


// Indices for LagrangeSolve Vector.

#define Ind_k1	 			0
#define Ind_k2 	 			1
#define Ind_k3 	 			2
#define Ind_k4    			3
#define Ind_Omega_s		4
#define Ind_vs_sdq_d		5


// ----------------------------------------------------------------------------------------------------------------------------------------------------------------






#ifdef TERMINAL_REF_PLANE_SIMULATION


	//Global function to interpolate "theta_r" for "Msr" and "d_Msr"
double InterpolateThetaRArray(int InterpolationType, unsigned int stator_phase, unsigned rotor_phase)
{

#ifdef INTERPOLATE_USING_TABLE

	double index;
	double fract_interpolate;
	int index_plus_one;
	int index_plus_zero;
	double ( * Msr_or_d_Msr)[3][3];

	if(InterpolationType == Msr)
	{
		Msr_or_d_Msr = Msr_ideal;
	}
	else // InterpolationType == d_Msr
	{
		Msr_or_d_Msr = d_Msr_ideal;
	}

	fract_interpolate = modf(theta_r * 360.0 / (2.0 * PI), &index);

	index_plus_zero = (int) index % 360;
	index_plus_one = ((int) index + 1) % 360;

	if(theta_r < 0)
	{
		fract_interpolate += 1.0;
		index_plus_zero += 359;
		index_plus_one += 359;
		if(index_plus_one == 360)
		{
			index_plus_one = 0;
		}
	}

	return(Msr_or_d_Msr[index_plus_zero][stator_phase][rotor_phase]*(1.0 - fract_interpolate) + fract_interpolate * Msr_or_d_Msr[index_plus_one][stator_phase][rotor_phase]);




#else

		//Refer to "Roberts..."  Eq. 2.6 page 39, Eq. 2.55 and Eq. 2.56 of page 64/65, and Eq. 2.53 of page 63.
	    //Also refer to "../BDFM-Dissertation-2005-Tests/Section_2_7_2/Stator_Rotor_Mutual_Inductance.h" and
	    //"../BDFM-Dissertation-2005-Tests/Section_2_7_2/Stator_Rotor_Derivative_Mutual_Inductance.h". Also, run octave batch file
	    //"../BDFM-Dissertation-2005-Tests/Section_2_7_2/plot_stator_rotor_inductance.m".
		//Finally note that Eq. 2.53 of page 63 can be approximated by the fundamental component only, which is verified with
	    //the octave batch file "plot_stator_rotor_inductance.m" and from the comments made in "Roberts..." page 78 regarding the D/Q
	    //transformation of the Stator-to-Rotor mutual inductance.
	    //

	if(InterpolationType == Msr)
	{
		return(M1_inductance_value * cos(theta_r - (double) stator_phase * 2.0 * PI / 3.0  - (double) rotor_phase * 2.0 * PI / 3.0 - Beta_1));
	}
	else
	{		//(Note that dtheta_r/dthata_r == 1.0 because we will be multiplying the result by omega_r)
		return( - M1_inductance_value * sin(theta_r - (double) stator_phase * 2.0 * PI / 3.0  - (double) rotor_phase * 2.0 * PI / 3.0 - Beta_1));
	}
#endif

}

#endif


// **** SrcObject Classes ********************************

#ifdef TERMINAL_REF_PLANE_SIMULATION

// ---- TriangleWave ---------------------------------------

class TriangleWave : public SrcObject
{
public:
  virtual void SrcFunction(double t);
  virtual void SrcRValueUpdate(void);
  TriangleWave(void);
  ~TriangleWave(void);
  double t_mod;
  double t_prev;
  double PwmRampDir;




};


TriangleWave Inst_TriangleWave;


// --------------------------------------------------------

// ---- PwmA  ---------------------------------------------

class PwmA : public SrcObject
{
public:
  virtual void SrcFunction(double t);
  virtual void OdeRValueUpdate(void);
  PwmA(void);
  ~PwmA(void);
  //source for this ODE
  //(All variables are declared global.)


 
};



PwmA Inst_PwmA;

// -------------------------------------------------------------

// ---- PwmB  ---------------------------------------------

class PwmB : public SrcObject
{
public:
  virtual void SrcFunction(double t);
  virtual void OdeRValueUpdate(void);
  PwmB(void);
  ~PwmB(void);
  //source for this ODE
  //(All variables are declared global.)



};



PwmB Inst_PwmB;

// -------------------------------------------------------------

// ---- PwmC  ---------------------------------------------

class PwmC : public SrcObject
{
public:
  virtual void SrcFunction(double t);
  virtual void OdeRValueUpdate(void);
  PwmC(void);
  ~PwmC(void);
  //source for this ODE
  //(All variables are declared global.)

 

};



PwmC Inst_PwmC;

// -------------------------------------------------------------


SrcObject * SrcObjectList[] = {(SrcObject *) &Inst_TriangleWave,
			       (SrcObject *) &Inst_PwmA,
			       (SrcObject *) &Inst_PwmB,
			       (SrcObject *) &Inst_PwmC,
			       0};

#else

		//There is a problem with the initialization. Simulator expects at least one SrcObject. Create a dummy for now.
// ---- src_dummy ---------------------------------------

class src_dummy : public SrcObject
{
public:
  src_dummy(void);
  ~src_dummy(void);
};


src_dummy Inst_src_dummy;


// --------------------------------------------------------


SrcObject * SrcObjectList[] = {(SrcObject *) &Inst_src_dummy,
		          0};

#endif


// ***********************************************************

// **** OdeObject Classes ********************************

#ifdef TERMINAL_REF_PLANE_SIMULATION

// ---- Is3_Ir6_1 -----------------------------------------

class Is3_Ir6_1 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void OdeGroupMSolve(double dydt[],  double dmdt[]);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Is3_Ir6_1(void);
  ~Is3_Ir6_1(void);
  //locals for this ODE
  double d_Msr_ir;
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  vector<double>  V_s1;
  vector<double> Is_dqd;
  vector<double> Is_dqq;
  vector<double> Is_dqz;
  vector<double> Is_sdqd;
  vector<double> Is_sdqq;
  vector<double> Is_sdqz;

  vector<double> Ir_dqd;
  vector<double> Ir_dqq;
  vector<double> Ir_dqz;
  vector<double> Ir_sdqd;
  vector<double> Ir_sdqq;
  vector<double> Ir_sdqz;

  vector<double> Vs_dqd;
  vector<double> Vs_dqq;
  vector<double> Vs_dqz;
  vector<double> Vs_sdqd;
  vector<double> Vs_sdqq;
  vector<double> Vs_sdqz;


  vector<double> V_neutral;


};

Is3_Ir6_1 Inst_Is3_Ir6_1;




// --------------------------------------------------------

// ---- Is3_Ir6_2 -----------------------------------------

class Is3_Ir6_2 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Is3_Ir6_2(void);
  ~Is3_Ir6_2(void);
  //locals for this ODE
  double d_Msr_ir;
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  vector<double>  V_s2;


};

Is3_Ir6_2 Inst_Is3_Ir6_2;


// --------------------------------------------------------


// ---- Is3_Ir6_3 -----------------------------------------

class Is3_Ir6_3 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Is3_Ir6_3(void);
  ~Is3_Ir6_3(void);
  //locals for this ODE
  double d_Msr_ir;
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  vector<double>  V_s3;


};

Is3_Ir6_3 Inst_Is3_Ir6_3;


// --------------------------------------------------------




// ---- Is3_Ir6_4 -----------------------------------------

class Is3_Ir6_4 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Is3_Ir6_4(void);
  ~Is3_Ir6_4(void);
  //locals for this ODE
  double d_Msr_is;
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  vector<double>  V_r1;


};

Is3_Ir6_4 Inst_Is3_Ir6_4;


// --------------------------------------------------------

// ---- Is3_Ir6_5 -----------------------------------------

class Is3_Ir6_5 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Is3_Ir6_5(void);
  ~Is3_Ir6_5(void);
  //locals for this ODE
  double d_Msr_is;
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  vector<double>  V_r2;


};

Is3_Ir6_5 Inst_Is3_Ir6_5;

// --------------------------------------------------------

// ---- Is3_Ir6_6 -----------------------------------------

class Is3_Ir6_6 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Is3_Ir6_6(void);
  ~Is3_Ir6_6(void);
  //locals for this ODE
  double d_Msr_is;
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  vector<double>  V_r3;

};

Is3_Ir6_6 Inst_Is3_Ir6_6;

// --------------------------------------------------------

// ---- Omega ---------------------------------------------

class Omega : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Omega(void);
  ~Omega(void);
  //locals for this ODE
   double d_Msr_ir[3];
   double is_d_Msr_ir;
  //source for this ODE
  //(All variables are declared global.)
   //storage for probes...
   vector<double> Omega_s;

};

Omega Inst_Omega;


// --------------------------------------------------------


#else

// ---- Is_Ir_sdq_1 -----------------------------------------

class Is_Ir_sdq_1 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void OdeGroupMSolve(double dydt[],  double dmdt[]);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Is_Ir_sdq_1(void);
  ~Is_Ir_sdq_1(void);
  //locals for this ODE
  //(None)
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  vector<double> Vs_dq_d;
  vector<double> Vs_dq_q;
  vector<double> Vs_dq_z;
  vector<double> Vs_sdq_d;
  vector<double> Vs_sdq_q;
  vector<double> Vs_sdq_z;

  vector<double> Is_inv_dqd;
  vector<double> Is_inv_dqq;
  vector<double> Is_inv_dqz;
  vector<double> Is1_inv;
  vector<double> Is2_inv;
  vector<double> Is3_inv;




};

Is_Ir_sdq_1 Inst_Is_Ir_sdq_1;


// --------------------------------------------------------


// ---- Is_Ir_sdq_2 -----------------------------------------

class Is_Ir_sdq_2 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void PostOdeFunction(double t);
  virtual void OdeRValueUpdate(void);
  Is_Ir_sdq_2(void);
  ~Is_Ir_sdq_2(void);
  //locals for this ODE
  //(None)
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  //(None right now.)

};

Is_Ir_sdq_2 Inst_Is_Ir_sdq_2;


// --------------------------------------------------------

// ---- Is_Ir_sdq_3 -----------------------------------------

class Is_Ir_sdq_3 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Is_Ir_sdq_3(void);
  ~Is_Ir_sdq_3(void);
  //locals for this ODE
  //(None)
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  vector<double> Vr_sdq_d;
  vector<double> Vr_sdq_q;
  vector<double> Vr_sdq_z;

};

Is_Ir_sdq_3 Inst_Is_Ir_sdq_3;


// --------------------------------------------------------


// ---- Is_Ir_sdq_4 -----------------------------------------

class Is_Ir_sdq_4 : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  Is_Ir_sdq_4(void);
  ~Is_Ir_sdq_4(void);
  //locals for this ODE
  //(None)
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  //(None right now.)

};

Is_Ir_sdq_4 Inst_Is_Ir_sdq_4;


// --------------------------------------------------------

// ---- Ir_sdq_z -----------------------------------------

class Ir_sdq_z : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  Ir_sdq_z(void);
  ~Ir_sdq_z(void);
  //locals for this ODE
  //(None)
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
  //(None right now.)

};

Ir_sdq_z Inst_Ir_sdq_z;


// --------------------------------------------------------


// ---- Omega ---------------------------------------------

class Omega : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  Omega(void);
  ~Omega(void);
  //locals for this ODE
  //(None)
  //source for this ODE
  //(All variables are declared global.)
  //storage for probes...
   vector<double> Omega_s;

};

Omega Inst_Omega;


// --------------------------------------------------------


#endif





// ---- Theta ---------------------------------------------

class Theta : public OdeObject
{
public:
  virtual double OdeFunction(double y, double t);
  virtual void OdeRValueUpdate(void);
  Theta(void);
  ~Theta(void);
  //source for this ODE
  //(All variables are declared global.)


};

Theta Inst_Theta;

// --------------------------------------------------------




#ifdef TERMINAL_REF_PLANE_SIMULATION

OdeObject * OdeObjectList[] = {(OdeObject *) &Inst_Is3_Ir6_1, 								//the next nine are in a group and must be maintained in this order.
												  (OdeObject *) &Inst_Is3_Ir6_2,
												  (OdeObject *) &Inst_Is3_Ir6_3,
												  (OdeObject *) &Inst_Is3_Ir6_4,
												  (OdeObject *) &Inst_Is3_Ir6_5,
												  (OdeObject *) &Inst_Is3_Ir6_6,
												  (OdeObject *) &Inst_Omega,
												  (OdeObject *) &Inst_Theta,
												  0};

#else


OdeObject * OdeObjectList[] = {(OdeObject *) &Inst_Is_Ir_sdq_1, 								//the next six are in a group and must be maintained in this order.
												  (OdeObject *) &Inst_Is_Ir_sdq_2,
												  (OdeObject *) &Inst_Is_Ir_sdq_3,
												  (OdeObject *) &Inst_Is_Ir_sdq_4,
												  (OdeObject *) & Inst_Ir_sdq_z,
												  (OdeObject *) &Inst_Omega,
												  (OdeObject *) &Inst_Theta,
												  0};



#endif


// ***********************************************************



// **** CtrlObject Classes **********************************




// ---- VDqCmd  ---------------------------------------------

class VDqCmd : public CtrlObject
{
public:
  virtual void CtrlFunction(double t);
  virtual void SrcRValueUpdate(void);
  virtual void OdeRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  VDqCmd(void);
  ~VDqCmd(void);
  void SpaceVectorControl(void);
  double V_xo_local[3];
     // Commands for magnitude and angle in the rotating D/Q plane. (These
     // commands ultimately come from another CTRL that is not part
     // of this simulation).
  double vcmd_mag;
  double vcmd_ang;
     // This signal is ultimate feed by a SRC or ODE that simulates the DC bus with
     // ripple voltage. For now, it will be set to a constant.
  double v_bus;
     // This table used to construct the reference commands for each phase.
  REFERENCE_CONSTRUCT SVTable[6][3];  
  //intermediary varables need for debugging only.
  double V_xo_debug[3];
  //storage for probes..
  vector<double> VCmd_a;  //value of V_xo_local[0].
  vector<double> VCmd_b;  //value of V_xo_local[1].
  vector<double> VCmd_c;  //value of V_xo_local[2].
  vector<double> VCmd_mag; 
  vector<double> VCmd_ang; 
};



VDqCmd Inst_VDqCmd;

// -------------------------------------------------------------




// ---- RefGen  ---------------------------------------------

class RefGen : public CtrlObject
{

public:
  virtual void CtrlFunction(double t);
  virtual void CtrlRValueUpdate(void);
  virtual void RecordProbes(void);
  virtual void PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[]);
  RefGen(void);
  ~RefGen(void);
  double vdd_local;
  double vqd_local;






  //storage for probes..
  vector<double> beta_d;
  vector<double> alpha_d;
  vector<double> omega_d;
  vector<double> theta_d;

  vector<double> Vs_sdq_d_r;
  vector<double> Vs_sdq_q_r;
  vector<double> Is_sdq_d_r;
  vector<double> Is_sdq_q_r;
  vector<double> Ir_sdq_d_r;
  vector<double> Ir_sdq_q_r;
  vector<double> Omega_s_r;



};








RefGen Inst_RefGen;

// -------------------------------------------------------------





//(NOTE: As of 6/12/08, "pTranslationList" and "pTrajectoryList" CTRL's have been 
//       deprecated and replaced with a "group" structure. However, we still maintain
//       only one "CtrlObjectList[]" array for all groups, but we add a "CtrlObjGroupStatus[]"
//       array to specify the "quantum" value for each CTRL object)

CtrlObject * CtrlObjectList[] = {(CtrlObject *) &Inst_RefGen,
                                 (CtrlObject *) &Inst_VDqCmd,
				 0};
        //This array contains the value of the execution quantium for each CtrlObject listed above
        //The order of this list must be relative to the order of the "CtrlObjectList[]" above.
        //CtrlObjects with the same quantum values may be considered a "group" of CtrlObjects.
        //However, there is no requirement that these CtrlObjects be related to each other.
      
int CtrlObjectQuantum[] = { REF_GEN_QUANTUM_CNT,
                            VDQ_CMD_QUANTUM_CNT,
                          };

// **************************************************************


// **** CoefObject Classes ****************************************

#ifdef TERMINAL_REF_PLANE_SIMULATION

// ---- Coef_ir_Msr_0_0_theta_r ---------------------------------------------

class Coef_ir_Msr_0_0_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_ir_Msr_0_0_theta_r(void);
  ~Coef_ir_Msr_0_0_theta_r(void);


};

Coef_ir_Msr_0_0_theta_r Coef_ir_Msr_0_0_theta_r_i;

// -------------------------------------------------------------

// ---- Coef_ir_Msr_0_1_theta_r ---------------------------------------------

class Coef_ir_Msr_0_1_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_ir_Msr_0_1_theta_r(void);
  ~Coef_ir_Msr_0_1_theta_r(void);


};

Coef_ir_Msr_0_1_theta_r Coef_ir_Msr_0_1_theta_r_i;

// -------------------------------------------------------------

// ---- Coef_ir_Msr_0_2_theta_r ---------------------------------------------

class Coef_ir_Msr_0_2_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_ir_Msr_0_2_theta_r(void);
  ~Coef_ir_Msr_0_2_theta_r(void);


};

Coef_ir_Msr_0_2_theta_r Coef_ir_Msr_0_2_theta_r_i;

// -------------------------------------------------------------


// ---- Coef_ir_Msr_1_0_theta_r ---------------------------------------------

class Coef_ir_Msr_1_0_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_ir_Msr_1_0_theta_r(void);
  ~Coef_ir_Msr_1_0_theta_r(void);


};

Coef_ir_Msr_1_0_theta_r Coef_ir_Msr_1_0_theta_r_i;

// -------------------------------------------------------------

// ---- Coef_ir_Msr_1_1_theta_r ---------------------------------------------

class Coef_ir_Msr_1_1_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_ir_Msr_1_1_theta_r(void);
  ~Coef_ir_Msr_1_1_theta_r(void);


};

Coef_ir_Msr_1_1_theta_r Coef_ir_Msr_1_1_theta_r_i;

// -------------------------------------------------------------

// ---- Coef_ir_Msr_1_2_theta_r ---------------------------------------------

class Coef_ir_Msr_1_2_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_ir_Msr_1_2_theta_r(void);
  ~Coef_ir_Msr_1_2_theta_r(void);


};

Coef_ir_Msr_1_2_theta_r Coef_ir_Msr_1_2_theta_r_i;

// -------------------------------------------------------------


// ---- Coef_ir_Msr_2_0_theta_r ---------------------------------------------

class Coef_ir_Msr_2_0_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_ir_Msr_2_0_theta_r(void);
  ~Coef_ir_Msr_2_0_theta_r(void);


};

Coef_ir_Msr_2_0_theta_r Coef_ir_Msr_2_0_theta_r_i;

// -------------------------------------------------------------

// ---- Coef_ir_Msr_2_1_theta_r ---------------------------------------------

class Coef_ir_Msr_2_1_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_ir_Msr_2_1_theta_r(void);
  ~Coef_ir_Msr_2_1_theta_r(void);


};

Coef_ir_Msr_1_1_theta_r Coef_ir_Msr_2_1_theta_r_i;

// -------------------------------------------------------------

// ---- Coef_ir_Msr_2_2_theta_r ---------------------------------------------

class Coef_ir_Msr_2_2_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_ir_Msr_2_2_theta_r(void);
  ~Coef_ir_Msr_2_2_theta_r(void);


};

Coef_ir_Msr_2_2_theta_r Coef_ir_Msr_2_2_theta_r_i;

// -------------------------------------------------------------


// ---- Coef_is_Msr_0_0_theta_r ---------------------------------------------

class Coef_is_Msr_0_0_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_is_Msr_0_0_theta_r(void);
  ~Coef_is_Msr_0_0_theta_r(void);


};

Coef_is_Msr_0_0_theta_r Coef_is_Msr_0_0_theta_r_i;

// -------------------------------------------------------------


// ---- Coef_is_Msr_1_0_theta_r ---------------------------------------------

class Coef_is_Msr_1_0_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_is_Msr_1_0_theta_r(void);
  ~Coef_is_Msr_1_0_theta_r(void);


};

Coef_is_Msr_1_0_theta_r Coef_is_Msr_1_0_theta_r_i;

// -------------------------------------------------------------

// ---- Coef_is_Msr_2_0_theta_r ---------------------------------------------

class Coef_is_Msr_2_0_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_is_Msr_2_0_theta_r(void);
  ~Coef_is_Msr_2_0_theta_r(void);


};

Coef_is_Msr_2_0_theta_r Coef_is_Msr_2_0_theta_r_i;

// -------------------------------------------------------------




// ---- Coef_is_Msr_0_1_theta_r ---------------------------------------------

class Coef_is_Msr_0_1_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_is_Msr_0_1_theta_r(void);
  ~Coef_is_Msr_0_1_theta_r(void);


};

Coef_is_Msr_0_1_theta_r Coef_is_Msr_0_1_theta_r_i;

// -------------------------------------------------------------


// ---- Coef_is_Msr_1_1_theta_r ---------------------------------------------

class Coef_is_Msr_1_1_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_is_Msr_1_1_theta_r(void);
  ~Coef_is_Msr_1_1_theta_r(void);


};

Coef_is_Msr_1_1_theta_r Coef_is_Msr_1_1_theta_r_i;

// -------------------------------------------------------------

// ---- Coef_is_Msr_2_1_theta_r ---------------------------------------------

class Coef_is_Msr_2_1_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_is_Msr_2_1_theta_r(void);
  ~Coef_is_Msr_2_1_theta_r(void);


};

Coef_is_Msr_2_1_theta_r Coef_is_Msr_2_1_theta_r_i;

// -------------------------------------------------------------



// ---- Coef_is_Msr_0_2_theta_r ---------------------------------------------

class Coef_is_Msr_0_2_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_is_Msr_0_2_theta_r(void);
  ~Coef_is_Msr_0_2_theta_r(void);


};

Coef_is_Msr_0_2_theta_r Coef_is_Msr_0_2_theta_r_i;

// -------------------------------------------------------------


// ---- Coef_is_Msr_1_2_theta_r ---------------------------------------------

class Coef_is_Msr_1_2_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_is_Msr_1_2_theta_r(void);
  ~Coef_is_Msr_1_2_theta_r(void);


};

Coef_is_Msr_1_2_theta_r Coef_is_Msr_1_2_theta_r_i;

// -------------------------------------------------------------

// ---- Coef_is_Msr_2_2_theta_r ---------------------------------------------

class Coef_is_Msr_2_2_theta_r : public CoefObject
{
public:
  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
  Coef_is_Msr_2_2_theta_r(void);
  ~Coef_is_Msr_2_2_theta_r(void);


};

Coef_is_Msr_2_2_theta_r Coef_is_Msr_2_2_theta_r_i;

// -------------------------------------------------------------



CoefObject * CoefObjectList[] = {(CoefObject *)  &Coef_ir_Msr_0_0_theta_r_i,
				 (CoefObject *)  &Coef_ir_Msr_0_1_theta_r_i,
				 (CoefObject *)  &Coef_ir_Msr_0_2_theta_r_i,
				 (CoefObject *)  &Coef_ir_Msr_1_0_theta_r_i,
				 (CoefObject *)  &Coef_ir_Msr_1_1_theta_r_i,
				 (CoefObject *)  &Coef_ir_Msr_1_2_theta_r_i,
				 (CoefObject *)  &Coef_ir_Msr_2_0_theta_r_i,
				 (CoefObject *)  &Coef_ir_Msr_2_1_theta_r_i,
				 (CoefObject *)  &Coef_ir_Msr_2_2_theta_r_i,
				 (CoefObject *)  &Coef_is_Msr_0_0_theta_r_i,
				 (CoefObject *)  &Coef_is_Msr_1_0_theta_r_i,
				 (CoefObject *)  &Coef_is_Msr_2_0_theta_r_i,
				 (CoefObject *)  &Coef_is_Msr_0_1_theta_r_i,
				 (CoefObject *)  &Coef_is_Msr_1_1_theta_r_i,
				 (CoefObject *)  &Coef_is_Msr_2_1_theta_r_i,
				 (CoefObject *)  &Coef_is_Msr_0_2_theta_r_i,
				 (CoefObject *)  &Coef_is_Msr_1_2_theta_r_i,
				 (CoefObject *)  &Coef_is_Msr_2_2_theta_r_i,
				 0};

#else

CoefObject * CoefObjectList[] = {0};

#endif

	// Special CoefObject Classes for "LagrangeSolve" SpiceObject. Note that we do not
    // generate a "CoefOjectList". We don't need it unless we need exception processing.
 	// These CoefObjects along with the "LagrangeSolve" SpiceObject are controlled directly
	// in CtrlObject "RefGen"

// ---- Coef_Eq_41_k1 ---------------------------------------------

class Coef_Eq_41_k1 : public CoefObject
{
public:
	  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	  Coef_Eq_41_k1(void);
	  ~Coef_Eq_41_k1(void);
};

Coef_Eq_41_k1 Coef_Eq_41_k1_i;

// ---------------------------------------------------------------------------

// ---- Coef_Eq_41_k2 ---------------------------------------------

class Coef_Eq_41_k2 : public CoefObject
{
public:
	  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	  Coef_Eq_41_k2(void);
	  ~Coef_Eq_41_k2(void);
};

Coef_Eq_41_k2 Coef_Eq_41_k2_i;

// ---------------------------------------------------------------------------

// ---- Coef_Eq_41_k3 ---------------------------------------------

class Coef_Eq_41_k3 : public CoefObject
{
public:
	  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	  Coef_Eq_41_k3(void);
	  ~Coef_Eq_41_k3(void);
};

Coef_Eq_41_k3 Coef_Eq_41_k3_i;

// ---------------------------------------------------------------------------

// ---- Coef_Eq_41_k4 ---------------------------------------------

class Coef_Eq_41_k4 : public CoefObject
{
public:
	  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	  Coef_Eq_41_k4(void);
	  ~Coef_Eq_41_k4(void);
};

Coef_Eq_41_k4 Coef_Eq_41_k4_i;

// ---------------------------------------------------------------------------


// ---- Coef_Eq_42_k1 ---------------------------------------------

class Coef_Eq_42_k1 : public CoefObject
{
public:
	  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	  Coef_Eq_42_k1(void);
	  ~Coef_Eq_42_k1(void);
};

Coef_Eq_42_k1 Coef_Eq_42_k1_i;

// ---------------------------------------------------------------------------

// ---- Coef_Eq_42_k2 ---------------------------------------------

class Coef_Eq_42_k2 : public CoefObject
{
public:
	  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	  Coef_Eq_42_k2(void);
	  ~Coef_Eq_42_k2(void);
};

Coef_Eq_42_k2 Coef_Eq_42_k2_i;

// ---------------------------------------------------------------------------

// ---- Coef_Eq_42_k3 ---------------------------------------------

class Coef_Eq_42_k3 : public CoefObject
{
public:
	  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	  Coef_Eq_42_k3(void);
	  ~Coef_Eq_42_k3(void);
};

Coef_Eq_42_k3 Coef_Eq_42_k3_i;

// ---------------------------------------------------------------------------

// ---- Coef_Eq_42_k4 ---------------------------------------------

class Coef_Eq_42_k4 : public CoefObject
{
public:
	  virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	  Coef_Eq_42_k4(void);
	  ~Coef_Eq_42_k4(void);
};

Coef_Eq_42_k4 Coef_Eq_42_k4_i;

// ---------------------------------------------------------------------------

// ---- Coef_Eq_30_is_ir_omega_r -----------------------------

class Coef_Eq_30_is_ir_omega_r : public CoefObject
{
public:
	virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	Coef_Eq_30_is_ir_omega_r(void);
	~Coef_Eq_30_is_ir_omega_r(void);
};

Coef_Eq_30_is_ir_omega_r Coef_Eq_30_is_ir_omega_r_i;

// --------------------------------------------------------------------------

// ---- Coef_Eq_30_omega_s ------------------------------------

class Coef_Eq_30_omega_s : public CoefObject
{
public:
	virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	Coef_Eq_30_omega_s(void);
	~Coef_Eq_30_omega_s(void);

};

Coef_Eq_30_omega_s Coef_Eq_30_omega_s_i;

// --------------------------------------------------------------------------

// ---- Coef_Eq_31_is_ir_omega_r -----------------------------

class Coef_Eq_31_is_ir_omega_r : public CoefObject
{
public:
	virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	Coef_Eq_31_is_ir_omega_r(void);
	~Coef_Eq_31_is_ir_omega_r(void);
};

Coef_Eq_31_is_ir_omega_r Coef_Eq_31_is_ir_omega_r_i;

// --------------------------------------------------------------------------

// ---- Coef_Eq_31_omega_s ------------------------------------

class Coef_Eq_31_omega_s : public CoefObject
{
public:
	virtual void CoefFunction(double recp_h, bool DoTrapezoidal);
	Coef_Eq_31_omega_s(void);
	~Coef_Eq_31_omega_s(void);

};

Coef_Eq_31_omega_s Coef_Eq_31_omega_s_i;

// --------------------------------------------------------------------------



// ****************************************************************

// **** SwitchObject Classes **************************************

SwitchObject * SwitchObjectList[] = {0};


// *********************************************************************


// **** SpiceObject Classes ***************************************


// ---- GroupOdeSolve ------------------------------------------

	//NOTE: This is a special use mode for "SpiceObject". We use it's Guassian Elimination function to solve the nine simultanious equations
    //           which are a product of the OdeObject simulation list. As such, we do not include this object in "SpiceObjectList[]" below.
    //           It is controlled by OdeObject " Is3_Ir6_1 " or " Is_Ir_sdq_1 " below.


class GroupOdeSolve : public SpiceObject
{
public:

  GroupOdeSolve(void);
  ~GroupOdeSolve(void);


};


GroupOdeSolve GroupOdeSolve_i;


// ---------------------------------------------------------------



// ---- LagrangeSolve --------------------------------------

//NOTE: This is a special use for "SpiceObject" used to solve the Lagrange constraint equatoin used in CtrlObject "RefGen".

class LagrangeSolve  : public SpiceObject
{
public:

LagrangeSolve(void);
~LagrangeSolve(void);


};

LagrangeSolve LagrangeSolve_i;


// ---------------------------------------------------------------



SpiceObject * SpiceObjectList[] = {0};

// **************************************************************





// **** SrcObject Functions **************************************

#ifdef TERMINAL_REF_PLANE_SIMULATION

// ---- TriangleWave  ----------------------------------------------------

TriangleWave::TriangleWave(void)
{
 

  SrcFuncName = SRC_FUNC_TriangleWave;
  LiteralName = "TriangleWave";


  //build the SRC Rvalue list.
  //(All variables are declared global.)



  PwmRampDir = 1.0;

  PlotThisOutput = TRUE;
  Plot_Tag = "TriangleWave";
}

TriangleWave::~TriangleWave(void)
{



}

void TriangleWave::SrcFunction(double t)
{
  t_mod += (t - t_prev);
  t_prev = t;

  if(t_mod > QUARTER_PWM_CYCLE){
    t_mod -=  QUARTER_PWM_CYCLE;
    PwmRampDir *= -1.0;
  }
 
  y = PWM_GAIN*(t_mod/QUARTER_PWM_CYCLE - .5)*PwmRampDir + PWM_OFFSET;

}

void TriangleWave::SrcRValueUpdate(void)
{
	TriAngWave = y;
}


// -----------------------------------------------------------------

// ---- PwmA ---------------------------------------------------

PwmA::PwmA(void)
{

  SrcFuncName = SRC_FUNC_PwmA;
  LiteralName = "PwmA";
  
  //build the ODE Rvalue list.
  //(All variables are declared global.)


}

PwmA::~PwmA(void)
{



}

void PwmA::SrcFunction(double t)
{

  //For simulation, "V_xo" is space vector reference to a triangle wave
  //running between 0 and PWM_GAIN.
	y = V_xo[0]  > TriAngWave ? 1.0 : 0;

}

void PwmA::OdeRValueUpdate(void)
{
#ifndef LINEAR_AMP_MODE
	pwm_sig[0] = y;
#endif
}


// -----------------------------------------------------------------


// ---- PwmB ---------------------------------------------------


PwmB::PwmB(void)
{

  SrcFuncName = SRC_FUNC_PwmB;
  LiteralName = "PwmB";
  
  //build the ODE Rvalue list.
  //(All variables are declared global.)

}


PwmB::~PwmB(void)
{


}


void PwmB::SrcFunction(double t)
{

  //For simulation, "V_xo" is space vector reference to a triangle wave
  //running between 0 and PWM_GAIN.
	y = V_xo[1] > TriAngWave ? 1.0 : 0;

}

void PwmB::OdeRValueUpdate(void)
{
#ifndef LINEAR_AMP_MODE
	pwm_sig[1] = y;
#endif
}


// ----------------------------------------------------------------- 


// ---- PwmC ---------------------------------------------------

PwmC::PwmC(void)
{

  SrcFuncName = SRC_FUNC_PwmC;
  LiteralName = "PwmC";
  
  //build the ODE Rvalue list.
  //(All variables are declared global.)


}

PwmC::~PwmC(void)
{


}


void PwmC::SrcFunction(double t)
{

  //For simulation, "V_xo" is space vector reference to a triangle wave
  //running between 0 and PWM_GAIN.
	y = V_xo[2] > TriAngWave ? 1.0 : 0;

}

void PwmC::OdeRValueUpdate(void)
{
#ifndef LINEAR_AMP_MODE
	pwm_sig[2] = y;
#endif
}

// ----------------------------------------------------------------- 

#else

	//There is a problem with the initialization. Simulator expects at least one SrcObject. Create a dummy for now.
// ---- src_dummy ---------------------------------------------------

src_dummy::src_dummy(void)
{

  SrcFuncName = SRC_FUNC_src_dummy;
  LiteralName = "src_dummy";



}

src_dummy::~src_dummy(void)
{



}

// -----------------------------------------------------------------

#endif




// ***************************************************************


// **** OdeObject Functions **************************************

#ifdef TERMINAL_REF_PLANE_SIMULATION

// ---- Is3_Ir6_1  ----------------------------------------------------

Is3_Ir6_1::Is3_Ir6_1(void)
{

  OdeFuncName = ODE_FUNC_Is3_Ir6_1;
  LiteralName = "Is3_Ir6_1";
  

  //this object marks the beginning of a "group solve" of
  //nine objects.
  GroupSolve = 1;
  NumberOfGrpOdes = 6;

  //build the ODE Rvalue list.
  //(All variables are declared global.)

 

  PlotThisOutput = TRUE;
  Plot_Tag = "is1";
  DoProbes = TRUE;
  
}

Is3_Ir6_1::~Is3_Ir6_1(void)
{

}

double Is3_Ir6_1::OdeFunction(double y, double t)
{
  int i;
  //Note: This is within a "group" ODE so we are really returning for "dm/dt + v_n"

          //"vs[0] - v_n - Rs_res[0][0]*is[0] - omega_r *d_Msr[theta_r][0][0 to 2] x ir[0 to 2]"

#ifdef LINEAR_AMP_MODE
     //generating the voltage command directly through CtrlObject "VDqCmd" 
  vs[0] = pwm_sig[0] + .5*DC_BUS_VOLTAGE;
#else
  vs[0] = ShapeSquareWaveSource(((pwm_sig[0] > 0) ? DC_BUS_VOLTAGE : 0), SRC_SLEW_RATE ,t);
#endif 
  d_Msr_ir = 0;
  for(i = 0; i < 3; i++)
  {
	  d_Msr_ir += InterpolateThetaRArray(d_Msr, 0, i) * ir[i];

  }

  //(Note: Unlike "App_Observer.hpp",  "v_n" is now part of the RValue.).
  //return(vs[0] - v_n -  Rs_res[0][0] * y - omega_r *d_Msr_ir);
  return(vs[0]  -  Rs_res[0][0] * y - omega_r *d_Msr_ir);
}


void Is3_Ir6_1::RecordProbes(void)
{
  V_s1.push_back(vs[0] - v_n);

  	  //Un-comment only those to be plotted.

  is_dq_d =  is_dq_d_derived;
  Is_dqd.push_back(is_dq_d );

  is_dq_q =  is_dq_q_derived;
  Is_dqq.push_back(is_dq_q);

//  is_dq_z =  is_dq_z_derived;
//  Is_dqz.push_back(is_dq_z);

  is_sdq_d =  is_sdq_d_derived;
  Is_sdqd.push_back(is_sdq_d);

  is_sdq_q =  is_sdq_q_derived;
  Is_sdqq.push_back(is_sdq_q);

//  is_sdq_z =  is_sdq_z_derived;
//  Is_sdqz.push_back(is_sdq_z);



  ir_dq_d = ir_dq_d_derived;			//(Need this to run FORCE_REF_DEBUG_TEST in "RefGen" when TERMINAL_REF_PLANE_SIMULATION is set to TRUE)
//  Ir_dqd.push_back(ir_dq_d);

  ir_dq_q = ir_dq_q_derived;		    //(Need this to run FORCE_REF_DEBUG_TEST in "RefGen" when TERMINAL_REF_PLANE_SIMULATION is set to TRUE)
//  Ir_dqq.push_back(ir_dq_q);

//  ir_dq_z = ir_dq_z_derived;
//  Ir_dqz.push_back(ir_dq_z);

//  vs_dq_d = vs_dq_d_derived;
//  Vs_dqd.push_back(vs_dq_d);

//  vs_dq_q = vs_dq_q_derived;   //(Need this to run FORCE_REF_DEBUG_TEST in "RefGen" when TERMINAL_REF_PLANE_SIMULATION is set to TRUE)
//  Vs_dqq.push_back(vs_dq_q);

//  vs_dq_z = vs_dq_z_derived;
//  Vs_dqz.push_back(vs_dq_z);


  ir_sdq_d = ir_sdq_d_derived;     //(Need this to run FORCE_REF_DEBUG_TEST in "RefGen" when TERMINAL_REF_PLANE_SIMULATION is set to TRUE)
  Ir_sdqd.push_back(ir_sdq_d);

  ir_sdq_q = ir_sdq_q_derived;    //(Need this to run FORCE_REF_DEBUG_TEST in "RefGen" when TERMINAL_REF_PLANE_SIMULATION is set to TRUE)
  Ir_sdqq.push_back(ir_sdq_q);

//  ir_sdq_z = ir_sdq_z_derived;
//  Ir_sdqz.push_back(ir_sdq_z);


  // vs_sdq_d = vs_sdq_d_derived;  //(**** IMPORTANT: This cannot be assigned if FORCE_REF_DEBUG_TEST in "RefGen" is set to a value other then "0" ! ****)
  Vs_sdqd.push_back(vs_sdq_d);

  vs_sdq_q = vs_sdq_q_derived;  //(Need this to run FORCE_REF_DEBUG_TEST in "RefGen" when TERMINAL_REF_PLANE_SIMULATION is set to TRUE)
  Vs_sdqq.push_back(vs_sdq_q);

//  vs_sdq_z = vs_sdq_z_derived;
//  Vs_sdqz.push_back(vs_sdq_z);


//   V_neutral.push_back(v_n);

}




void Is3_Ir6_1::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
  int i;
  if(TagNamesToPlot[0] == ""){
	  return;
  }
  else{
    for(i = 0; i < 20; i++){
      if(TagNamesToPlot[i] == "vs1"){
	SimuPlot.plot_xy(Plot_t, V_s1, "vs1");
	printf("got here");
      }
      else if(TagNamesToPlot[i] == "isdqd"){
 	SimuPlot.plot_xy(Plot_t, Is_dqd, "isdqd_derived");
       }
      else if(TagNamesToPlot[i] == "isdqq"){
 	SimuPlot.plot_xy(Plot_t, Is_dqq, "isdqq_derived");
       }
      else if(TagNamesToPlot[i] == "isdqz"){
     	SimuPlot.plot_xy(Plot_t, Is_dqz, "isdqz_derived");
           }
      else if(TagNamesToPlot[i] == "issdqd"){
 	SimuPlot.plot_xy(Plot_t, Is_sdqd, "issdqd_derived");
       }
      else if(TagNamesToPlot[i] == "issdqq"){
 	SimuPlot.plot_xy(Plot_t, Is_sdqq, "issdqq_derived");
       }
      else if(TagNamesToPlot[i] == "issdqz"){
     	SimuPlot.plot_xy(Plot_t, Is_sdqz, "issdqz_derived");
           }

      else if(TagNamesToPlot[i] == "irdqd"){
 	SimuPlot.plot_xy(Plot_t, Ir_dqd, "irdqd_derived");
       }
      else if(TagNamesToPlot[i] == "irdqq"){
 	SimuPlot.plot_xy(Plot_t, Ir_dqq, "irdqq_derived");
       }
      else if(TagNamesToPlot[i] == "irdqz"){
     	SimuPlot.plot_xy(Plot_t, Ir_dqz, "irdqz_derived");
           }
      else if(TagNamesToPlot[i] == "irsdqd"){
 	SimuPlot.plot_xy(Plot_t, Ir_sdqd, "irsdqd_derived");
       }
      else if(TagNamesToPlot[i] == "irsdqq"){
 	SimuPlot.plot_xy(Plot_t, Ir_sdqq, "irsdqq_derived");
       }
      else if(TagNamesToPlot[i] == "irsdqz"){
     	SimuPlot.plot_xy(Plot_t, Ir_sdqz, "irsdqz_derived");
           }


      else if(TagNamesToPlot[i] == "vsdqd"){
 	SimuPlot.plot_xy(Plot_t, Vs_dqd, "vsdqd_derived");
       }
      else if(TagNamesToPlot[i] == "vsdqq"){
 	SimuPlot.plot_xy(Plot_t, Vs_dqq, "vsdqq_derived");
       }
      else if(TagNamesToPlot[i] == "vsdqz"){
     	SimuPlot.plot_xy(Plot_t, Vs_dqz, "vsdqz_derived");
           }
      else if(TagNamesToPlot[i] == "vssdqd"){
 	SimuPlot.plot_xy(Plot_t, Vs_sdqd, "vssdqd_derived");
       }
      else if(TagNamesToPlot[i] == "vssdqq"){
 	SimuPlot.plot_xy(Plot_t, Vs_sdqq, "vssdqq_derived");
       }
      else if(TagNamesToPlot[i] == "vssdqz"){
     	SimuPlot.plot_xy(Plot_t, Vs_sdqz, "vssdqz_derived");
           }






      else if(TagNamesToPlot[i] == "v_n"){
       	SimuPlot.plot_xy(Plot_t, V_neutral, "v_n");
             }

      else if(TagNamesToPlot[i] == ""){
	break;
      }
    }

  }
}

       

void Is3_Ir6_1::OdeGroupMSolve(double dydt[], double dmdt[])
{
  //Note: This instance is the first of the group. As such, this
  //      is where the "group solve" of the individual 
  //      "dy/dt's" is performed.

		//Update the "R-value" vector which equates to  "Matrix" X "L-value".

	GroupOdeSolve_i.a_Static[0][7] = dmdt[0];
	GroupOdeSolve_i.a_Static[1][7] = dmdt[1];
	GroupOdeSolve_i.a_Static[2][7] = dmdt[2];
	GroupOdeSolve_i.a_Static[3][7] = 0;				//"stator_dcurrent_sum" = 0.
	GroupOdeSolve_i.a_Static[4][7] = dmdt[3];
	GroupOdeSolve_i.a_Static[5][7] = dmdt[4];
	GroupOdeSolve_i.a_Static[6][7] = dmdt[5];

		//Determine the "L-value" vector (which consists of a vector of "dy/dt's)
	GroupOdeSolve_i.PreSpiceFunction(0, FALSE);
	GroupOdeSolve_i.Gauss(FALSE);

		//Assign the "dy/dt's for each OdeObject in the group.

	dydt[0] = GroupOdeSolve_i.a[0][7];
	dydt[1] = GroupOdeSolve_i.a[1][7];
	dydt[2] = GroupOdeSolve_i.a[2][7];
	v_n      = GroupOdeSolve_i.a[3][7];
	dydt[3] = GroupOdeSolve_i.a[4][7];
	dydt[4] = GroupOdeSolve_i.a[5][7];
	dydt[5] = GroupOdeSolve_i.a[6][7];



}

void Is3_Ir6_1::OdeRValueUpdate(void)
{
	  is[0] = y;
}




// -----------------------------------------------------------------


// ---- Is3_Ir6_2  ----------------------------------------------------

Is3_Ir6_2::Is3_Ir6_2(void)
{

  OdeFuncName = ODE_FUNC_Is3_Ir6_2;
  LiteralName = "Is3_Ir6_2";

  //build the ODE Rvalue list.
  //(All variables are declared global.)

 

  PlotThisOutput = TRUE;
  Plot_Tag = "is2";
  DoProbes = TRUE;
  
}

Is3_Ir6_2::~Is3_Ir6_2(void)
{

}

double Is3_Ir6_2::OdeFunction(double y, double t)
{
  int i;
  //Note: This is within a "group" ODE so we are really returning for "dm/dt + v_n"

          //"vs[1] - v_n - Rs_res[1][1]*is[1] - omega_r *d_Msr[theta_r][1][0 to 2] x ir[0 to 2]"

#ifdef LINEAR_AMP_MODE
     //generating the voltage command directly through CtrlObject "VDqCmd" 
  vs[1] = pwm_sig[1] + .5*DC_BUS_VOLTAGE;
#else
  vs[1] = ShapeSquareWaveSource(((pwm_sig[1] > 0) ? DC_BUS_VOLTAGE : 0), SRC_SLEW_RATE ,t);
#endif
  d_Msr_ir = 0;
  for(i = 0; i < 3; i++)
  {
	  d_Msr_ir += InterpolateThetaRArray(d_Msr, 1, i) * ir[i];

  }

  //(Note: Unlike "App_Observer.hpp",  "v_n" is now part of the RValue.).
 // return(vs[1] - v_n - Rs_res[1][1] * y - omega_r *d_Msr_ir);
  return(vs[1] - Rs_res[1][1] * y - omega_r *d_Msr_ir);
}


void Is3_Ir6_2::RecordProbes(void)
{
  V_s2.push_back(vs[1] - v_n);
}




void Is3_Ir6_2::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
  int i;
  if(TagNamesToPlot[0] == ""){
	  return;
  }
  else{
    for(i = 0; i < 20; i++){
    	if(TagNamesToPlot[i] == "vs2"){
	SimuPlot.plot_xy(Plot_t, V_s2, "vs2");
      }
    	else if(TagNamesToPlot[i] == ""){
	break;
      }
    }

  }
}

void Is3_Ir6_2::OdeRValueUpdate(void)
{
	  is[1] = y;
}


// -----------------------------------------------------------------


// ---- Is3_Ir6_3  ----------------------------------------------------

Is3_Ir6_3::Is3_Ir6_3(void)
{

  OdeFuncName = ODE_FUNC_Is3_Ir6_3;
  LiteralName = "Is3_Ir6_3";

  //build the ODE Rvalue list.
  //(All variables are declared global.)

 

  PlotThisOutput = TRUE;
  Plot_Tag = "is3";
  DoProbes = TRUE;
  
}

Is3_Ir6_3::~Is3_Ir6_3(void)
{

}

double Is3_Ir6_3::OdeFunction(double y, double t)
{
  int i;
  //Note: This is within a "group" ODE so we are really returning for "dm/dt + v_n"

          //"vs[2] - v_n -  Rs_res[2][2]*is[2] - omega_r *d_Msr[theta_r][2][0 to 2] x ir[0 to 2]"

#ifdef LINEAR_AMP_MODE
     //generating the voltage command directly through CtrlObject "VDqCmd" 
  vs[2] = pwm_sig[2] + .5*DC_BUS_VOLTAGE;
#else
  vs[2] = ShapeSquareWaveSource(((pwm_sig[2]  > 0) ? DC_BUS_VOLTAGE : 0), SRC_SLEW_RATE ,t);
#endif
  d_Msr_ir = 0;
  for(i = 0; i < 3; i++)
  {
	  d_Msr_ir += InterpolateThetaRArray(d_Msr, 2, i) * ir[i];

  }

  //(Note: Unlike "App_Observer.hpp",  "v_n" is now part of the RValue.).
  //return(vs[2] - v_n - Rs_res[2][2] * y - omega_r *d_Msr_ir);
  return(vs[2]  - Rs_res[2][2] * y - omega_r *d_Msr_ir);
}


void Is3_Ir6_3::RecordProbes(void)
{
  V_s3.push_back(vs[2] - v_n);
}




void Is3_Ir6_3::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
  int i;
  if(TagNamesToPlot[0] == ""){
	  return;
  }
  else{
    for(i = 0; i < 20; i++){
    	if(TagNamesToPlot[i] == "vs3"){
	SimuPlot.plot_xy(Plot_t, V_s3, "vs3");
      }
    	else if(TagNamesToPlot[i] == ""){
	break;
      }
    }

  }
}

void Is3_Ir6_3::OdeRValueUpdate(void)
{
	  is[2] = y;
}

// -----------------------------------------------------------------



// ----  Is3_Ir6_4  ----------------------------------------------------

Is3_Ir6_4::Is3_Ir6_4(void)
{

  OdeFuncName = ODE_FUNC_Is3_Ir6_4;
  LiteralName = "Is3_Ir6_4";



  //build the ODE Rvalue list.
  //(All variables are declared global.)



  PlotThisOutput = TRUE;
  Plot_Tag = "ir1";
  DoProbes = TRUE;

}

Is3_Ir6_4::~Is3_Ir6_4(void)
{

}

double Is3_Ir6_4::OdeFunction(double y, double t)
{
  int i;
  //Note: This is within a "group" ODE so we are really returning for "dm/dt + v_n"

          //"0 - Rr_res[0][0]*ir[0]  -  Rr_res[0][1]*ir[1]  -  Rr_res[0][2]*ir[2]  - omega_r *d_Msr[theta_r][0 to 2][0] x is[0 to 2]"


  d_Msr_is = 0;
  for(i = 0; i < 3; i++)
  {
	  d_Msr_is += InterpolateThetaRArray(d_Msr, i, 0) * is[i];

  }

  //(Note: "v_n" is really part of the LValue when we are doing the calculations).
  return(0 - Rr_res[0][0] * y  -  Rr_res[0][1]*ir[1]  -  Rr_res[0][2] * ir[2] - omega_r *d_Msr_is);
}


void Is3_Ir6_4::RecordProbes(void)
{
  V_r1.push_back( Rr_res[0][0] * y  +  Rr_res[0][1]*ir[1]  + Rr_res[0][2] * ir[2] + omega_r *d_Msr_is);
}




void Is3_Ir6_4::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
  int i;
  if(TagNamesToPlot[0] == ""){
	  return;
  }
  else{
    for(i = 0; i < 20; i++){
    	if(TagNamesToPlot[i] == "vr1"){
	SimuPlot.plot_xy(Plot_t, V_r1, "vr1");
      }
    	else if(TagNamesToPlot[i] == ""){
	break;
      }
    }

  }
}

void Is3_Ir6_4::OdeRValueUpdate(void)
{
	ir[0] = y;
}

// -----------------------------------------------------------------




// ----  Is3_Ir6_5  ----------------------------------------------------

Is3_Ir6_5::Is3_Ir6_5(void)
{

  OdeFuncName = ODE_FUNC_Is3_Ir6_5;
  LiteralName = "Is3_Ir6_5";

  //build the ODE Rvalue list.
  //(All variables are declared global.)



  PlotThisOutput = TRUE;
  Plot_Tag = "ir2";
  DoProbes = TRUE;

}

Is3_Ir6_5::~Is3_Ir6_5(void)
{

}

double Is3_Ir6_5::OdeFunction(double y, double t)
{
  int i;
  //Note: This is within a "group" ODE so we are really returning for "dm/dt + v_n"

  	  	  //"0 - Rr_res[1][0]*ir[0]  -  Rr_res[1][1]*ir[1]  -  Rr_res[1][2]*ir[2]  - omega_r *d_Msr[theta_r][0 to 2][1] x is[0 to 2]"


  d_Msr_is = 0;
  for(i = 0; i < 3; i++)
  {
	  d_Msr_is += InterpolateThetaRArray(d_Msr, i, 1) * is[i];

  }

  //(Note: "v_n" is really part of the LValue when we are doing the calculations).
  return(0 - Rr_res[1][0]*ir[0]  -  Rr_res[1][1]*y  -  Rr_res[1][2]*ir[2] - omega_r *d_Msr_is);
}


void Is3_Ir6_5::RecordProbes(void)
{
  V_r2.push_back( Rr_res[1][0]*ir[0]  +  Rr_res[1][1]*y  +  Rr_res[1][2]*ir[2] + omega_r *d_Msr_is);
}




void Is3_Ir6_5::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
  int i;
  if(TagNamesToPlot[0] == ""){
	  return;
  }
  else{
    for(i = 0; i < 20; i++){
    	if(TagNamesToPlot[i] == "vr2"){
	SimuPlot.plot_xy(Plot_t, V_r2, "vr2");
      }
      else if(TagNamesToPlot[i] == ""){
	break;
      }
    }

  }
}

void Is3_Ir6_5::OdeRValueUpdate(void)
{
	  ir[1] = y;
}

// -----------------------------------------------------------------



// ----  Is3_Ir6_6  ----------------------------------------------------

Is3_Ir6_6::Is3_Ir6_6(void)
{

  OdeFuncName = ODE_FUNC_Is3_Ir6_6;
  LiteralName = "Is3_Ir6_6";

  //build the ODE Rvalue list.
  //(All variables are declared global.)



  PlotThisOutput = TRUE;
  Plot_Tag = "ir3";
  DoProbes = TRUE;

}

Is3_Ir6_6::~Is3_Ir6_6(void)
{

}

double Is3_Ir6_6::OdeFunction(double y, double t)
{
  int i;
  //Note: This is within a "group" ODE so we are really returning for "dm/dt + v_n"

  	  	  //"0 - Rr_res[2][1]*ir[1]  -  Rr_res[2][2]*ir[2]  -  Rr_res[2][0]*ir[0]  - omega_r *d_Msr[theta_r][0 to 2][2] x is[0 to 2]"


  d_Msr_is = 0;
  for(i = 0; i < 3; i++)
  {
	  d_Msr_is += InterpolateThetaRArray(d_Msr, i, 2) * is[i];

  }

  //(Note: "v_n" is really part of the LValue when we are doing the calculations).
  return(0 - Rr_res[2][1]*ir[1]  -  Rr_res[2][2]*y  -  Rr_res[2][0]*ir[0] - omega_r *d_Msr_is);
}


void Is3_Ir6_6::RecordProbes(void)
{
  V_r3.push_back( Rr_res[2][1]*ir[1]  +  Rr_res[2][2]*y  +  Rr_res[2][0]*ir[0] + omega_r *d_Msr_is);
}




void Is3_Ir6_6::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
  int i;
  if(TagNamesToPlot[0] == ""){
	  return;
  }
  else{
    for(i = 0; i < 20; i++){
    	if(TagNamesToPlot[i] == "vr3"){
	SimuPlot.plot_xy(Plot_t, V_r3, "vr3");
      }
    	else if(TagNamesToPlot[i] == ""){
	break;
      }
    }

  }
}

void Is3_Ir6_6::OdeRValueUpdate(void)
{
	ir[2] = y;
}

// -----------------------------------------------------------------


// ---- Omega  ----------------------------------------------------

Omega::Omega(void)
{

  OdeFuncName = ODE_FUNC_Omega;
  LiteralName = "Omega";

  //build the ODE Rvalue list.
  //(All variables are declared global.)


  PlotThisOutput = TRUE;
  Plot_Tag = "omega_r";
  DoProbes = TRUE;

}

Omega::~Omega(void)
{

}

double Omega::OdeFunction(double y, double t)
{
	int i,j;
	//"(is[0 to 3] x d_Msr[theta_r][0 to 3]][0 to 5] x ir[0 to 5] )/ Jm"

	is_d_Msr_ir = 0;
	for(j = 0; j < 3; j++)
	{
		d_Msr_ir[j] = 0;
		for(i = 0; i < 3; i++)
		{
			d_Msr_ir[j] += InterpolateThetaRArray(d_Msr, j, i) * ir[i];

		}
		is_d_Msr_ir += is[j] * d_Msr_ir[j];
	}


	return((is_d_Msr_ir - Ti) / Jm);


}

void Omega::RecordProbes(void)
{
  Omega_s.push_back(omega_s);
}




void Omega::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
  int i;
  if(TagNamesToPlot[0] == ""){
	  return;
  }
  else{
    for(i = 0; i < 20; i++){
      if(TagNamesToPlot[i] == "omega_s"){
	SimuPlot.plot_xy(Plot_t, Omega_s, "omega_s");
      }
      else if(TagNamesToPlot[i] == ""){
	break;
      }
    }

  }
}


void Omega::OdeRValueUpdate(void)
{
	omega_r =  y;
}

// -----------------------------------------------------------------

#else

// ---- Is_Ir_sdq_1  ----------------------------------------------------

Is_Ir_sdq_1::Is_Ir_sdq_1(void)
{

  OdeFuncName = ODE_FUNC_Is_Ir_sdq_1;
  LiteralName = "Is_Ir_sdq_1";


  //this object marks the beginning of a "group solve" of
  //nine objects.
  GroupSolve = 1;
  NumberOfGrpOdes = 4;

  //build the ODE Rvalue list.
  //(All variables are declared global.)



  PlotThisOutput = TRUE;
  Plot_Tag = "issdqd";
  DoProbes = TRUE;

}

Is_Ir_sdq_1::~Is_Ir_sdq_1(void)
{

}

double Is_Ir_sdq_1::OdeFunction(double y, double t)
{
  int i;


   //"vs_sdq_d  -  is_sdq_d * Rsync0s[0][0]  - omega_r * ( is_sdq_q * Qsync0s[0][1]  +  ir_sdq_q * Qsyncsr[0][1] )	-
   //	  	  	  	  	  	  	  	  	  	  			  (omega_r - omega_s) * (is_sdq_q * Qsyncd0s[0][1] + ir_sdq_q * Qsyncdsr[0][1])"




  return(vs_sdq_d  -  y * Rsync0s[0][0]  - omega_r * ( is_sdq_q * Qsync0s[0][1]  +  ir_sdq_q * Qsyncsr[0][1] )	-
		  	  	  	  	  	  	  	  	  	  	  	  (omega_r - omega_s) * (is_sdq_q * Qsyncd0s[0][1] + ir_sdq_q * Qsyncdsr[0][1]) );
}


void Is_Ir_sdq_1::OdeGroupMSolve(double dydt[], double dmdt[])
{
  //Note: This instance is the first of the group. As such, this
  //      is where the "group solve" of the individual
  //      "dy/dt's" is performed.

		//Update the "R-value" vector which equates to  "Matrix" X "L-value".

	GroupOdeSolve_i.a_Static[0][4] = dmdt[0];
	GroupOdeSolve_i.a_Static[1][4] = dmdt[1];
	GroupOdeSolve_i.a_Static[2][4] = dmdt[2];
	GroupOdeSolve_i.a_Static[3][4] = dmdt[3];


		//Determine the "L-value" vector (which consists of a vector of "dy/dt's)
	GroupOdeSolve_i.PreSpiceFunction(0, FALSE);
	GroupOdeSolve_i.Gauss(FALSE);

		//Assign the "dy/dt's for each OdeObject in the group.

	dydt[0] = GroupOdeSolve_i.a[0][4];
	dydt[1] = GroupOdeSolve_i.a[1][4];
	dydt[2] = GroupOdeSolve_i.a[2][4];
	dydt[3] = GroupOdeSolve_i.a[3][4];




}

void Is_Ir_sdq_1::RecordProbes(void)
{

	  //Un-comment only those to be plotted.

	Vs_dq_d.push_back(vs_dq_d);
	Vs_dq_q.push_back(vs_dq_q);
	Vs_dq_z.push_back(vs_dq_z);
	Vs_sdq_d.push_back(vs_sdq_d);
	Vs_sdq_q.push_back(vs_sdq_q);
	Vs_sdq_z.push_back(vs_sdq_z);

	is_dq_d =  is_dq_d_inv_derived;
	Is_inv_dqd.push_back(is_dq_d);

	is_dq_q = is_dq_q_inv_derived;
	Is_inv_dqq.push_back(is_dq_q);

	is_dq_z = is_dq_z_inv_derived;
	Is_inv_dqz.push_back(is_dq_z);

	is[0] =  is1_inv_derived;
	Is1_inv.push_back(is[0]);

	is[1] =  is2_inv_derived;
	Is2_inv.push_back(is[1]);

	is[2] =  is3_inv_derived;
	Is3_inv.push_back(is[2]);








}

void Is_Ir_sdq_1::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
	  int i;
	  if(TagNamesToPlot[0] == ""){
		  return;
	  }
	  else{
	    for(i = 0; i < 20; i++){
	    	if(TagNamesToPlot[i] == "vsdqd"){
	    		SimuPlot.plot_xy(Plot_t, Vs_dq_d, "vsdqd");
	      }
	    	else if(TagNamesToPlot[i] == "vsdqq"){
	    		SimuPlot.plot_xy(Plot_t, Vs_dq_q, "vsdqq");
	      }
	    	else if(TagNamesToPlot[i] == "vsdqz"){
	    		SimuPlot.plot_xy(Plot_t, Vs_dq_z, "vsdqz");
	      }
	    	else if(TagNamesToPlot[i] == "vssdqd"){
	    		SimuPlot.plot_xy(Plot_t, Vs_sdq_d, "vssdqd");
	      }
	    	else if(TagNamesToPlot[i] == "vssdqq"){
	    		SimuPlot.plot_xy(Plot_t, Vs_sdq_q, "vssdqq");
	      }
	    	else if(TagNamesToPlot[i] == "vssdqz"){
	    		SimuPlot.plot_xy(Plot_t, Vs_sdq_z, "vssdqz");
	      }

	    	else if(TagNamesToPlot[i] == "isdqd"){
	    		SimuPlot.plot_xy(Plot_t, Is_inv_dqd, "isdqd_derived");
	    	}
	    	else if(TagNamesToPlot[i] == "isdqq"){
	    		SimuPlot.plot_xy(Plot_t, Is_inv_dqq, "isdqq_derived");
	    	}
	    	else if(TagNamesToPlot[i] == "isdqz"){
	    		SimuPlot.plot_xy(Plot_t, Is_inv_dqz, "isdqz_derived");
	    	}

	    	else if(TagNamesToPlot[i] == "is1"){
	    		SimuPlot.plot_xy(Plot_t, Is1_inv, "is1_derived");
	    	}
	    	else if(TagNamesToPlot[i] == "is2"){
	    	    		SimuPlot.plot_xy(Plot_t, Is2_inv, "is2_derived");
	    	}
	    	else if(TagNamesToPlot[i] == "is3"){
	    	    		SimuPlot.plot_xy(Plot_t, Is3_inv, "is3_derived");
	    	}



	    	else if(TagNamesToPlot[i] == ""){
		break;
	      }
	    }

	  }

}


void Is_Ir_sdq_1::OdeRValueUpdate(void)
{
	is_sdq_d = y;
}


// -----------------------------------------------------------------

// ---- Is_Ir_sdq_2  ----------------------------------------------------

Is_Ir_sdq_2::Is_Ir_sdq_2(void)
{

  OdeFuncName = ODE_FUNC_Is_Ir_sdq_2;
  LiteralName = "Is_Ir_sdq_2";



  //build the ODE Rvalue list.
  //(All variables are declared global.)



  PlotThisOutput = TRUE;
  Plot_Tag = "issdqq";
  DoProbes = TRUE;

}

Is_Ir_sdq_2::~Is_Ir_sdq_2(void)
{

}

double Is_Ir_sdq_2::OdeFunction(double y, double t)
{
  int i;


   //"vs_sdq_q  -  is_sdq_q * Rsync0s[1][1]  - omega_r * ( is_sdq_d * Qsync0s[1][0]  +  ir_sdq_d * Qsyncsr[1][0] ) -
  //															(omega_r - omega_s) * (is_sdq_d * Qsyncd0s[1][0] + ir_sdq_d * Qsyncdsr[1][0])"




  return(vs_sdq_q  -  y * Rsync0s[1][1]  - omega_r * ( is_sdq_d * Qsync0s[1][0]  +  ir_sdq_d * Qsyncsr[1][0] )  -
		  	  	  	  	  	  	  	  	  	  	  	  	  	  	  (omega_r - omega_s) * (is_sdq_d * Qsyncd0s[1][0] + ir_sdq_d * Qsyncdsr[1][0]));
}

void Is_Ir_sdq_2::PostOdeFunction(double t)
{
		//This is not coupled to the the set of ODE equations but can be observed. If vs[0], vs[1], and vs[2] are balanced, this will evaluate to zero.
		is_sdq_z  = vs_sdq_z / Rsync0s[2][2];

}

void Is_Ir_sdq_2::OdeRValueUpdate(void)
{
	is_sdq_q = y;
}


// -----------------------------------------------------------------



// ---- Is_Ir_sdq_3  ----------------------------------------------------

Is_Ir_sdq_3::Is_Ir_sdq_3(void)
{

  OdeFuncName = ODE_FUNC_Is_Ir_sdq_3;
  LiteralName = "Is_Ir_sdq_3";



  //build the ODE Rvalue list.
  //(All variables are declared global.)



  PlotThisOutput = TRUE;
  Plot_Tag = "irsdqd";
  DoProbes = TRUE;

}

Is_Ir_sdq_3::~Is_Ir_sdq_3(void)
{

}

double Is_Ir_sdq_3::OdeFunction(double y, double t)
{
  int i;


   //"0 -  ir_sdq_d * Rsyncr[0][0]    -   (omega_r - omega_s) *  (is_sdq_q * Qsyncdsr_t[0][1] + ir_sdq_q * Qsyncdr[0][1])"




  return(0 -  y * Rsyncr[0][0]    -   (omega_r - omega_s) *  (is_sdq_q * Qsyncdsr_t[0][1] + ir_sdq_q * Qsyncdr[0][1]));
}

void Is_Ir_sdq_3::RecordProbes(void)
{
	Vr_sdq_d.push_back(ir_sdq_d * Rsyncr[0][0]  + (omega_r - omega_s) *  (is_sdq_q * Qsyncdsr_t[0][1] + ir_sdq_q * Qsyncdr[0][1]));
	Vr_sdq_q.push_back(ir_sdq_q * Rsyncr[1][1]  + (omega_r - omega_s) *  (is_sdq_d * Qsyncdsr_t[1][0] + ir_sdq_d * Qsyncdr[1][0]));
	Vr_sdq_z.push_back(ir_sdq_z * Rsyncr[2][2]);


}

void Is_Ir_sdq_3::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
	  int i;
	  if(TagNamesToPlot[0] == ""){
		  return;
	  }
	  else{
	    for(i = 0; i < 20; i++){
	    	if(TagNamesToPlot[i] == "vrsdqd"){
	    		SimuPlot.plot_xy(Plot_t, Vr_sdq_d, "vrsdqd");
	      }
	    	else if(TagNamesToPlot[i] == "vrsdqq"){
	    		SimuPlot.plot_xy(Plot_t, Vr_sdq_q, "vrsdqq");
	      }
	    	else if(TagNamesToPlot[i] == "vrsdqz"){
	    		SimuPlot.plot_xy(Plot_t, Vr_sdq_z, "vrsdqz");
	      }
	    	else if(TagNamesToPlot[i] == ""){
		break;
	      }
	    }

	  }

}

void Is_Ir_sdq_3::OdeRValueUpdate(void)
{
	ir_sdq_d = y;
}


// -----------------------------------------------------------------


// ---- Is_Ir_sdq_4  ----------------------------------------------------

Is_Ir_sdq_4::Is_Ir_sdq_4(void)
{

  OdeFuncName = ODE_FUNC_Is_Ir_sdq_4;
  LiteralName = "Is_Ir_sdq_4";



  //build the ODE Rvalue list.
  //(All variables are declared global.)



  PlotThisOutput = TRUE;
  Plot_Tag = "irsdqq";
  DoProbes = TRUE;

}

Is_Ir_sdq_4::~Is_Ir_sdq_4(void)
{

}

double Is_Ir_sdq_4::OdeFunction(double y, double t)
{
  int i;


   //"0 -  ir_sdq_q * Rsyncr[1][1]    -   (omega_r - omega_s) *  (is_sdq_d * Qsyncdsr_t[1][0] + ir_sdq_d * Qsyncdr[1][0])"




  return(0 -  y * Rsyncr[1][1]    -   (omega_r - omega_s) *  (is_sdq_d * Qsyncdsr_t[1][0] + ir_sdq_d * Qsyncdr[1][0]));
}



void Is_Ir_sdq_4::OdeRValueUpdate(void)
{
	ir_sdq_q = y;
}


// -----------------------------------------------------------------



// ---- Ir_sdq_z  ----------------------------------------------------

Ir_sdq_z::Ir_sdq_z(void)
{

  OdeFuncName = ODE_FUNC_Ir_sdq_z;
  LiteralName = "Ir_sdq_z";



  //build the ODE Rvalue list.
  //(All variables are declared global.)



  PlotThisOutput = TRUE;
  Plot_Tag = "irsdqz";
  DoProbes = TRUE;

}

Ir_sdq_z::~Ir_sdq_z(void)
{

}

double Ir_sdq_z::OdeFunction(double y, double t)
{
  int i;


   //"0 -  ir_sdq_z * Rsyncr[2][2]"




  return(0 -  y * Rsyncr[2][2]	);
}



void Ir_sdq_z::OdeRValueUpdate(void)
{
	ir_sdq_z = y;
}


// -----------------------------------------------------------------




// ---- Omega  ----------------------------------------------------

Omega::Omega(void)
{

  OdeFuncName = ODE_FUNC_Omega;
  LiteralName = "Omega";

  //build the ODE Rvalue list.
  //(All variables are declared global.)


  PlotThisOutput = TRUE;
  Plot_Tag = "omega_r";
  DoProbes = TRUE;

}

Omega::~Omega(void)
{

}

double Omega::OdeFunction(double y, double t)
{

	//"(.5 * is_sdq_d * ir_sdq_q * Ssyncsr[0][1] + .5 * is_sdq_q *  ir_sdq_d * Ssyncsr[1][0] + .5 * ir_sdq_d *  is_sdq_q * Ssyncsr_t[0][1] + .5 * ir_sdq_q * is_sdq_d * Ssyncsr_t[1][0]  - Ti)  / Jm"

	return((.5 * is_sdq_d * ir_sdq_q * Ssyncsr[0][1] + .5 * is_sdq_q *  ir_sdq_d * Ssyncsr[1][0] + .5 * ir_sdq_d *  is_sdq_q * Ssyncsr_t[0][1] + .5 * ir_sdq_q * is_sdq_d * Ssyncsr_t[1][0]  - Ti)  / Jm);


}

void Omega::RecordProbes(void)
{
  Omega_s.push_back(omega_s);
}




void Omega::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
  int i;
  if(TagNamesToPlot[0] == ""){
	  return;
  }
  else{
    for(i = 0; i < 20; i++){
      if(TagNamesToPlot[i] == "omega_s"){
	SimuPlot.plot_xy(Plot_t, Omega_s, "omega_s");
      }
      else if(TagNamesToPlot[i] == ""){
	break;
      }
    }

  }
}

void Omega::OdeRValueUpdate(void)
{
	omega_r =  y;
}

// -----------------------------------------------------------------





#endif


// ---- Theta  ----------------------------------------------------

Theta::Theta(void)
{

  OdeFuncName = ODE_FUNC_Theta;
  LiteralName = "Theta";    

  //build the ODE Rvalue list.
  //(All variables are declared global.)



  PlotThisOutput = TRUE;
  Plot_Tag = "theta_r";

}

Theta::~Theta(void)
{

}

double Theta::OdeFunction(double y, double t)
{
 

	//omega_r;
	return(omega_r);

}

void Theta::OdeRValueUpdate(void)
{
	theta_r = y;
}


// -----------------------------------------------------------------


// ******************************************************************




// ***** CtrlObject Functions ***************************************


// ** (Control of D/Q voltage command) **


// ---- VDqCmd  ---------------------------------------------------

VDqCmd::VDqCmd(void)
{

  CtrlFuncName = CTRL_FUNC_VDqCmd;
  LiteralName = "VDqCmd";

  // Refering to Figure 11 of "SpaceVector_PWM_Inverter.pdf", we set  up the reference constructs.
  // The form here is:
  //
  //       SVTable[<sector_index>][<phase>] = <reference construct>
  //
  //                    where
  //                        <sector_index> == SectorNumber - 1
  //
  //                        <phase> == 0 -> "A", 1 -> "B", 2 -> "C"
  //
  //                        <reference construct> == TIME_T1_T2 -> "T1 + T2", TIME_T1 -> "T1", TIME_T2 -> "T2", TIME_NONE -> 0
  //                                                 (for non-clamped SVPWM, add ".5*T0" to all references.
  //

  // Definitions here are for minus side "clamped" SVPWM. For regular SVPWM, add ".5*TO" to all reference values.
  SVTable[0][0] = TIME_T1_T2;
  SVTable[0][1] = TIME_T2;
  SVTable[0][2] = TIME_NONE;
  SVTable[1][0] = TIME_T1;
  SVTable[1][1] = TIME_T1_T2;
  SVTable[1][2] = TIME_NONE;
  SVTable[2][0] = TIME_NONE;
  SVTable[2][1] = TIME_T1_T2;
  SVTable[2][2] = TIME_T2;
  SVTable[3][0] = TIME_NONE;
  SVTable[3][1] = TIME_T1;
  SVTable[3][2] = TIME_T1_T2;
  SVTable[4][0] = TIME_T2;
  SVTable[4][1] = TIME_NONE;
  SVTable[4][2] = TIME_T1_T2;
  SVTable[5][0] = TIME_T1_T2;
  SVTable[5][1] = TIME_NONE;
  SVTable[5][2] = TIME_T1;




  //until we can simulate DC bus ripple voltage, we set for a constant value.
  v_bus = DC_BUS_VOLTAGE;



  DoProbes = TRUE;

}

VDqCmd::~VDqCmd(void)
{



}



void VDqCmd::CtrlFunction(double t)
{
  int i;

  //(Note: "y" is not used in this CTRL. We use this CTRL to send command
  //       to the "PwmA", "PwmB" and "PwmC" CTRL's directly.


  //For simulation mode, we generate space vector PWM references.

//#define CONSTANT_VDQ_COMMAND
#ifdef CONSTANT_VDQ_COMMAND

  //For now, we provide constant commands for magnitude and angle.
  //These will come form seperate CTRL later.
  vcmd_mag = 10.0;
  vcmd_ang = PI/2;   //valid values are  +/-PI/2 <= vcmd_ang < +/-PI (pure "q" to pure "d")
#else

  //#define FSF_CTRL_VDQ_COMMAND
#ifdef FSF_CTRL_VDQ_COMMAND

  //"vcmd_mag" and "vcmd_ang" will be generated from signals "vd" and "vq", the command voltages
  //originating form CtrlObject 'FSFCtrl".

#else



  //This is a "Space Vector" command reference test....

  //VDQ command is generated by "RefGen" CtrlObject. This is a test to see
  //"theta_r", "omega_r", and "alpha" tracks "thedad", "omegad", and "alphad". Also if "id" and "iq" (generated in
  //"FSFCtrl" tracks "idd" and "idq"

  vcmd_mag = sqrt(vdd*vdd + vqd*vqd);

  if(vqd != 0){

     if(vqd >= 0)
       vcmd_ang = PI/2.0;
     else
       vcmd_ang = - PI/2.0;


     vcmd_ang -= atan(vdd/vqd);

  }
  else{
    vcmd_ang = PI/2.0;
  }


#endif

#endif


  //#define DEBUG_SPACE_VECTOR_CONTROL   //un-comment this to debug function "SpaceVectorControl()"
#ifdef DEBUG_SPACE_VECTOR_CONTROL
  //force feedback position to sweep a number of cycles so
  //that we may view "V_xo_local[]"
  theta_r = PI*t*10;   //specify "- PI*t*10" for minus test.
#endif

  //generate the references.
  SpaceVectorControl();

#ifdef DEBUG_SPACE_VECTOR_CONTROL
  for(i = 0; i < 3; i++){
    //transfer over to debug buffers.
    V_xo_debug[i] = V_xo_local[i];
    //keep the actual commands zero to prevent the simulation from running away.
    V_xo_local[i] = 0;
  }

#endif


}

void VDqCmd::RecordProbes(void)
{

#ifndef FREQUENCY_SWEEP_MODE

#ifdef DEBUG_SPACE_VECTOR_CONTROL

  VCmd_a.push_back(V_xo_debug[0]);
  VCmd_b.push_back(V_xo_debug[1]);
#ifdef RECORD_ALL_PROBES
  VCmd_c.push_back(V_xo_debug[2]);
#endif

#else

  VCmd_a.push_back(V_xo_local[0]);
  VCmd_b.push_back(V_xo_local[1]);
#ifdef RECORD_ALL_PROBES
  VCmd_c.push_back(V_xo_local[2]);
#endif


#endif

  VCmd_mag.push_back(vcmd_mag);
  VCmd_ang.push_back(vcmd_ang);

#endif
}

void VDqCmd::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
#ifndef FREQUENCY_SWEEP_MODE
  int i;
  if(TagNamesToPlot[0] == ""){
    SimuPlot.plot_xy(Plot_t, VCmd_a, "VCmd_a");
    SimuPlot.plot_xy(Plot_t, VCmd_b, "VCmd_b");
    SimuPlot.plot_xy(Plot_t, VCmd_c, "VCmd_c");
    SimuPlot.plot_xy(Plot_t, VCmd_mag, "VCmd_mag");
    SimuPlot.plot_xy(Plot_t, VCmd_ang, "VCmd_ang");
  }
  else{
    for(i = 0; i < 20; i++){
      if(TagNamesToPlot[i] == "VCmd_a"){
	SimuPlot.plot_xy(Plot_t, VCmd_a, "VCmd_a");
      }
      else if(TagNamesToPlot[i] == "VCmd_b"){
	SimuPlot.plot_xy(Plot_t, VCmd_b, "VCmd_b");
      }
      else if(TagNamesToPlot[i] == "VCmd_c"){
	SimuPlot.plot_xy(Plot_t, VCmd_c, "VCmd_c");
      }
      else if(TagNamesToPlot[i] == "VCmd_mag"){
	SimuPlot.plot_xy(Plot_t, VCmd_mag, "VCmd_mag");
      }
      else if(TagNamesToPlot[i] == "VCmd_ang"){
	SimuPlot.plot_xy(Plot_t, VCmd_ang, "VCmd_ang");
      }


    }
  }
#endif

}

void  VDqCmd::SrcRValueUpdate(void)
{
	V_xo[0] = V_xo_local[0];
	V_xo[1] = V_xo_local[1];
	V_xo[2] = V_xo_local[2];

}

void VDqCmd::OdeRValueUpdate(void)
{

#ifdef LINEAR_AMP_MODE

#ifdef TERMINAL_REF_PLANE_SIMULATION

 	pwm_sig[0] = V_xo_local[0];
 	pwm_sig[1] = V_xo_local[1];
 	pwm_sig[2] = V_xo_local[2];

#else

 	vs[0] = V_xo_local[0];
 	vs[1] = V_xo_local[1];
 	vs[2] = V_xo_local[2];

 	vs_dq_d = vs_dq_d_derived;
 	vs_sdq_d = vs_sdq_d_derived;

 	vs_dq_q = vs_dq_q_derived;
 	vs_sdq_q = vs_sdq_q_derived;

 	vs_dq_z = vs_dq_z_derived;
 	vs_sdq_z = vs_sdq_z_derived;

#endif

#endif


}



void VDqCmd::SpaceVectorControl(void)
{
  int SectorNumber;
  int SectorIndex;
  double SectorAngle;
  double CtrlAngle;
  double T0, T1, T2;
  double Amplitude;
  double T_Z_Scaled;
  int i;



#ifdef TRIANGLE_REF_MODE
  //This is a "Triangle" command reference test....

#ifdef FREQUENCY_SWEEP_MODE

  CtrlAngle = thetad;

#ifdef LINEAR_AMP_MODE
  //Here we generate analog voltage commands directly....

  Amplitude = omegad;

  V_xo_local[0] = Amplitude*.5*DC_BUS_VOLTAGE*cos(.5*CtrlAngle)/VO_TRAJ;
  V_xo_local[1] = Amplitude*.5*DC_BUS_VOLTAGE*cos(.5*CtrlAngle - 2*PI/3)/VO_TRAJ;
  V_xo_local[2] = Amplitude*.5*DC_BUS_VOLTAGE*cos(.5*CtrlAngle - 4*PI/3)/VO_TRAJ;

#else

  Amplitude = PWM_GAIN*omegad;

  V_xo_local[0] = Amplitude*cos(.5*CtrlAngle)/VO_TRAJ + PWM_OFFSET;
  V_xo_local[1] = Amplitude*cos(.5*CtrlAngle - 2*PI/3)/VO_TRAJ + PWM_OFFSET;
  V_xo_local[2] = Amplitude*cos(.5*CtrlAngle - 4*PI/3)/VO_TRAJ + PWM_OFFSET;

#endif
  	  //These are the electrical stator position and velocities variables applied to the synchronous D/Q equations.
      //which compensates for the scaling of "thetad" done above
  theta_s = .5 * thetad;
  omega_s = .5 * omegad;  //(because thetad was scaled, we must also scale omegad.)


#else

  CtrlAngle = Nr*theta_r;

#ifdef LINEAR_AMP_MODE
  //Here we generate analog voltage commands directly....

  Amplitude = (2.0/3.0);

  V_xo_local[0] = Amplitude*(vdd*cos(CtrlAngle) - vqd*sin(CtrlAngle));
  V_xo_local[1] = Amplitude*(vdd*cos(CtrlAngle - 2*PI/3) - vqd*sin(CtrlAngle - 2*PI/3));
  V_xo_local[2] = Amplitude*(vdd*cos(CtrlAngle - 4*PI/3) - vqd*sin(CtrlAngle - 4*PI/3));

#else

  Amplitude = (2.0/3.0)*PWM_GAIN;

  V_xo_local[0] = Amplitude*(vdd*cos(CtrlAngle) - vqd*sin(CtrlAngle)) / v_bus;
  V_xo_local[1] = Amplitude*(vdd*cos(CtrlAngle - 2*PI/3) - vqd*sin(CtrlAngle - 2*PI/3)) / v_bus;
  V_xo_local[2] = Amplitude*(vdd*cos(CtrlAngle - 4*PI/3) - vqd*sin(CtrlAngle - 4*PI/3)) / v_bus;

#endif

#endif

#else

  //This is a "Space Vector" command reference test....

     //for now, only "theta_r" and "vcmd_ang" determine the control angle. Position correction due to "omega_r"
     //and "alpha" will be added later.
  CtrlAngle = theta_r * Nr + vcmd_ang;
  SectorIndex = (int) (CtrlAngle / SECTOR_ANGLE);

  //Note: "SpaceVector_PWM_Inverter.pdf" specifies the the range of "SectorAngle" between 0 and 60 degrees.
  //      This is wronge, the range should be 0 to 360 degrees.
  if(CtrlAngle >= 0){
    SectorNumber = SectorIndex % 6 + 1;
    SectorAngle = CtrlAngle - (double) (SectorIndex / 6) * SECTOR_ANGLE * 6.0;
  }
  else{
    SectorNumber = 6 + SectorIndex % 6;
    SectorAngle = CtrlAngle + (double) (6 - SectorIndex / 6) * SECTOR_ANGLE * 6.0;
  }

  T_Z_Scaled = (2.0 / 3.0) * T_Z;

  T1 = SQRT_3 * T_Z_Scaled * vcmd_mag * sin((PI * (double) SectorNumber / 3.0) - SectorAngle) / v_bus;
  T2 = SQRT_3 * T_Z_Scaled * vcmd_mag * sin(SectorAngle - (SectorNumber - 1) * PI / 3.0) / v_bus;
  T0 = T_Z_Scaled - T1 - T2;
  //assign references to each phase,
  for(i = 0; i < 3; i++){

    switch(SVTable[SectorNumber-1][i]){
    case TIME_NONE:
      V_xo_local[i] = 0;
      break;
    case TIME_T1:
      V_xo_local[i] = T1;
      break;
    case TIME_T2:
      V_xo_local[i] = T2;
      break;
    case TIME_T1_T2:
      V_xo_local[i] = T1 + T2;
      break;
    }

  }


#endif






}




// ---------------------------------------------------------------



// ---- RefGen  ---------------------------------------------------

RefGen::RefGen(void)
{


  CtrlFuncName = CTRL_FUNC_RefGen;
  LiteralName = "RefGen";

    //We want this "RefGen" to immediately update "VDqCmd" and other selected CtrlObject's ahead of it after it's
    //control function is executed.
  DoImmedCtrlUpdate = TRUE;

  //build the CTRL Rvalue list
  //(All variables are declared global.)






  DoProbes = TRUE;


}

RefGen::~RefGen(void)
{



}

// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------

		//Copied from the output generated by "../BDFM-Dissertation-2005-Tests/Verify_Msync_inverse_Eq_8_11/Verify_Msync_inverse_Eq_8_11.m"

double Msync0s_ir[2][2] = {
										 {3.525236178152328,   0.000000000000000},
										 {0.000000000000000,   3.525236178152328},
										};

double Msyncsr_ir[2][2] = {
										{-215.019870069509807,     0.000000000000000},
										{0.000000000000000,  -215.019870069509807},
							  	  	  };

double Msyncsr_t_ir[2][2] = {
											{-215.019870069509807,     0.000000000000000},
											{0.000000000000000,  -215.019870069509807},
								 	 	 };

double Msyncr_ir[2][2] =  {
										{4.07834311366690e+04,  -0.00000000000000e+00},
										{0.00000000000000e+00,   4.07834311366690e+04},
									  };

		//Based on the observation made for the equations derived above which takes note of the fact the in a balanced system, the zero sequence terms for the stator and rotor
	   // can be ignored, we extend the definitions for all other matrix's defined for the synchronous D/Q plane.

double Rsync0s_r[2][2] = {
										{2.72855			,0						},
										{0						,2.72855			},
								       };

double Rsyncr_r[2][2] = {
										{0.000125			,0						},
										{0						,0.000125			},
								     };

double Qsync0s_r[2][2] = {
											{0						,0.418313			},
											{-0.418313			,0						},
										};


double Qsyncsr_r[2][2] = {
											{0						,0.00220448		},
											{-0.00220448		,0						},
									  };


double Qsyncd0s_r[2][2] = {
											{0						,-0.418313			},
											{0.418313			,0						},
										 };


double Qsyncdsr_r[2][2] = {
											{0						,-0.00220448		},
											{0.00220448		,0						},
										};

double Qsyncdsr_t_r[2][2] = {
												{0						,-0.00220448		},
												{0.00220448		,0						},
										  };



double Qsyncdr_r[2][2] = {
											{0						,-3.61423e-05		},
											{3.61423e-05		,0						},
									   };



double Ssyncsr_r[2][2] = {
											{0						,0.00220448		},
											{-0.00220448		,0						},
									   };

double Ssyncsr_t_r[2][2] = {
											{0						,-0.00220448		},
											{0.00220448		,0						},
									  	  };


	// Refer to "../BDFM-Dissertation-2005-Tests/Verify_Msync_inverse_Eq_8_11/Verify_Msync_inverse_Eq_8_11.m", Section 8.2.2 "Control strategy 1: Speed Only Regulation"
    // page 213 of "Roberts...".and Equations 19 through 27 near line 973 of this file.


//	| d_is_sdq_d |          											{  | vs_sdq_d |      																									 																			 		 	  				   | is_sdq_d |  }
//	| d_is_sdq_q |        | Msync0s_ir 	    Msyncsr_ir |  {  | vs_sdq_q |			 {  | Rsync0s_r       0     |                                	  | Qsync0s_r    Qsyncsr_r  |									         | Qsyncd0s_r     Qsyncdsr_r  |  }   | is_sdq_q |  }
//	| d_ir_sdq_d |     =  | Msyncsr_t_ir   Msyncr_ir   |  {  |     0        |  	-    {  |     0          Rsyncr_r |    -    omega_r    	   *  |      0               0      		 |    -  (omega_r - omega_s) *   | Qsyncdsr_t_r	 Qsyncdr_r    |  }   | ir_sdq_d |   }    Eq. (28)
//	| d_ir_sdq_q |           											{  |     0        | 																																													 		  	 				   | ir_sdq_q |   }


double Msync_r_1[4][4] = {
											{ 3.525236178152328   		,0.000000000000000	 		,-215.019870069509807    , 0.000000000000000				 },
											{ 0.000000000000000   		,3.525236178152328   		,0.000000000000000   	   ,-215.019870069509807			 },
											{ -215.019870069509807  	,0.000000000000000	  		,4.07834311366690e+04    ,0.00000000000000e+00		     },
											{ 0.000000000000000   		,-215.019870069509807   	,0.00000000000000e+00    ,4.07834311366690e+04    		 },
									  };

// Msync_r_1 * Rsync_r = Rsync_rm
//
//	| 3.525236178152328   	0.000000000000000	 -215.019870069509807     0.000000000000000		 |  | 2.72855            0	       			   0			          0  				 |
//  | 0.000000000000000   	3.525236178152328     0.000000000000000   	  -215.019870069509807     |  | 0 						 2.72855           0	  				  0					 |
//	| -215.019870069509807  0.000000000000000	  4.07834311366690e+04   0.00000000000000e+00   |  | 0			             0					   0.000125		  0 				 |
//	| 0.000000000000000   -215.019870069509807   0.00000000000000e+00   4.07834311366690e+04   |  | 0					     0					   0	  				  0.000125	     |
//



double Rsync_rm[4][4] = {
										{3.525236178152328 * 2.72855		,0												  	,-215.019870069509807 * 0.000125   ,0														},
										{0													,3.525236178152328 * 2.72855	  	,0											 	 	  ,-215.019870069509807 * 0.000125	    },
										{-215.019870069509807 * 2.72855	,0													,4.07834311366690e+04 * 0.000125  ,0														},
										{0													,-215.019870069509807 * 2.72855	,0													  ,4.07834311366690e+04 * 0.000125      },
									};

// Msync_r_1 * Qsync_r = Qsync_rm
//
//	| 3.525236178152328   	0.000000000000000	 -215.019870069509807     0.000000000000000		 |  | 0			             0.418313		   0			          0.00220448  |
//  | 0.000000000000000   	3.525236178152328     0.000000000000000   	  -215.019870069509807     |  | -0.418313			 0			           -0.00220448	  0					 |
//	| -215.019870069509807  0.000000000000000	  4.07834311366690e+04   0.00000000000000e+00   |  | 0			             0					   0					  0 				 |
//	| 0.000000000000000   -215.019870069509807   0.00000000000000e+00   4.07834311366690e+04   |  | 0					     0					   0	  				  0				     |
//


double Qsync_rm[4][4] = {
										{ 0														,3.525236178152328 * 0.418313			,0 													    	,3.525236178152328 * 	0.00220448	 },
										{ 3.525236178152328 * (-0.418313)		,0														,3.525236178152328 * (-	0.00220448)  		,0													 	 },
										{ 0														,-215.019870069509807 * 0.418313		,0															,-215.019870069509807 * 0.00220448	 },
										{-215.019870069509807 * (-0.418313)  ,0														,-215.019870069509807 * (-	0.00220448)	,0														 },
									};

// Msync_r_1 * Qsyncd_r = Qsyncd_rm
//
//	| 3.525236178152328   	0.000000000000000	 -215.019870069509807     0.000000000000000		 |  | 0	                    -0.418313	       0			         -0.00220448  |
//  | 0.000000000000000   	3.525236178152328     0.000000000000000   	  -215.019870069509807     |  | 0.418313			 0	                   0.00220448		  0					 |
//	| -215.019870069509807  0.000000000000000	  4.07834311366690e+04   0.00000000000000e+00   |  | 0			            -0.00220448     0					 -3.61423e-05 |
//	| 0.000000000000000   -215.019870069509807   0.00000000000000e+00   4.07834311366690e+04   |  | 0.00220448	     0					   3.61423e-05	  0				     |
//


double Qsyncd_rm[4][4] = {
											{ 0		,3.525236178152328 * (-0.418313)	+ 	-215.019870069509807 * (-0.00220448) ,0	,3.525236178152328	* (-0.00220448) +  -215.019870069509807 * 	(-3.61423e-05)				},
											{ 3.525236178152328	* 0.418313 + 	-215.019870069509807 * 0.00220448		,0		,3.525236178152328 * 0.00220448 + -215.019870069509807 * 3.61423e-05	,0							},
											{ 0		,-215.019870069509807 * (-0.418313) + 4.07834311366690e+04 * (-0.00220448 )	,0		,-215.019870069509807 * (-0.00220448) + 4.07834311366690e+04 * (-3.61423e-05)		},
											{-215.019870069509807 * 0.418313 + 4.07834311366690e+04 * 0.00220448		,0		,-215.019870069509807 * 0.00220448 + 4.07834311366690e+04 * 3.61423e-05		,0				},
										};

//	| d_is_sdq_d |          					 | vs_sdq_d |        																									 					 | is_sdq_d |
//	| d_is_sdq_q |        					 | vs_sdq_q |		  	 																													 | is_sdq_q |
//	| d_ir_sdq_d |     =   Msync_r_1    |     0        |  	-    { Rsync_rm    -    omega_r * Qsync_rm    -  (omega_r - omega_s) * Qsyncd_rm  }   | ir_sdq_d |                 Eq. (29)
//	| d_ir_sdq_q |           					 |     0        | 		  																														 | ir_sdq_q |


//  d_is_sdq_d = vs_sdq_d*Msync_r_1[0][0] - is_sdq_d * Rsync_rm[0][0] - ir_sdq_d * Rsync_rm[0][2] - omega_r * (is_sdq_q * Qsync_rm[0][1] + ir_sdq_q * Qsync_rm[0][3])
//															    	- (omega_r - omega_s) * ( is_sdq_q * Qsyncd_rm[[0][1] + ir_sdq_q * Qsyncd_rm[0][3])																Eq. (30)
//
//
//  d_is_sdq_q = vs_sdq_q*Msync_r_1[1][1] - is_sdq_q * Rsync_rm[1][1] - ir_sdq_q * Rsync_rm[1][3] - omega_r * (is_sdq_d * Qsync_rm[1][0] + ir_sdq_d * Qsync_rm[1][2])
//																	- (omega_r - omega_s) * ( is_sdq_d * Qsyncd_rm[1][0] + ir_sdq_d * Qsyncd_rm[1][2])																	Eq. (31)
//
//
//  d_ir_sdq_d = vs_sdq_d*Msync_r_1[2][0] - is_sdq_d * Rsync_rm[2][0] - ir_sdq_d * Rsync_rm[2][2] - omega_r * (is_sdq_q * Qsync_rm[2][1] + ir_sdq_q * Qsync_rm[2][3])
//																	- (omega_r - omega_s) * ( is_sdq_q * Qsyncd_rm[2][1] + ir_sdq_q * Qsyncd_rm[2][3])																	Eq. (32)
//
//
//  d_ir_sdq_q = vs_sdq_q*Msync_r_1[3][1] - is_sdq_q * Rsync_rm[3][1] - ir_sdq_q * Rsync_rm[3][3] - omega_r * (is_sdq_d * Qsync_rm[3][0] + ir_sdq_d * Qsync_rm[3][2])
//																	- (omega_r - omega_s) * ( is_sdq_d * Qsyncd_rm[3][0] + ir_sdq_d * Qsyncd_rm[3][2])																	Eq. (33)
//
//

// Now, turning to Section 8.2.2, page 213 of "Roberts..." and the section of Eq. (19) above describing "Ssync"

//	From these definitions made above, combine into one 4x4 matrix.
//
//
//double Ssyncsr_r[2][2] = {
//											{ 0						,0.00220448				},
//											{ -0.00220448		,0								},
//									 };
//
//double Ssyncsr_t_r[2][2] = {
//											{ 0						,-0.00220448				},
//											{ 0.00220448		,0								},
//									    };

double Ssync_r[4][4] = {
										{ 0							,0							,0						,0.00220448			},
										{ 0							,0							,-0.00220448		,0							},
										{ 0							,-0.00220448			,0						,0							},
										{ 0.00220448			,0							,0						,0							},
								  };

//  Ssync_r * Msync_r_1 = Tsync_r
//
//  | 0							0							0						0.00220448 |   | 3.525236178152328   	0.000000000000000	 -215.019870069509807     0.000000000000000		 |
//  | 0							0							-0.00220448		0	 			  |	 | 0.000000000000000   	3.525236178152328     0.000000000000000   	  -215.019870069509807     |
//	| 0							-0.00220448			0						0				  |	 | -215.019870069509807  0.000000000000000	  4.07834311366690e+04   0.00000000000000e+00   |
//	| 0.00220448			0							0						0				  |  | 0.000000000000000   -215.019870069509807   0.00000000000000e+00   4.07834311366690e+04   |
//

double Tsync_r[4][4] = {
										{ 0															 ,-215.019870069509807 * 0.00220448	  ,0															,4.07834311366690e+04 * 0.00220448	  	},
										{ -215.019870069509807 * (-0.00220448)	 ,0														  ,4.07834311366690e+04 * (-0.00220448)	,0                                                       	},
										{ 0															 ,3.525236178152328 * (-0.00220448)	  ,0															,-215.019870069509807 * (-0.00220448)	},
										{ 3.525236178152328 * 0.00220448			 ,0														  ,-215.019870069509807 * 0.00220448		,0	 														},
								 };

// Tsync_r * Rsync_r = Rsync_rc
//
// | 0		-215.019870069509807 * 0.00220448	  0		4.07834311366690e+04 * 0.00220448		|   | 2.72855            0	       			   0			          0  				 |
// |  -215.019870069509807 * (-0.00220448)	 0	 4.07834311366690e+04 * (-0.00220448)		0  |   | 0 					 2.72855           0	  				  0					 |
// |  0		3.525236178152328 * (-0.00220448)	  0		-215.019870069509807 * (-0.00220448)   |   | 0			             0					   0.000125		  0 				 |
// | 3.525236178152328 * 0.00220448			 0	 -215.019870069509807 * 0.00220448		    0  |   | 0					     0					   0	  				  0.000125	     |
//

double Rsync_rc[4][4] = {
											{ 0    																		,-215.019870069509807 * 0.00220448 * 2.72855		,0										        							 ,4.07834311366690e+04 * 0.00220448 * 0.000125	 },
											{ -215.019870069509807 * (-0.00220448) * 2.72855   ,0																			,4.07834311366690e+04 * (-0.00220448) * 0.000125  ,0																			 },
											{ 0																			,3.525236178152328 * (-0.00220448) * 2.72855			,0																			 ,-215.019870069509807 * (-0.00220448) * 0.000125	 },
											{ 3.525236178152328 * 0.00220448 * 2.72855			,0																			,-215.019870069509807 * 0.00220448 * 0.000125 	 ,0																			 },
									};

// Tsync_r * Qsync_r = Qsync_rc
//
// | 0		-215.019870069509807 * 0.00220448	  0		4.07834311366690e+04 * 0.00220448		|  | 0			             0.418313		   0			          0.00220448  |
// |  -215.019870069509807 * (-0.00220448)	 0	 4.07834311366690e+04 * (-0.00220448)		0  |  | -0.418313			 0			           -0.00220448	  0					 |
// |  0		3.525236178152328 * (-0.00220448)	  0		-215.019870069509807 * (-0.00220448)   |  | 0			             0					   0					  0 				 |
// | 3.525236178152328 * 0.00220448			 0	 -215.019870069509807 * 0.00220448		    0  |  | 0			             0					   0					  0 				 |
//

double Qsync_rc[4][4] = {
										{ -215.019870069509807 * 0.00220448 * (-0.418313)			,0																			,-215.019870069509807 * 0.00220448 * (-0.00220448)	,0																				},
										{ 0																					,-215.019870069509807 * (-0.00220448) * 0.418313	,0																				,-215.019870069509807 * (-0.00220448) * 0.00220448	},
										{ 3.525236178152328 * (-0.00220448) * (-0.418313)			,0																			,3.525236178152328 * (-0.00220448) * (-0.00220448) 	,0																				},
										{ 0																					,3.525236178152328 * 0.00220448 * 0.418313			,0																				,3.525236178152328 * 0.00220448 * 0.00220448    		},
							 	 	};

// Tsync_r * Qsyncd_r = Qsyncd_rc
//
// | 0		-215.019870069509807 * 0.00220448	  0		4.07834311366690e+04 * 0.00220448		|  | 0	                    -0.418313	       0			         -0.00220448  |
// |  -215.019870069509807 * (-0.00220448)	 0	 4.07834311366690e+04 * (-0.00220448)		0  |  | 0.418313			 0	                   0.00220448		  0					 |
// |  0		3.525236178152328 * (-0.00220448)	  0		-215.019870069509807 * (-0.00220448)   |  | 0			            -0.00220448     0					 -3.61423e-05 |
// | 3.525236178152328 * 0.00220448			 0	 -215.019870069509807 * 0.00220448		    0  |  | 0.00220448	     0					   3.61423e-05	  0				     |
//

double Qsyncd_rc[4][4] = {
											{ -215.019870069509807 * 0.00220448 * 0.418313 + 4.07834311366690e+04 * 0.00220448 * 0.00220448	,0  ,-215.019870069509807 * 0.00220448 * 0.00220448	 + 4.07834311366690e+04 * 0.00220448 * 3.61423e-05  ,0						 },
											{ 0, -215.019870069509807 * (-0.00220448) * (-0.418313)	+ 4.07834311366690e+04 * (-0.00220448) * (-0.00220448)  ,0 ,-215.019870069509807 * (-0.00220448) * (-0.00220448) + 4.07834311366690e+04 * (-0.00220448) * (-3.61423e-05)	 },
											{ 3.525236178152328 * (-0.00220448) * 0.418313 + -215.019870069509807 * (-0.00220448) * 0.00220448  ,0  ,3.525236178152328 * (-0.00220448) * 0.00220448	+ -215.019870069509807 * (-0.00220448) * 3.61423e-05 ,0						 },
											{ 0, 3.525236178152328 * 0.00220448 * (-0.418313)  + 215.019870069509807 * 0.00220448 * (-0.00220448)  ,0  ,3.525236178152328 * 0.00220448 * (-0.00220448) + -215.019870069509807 * 0.00220448 * (-3.61423e-05)   						 },
									 };


// Reduce the portion of Eq. 8.11 on page 213 so that  "vs_sdq_d" and "vs_sdq_q" ends up as a "lvalue" of this  equation.
//
//
// 																			| 0			 			Tsync_r[0][1]		0 						Tsync_r[0][3] |  | vs_sdq_d |
// | is_sdq_d |	 | is_sdq_q |  | ir_sdq_d |  | ir_sdq_q |	| Tsync_r[1][0]  	0						Tsync_r[1][2]		0					|  | vs_sdq_q |	  * 1 / Jm
//   																		| 0			 			Tsync_r[2][1]		0 						Tsync_r[2][3] |  |     0        |
//  																		| Tsync_r[3][0]  	0						Tsync_r[3][2]		0					|  |     0        |
//
//
//
//																			| vs_sdq_q * Tsync_r[0][1]  |
//																		    | vs_sdq_d * Tsync_r[1][0]  |
//  | is_sdq_d | | is_sdq_q |  | ir_sdq_d | | ir_sdq_q |	| vs_sdq_q * Tsync_r[2][1]  |  * 1 / Jm
//																			| vs_sdq_d * Tsync_r[3][0]  |
//
//
//
//	(is_sdq_d * vs_sdq_q * Tsync_r[0][1] + is_sdq_q * vs_sdq_d * Tsync_r[1][0] + ir_sdq_d * vs_sdq_q * Tsync_r[2][1] + ir_sdq_q * vs_sdq_d * Tsync_r[3][0])  / Jm
//
//
//
//
//




// Now, with the formulations above, reduce the "rvalue" Eq. 8.11 on page 213 of "Roberts..."
//
//

//
//							 										 | 0                       Rsync_rc[0][1]    0  				  	  Rsync_rc[0][3] 	|  | is_sdq_d |
// | is_sdq_d   is_sdq_q   ir_sdq_d  ir_sdq_q  |	 | Rsync_rc[1][0]    0					     Rsync_rc[1][2]    0					    |  | is_sdq_q  |  * 1 / Jm
//							 										 | 0                       Rsync_rc[2][1]    0  				  	  Rsync_rc[2][3] 	|  | ir_sdq_d  |
//																	 | Rsync_rc[3][0]    0					     Rsync_rc[3][2]    0					    |  | ir_sdq_q  |
//
//
//
//	 																| is_sdq_q * Rsync_rc[0][1] + ir_sdq_q * Rsync_rc[0][3] |
// | is_sdq_d   is_sdq_q   ir_sdq_d  ir_sdq_q  |  | is_sdq_d * Rsync_rc[1][0] + ir_sdq_d * Rsync_rc[1][2] | * 1 / Jm
//																	| is_sdq_q * Rsync_rc[2][1] + ir_sdq_q * Rsync_rc[2][3] |
//																	| is_sdq_d * Rsync_rc[3][0] + ir_sdq_d * Rsync_rc[3][2] |
//
//
//
// ( is_sdq_d * is_sdq_q * Rsync_rc[0][1] + is_sdq_d * ir_sdq_q * Rsync_rc[0][3] + is_sdq_q * is_sdq_d * Rsync_rc[1][0] + is_sdq_q * ir_sdq_d * Rsync_rc[1][2] +
//	 					ir_sdq_d * is_sdq_q * Rsync_rc[2][1] + ir_sdq_d * ir_sdq_q * Rsync_rc[2][3] + ir_sdq_q * is_sdq_d * Rsync_rc[3][0] + ir_sdq_q * ir_sdq_d * Rsync_rc[3][2]) / Jm
//
//
// ( is_sdq_d * (is_sdq_q * Rsync_rc[0][1] + ir_sdq_q * Rsync_rc[0][3]) + is_sdq_q * (is_sdq_d * Rsync_rc[1][0] + ir_sdq_d * Rsync_rc[1][2]) +
//	 					ir_sdq_d * (is_sdq_q * Rsync_rc[2][1] + ir_sdq_q * Rsync_rc[2][3]) + ir_sdq_q * (is_sdq_d * Rsync_rc[3][0] + ir_sdq_d * Rsync_rc[3][2])) / Jm
//
//




//
//							 										 | Qsync_rc[0][0]    0  					   Qsync_rc[0][2]    0  					|  | is_sdq_d |
// | is_sdq_d   is_sdq_q   ir_sdq_d  ir_sdq_q  |	 | 0    					Qsync_rc[1][1]  0					    	Qsync_rc[1][3]  |  | is_sdq_q  |  * omega_r * 1 / Jm
//							 										 | Qsync_rc[2][0]    0  					   Qsync_rc[2][2]    0  					|  | ir_sdq_d  |
//																	 | 0    					Qsync_rc[3][1]  0					    	Qsync_rc[3][3]  |  | ir_sdq_q  |
//
//
//
//	 																| is_sdq_d * Qsync_rc[0][0] + ir_sdq_d * Qsync_rc[0][2] |
// | is_sdq_d   is_sdq_q   ir_sdq_d  ir_sdq_q  |  | is_sdq_q * Qsync_rc[1][1] + ir_sdq_q * Qsync_rc[1][3] | * omega_r * 1 / Jm
//																	| is_sdq_d * Qsync_rc[2][0] + ir_sdq_d * Qsync_rc[2][2] |
//																	| is_sdq_q * Qsync_rc[3][1] + ir_sdq_q * Qsync_rc[3][3] |
//
//
//
// ( is_sdq_d**2 * Qsync_rc[0][0] + is_sdq_d * ir_sdq_d * Qsync_rc[0][2] + is_sdq_q**2 * Qsync_rc[1][1] + is_sdq_q * ir_sdq_q * Qsync_rc[1][3] +
//	 					ir_sdq_d * is_sdq_d * Qsync_rc[2][0] + ir_sdq_d**2 * Qsync_rc[2][2] + ir_sdq_q * is_sdq_q * Qsync_rc[3][1] + ir_sdq_q**2 * Qsync_rc[3][3]) * omega_r  / Jm
//
//
//

//
//							 										 | Qsyncd_rc[0][0]    0  					   	Qsyncd_rc[0][2]    	0  						 |  | is_sdq_d |
// | is_sdq_d   is_sdq_q   ir_sdq_d  ir_sdq_q  |	 | 0    					  Qsyncd_rc[1][1]  	0					    	Qsyncd_rc[1][3]  |  | is_sdq_q  |  * (omega_r - omega_s) * 1 / Jm
//							 										 | Qsyncd_rc[2][0]    0  					   	Qsyncd_rc[2][2]    	0  						 |  | ir_sdq_d  |
//																	 | 0    					  Qsyncd_rc[3][1]  	0					    	Qsyncd_rc[3][3]  |  | ir_sdq_q  |
//
//
//
//	 																| is_sdq_d * Qsyncd_rc[0][0] + ir_sdq_d * Qsyncd_rc[0][2] |
// | is_sdq_d   is_sdq_q   ir_sdq_d  ir_sdq_q  |  | is_sdq_q * Qsyncd_rc[1][1] + ir_sdq_q * Qsyncd_rc[1][3] | * (omega_r  - omega_s) * 1 / Jm
//																	| is_sdq_d * Qsyncd_rc[2][0] + ir_sdq_d * Qsyncd_rc[2][2] |
//																	| is_sdq_q * Qsyncd_rc[3][1] + ir_sdq_q * Qsyncd_rc[3][3] |
//
//
//
// ( is_sdq_d**2 * Qsyncd_rc[0][0] + is_sdq_d * ir_sdq_d * Qsyncd_rc[0][2] + is_sdq_q**2 * Qsyncd_rc[1][1] + is_sdq_q * ir_sdq_q * Qsyncd_rc[1][3] +
//	 					ir_sdq_d * is_sdq_d * Qsyncd_rc[2][0] + ir_sdq_d**2 * Qsyncd_rc[2][2] + ir_sdq_q * is_sdq_q * Qsyncd_rc[3][1] + ir_sdq_q**2 * Qsyncd_rc[3][3]) * (omega_r - omega_s)  / Jm
//
//
//

// Rewrite Eq. 8.11 on page 213 using the info above.
//
//
//	is_sdq_d * vs_sdq_q * Tsync_r[0][1] + is_sdq_q * vs_sdq_d * Tsync_r[1][0] + ir_sdq_d * vs_sdq_q * Tsync_r[2][1] + ir_sdq_q * vs_sdq_d * Tsync_r[3][0]  -
//
//					is_sdq_d * (is_sdq_q * Rsync_rc[0][1] + ir_sdq_q * Rsync_rc[0][3]) - is_sdq_q * (is_sdq_d * Rsync_rc[1][0] + ir_sdq_d * Rsync_rc[1][2]) -
//	 							ir_sdq_d * (is_sdq_q * Rsync_rc[2][1] + ir_sdq_q * Rsync_rc[2][3]) - ir_sdq_q * (is_sdq_d * Rsync_rc[3][0] + ir_sdq_d * Rsync_rc[3][2])  -
//
// 					( is_sdq_d**2 * Qsync_rc[0][0] + is_sdq_d * ir_sdq_d * Qsync_rc[0][2] + is_sdq_q**2 * Qsync_rc[1][1] + is_sdq_q * ir_sdq_q * Qsync_rc[1][3] +
//	 					ir_sdq_d * is_sdq_d * Qsync_rc[2][0] + ir_sdq_d**2 * Qsync_rc[2][2] + ir_sdq_q * is_sdq_q * Qsync_rc[3][1] + ir_sdq_q**2 * Qsync_rc[3][3]) * omega_r  -
//
//					 ( is_sdq_d**2 * Qsyncd_rc[0][0] + is_sdq_d * ir_sdq_d * Qsyncd_rc[0][2] + is_sdq_q**2 * Qsyncd_rc[1][1] + is_sdq_q * ir_sdq_q * Qsyncd_rc[1][3] +
//	 					ir_sdq_d * is_sdq_d * Qsyncd_rc[2][0] + ir_sdq_d**2 * Qsyncd_rc[2][2] + ir_sdq_q * is_sdq_q * Qsyncd_rc[3][1] + ir_sdq_q**2 * Qsyncd_rc[3][3]) * (omega_r - omega_s)  -
//
//					Jm * d2omega_r_dt2  -
//
//					Bm * domega_r_dt = 0																																														Eq. (34)

// Using the technique described for "Lagrange Multipiliers" in paper and "C:\Simulation-Development\Brushless-DoublyFed-Motor-Dissertation\LaGrangeMultipliers.txt" and
// the material described in Section 4.3 "Constrained Extrema and Lagrange Multipiliers", "Vector Calculus - Thomba" pages 217 through 224, create the lagrange equations.
//
//   For additional reference and tools, see:
//
//							- C:\Simulation-Development\Brushless-DoublyFed-Motor-Dissertation\Calculus III - Lagrange Multipliers.html
//							- C:\Simulation-Development\Brushless-DoublyFed-Motor-Dissertation\Matlab in Chemical Engineering at CMU.html
//							- C:\Simulation-Development\Brushless-DoublyFed-Motor-Dissertation\GNU Octave_ Solvers.html							<-- (Good interative way to check results).
//
//
//
//
//
//	Eq. (30), Eq. (31), Eq. (32) and Eq. (33) above is formulated with the condition of steady state operation (eg., "di/dt" terms are set to zero).
//
//
//
//																								f1(vs_sdq_d, vs_sdq_q, is_sdq_d, is_sdq_q, ir_sdq_d, ir_sdq_q, omega_r, omega_s)  <--- Eq. (30) at steady state.
//																								f2(vs_sdq_d, vs_sdq_q, is_sdq_d, is_sdq_q, ir_sdq_d, ir_sdq_q, omega_r, omega_s)  <--- Eq. (31) at steady state.
//																								f3(vs_sdq_d, vs_sdq_q, is_sdq_d, is_sdq_q, ir_sdq_d, ir_sdq_q, omega_r, omega_s)  <--- Eq. (32) at steady state.
//																								f4(vs_sdq_d, vs_sdq_q, is_sdq_d, is_sdq_q, ir_sdq_d, ir_sdq_q, omega_r, omega_s)  <--- Eq. (33) at steady state.
//
//
//
//  The constraint equation is defined as
//																								g(vs_sdq_d, vs_sdq_q, is_sdq_d, is_sdq_q, ...)  <---- vs_sdq_d**2 + vs_sdq_q**2 <= C
//
//
//
//					k1*df1/dvs_sdq_d + k2*df2/dvs_sdq_d + k3*df3/dvs_sdq_d + k4*df4/dvs_sdq_d = dg/dvs_sdq_d					 									Eq. (35)
//
//										k1*Msync_r_1[0][0] + k3*Msync_r_1[2][0] = 2*vs_sdq_d
//
//					k1*df1/dvs_sdq_q + k2*df2/dvs_sdq_q + k3*df3/dvs_sdq_q + k4*df4/dvs_sdq_q = dg/dvs_sdq_q					  									Eq. (36)
//
//										k2*Msync_r_1[1][1] + k4*Msync_r_1[3][1] = 2*vs_sdq_q
//
//					k1*df1/dis_sdq_d + k2*df2/dis_sdq_d + k3*df3/dis_sdq_d + k4*df4/dis_sdq_d = dg/dis_sdq_d						  									Eq. (37)
//
//										- k1*Rsync_rm[0][0] - k2*omega_r*(Qsync_rm[1][0] + Qsyncd_rm[1][0]) + k2*omega_s*Qsyncd_rm[1][0] -
//										  k3*Rsync_rm[2][0] - k4*omega_r*(Qsync_rm[3][0] + Qsyncd_rm[3][0]) + k4*omega_s*Qsyncd_rm[3][0] = 0
//
//					k1*df1/dis_sdq_q + k2*df2/dis_sdq_q + k3*df3/dis_sdq_q + k4*df4/dis_sdq_q = dg/dis_sdq_q						  									Eq. (38)
//
//										- k1*omega_r*(Qsync_rm[0][1] + Qsyncd_rm[0][1]) + k1*omega_s*Qsyncd_rm[0][1] - k2*Rsync_rm[1][1] -
//										  k3*omega_r*(Qsync_rm[2][1] + Qsyncd_rm[2][1]) + k3*omega_s*Qsyncd_rm[2][1] - k4*Rsync_rm[3][1] = 0
//
//					k1*df1/dir_sdq_d + k2*df2/dir_sdq_d + k3*df3/dir_sdq_d + k4*df4/dir_sdq_d = dg/dir_sdq_d						  									    Eq. (39)
//
//										- k1*Rsync_rm[0][2] - k2*omega_r*(Qsync_rm[1][2] + Qsyncd_rm[1][2]) + k2*omega_s*Qsyncd_rm[1][2]) -
//										  k3*Rsync_rm[2][2] - k4*omega_r*(Qsync_rm[3][2] + Qsyncd_rm[3][2]) + k4*omega_s*Qsyncd_rm[3][2] = 0
//
//					k1*df1/dir_sdq_q + k2*df2/dir_sdq_q + k3*df3/dir_sdq_q + k4*df4/dir_sdq_q = dg/dir_sdq_q						  										Eq. (40)
//
//										- k1*omega_r*(Qsync_rm[0][3] + Qsyncd_rm[0][3]) + k1*omega_s*Qsyncd_rm[0][3] - k2*Rsync_rm[1][3] -
//										  k3*omega_r*(Qsync_rm[2][3] + Qsyncd_rm[2][3]) + k3*omega_s*Qsyncd_rm[2][3] - k4*Rsync_rm[3][3] = 0
//
//					k1*df1/domega_r + k2*df2/domega_r + k3*df3/domega_r + k4*df4/domega_r = dg/domega_r																Eq. (41)
//
//										- k1*(is_sdq_q*(Qsync_rm[0][1] + Qsyncd_rm[0][1]) + ir_sdq_q*(Qsync_rm[0][3] + Qsyncd_rm[0][3])) -
//										  k2*(is_sdq_d*(Qsync_rm[1][0] + Qsyncd_rm[1][0]) + ir_sdq_d*(Qsync_rm[1][2] + Qsyncd_rm[1][2])) -
//										  k3*(is_sdq_q*(Qsync_rm[2][1] + Qsyncd_rm[2][1]) + ir_sdq_q*(Qsync_rm[2][3] + Qsyncd_rm[2][3])) -
//										  k4*(is_sdq_d*(Qsync_rm[3][0] + Qsyncd_rm[3][0]) + ir_sdq_d*(Qsync_rm[3][2] + Qsyncd_rm[3][2])) = 0
//
//					k1*df1/domega_s + k2*df2/domega_s + k3*df3/domega_s + k4*df4/domega_s = dg/domega_s															Eq. (42)
//
//										 k1*(is_sdq_q*Qsyncd_rm[0][1] + ir_sdq_q*Qsyncd_rm[0][3]) +
//										 k2*(is_sdq_d*Qsyncd_rm[1][0] + ir_sdq_d*Qsyncd_rm[1][2]) +
//										 k3*(is_sdq_q*Qsyncd_rm[2][1] + ir_sdq_q*Qsyncd_rm[2][3]) +
//										 k4*(is_sdq_d*Qsyncd_rm[3][0] + ir_sdq_d*Qsyncd_rm[3][2]) = 0
//
//
//







//
//
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void RefGen::CtrlFunction(double t)
{




  //Point to point, "modified sin" trajectory generator.


  if(t < RT_TRAJ){
    omegad = VO_TRAJ*(sin(t*PI/RT_TRAJ - PI/2.0) + 1)/2.0;
    thetad =  VO_TRAJ*(-(RT_TRAJ/PI)*cos(t*PI/RT_TRAJ - PI/2.0) + t)/2.0;
    alphad = VO_TRAJ*(PI/RT_TRAJ)*cos(t*PI/RT_TRAJ - PI/2.0)/2.0;
    betad = VO_TRAJ*(-PI/RT_TRAJ)*(PI/RT_TRAJ)*sin(t*PI/RT_TRAJ - PI/2.0)/2.0;

  }
  else if(t < (RT_TRAJ + CT_TRAJ)){
    omegad = VO_TRAJ;
    thetad = VO_TRAJ*RT_TRAJ/2.0 + VO_TRAJ*(t-RT_TRAJ);
    alphad = 0;
    betad = 0;

  }
  else if(t < (2*RT_TRAJ + CT_TRAJ)){
    omegad = VO_TRAJ*(sin((CT_TRAJ+2*RT_TRAJ-t)*PI/RT_TRAJ - PI/2.0) + 1)/2.0;
    thetad =  VO_TRAJ*RT_TRAJ/2.0 + VO_TRAJ*(CT_TRAJ) + VO_TRAJ*(-(RT_TRAJ/PI)*cos((CT_TRAJ+RT_TRAJ-t)*PI/RT_TRAJ - PI/2.0) +
							      t-(RT_TRAJ+CT_TRAJ))/2.0;
    alphad = VO_TRAJ*(-PI/RT_TRAJ)*cos((CT_TRAJ+2*RT_TRAJ-t)*PI/RT_TRAJ - PI/2.0)/2.0;
    betad = VO_TRAJ*(PI/RT_TRAJ)*(-PI/RT_TRAJ)*sin((CT_TRAJ+2*RT_TRAJ-t)*PI/RT_TRAJ - PI/2.0)/2.0;

  }
  else{
    omegad = 0;
    thetad = VO_TRAJ*RT_TRAJ + VO_TRAJ*(CT_TRAJ);
    alphad = 0;
    betad = VO_TRAJ*(PI/RT_TRAJ)*(-PI/RT_TRAJ)*(-1.0/2.0);
    
  }

  //!!!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!1

  //"betad" being discontinuous causes small trajectory generation.

  betad = 0;

  //This is why exponential based ramping is ideal (no discontinuities at higher differencials)
  //Interesting howerver, if we force to "0", we can get a pretty good representation without generating
  //a "bump" on vdq.

  //In any event, this enforces the idea that the trajectory should be generated with using exponential ramping.

  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!




  // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  	  // These test will work with TERMINAL_REF_PLANE_SIMULATION set to TRUE or FALSE. Induction motor paper uses this set to TRUE.

#define FORCE_REF_DEBUG_TEST  3


#if (FORCE_REF_DEBUG_TEST == 3)

	 //Force the following as the driving variables.
	omega_r_r = omega_r;

 	is_sdq_d_r = is_sdq_d;
 	is_sdq_q_r = is_sdq_q;
 	ir_sdq_d_r = ir_sdq_d;
 	ir_sdq_q_r = ir_sdq_q;

 	vs_sdq_q_r = vs_sdq_q;








 	LagrangeSolve_i.PreSpiceFunction(0, FALSE);
 	LagrangeSolve_i.Gauss(FALSE);


 	k1 = LagrangeSolve_i.a[Ind_k1][6];
 	k2 = LagrangeSolve_i.a[Ind_k2][6];
 	k3 = LagrangeSolve_i.a[Ind_k3][6];
 	k4 = LagrangeSolve_i.a[Ind_k4][6];
 	omega_s_r = LagrangeSolve_i.a[Ind_Omega_s][6];
 	vs_sdq_d_r = LagrangeSolve_i.a[Ind_vs_sdq_d][6];

 	//There is a problem with the Guassian solver. It looks like we need to rearange the columns or add the "full" pivoting to the algorythm.
 	//There are certain points at which the solution generates NAN. It seems to happen only on one single interation (recovers on the next).
 	//For now, save the previous state to filter this problem.
 	// (See "C:\Simulation-Development\Brushless-DoublyFed-Motor-Dissertation\lecture5-(Roundoff Analysis of Gaussian Elimination).pdf")

 	if(isnan(omega_s_r ))
 		omega_s_r = omega_s_r_prev;

 	omega_s_r_prev = omega_s_r;

 	if(isnan(vs_sdq_d_r))
 		vs_sdq_d_r = vs_sdq_d_r_prev;

 	vs_sdq_d_r_prev = vs_sdq_d_r;




#endif

#if (FORCE_REF_DEBUG_TEST == 2)


		domega_r_dt = alphad;

		d2omega_r_dt2 = betad;


		 //Force the following as the driving variables.
		omega_r_r = omega_r;
		omega_s_r = omega_s;

	 	is_sdq_d_r = is_sdq_d;
	 	is_sdq_q_r = is_sdq_q;
	 	ir_sdq_d_r = ir_sdq_d;
	 	ir_sdq_q_r = ir_sdq_q;

	 	vs_sdq_q_r = vs_sdq_q;

	 	//Results: With this test the following variables track each other in the plot screens.
	 	//             (NOTE: View plot starting at 1 second because of "is_sdq_q_r" and "ir_sdq_q_r" unconstrained zero in denominator)
	 	//
	 	//	"vs_sdq_d" and "vs_sdq_d_r"
	 	//
	 	//




	 	if((is_sdq_q_r != 0)  ||  (ir_sdq_q_r  != 0))
	 	{
			vs_sdq_d_r =

		 ( - is_sdq_d_r * vs_sdq_q_r * Tsync_r[0][1] - ir_sdq_d_r * vs_sdq_q_r * Tsync_r[2][1] +

			is_sdq_d_r * (is_sdq_q_r * Rsync_rc[0][1] + ir_sdq_q_r * Rsync_rc[0][3]) + is_sdq_q_r * (is_sdq_d_r * Rsync_rc[1][0] + ir_sdq_d_r * Rsync_rc[1][2]) +
						ir_sdq_d_r * (is_sdq_q_r * Rsync_rc[2][1] + ir_sdq_q_r * Rsync_rc[2][3]) + ir_sdq_q_r * (is_sdq_d_r * Rsync_rc[3][0] + ir_sdq_d_r * Rsync_rc[3][2])  +

			( is_sdq_d_r * is_sdq_d_r * Qsync_rc[0][0] + is_sdq_d_r * ir_sdq_d_r * Qsync_rc[0][2] + is_sdq_q_r *  is_sdq_q_r * Qsync_rc[1][1] + is_sdq_q_r * ir_sdq_q_r * Qsync_rc[1][3] +
				ir_sdq_d_r * is_sdq_d_r * Qsync_rc[2][0] + ir_sdq_d_r * ir_sdq_d_r * Qsync_rc[2][2] + ir_sdq_q_r * is_sdq_q_r * Qsync_rc[3][1] + ir_sdq_q_r * ir_sdq_q_r * Qsync_rc[3][3]) * omega_r_r  +

			 ( is_sdq_d_r * is_sdq_d_r * Qsyncd_rc[0][0] + is_sdq_d_r * ir_sdq_d_r * Qsyncd_rc[0][2] + is_sdq_q_r * is_sdq_q_r * Qsyncd_rc[1][1] + is_sdq_q_r * ir_sdq_q_r * Qsyncd_rc[1][3] +
				ir_sdq_d_r * is_sdq_d_r * Qsyncd_rc[2][0] + ir_sdq_d_r * ir_sdq_d_r * Qsyncd_rc[2][2] + ir_sdq_q_r * is_sdq_q_r * Qsyncd_rc[3][1] + ir_sdq_q_r * ir_sdq_q_r * Qsyncd_rc[3][3]) * (omega_r_r - omega_s_r)  +

			Jm * d2omega_r_dt2  +

			Bm * domega_r_dt    )  / (is_sdq_q_r * Tsync_r[1][0] +  ir_sdq_q_r * Tsync_r[3][0]);

	 	}

#endif


#if (FORCE_REF_DEBUG_TEST == 1)

	 	//This is a test for code below that executes the electrical equations defined by Eq. (30) through Eq. (33) above.

	 	 //Force the following as the driving variables.
	 	omega_r_r = omega_r;
	 	omega_s_r = omega_s;

	 	vs_sdq_d_r = vs_sdq_d;
	 	vs_sdq_q_r = vs_sdq_q;

	 	//Results: With this test the following variables track each other in the plot screens.
	 	//
	 	//	"is_sdq_d" and "is_sdq_d_r"
	 	//  "is_sdq_q" and "is_sdq_q_r"
	 	//  "ir_sdq_d" and "ir_sdq_d_r"
	 	//  "ir_sdq_q" and "ir_sdq_q_r"
	 	//
	 	//  Note that the reference counter-parts ("_r") are stepwise plots at intervals of .0001 seconds as expected and there
	 	//  is a small error between the simulated variables and the reference variables as expected.
	 	//




	 // These are the electrial equations as defined by Eq. (30) through Eq. (33) above.

	d_is_sdq_d_r = (vs_sdq_d_r*Msync_r_1[0][0] - is_sdq_d_r * Rsync_rm[0][0] - ir_sdq_d_r * Rsync_rm[0][2] - omega_r_r * (is_sdq_q_r * Qsync_rm[0][1] + ir_sdq_q_r * Qsync_rm[0][3])
																	- (omega_r_r - omega_s_r) * ( is_sdq_q_r * Qsyncd_rm[0][1] + ir_sdq_q_r * Qsyncd_rm[0][3])) *
																			REF_GEN_QUANTUM_CNT * QUANTUM_PERIOD;


	d_is_sdq_q_r = (vs_sdq_q_r*Msync_r_1[1][1] - is_sdq_q_r * Rsync_rm[1][1] - ir_sdq_q_r * Rsync_rm[1][3] - omega_r_r * (is_sdq_d_r * Qsync_rm[1][0] + ir_sdq_d_r * Qsync_rm[1][2])
																	- (omega_r_r - omega_s_r) * ( is_sdq_d_r * Qsyncd_rm[1][0] + ir_sdq_d_r * Qsyncd_rm[1][2])) *
																			REF_GEN_QUANTUM_CNT * QUANTUM_PERIOD;


	d_ir_sdq_d_r = (vs_sdq_d_r*Msync_r_1[2][0] - is_sdq_d_r * Rsync_rm[2][0] - ir_sdq_d_r * Rsync_rm[2][2] - omega_r_r * (is_sdq_q_r * Qsync_rm[2][1] + ir_sdq_q_r * Qsync_rm[2][3])
																	- (omega_r_r - omega_s_r) * ( is_sdq_q_r * Qsyncd_rm[2][1] + ir_sdq_q_r * Qsyncd_rm[2][3])) *
																			REF_GEN_QUANTUM_CNT * QUANTUM_PERIOD;


	d_ir_sdq_q_r = (vs_sdq_q_r*Msync_r_1[3][1] - is_sdq_q_r * Rsync_rm[3][1] - ir_sdq_q_r * Rsync_rm[3][3] - omega_r_r * (is_sdq_d_r * Qsync_rm[3][0] + ir_sdq_d_r * Qsync_rm[3][2])
																	- (omega_r_r - omega_s_r) * ( is_sdq_d_r * Qsyncd_rm[3][0] + ir_sdq_d_r * Qsyncd_rm[3][2])) *
																			REF_GEN_QUANTUM_CNT * QUANTUM_PERIOD;

	is_sdq_d_r += d_is_sdq_d_r;
	is_sdq_q_r += d_is_sdq_q_r;
	ir_sdq_d_r += d_ir_sdq_d_r;
	ir_sdq_q_r += d_ir_sdq_q_r;

#endif





  // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

}

void RefGen::RecordProbes(void)
{

#ifndef FREQUENCY_SWEEP_MODE
#ifdef RECORD_ALL_PROBES
  beta_d.push_back(betad);
  alpha_d.push_back(alphad);
#endif
  omega_d.push_back(omegad);
#ifdef RECORD_ALL_PROBES
  theta_d.push_back(thetad);
  zeta_d.push_back(zetad);
#endif

#endif

	  //Comment unused varable storage to reduce execution time.
	Vs_sdq_d_r.push_back(vs_sdq_d_r);
	Vs_sdq_q_r.push_back(vs_sdq_q_r);
	Is_sdq_d_r.push_back(is_sdq_d_r);
	Is_sdq_q_r.push_back(is_sdq_q_r);
	Ir_sdq_d_r.push_back(ir_sdq_d_r);
	Ir_sdq_q_r.push_back(ir_sdq_q_r);
	Omega_s_r.push_back(omega_s_r);


}


void RefGen::PlotProbes(Gnuplot & SimuPlot, vector<double> & Plot_t, string TagNamesToPlot[])
{
  int i;
#ifndef FREQUENCY_SWEEP_MODE

  if(TagNamesToPlot[0] == ""){
    SimuPlot.plot_xy(Plot_t, beta_d, "betad");
    SimuPlot.plot_xy(Plot_t, alpha_d, "alphad");
    SimuPlot.plot_xy(Plot_t, omega_d, "omegad");
    SimuPlot.plot_xy(Plot_t, theta_d, "thetad");

  }
  else{
    for(i = 0; i < 20; i++){
      if(TagNamesToPlot[i] == "betad"){
	SimuPlot.plot_xy(Plot_t, beta_d, "betad");
      }
      else if(TagNamesToPlot[i] == "alphad"){
	SimuPlot.plot_xy(Plot_t, alpha_d, "alphad");
      }
      else if(TagNamesToPlot[i] == "omegad"){
	SimuPlot.plot_xy(Plot_t, omega_d, "omegad");
      }
      else if(TagNamesToPlot[i] == "thetad"){
	SimuPlot.plot_xy(Plot_t, theta_d, "thetad");
      }


     }
  }
#else
  for(i = 0; i < 20; i++){
  if(TagNamesToPlot[i] == "vssdqd_r"){
	SimuPlot.plot_xy(Plot_t, Vs_sdq_d_r, "vssdqd_r");
   }
   else if(TagNamesToPlot[i] == "vssdqq_r"){
	SimuPlot.plot_xy(Plot_t, Vs_sdq_q_r, "vssdqq_r");
   }
   else if(TagNamesToPlot[i] == "issdqd_r"){
	SimuPlot.plot_xy(Plot_t, Is_sdq_d_r, "issdqd_r");
   }
   else if(TagNamesToPlot[i] == "issdqq_r"){
	SimuPlot.plot_xy(Plot_t, Is_sdq_q_r, "issdqq_r");
   }
   else if(TagNamesToPlot[i] == "irsdqd_r"){
	SimuPlot.plot_xy(Plot_t, Ir_sdq_d_r, "irsdqd_r");
   }
   else if(TagNamesToPlot[i] == "irsdqq_r"){
	SimuPlot.plot_xy(Plot_t, Ir_sdq_q_r, "irsdqq_r");
   }
   else if(TagNamesToPlot[i] == "omega_s_r"){
	SimuPlot.plot_xy(Plot_t, Omega_s_r, "omega_s_r");
   }
  }

#endif

}

void RefGen::CtrlRValueUpdate(void)
{
	vdd = vdd_local;
	vqd = vqd_local;

}

// ---------------------------------------------------------------


// *****************************************************************





// **** CoefObject Functions ****************************************

#ifdef TERMINAL_REF_PLANE_SIMULATION

// ---- Coef_ir_Msr_0_0_theta_r ---------------------------------------------

Coef_ir_Msr_0_0_theta_r::Coef_ir_Msr_0_0_theta_r(void)
{
  CoefFuncName = COEF_FUNC_ir_Msr_0_0_theta_r;
  LiteralName = "ir_Msr_0_0_theta_r";
}

Coef_ir_Msr_0_0_theta_r::~Coef_ir_Msr_0_0_theta_r(void)
{

}

void Coef_ir_Msr_0_0_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 0, 0) ;
}

// ------------------------------------------------------------------

// ---- Coef_ir_Msr_0_1_theta_r ---------------------------------------------

Coef_ir_Msr_0_1_theta_r::Coef_ir_Msr_0_1_theta_r(void)
{
  CoefFuncName = COEF_FUNC_ir_Msr_0_1_theta_r;
  LiteralName = "ir_Msr_0_1_theta_r";
}

Coef_ir_Msr_0_1_theta_r::~Coef_ir_Msr_0_1_theta_r(void)
{

}

void Coef_ir_Msr_0_1_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 0, 1) ;
}

// ------------------------------------------------------------------

// ---- Coef_ir_Msr_0_2_theta_r ---------------------------------------------

Coef_ir_Msr_0_2_theta_r::Coef_ir_Msr_0_2_theta_r(void)
{
  CoefFuncName = COEF_FUNC_ir_Msr_0_2_theta_r;
  LiteralName = "ir_Msr_0_2_theta_r";
}

Coef_ir_Msr_0_2_theta_r::~Coef_ir_Msr_0_2_theta_r(void)
{

}

void Coef_ir_Msr_0_2_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 0, 2) ;
}

// ------------------------------------------------------------------


// ---- Coef_ir_Msr_1_0_theta_r ---------------------------------------------

Coef_ir_Msr_1_0_theta_r::Coef_ir_Msr_1_0_theta_r(void)
{
  CoefFuncName = COEF_FUNC_ir_Msr_1_0_theta_r;
  LiteralName = "ir_Msr_1_0_theta_r";
}

Coef_ir_Msr_1_0_theta_r::~Coef_ir_Msr_1_0_theta_r(void)
{

}

void Coef_ir_Msr_1_0_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 1, 0) ;
}

// ------------------------------------------------------------------

// ---- Coef_ir_Msr_1_1_theta_r ---------------------------------------------

Coef_ir_Msr_1_1_theta_r::Coef_ir_Msr_1_1_theta_r(void)
{
  CoefFuncName = COEF_FUNC_ir_Msr_1_1_theta_r;
  LiteralName = "ir_Msr_1_1_theta_r";
}

Coef_ir_Msr_1_1_theta_r::~Coef_ir_Msr_1_1_theta_r(void)
{

}

void Coef_ir_Msr_1_1_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 1, 1) ;
}

// ------------------------------------------------------------------

// ---- Coef_ir_Msr_1_2_theta_r ---------------------------------------------

Coef_ir_Msr_1_2_theta_r::Coef_ir_Msr_1_2_theta_r(void)
{
  CoefFuncName = COEF_FUNC_ir_Msr_1_2_theta_r;
  LiteralName = "ir_Msr_1_2_theta_r";
}

Coef_ir_Msr_1_2_theta_r::~Coef_ir_Msr_1_2_theta_r(void)
{

}

void Coef_ir_Msr_1_2_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 1, 2) ;
}

// ------------------------------------------------------------------


// ---- Coef_ir_Msr_2_0_theta_r ---------------------------------------------

Coef_ir_Msr_2_0_theta_r::Coef_ir_Msr_2_0_theta_r(void)
{
  CoefFuncName = COEF_FUNC_ir_Msr_2_0_theta_r;
  LiteralName = "ir_Msr_2_0_theta_r";
}

Coef_ir_Msr_2_0_theta_r::~Coef_ir_Msr_2_0_theta_r(void)
{

}

void Coef_ir_Msr_2_0_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 2, 0) ;
}

// ------------------------------------------------------------------

// ---- Coef_ir_Msr_2_1_theta_r ---------------------------------------------

Coef_ir_Msr_2_1_theta_r::Coef_ir_Msr_2_1_theta_r(void)
{
  CoefFuncName = COEF_FUNC_ir_Msr_2_1_theta_r;
  LiteralName = "ir_Msr_2_1_theta_r";
}

Coef_ir_Msr_2_1_theta_r::~Coef_ir_Msr_2_1_theta_r(void)
{

}

void Coef_ir_Msr_2_1_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 2, 1) ;
}

// ------------------------------------------------------------------

// ---- Coef_ir_Msr_2_2_theta_r ---------------------------------------------

Coef_ir_Msr_2_2_theta_r::Coef_ir_Msr_2_2_theta_r(void)
{
  CoefFuncName = COEF_FUNC_ir_Msr_2_2_theta_r;
  LiteralName = "ir_Msr_2_2_theta_r";
}

Coef_ir_Msr_2_2_theta_r::~Coef_ir_Msr_2_2_theta_r(void)
{

}

void Coef_ir_Msr_2_2_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 2, 2) ;
}

// ------------------------------------------------------------------


// ---- Coef_is_Msr_0_0_theta_r ---------------------------------------------

Coef_is_Msr_0_0_theta_r::Coef_is_Msr_0_0_theta_r(void)
{
  CoefFuncName = COEF_FUNC_is_Msr_0_0_theta_r;
  LiteralName = "is_Msr_0_0_theta_r";
}

Coef_is_Msr_0_0_theta_r::~Coef_is_Msr_0_0_theta_r(void)
{

}

void Coef_is_Msr_0_0_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 0, 0) ;
}

// ------------------------------------------------------------------

// ---- Coef_is_Msr_1_0_theta_r ---------------------------------------------

Coef_is_Msr_1_0_theta_r::Coef_is_Msr_1_0_theta_r(void)
{
  CoefFuncName = COEF_FUNC_is_Msr_1_0_theta_r;
  LiteralName = "is_Msr_1_0_theta_r";
}

Coef_is_Msr_1_0_theta_r::~Coef_is_Msr_1_0_theta_r(void)
{

}

void Coef_is_Msr_1_0_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 1, 0) ;
}

// ------------------------------------------------------------------

// ---- Coef_is_Msr_2_0_theta_r ---------------------------------------------

Coef_is_Msr_2_0_theta_r::Coef_is_Msr_2_0_theta_r(void)
{
  CoefFuncName = COEF_FUNC_is_Msr_2_0_theta_r;
  LiteralName = "is_Msr_2_0_theta_r";
}

Coef_is_Msr_2_0_theta_r::~Coef_is_Msr_2_0_theta_r(void)
{

}

void Coef_is_Msr_2_0_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 2, 0) ;
}

// ------------------------------------------------------------------

// ---- Coef_is_Msr_0_1_theta_r ---------------------------------------------

Coef_is_Msr_0_1_theta_r::Coef_is_Msr_0_1_theta_r(void)
{
  CoefFuncName = COEF_FUNC_is_Msr_0_1_theta_r;
  LiteralName = "is_Msr_0_1_theta_r";
}

Coef_is_Msr_0_1_theta_r::~Coef_is_Msr_0_1_theta_r(void)
{

}

void Coef_is_Msr_0_1_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 0,1) ;
}

// ------------------------------------------------------------------

// ---- Coef_is_Msr_1_1_theta_r ---------------------------------------------

Coef_is_Msr_1_1_theta_r::Coef_is_Msr_1_1_theta_r(void)
{
  CoefFuncName = COEF_FUNC_is_Msr_1_1_theta_r;
  LiteralName = "is_Msr_1_1_theta_r";
}

Coef_is_Msr_1_1_theta_r::~Coef_is_Msr_1_1_theta_r(void)
{

}

void Coef_is_Msr_1_1_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 1, 1) ;
}

// ------------------------------------------------------------------

// ---- Coef_is_Msr_2_1_theta_r ---------------------------------------------

Coef_is_Msr_2_1_theta_r::Coef_is_Msr_2_1_theta_r(void)
{
  CoefFuncName = COEF_FUNC_is_Msr_2_1_theta_r;
  LiteralName = "is_Msr_2_1_theta_r";
}

Coef_is_Msr_2_1_theta_r::~Coef_is_Msr_2_1_theta_r(void)
{

}

void Coef_is_Msr_2_1_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 2, 1) ;
}

// ------------------------------------------------------------------

// ---- Coef_is_Msr_0_2_theta_r ---------------------------------------------

Coef_is_Msr_0_2_theta_r::Coef_is_Msr_0_2_theta_r(void)
{
  CoefFuncName = COEF_FUNC_is_Msr_0_2_theta_r;
  LiteralName = "is_Msr_0_2_theta_r";
}

Coef_is_Msr_0_2_theta_r::~Coef_is_Msr_0_2_theta_r(void)
{

}

void Coef_is_Msr_0_2_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 0,2) ;
}

// ------------------------------------------------------------------

// ---- Coef_is_Msr_1_2_theta_r ---------------------------------------------

Coef_is_Msr_1_2_theta_r::Coef_is_Msr_1_2_theta_r(void)
{
  CoefFuncName = COEF_FUNC_is_Msr_1_2_theta_r;
  LiteralName = "is_Msr_1_2_theta_r";
}

Coef_is_Msr_1_2_theta_r::~Coef_is_Msr_1_2_theta_r(void)
{

}

void Coef_is_Msr_1_2_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 1, 2) ;
}

// ------------------------------------------------------------------

// ---- Coef_is_Msr_2_2_theta_r ---------------------------------------------

Coef_is_Msr_2_2_theta_r::Coef_is_Msr_2_2_theta_r(void)
{
  CoefFuncName = COEF_FUNC_is_Msr_2_2_theta_r;
  LiteralName = "is_Msr_2_2_theta_r";
}

Coef_is_Msr_2_2_theta_r::~Coef_is_Msr_2_2_theta_r(void)
{

}

void Coef_is_Msr_2_2_theta_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{
  y = InterpolateThetaRArray(Msr, 2, 2) ;
}

// ------------------------------------------------------------------

#endif

	// Special CoefObject functions for "LagrangeSolve" SpiceObject.
	// These CoefObjects functions along with the "LagrangeSolve" SpiceObject are used
	// in CtrlObject "RefGen". Note that we do not assign "CoefFuncName" to these functions.

// ---- Coef_Eq_41_k1 ---------------------------------------------

Coef_Eq_41_k1::Coef_Eq_41_k1(void)
{
	LiteralName = "Eq_41_k1";
}

Coef_Eq_41_k1::~Coef_Eq_41_k1(void)
{

}

void Coef_Eq_41_k1::CoefFunction(double recp_h, bool DoTrapezoidal)
{
	y = - (is_sdq_q_r*(Qsync_rm[0][1] + Qsyncd_rm[0][1]) + ir_sdq_q_r*(Qsync_rm[0][3] + Qsyncd_rm[0][3]));
}

// ---------------------------------------------------------------------------

// ---- Coef_Eq_41_k2 ---------------------------------------------

Coef_Eq_41_k2::Coef_Eq_41_k2(void)
{
	LiteralName = "Eq_41_k2";
}

Coef_Eq_41_k2::~Coef_Eq_41_k2(void)
{

}

void Coef_Eq_41_k2::CoefFunction(double recp_h, bool DoTrapezoidal)
{
	y = - (is_sdq_d_r*(Qsync_rm[1][0] + Qsyncd_rm[1][0]) + ir_sdq_d_r*(Qsync_rm[1][2] + Qsyncd_rm[1][2]));
}

// ---------------------------------------------------------------------------

// ---- Coef_Eq_41_k3 ---------------------------------------------

Coef_Eq_41_k3::Coef_Eq_41_k3(void)
{
	LiteralName = "Eq_41_k3";
}

Coef_Eq_41_k3::~Coef_Eq_41_k3(void)
{

}

void Coef_Eq_41_k3::CoefFunction(double recp_h, bool DoTrapezoidal)
{
	y = - (is_sdq_q_r*(Qsync_rm[2][1] + Qsyncd_rm[2][1]) + ir_sdq_q_r*(Qsync_rm[2][3] + Qsyncd_rm[2][3]));
}

// ---------------------------------------------------------------------------

// ---- Coef_Eq_41_k4 ---------------------------------------------

Coef_Eq_41_k4::Coef_Eq_41_k4(void)
{
	LiteralName = "Eq_41_k4";
}

Coef_Eq_41_k4::~Coef_Eq_41_k4(void)
{

}

void Coef_Eq_41_k4::CoefFunction(double recp_h, bool DoTrapezoidal)
{
	y = - (is_sdq_d_r*(Qsync_rm[3][0] + Qsyncd_rm[3][0]) + ir_sdq_d_r*(Qsync_rm[3][2] + Qsyncd_rm[3][2]));
}

// ---------------------------------------------------------------------------

// ---- Coef_Eq_42_k1 ---------------------------------------------

Coef_Eq_42_k1::Coef_Eq_42_k1(void)
{
	LiteralName = "Eq_42_k1";
}

Coef_Eq_42_k1::~Coef_Eq_42_k1(void)
{

}

void Coef_Eq_42_k1::CoefFunction(double recp_h, bool DoTrapezoidal)
{
	y = (is_sdq_q_r*Qsyncd_rm[0][1] + ir_sdq_q_r*Qsyncd_rm[0][3]);
}

// ---------------------------------------------------------------------------

// ---- Coef_Eq_42_k2 ---------------------------------------------

Coef_Eq_42_k2::Coef_Eq_42_k2(void)
{
	LiteralName = "Eq_42_k2";
}

Coef_Eq_42_k2::~Coef_Eq_42_k2(void)
{

}

void Coef_Eq_42_k2::CoefFunction(double recp_h, bool DoTrapezoidal)
{
	y = (is_sdq_d_r*Qsyncd_rm[1][0] + ir_sdq_d_r*Qsyncd_rm[1][2]);
}

// ---------------------------------------------------------------------------

// ---- Coef_Eq_42_k3 ---------------------------------------------

Coef_Eq_42_k3::Coef_Eq_42_k3(void)
{
	LiteralName = "Eq_42_k3";
}

Coef_Eq_42_k3::~Coef_Eq_42_k3(void)
{

}

void Coef_Eq_42_k3::CoefFunction(double recp_h, bool DoTrapezoidal)
{
	y = (is_sdq_q_r*Qsyncd_rm[2][1] + ir_sdq_q_r*Qsyncd_rm[2][3]);
}

// ---------------------------------------------------------------------------

// ---- Coef_Eq_42_k4 ---------------------------------------------

Coef_Eq_42_k4::Coef_Eq_42_k4(void)
{
	LiteralName = "Eq_42_k4";
}

Coef_Eq_42_k4::~Coef_Eq_42_k4(void)
{

}

void Coef_Eq_42_k4::CoefFunction(double recp_h, bool DoTrapezoidal)
{
	y = (is_sdq_d_r*Qsyncd_rm[3][0] + ir_sdq_d_r*Qsyncd_rm[3][2]);
}

// ---------------------------------------------------------------------------

// ---- Coef_Eq_30_is_ir_omega_r -----------------------------

Coef_Eq_30_is_ir_omega_r::Coef_Eq_30_is_ir_omega_r(void)
{
	LiteralName = "Eq_30_is_ir_omega_r";
}

Coef_Eq_30_is_ir_omega_r::~Coef_Eq_30_is_ir_omega_r(void)
{

}

void Coef_Eq_30_is_ir_omega_r::CoefFunction(double recp_h, bool DoTrapezoidal)
{		//(This is the right side of the solution.)
	y = - is_sdq_d_r * Rsync_rm[0][0] - ir_sdq_d_r * Rsync_rm[0][2] - omega_r_r * (is_sdq_q_r * Qsync_rm[0][1] + ir_sdq_q_r * Qsync_rm[0][3]) -
																							          omega_r_r * (is_sdq_q_r * Qsyncd_rm[0][1] + ir_sdq_q_r * Qsyncd_rm[0][3]);
}

// --------------------------------------------------------------------------

// ---- Coef_Eq_30_omega_s ------------------------------------

Coef_Eq_30_omega_s::Coef_Eq_30_omega_s(void)
{
	LiteralName = "Eq_30_omega_s";
}

Coef_Eq_30_omega_s::~Coef_Eq_30_omega_s(void)
{

}

void Coef_Eq_30_omega_s::CoefFunction(double recp_h, bool DoTrapezoidal)
{
	y = - (is_sdq_q_r * Qsyncd_rm[0][1] + ir_sdq_q_r * Qsyncd_rm[0][3]);
}

// --------------------------------------------------------------------------


// ---- Coef_Eq_31_is_ir_omega_r -----------------------------

  Coef_Eq_31_is_ir_omega_r::Coef_Eq_31_is_ir_omega_r(void)
  {
  	LiteralName = "Eq_31_is_ir_omega_r";
  }

  Coef_Eq_31_is_ir_omega_r::~Coef_Eq_31_is_ir_omega_r(void)
  {

  }

  void Coef_Eq_31_is_ir_omega_r::CoefFunction(double recp_h, bool DoTrapezoidal)
  {		//(This is the right side of the solution.)
  	y = - vs_sdq_q_r*Msync_r_1[1][1] - is_sdq_q_r * Rsync_rm[1][1] - ir_sdq_q_r * Rsync_rm[1][3] - omega_r_r * (is_sdq_d_r * Qsync_rm[1][0] + ir_sdq_d_r * Qsync_rm[1][2]) -
  																							   	                                               omega_r_r * (is_sdq_d_r * Qsyncd_rm[1][0] + ir_sdq_d_r * Qsyncd_rm[1][2]);
  }

// --------------------------------------------------------------------------

// ---- Coef_Eq_31_omega_s ------------------------------------

  Coef_Eq_31_omega_s::Coef_Eq_31_omega_s(void)
  {
  	LiteralName = "Eq_31_omega_s";
  }

  Coef_Eq_31_omega_s::~Coef_Eq_31_omega_s(void)
  {

  }

  void Coef_Eq_31_omega_s::CoefFunction(double recp_h, bool DoTrapezoidal)
  {
  	y = - (is_sdq_d_r * Qsyncd_rm[1][0] + ir_sdq_d_r * Qsyncd_rm[1][2]);
  }

 // --------------------------------------------------------------------------








// ***********************************************************************






// **** SwitchObject Functions **************************************

// ***********************************************************************



// **** SpiceObject Functions ***************************************

// ---- GroupOdeSolve ------------------------------------------

GroupOdeSolve::GroupOdeSolve(void)
{

#ifdef TERMINAL_REF_PLANE_SIMULATION

	  InitializeMatrix(7);   //(7 rows, 8 columns)

	  //Eq. (1)
	  a_CoefObj[0][Ind_d_is_0] = 0;
	  a_Static[0][Ind_d_is_0] = Mss[0][0];
	  a_CoefObj[0][Ind_d_is_1] = 0;
	  a_Static[0][Ind_d_is_1] = Mss[0][1];
	  a_CoefObj[0][Ind_d_is_2] = 0;
	  a_Static[0][Ind_d_is_2] = Mss[0][2];
	  a_CoefObj[0][Ind_v_n] = 0;
	  a_Static[0][Ind_v_n] = 1.0;
	  a_CoefObj[0][Ind_d_ir_0] = &Coef_ir_Msr_0_0_theta_r_i;
	  a_Static[0][Ind_d_ir_0] = 1.0;
	  a_CoefObj[0][Ind_d_ir_1] = &Coef_ir_Msr_0_1_theta_r_i;
	  a_Static[0][Ind_d_ir_1] = 1.0;
	  a_CoefObj[0][Ind_d_ir_2] = &Coef_ir_Msr_0_2_theta_r_i;
	  a_Static[0][Ind_d_ir_2] = 1.0;
	  a_CoefObj[0][7] = 0;
	  a_Static[0][7] = 0;				//This element is updated in "Is3_Ir6_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".


	  //Eq. (2)
	  a_CoefObj[1][Ind_d_is_0] = 0;
	  a_Static[1][Ind_d_is_0] = Mss[1][0];
	  a_CoefObj[1][Ind_d_is_1] = 0;
	  a_Static[1][Ind_d_is_1] = Mss[1][1];
	  a_CoefObj[1][Ind_d_is_2] = 0;
	  a_Static[1][Ind_d_is_2] = Mss[1][2];
	  a_CoefObj[1][Ind_v_n] = 0;
	  a_Static[1][Ind_v_n] = 1.0;
	  a_CoefObj[1][Ind_d_ir_0] = &Coef_ir_Msr_1_0_theta_r_i;
	  a_Static[1][Ind_d_ir_0] = 1.0;
	  a_CoefObj[1][Ind_d_ir_1] = &Coef_ir_Msr_1_1_theta_r_i;
	  a_Static[1][Ind_d_ir_1] = 1.0;
	  a_CoefObj[1][Ind_d_ir_2] = &Coef_ir_Msr_1_2_theta_r_i;
	  a_Static[1][Ind_d_ir_2] = 1.0;
	  a_CoefObj[1][7] = 0;
	  a_Static[1][7] = 0;				//This element is updated in "Is3_Ir6_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".


	  //Eq. (3)
	  a_CoefObj[2][Ind_d_is_0] = 0;
	  a_Static[2][Ind_d_is_0] = Mss[2][0];
	  a_CoefObj[2][Ind_d_is_1] = 0;
	  a_Static[2][Ind_d_is_1] = Mss[2][1];
	  a_CoefObj[2][Ind_d_is_2] = 0;
	  a_Static[2][Ind_d_is_2] = Mss[2][2];
	  a_CoefObj[2][Ind_v_n] = 0;
	  a_Static[2][Ind_v_n] = 1.0;
	  a_CoefObj[2][Ind_d_ir_0] = &Coef_ir_Msr_2_0_theta_r_i;
	  a_Static[2][Ind_d_ir_0] = 1.0;
	  a_CoefObj[2][Ind_d_ir_1] = &Coef_ir_Msr_2_1_theta_r_i;
	  a_Static[2][Ind_d_ir_1] = 1.0;
	  a_CoefObj[2][Ind_d_ir_2] = &Coef_ir_Msr_2_2_theta_r_i;
	  a_Static[2][Ind_d_ir_2] = 1.0;
	  a_CoefObj[2][7] = 0;
	  a_Static[2][7] = 0;				//This element is updated in "Is3_Ir6_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".



	  //Eq. (4)
	  a_CoefObj[3][Ind_d_is_0] = 0;
	  a_Static[3][Ind_d_is_0] = 1.0;
	  a_CoefObj[3][Ind_d_is_1] = 0;
	  a_Static[3][Ind_d_is_1] = 1.0;
	  a_CoefObj[3][Ind_d_is_2] = 0;
	  a_Static[3][Ind_d_is_2] = 1.0;
	  a_CoefObj[3][Ind_v_n] = 0;
	  a_Static[3][Ind_v_n] = 0;
	  a_CoefObj[3][Ind_d_ir_0] = 0;
	  a_Static[3][Ind_d_ir_0] = 0;
	  a_CoefObj[3][Ind_d_ir_1] = 0;
	  a_Static[3][Ind_d_ir_1] = 0;
	  a_CoefObj[3][Ind_d_ir_2] = 0;
	  a_Static[3][Ind_d_ir_2] = 0;
	  a_CoefObj[3][7] = 0;
	  a_Static[3][7] = 0;		  	//"dcurrent" sum is always zero.




	  //Eq. (5)
	  a_CoefObj[4][Ind_d_is_0] = &Coef_is_Msr_0_0_theta_r_i;
	  a_Static[4][Ind_d_is_0] =  1.0;
	  a_CoefObj[4][Ind_d_is_1] = &Coef_is_Msr_1_0_theta_r_i;
	  a_Static[4][Ind_d_is_1] =  1.0;
	  a_CoefObj[4][Ind_d_is_2] = &Coef_is_Msr_2_0_theta_r_i;
	  a_Static[4][Ind_d_is_2] =  1.0;
	  a_CoefObj[4][Ind_v_n] = 0;
	  a_Static[4][Ind_v_n] = 0;
	  a_CoefObj[4][Ind_d_ir_0] = 0;
	  a_Static[4][Ind_d_ir_0] = Mrr[0][0];
	  a_CoefObj[4][Ind_d_ir_1] = 0;
	  a_Static[4][Ind_d_ir_1] = Mrr[0][1];
	  a_CoefObj[4][Ind_d_ir_2] = 0;
	  a_Static[4][Ind_d_ir_2] = Mrr[0][2];
	  a_CoefObj[4][7] = 0;
	  a_Static[4][7] = 0;				//This element is updated in "Is3_Ir6_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".


	  //Eq. (6)
	  a_CoefObj[5][Ind_d_is_0] = &Coef_is_Msr_0_1_theta_r_i;
	  a_Static[5][Ind_d_is_0] =  1.0;
	  a_CoefObj[5][Ind_d_is_1] = &Coef_is_Msr_1_1_theta_r_i;
	  a_Static[5][Ind_d_is_1] =  1.0;
	  a_CoefObj[5][Ind_d_is_2] = &Coef_is_Msr_2_1_theta_r_i;
	  a_Static[5][Ind_d_is_2] =  1.0;
	  a_CoefObj[5][Ind_v_n] = 0;
	  a_Static[5][Ind_v_n] = 0;
	  a_CoefObj[5][Ind_d_ir_0] = 0;
	  a_Static[5][Ind_d_ir_0] = Mrr[1][0];
	  a_CoefObj[5][Ind_d_ir_1] = 0;
	  a_Static[5][Ind_d_ir_1] = Mrr[1][1];
	  a_CoefObj[5][Ind_d_ir_2] = 0;
	  a_Static[5][Ind_d_ir_2] = Mrr[1][2];
	  a_CoefObj[5][7] = 0;
	  a_Static[5][7] = 0;				//This element is updated in "Is3_Ir6_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".


	  //Eq. (7)
	  a_CoefObj[6][Ind_d_is_0] = &Coef_is_Msr_0_2_theta_r_i;
	  a_Static[6][Ind_d_is_0] =  1.0;
	  a_CoefObj[6][Ind_d_is_1] = &Coef_is_Msr_1_2_theta_r_i;
	  a_Static[6][Ind_d_is_1] =  1.0;
	  a_CoefObj[6][Ind_d_is_2] = &Coef_is_Msr_2_2_theta_r_i;
	  a_Static[6][Ind_d_is_2] =  1.0;
	  a_CoefObj[6][Ind_v_n] = 0;
	  a_Static[6][Ind_v_n] = 0;
	  a_CoefObj[6][Ind_d_ir_0] = 0;
	  a_Static[6][Ind_d_ir_0] = Mrr[2][0];
	  a_CoefObj[6][Ind_d_ir_1] = 0;
	  a_Static[6][Ind_d_ir_1] = Mrr[2][1];
	  a_CoefObj[6][Ind_d_ir_2] = 0;
	  a_Static[6][Ind_d_ir_2] = Mrr[2][2];
	  a_CoefObj[6][7] = 0;
	  a_Static[6][7] = 0;				//This element is updated in "Is3_Ir6_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".

#else

	  InitializeMatrix(4);   //(4 rows, 5 columns)

	  //Eq. (20)
	  a_CoefObj[0][Ind_d_is_sdq_d] = 0;
	  a_Static[0][Ind_d_is_sdq_d] = Msync0s[0][0];
	  a_CoefObj[0][ Ind_d_is_sdq_q] = 0;
	  a_Static[0][ Ind_d_is_sdq_q] = 0;
	  a_CoefObj[0][Ind_d_ir_sdq_d] = 0;
	  a_Static[0][Ind_d_ir_sdq_d] = Msyncsr[0][0];
	  a_CoefObj[0][Ind_d_ir_sdq_q] = 0;
	  a_Static[0][Ind_d_ir_sdq_q] = 0;
	  a_CoefObj[0][4] = 0;
	  a_Static[0][4] = 0;				//This element is updated in "Is_Ir_sdq_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".

	  //Eq. (21)
	  a_CoefObj[1][Ind_d_is_sdq_d] = 0;
	  a_Static[1][Ind_d_is_sdq_d] = 0;
	  a_CoefObj[1][ Ind_d_is_sdq_q] = 0;
	  a_Static[1][ Ind_d_is_sdq_q] = Msync0s[1][1];
	  a_CoefObj[1][Ind_d_ir_sdq_d] = 0;
	  a_Static[1][Ind_d_ir_sdq_d] = 0;
	  a_CoefObj[1][Ind_d_ir_sdq_q] = 0;
	  a_Static[1][Ind_d_ir_sdq_q] = Msyncsr[1][1];
	  a_CoefObj[1][4] = 0;
	  a_Static[1][4] = 0;				//This element is updated in "Is_Ir_sdq_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".

	  //Eq. (23)
	  a_CoefObj[2][Ind_d_is_sdq_d] = 0;
	  a_Static[2][Ind_d_is_sdq_d] = Msyncsr_t[0][0];
	  a_CoefObj[2][ Ind_d_is_sdq_q] = 0;
	  a_Static[2][ Ind_d_is_sdq_q] = 0;
	  a_CoefObj[2][Ind_d_ir_sdq_d] = 0;
	  a_Static[2][Ind_d_ir_sdq_d] = Msyncr[0][0];
	  a_CoefObj[2][Ind_d_ir_sdq_q] = 0;
	  a_Static[2][Ind_d_ir_sdq_q] = 0;
	  a_CoefObj[2][4] = 0;
	  a_Static[2][4] = 0;				//This element is updated in "Is_Ir_sdq_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".

	  //Eq. (24)
	  a_CoefObj[3][Ind_d_is_sdq_d] = 0;
	  a_Static[3][Ind_d_is_sdq_d] = 0;
	  a_CoefObj[3][ Ind_d_is_sdq_q] = 0;
	  a_Static[3][ Ind_d_is_sdq_q] = Msyncsr_t[1][1];
	  a_CoefObj[3][Ind_d_ir_sdq_d] = 0;
	  a_Static[3][Ind_d_ir_sdq_d] = 0;
	  a_CoefObj[3][Ind_d_ir_sdq_q] = 0;
	  a_Static[3][Ind_d_ir_sdq_q] = Msyncr[1][1];
	  a_CoefObj[3][4] = 0;
	  a_Static[3][4] = 0;				//This element is updated in "Is_Ir_sdq_1::OdeGroupMSolve()" before call to "GroupOdeSolve::PreSpiceFunction()".





#endif

}

GroupOdeSolve::~GroupOdeSolve(void)
{


}



// ----------------------------------------------------------------------


// ---- LagrangeSolve ------------------------------------------

LagrangeSolve::LagrangeSolve(void)
{

		//See "RefGen::CtrlFunction()" for call to "LagrangeSolve_i::PreSpiceFunction()" and "LagrangeSolve_i::Guass()".

	  InitializeMatrix(6);   //(6 rows, 7 columns)


	  	  //See Eq. (35) in CtrlObject "RefGen"
	  a_CoefObj[0][Ind_k1] = 0;
	  a_Static[0][Ind_k1] = Msync_r_1[0][0];
	  a_CoefObj[0][Ind_k2] = 0;
	  a_Static[0][Ind_k2] = 0;
	  a_CoefObj[0][Ind_k3] = 0;
	  a_Static[0][Ind_k3] = Msync_r_1[2][0];
	  a_CoefObj[0][Ind_k4] = 0;
	  a_Static[0][Ind_k4] = 0;
	  a_CoefObj[0][Ind_Omega_s] = 0;
	  a_Static[0][Ind_Omega_s] = 0;
	  a_CoefObj[0][Ind_vs_sdq_d] = 0;
	  a_Static[0][Ind_vs_sdq_d] = - 2.0;
	  a_CoefObj[0][6] = 0;
	  a_Static[0][6] = 0;


	  	  //See Eq. (36) in CtrlObject "RefGen"
	  a_CoefObj[1][Ind_k1] = 0;
	  a_Static[1][Ind_k1] = 0;
	  a_CoefObj[1][Ind_k2] = 0;
	  a_Static[1][Ind_k2] = Msync_r_1[1][1];
	  a_CoefObj[1][Ind_k3] = 0;
	  a_Static[1][Ind_k3] = 0;
	  a_CoefObj[1][Ind_k4] = 0;
	  a_Static[1][Ind_k4] = Msync_r_1[3][1];
	  a_CoefObj[1][Ind_Omega_s] = 0;
	  a_Static[1][Ind_Omega_s] = 0;
	  a_CoefObj[1][Ind_vs_sdq_d] = 0;
	  a_Static[1][Ind_vs_sdq_d] = 0;
	  a_CoefObj[1][6] = 0;
	  a_Static[1][6] = 2*vs_sdq_q_r;


  	  //See Eq. (41) in CtrlObject "RefGen"
	  a_CoefObj[2][Ind_k1] = &Coef_Eq_41_k1_i;
	  a_Static[2][Ind_k1] = 1.0;
	  a_CoefObj[2][Ind_k2] = &Coef_Eq_41_k2_i;
	  a_Static[2][Ind_k2] = 1.0;
	  a_CoefObj[2][Ind_k3] = &Coef_Eq_41_k3_i;
	  a_Static[2][Ind_k3] = 1.0;
	  a_CoefObj[2][Ind_k4] = &Coef_Eq_41_k4_i;
	  a_Static[2][Ind_k4] = 1.0;
	  a_CoefObj[2][Ind_Omega_s] = 0;
	  a_Static[2][Ind_Omega_s] = 0;
	  a_CoefObj[2][Ind_vs_sdq_d] = 0;
	  a_Static[2][Ind_vs_sdq_d] = 0;
	  a_CoefObj[2][6] = 0;
	  a_Static[2][6] = 0;


  	  //See Eq. (42) in CtrlObject "RefGen"
	  a_CoefObj[3][Ind_k1] = &Coef_Eq_42_k1_i;
	  a_Static[3][Ind_k1] = 1.0;
	  a_CoefObj[3][Ind_k2] = &Coef_Eq_42_k2_i;
	  a_Static[3][Ind_k2] = 1.0;
	  a_CoefObj[3][Ind_k3] = &Coef_Eq_42_k3_i;
	  a_Static[3][Ind_k3] = 1.0;
	  a_CoefObj[3][Ind_k4] = &Coef_Eq_42_k4_i;
	  a_Static[3][Ind_k4] = 1.0;
	  a_CoefObj[3][Ind_Omega_s] = 0;
	  a_Static[3][Ind_Omega_s] = 0;
	  a_CoefObj[3][Ind_vs_sdq_d] = 0;
	  a_Static[3][Ind_vs_sdq_d] = 0;
	  a_CoefObj[3][6] = 0;
	  a_Static[3][6] = 0;


  	  //See Eq. (30) in CtrlObject "RefGen"
	  a_CoefObj[4][Ind_k1] = 0;
	  a_Static[4][Ind_k1] = 0;
	  a_CoefObj[4][Ind_k2] = 0;
	  a_Static[4][Ind_k2] = 0;
	  a_CoefObj[4][Ind_k3] = 0;
	  a_Static[4][Ind_k3] = 0;
	  a_CoefObj[4][Ind_k4] = 0;
	  a_Static[4][Ind_k4] = 0;
	  a_CoefObj[4][Ind_Omega_s] = &Coef_Eq_30_omega_s_i;
	  a_Static[4][Ind_Omega_s] = 1.0;
	  a_CoefObj[4][Ind_vs_sdq_d] = 0;
	  a_Static[4][Ind_vs_sdq_d] = - Msync_r_1[0][0];
	  a_CoefObj[4][6] = &Coef_Eq_30_is_ir_omega_r_i;
	  a_Static[4][6] = 1.0;


  	  //See Eq. (31) in CtrlObject "RefGen"
	  a_CoefObj[5][Ind_k1] = 0;
	  a_Static[5][Ind_k1] = 0;
	  a_CoefObj[5][Ind_k2] = 0;
	  a_Static[5][Ind_k2] = 0;
	  a_CoefObj[5][Ind_k3] = 0;
	  a_Static[5][Ind_k3] = 0;
	  a_CoefObj[5][Ind_k4] = 0;
	  a_Static[5][Ind_k4] = 0;
	  a_CoefObj[5][Ind_Omega_s] = &Coef_Eq_31_omega_s_i;
	  a_Static[5][Ind_Omega_s] = 1.0;
	  a_CoefObj[5][Ind_vs_sdq_d] = 0;
	  a_Static[5][Ind_vs_sdq_d] = 0;
	  a_CoefObj[5][6] = &Coef_Eq_31_is_ir_omega_r_i;
	  a_Static[5][6] = 1.0;




}

LagrangeSolve::~LagrangeSolve(void)
{


}



// ----------------------------------------------------------------------


  
// ***********************************************************************



// **** SimuObject ************************************************




SimuObject Simulation;

SimuObject::SimuObject(void)
{
  OdeObjItem * pCurOdeItem;
  SrcObjItem * pCurSrcItem;
  CtrlObjItem * pCurCtrlItem;
  CtrlObjGroup * pCurCtrlGroup; 
  int i;

  printf("%g", Rr_matrix_loop     );
  SimuTime = 10.0;
  
  MinimumPlotTime = 0;
  MaximumPlotTime = 10;

  // !!!!!!!!!!!! TEMPORARY !!!!!!!!!!!!!!!!!!1
   // OdeSimuFixed = true;
  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  ExceptionTime = .05;

  //For this example the setting of "RelTol" is important. If it is set to large
  //the system will become unstable. 
  RelTol =  .0000000001;
  //Setting "AbsTol" too small will make a system with a decaying oscillation 
  //take too long to finish.
  AbsTol =  .0000000000001;
  //typical error correction setting as per "RungeKutta_java.htm" (never set higher then "1.0")
  Safety = .98;
  h_start = .000000001; 

  h = h_start;

  //set to a value other then "0" to clamp maximum "h";
  h_max = .00002;

  //set to store and plot "h" parameter.
  Do_h_Plot = 1;
  
  TimeQuantum = h;
  CtrlTimeQuantum = QUANTUM_PERIOD;

  //set tp force CTRL update on first ODE update.
  CtrlTimeAccumulator = 0;

  SrcPeriodQuantum = QUANTUM_PERIOD;
  SrcPeriodAccumulator = 0;
 

  //build the SRC equation list
  pSrcEquationList = new SrcObjItem;
  pCurSrcItem = pSrcEquationList;
  i = 0;
  while(SrcObjectList[i]){
    pCurSrcItem->pSrcObject = SrcObjectList[i];
    i++;
    if(!SrcObjectList[i])
      break;
    pCurSrcItem->pNextSrcItem = new SrcObjItem;
    pCurSrcItem = pCurSrcItem->pNextSrcItem;


  }

  //build the ODE equation list.
  pOdeEquationList = new OdeObjItem;
  pCurOdeItem = pOdeEquationList;
  i = 0;
  while(1){
    pCurOdeItem->pOdeObject = OdeObjectList[i];
    i++;
    if(!OdeObjectList[i])
      break;
    pCurOdeItem->pNextOdeItem = new OdeObjItem;
    pCurOdeItem = pCurOdeItem->pNextOdeItem;
  }

  //build the CTRL equation lists.

  //(NOTE: As of 6/12/08, "pTranslationList" and "pTrajectoryList" CTRL's have been 
  //       deprecated and replaced with a "group" structure.)

  pCtrlGroupList = new CtrlObjGroup;
  pCurCtrlGroup = pCtrlGroupList;

  pCurCtrlGroup->pCtrlEquationList = new CtrlObjItem;
  pCurCtrlItem = pCurCtrlGroup->pCtrlEquationList;
  //set tp force CTRL update on first ODE update.
  pCurCtrlGroup->QuantumCount = 1;
  pCurCtrlGroup->QuantumNum = CtrlObjectQuantum[0];

  i = 0;
  while(1){
    pCurCtrlItem->pCtrlObject = CtrlObjectList[i];   
    i++;
    if(!CtrlObjectList[i])                 
      break;

    if(CtrlObjectQuantum[i] == CtrlObjectQuantum[i-1]){
      pCurCtrlItem->pNextCtrlItem = new CtrlObjItem;
      pCurCtrlItem = pCurCtrlItem->pNextCtrlItem;
    }
    else{
      //create a new group...
      pCtrlGroupList->pNextCtrlGroup = new CtrlObjGroup;
      pCurCtrlGroup = pCtrlGroupList->pNextCtrlGroup;

      pCurCtrlGroup->pCtrlEquationList = new CtrlObjItem;
      pCurCtrlItem = pCurCtrlGroup->pCtrlEquationList;
      //set tp force CTRL update on first ODE update.
      pCurCtrlGroup->QuantumCount = 1;
      pCurCtrlGroup->QuantumNum = CtrlObjectQuantum[i];  
    }
  }



 

}


SimuObject::~SimuObject(void)
{

  //(ideally we should delete all make allocation make in the constructor, here)

}



// ************************************************************





bool ExecuteSimulation(void)
{

   

  Simulation.OdeSimuType = ODE_SIMU_56;

  while(Simulation.t < Simulation.SimuTime){               

    if(!Simulation.DoOneInteration())
      return FALSE;
    
  }
  if(Simulation.GotException){
    cout << Simulation.ExceptionMessageBuffer.str().c_str();
  }

  return TRUE;
}

void PlotResults(string TagNamesToPlot[], double ScaleFactors[], double MinPlotTimes[], double MaxPlotTimes[], 
		 double PlotTimeSteps[], double PlotTimeOffset)
{
  Simulation.PlotSimuResults(TagNamesToPlot, ScaleFactors, MinPlotTimes, MaxPlotTimes, PlotTimeSteps, PlotTimeOffset);


}
