/[ascend]/trunk/models/johnpye/fprops/asc_heatex_pinch.c
ViewVC logotype

Contents of /trunk/models/johnpye/fprops/asc_heatex_pinch.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2631 - (show annotations) (download) (as text)
Wed Aug 8 03:32:55 2012 UTC (7 years, 11 months ago) by jpye
File MIME type: text/x-csrc
File size: 7266 byte(s)
Fixed error in pinch calculation. Seems to be working OK.
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 Pinch model of heat exchanger calculated with FPROPS.
20 */
21
22 //#define ASC_HEATEX_DEBUG
23
24 /* include the external function API from libascend... */
25 #include <ascend/compiler/extfunc.h>
26
27 /* include error reporting API as well, so we can send messages to user */
28 #include <ascend/utilities/error.h>
29
30 /* for accessing the DATA instance */
31 #include <ascend/compiler/child.h>
32 #include <ascend/general/list.h>
33 #include <ascend/compiler/module.h>
34 #include <ascend/compiler/childinfo.h>
35 #include <ascend/compiler/parentchild.h>
36 #include <ascend/compiler/slist.h>
37 #include <ascend/compiler/type_desc.h>
38 #include <ascend/compiler/packages.h>
39 #include <ascend/compiler/symtab.h>
40 #include <ascend/compiler/instquery.h>
41 #include <ascend/compiler/instmacro.h>
42 #include <ascend/compiler/instance_types.h>
43
44 /* the code that we're wrapping... */
45 #include "helmholtz.h"
46 #include "sat.h"
47 #include "solve_ph.h"
48
49 /* for the moment, species data are defined in C code, we'll implement something
50 better later on, hopefully. */
51 #include "fluids.h"
52
53 #ifndef ASC_EXPORT
54 # error "Where is ASC_EXPORT?"
55 #endif
56
57 typedef struct{
58 const HelmholtzData *comp[2];/* 0 = cold, 1 = hot */
59 int n;
60 } HeatExData;
61
62 typedef struct{
63 double p,h,mdot;
64 } StreamData;
65
66 /*------------------------------------------------------------------------------
67 FORWARD DECLARATIONS
68 */
69
70 ExtBBoxInitFunc heatex_prepare;
71 ExtBBoxFunc heatex_calc;
72
73 /*------------------------------------------------------------------------------
74 GLOBALS
75 */
76
77 /* place to store symbols needed for accessing ASCEND's instance tree */
78 static symchar *heatex_symbols[3];
79 #define COMPONENT_SYM heatex_symbols[0]
80 #define COMPONENT_HOT_SYM heatex_symbols[1]
81 #define N_SYM heatex_symbols[2]
82
83 static const char *heatex_help = "Calculate heat exchanger pinch temperature (detailed analysis)";
84
85 /*------------------------------------------------------------------------------
86 REGISTRATION FUNCTION
87 */
88
89 /**
90 This is the function called from "IMPORT heatex"
91
92 It sets up the functions contained in this external library
93 */
94 extern
95 ASC_EXPORT int heatex_pinch_register(){
96 int result = 0;
97
98 ERROR_REPORTER_HERE(ASC_USER_WARNING,"HEATEX is still EXPERIMENTAL.\n");
99
100 result += CreateUserFunctionBlackBox("heatex_DT_phmphmQ"
101 ,heatex_prepare
102 ,heatex_calc
103 ,(ExtBBoxFunc*)NULL /* no derivatives yet */
104 ,(ExtBBoxFunc*)NULL /* hessian not provided yet */ \
105 ,(ExtBBoxFinalFunc*)NULL /* finalisation not implemented */ \
106 ,7, 1 /* inputs, outputs */
107 ,heatex_help
108 ,0.0
109 );
110
111 if(result){
112 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"result = %d\n",result);
113 }
114 return result;
115 }
116
117 /**
118 'heatex_prepare' just gets the stream details and the number of slices for
119 internal calculation, and checks that the stream names are valid in FPROPS.
120 */
121 int heatex_prepare(struct BBoxInterp *bbox,
122 struct Instance *data,
123 struct gl_list_t *arglist
124 ){
125 HeatExData *hxd = ASC_NEW(HeatExData);
126 if(!hxd)goto fail;
127
128 struct Instance *compinst[2], *ninst;
129 const char *comp[2];
130
131 heatex_symbols[0] = AddSymbol("component");
132 heatex_symbols[1] = AddSymbol("component_hot");
133 N_SYM = AddSymbol("n");
134
135 ninst = ChildByChar(data,N_SYM);
136 if(!ninst){
137 ERROR_REPORTER_HERE(ASC_USER_ERROR
138 ,"Couldn't locate '%s' in DATA, please check usage.",SCP(N_SYM)
139 );
140 goto fail;
141 }
142 if(InstanceKind(ninst)!=INTEGER_CONSTANT_INST){
143 ERROR_REPORTER_HERE(ASC_USER_ERROR,"DATA member '%s' must be a symbol_constant",SCP(N_SYM));
144 goto fail;
145 }
146 hxd->n = IC_INST(ninst)->value;
147
148 int i;
149 for(i=0;i<2;++i){
150 /* get the component names for cold and hot sides */
151 compinst[i] = ChildByChar(data,heatex_symbols[i]);
152 if(!compinst[i]){
153 ERROR_REPORTER_HERE(ASC_USER_ERROR
154 ,"Couldn't locate '%s' in DATA, please check usage."
155 ,SCP(heatex_symbols[i])
156 );
157 goto fail;
158 }
159 if(InstanceKind(compinst[i])!=SYMBOL_CONSTANT_INST){
160 ERROR_REPORTER_HERE(ASC_USER_ERROR,"DATA member '%s' must be a symbol_constant",SCP(heatex_symbols[i]));
161 goto fail;
162 }
163 comp[i] = SCP(SYMC_INST(compinst[i])->value);
164 CONSOLE_DEBUG("%s: %s",SCP(heatex_symbols[i]),comp[i]);
165 if(comp[i]==NULL || strlen(comp[i])==0){
166 ERROR_REPORTER_HERE(ASC_USER_ERROR,"'%s' is NULL or empty",heatex_symbols[i]);
167 goto fail;
168 }
169
170 hxd->comp[i] = fprops_fluid(comp[i]);
171 if(hxd->comp[i] == NULL){
172 ERROR_REPORTER_HERE(ASC_USER_ERROR,"Heat exchanger %s name '%s' not recognised. Check list of supported species.",SCP(heatex_symbols[i]),comp[i]);
173 goto fail;
174 }
175 }
176
177 bbox->user_data = (void *)hxd;
178 ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Heat exchanger data structure OK.\n",comp);
179 return 0;
180
181 fail:
182 if(hxd){
183 /* TODO FIXME implement FPROPS freeing */
184 //if(hxd->comp[0])ASC_FREE(hxd->comp[0]);
185 //if(hxd->comp[1])ASC_FREE(hxd->comp[1]);
186 ASC_FREE(hxd);
187 }
188 return 1;
189 }
190
191 /*------------------------------------------------------------------------------
192 EVALULATION ROUTINES
193 */
194
195 #define CALCPREPARE(NIN,NOUT) \
196 /* a few checks about the input requirements */ \
197 if(ninputs != NIN)return -1; \
198 if(noutputs != NOUT)return -2; \
199 if(inputs==NULL)return -3; \
200 if(outputs==NULL)return -4; \
201 if(bbox==NULL)return -5; \
202 \
203 /* the 'user_data' in the black box object will contain the */\
204 /* coefficients required for this fluid; cast it to the required form: */\
205 const HeatExData *heatex_data = (const HeatExData *)bbox->user_data
206
207 /**
208 Evaluation function for 'helmholtz_phsx_vT'
209 @return 0 on success
210 */
211 int heatex_calc(struct BBoxInterp *bbox,
212 int ninputs, int noutputs,
213 double *inputs, double *outputs,
214 double *jacobian
215 ){
216 CALCPREPARE(7,1);
217
218 StreamData cold = {inputs[0],inputs[1],inputs[2]};
219 StreamData hot = {inputs[3],inputs[4],inputs[5]};
220 double Q = inputs[6];
221 double DT_min = DBL_MAX;
222 int i, n = heatex_data->n;
223
224 CONSOLE_DEBUG("hot: p = %f bar, h = %f kJ/kg, mdot = %f kg/s",hot.p/1e5, hot.h/1e3, hot.mdot);
225 CONSOLE_DEBUG("cold: p = %f bar, h = %f kJ/kg, mdot = %f kg/s",cold.p/1e5, cold.h/1e3, cold.mdot);
226
227 double Th,Tc,rhoh,rhoc;
228 /* loop from i=0 (cold inlet) to i=n (cold outlet) */
229 for(i=0;i<=n;++i){
230 double hh = hot.h - Q/hot.mdot*(n-i)/n;
231 double hc = cold.h + Q/cold.mdot*i/n;
232 /* FIXME make use of guess values? */
233 if(fprops_solve_ph(hot.p, hh, &Th, &rhoh, 0, heatex_data->comp[1])){
234 /* error solving (p,h) hotside */
235 }
236 if(fprops_solve_ph(cold.p, hc, &Tc, &rhoc, 0, heatex_data->comp[0])){
237 /* error solving (p,h) coldside */
238 }
239 double DT = Th - Tc;
240 if(DT<DT_min)DT_min = DT;
241 }
242
243 CONSOLE_DEBUG("DT = %f K",DT_min);
244
245 /* non-saturated */
246 outputs[0] = DT_min;
247 return 0;
248 }
249

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