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 = "Calculate sun position (local zenith, azimuth angles) given time, pressure and temperature, using Grena algorithm. DATA member for this external relation is required to provide constants for latitude and longitude of the selected location."; |
54 |
|
55 |
/*------------------------------------------------------------------------------ |
56 |
REGISTRATION FUNCTION |
57 |
*/ |
58 |
|
59 |
/** |
60 |
This is the function called from 'IMPORT "johnpye/grena/sunpos";' |
61 |
|
62 |
It sets up the functions contained in this external library |
63 |
*/ |
64 |
extern |
65 |
ASC_EXPORT int sunpos_register(){ |
66 |
int result = 0; |
67 |
|
68 |
ERROR_REPORTER_HERE(ASC_USER_WARNING,"SUNPOS is still EXPERIMENTAL. Use with caution.\n"); |
69 |
|
70 |
#define CALCFN(NAME,INPUTS,OUTPUTS) \ |
71 |
result += CreateUserFunctionBlackBox(#NAME \ |
72 |
, sunpos_prepare \ |
73 |
, NAME##_calc /* value */ \ |
74 |
, (ExtBBoxFunc*)NULL /* derivatives not provided yet*/ \ |
75 |
, (ExtBBoxFunc*)NULL /* hessian not provided yet */ \ |
76 |
, (ExtBBoxFinalFunc*)NULL /* finalisation not implemented */ \ |
77 |
, INPUTS,OUTPUTS /* inputs, outputs */ \ |
78 |
, NAME##_help /* help text */ \ |
79 |
, 0.0 \ |
80 |
) /* returns 0 on success */ |
81 |
|
82 |
CALCFN(sunpos,3,2); |
83 |
|
84 |
#undef CALCFN |
85 |
|
86 |
if(result){ |
87 |
ERROR_REPORTER_HERE(ASC_PROG_NOTE,"CreateUserFunction result = %d\n",result); |
88 |
} |
89 |
return result; |
90 |
} |
91 |
|
92 |
|
93 |
/** |
94 |
This function is called when the black-box relation is being instantiated. |
95 |
|
96 |
'sunpos_prepare' just gets the data member and checks that it's |
97 |
valid, and stores it in the blackbox data field. |
98 |
*/ |
99 |
int sunpos_prepare(struct BBoxInterp *bbox, |
100 |
struct Instance *data, |
101 |
struct gl_list_t *arglist |
102 |
){ |
103 |
struct Instance *inst; |
104 |
double latitude, longitude; |
105 |
|
106 |
LATITUDE_SYM = AddSymbol("latitude"); |
107 |
LONGITUDE_SYM = AddSymbol("longitude"); |
108 |
|
109 |
/* get the latitude */ |
110 |
inst = ChildByChar(data,LATITUDE_SYM); |
111 |
if(!inst){ |
112 |
ERROR_REPORTER_HERE(ASC_USER_ERROR |
113 |
,"Couldn't locate 'latitude' in DATA, please check usage of SUNPOS." |
114 |
); |
115 |
return 1; |
116 |
} |
117 |
if(InstanceKind(inst)!=REAL_CONSTANT_INST){ |
118 |
ERROR_REPORTER_HERE(ASC_USER_ERROR,"DATA member 'latitude' must be a real_constant"); |
119 |
return 1; |
120 |
} |
121 |
latitude = RC_INST(inst)->value; |
122 |
CONSOLE_DEBUG("Latitude: %0.3f",latitude); |
123 |
if(latitude > PI/2 || latitude < -PI/2){ |
124 |
ERROR_REPORTER_HERE(ASC_USER_ERROR,"'latitude' is out of allowable range -PI/2 to PI/2."); |
125 |
return 1; |
126 |
} |
127 |
|
128 |
/* get the longitude */ |
129 |
inst = ChildByChar(data,LONGITUDE_SYM); |
130 |
if(!inst){ |
131 |
ERROR_REPORTER_HERE(ASC_USER_ERROR |
132 |
,"Couldn't locate 'longitude' in DATA, please check usage of SUNPOS." |
133 |
); |
134 |
return 1; |
135 |
} |
136 |
if(InstanceKind(inst)!=REAL_CONSTANT_INST){ |
137 |
ERROR_REPORTER_HERE(ASC_USER_ERROR,"DATA member 'longitude' must be a real_constant"); |
138 |
return 1; |
139 |
} |
140 |
longitude = RC_INST(inst)->value; |
141 |
CONSOLE_DEBUG("Longitude: %0.3f",longitude); |
142 |
|
143 |
if(longitude > PI || longitude < -PI){ |
144 |
ERROR_REPORTER_HERE(ASC_USER_ERROR,"'latitude' is out of allowable range -PI to PI."); |
145 |
return 1; |
146 |
} |
147 |
|
148 |
SunPos *S = ASC_NEW(SunPos); |
149 |
SunPos_set_lat_long(S, latitude, longitude); |
150 |
bbox->user_data = (void *)S; |
151 |
|
152 |
ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Prepared position for sun position.\n"); |
153 |
return 0; |
154 |
} |
155 |
|