예제 #1
0
파일: grid.c 프로젝트: sakov/enkf-c
void grid_getdims(grid* g, int* ni, int* nj, int* nk)
{
    if (ni != NULL) {
        if (g->htype == GRIDHTYPE_LATLON) {
            gnxy_simple* nodes = (gnxy_simple*) g->gridnodes_xy;

            *ni = nodes->nx;
            *nj = nodes->ny;
#if !defined(NO_GRIDUTILS)
        } else if (g->htype == GRIDHTYPE_CURVILINEAR) {
            gnxy_curv* nodes = (gnxy_curv*) g->gridnodes_xy;

            *ni = gridnodes_getnx(nodes->gn);
            *nj = gridnodes_getny(nodes->gn);
#endif
        } else
            enkf_quit("programming error");
    }
    if (nk != NULL) {
        if (g->vtype == GRIDVTYPE_Z || g->vtype == GRIDVTYPE_SIGMA)
            *nk = ((gnz_simple *) g->gridnodes_z)->nz;
        else
            enkf_quit("not implemented");
    }
}
예제 #2
0
파일: grid.c 프로젝트: sakov/enkf-c
static void grid_setcoords(grid* g, int htype, int hnodetype, int nx, int ny, int nz, void* x, void* y, double* z)
{
    g->htype = htype;
    if (htype == GRIDHTYPE_LATLON)
        g->gridnodes_xy = gnxy_simple_create(nx, ny, x, y);
#if !defined(NO_GRIDUTILS)
    else if (htype == GRIDHTYPE_CURVILINEAR) {
        g->gridnodes_xy = gnxy_curv_create(hnodetype, nx, ny, x, y, g->maptype);
#if defined(GRIDNODES_WRITE)
        {
            char fname[MAXSTRLEN];

            snprintf(fname, MAXSTRLEN, "gridnodes-%d.txt", grid_getid(g));
            if (!file_exists(fname))
                gridnodes_write(((gnxy_curv*) g->gridnodes_xy)->gn, fname, CT_XY);
        }
#endif
    }
#endif
    else
        enkf_quit("programming error");

    grid_setlonbase(g);
    if (g->vtype == GRIDVTYPE_Z || g->vtype == GRIDVTYPE_SIGMA)
        g->gridnodes_z = gnz_simple_create(nz, z);
    else
        enkf_quit("not implemented");
}
예제 #3
0
파일: calcs.c 프로젝트: sakov/enkf-c
/** Calculates G = inv(I + S' * S) * S' = S' * inv(I + S * S').
 */
void calc_G_denkf(int m, int p, double** S, int i, int j, double** G)
{
    double** M;
    double a = 1.0;
    double b = 0.0;
    int lapack_info;

    if (p < m) {
        M = alloc2d(p, p, sizeof(double));
        /*
         * M = inv(I + S * S')
         */
        lapack_info = calc_M(p, m, 1, S, M);
        if (lapack_info != 0)
            enkf_quit("dpotrf() or dpotri(): lapack_info = %d at (i, j) = (%d, %d)", lapack_info, i, j);

        /*
         * G = S' * inv(I + S * S') 
         */
        dgemm_(&doT, &noT, &m, &p, &p, &a, S[0], &p, M[0], &p, &b, G[0], &m);
    } else {
        /*
         * M = inv(I + S' * S)
         */
        M = alloc2d(m, m, sizeof(double));
        lapack_info = calc_M(p, m, 0, S, M);
        if (lapack_info != 0)
            enkf_quit("dpotrf() or dpotri(): lapack_info = %d at (i, j) = (%d, %d)", lapack_info, i, j);
        /*
         * G = inv(I + S * S') * S'
         */
        dgemm_(&noT, &doT, &m, &p, &m, &a, M[0], &m, S[0], &p, &b, G[0], &m);
    }

#if defined(CHECK_G)
    {
        int e, o;

        /*
         * check that columns of G sum up to 0
         */
        for (o = 1; o < p; ++o) {
            double* Go = G[o];
            double sumG = 0.0;
            double sumS = 0.0;

            for (e = 0; e < m; ++e) {
                sumG += Go[e];
                sumS += S[e][o];
            }

            if (fabs(sumG) > EPS)
                enkf_quit("inconsistency in G: column %d sums up to %.15f for (i, j) = (%d, %d); sum(S(%d,:) = %.15f)", o, sumG, i, j, o, sumS);
        }
    }
#endif

    free(M);
}
예제 #4
0
파일: calcs.c 프로젝트: sakov/enkf-c
/** Calculates G = inv(I + S' * S) * S' and T = (I + S' * S)^-1/2.
 */
