/[ascend]/trunk/models/johnpye/nrel/asc_sunpos.c
ViewVC logotype

Contents of /trunk/models/johnpye/nrel/asc_sunpos.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2584 - (show annotations) (download) (as text)
Tue Apr 10 16:11:39 2012 UTC (11 years, 5 months ago) by jpye
File MIME type: text/x-csrc
File size: 6460 byte(s)
sunpos model works, need to check integration with weather data (timezones, JD conversion, etc).
1 /* ASCEND modelling environment
2 Copyright (C) 2008 Carnegie Mellon University
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18 *//** @file
19 Wrapper for sunpos_nrel.c to allow access to the calculation from ASCEND.
20 */
21
22 /* include the external function API from libascend... */
23 #include <ascend/compiler/extfunc.h>
24
25 /* include error reporting API as well, so we can send messages to user */
26 #include <ascend/utilities/error.h>
27
28 /* for accessing the DATA instance */
29 #include <ascend/compiler/child.h>
30 #include <ascend/general/list.h>
31 #include <ascend/compiler/module.h>
32 #include <ascend/compiler/childinfo.h>
33 #include <ascend/compiler/parentchild.h>
34 #include <ascend/compiler/slist.h>
35 #include <ascend/compiler/type_desc.h>
36 #include <ascend/compiler/packages.h>
37 #include <ascend/compiler/symtab.h>
38 #include <ascend/compiler/instquery.h>
39 #include <ascend/compiler/instmacro.h>
40 #include <ascend/compiler/instance_types.h>
41
42 /* the code that we're wrapping... */
43 #include "spa.h"
44
45 #ifndef PI
46 # define PI 3.14159265358979
47 #endif
48
49 ExtBBoxInitFunc sunpos_nrel_prepare;
50 ExtBBoxFunc sunpos_nrel_calc;
51
52 static const char *sunpos_nrel_help = "Calculate sun position (local zenith, azimuth "
53 "angles) given time, pressure and temperature, using NREL algorithm. DATA "
54 "member for this external relation is required to provide constants for "
55 "latitude and longitude of the selected location.\n\n"
56 "Time is required to be in the form of Julian Date. ASCEND will convert the "
57 "Julian Date into seconds automatically. The JD should be in the range"
58 "-2000 BC to 6000 AD (12:00pm 1 Jan 2000 GMT is 2451545.0 JD)";
59
60 /*------------------------------------------------------------------------------
61 REGISTRATION FUNCTION
62 */
63
64 /**
65 This is the function called from 'IMPORT "johnpye/grena/sunpos";'
66
67 It sets up the functions contained in this external library
68 */
69 extern
70 ASC_EXPORT int sunpos_nrel_register(){
71 int result = 0;
72
73 ERROR_REPORTER_HERE(ASC_USER_WARNING,"SUNPOS is still EXPERIMENTAL. Use with caution.\n");
74
75 #define CALCFN(NAME,INPUTS,OUTPUTS) \
76 result += CreateUserFunctionBlackBox(#NAME \
77 , sunpos_nrel_prepare \
78 , NAME##_calc /* value */ \
79 , (ExtBBoxFunc*)NULL /* derivatives not provided yet*/ \
80 , (ExtBBoxFunc*)NULL /* hessian not provided yet */ \
81 , (ExtBBoxFinalFunc*)NULL /* finalisation not implemented */ \
82 , INPUTS,OUTPUTS /* inputs, outputs */ \
83 , NAME##_help /* help text */ \
84 , 0.0 \
85 ) /* returns 0 on success */
86
87 CALCFN(sunpos_nrel,3,2);
88
89 #undef CALCFN
90
91 if(result){
92 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"CreateUserFunction result = %d\n",result);
93 }
94 return result;
95 }
96
97
98 /**
99 This function is called when the black-box relation is being instantiated.
100
101 'sunpos_prepare' just gets the data member and checks that it's
102 valid, and stores it in the blackbox data field.
103 */
104 int sunpos_nrel_prepare(struct BBoxInterp *bbox,
105 struct Instance *data,
106 struct gl_list_t *arglist
107 ){
108 struct Instance *inst;
109 double latitude, longitude, elevation;
110
111 /* fetch DATA items for geographical location, timezone etc */
112 #define GET_CHILD_VAL(NAME) \
113 inst = ChildByChar(data,AddSymbol(#NAME)); \
114 if(!inst){ \
115 ERROR_REPORTER_HERE(ASC_USER_ERROR \
116 ,"Couldn't locate '" #NAME "' in DATA, please check usage of SUNPOS."\
117 );\
118 return 1;\
119 }\
120 if(InstanceKind(inst)!=REAL_CONSTANT_INST){\
121 ERROR_REPORTER_HERE(ASC_USER_ERROR,"DATA member '" #NAME "' must be a real_constant");\
122 return 1;\
123 }\
124 NAME = RC_INST(inst)->value;
125
126 /* get the latitude */
127 GET_CHILD_VAL(latitude);
128 CONSOLE_DEBUG("Latitude: %0.3f",latitude);
129 if(latitude > PI/2 || latitude < -PI/2){
130 ERROR_REPORTER_HERE(ASC_USER_ERROR,"'latitude' is out of allowable range -PI/2 to PI/2.");
131 return 1;
132 }
133
134 /* get the longitude */
135 GET_CHILD_VAL(longitude);
136 CONSOLE_DEBUG("Longitude: %0.3f",longitude);
137 if(longitude > PI || longitude < -PI){
138 ERROR_REPORTER_HERE(ASC_USER_ERROR,"'latitude' is out of allowable range -PI to PI.");
139 return 1;
140 }
141
142 /* get the elevation */
143 GET_CHILD_VAL(elevation);
144 CONSOLE_DEBUG("Elevation: %0.3f m",elevation);
145 if(elevation < -6500000){
146 ERROR_REPORTER_HERE(ASC_USER_ERROR,"'elevation' is out of allowable range (must be > -6,500 km)");
147 return 1;
148 }
149
150 #undef GET_CHILD_VAL
151
152 spa_data *S = ASC_NEW(spa_data);
153 S->latitude = latitude * 180/PI;
154 S->longitude = longitude * 180/PI;
155 S->elevation = elevation;
156 S->function = SPA_ZA_JD;
157
158 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Prepared position for sun position.\n");
159 bbox->user_data = (void *)S;
160 return 0;
161 }
162
163 #define CALCPREPARE(NIN,NOUT) \
164 /* a few checks about the input requirements */ \
165 if(ninputs != NIN)return -1; \
166 if(noutputs != NOUT)return -2; \
167 if(inputs==NULL)return -3; \
168 if(outputs==NULL)return -4; \
169 if(bbox==NULL)return -5; \
170 \
171 /* the 'user_data' in the black box object will contain the */\
172 /* coefficients required for this fluid; cast it to the required form: */\
173 const spa_data *sunpos1 = (const spa_data *)bbox->user_data
174
175
176 /**
177 Evaluation function for 'sunpos'
178 @return 0 on success
179 */
180 int sunpos_nrel_calc(struct BBoxInterp *bbox,
181 int ninputs, int noutputs,
182 double *inputs, double *outputs,
183 double *jacobian
184 ){
185 CALCPREPARE(3,2);
186
187 double t, p, T;
188
189 t = inputs[0]/ 86400.; /* convert from JD seconds to JD days */
190 p = inputs[1] / 100. /* convert Pa to mbar */;
191 T = inputs[2] - 273.15 /* convert ��C to K */;
192
193 spa_data S = *sunpos1;
194 S.pressure = p;
195 S.temperature = T;
196 S.jd = t;
197
198 int res = spa_calculate(&S);
199 CONSOLE_DEBUG("Sun position: t = %f JD, p %f mbar, T = %f C: res = %d, az = %f, zen = %f",t, p, T, res, S.azimuth, S.zenith);
200
201 /* returned values are in degrees, need to convert back to base SI: radians */
202 outputs[0] = S.zenith * PI/180.;
203 outputs[1] = S.azimuth * PI/180.;
204
205 /* 0 on success, non-zero is error code from spa_calculate (would prob be input parameters out-of-range) */
206 return res;
207 }
208
209
210

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22