Calculation will run with almost 2-fold (Dual Core) or 4-fold (Quad-Core) the speed.
Calculation will run up to 16-fold the speed. (Requires multiple networked sufficient PCs; Special Installation knowledge required.)
//============================================================ TalDef.c
//
// Write DEF-Files for LASAT
// =========================
//
// Copyright (C) Umweltbundesamt, 14191 Berlin, Germany, 2002-2007
// Copyright (C) Janicke Consulting, 26427 Dunum, Germany, 2002-2007
// email: info@austal2000.de
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// last change: 2007-03-07
//
//==========================================================================
char *TalDefVersion = "2.3.6";
char TalVersion[80];
static char *eMODn = "TalDef";
static int CHECK = 0;
// #define LOG_ALLOCATION
#include
#include
#include
#include "limits.h" //bp
#include
#include "genutl.h"
#include "IBJmsg.h"
#include "IBJary.h"
#include "IBJdmn.h"
#include "TalAKT.h"
#include "TalAKS.h"
#include "TalUtl.h"
#include "TalInp.h"
#include "TalMat.h"
#include "TalDef.h"
#include "TalDef.nls"
#define TE(i) ((TMSREC*)AryPtrX(&AryDsc, i))->t
#define RA(i) ((TMSREC*)AryPtrX(&AryDsc, i))->fRa
#define UA(i) ((TMSREC*)AryPtrX(&AryDsc, i))->fUa
#define LM(i) ((TMSREC*)AryPtrX(&AryDsc, i))->fLm
#ifdef DIAM //bp
static int numprocs = 1;//bp
#else //bp
extern int numprocs; //bp
#endif //bp
extern char AbsoluteWindLibPath[256]; //bp
static char Path[256];
static int Mode;
static ARYDSC AryDsc;
// bp static char WindLib[256] = "~../lib";
static int CalculateQq=0; //-2002-12-10
/*=================================== Time ===============================*/
static char *LocalTmString( /* return string representation of time t */
long *pt ); /* pointer to time t */
static void LocalTimeStr( long, char* );
static const char TmMinString[] = "-inf";
static const char TmMaxString[] = "+inf";
static const long TmMinValue = LONG_MIN;
static const long TmMaxValue = LONG_MAX;
/*=============================================================== LocalTmString
*/
static char *LocalTmString( /* return string representation of time t */
long *pt ) /* pointer to time t */
{
static char tstr[40];
if (!pt) strcpy( tstr, "NOT");
else if (*pt == TmMinValue) strcpy( tstr, TmMinString );
else if (*pt == TmMaxValue) strcpy( tstr, TmMaxString );
else LocalTimeStr( *pt, tstr );
return tstr;
}
/*=================================================================== LocalTimeStr
*/
static void LocalTimeStr( /* Umwandlung einer Sekundenzahl n in eine Zeichen- */
long n, /* kette t[] der Form ddd.hh:mm:ss; */
char *t ) /* führende Nullen werden fortgelassen. */
{
int l = 0;
long k;
char b[10];
t[0] = '\0';
if (n < 0) { strcat( t, "-" ); n = -n; }
k = n / 86400L;
if (k > 0) {
sprintf( b, "%ld.", k ); strcat( t, b ); n -= k*86400L; l++; }
k = n/3600L;
sprintf(b, "%02ld:", k);
strcat(t, b); n -= k*3600L; l++;
k = n/60L;
sprintf(b, "%02ld:", k);
strcat(t, b); n -= k*60L; l++;
sprintf(b, "%02ld", n);
strcat(t, b);
return; }
//===============================================================================
static int endswith( char *s, char *t ) {
int ls = strlen(s);
int lt = strlen(t);
if (lt<=ls && !strcmp(s+ls-lt, t)) return 1;
return 0;
}
//=============================================================== TdfCopySurface
//
int TdfCopySurface( // copy zg??.dmna to work/srfa??.arr
char *path ) // working directory
{
dP(TdfCopySurface);
int rc, n=0;
char fn[256];
ARYDSC dsc;
TXTSTR usr = { NULL, 0 };
TXTSTR sys = { NULL, 0 };
memset(&dsc, 0, sizeof(ARYDSC));
for (n=0; nsprintf(fn, "%s/zg%02d", path, n+(TI.nn>1));
rc = DmnRead(fn, &usr, &sys, &dsc); if (rc < 0) eX(3);
if (dsc.numdm != 2) eX(6);
DmnRplValues(&usr, "format", "zg%6.1f");
sprintf(fn, "%s/work", path);
TutDirMake(fn);
sprintf(fn, "%s/work/srfa0%d%d.arr", path, TI.gl[n], TI.gi[n]);
rc = DmnWrite(fn, usr.s, &dsc); if (rc < 0) eX(5);
AryFree(&dsc);
TxtClr(&usr);
TxtClr(&sys);
}
MsgCode = 1;
goto clear;
eX_5:
vMsg(_internal_error_);
goto clear;
eX_3: eX_6:
vMsg(_cant_read_surface_file_$_, fn);
clear:
TxtClr(&usr);
TxtClr(&sys);
if (MsgCode < 0) MsgSource = ePGMs;
return MsgCode;
}
//================================================================= TdfWriteWetter
//
static int TdfWriteWetter( char *fname ) {
dP(TdfWriteWetter);
int i, nn, i0, i1, iv;
int ir, kl;
int wind;
float ua, ra, lm, *pf, ftv[6];
float su=-1, sv=-1, sw=-1, us=-1, svf=-1;
char buf[100];
float blm_version = 2.6;
long n1, n2;
char t1s[40], t2s[40];
TIPVAR *ptv;
FILE *tms;
for (i=0; i<6; i++) ftv[i] = -1;
i0 = AryDsc.bound[0].low;
i1 = AryDsc.bound[0].hgh;
tms = fopen(fname, "w"); if (!tms) eX(1);
iv = -1;
if (NOSTANDARD) {
char *pc, *pc1, *pc2;
int nv;
pc = strstr(TI.os, "Blm="); //-2006-02-13
pc1 = strstr(TI.os, "NOSHEAR");
pc2 = strstr(TI.os, "SPREAD");
if (pc && (pc1 || pc2)) eX(2);
if (pc) sscanf(pc+4, "%f", &blm_version);
else if (pc1)
blm_version = (pc2) ? 3.8 : 2.8;
else
blm_version = (pc2) ? 3.6 : 2.6;
pc = strstr(TI.os, "Su=");
if (pc) sscanf(pc+3, "%f", &su);
pc = strstr(TI.os, "Sv=");
if (pc) sscanf(pc+3, "%f", &sv);
pc = strstr(TI.os, "Sw=");
if (pc) sscanf(pc+3, "%f", &sw);
pc = strstr(TI.os, "Us=");
if (pc) sscanf(pc+3, "%f", &us);
pc = strstr(TI.os, "Svf="); //-2007-01-30
if (pc) sscanf(pc+4, "%f", &svf);
pc = strstr(TI.os, "Ftv=");
if (pc) {
GetData("FTV", pc, "%[6]f", ftv);
}
if (TI.hm == HUGE_VAL) {
nv = TipVar.bound[0].hgh+1;
for (iv=0; ivptv = AryPtr(&TipVar, iv); if (!ptv) goto return_0;
if (!strcmp(ptv->name, "hm")) break;
}
if (iv >= nv) goto return_0;
}
}
fprintf(tms, "==================================================== wetter.def\n" );
fprintf(tms, "- TalDef: Meteorological time series %s\n", TI.az );
fprintf(tms, "- Umin=%3.1f\n", TatUmin);
fprintf(tms, ".\n");
fprintf(tms, " Version = %1.1f\n", blm_version);
fprintf(tms, " Z0 = %5.3lf \n", TI.z0 );
fprintf(tms, " D0 = %5.3lf \n", TI.d0 );
fprintf(tms, " Xa=%1.1lf Ya=%1.1lf Ha=%1.1lf \n", TI.xa, TI.ya, TI.ha );
fprintf(tms, " Ua = ? \n" );
fprintf(tms, " Ra = ? \n" );
fprintf(tms, " Lm = ? \n" );
if (NOSTANDARD) { //-2002-03-17
if (TI.hm == HUGE_VAL)
fprintf(tms, " Hm = ? \n" );
else if (TI.hm > 0)
fprintf(tms, " Hm = %6.1lf \n", TI.hm );
if (su >= 0) fprintf(tms, " Su = %1.5f \n", su);
if (sv >= 0) fprintf(tms, " Sv = %1.5f \n", sv);
if (sw >= 0) fprintf(tms, " Sw = %1.5f \n", sw);
if (us > 0) fprintf(tms, " Us = %1.5f \n", us);
if (svf > 0) fprintf(tms, " Svf = %1.5f \n", svf); //-2007-01-30
if (ftv[0] >= 0) {
fprintf(tms, " Ftv = {");
for (i=0; i<6; i++) fprintf(tms, " %1.1f", ftv[i]);
fprintf(tms, " } \n");
}
}
if (TI.mh > 0) {
fprintf(tms, " HmMean = { 0, 0, 0, %1.0lf, %1.0lf, %1.0lf }\n",
TI.mh+TipHmMean[3], TI.mh+TipHmMean[4], TI.mh+TipHmMean[5]);
}
fprintf(tms, " Wind = ? \n" );
fprintf(tms, " WindLib = %s \n", AbsoluteWindLibPath);//bp
fprintf(tms, "---------------------------------------------------------\n");
fprintf(tms, "- \n" );
fprintf(tms, "! T1 T2 Ua Ra Lm Wind ");
if (iv >= 0) fprintf(tms, " Hm"); //-2002-03-17
fprintf(tms, "\n");
fprintf(tms, "- (ddd.hh:mm:ss) (ddd.hh:mm:ss) (m/s) (deg.) (m) (1) ");
if (iv >= 0) fprintf(tms, " (m)"); //-2002-03-17
fprintf(tms, "\n");
nn = 0;
strcpy(buf, "Z \n" );
n1 = 0;
for (i=i0; i<=i1; ) {
ua = UA(i);
ra = RA(i);
lm = LM(i);
kl = TipKMclass(TI.z0, lm);
ir = 0.5 + 0.1*ra;
if (ir == 0) ir = 36;
wind = 1000*kl + ir;
n2 = n1 + TI.interval; //-2007-02-03
strcpy(t1s, LocalTmString(&n1));
strcpy(t2s, LocalTmString(&n2));
fprintf(tms, "Z %13s %13s %6.3f %6.0f %7.1f %4d", t1s, t2s, ua, ra, lm, wind);
if (iv >= 0) { //-2002-03-17
ptv = AryPtr(&TipVar, iv); if (!ptv) goto return_0;
pf = AryOPtr(ptv->o, &AryDsc, i); if (!pf) goto return_0;
fprintf(tms, " %6.1f", *pf);
}
fprintf(tms, "\n");
n1 += TI.interval;
i++;
nn++;
}
fprintf(tms, "---------------------------------------------------------\n");
fclose(tms);
return nn;
return_0:
if (tms) fclose(tms);
return 0;
eX_1:
eMSG(_cant_write_$_, fname);
eX_2:
eMSG(_error_option_);
}
//================================================================= TdfWriteMetlib
//
int TdfWriteMetlib( // write metlib.def for generating a wind library
int mode ) // TIP_COMPLEX: 2 base fields for each class
{ // RETURN: number of entries
dP(TdfWriteMetlib);
int i, n, i0, i1;
int ir, kl, ir1, ir2, irstep;
int wind, hour, day;
float ua, ra, lm;
float umean1[7];
int nmean1[7];
char buf[100], fname[256];
float blm_version = 2.6;
FILE *tms;
if (mode&TIP_COMPLEX == 0) return -2;
i0 = AryDsc.bound[0].low;
i1 = AryDsc.bound[0].hgh;
if (NOSTANDARD) {
char *pc, *pc1;
pc = strstr(TI.os, "Blm="); //-2006-02-13
pc1 = strstr(TI.os, "NOSHEAR");
if (pc && pc1) eX(2);
if (pc) sscanf(pc+4, "%f", &blm_version);
else if (pc1)
blm_version = 2.8;
else
blm_version = 2.6; //-
}
sprintf(fname, "%s/%s", Path, "metlib.def");
tms = fopen(fname, "w"); if (!tms) eX(1);
fprintf(tms, "==================================================== metlib.def\n" );
fprintf(tms, "- TalDef: Time series %s for library\n", TI.az );
fprintf(tms, "- Umin=%3.1f\n", TatUmin);
fprintf(tms, ".\n");
fprintf(tms, " Version = %1.1f\n", blm_version);
fprintf(tms, " Z0 = %5.3f \n", TI.z0 );
fprintf(tms, " D0 = %5.3f \n", TI.d0 );
fprintf(tms, " Xa=%1.1f Ya=%1.1f Ha=%1.1f \n", TI.xa, TI.ya, TI.ha );
fprintf(tms, " Ua = ? \n" );
fprintf(tms, " Ra = ? \n" );
fprintf(tms, " Lm = ? \n" );
if (TI.mh > 0) {
fprintf(tms, " HmMean = { 0, 0, 0, %1.0lf, %1.0lf, %1.0lf }\n",
TI.mh+TipHmMean[3], TI.mh+TipHmMean[4], TI.mh+TipHmMean[5]);
}
fprintf(tms, " Wind = ? \n" );
fprintf(tms, " WindLib = %s \n", AbsoluteWindLibPath);//bp
fprintf(tms, "---------------------------------------------------------\n");
fprintf(tms, "- \n" );
fprintf(tms, "! T1 T2 Ua Ra Lm Wind ");
fprintf(tms, "\n");
fprintf(tms, "- (ss) (ss) (m/s) (deg.) (m) (1) ");
fprintf(tms, "\n");
strcpy(buf, "Z \n" );
hour = 0;
day = 0;
for (kl=0; kl<=6; kl++) {
umean1[kl] = 0;
nmean1[kl] = 0;
}
for (i=i0; i<=i1; i++) {
ua = UA(i);
lm = LM(i);
if (lm == 0) continue; //-2007-03-07
kl = TipKMclass(TI.z0, lm);
ir = (int)(RA(i)/10.+0.5);
nmean1[kl] += 1;
umean1[kl] += ua;
}
n = 0;
for (kl=1; kl<=6; kl++) {
if (nmean1[kl] == 0) continue;
if (mode & TIP_LIB2) {
ir1 = (int)(RA(i0) + 0.5);
if (ir1 <= 270)
ir2 = ir1 + 90;
else {
ir2 = ir1;
ir1 -= 90;
}
irstep = 90;
}
else if ((mode & TIP_LIB36) || (mode & TIP_BODIES)) {
ir1 = 10;
ir2 = 360;
irstep = 10;
}
else {
ir1 = 180;
ir2 = 270;
irstep = 90;
}
for (ir=ir1; ir<=ir2; ir+=irstep) {
lm = TipMOvalue(TI.z0, kl);
wind = 1000*kl + (int)(ir/10.+0.5);
ra = ir;
ua = umean1[kl]/nmean1[kl];
fprintf(tms, "Z %4d %4d %6.3f %6.0f %7.1f %4d\n", n, n+1, ua, ra, lm, wind);
n++;
}
}
fprintf(tms, "---------------------------------------------------------\n");
fclose(tms);
return n;
eX_1:
eMSG(_cant_write_$_, fname);
eX_2:
eMSG(_error_option_);
}
//============================================================== TdfWriteBodies
//
int TdfWriteBodies( FILE *f ) {
int i, n, setpoint=1;
char *pc, name[256];;
fprintf(f, "================================================== bodies.def\n");
fprintf(f, ". \n");
fprintf(f, " DMKp = { %1.3f %1.3f %1.3f %1.3f %1.3f %1.3f %1.1f "
"%1.3f %1.3f }\n", TI.dmk[0], TI.dmk[1], TI.dmk[2], TI.dmk[3], TI.dmk[4],
TI.dmk[5], TI.dmk[6], TI.dmk[7], TI.dmk[8]); //-2004-12-14
fprintf(f, " TrbExt = %d\n", TipTrbExt);
fprintf(f, "-\n");
if (TI.nb < 0) {
strcpy(name, TI.bf);
for (pc=name; (*pc); pc++) if (*pc == '\\') *pc = '/';
if (*pc == '/')
fprintf(f, " RFile = %s\n", name);
else
fprintf(f, " RFile = ~../%s\n", name);
}
else {
for (n=0,i=0; i0) n++;
if (n) {
fprintf(f, "- Rectangles \n");
if (!setpoint) fprintf(f, ".\n");
fprintf(f, " Btype = BOX\n");
fprintf(f, "! Name | Xb Yb Hb Ab Bb Cb Wb\n");
fprintf(f, "---------+--------------------------------------------------------------\n");
for (i=0; iif (TI.bb[i] > 0) {
fprintf(f, "B %02d | %10.2f %10.2f %7.2f %7.2f %7.2f %7.2f "
"%7.2f\n", i+1, TI.xb[i], TI.yb[i], 0., TI.ab[i], TI.bb[i], TI.cb[i],
TI.wb[i]); //-2004-12-14
}
fprintf(f, "------------------------------------------------------------------------\n");
setpoint = 0;
}
for (n=0,i=0; iif (n) {
fprintf(f, "- Cooling towers \n");
if (!setpoint) fprintf(f, ".\n");
fprintf(f, " Btype = TOWER\n");
fprintf(f, "! Name | Xb Yb Hb Cb Db\n");
fprintf(f, "---------+----------------------------------------------\n");
for (i=0; iif (TI.bb[i] < 0) {
fprintf(f, "B %02d | %10.2f %10.2f %7.2f %7.2f %7.2f\n",
i+1, TI.xb[i], TI.yb[i], 0., TI.cb[i], -TI.bb[i]);
}
fprintf(f, "--------------------------------------------------------\n");
setpoint = 0;
}
}
return 0;
}
//================================================================= TdfWriteGrid
//
int TdfWriteGrid( FILE *f ) {
int k, n, nzd=1, periodic=0;
char flags[256] = "";
if (NOSTANDARD) {
char *pc;
pc = strstr(TI.os, "PERIODIC");
if (pc) periodic = 1;
}
fprintf(f, "==================================================== grid.def\n");
fprintf(f, ". \n");
fprintf(f, " GaKrX = %1.0lf\n", TI.gx);
fprintf(f, " GaKrY = %1.0lf\n", TI.gy);
fprintf(f, " Sk = {");
for (k=0; k<=TI.nzmax; k++) fprintf(f, " %1.1lf", TI.hh[k]);
fprintf(f, " }\n");
nzd = 1;
if (TI.kp > nzd) nzd = TI.kp; //-2001-08-03
fprintf(f, " Nzd = %d\n", nzd);
if (TI.nn > 1) strcat(flags, "+NESTED");
if (TI.nb) strcat(flags, "+BODIES");
if (strstr(TI.os, "DMKHM") && strstr(TI.os, "NOSTANDARD")) //-2005-03-11
strcat(flags, "+DMKHM");
if (*flags) fprintf(f, " Flags = %s\n", flags);
if (periodic) {
fprintf(f, " Bcx=P Bcy=P Bcz=R Hmax=%1.1lf\n", TI.hh[TI.nzmax]);
}
if (TI.nn == 1) {
fprintf(f, " Xmin = %1.1lf\n", TI.x0[0]);
fprintf(f, " Ymin = %1.1lf\n", TI.y0[0]);
fprintf(f, " Delta = %1.1lf\n", TI.dd[0]);
fprintf(f, " Nx = %d\n", TI.nx[0]);
fprintf(f, " Ny = %d\n", TI.ny[0]);
if (TI.gh[0]) { //-2001-09-15
fprintf(f, " Ntype = COMPLEX\n");
fprintf(f, " Im = %d\n", TI.im);
fprintf(f, " Ie = %1.2le\n", TI.ie);
}
else if (TI.nb) {
fprintf(f, " Ntype = FLAT3D\n");
fprintf(f, " Im = %d\n", TI.im);
fprintf(f, " Ie = %1.2le\n", TI.ie);
}
else {
fprintf(f, " Ntype = FLAT1D\n");
fprintf(f, " Rand = 20\n");
}
}
else { //-2001-10-30
int nt, nz;
double rf;
if (TI.gh[0]) nt = 3;
else if (TI.nb) nt = 2;
else nt = 1;
fprintf(f, "-\n");
fprintf(f, "! Nm | Nl Ni Nt Pt Dd Nx Ny Nz Xmin Ymin Rf Im Ie\n");
fprintf(f, "-----+------------------------------------------------------------------\n");
for (n=TI.nn-1; n>=0; n--) {
rf = (n > 1) ? 0.5 : 1.0;
fprintf(f,
"N %02d | %2d %2d %2d %2d %6.1lf %3d %3d %3d %8.1lf %8.1lf %3.1lf %3d %8.1le\n",
n+1, TI.gl[n], TI.gi[n], nt, 3, TI.dd[n], TI.nx[n], TI.ny[n], TI.nz[n],
TI.x0[n], TI.y0[n], rf, TI.im, TI.ie);
}
fprintf(f, "------------------------------------------------------------------------\n");
}
return 0;
}
//================================================================= TdfWriteParam
//
static char *ems( double eq ) {
static char s[32];
if (eq == HUGE_VAL) return " ?";
sprintf(s, "%10.3e", eq/numprocs); //bp
return s;
}
static int TdfWriteParam( void ) // write param.def
{
dP(TdfWriteParam);
char fname[256], ts[40], flags[256], name[256];
int n, i, i1, i2, k, nox, odor, ks, ic, groups=0, trace=0, spectrum=0;
int odmod=0;
long tm;
double t0, t1, t2, rate=0;
float vdep=-1, vsed=-1, vd, vs, refc, refd, tau=0, threshold;
int pm[] = { 0, 0, 0, 0, 0, 0 };
FILE *f;
threshold = TipOdorThreshold;
if (CHECK) vMsg("TdfWriteParam() ...");
if (NOSTANDARD) {
char *pc;
pc = strstr(TI.os, "Groups=");
if (pc) sscanf(pc+7, "%d", &groups);
pc = strstr(TI.os, "Tau=");
if (pc) sscanf(pc+4, "%f", &tau);
pc = strstr(TI.os, "Rate=");
if (pc) sscanf(pc+5, "%lf", &rate);
pc = strstr(TI.os, "Vd=");
if (pc) sscanf(pc+3, "%f", &vdep);
pc = strstr(TI.os, "Vs=");
if (pc) sscanf(pc+3, "%f", &vsed);
pc = strstr(TI.os, "TRACE");
if (pc) trace = 1;
pc = strstr(TI.os, "SPECTRUM"); //-2003-06-16
if (pc) spectrum = 1;
pc = strstr(TI.os, "ODMOD"); //-2004-10-04
if (pc) odmod = 1;
}
nox = (TI.cmp[cNO] != NULL);
odor = (TI.cmp[cODOR] != NULL); //-2004-08-12
for (k=0; ; k++) { //-2001-07-07
if (!*TipCmpNames[k]) break;
if (!TI.cmp[k]) continue;
strcpy(name, TipCmpNames[k]);
if (endswith(name, "-3")) pm[3] = 1;
else if (endswith(name, "-4")) pm[4] = 1;
else if (endswith(name, "-u")) pm[5] = 1;
else pm[2] = 1;
}
strcpy(fname, Path);
strcat(fname, "/work/wetter.def");
if (Mode & TIP_SERIES) {
n = TdfWriteWetter(fname); if (n < 1) eX(3);
}
else if (Mode & TIP_STAT) {
char s[512], *pc;
sprintf(s, "-B%s", AbsoluteWindLibPath); //bp
TalAKS(s);
pc = strstr(TI.os, "TAS("); //-2001-11-16
if (pc) {
if (strlen(pc) < 512) {
strcpy(s, pc+4);
pc = strchr(s, ')');
if (pc) *pc = 0;
TalAKS(s);
}
}
n = TasWriteWetter(); if (n < 0) eX(13);
AryDsc = AKSary;
n = TasWriteStaerke(); if (n < 0) eX(14);
}
//
// write param.def
//
strcpy(fname, Path);
strcat(fname, "/work/param.def");
f = fopen(fname, "wb"); if (!f) eX(4);
fprintf(f, "- Input file generated by AUSTAL2000 %s\n", TalVersion);
fprintf(f, "==================================================== param.def\n");
fprintf(f, ". \n");
if (*TI.ti)
fprintf(f, " Kennung = %s\n", TxtQuote(TI.ti));
fprintf(f, " Seed = %d\n", TI.sd);
*flags = 0;
i1 = AryDsc.bound[0].low;
i2 = AryDsc.bound[0].hgh;
if (Mode & TIP_SERIES) {
int ints = i2-i1+1;
tm = TI.interval; //-2007-02-03
fprintf(f, " Intervall = %s\n", LocalTmString(&tm));
t0 = MsgDateIncrease(TE(i1), -TI.interval);
strcpy(ts, MsgDateString(t0));
if (!strstr(ts, "00:00:00")) eX(5);
fprintf(f, " RefDatum = %s\n", ts);
tm = 0;
fprintf(f, " Start = %s\n", LocalTmString(&tm));
tm = ints * TI.interval;
fprintf(f, " Ende = %s\n", LocalTmString(&tm));
fprintf(f, " Average = %d\n", TI.average);
strcat(flags, "+MAXIMA");
if (rate <= 0) rate = 2*pow(2, TI.qs);
}
else if (Mode & TIP_STAT) {
int days = i2-i1+1;
fprintf(f, " Start = 0\n");
fprintf(f, " Ende = %d.00:00:00\n", days);
//
// to avoid lost of numerical significance //-2003-09-23
//
// if (TI.cmp[cSO2] || TI.cmp[cNO] || TI.cmp[cNO2]) {
fprintf(f, " Intervall = 1.00:00:00\n");
fprintf(f, " Average = %d\n", days);
// }
// else {
// fprintf(f, " Intervall = %d.00:00:00\n", days);
// }
if (rate <= 0) rate = 500*pow(2, TI.qs);
}
if (nox) strcat(flags, "+CHEM");
if (odor) strcat(flags, "+ODOR"); //-2004-08-12
if (odmod) strcat(flags, "+ODMOD"); //-2004-10-04
if (trace) strcat(flags, "+ONLYADVEC+EXACTTAU+TRACING");
if (TI.np && (Mode & TIP_SERIES)) strcat(flags, "+MNT"); //-2001-07-07
if (*flags) fprintf(f, " Flags = %s\n", flags);
if (tau > 0) fprintf(f, " Tau = %1.0f\n", tau);
if (groups > 0) fprintf(f, " Gruppen = %d\n", groups);
if (odor > 0) fprintf(f, " OdorThr = %6.3f\n", threshold); //-2005-03-11
//
// write grid.def
//
TdfWriteGrid(f);
//
// write bodies.def
//
if (TI.nb) TdfWriteBodies(f);
//
// write quellen.def
//
fprintf(f, "==================================================== quellen.def\n");
fprintf(f, ". \n");
fprintf(f, "! Nr. | Xq Yq Hq Aq Bq Cq Wq Dq Vq Qq Ts Lw Rh Tt\n");
fprintf(f, "------+--------------------------------------------------------------------------------------------\n");
for (i=0; idouble dq, vq, qq, sq, lq, rq, tq;
qq = TI.qq[i];
sq = TI.sq[i]; //-2001-12-27
dq = TI.dq[i];
vq = TI.vq[i];
rq = TI.rq[i]; //-2002-12-10
tq = TI.tq[i]; //-2002-12-10
lq = TI.lq[i]; //-2002-12-10
if (sq==HUGE_VAL || sq>0) {
qq = 0;
tq = 0;
lq = 0;
rq = 0;
}
else {
sq = -1; //-2002-01-03
}
fprintf(f, "Q %02d |", i+1);
fprintf(f, " %7.1lf", TI.xq[i]);
fprintf(f, " %7.1lf", TI.yq[i]);
fprintf(f, " %5.1lf", TI.hq[i]);
fprintf(f, " %5.1lf", TI.aq[i]);
fprintf(f, " %5.1lf", TI.bq[i]);
fprintf(f, " %5.1lf", TI.cq[i]);
fprintf(f, " %6.1lf", TI.wq[i]); //-2005-03-11
fprintf(f, " %4.1lf", TI.dq[i]);
if (vq == HUGE_VAL) fprintf(f, " ?");
else fprintf(f, " %4.1lf", vq);
if (qq == HUGE_VAL) fprintf(f, " ?");
else fprintf(f, " %7.3lf", qq); //-2006-10-26
if (sq == HUGE_VAL) fprintf(f, " ?"); //-2001-12-27
else fprintf(f, " %5.1lf", sq);
if (lq == HUGE_VAL) fprintf(f, " ?"); //-2002-12-10
else fprintf(f, " %6.4lf", lq);
if (rq == HUGE_VAL) fprintf(f, " ?"); //-2002-12-10
else fprintf(f, " %6.1lf", rq); //-2005-03-11
if (tq == HUGE_VAL) fprintf(f, " ?"); //-2002-12-10
else fprintf(f, " %6.1lf", tq); //-2005-03-11
fprintf(f, "\n");
}
fprintf(f, "------+--------------------------------------------------------------------------------------------\n");
//
// write stoffe.def
//
fprintf(f, "==================================================== stoffe.def\n");
for (ic=2; ic<6; ic++) { //-2001-07-07
if (!pm[ic]) continue;
fprintf(f, ". \n");
fprintf(f, " Name = %s\n", TipGruppen[ic]);
fprintf(f, " Einheit = g\n");
fprintf(f, " Rate = %1.5lf\n", rate); //-2005-02-01
if (vsed < 0) vs = 0.01*TipVsVec[ic];
else vs = vsed;
if (spectrum && ic>2) { //-2003-06-16
if (ic == 3) fprintf(f, " Diameter = { 10 50 }\n");
else if (ic == 4) fprintf(f, " Diameter = { 50 100 }\n");
else fprintf(f, " Diameter = { 10 100 }\n");
fprintf(f, " Probability = { 0 1 }\n");
}
else {
fprintf(f, " Vsed = %1.4f\n", vs); //-2004-06-08
}
fprintf(f, "-\n");
fprintf(f, "! Stoff | Vdep Refc Refd\n");
fprintf(f, "---------+---------------------------------\n");
for (k=0; ; k++) {
if (!*TipCmpNames[k]) break;
if (!TI.cmp[k]) continue;
strcpy(name, TipCmpNames[k]);
ks = TipSpcIndex(name);
vd = 0.01*TipVdVec[ic];
if (endswith(name, "-1")) {
if (ic != 2) continue;
vd = 0.01*TipVdVec[1];
}
else if (endswith(name, "-2")) {
if (ic != 2) continue;
}
else if (endswith(name, "-3")) {
if (ic != 3) continue;
}
else if (endswith(name, "-4")) {
if (ic != 4) continue;
}
else if (endswith(name, "-u")) {
if (ic != 5) continue;
}
else {
if (ic != 2) continue;
vd = (ks >= 0) ? 0.01*TipSpcTab[ks].vd : 0; //-2001-07-07
}
if (vdep >= 0) vd = vdep;
else if (spectrum && ic>2) vd = 0.01; //-2003-06-16
if (ks >= 0) {
refc = TipSpcTab[ks].ry/TipSpcTab[ks].fc;
refd = TipSpcTab[ks].rn/TipSpcTab[ks].fn;
}
else {
refc = 0;
refd = 0;
}
fprintf(f, "K %-6s | %10.3e %10.3e %10.3e\n", name, vd, refc, refd); //-2004-06-08
}
fprintf(f, "---------+---------------------------------\n");
}
//
// write chemie.def
//
if (nox) {
fprintf(f, "==================================================== chemie.def\n");
fprintf(f, ". \n");
fprintf(f, "! erzeugt\\aus | gas.no\n");
fprintf(f, "---------------+--------\n");
fprintf(f, "C gas.no2 | ?\n");
fprintf(f, "C gas.no | ?\n");
fprintf(f, "---------------+--------\n");
}
//
// write staerke.def
//
fprintf(f, "==================================================== staerke.def\n");
fprintf(f, ". \n");
if (Mode & TIP_STAT) fprintf(f, " EmisFac = ?\n-\n");
fprintf(f, "! QUELLE |");
for (k=0; ; k++) {
if (!*TipCmpNames[k]) break;
if (!TI.cmp[k]) continue;
strcpy(name, TipCmpNames[k]);
if (endswith(name, "-3")) ic = 3;
else if (endswith(name, "-4")) ic = 4;
else if (endswith(name, "-u")) ic = 5;
else ic = 2;
fprintf(f, " %s.%-6s", TipGruppen[ic], name);
}
fprintf(f, "\n");
fprintf(f, "---------+");
for (k=0; ; k++) {
if (!*TipCmpNames[k]) break;
if (!TI.cmp[k]) continue;
fprintf(f, "-----------");
}
fprintf(f, "\n");
for (i=0; ifprintf(f, "E %02d |", i+1);
for (k=0; ; k++) {
if (!*TipCmpNames[k]) break;
if (!TI.cmp[k]) continue;
strcpy(name, TipCmpNames[k]);
fprintf(f, " %s", ems(TI.cmp[k][i]));
}
fprintf(f, "\n");
}
fprintf(f, "---------+");
for (k=0; ; k++) {
if (!*TipCmpNames[k]) break;
if (!TI.cmp[k]) continue;
fprintf(f, "-----------");
}
fprintf(f, "\n");
//
// write monitor.def
//
if (TI.np>0 && (Mode&TIP_SERIES)) {
fprintf(f, "==================================================== monitor.def\n");
fprintf(f, ". \n");
fprintf(f, "! Nr. | Xp Yp Hp\n");
fprintf(f, "------+----------------------\n");
for (i=0; ifprintf(f, "M %02d | %7.1lf %7.1lf %5.1lf\n",
i+1, TI.xp[i], TI.yp[i], TI.hp[i]);
fprintf(f, "------+----------------------\n");
}
fprintf(f, "====================================================\n");
fclose(f);
return 0;
eX_3: eX_13: eX_14:
eMSG(_cant_write_series_$_, fname);
eX_4:
eMSG(_cant_write_$_, fname);
eX_5:
eMSG(_no_daystart_at_00_$_, ts);
}
//========================================================== TdfWriteVariabel
//
static int TdfWriteVariabel( void ) // write variabel.ztr
{
dP(TdfWriteVariabel);
char fname[256], t1s[40], t2s[40];
int i0, i1, i, k, nv, iv, nox;
long n1, n2;
float *pf, r1, r2;
FILE *f;
TIPVAR *ptv;
int clc_qq=0;
if (CHECK) vMsg("TdfWriteVariabel() ...\n");
nox = (TI.cmp[cNO] != NULL);
//
if (!nox && !(Mode & TIP_VARIABLE)) return 0;
//
if (!TipVar.start) nv = 0;
else nv = TipVar.bound[0].hgh+1;
strcpy(fname, Path);
strcat(fname, "/work/variabel.ztr");
f = fopen(fname, "w");
if (!f) {
vMsg(_cant_write_$_, fname);
return -1;
}
i0 = AryDsc.bound[0].low;
i1 = AryDsc.bound[0].hgh;
fprintf(f, "- LASAT input file generated by AUSTAL2000 %s\n", TalVersion);
fprintf(f, "==================================================== variabel.ztr\n");
fprintf(f, ". \n");
if (nox) {
fprintf(f, " gas.no2-gas.no = R2\n");
fprintf(f, " gas.no-gas.no = R1\n");
}
for (iv=0; ivptv = AryPtr(&TipVar, iv); if (!ptv) eX(10);
if (*(ptv->lasn)) fprintf(f, " %s = %s\n", ptv->lasn, ptv->name);
}
fprintf(f, "-\n");
fprintf(f, "! T1 T2");
if (nox) fprintf(f, " R2 R1");
for (iv=0; ivptv = AryPtr(&TipVar, iv); if (!ptv) eX(10);
fprintf(f, " %10s", ptv->name);
}
fprintf(f, "\n");
fprintf(f, "---------------------------");
if (nox) fprintf(f, "------------------------");
for (iv=0; ivfprintf(f, "\n");
for (iv=0; iv
}
n1 = 0;
for (i=i0; i<=i1; i++) {
k = TipKMclass(TI.z0, LM(i)) - 1;
n2 = n1 + TI.interval; //-2007-02-03
strcpy(t1s, LocalTmString(&n1));
strcpy(t2s, LocalTmString(&n2));
fprintf(f, "Z %12s %12s", t1s, t2s);
if (nox) {
r1 = -1.0/(TipNoxTimes[k]*3600);
r2 = -r1*46.0/30.0;
fprintf(f, " %11.3e %11.3e", r2, r1);
}
for (iv=0; ivptv = AryPtr(&TipVar, iv); if (!ptv) eX(11);
if (!strcmp(ptv->name, "hm")) continue;
pf = AryOPtr(ptv->o, &AryDsc, i); if (!pf) eX(12);
fprintf(f, " %10.3e", *pf/numprocs); //bp
}
fprintf(f, "\n");
n1 += TI.interval;
}
fprintf(f, "---------------------------");
if (nox) fprintf(f, "------------------------");
for (iv=0; ivfprintf(f, "\n");
fclose(f);
return 0;
eX_10: eX_11: eX_12:
eMSG(_internal_error_);
}
//================================================================== TdfWrite
//
int TdfWrite( // write def-files
char *path, // working directory
ARYDSC *pary, // time series or statistics
DMNFRMREC *frmtab, // format table for array record
int mode ) // working mode (TIP_SERIES, TIP_STAT, TIP_VARIABLE)
{
dP(TdfWrite);
int n;
if (CHECK) vMsg("TdfWrite() ...");
if (!pary) eX(11);
strcpy(Path, path);
AryDsc = *pary;
AryDsc.usrcnt = -1;
Mode = mode;
if (mode & TIP_LIBRARY) {
n = TdfWriteMetlib(mode);
return n;
}
n = TdfWriteParam(); if (n < 0) return n;
if (Mode & TIP_SERIES) {
n = TdfWriteVariabel(); if (n < 0) return n;
}
return n;
eX_11:
eMSG(_internal_error_);
}
//==============================================================================
//
// history:
//
// 2001-07-07 lj 0.5.3 monitor.def for time series only
// pm-3, pm-4 and pm-u
// 2001-07-09 lj 0.6.0 release candidate
// 2001-08-03 lj 0.6.1 nzd>1 if required
// 2001-09-23 lj 0.8.0 release candidate
// 2001-10-30 lj 0.8.1 grid nesting
// 2001-11-05 lj 0.9.0 release candidate
// 2001-11-16 lj 0.9.1 parameter for TalAKS form TI.os
// 2002-01-03 lj 0.10.1 default value of sq = -1
// 2002-03-17 lj 0.11.1 parameter mixing height
// 2002-03-28 lj 0.11.2 adaption to new vMsg()
// 2002-06-20 lj 0.12.2 wind direction ra as float
// 2002-09-23 lj 0.13.2 source parameter RH and LW
// 2002-09-24 lj 1.0.0 final release candidate
// 2002-12-10 lj 1.0.4 parameter lq, rq, tq allowed to vary with time
// 2003-09-23 lj 1.1.10 avoid lost of numerical significance (AKS)
// 2004-06-08 lj 1.1.18 write vd using %10.3e
// 2004-06-10 lj 2.1.1 species odor
// 2004-10-04 lj 2.1.3 no standard option ODMOD
// 2004-10-25 lj 2.1.4 factors ftv[] in NOSTANDARD
// 2004-12-14 uj 2.1.5 angle wb in degree
// 2005-02-01 uj 2.1.6 write out Rate with 5 decimal places
// 2005-02-15 uj 2.1.14 option DMKHM
// 2005-03-11 lj 2.1.16 output to *.def with 1 fractional digit, OdorThr
// 2005-03-17 uj 2.2.0 version number upgrade
// 2006-02-06 uj 2.2.7 TmString->LocalTmString, TimeStr->LocalTimeStr
// unused function Seconds() removed
// 2006-02-13 uj 2.2.8 nostandard option SPREAD
// 2006-10-18 lj 2.3.0 externalization of strings
// 2006-10-23 uj 2.3.1 qq with three decimal places
// 2007-01-30 uj 2.3.4 define Svf via option string
// 2007-02-03 uj 2.3.5 time interval revised
// 2007-03-07 uj 2.3.6 calculation of uamean corrected
//
//==============================================================================