void calc_G_etkf(int m, int p, double** S, double alpha, int ii, int jj, double** G, double** T)
{
    double** M = alloc2d(m, m, sizeof(double));
    int lapack_info;
    int i;

    /*
     * dgemm stuff 
     */
    double a = 1.0;
    double b = 0.0;

    /*
     * M = S' * S 
     */
    dgemm_(&doT, &noT, &m, &m, &p, &a, S[0], &p, S[0], &p, &b, M[0], &m);

    /*
     * M = I + S' * S
     */
    for (i = 0; i < m; ++i)
        M[i][i] += 1.0;

    lapack_info = invsqrtm2(m, alpha, M, T);    /* M = M^-1, T = M^-1/2 */
    if (lapack_info != 0)
        enkf_quit("dgesvd(): lapack_info = %d at (i, j) = (%d, %d)", lapack_info, ii, jj);

    /*
     * G = inv(I + S * S') * S'
     */
    dgemm_(&noT, &doT, &m, &p, &m, &a, M[0], &m, S[0], &p, &b, G[0], &m);

#if defined(CHECK_G)
    /*
     * check that columns of G sum up to 0
     */
    {
        int e, o;

        for (o = 1; o < p; ++o) {
            double* Go = G[o];
            double sumG = 0.0;
            double sumS = 0.0;

            for (e = 0; e < m; ++e) {
                sumG += Go[e];
                sumS += S[e][o];
            }

            if (fabs(sumG) > EPS)
                enkf_quit("inconsistency in G: column %d sums up to %.15f for (i, j) = (%d, %d); sum(S(%d,:) = %.15f)", o, sumG, ii, jj, o, sumS);
        }
    }
#endif

    free(M);
}
예제 #5
0
파일: obstypes.c 프로젝트: juicydut/enkf-c
static void obstype_check(obstype* type)
{
    assert(type->name != NULL);
    if (type->issurface < 0)
        enkf_quit("\"%s\": ISSURFACE not specified\n");
    if (type->varname == NULL)
        enkf_quit("\"%s\": VAR not specified\n");
    if (type->hfunction == NULL)
        enkf_quit("\"%s\": HFUNCTION not specified\n");
}
예제 #6
0
파일: model.c 프로젝트: sakov/enkf-c
static void model_checkvars(model* m, char* modelprm)
{
    int i;

    for (i = 0; i < m->nvar; ++i) {
        variable* v = &m->vars[i];

        if (!isfinite(v->inflation) || v->inflation <= 0)
            enkf_quit("\"%s\": \"%s\": inflation = %.3g\n", modelprm, v->name, v->inflation);
        if (v->deflation <= 0)
            enkf_quit("\"%s\": \"%s\": deflation = %.3g\n", modelprm, v->name, v->deflation);
    }
}
예제 #7
0
파일: model.c 프로젝트: sakov/enkf-c
void model_addorreplacedata(model* m, char tag[], int vid, int alloctype, void* data)
{
    modeldata* mdata;
    int i;
    int ni, nj, nk;

    for (i = 0; i < m->ndata; ++i)
        if (strcmp(tag, m->data[i].tag) == 0)
            break;

    mdata = &m->data[i];
    if (i == m->ndata) {
        if (m->ndata % NMODELDATA_INC == 0)
            m->data = realloc(m->data, (m->ndata + NMODELDATA_INC) * sizeof(modeldata));
        mdata->tag = strdup(tag);
        mdata->vid = vid;
        mdata->alloctype = alloctype;
        m->ndata++;
    } else
        assert(mdata->alloctype == alloctype);

    model_getvardims(m, mdata->vid, &ni, &nj, &nk);
    if (mdata->alloctype == ALLOCTYPE_1D)
        memcpy(mdata->data, data, nk * sizeof(float));
    else if (mdata->alloctype == ALLOCTYPE_2D)
        mdata->data = copy2d(data, nj, ni, sizeof(float));
    else if (mdata->alloctype == ALLOCTYPE_3D)
        mdata->data = copy3d(data, nk, nj, ni, sizeof(float));
    else
        enkf_quit("programming error");
}
예제 #8
0
파일: grid.c 프로젝트: sakov/enkf-c
void grid_ij2xy(grid* g, int i, int j, double* x, double* y)
{
    if (g->htype == GRIDHTYPE_LATLON) {
        gnxy_simple* gs = (gnxy_simple*) g->gridnodes_xy;

        if (i < 0 || j < 0 || i >= gs->nx || j >= gs->ny) {
            *x = NaN;
            *y = NaN;
        } else {
            *x = gs->x[i];
            *y = gs->y[j];
        }
    }
#if !defined(NO_GRIDUTILS)
    else if (g->htype == GRIDHTYPE_CURVILINEAR) {
        gridnodes* gn = ((gnxy_curv*) g->gridnodes_xy)->gn;

        if (i < 0 || j < 0 || i >= gridnodes_getnce1(gn) || j >= gridnodes_getnce2(gn)) {
            *x = NaN;
            *y = NaN;
        } else {
            *x = gridnodes_getx(gn)[j][i];
            *y = gridnodes_gety(gn)[j][i];
        }
    }
#endif
    else
        enkf_quit("programming error");
}
예제 #9
0
파일: grid.c 프로젝트: sakov/enkf-c
static void z2fk(void* p, double fi, double fj, double z, double* fk)
{
    grid* g = (grid*) p;
    gnz_simple* nodes = g->gridnodes_z;

    /*
     * for sigma coordinates convert `z' to sigma
     */
    if (g->vtype == GRIDVTYPE_SIGMA) {
        int ni = 0, nj = 0;
        double depth;

        if (g->htype == GRIDHTYPE_LATLON) {
            gnxy_simple* nodes = (gnxy_simple*) g->gridnodes_xy;

            ni = nodes->nx;
            nj = nodes->ny;
#if !defined(NO_GRIDUTILS)
        } else if (g->htype == GRIDHTYPE_CURVILINEAR) {
            gnxy_curv* nodes = (gnxy_curv*) g->gridnodes_xy;

            ni = gridnodes_getnx(nodes->gn);
            nj = gridnodes_getny(nodes->gn);
#endif
        } else
            enkf_quit("programming error");

        depth = (double) interpolate2d(fi, fj, ni, nj, g->depth, g->numlevels, grid_isperiodic_x(g));
        z /= depth;
    }

    *fk = z2fk_basic(nodes->nz, nodes->zt, nodes->zc, z);
}
예제 #10
0
파일: grid.c 프로젝트: sakov/enkf-c
void grid_z2fk(grid* g, double fi, double fj, double z, double* fk)
{
    if (g->vtype == GRIDVTYPE_Z || g->vtype == GRIDVTYPE_SIGMA)
        z2fk(g, fi, fj, z, fk);
    else
        enkf_quit("not implemented");
}
예제 #11
0
파일: ensobs.c 프로젝트: juicydut/enkf-c
/** Replaces observation errors in the observation file with the modified
 * values. The original values are stored as "std_orig".
 */
