1 /*============================================================================
2  * Radiation solver operations.
3  *============================================================================*/
4 
5 /* This file is part of Code_Saturne, a general-purpose CFD tool.
6 
7   Copyright (C) 1998-2021 EDF S.A.
8 
9   This program is free software; you can redistribute it and/or modify it under
10   the terms of the GNU General Public License as published by the Free Software
11   Foundation; either version 2 of the License, or (at your option) any later
12   version.
13 
14   This program is distributed in the hope that it will be useful, but WITHOUT
15   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17   details.
18 
19   You should have received a copy of the GNU General Public License along with
20   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
21   Street, Fifth Floor, Boston, MA 02110-1301, USA. */
22 
23 /*----------------------------------------------------------------------------*/
24 
25 #include "cs_defs.h"
26 #include "cs_math.h"
27 
28 /*----------------------------------------------------------------------------
29  * Standard C library headers
30  *----------------------------------------------------------------------------*/
31 
32 #include <assert.h>
33 #include <errno.h>
34 #include <stdio.h>
35 #include <stdarg.h>
36 #include <string.h>
37 #include <math.h>
38 #include <float.h>
39 
40 #if defined(HAVE_MPI)
41 #include <mpi.h>
42 #endif
43 
44 /*----------------------------------------------------------------------------
45  *  Local headers
46  *----------------------------------------------------------------------------*/
47 
48 #include "bft_error.h"
49 #include "bft_mem.h"
50 #include "bft_printf.h"
51 
52 #include "cs_log.h"
53 #include "cs_mesh.h"
54 #include "cs_mesh_quantities.h"
55 #include "cs_parall.h"
56 #include "cs_parameters.h"
57 #include "cs_sles.h"
58 #include "cs_sles_it.h"
59 #include "cs_timer.h"
60 #include "cs_time_step.h"
61 
62 #include "cs_rad_transfer.h"
63 
64 /*----------------------------------------------------------------------------
65  *  Header for the current file
66  *----------------------------------------------------------------------------*/
67 
68 #include "cs_rad_transfer_fsck.h"
69 
70 /*----------------------------------------------------------------------------*/
71 
72 BEGIN_C_DECLS
73 
74 /*=============================================================================
75  * Additional Doxygen documentation
76  *============================================================================*/
77 
78 /* \file cs_rad_transfer_fsck.c.f90 */
79 
80 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
81 
82 /*=============================================================================
83  * Local static variables
84  *============================================================================*/
85 
86 static int ipass = 0;
87 
88 static cs_real_t  *gi;
89 static cs_real_t  *tt;
90 static cs_real_t  *kpco2;
91 static cs_real_t  *kph2o;
92 static cs_real_t  *wv;
93 static cs_real_t  *dwv;
94 static cs_real_t  *kmfs;
95 static cs_real_t  *gq;
96 
97 /*=============================================================================
98  * Local const variables
99  *============================================================================*/
100 
101 const int ng = 100;
102 const int nt     = 38;
103 const int nconc  = 5;
104 const int nband  = 450;
105 const int maxit  = 1000;
106 const int imlinear    = 0;
107 const int im3dspline  = 7;
108 const int im1dspline  = 2;
109 const int im2dspline  = 6;
110 const cs_real_t eps    = 3e-14;
111 const cs_real_t x_kg[5] = {0.0001, 0.25, 0.5, 0.75, 1.0};
112 
113 /*=============================================================================
114  * Private function definitions
115  *============================================================================*/
116 
117 /*----------------------------------------------------------------------------*/
118 /*!
119  * \brief Convert a line of values in a file into an array of cs_real_t and
120  *        returns the number of values read
121  *
122  * \param[in]  radfile     pointer to file for reading values
123  * \param[in]  values      array for values storage
124  * \param[in]  nvalues     number of values read
125  */
126 /*----------------------------------------------------------------------------*/
127 
128 static inline void
_line_to_array(FILE * radfile,cs_real_t values[],int * nvalues)129 _line_to_array(FILE       *radfile,
130                cs_real_t   values[],
131                int        *nvalues)
132 {
133   char line[256];
134   fgets(line, 256, radfile);
135   int index = 0;
136 
137   /* now read all info along the line */
138   while (strlen(line) > 1) {
139     char temp[256];
140     /* store next value in string format */
141     sscanf(line, "%s", temp);
142     /* read and convert to double precision */
143     sscanf(temp, "%lf", &(values[index]));
144     /* increase index in array */
145     index++;
146 
147     int l = strlen(temp);
148     int i = 0;
149     while (line[i] == ' ')
150       i++;
151     snprintf(temp, 256, "%s", &line[l+i]);
152     strcpy(line, temp);
153   }
154 
155   *nvalues = index;
156 }
157 
158 /*----------------------------------------------------------------------------*/
159 /*!
160  * \brief number of segents
161  *
162  * \param[in]     trad          Reference temperature
163  * \param[in]     t             Local Temperature
164  * \param[in]     xco2          CO2 volume fraction
165  * \param[in]     xh2o          H2O volume fraction
166  * \param[in]     interp_method Interpolation method
167  * \param[inout]  itx[4][4]     itx[0]: TPlanck; iTx[1]: Tloc;
168  *                              iTx[2]: xCO2; iTx[3] = xH2O
169  */
170 /*----------------------------------------------------------------------------*/
171 
172 inline static void
_gridposnbsg1(cs_real_t trad,cs_real_t t,cs_real_t xco2,cs_real_t xh2o,int interp_method,int itx[4][4])173 _gridposnbsg1(cs_real_t  trad,
174               cs_real_t  t,
175               cs_real_t  xco2,
176               cs_real_t  xh2o,
177               int        interp_method,
178               int        itx[4][4])
179 {
180   int itrad[4] = {0};
181   int ita[4]   = {0};
182   int ico2a[4] = {0};
183   int ih2oa[4] = {0};
184 
185   /* Mole fraction interpolation: determine xCO2 */
186 
187   int i = 0;
188   int j = nconc - 1;
189   int ip = (i + j) / 2;
190   while (j - i > 1) {
191     if (xco2 < x_kg[ip])
192       j = ip;
193     else
194       i = ip;
195     ip = (i + j) / 2;
196   }
197 
198   /*  spline on x */
199 
200   if (interp_method == im2dspline) {
201 
202     if ((i > 0) && (i < nconc - 2)) {
203       ico2a[0] = i - 1;
204       ico2a[1] = i;
205       ico2a[2] = i + 1;
206       ico2a[3] = i + 2;
207     }
208     else if (i == 0) {
209       ico2a[0] = 0;
210       ico2a[1] = 1;
211       ico2a[2] = 2;
212       ico2a[3] = 3;
213     }
214     else if (i == nconc - 2) {
215       ico2a[0] = nconc - 4;
216       ico2a[1] = nconc - 3;
217       ico2a[2] = nconc - 2;
218       ico2a[3] = nconc - 1;
219     }
220     else
221       cs_log_printf(CS_LOG_DEFAULT, _("x grid failure, i = %d"), i);
222   }
223   /* linear in x */
224   else {
225     if (i < 0) //not possible...
226       i = 0;
227     else if (i > nconc - 2)
228       i = nconc - 2;
229     ico2a[0] = i;
230     ico2a[1] = i + 1;
231   }
232 
233   /* Mole fraction interpolation: determine xH2O */
234 
235   i  = 0;
236   j  = nconc - 1;
237   ip = (i + j) / 2;
238   while (j - i > 1) {
239     if (xh2o < x_kg[ip])
240       j = ip;
241     else
242       i = ip;
243     ip = (i + j) / 2;
244   }
245 
246   /*  spline on x */
247   if (interp_method == im2dspline) {
248 
249     if ((i > 0) && (i < nconc - 2)) {
250       ih2oa[0] = i - 1;
251       ih2oa[1] = i;
252       ih2oa[2] = i + 1;
253       ih2oa[3] = i + 2;
254     }
255     else if (i == 0) {
256       ih2oa[0] = 0;
257       ih2oa[1] = 1;
258       ih2oa[2] = 2;
259       ih2oa[3] = 3;
260     }
261     else if (i == nconc - 2) {
262       ih2oa[0] = nconc - 4;
263       ih2oa[1] = nconc - 3;
264       ih2oa[2] = nconc - 2;
265       ih2oa[3] = nconc - 1;
266     }
267     else
268       cs_log_printf(CS_LOG_DEFAULT, _("x grid failure, i = %d"), i);
269   }
270   /* linear in x */
271   else {
272     if (i < 0) //not possible...
273       i = 0;
274     else if (i > nconc - 2)
275       i = nconc - 2;
276     ih2oa[0] = i;
277     ih2oa[1] = i + 1;
278   }
279 
280   /* Temperature interpolation */
281 
282   i  = 0;
283   j  = nt - 1;
284   ip = (i + j) / 2;
285   while (j - i > 1) {
286     if (t < tt[ip])
287       j = ip;
288     else
289       i = ip;
290     ip = (i + j) / 2;
291   }
292 
293   /* spline in t */
294   if (interp_method != 0) {
295 
296     if ((i > 0) && (i < nt - 2)) {
297       ita[0] = i - 1;
298       ita[1] = i;
299       ita[2] = i + 1;
300       ita[3] = i + 2;
301     }
302     else if (i == 0) {
303       ita[0]  = 0;
304       ita[1]  = 1;
305       ita[2]  = 2;
306       ita[3]  = 3;
307     }
308     else if (i == nt - 1) {
309       ita[0] = nt - 4;
310       ita[1] = nt - 3;
311       ita[2] = nt - 2;
312       ita[3] = nt - 1;
313     }
314     else
315       cs_log_printf(CS_LOG_DEFAULT, _("t grid failure, i = %d"), i);
316   }
317   /* linear in t */
318   else {
319     if (i < 0)
320       i  = 0;
321     else if (i > nt - 2)
322       i = nt - 2;
323     ita[0] = i;
324     ita[1] = i + 1;
325   }
326 
327   /* Determine closest Planck temperature in database
328      lower than local temperature */
329 
330   i  = 0;
331   j  = nt - 1;
332   ip = (i + j) / 2;
333   while (j - i > 1) {
334     if (trad < tt[ip])
335       j = ip;
336     else
337       i = ip;
338     ip = (i + j) / 2;
339   }
340 
341   /* spline in t */
342   if (interp_method != 0) {
343     if ((i > 0) && (i < nt - 2)) {
344       itrad[0] = i - 1;
345       itrad[1] = i;
346       itrad[2] = i + 1;
347       itrad[3] = i + 2;
348     }
349     else if (i == 0) {
350       itrad[0] = 0;
351       itrad[1] = 1;
352       itrad[2] = 2;
353       itrad[3] = 3;
354     }
355     else if (i == nt - 2) {
356       itrad[0] = nt - 4;
357       itrad[1] = nt - 3;
358       itrad[2] = nt - 2;
359       itrad[3] = nt - 1;
360     }
361     else
362       cs_log_printf(CS_LOG_DEFAULT, _("t grid failure, i = %d"), i);
363   }
364   /* linear in t */
365   else {
366     if (i < 0)
367         i = 0;
368     else if (i > nt - 1) {
369       i = nt - 1;
370     }
371     itrad[0] = i;
372     itrad[1] = i + 1;
373   }
374 
375   /* attribution itx */
376 
377   for (int k = 0; k < 4; k++) {
378     itx[0][k] = itrad[k];
379     itx[1][k] = ita[k];
380     itx[2][k] = ico2a[k];
381     itx[3][k] = ih2oa[k];
382   }
383 }
384 
385 /*----------------------------------------------------------------------------*/
386 /*!
387  * \brief This subroutine evaluates the cubic spline function
388  *
389  *    seval = y(i) + b(i)*(u-x(i)) + c(i)*(u-x(i))**2 + d(i)*(u-x(i))**3
390  *
391  *    where  x(i) .lt. u .lt. x(i+1), using horner's rule
392  *
393  *  if  u .lt. x(1) then  i = 1  is used.
394  *  if  u .ge. x(n) then  i = n  is used.
395  *
396  *  if  u  is not in the same interval as the previous call, then a
397  *  binary search is performed to determine the proper interval.
398  *
399  * \param[in]     n            Number of data points
400  * \param[in]     u            Abscissa at which the spline is to be evaluated
401  * \param[in]     x,y          Arrays of data abscissas and ordinates
402  * \param[in]     b,c,d        Arrays of spline coefficients computed by spline
403  */
404 /*----------------------------------------------------------------------------*/
405 
406 inline static cs_real_t
_seval(int n,cs_real_t u,cs_real_t x[],cs_real_t y[],cs_real_t b[],cs_real_t c[],cs_real_t d[])407 _seval(int       n,
408        cs_real_t u,
409        cs_real_t x[],
410        cs_real_t y[],
411        cs_real_t b[],
412        cs_real_t c[],
413        cs_real_t d[])
414 {
415   int i = 0;
416   if (i > n)
417     i = 0;
418 
419   /*  Binary search */
420   if (   u < x[i]
421       || u > x[i + 1]) {
422     i = 0;
423     int j = n;
424     int k = (j + i)/2;
425     while (j > i + 1) {
426       if (u < x[k])
427         j = k;
428       else
429         i = k;
430     }
431   }
432   /*  Evaluate spline */
433   cs_real_t dx = u - x[i];
434 
435   return y[i] + dx * (b[i] + dx * (c[i] + dx * d[i]));
436 }
437 
438 /*----------------------------------------------------------------------------*/
439 /*!
440  * \brief  1-d monotonic spline interpolation: coefficients
441  *  The coefficients b(i), c(i), and d(i), i = 1,2,...,n are computed
442  *  for a monotonically varying cubic interpolating spline
443  *
444  *    s(x) = y(i) + b(i)*(x-x(i)) + c(i)*(x-x(i))**2 + d(i)*(x-x(i))**3
445  *    for  x(i) .le. x .le. x(i+1)
446  *    with y(i+1).ge.y(i) (all i) or y(i+1).lt.y(i) (all i)
447  *
448  ********************************************************************************
449  *
450  * THEORY FROM 'MONOTONE PIECEWISE CUBIC INTERPOLATION',
451  * BY F.N. FRITSCH AND R.E. CARLSON IN SIAM J.NUMER.ANAL.,V.17,P.238
452  *
453  ********************************************************************************
454  *
455  *    Y(I) = S(X(I))
456  *    B(I) = SP(X(I))
457  *    C(I) = SPP(X(I))/2
458  *    D(I) = SPPP(X(I))/6  (DERIVATIVE FROM THE RIGHT)
459  *
460  *  THE ACCOMPANYING FUNCTION SUBPROGRAM  SEVAL  CAN BE USED
461  *  TO EVALUATE THE SPLINE.
462  *
463  * \param[in]     n           Number of data points or knots (n.ge.2)
464  * \param[in]     x           Abscissa of the knots in strictly increasing order
465  * \param[in]     y           Ordinates of the knots
466  * \param[out]    b,c,d       Arrays of spline coefficients as defined above
467  */
468 /*----------------------------------------------------------------------------*/
469 
470 inline static void
_splmi(int n,cs_real_t x[],cs_real_t y[],cs_real_t b[],cs_real_t c[],cs_real_t d[])471 _splmi(int        n,
472        cs_real_t  x[],
473        cs_real_t  y[],
474        cs_real_t  b[],
475        cs_real_t  c[],
476        cs_real_t  d[])
477 {
478   cs_real_t delta[n], h[n], al[n], be[n];
479 
480   int nm1 = n - 1;
481 
482   if (n < 2)
483     return;
484 
485   if (n >= 3) {
486 
487     /*  Calculate the h(i) and delta(i) */
488     for (int i = 0; i < nm1; i++) {
489       al[i]    = 0.0;
490       be[i]    = 0.0;
491       h[i]     = x[i + 1] - x[i];
492       delta[i] = (y[i + 1] - y[i]) / h[i];
493     }
494 
495     /* calculate first values for al and be by 3-point difference */
496     if (CS_ABS(delta[0]) < eps)
497       al[0] =  (  pow((h[0] + h[1]), 2.0) * y[1]
498                 - pow (h[0], 2.0) * y[2]
499                 - h[1] * (2.0 * h[0] + h[1]) * y[0])
500              / (h[1] * (h[0] + h[1]) * (y[1] - y[0]));
501 
502     for (int i = 1; i < nm1; i++) {
503       if (CS_ABS(delta[0]) < eps)
504         al[i] =  (  pow(h[i - 1], 2.0) * y[i + 1]
505                   + (pow (h[i], 2.0) - pow (h[i - 1], 2.0)) * y[i]
506                   - pow (h[i], 2.0) * y[i - 1])
507                / (h[i - 1] * (h[i] + h[i - 1]) * (y[i + 1] - y[i]));
508 
509     }
510 
511     int nm2 = n - 2;
512     for (int i = 0; i < nm2; i++) {
513       if (CS_ABS(delta[0]) < eps)
514         be[i] =  (  pow(h[i], 2.0) * y[i + 2]
515                   + (pow (h[i + 1], 2.0) - pow (h[i], 2.0)) * y[i + 1]
516                   - pow (h[i + 1], 2.0) * y[i])
517                / (h[i + 1] * (h[i] + h[i + 1]) * (y[i + 1] - y[i]));
518 
519     }
520 
521     if (CS_ABS(delta[0]) < eps) {
522       be[n - 2] =  (  h[n - 3] * (2.0 * h[n - 2] + h[n - 3]) * y[n - 1]
523                      - pow((h[n - 2] + h[n - 3]), 2.0) * y[n - 2]
524                      + pow (h[n - 2], 2.0) * y[n - 3])
525                   / (h[n - 3] * (h[n - 2] + h[n - 3]) * (y[n - 1] - y[n - 2]));
526     }
527 
528     /* Correct values for al and be */
529     for (int i = 0; i < nm1; i++) {
530       if (   al[i] + be[i] > 2.0
531           && 2.0 * al[i] + be[i] > 3.0
532           && al[i] + 2.0 * be[i] > 3.0) {
533 
534         cs_real_t phi = al[i] -   pow((2.0 * al[i] + be[i] - 3.0), 2.0)
535                                 / (al[i] + be[i] - 2.0) / 3.0;
536 
537         if (phi < 0.0) {
538           cs_real_t ti = 3.0 / sqrt (pow (al[i], 2.0) + pow (be[i], 2.0));
539           al[i] = ti * al[i];
540           be[i] = ti * be[i];
541         }
542 
543       }
544     }
545 
546     /* Calculate spline coefficients */
547 
548     for (int i = 0; i < nm1; i++) {
549       d[i] = (al[i] + be[i] - 2.0) * delta[i] / (pow (h[i], 2.0));
550       c[i] = (3.0 - 2.0 * al[i] - be[i]) * delta[i] / (h[i]);
551       b[i] = al[i] * delta[i];
552       if (b[i] * delta[i] < 0.0) {
553         b[i] = delta[i];
554         c[i] = 0.0;
555         d[i] = 0.0;
556       }
557     }
558 
559     b[n - 1] = be[n - 2] * delta[n - 2];
560     c[n - 1] = 0.0;
561     d[n - 1] = 0.0;
562 
563   }
564   else if (n == 2) {
565 
566     b[0] = (y[1] - y[0]) / (x[1] - x[0]);
567     c[0] = 0.0;
568     d[0] = 0.0;
569     b[1] = b[0];
570     c[1] = 0.0;
571     d[1] = 0.0;
572 
573   }
574 }
575 
576 /*----------------------------------------------------------------------------*/
577 /*!
578  * \brief simple_interpg
579  *
580  * \param[in]     nxy
581  * \param[in]     xx
582  * \param[in]     yy
583  * \param[in]     ni
584  * \param[in]     xi
585  * \param[out]    yi
586  */
587 /*----------------------------------------------------------------------------*/
588 
589 static inline void
_simple_interpg(int nxy,cs_real_t xx[],cs_real_t yy[],int ni,cs_real_t xi[],cs_real_t yi[])590 _simple_interpg (int        nxy,
591                  cs_real_t  xx[],
592                  cs_real_t  yy[],
593                  int        ni,
594                  cs_real_t  xi[],
595                  cs_real_t  yi[])
596 {
597   int ibgn = 0;
598 
599   for (int iq = 0; iq < ni; iq++) {
600 
601     for (int i = ibgn; i < nxy; i++) {
602 
603       if (xi[iq] < xx[0]) {
604         yi[iq] = yy[0] * xi[iq] / CS_MAX(1e-09, xx[0]);
605         break;
606       }
607       else if (xi[iq] > xx[nxy])
608         yi[iq] = yy[nxy];
609 
610 
611       /* interpolate */
612       if (CS_ABS(xi[iq] - xx[i]) / (xx[i] + 1e-15) < 0.001) {
613         yi[iq] = yy[i];
614         ibgn = i;
615         break;
616       }
617       else if (xx[i] > xi[iq]) {
618         yi[iq] =   yy[i - 1]
619                 + (yy[i] - yy[i - 1]) * (xi[iq] - xx[i - 1])
620                                       / CS_MAX(1e-09, (xx[i] - xx[i - 1]));
621         ibgn = i;
622         break;
623       }
624     }
625   }
626 
627   if (CS_ABS(xi[ni] - xx[nxy]) / (xx[nxy] + 1e-15) < 0.001)
628     yi[ni] = yy[nxy];
629 }
630 
631 /*----------------------------------------------------------------------------*/
632 /*!
633  * \brief interpolation4d
634  *
635  * \param[in]     trad          Reference temperature
636  * \param[in]     t             Local temperature
637  * \param[in]     xco2          Reference CO2 volume fraction
638  * \param[in]     xh2o          Reference H2O volume fraction
639  * \param[in]     interp_method Interpolation method
640  * \param[out]    gdb
641  * \param[out]    kdb
642  */
643 /*----------------------------------------------------------------------------*/
644 
645 inline static void
_interpolation4d(cs_real_t trad,cs_real_t t,cs_real_t xco2,cs_real_t xh2o,int interp_method,cs_real_t gdb[],cs_real_t kdb[])646 _interpolation4d(cs_real_t trad,
647                  cs_real_t t,
648                  cs_real_t xco2,
649                  cs_real_t xh2o,
650                  int       interp_method,
651                  cs_real_t gdb[],
652                  cs_real_t kdb[])
653 {
654   int     itx[4][4];
655   int     nix, nit;
656 
657   cs_real_t *karray, *kint1, *kint2, *kint3;
658   BFT_MALLOC(karray, ng*4*4*4*4, cs_real_t);
659   BFT_MALLOC(kint1,  ng*4*4*4, cs_real_t);
660   BFT_MALLOC(kint2,  ng*4*4, cs_real_t);
661   BFT_MALLOC(kint3,  ng*4, cs_real_t);
662 
663   cs_real_t *b, *c, *d, *kg_t2, *kg_x2;
664   BFT_MALLOC(b, 4, cs_real_t);
665   BFT_MALLOC(c, 4, cs_real_t);
666   BFT_MALLOC(d, 4, cs_real_t);
667   BFT_MALLOC(kg_t2, 4, cs_real_t);
668   BFT_MALLOC(kg_x2, 4, cs_real_t);
669 
670   /* Determine positions in x and T
671    * in the NB database for interpolation. */
672   for (int i = 0; i < ng; i++)
673     gdb[i] = gi[i];
674 
675   /* number of interpolation points along t & x: 2 linear or 4 spline */
676   _gridposnbsg1(trad,
677                 t,
678                 xco2,
679                 xh2o,
680                 interp_method,
681                 itx);
682 
683   /* spline over x */
684   if (interp_method == im2dspline)
685     nix  = 4;
686   else
687     nix  = 2;
688 
689   /* spline over t */
690   if (interp_method != 0)
691     nit  = 4;
692   else
693     nit  = 2;
694 
695   /* Attribute interpolation point indexes along T & x */
696 
697   int itrada[4] = {0, 0, 0, 0};
698   int ita[4]    = {0, 0, 0, 0};
699   int ico2a[4] = {0, 0, 0, 0};
700   int ih2oa[4] = {0, 0, 0, 0};
701 
702   for (int i = 0; i < nit; i++) {
703     itrada[i] = itx[0][i];
704     ita[i] = itx[1][i];
705   }
706 
707   for (int i = 0; i < nix; i++) {
708     ico2a[i] = itx[2][i];
709     ih2oa[i] = itx[3][i];
710   }
711 
712   for (int ih2o = 0; ih2o < nix; ih2o++) {
713     for (int ico2 = 0; ico2 < nix; ico2++) {
714       for (int it = 0; it < nit; it++) {
715         for (int itrad = 0; itrad < nit; itrad++) {
716           for (int ig = 0; ig < ng; ig++) {
717             karray[  ih2o
718                    + ico2*4
719                    + it*4*4
720                    + itrad*4*4*4
721                    + ig*4*4*4*4] =
722               kmfs[  ih2oa[ih2o]
723                    + ico2a[ico2]*nconc
724                    + ita[it]*nconc*nconc
725                    + itrada[itrad]*nconc*nconc*nt
726                    + ig*nconc*nconc*nt*nt];
727           }
728         }
729       }
730     }
731   }
732 
733   /* Interpolation on XH2O; spline over x */
734 
735   if (interp_method == im2dspline) {
736     for (int ico2 = 0; ico2 < nix; ico2++) {
737       for (int it = 0; it < nit; it++) {
738         for (int itrad = 0; itrad < nit; itrad++) {
739           for (int ig = 0; ig < ng; ig++) {
740             kg_x2[0] = x_kg[ih2oa[0]];
741             kg_x2[1] = x_kg[ih2oa[1]];
742             kg_x2[2] = x_kg[ih2oa[2]];
743             kg_x2[3] = x_kg[ih2oa[3]];
744             int ih2o = 0;
745             int nargs = 4;
746             _splmi(nargs,
747                    kg_x2,
748                    &karray[ih2o + ico2*4 + it*4*4 + itrad*4*4*4 + ig*4*4*4*4],
749                    b,
750                    c,
751                    d);
752 
753             kint1[ico2 + it*4 + itrad*4*4 + ig*4*4*4]
754               = _seval(nargs,
755                        xh2o,
756                        kg_x2,
757                        &karray[ih2o + ico2*4 + it*4*4 + itrad*4*4*4 + ig*4*4*4*4],
758                        b,
759                        c,
760                        d);
761           }
762         }
763       }
764     }
765   }
766   else {
767     cs_real_t wx = (xh2o - x_kg[ih2oa[0]]) / (x_kg[ih2oa[1]] - x_kg[ih2oa[0]]);
768     for (int ico2 = 0; ico2 < nix; ico2++) {
769       for (int it = 0; it < nit; it++) {
770         for (int itrad = 0; itrad < nit; itrad++) {
771           for (int ig = 0; ig < ng; ig++) {
772             kint1[ico2 + it*4 + itrad*4*4 + ig*4*4*4]
773               =          wx  * karray[1 + ico2*4 + it*4*4 + itrad*4*4*4 + ig*4*4*4*4]
774                 + (1.0 - wx) * karray[0 + ico2*4 + it*4*4 + itrad*4*4*4 + ig*4*4*4*4];
775           }
776         }
777       }
778     }
779   }
780 
781   /* Interpolation on XCO2: spline over x */
782 
783   if (interp_method == im2dspline) {
784     for (int it = 0; it < nit; it++) {
785       for (int itrad = 0; itrad < nit; itrad++) {
786         for (int ig = 0; ig < ng; ig++) {
787           kg_x2[0] = x_kg[ico2a[0]];
788           kg_x2[1] = x_kg[ico2a[1]];
789           kg_x2[2] = x_kg[ico2a[2]];
790           kg_x2[3] = x_kg[ico2a[3]];
791 
792           int ico2 = 0;
793           int nargs = 4;
794           _splmi(nargs,
795                  kg_x2,
796                  &kint1[ico2 + it*4 + itrad*4*4 + ig*4*4*4],
797                  b,
798                  c,
799                  d);
800           kint2[it + itrad*4 + ig*4*4]
801             = _seval(nargs,
802                      xco2,
803                      kg_x2,
804                      &kint1[ico2 + it*4 + itrad*4*4 + ig*4*4*4],
805                      b,
806                      c,
807                      d);
808         }
809       }
810     }
811   }
812   else {
813     cs_real_t wx = (xco2 - x_kg[ico2a[0]]) / (x_kg[ico2a[1]] - x_kg[ico2a[0]]);
814     for (int it = 0; it < nit; it++) {
815       for (int itrad = 0; itrad < nit; itrad++) {
816         for (int ig = 0; ig < ng; ig++) {
817           kint2[it + itrad*4 + ig*4*4]
818             =          wx  * kint1[1 + it*4 + itrad*4*4 + ig*4*4*4]
819               + (1.0 - wx) * kint1[0 + it*4 + itrad*4*4 + ig*4*4*4];
820         }
821       }
822     }
823   }
824 
825   /* Interpolation on T: spline on t */
826 
827   if (interp_method != 0) {
828     for (int itrad = 0; itrad < nit; itrad++) {
829       for (int ig = 0; ig < ng; ig++) {
830         kg_t2[0] = tt[ita[0]];
831         kg_t2[1] = tt[ita[1]];
832         kg_t2[2] = tt[ita[2]];
833         kg_t2[3] = tt[ita[3]];
834         int nargs = 4;
835         _splmi (nargs,
836                 kg_t2,
837                 &kint2[0 + itrad*4 + ig*4*4],
838                 b,
839                 c,
840                 d);
841         kint3[itrad + ig*4] = _seval(nargs,
842                                      t,
843                                      kg_t2,
844                                      &kint2[0 + itrad*4 + ig*4*4],
845                                      b,
846                                      c,
847                                      d);
848       }
849     }
850   }
851   else {
852     cs_real_t wt = (t - tt[ita[0]]) / (tt[ita[1]] - tt[ita[0]]);
853     for (int itrad = 0; itrad < nit; itrad++) {
854       for (int ig = 0; ig < ng; ig++) {
855         kint3[itrad + ig*4] =         wt  * kint2[1 + itrad*4 + ig*4*4]
856                              + (1.0 - wt) * kint2[0 + itrad*4 + ig*4*4];
857       }
858     }
859   }
860 
861   /* Interpolation on Trad: spline */
862 
863   if (interp_method != 0) {
864     for (int ig = 0; ig < ng; ig++) {
865       kg_t2[0] = tt[itrada[0]];
866       kg_t2[1] = tt[itrada[1]];
867       kg_t2[2] = tt[itrada[2]];
868       kg_t2[3] = tt[itrada[3]];
869       int nargs = 4;
870       _splmi(nargs,
871              kg_t2,
872              &kint3[0 + ig*4],
873              b,
874              c,
875              d);
876       kdb[ig] = _seval(nargs,
877                        trad,
878                        kg_t2,
879                        &kint3[0 + ig*4],
880                        b,
881                        c,
882                        d);
883     }
884   }
885   else {
886     cs_real_t wt = (trad - tt[itrada[0]]) / (tt[itrada[1]] - tt[itrada[0]]);
887     for (int ig = 0; ig < ng; ig++) {
888       kdb[ig] = wt * kint3[1 + ig*4] + (1.0 - wt) * kint3[0 + ig*4];
889     }
890   }
891 
892   /* Free memory */
893   BFT_FREE(karray);
894   BFT_FREE(kint1);
895   BFT_FREE(kint2);
896   BFT_FREE(kint3);
897   BFT_FREE(b);
898   BFT_FREE(c);
899   BFT_FREE(d);
900   BFT_FREE(kg_t2);
901   BFT_FREE(kg_x2);
902 }
903 
904 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
905 
906 /*=============================================================================
907  * Public function definitions
908  *============================================================================*/
909 
910 /*----------------------------------------------------------------------------*/
911 /*!
912  *  \brief Determine the radiation coefficients of the FSCK model
913  *         as well as the corresponding weights.
914  *
915  * \param[in]     pco2        CO2 volume fraction
916  * \param[in]     ph2o        H2O volume fraction
917  * \param[in]     teloc       gas temperature
918  * \param[out]    kloc        radiation coefficient of the i different gases
919  * \param[out]    aloc        weights of the i different gases in cells
920  * \param[out]    alocb       weights of the i different gases at boundaries
921  */
922 /*----------------------------------------------------------------------------*/
923 
924 void
cs_rad_transfer_fsck(const cs_real_t * restrict pco2,const cs_real_t * restrict ph2o,const cs_real_t * restrict teloc,cs_real_t * restrict kloc,cs_real_t * restrict aloc,cs_real_t * restrict alocb)925 cs_rad_transfer_fsck(const cs_real_t  *restrict pco2,
926                      const cs_real_t  *restrict ph2o,
927                      const cs_real_t  *restrict teloc,
928                      cs_real_t        *restrict kloc,
929                      cs_real_t        *restrict aloc,
930                      cs_real_t        *restrict alocb)
931 {
932   /* Initialization */
933 
934   cs_real_t   *gfskref, *kfskref, *kfsk, *gfsk, *gg1;
935   cs_real_t   *kg1, *as, *ag, *aw, *kloctmp;
936 
937   BFT_MALLOC(gfskref, ng, cs_real_t);
938   BFT_MALLOC(kfskref, ng, cs_real_t);
939   BFT_MALLOC(gfsk, ng, cs_real_t);
940   BFT_MALLOC(kfsk, ng, cs_real_t);
941   BFT_MALLOC(gg1, ng, cs_real_t);
942   BFT_MALLOC(kg1, ng, cs_real_t);
943   BFT_MALLOC(as, ng, cs_real_t);
944 
945   BFT_MALLOC(ag, cs_glob_rad_transfer_params->nwsgg, cs_real_t);
946   BFT_MALLOC(aw, cs_glob_rad_transfer_params->nwsgg, cs_real_t);
947   BFT_MALLOC(kloctmp, cs_glob_rad_transfer_params->nwsgg, cs_real_t);
948 
949   cs_field_t *f_bound_t = cs_field_by_name_try("boundary_temperature");
950   cs_real_t *tpfsck = f_bound_t->val;
951 
952   /* Read the data base files */
953 
954   ipass++;
955   if (ipass == 1) { /* Read parameters files */
956 
957     FILE *radfile = NULL;
958     const char *pathdatadir = cs_base_get_pkgdatadir();
959     char filepath[256];
960 
961     BFT_MALLOC(gi,    ng, cs_real_t);
962     BFT_MALLOC(tt,    nt, cs_real_t);
963     BFT_MALLOC(kpco2, nt, cs_real_t);
964     BFT_MALLOC(kph2o, nt, cs_real_t);
965     BFT_MALLOC(wv,    nband, cs_real_t);
966     BFT_MALLOC(dwv,   nband, cs_real_t);
967 
968     BFT_MALLOC(kmfs, nconc * nconc * nt *nt *ng, cs_real_t);
969 
970     /* Read k-distributions */
971     {
972       snprintf(filepath, 256, "%s/data/thch/dp_radiat_MFS", pathdatadir);
973       radfile = fopen(filepath, "r");
974       char line[256];
975       for (int cco2 = 0; cco2 < nconc; cco2++) {
976         for (int ch2o = 0; ch2o < nconc; ch2o++) {
977           for (int it = 0; it < nt; it++) {
978             for (int itrad = 0; itrad < nt; itrad++) {
979               fgets(line, 256, radfile);
980               fgets(line, 256, radfile);
981               for (int ig = 0; ig < ng; ig++) {
982                 cs_real_t temp[2] = {0.};
983                 int nvalues;
984                 _line_to_array(radfile, temp, &nvalues);
985                 assert(nvalues == 2);
986                 gi[ig] = temp[0];
987                 kmfs[  ch2o
988                      + cco2*nconc
989                      + it*nconc*nconc
990                      + itrad*nconc*nconc*nt
991                      + ig*nconc*nconc*nt*nt] = temp[1];
992               }
993             }
994           }
995         }
996       }
997       fclose(radfile);
998     }
999 
1000     /* Read the Planck coefficients */
1001     {
1002       snprintf(filepath, 256, "%s/data/thch/dp_radiat_Planck_CO2", pathdatadir);
1003       radfile = fopen(filepath, "r");
1004       for (int it = 0; it < nt; it++) {
1005         cs_real_t temp[2] = {0.};
1006         int nvalues;
1007         _line_to_array(radfile, temp, &nvalues);
1008         assert(nvalues == 2);
1009         tt[it]    = temp[0];
1010         kpco2[it] = temp[1];
1011       }
1012       fclose(radfile);
1013     }
1014 
1015     {
1016       snprintf(filepath, 256, "%s/data/thch/dp_radiat_Planck_H2O", pathdatadir);
1017       radfile = fopen(filepath, "r");
1018       for (int it = 0; it < nt; it++) {
1019         cs_real_t temp[2] = {0.};
1020         int nvalues;
1021         _line_to_array(radfile, temp, &nvalues);
1022         assert(nvalues == 2);
1023         tt[it]    = temp[0];
1024         kph2o[it] = temp[1];
1025       }
1026       fclose(radfile);
1027     }
1028 
1029     /* Read the wavelength interval */
1030     {
1031       snprintf(filepath, 256, "%s/data/thch/dp_radiat_wave", pathdatadir);
1032       radfile = fopen(filepath, "r");
1033       for (int iwvnb = 0; iwvnb < nband; iwvnb++) {
1034         cs_real_t temp[2] = {0.};
1035         int nvalues;
1036         _line_to_array(radfile, temp, &nvalues);
1037         assert(nvalues == 2);
1038         wv[iwvnb]  = temp[0];
1039         dwv[iwvnb] = temp[1];
1040       }
1041       fclose(radfile);
1042     }
1043 
1044     /* Gaussian quadrature */
1045 
1046     /* Allocation */
1047     BFT_MALLOC(gq, cs_glob_rad_transfer_params->nwsgg, cs_real_t);
1048     int m = (cs_glob_rad_transfer_params->nwsgg + 1) / 2;
1049     cs_real_t *p1, *p2, *p3, *pp;
1050     cs_real_t *z, *z1, *arth;
1051     bool *unfinished;
1052     BFT_MALLOC(p1, m, cs_real_t);
1053     BFT_MALLOC(p2, m, cs_real_t);
1054     BFT_MALLOC(p3, m, cs_real_t);
1055     BFT_MALLOC(pp, m, cs_real_t);
1056     BFT_MALLOC(z,  m, cs_real_t);
1057     BFT_MALLOC(z1, m, cs_real_t);
1058     BFT_MALLOC(arth, m, cs_real_t);
1059     BFT_MALLOC(unfinished, m, bool);
1060 
1061     /* Boundaries */
1062     cs_real_t x1 = 0.0;
1063     cs_real_t x2 = 1.0;
1064 
1065     /* Given the lower and upper limits of integration x1 and x2, this routine
1066      * returns arrays x[0..n-1]
1067      * and w[0..n-1] of length n, containing the abscissas and weights of the
1068      * Gauss-Legendre n-point
1069      * quadrature formula. The parameter EPS is the relative precision.
1070      * Note that internal computations are done in double precision. */
1071 
1072     int n = cs_glob_rad_transfer_params->nwsgg;
1073 
1074     /* The roots are symmetric in the interval, so we only have to find half of them. */
1075 
1076     cs_real_t xm = 0.5 * (x2 + x1);
1077     cs_real_t xl = 0.5 * (x2 - x1);
1078 
1079     for (int i = 0; i < m; i++)
1080       arth[i] = i;
1081 
1082     /* initial aproximation of the roots */
1083 
1084     for (int i = 0; i < m; i++) {
1085       z[i] = cos(cs_math_pi * (arth[i] - 0.25) / (n + 0.5));
1086       unfinished[i] = true;
1087     }
1088 
1089     /* Newton's method carried out simultaneously on the roots */
1090     int its;
1091     for (its = 0; its < maxit; its++) {
1092 
1093       /* initialisation */
1094 
1095       for (int j = 0; j < m; j++) {
1096         if (unfinished[j]) {
1097           p1[j]    = 1.0;
1098           p2[j]    = 0.0;
1099         }
1100       }
1101 
1102       for (int j = 0; j < n; j++) {
1103         for (int i = 0; i < m; i++) {
1104           p3[i] = p2[i];
1105           p2[i] = p1[i];
1106           p1[i] = ((2.0 * j - 1.0) * z[i] * p2[i] - (j - 1.0) * p3[i]) / j;
1107         }
1108       }
1109 
1110       /* p1 now contains the desired Legendre polynomials.
1111        * We next compute pp, its derivative, by a standard relation involving
1112        * also p2, the polynomial of one lower order. */
1113 
1114       for (int j = 0; j < m; j++) {
1115         pp[j] = n * (z[j] * p1[j] - p2[j]) / (z[j] * z[j] - 1.0);
1116         z1[j] = z[j];
1117         z[j]  = z1[j] - p1[j] / pp[j];
1118         unfinished[j] = (CS_ABS(z[j] - z1[j]) > eps);
1119       }
1120 
1121       /* check if we should continue */
1122       int cont = 0;
1123       for (int j = 0; j < m; j++) {
1124         cont = 1;
1125       }
1126       if (cont == 0)
1127         break;
1128 
1129     }
1130 
1131     if (its == maxit)
1132       cs_log_printf(CS_LOG_DEFAULT, "Maximum number of iterations during GAULEG");
1133 
1134     /* Scale the root to the desired interval, and put in its symmetric counterpart. */
1135 
1136     for (int j = 0; j < m; j++) {
1137       gq[j]         = xm - xl * z[j];
1138       gq[n - j + 1] = xm + xl * z[j];
1139     }
1140 
1141     /* Compute the weight and its symmetric counterpart. */
1142 
1143     for (int j = 0; j < m; j++) {
1144       cs_glob_rad_transfer_params->wq[j] = 2.0 * xl / ((1.0 - pow (z[j], 2.0)) * pow (pp[j], 2.0));
1145       cs_glob_rad_transfer_params->wq[n - j + 1] = cs_glob_rad_transfer_params->wq[j];
1146     }
1147 
1148     BFT_FREE(p1);
1149     BFT_FREE(p2);
1150     BFT_FREE(p3);
1151     BFT_FREE(pp);
1152     BFT_FREE(z);
1153     BFT_FREE(z1);
1154     BFT_FREE(arth);
1155     BFT_FREE(unfinished);
1156 
1157   }
1158 
1159   /* Compute the reference state */
1160 
1161   cs_real_t pco2ref = 0.0;
1162   cs_real_t ph2oref = 0.0;
1163   cs_real_t tref   = 0.0;
1164   cs_real_t sum1   = 0.0;
1165   cs_real_t sum2   = 0.0;
1166 
1167   for (cs_lnum_t iel = 0; iel < cs_glob_mesh->n_cells; iel++) {
1168 
1169     /* Calculation of pco2ref and ph2oref */
1170     pco2ref += pco2[iel] * cs_glob_mesh_quantities->cell_vol[iel];
1171     ph2oref += ph2o[iel] * cs_glob_mesh_quantities->cell_vol[iel];
1172 
1173     /* Calculation of tref */
1174     /* Interplolation of Planck coefficient for mix */
1175     cs_real_t kp;
1176     if (teloc[iel] <= tt[0])
1177       kp = pco2[iel] * kpco2[0] + ph2o[iel] * kph2o[0];
1178     else if (teloc[iel] >= tt[nt - 1])
1179       kp = pco2[iel] * kpco2[nt - 1] + ph2o[iel] * kpco2[nt - 1];
1180     else {
1181       kp = 0.;
1182       for (int it = 0; it < nt - 1; it++) {
1183         if ((teloc[iel] >= tt[it]) && (teloc[iel] < tt[it + 1])) {
1184           cs_real_t kp1 = pco2[iel] * kpco2[it] + ph2o[iel] * kph2o[it];
1185           cs_real_t kp2 = pco2[iel] * kpco2[it + 1] + ph2o[iel] * kph2o[it + 1];
1186           kp = (kp2 - kp1) / (tt[it + 1] - tt[it]) * (teloc[iel] - tt[it]) + kp1;
1187           break;
1188         }
1189       }
1190     }
1191     cs_real_t kpt4dv =  kp
1192                       * pow(teloc[iel], 4.0)
1193                       * cs_glob_mesh_quantities->cell_vol[iel];
1194     sum1 += kpt4dv * teloc[iel];
1195     sum2 += kpt4dv;
1196   }
1197 
1198   if (cs_glob_rank_id >= 0) {
1199     cs_parall_sum(1, CS_DOUBLE, &pco2ref);
1200     cs_parall_sum(1, CS_DOUBLE, &ph2oref);
1201     cs_parall_sum(1, CS_DOUBLE, &sum1);
1202     cs_parall_sum(1, CS_DOUBLE, &sum2);
1203   }
1204 
1205   pco2ref /= cs_glob_mesh_quantities->tot_vol;
1206   ph2oref /= cs_glob_mesh_quantities->tot_vol;
1207   tref = sum1 / sum2;
1208 
1209   /* Interpolation */
1210 
1211   /* Determination of the k-distribution at the reference state */
1212   int interp_method = imlinear;
1213   _interpolation4d(tref,
1214                    tref,
1215                    pco2ref,
1216                    ph2oref,
1217                    interp_method,
1218                    gfskref,
1219                    kfskref);
1220 
1221   /* [m^-1] */
1222   for (int i = 0; i < ng; i++)
1223     kfskref[i] *= 100.0;
1224 
1225   for (cs_lnum_t iel = 0; iel < cs_glob_mesh->n_cells; iel++) {
1226 
1227     /* Determination of the local absorbtion coefficient */
1228     for (int i = 0; i < ng; i++) {
1229       kfsk[i] = 0.;
1230       gfsk[i] = 0.;
1231     }
1232     _interpolation4d (tref,
1233                       teloc[iel],
1234                       pco2[iel],
1235                       ph2o[iel],
1236                       interp_method,
1237                       gfsk,
1238                       kfsk);
1239     /* [m^-1] */
1240     for (int i = 0; i < ng; i++)
1241       kfsk[i] *= 100.0;
1242 
1243     _simple_interpg(ng,
1244                     gfsk,
1245                     kfsk,
1246                     cs_glob_rad_transfer_params->nwsgg,
1247                     gq,
1248                     kloctmp);
1249     for (int i = 0; i < cs_glob_rad_transfer_params->nwsgg; i++)
1250       kloc[i * cs_glob_mesh->n_cells + iel] = kloctmp[i];
1251 
1252     /* Determination of the local weights */
1253     for (int i = 0; i < ng; i++) {
1254       kfsk[i] = 0.;
1255       gfsk[i] = 0.;
1256     }
1257     _interpolation4d(teloc[iel],
1258                      tref,
1259                      pco2ref,
1260                      ph2oref,
1261                      interp_method,
1262                      gg1,
1263                      kg1);
1264     /* [m^-1] */
1265     for (int i = 0; i < ng; i++)
1266       kg1[i] *= 100.0;
1267 
1268     _simple_interpg(ng,
1269                     kg1,
1270                     gg1,
1271                     ng,
1272                     kfskref,
1273                     gfsk);
1274     as[0]  = (gfsk[1] - gfsk[0]) / (gfskref[1] - gfskref[0] + 1e-15);
1275     as[ng-1] = (gfsk[ng-1] - gfsk[ng - 2]) / (gfskref[ng-1] - gfskref[ng - 2] + 1e-15);
1276     for (int k = 1; k < ng - 1; k++)
1277       as[k] = (gfsk[k + 1] - gfsk[k - 1]) / (gfskref[k + 1] - gfskref[k - 1] + 1e-15);
1278     _simple_interpg(ng,
1279                     gfskref,
1280                     as,
1281                     cs_glob_rad_transfer_params->nwsgg,
1282                     gq,
1283                     ag);
1284     for (int i = 0; i < cs_glob_rad_transfer_params->nwsgg; i++)
1285       aloc[i * cs_glob_mesh->n_cells + iel] = ag[i];
1286 
1287   }
1288 
1289   for (cs_lnum_t ifac = 0; ifac < cs_glob_mesh->n_b_faces; ifac++) {
1290     _interpolation4d(tpfsck[ifac],
1291                      tref,
1292                      pco2ref,
1293                      ph2oref,
1294                      interp_method,
1295                      gg1,
1296                      kg1);
1297     for (int i = 0; i < ng; i++)
1298       kg1[i] *= 100.0;
1299 
1300     _simple_interpg(ng,
1301                     kg1,
1302                     gg1,
1303                     ng,
1304                     kfskref,
1305                     gfsk);
1306     as[0]  = (gfsk[1] - gfsk[0]) / (gfskref[1] - gfskref[0] + 1e-15);
1307     as[ng] = (gfsk[ng] - gfsk[ng - 1]) / (gfskref[ng] - gfskref[ng - 1] + 1e-15);
1308     for (int k = 1; k < ng - 1; k++)
1309       as[k] = (gfsk[k + 1] - gfsk[k - 1]) / (gfskref[k + 1] - gfskref[k - 1] + 1e-15);
1310     _simple_interpg(ng,
1311                     gfskref,
1312                     as,
1313                     cs_glob_rad_transfer_params->nwsgg,
1314                     gq,
1315                     aw);
1316     for (int i = 0; i < cs_glob_rad_transfer_params->nwsgg; i++)
1317       alocb[i * cs_glob_mesh->n_b_faces + ifac] = aw[i];
1318   }
1319 
1320   /* free memory */
1321   if (cs_glob_time_step->nt_cur == cs_glob_time_step->nt_max) {
1322     BFT_FREE(gi);
1323     BFT_FREE(tt);
1324     BFT_FREE(kpco2);
1325     BFT_FREE(kph2o);
1326     BFT_FREE(wv);
1327     BFT_FREE(dwv);
1328     BFT_FREE(kmfs);
1329     BFT_FREE(gq);
1330   }
1331 
1332   BFT_FREE(kloctmp);
1333 }
1334 
1335 /*----------------------------------------------------------------------------*/
1336 
1337 END_C_DECLS
1338