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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2594 - (show annotations) (download) (as text)
Fri Apr 13 20:20:33 2012 UTC (10 years, 2 months ago) by jpye
File MIME type: text/x-csrc
File size: 6426 byte(s)
Renaming sunpos.a4c to sunpos_db.a4c. 
Changing angle convention for NREL SPA to accord with DB & Grena.
Adding model to compare the three sunpos models.
Updating files depending on sunpos_db.a4c.
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_grena.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 "sunpos_grena.h"
44
45 ExtBBoxInitFunc sunpos_prepare;
46 ExtBBoxFunc sunpos_calc;
47
48 /* place to store symbols needed for accessing ASCEND's instance tree */
49 static symchar *sunpos_symbols[2];
50 #define LATITUDE_SYM sunpos_symbols[0]
51 #define LONGITUDE_SYM sunpos_symbols[1]
52
53 static const char *sunpos_help = "\
54 Calculate sun position (local zenith, azimuth angles) given time, pressure \n\
55 and temperature, using Grena algorithm. DATA member for this external relation \n\
56 is required to provide constants for latitude and longitude of the selected \n\
57 location.\n\
58 \n\
59 Time input to this calculation is an offset from 0h00 on 1 Jan 2003, which \n\
60 ASCEND will automatically convert to seconds if you use a variable of type \n\
61 'time'.";
62
63 /*------------------------------------------------------------------------------
64 REGISTRATION FUNCTION
65 */
66
67 /**
68 This is the function called from 'IMPORT "johnpye/grena/sunpos";'
69
70 It sets up the functions contained in this external library
71 */
72 extern
73 ASC_EXPORT int sunpos_register(){
74 int result = 0;
75
76 ERROR_REPORTER_HERE(ASC_USER_WARNING,"SUNPOS is still EXPERIMENTAL. Use with caution.\n");
77
78 #define CALCFN(NAME,INPUTS,OUTPUTS) \
79 result += CreateUserFunctionBlackBox(#NAME \
80 , sunpos_prepare \
81 , NAME##_calc /* value */ \
82 , (ExtBBoxFunc*)NULL /* derivatives not provided yet*/ \
83 , (ExtBBoxFunc*)NULL /* hessian not provided yet */ \
84 , (ExtBBoxFinalFunc*)NULL /* finalisation not implemented */ \
85 , INPUTS,OUTPUTS /* inputs, outputs */ \
86 , NAME##_help /* help text */ \
87 , 0.0 \
88 ) /* returns 0 on success */
89
90 CALCFN(sunpos,3,2);
91
92 #undef CALCFN
93
94 if(result){
95 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"CreateUserFunction result = %d\n",result);
96 }
97 return result;
98 }
99
100
101 /**
102 This function is called when the black-box relation is being instantiated.
103
104 'sunpos_prepare' just gets the data member and checks that it's
105 valid, and stores it in the blackbox data field.
106 */
107 int sunpos_prepare(struct BBoxInterp *bbox,
108 struct Instance *data,
109 struct gl_list_t *arglist
110 ){
111 struct Instance *inst;
112 double latitude, longitude;
113
114 LATITUDE_SYM = AddSymbol("latitude");
115 LONGITUDE_SYM = AddSymbol("longitude");
116
117 /* get the latitude */
118 inst = ChildByChar(data,LATITUDE_SYM);
119 if(!inst){
120 ERROR_REPORTER_HERE(ASC_USER_ERROR
121 ,"Couldn't locate 'latitude' in DATA, please check usage of SUNPOS."
122 );
123 return 1;
124 }
125 if(InstanceKind(inst)!=REAL_CONSTANT_INST){
126 ERROR_REPORTER_HERE(ASC_USER_ERROR,"DATA member 'latitude' must be a real_constant");
127 return 1;
128 }
129 latitude = RC_INST(inst)->value;
130 CONSOLE_DEBUG("Latitude: %0.3f",latitude);
131 if(latitude > PI/2 || latitude < -PI/2){
132 ERROR_REPORTER_HERE(ASC_USER_ERROR,"'latitude' is out of allowable range -PI/2 to PI/2.");
133 return 1;
134 }
135
136 /* get the longitude */
137 inst = ChildByChar(data,LONGITUDE_SYM);
138 if(!inst){
139 ERROR_REPORTER_HERE(ASC_USER_ERROR
140 ,"Couldn't locate 'longitude' in DATA, please check usage of SUNPOS."
141 );
142 return 1;
143 }
144 if(InstanceKind(inst)!=REAL_CONSTANT_INST){
145 ERROR_REPORTER_HERE(ASC_USER_ERROR,"DATA member 'longitude' must be a real_constant");
146 return 1;
147 }
148 longitude = RC_INST(inst)->value;
149 CONSOLE_DEBUG("Longitude: %0.3f",longitude);
150
151 if(longitude > PI || longitude < -PI){
152 ERROR_REPORTER_HERE(ASC_USER_ERROR,"'latitude' is out of allowable range -PI to PI.");
153 return 1;
154 }
155
156 SunPos *S = ASC_NEW(SunPos);
157 SunPos_set_lat_long(S, latitude, longitude);
158 bbox->user_data = (void *)S;
159
160 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Prepared position for sun position.\n");
161 return 0;
162 }
163
164 #define CALCPREPARE(NIN,NOUT) \
165 /* a few checks about the input requirements */ \
166 if(ninputs != NIN)return -1; \
167 if(noutputs != NOUT)return -2; \
168 if(inputs==NULL)return -3; \
169 if(outputs==NULL)return -4; \
170 if(bbox==NULL)return -5; \
171 \
172 /* the 'user_data' in the black box object will contain the */\
173 /* coefficients required for this fluid; cast it to the required form: */\
174 const SunPos *sunpos1 = (const SunPos *)bbox->user_data
175
176
177 /**
178 Evaluation function for 'sunpos'
179 @return 0 on success
180 */
181 int sunpos_calc(struct BBoxInterp *bbox,
182 int ninputs, int noutputs,
183 double *inputs, double *outputs,
184 double *jacobian
185 ){
186 CALCPREPARE(3,2);
187
188 double t, p, T;
189
190 t = inputs[0]/ 86400. - 0.5 /* convert seconds to days, offset such that 0:00 1 Jan 2003 --> -0.5 */;
191 p = inputs[1] / 101325. /* convert Pa to atm */;
192 T = inputs[2] - 273.15 /* convert ��C to K */;
193
194 SunPos S = *sunpos1;
195
196 SunPos_set_press_temp(&S, p, T);
197 /* we ignore differences between universal time and terrestrial time.
198 it seems that these differences are < 1 sec in general
199 http://en.wikipedia.org/wiki/DUT1 */
200 SunPos_set_time(&S, t, 0);
201
202 double zenith, azimuth;
203
204 SunPos_calc_zen_azi(&S, &zenith, &azimuth);
205
206 /* returned values are in Radians, no offsets required */
207 outputs[0] = zenith;
208 outputs[1] = azimuth;
209
210 return 0;
211 }
212
213
214

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