void das_addmodifiederrors(dasystem* das, char fname[])
{
    int ncid;
    int dimid_nobs[1];
    size_t nobs;
    int varid_std;
    double* std;
    int i;

    if (rank != 0)
        return;

    ncw_open(fname, NC_WRITE, &ncid);
    ncw_inq_dimid(fname, ncid, "nobs", dimid_nobs);
    ncw_inq_dimlen(fname, ncid, dimid_nobs[0], &nobs);

    ncw_redef(fname, ncid);
    if (ncw_var_exists(ncid, "std_orig"))
        enkf_quit("\"observations.nc\" has already been modified by `enkf_calc\'. To proceed please remove observations*.nc and rerun `enkf_prep\'.");
    ncw_rename_var(fname, ncid, "std", "std_orig");
    ncw_def_var(fname, ncid, "std", NC_FLOAT, 1, dimid_nobs, &varid_std);
    ncw_enddef(fname, ncid);

    std = malloc(nobs * sizeof(double));

    for (i = 0; i < (int) nobs; ++i)
        std[i] = das->obs->data[i].std;
    ncw_put_var_double(fname, ncid, varid_std, std);

    free(std);

    ncw_close(fname, ncid);
}
예제 #12
0
파일: ensobs.c 프로젝트: juicydut/enkf-c
static void das_changeSmode(dasystem* das, int mode_from, int mode_to)
{
    assert(das->s_mode == mode_from);

    if (das->obs->nobs == 0)
        goto finish;

    if (mode_from == S_MODE_HA_f && mode_to == S_MODE_HE_f) {
        observations* obs = das->obs;
        int e, o;

        for (e = 0; e < das->nmem; ++e) {
            ENSOBSTYPE* Se = das->S[e];

            for (o = 0; o < obs->nobs; ++o)
                /*
                 * das->s_f is innovation = obs - forecast; hence forecast = obs
                 * - innovation 
                 */
                Se[o] += obs->data[o].value - das->s_f[o];
        }
    } else
        enkf_quit("das_changesmode(): transition from mode %d to mode %d is not handled yet\n", mode_from, mode_to);

 finish:
    das->s_mode = mode_to;
}
예제 #13
0
파일: grid.c 프로젝트: marshallward/enkf-c
static gnz* gnz_create(int nz, double* z)
{
    gnz* nodes = malloc(sizeof(gnz));
    int i;

    /*
     * reverse z if it is negative
     */
    for (i = 0; i < nz; ++i)
        if (z[i] < -EPSZ)
            break;
    if (i < nz)
        for (i = 0; i < nz; ++i)
            z[i] = -z[i];
    for (i = 0; i < nz; ++i)
        if (z[i] < -EPSZ)
            enkf_quit("layer centre coordinates should be either positive or negative only");

    nodes->zt = z;
    nodes->nz = nz;

    /*
     * this code is supposed to work both for z and sigma grids
     */
    nodes->zc = malloc((nz + 1) * sizeof(double));
    if (z[nz - 1] >= z[0]) {
        /*
         * layer 0 at surface
         */
        nodes->zc[0] = 0.0;
        for (i = 1; i <= nz; ++i) {
            nodes->zc[i] = 2.0 * z[i - 1] - nodes->zc[i - 1];
            /*
             * layer boundary should be above the next layer centre
             */
            if (i < nz)
                assert(nodes->zc[i] < z[i]);
        }
    } else {
        /*
         * layer 0 the deepest
         */
        nodes->zc[nz] = 0.0;
        for (i = nz - 1; i >= 0; --i) {
            nodes->zc[i] = 2.0 * z[i] - nodes->zc[i + 1];
            /*
             * layer boundary should be above the next layer centre
             */
            if (i > 0)
                assert(nodes->zc[i] < z[i - 1]);
        }
    }

    return nodes;
}
예제 #14
0
파일: model.c 프로젝트: sakov/enkf-c
void* model_getgridbyname(model* m, char name[])
{
    int i;

    for (i = 0; i < m->ngrid; ++i)
        if (strcmp(grid_getname(m->grids[i]), name) == 0)
            return m->grids[i];

    enkf_quit("model_getgridbyname(): found no grid named \"%s\"", name);
    return NULL;
}
예제 #15
0
파일: grid.c 프로젝트: sakov/enkf-c
void grid_fij2xy(grid* g, double fi, double fj, double* x, double* y)
{
    if (g->htype == GRIDHTYPE_LATLON)
        gs_fij2xy(g, fi, fj, x, y);
#if !defined(NO_GRIDUTILS)
    else if (g->htype == GRIDHTYPE_CURVILINEAR)
        gc_fij2xy(g, fi, fj, x, y);
#endif
    else
        enkf_quit("programming error");
}
예제 #16
0
파일: grid.c 프로젝트: sakov/enkf-c
void grid_xy2fij(grid* g, double x, double y, double* fi, double* fj)
{
    if (g->htype == GRIDHTYPE_LATLON)
        gs_xy2fij(g, x, y, fi, fj);
#if !defined(NO_GRIDUTILS)
    else if (g->htype == GRIDHTYPE_CURVILINEAR)
        gc_xy2fij(g, x, y, fi, fj);
#endif
    else
        enkf_quit("programming error");
}
예제 #17
0
파일: grid.c 프로젝트: sakov/enkf-c
int grid_gettoplayerid(grid* g)
{
    if (g->vtype == GRIDVTYPE_Z || g->vtype == GRIDVTYPE_SIGMA) {
        gnz_simple* nodes = g->gridnodes_z;
        int kmax = nodes->nz - 1;
        double* z = nodes->zt;

        return (fabs(z[0]) < fabs(z[kmax])) ? 0 : kmax;
    } else
        enkf_quit("not implemented");

    return -1;
}
예제 #18
0
파일: model.c 프로젝트: TheProjecter/enkf-c
int model_getvarid(model* m, char* varname, int hastosucceed)
{
    int i;

    for (i = 0; i < m->nvar; ++i)
        if (strcmp(m->vars[i].name, varname) == 0)
            return i;

    if (hastosucceed)
        enkf_quit("model_getvarid(): can not find variable \"%s\" in the model", varname);

    return -1;
}
예제 #19
0
파일: calcs.c 프로젝트: sakov/enkf-c
/** Calculates X5 = G * s * 1' + T.
 * X5 is assumed being initialised to 0
 * G is [m x p]
 * S is [p x m]
 * s is [p]
 * X5 is [m x m]
 */
