123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- #include <grass/gis.h>
- #include <grass/raster.h>
- #include "global.h"
- double get_lambda(void)
- {
- int i;
- double retval;
- retval = 0.0;
- for (i = 1; i < misc.nidxclass; i++)
- retval += idxstats.Aatb_r[i] *
- (idxstats.atb[i] + idxstats.atb[i - 1]) / 2.0;
- return retval;
- }
- void initialize(void)
- {
- int i, j, t;
- double A1, A2;
- misc.lambda = get_lambda();
- misc.lnTe = params.lnTe + log(input.dt);
- misc.vch = params.vch * input.dt;
- misc.vr = params.vr * input.dt;
- misc.qs0 = params.qs0 * input.dt;
- misc.qss = exp(misc.lnTe - misc.lambda);
- misc.tch = (double *)G_malloc(params.nch * sizeof(double));
- misc.tch[0] = params.d[0] / misc.vch;
- for (i = 1; i < params.nch; i++)
- misc.tch[i] = misc.tch[0] + (params.d[i] - params.d[0]) / misc.vr;
- misc.nreach = (int)misc.tch[params.nch - 1];
- if ((double)misc.nreach < misc.tch[params.nch - 1])
- misc.nreach++;
- misc.ndelay = (int)misc.tch[0];
- misc.nreach -= misc.ndelay;
- misc.Ad = (double *)G_malloc(misc.nreach * sizeof(double));
- for (i = 0; i < misc.nreach; i++) {
- t = misc.ndelay + i + 1;
- if (t > misc.tch[params.nch - 1]) {
- misc.Ad[i] = 1.0;
- }
- else {
- for (j = 1; j < params.nch; j++) {
- if (t <= misc.tch[j]) {
- misc.Ad[i] = params.Ad_r[j - 1] +
- (params.Ad_r[j] - params.Ad_r[j - 1]) *
- (t - misc.tch[j - 1]) /
- (misc.tch[j] - misc.tch[j - 1]);
- break;
- }
- }
- }
- }
- A1 = misc.Ad[0];
- misc.Ad[0] *= params.A;
- for (i = 1; i < misc.nreach; i++) {
- A2 = misc.Ad[i];
- misc.Ad[i] = A2 - A1;
- A1 = A2;
- misc.Ad[i] *= params.A;
- }
- misc.Srz = (double **)G_malloc(input.ntimestep * sizeof(double *));
- misc.Suz = (double **)G_malloc(input.ntimestep * sizeof(double *));
- for (i = 0; i < input.ntimestep; i++) {
- misc.Srz[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
- misc.Suz[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
- }
- for (i = 0; i < misc.nidxclass; i++) {
- misc.Srz[0][i] = params.Sr0;
- misc.Suz[0][i] = 0.0;
- }
- misc.S_mean = (double *)G_malloc(input.ntimestep * sizeof(double));
- misc.S_mean[0] = -params.m * log(misc.qs0 / misc.qss);
- misc.Qt = (double *)G_malloc(input.ntimestep * sizeof(double));
- for (i = 0; i < input.ntimestep; i++)
- misc.Qt[i] = 0.0;
- for (i = 0; i < misc.ndelay; i++)
- misc.Qt[i] = misc.qs0 * params.A;
- A1 = 0.0;
- for (i = 0; i < misc.nreach; i++) {
- A1 += misc.Ad[i];
- misc.Qt[misc.ndelay + i] = misc.qs0 * (params.A - A1);
- }
- return;
- }
- void implement(void)
- {
- int i, j, k;
- double Aatb_r;
- double R;
- double _qo, _qv;
- misc.S = (double **)G_malloc(input.ntimestep * sizeof(double *));
- misc.Ea = (double **)G_malloc(input.ntimestep * sizeof(double *));
- misc.ex = (double **)G_malloc(input.ntimestep * sizeof(double *));
- misc.qt = (double **)G_malloc(input.ntimestep * sizeof(double *));
- misc.qo = (double **)G_malloc(input.ntimestep * sizeof(double *));
- misc.qv = (double **)G_malloc(input.ntimestep * sizeof(double *));
- misc.qs = (double *)G_malloc(input.ntimestep * sizeof(double));
- misc.f = (double *)G_malloc(input.ntimestep * sizeof(double));
- misc.fex = (double *)G_malloc(input.ntimestep * sizeof(double));
- for (i = 0; i < input.ntimestep; i++) {
- misc.S[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
- misc.Ea[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
- misc.ex[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
- misc.qt[i] = (double *)G_malloc((misc.nidxclass + 1) *
- sizeof(double));
- misc.qo[i] = (double *)G_malloc((misc.nidxclass + 1) *
- sizeof(double));
- misc.qv[i] = (double *)G_malloc((misc.nidxclass + 1) *
- sizeof(double));
- misc.qt[i][misc.nidxclass] = 0.0;
- misc.qo[i][misc.nidxclass] = 0.0;
- misc.qv[i][misc.nidxclass] = 0.0;
- misc.qs[i] = 0.0;
- if (params.infex) {
- misc.f[i] = input.dt *
- get_f((i + 1) * input.dt, input.R[i] / input.dt);
- misc.fex[i] = input.R[i] - misc.f[i];
- R = misc.f[i];
- }
- else {
- misc.f[i] = 0.0;
- misc.fex[i] = 0.0;
- R = input.R[i];
- }
- if (i) {
- for (j = 0; j < misc.nidxclass; j++) {
- misc.Srz[i][j] = misc.Srz[i - 1][j];
- misc.Suz[i][j] = misc.Suz[i - 1][j];
- }
- }
- misc.qs[i] = misc.qss * exp(-misc.S_mean[i] / params.m);
- for (j = 0; j < misc.nidxclass; j++) {
- Aatb_r = (idxstats.Aatb_r[j] +
- (j < misc.nidxclass - 1 ? idxstats.Aatb_r[j + 1]
- : 0.0)) / 2.0;
- misc.S[i][j] = misc.S_mean[i] +
- params.m * (misc.lambda - idxstats.atb[j]);
- if (misc.S[i][j] < 0.0)
- misc.S[i][j] = 0.0;
- misc.Srz[i][j] -= R;
- if (misc.Srz[i][j] < 0.0) {
- misc.Suz[i][j] -= misc.Srz[i][j];
- misc.Srz[i][j] = 0.0;
- }
- misc.ex[i][j] = 0.0;
- if (misc.Suz[i][j] > misc.S[i][j]) {
- misc.ex[i][j] = misc.Suz[i][j] - misc.S[i][j];
- misc.Suz[i][j] = misc.S[i][j];
- }
- _qv = 0.0;
- if (misc.S[i][j] > 0.0) {
- _qv = (params.td > 0.0 ?
- misc.Suz[i][j] /
- (misc.S[i][j] * params.td) * input.dt
- : -params.td * params.K0 *
- exp(-misc.S[i][j] / params.m));
- if (_qv > misc.Suz[i][j])
- _qv = misc.Suz[i][j];
- misc.Suz[i][j] -= _qv;
- if (misc.Suz[i][j] < ZERO)
- misc.Suz[i][j] = 0.0;
- _qv *= Aatb_r;
- }
- misc.qv[i][j] = _qv;
- misc.qv[i][misc.nidxclass] += misc.qv[i][j];
- misc.Ea[i][j] = 0.0;
- if (input.Ep[i] > 0.0) {
- misc.Ea[i][j] = input.Ep[i] *
- (1 - misc.Srz[i][j] / params.Srmax);
- if (misc.Ea[i][j] > params.Srmax - misc.Srz[i][j])
- misc.Ea[i][j] = params.Srmax - misc.Srz[i][j];
- }
- misc.Srz[i][j] += misc.Ea[i][j];
- _qo = 0.0;
- if (j > 0) {
- if (misc.ex[i][j] > 0.0)
- _qo = idxstats.Aatb_r[j] *
- (misc.ex[i][j - 1] + misc.ex[i][j]) / 2.0;
- else if (misc.ex[i][j - 1] > 0.0)
- _qo = Aatb_r * misc.ex[i][j - 1] /
- (misc.ex[i][j - 1] -
- misc.ex[i][j]) * misc.ex[i][j - 1] / 2.0;
- }
- misc.qo[i][j] = _qo;
- misc.qo[i][misc.nidxclass] += misc.qo[i][j];
- misc.qt[i][j] = misc.qo[i][j] + misc.qs[i];
- }
- misc.qo[i][misc.nidxclass] += misc.fex[i];
- misc.qt[i][misc.nidxclass] = misc.qo[i][misc.nidxclass] + misc.qs[i];
- misc.S_mean[i] = misc.S_mean[i] +
- misc.qs[i] - misc.qv[i][misc.nidxclass];
- if (i + 1 < input.ntimestep)
- misc.S_mean[i + 1] = misc.S_mean[i];
- for (j = 0; j < misc.nreach; j++) {
- k = i + j + misc.ndelay;
- if (k > input.ntimestep - 1)
- break;
- misc.Qt[k] += misc.qt[i][misc.nidxclass] * misc.Ad[j];
- }
- }
- return;
- }
- /* Object function for hydrograph suggested by Servet and Dezetter(1991) */
- double get_Em(void)
- {
- int i;
- double Em, numerator, denominator;
- misc.Qobs_mean = 0.0;
- numerator = 0.0;
- for (i = 0; i < input.ntimestep; i++) {
- misc.Qobs_mean += misc.Qobs[i];
- numerator += pow(misc.Qobs[i] - misc.Qt[i], 2.0);
- }
- misc.Qobs_mean /= input.ntimestep;
- denominator = 0.0;
- for (i = 0; i < input.ntimestep; i++)
- denominator += pow(misc.Qobs[i] - misc.Qobs_mean, 2.0);
- if (denominator == 0.0) {
- G_warning("Em can not be resolved due to constant " "observed Q");
- Rast_set_d_null_value(&Em, 1);
- }
- else {
- Em = 1.0 - numerator / denominator;
- }
- return Em;
- }
- void others(void)
- {
- int i;
- misc.Qt_mean = 0.0;
- for (i = 0; i < input.ntimestep; i++) {
- misc.Qt_mean += misc.Qt[i];
- if (!i || misc.Qt_peak < misc.Qt[i]) {
- misc.Qt_peak = misc.Qt[i];
- misc.tt_peak = i + 1;
- }
- }
- misc.Qt_mean /= input.ntimestep;
- if (file.Qobs) {
- misc.Em = get_Em();
- for (i = 0; i < input.ntimestep; i++) {
- if (!i || misc.Qobs_peak < misc.Qobs[i]) {
- misc.Qobs_peak = misc.Qobs[i];
- misc.tobs_peak = i + 1;
- }
- }
- }
- return;
- }
- void topmodel(void)
- {
- initialize();
- implement();
- others();
- return;
- }
|