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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2584 - (hide annotations) (download) (as text)
Tue Apr 10 16:11:39 2012 UTC (10 years, 4 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 jpye 2584 /* 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