void calc_X5_denkf(int m, int p, double** G, double** S, double* s, double alpha, int ii, int jj, double** X5)
{
    double* w = calloc(m, sizeof(double));
    double a, b;
    int i, j;

    /*
     * w = G * s 
     */
    if (enkf_nomeanupdate == 0) /* "normal" way */
        calc_w(m, p, G, s, w);

    /*
     * X5 = G * s * 1^T 
     */
    for (j = 0; j < m; ++j)
        memcpy(X5[j], w, m * sizeof(double));

    /*
     * X5 = G * s * 1^T - 1/2 * alpha * G * S 
     */
    a = -0.5 * alpha;
    b = 1.0;
    dgemm_(&noT, &noT, &m, &m, &p, &a, G[0], &m, S[0], &p, &b, X5[0], &m);

    /*
     * X5 = G * s * 1^T - 1/2 * alpha * G * S + I 
     */
    for (i = 0; i < m; ++i)
        X5[i][i] += 1.0;

#if defined(CHECK_X5)
    /*
     * check that columns of X5 sum up to 1 
     */
    for (i = 0; i < m; ++i) {
        double* X5i = X5[i];
        double sum = 0.0;

        for (j = 0; j < m; ++j)
            sum += X5i[j];

        if (fabs(sum - 1.0) > EPS)
            enkf_quit("inconsistency in X5: column %d sums up to %.15f for (i, j) = (%d, %d)", i, sum, ii, jj);
    }
#endif

    free(w);
}
예제 #20
0
파일: grid.c 프로젝트: marshallward/enkf-c
void grid_ij2xy(grid* g, int i, int j, double* x, double* y)
{
    if (g->htype == GRIDHTYPE_LATLON_REGULAR || g->htype == GRIDHTYPE_LATLON_IRREGULAR) {
        *x = ((gnxy_simple*) g->gridnodes_xy)->x[i];
        *y = ((gnxy_simple*) g->gridnodes_xy)->y[j];
    }
#if !defined(NO_GRIDUTILS)
    else if (g->htype == GRIDHTYPE_CURVILINEAR) {
        *x = gridnodes_getx(((gnxy_curv*) g->gridnodes_xy)->gn)[j][i];
        *y = gridnodes_gety(((gnxy_curv*) g->gridnodes_xy)->gn)[j][i];
    }
#endif
    else
        enkf_quit("programming error");
}
예제 #21
0
파일: grid.c 프로젝트: sakov/enkf-c
void grid_destroy(grid* g)
{
    free(g->name);
    if (g->htype == GRIDHTYPE_LATLON)
        gnxy_simple_destroy(g->gridnodes_xy);
#if !defined(NO_GRIDUTILS)
    else if (g->htype == GRIDHTYPE_CURVILINEAR)
        gnxy_curv_destroy(g->gridnodes_xy);
#endif
    else
        enkf_quit("programming_error");
    if (g->gridnodes_z != NULL) {
        if (g->vtype == GRIDVTYPE_Z || g->vtype == GRIDVTYPE_SIGMA)
            gnz_simple_destroy(g->gridnodes_z);
        else
            enkf_quit("not implemented");
    }
    if (g->numlevels != NULL)
        free(g->numlevels);
    if (g->depth != NULL)
        free(g->depth);

    free(g);
}
예제 #22
0
파일: model.c 프로젝트: TheProjecter/enkf-c
void model_addmodeldata(model* m, char tag[], int alloctype, void* data)
{
    int i;

    for (i = 0; i < m->ndata; ++i)
        if (strcmp(tag, m->data[i].tag) == 0)
            enkf_quit("model data tag \"%s\" already in use", tag);

    if (m->ndata % NMODELDATA_INC == 0)
        m->data = realloc(m->data, (m->ndata + NMODELDATA_INC) * sizeof(modeldata));
    m->data[m->ndata].tag = strdup(tag);
    m->data[m->ndata].alloctype = alloctype;
    m->data[m->ndata].data = data;
    m->ndata++;
}
예제 #23
0
파일: ensobs.c 프로젝트: juicydut/enkf-c
void das_destandardise(dasystem* das)
{
    observations* obs = das->obs;
    double mult = sqrt((double) das->nmem - 1);
    int e, i;

    if (das->s_mode == S_MODE_HA_f || das->s_mode == S_MODE_HA_a)
        return;

    if (obs->nobs == 0)
        goto finish;

    for (e = 0; e < das->nmem; ++e) {
        ENSOBSTYPE* Se = das->S[e];

        for (i = 0; i < obs->nobs; ++i) {
            observation* o = &obs->data[i];

            Se[i] *= o->std * sqrt(obs->obstypes[o->type].rfactor) * mult;
        }
    }
    if (das->s_f != NULL) {
        for (i = 0; i < obs->nobs; ++i) {
            observation* o = &obs->data[i];

            das->s_f[i] *= o->std * sqrt(obs->obstypes[o->type].rfactor) * mult;
        }
    }
    if (das->s_a != NULL) {
        for (i = 0; i < obs->nobs; ++i) {
            observation* o = &obs->data[i];

            das->s_a[i] *= o->std * sqrt(obs->obstypes[o->type].rfactor) * mult;
        }
    }

 finish:
    if (das->s_mode == S_MODE_S_f)
        das->s_mode = S_MODE_HA_f;
    else if (das->s_mode == S_MODE_S_a)
        das->s_mode = S_MODE_HA_a;
    else
        enkf_quit("programming error");

}
예제 #24
0
파일: grid.c 프로젝트: sakov/enkf-c
void grid_print(grid* g, char offset[])
{
    int nx, ny, nz;

    enkf_printf("%sgrid info:\n", offset);
    switch (g->htype) {
    case GRIDHTYPE_LATLON:
        enkf_printf("%s  hor type = LATLON\n", offset);
        enkf_printf("%s  periodic by X = %s\n", offset, grid_isperiodic_x(g) ? "yes" : "no");
        break;
#if !defined(NO_GRIDUTILS)
    case GRIDHTYPE_CURVILINEAR:
        enkf_printf("%s  hor type = CURVILINEAR\n", offset);
        if (g->maptype == GRIDMAP_TYPE_BINARY)
            enkf_printf("%s  map type = BINARY TREE\n", offset);
        else if (g->maptype == GRIDMAP_TYPE_KDTREE)
            enkf_printf("%s  map type = KD-TREE\n", offset);
        else
            enkf_quit("unknown grid map type");
        break;
#endif
    default:
        enkf_printf("%s  h type = NONE\n", offset);
    }
    grid_getdims(g, &nx, &ny, &nz);
    enkf_printf("%s  dims = %d x %d x %d\n", offset, nx, ny, nz);
    if (!isnan(g->lonbase))
        enkf_printf("%s  longitude range = [%.3f, %.3f]\n", offset, g->lonbase, g->lonbase + 360.0);
    else
        enkf_printf("%s  longitude range = any\n", offset);
    switch (g->vtype) {
    case GRIDVTYPE_Z:
        enkf_printf("%s  vert type = Z\n", offset);
        break;
    case GRIDVTYPE_SIGMA:
        enkf_printf("%s  vert type = SIGMA\n", offset);
        break;
    default:
        enkf_printf("%s  vert type = NONE\n", offset);
    }
    if (g->sfactor != 1.0)
        enkf_printf("%s  SFACTOR = \"%.f\"\n", offset, g->sfactor);
}
예제 #25
0
파일: ensobs.c 프로젝트: sakov/enkf-c
/** Replaces observation errors in the observation file with the modified
 * values. The original values are stored as "std_orig".
 */
