00001
00008 #include "solar_panel.h"
00009 #include <string.h>
00010
00011
00012 ml_matrix sun_vector(double jd);
00013 ml_matrix earth_rot(double jcent);
00014 double gms_time(double jd);
00015 double jd_to_midnight(double jd);
00016 double jd_to_jcent(double jd);
00017
00018
00019 const double DEGREES_TO_RADIANS = 0.0174532925199433;
00020
00021 const double REVS_TO_DEGREES = 360.0;
00022
00023 const double JD_2000 = 2451545.0;
00024
00025 const double SECS_TO_DAYS = 1.157407407407407e-05;
00026
00027 const double DAYS_TO_CENTURIES = 2.737850787132101e-05;
00028
00029
00030
00031 solar_panel :: solar_panel(dsim_model_setup *setup) : dsim_model(setup)
00032 {
00033 }
00034
00035 void solar_panel :: initialize_data()
00036 {
00037 dsim_model::initialize_data();
00038
00039 double power_total = 0;
00040 ml_matrix normal(3,1); normal(1,1) = 1;
00041 ml_matrix area(1,1); area(1,1) = 25;
00042 ml_matrix efficiency(1,1); efficiency(1,1) = 0.22;
00043
00044 power_dsim = create_output("power", sd_type_double, &power_total, 1,1, "W", "Power panel");
00045 normal_dsim = create_parameter("normal", sd_type_matrix, &normal, 3,1, "", "Solar panel cell face normal");
00046 area_dsim = create_parameter("area", sd_type_matrix, &area, 1,1, "m^2", "Solar panel area"); ;
00047 efficiency_dsim = create_parameter("efficiency", sd_type_matrix, &efficiency, 1,1, "", "Solar panel efficiency");
00048
00049 power_dsim.mark_telemetry();
00050
00051 configure_timestep(true, false, false);
00052
00053 }
00054
00055 void solar_panel :: initialization_complete()
00056 {
00057 dsim_model::initialization_complete();
00058 }
00059
00060 void solar_panel :: pre_calculate()
00061 {
00062 dsim_model::initialize_timestep();
00063
00064 double jd = sim_jd();
00065 ml_matrix solar_flux = 1000*earth_rot(jd)*sun_vector(jd);
00066 ml_matrix n = normal_dsim.value_as_matrix();
00067 ml_matrix area = area_dsim.value_as_matrix();
00068 ml_matrix eff = efficiency_dsim.value_as_matrix();
00069
00070 double p;
00071 double power_total = 0;
00072
00073 for( int k = 1; k <= n.cols(); k++ )
00074 {
00075 p = area.get(1,k)*eff.get(1,k)*solar_flux.dot(n.get_col(k));
00076 if( p < 0 ) p = 0;
00077 power_total += p;
00078 }
00079
00080 power_dsim.set_value_as_double( power_total );
00081 }
00082
00083 double jd_to_midnight(double jd)
00084 {
00085 double jd_noon = floor(jd);
00086 return (jd - jd_noon >= 0.5) ? (jd_noon + 0.5) : (jd_noon - 0.5);
00087 }
00088
00089 double jd_to_jcent(double jd)
00090 {
00091 return (jd - JD_2000) * DAYS_TO_CENTURIES;
00092 }
00093
00094 double gms_time(double jd)
00095 {
00096
00097 double jd_mid = jd_to_midnight(jd);
00098 double t_diff = jd_to_jcent(jd_mid);
00099
00100
00101 double gmst = ((0.093104 - 6.2e-6*t_diff)*t_diff + 8640184.812866)*t_diff + 24110.54841;
00102
00103
00104 gmst *= SECS_TO_DAYS;
00105 gmst += jd-jd_mid;
00106
00107
00108 gmst = fmod(gmst*360, 360);
00109 if (gmst < 0)
00110 {
00111 gmst = gmst + 360;
00112 }
00113 return gmst;
00114 }
00115
00116
00117 ml_matrix earth_rot(double jd)
00118 {
00119
00120 double gmst = gms_time(jd);
00121 double sin_gmst = sin(gmst * DEGREES_TO_RADIANS);
00122 double cos_gmst = cos(gmst * DEGREES_TO_RADIANS);
00123 ml_matrix b(3,3);
00124 b(1,1) = cos_gmst;
00125 b(1,2) = sin_gmst;
00126 b(2,1) = -sin_gmst;
00127 b(2,2) = cos_gmst;
00128 b(3,3) = 1;
00129 return b;
00130 }
00131
00132
00133 ml_matrix sun_vector(double jd)
00134 {
00135
00136 double t_diff = jd - JD_2000;
00137 double g = fmod((357.528 + 0.9856003 * t_diff),REVS_TO_DEGREES) * DEGREES_TO_RADIANS;
00138
00139 double lam = (fmod(280.460 + 0.9856474 * t_diff, REVS_TO_DEGREES) + 1.915*sin(g) + 0.02*sin(2.0*g)) * DEGREES_TO_RADIANS;
00140
00141
00142 double ob_of_e = (23.439 - 4.00e-7 * t_diff) * DEGREES_TO_RADIANS;
00143
00144
00145 double s_lam = sin(lam);
00146 ml_matrix s_vec(3,1);
00147 s_vec(1,1) = cos(lam);
00148 s_vec(2,1) = cos(ob_of_e)*s_lam;
00149 s_vec(3,1) = sin(ob_of_e)*s_lam;
00150 return s_vec;
00151 }
00152
00153
00154
00155 extern "C"
00156 {
00157
00158 dsim_model *SolarPanelModel(void *setup);
00159
00160 dsim_model *SolarPanelModel(void *setup)
00161 {
00162 return new solar_panel((dsim_model_setup *)setup);
00163 }
00164 }