void das_addmodifiederrors(dasystem* das, char fname[])
{
    int ncid;
    int dimid_nobs[1];
    size_t nobs;
    int varid_std;
    double* std;
    int i;
    double da_julday = NaN;

    if (rank != 0)
        return;

    ncw_open(fname, NC_WRITE, &ncid);
    ncw_inq_dimid(ncid, "nobs", dimid_nobs);
    ncw_inq_dimlen(ncid, dimid_nobs[0], &nobs);

    ncw_get_att_double(ncid, NC_GLOBAL, "DA_JULDAY", &da_julday);
    if (!enkf_noobsdatecheck && (isnan(da_julday) || fabs(das->obs->da_date - da_julday) > 1e-6))
        enkf_quit("\"observations.nc\" from a different cycle");

    if (ncw_var_exists(ncid, "std_orig")) {
        enkf_printf("    nothing to do\n");
        ncw_close(ncid);
        return;
    }

    ncw_redef(ncid);
    ncw_rename_var(ncid, "std", "std_orig");
    ncw_def_var(ncid, "std", NC_FLOAT, 1, dimid_nobs, &varid_std);
    ncw_enddef(ncid);

    std = malloc(nobs * sizeof(double));

    for (i = 0; i < (int) nobs; ++i)
        std[i] = das->obs->data[i].std;
    ncw_put_var_double(ncid, varid_std, std);

    free(std);

    ncw_close(ncid);
}
예제 #26
0
파일: grid.c 프로젝트: marshallward/enkf-c
void grid_destroy(grid* g)
{
    free(g->name);
    if (g->htype == GRIDHTYPE_LATLON_REGULAR || g->htype == GRIDHTYPE_LATLON_IRREGULAR)
        gnxy_simple_destroy(g->gridnodes_xy);
#if !defined(NO_GRIDUTILS)
    else if (g->htype == GRIDHTYPE_CURVILINEAR)
        gnxy_curv_destroy(g->gridnodes_xy);
#endif
    else
        enkf_quit("programming_error");
    if (g->gridnodes_z != NULL)
        gnz_destroy(g->gridnodes_z);
    if (g->numlevels != NULL)
        free2d(g->numlevels);
    if (g->depth != NULL)
        free2d(g->depth);

    free(g);
}
예제 #27
0
파일: model.c 프로젝트: TheProjecter/enkf-c
static void model_freemodeldata(model* m)
{
    int i;

    for (i = 0; i < m->ndata; ++i) {
        modeldata* data = &m->data[i];

        if (data->alloctype == ALLOCTYPE_1D)
            free(data->data);
        else if (data->alloctype == ALLOCTYPE_2D)
            free2d(data->data);
        else if (data->alloctype == ALLOCTYPE_3D)
            free3d(data->data);
        else
            enkf_quit("programming error");
        free(data->tag);
    }
    free(m->data);
    m->ndata = 0;
}
예제 #28
0
파일: grid.c 프로젝트: marshallward/enkf-c
void grid_getdims(grid* g, int* ni, int* nj, int* nk)
{
    if (ni != NULL) {
        if (g->htype == GRIDHTYPE_LATLON_REGULAR || g->htype == GRIDHTYPE_LATLON_IRREGULAR) {
            gnxy_simple* nodes = (gnxy_simple*) g->gridnodes_xy;

            *ni = nodes->nx;
            *nj = nodes->ny;
#if !defined(NO_GRIDUTILS)
        } else if (g->htype == GRIDHTYPE_CURVILINEAR) {
            gnxy_curv* nodes = (gnxy_curv*) g->gridnodes_xy;

            *ni = gridnodes_getnx(nodes->gn);
            *nj = gridnodes_getny(nodes->gn);
#endif
        } else
            enkf_quit("programming error");
    }
    if (nk != NULL)
        *nk = g->gridnodes_z->nz;
}
예제 #29
0
파일: calcs.c 프로젝트: sakov/enkf-c
/** Calculates X5 = G * s * 1' + T.
 * X5 = T on input
 */
void calc_X5_etkf(int m, int p, double** G, double* s, int ii, int jj, double** X5)
{
    double* w = calloc(m, sizeof(double));
    int i, j;

    /*
     * w = G * s 
     */
    if (enkf_nomeanupdate == 0) /* "normal" way */
        calc_w(m, p, G, s, w);

    /*
     * X5 = G * s * 1^T + T
     */
    for (i = 0; i < m; ++i) {
        double* X5i = X5[i];

        for (j = 0; j < m; ++j)
            X5i[j] += w[j];
    }

#if defined(CHECK_X5)
    /*
     * check that columns of X5 sum up to 1 
     */
    for (i = 0; i < m; ++i) {
        double* X5i = X5[i];
        double sum = 0.0;

        for (j = 0; j < m; ++j)
            sum += X5i[j];

        if (fabs(sum - 1.0) > EPS)
            enkf_quit("inconsistency in X5: column %d sums up to %.15f for (i, j) = (%d, %d)", i, sum, ii, jj);
    }
#endif

    free(w);
}
예제 #30
0
파일: grid.c 프로젝트: sakov/enkf-c
void grid_fk2z(grid* g, int i, int j, double fk, double* z)
{
    if (g->vtype == GRIDVTYPE_Z || g->vtype == GRIDVTYPE_SIGMA) {
        gnz_simple* nodes = g->gridnodes_z;
        double* zc = nodes->zc;
        int nt = nodes->nz;

        fk += 0.5;

        if (fk <= 0.0)
            *z = zc[0];
        else if (fk >= nt)
            *z = zc[nt];
        else {
            int k = (int) floor(fk);

            *z = zc[k] + (fk - (double) k) * (zc[k + 1] - zc[k]);
        }
        if (g->vtype == GRIDVTYPE_SIGMA)
            *z *= g->depth[j][i];
    } else
        enkf_quit("not implemented");
}