コード例 #1
0
PetscErrorCode FormFunctionLocal(DMDALocalInfo *info, PetscReal **u,
                                 PetscReal **F, Ctx *usr) {
    PetscInt        i, j;
    const PetscReal e = usr->eps;
    PetscReal       x, y, uu, uxx, uyy, Wux, Wuy;
    Wind            W;
    Spacings        s;

    getSpacings(info,&s);
    for (j=info->ys; j<info->ys+info->ym; j++) {
        y = -1.0 + j * s.hy;
        for (i=info->xs; i<info->xs+info->xm; i++) {
            x = -1.0 + i * s.hx;
            if (i == info->mx-1) {
                F[j][i] = u[j][i] - 1.0;
            } else if (i == 0 || j == 0 || j == info->my-1) {
                F[j][i] = u[j][i];
            } else {
                uu = u[j][i];
                uxx = (u[j][i-1] - 2.0 * uu + u[j][i+1]) / s.hx2;
                uyy = (u[j-1][i] - 2.0 * uu + u[j+1][i]) / s.hy2;
                W = getWind(x,y);
                Wux = W.x * (u[j][i+1] - u[j][i-1]) / (2.0 * s.hx);
                Wuy = W.y * (u[j+1][i] - u[j-1][i]) / (2.0 * s.hy);
                F[j][i] = - e * (uxx + uyy) + Wux + Wuy;
            }
        }
    }
    return 0;
}
コード例 #2
0
PetscErrorCode FormJacobianLocal(DMDALocalInfo *info, PetscScalar ***u,
                                 Mat J, Mat Jpre, Ctx *usr) {
    PetscErrorCode  ierr;
    PetscInt        i,j,q;
    PetscReal       v[5],diag,x,y;
    const PetscReal e = usr->eps;
    MatStencil      col[5],row;
    Spacings        s;
    Wind            W;

    getSpacings(info,&s);
    diag = e * 2.0 * (1.0/s.hx2 + 1.0/s.hy2);
    for (j=info->ys; j<info->ys+info->ym; j++) {
        y = -1.0 + j * s.hy;
        row.j = j;
        col[0].j = j;
        for (i=info->xs; i<info->xs+info->xm; i++) {
            x = -1.0 + i * s.hx;
            row.i = i;
            col[0].i = i;
            q = 1;
            if (i == 0 || j == 0 || i == info->mx-1 || j == info->my-1) {
                v[0] = 1.0;
            } else {
                W = getWind(x,y);
                v[0] = diag;
                if (i-1 != 0) {
                    v[q] = - e / s.hx2 - W.x / (2.0 * s.hx);
                    col[q].j = j;  col[q].i = i-1;
                    q++;
                }
                if (i+1 != info->mx-1) {
                    v[q] = - e / s.hx2 + W.x / (2.0 * s.hx);
                    col[q].j = j;  col[q].i = i+1;
                    q++;
                }
                if (j-1 != 0) {
                    v[q] = - e / s.hy2 - W.y / (2.0 * s.hy);
                    col[q].j = j-1;  col[q].i = i;
                    q++;
                }
                if (j+1 != info->my-1) {
                    v[q] = - e / s.hy2 + W.y / (2.0 * s.hy);
                    col[q].j = j+1;  col[q].i = i;
                    q++;
                }
            }
            ierr = MatSetValuesStencil(Jpre,1,&row,q,col,v,INSERT_VALUES); CHKERRQ(ierr);
        }
    }
    ierr = MatAssemblyBegin(Jpre,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
    ierr = MatAssemblyEnd(Jpre,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
    if (J != Jpre) {
        ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
        ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
    }
    return 0;
}
コード例 #3
0
//STARTFUNCTION
PetscErrorCode FormFunctionLocal(DMDALocalInfo *info, double ***u,
                                 double ***F, Ctx *usr) {
    PetscErrorCode ierr;
    int          i, j, k;
    const double e = usr->eps;
    double       x, y, z, uu, uxx, uyy, uzz, Wux, Wuy, Wuz, ***af, ***ag;
    Wind         W;
    Spacings     s;

    getSpacings(info,&s);
    ierr = DMDAVecGetArray(usr->da, usr->f, &af);
    CHKERRQ(ierr);
    ierr = DMDAVecGetArray(usr->da, usr->g, &ag);
    CHKERRQ(ierr);
    for (k=info->zs; k<info->zs+info->zm; k++) {
        z = -1.0 + k * s.hz;
        for (j=info->ys; j<info->ys+info->ym; j++) {
            y = -1.0 + j * s.hy;
            for (i=info->xs; i<info->xs+info->xm; i++) {
                x = -1.0 + i * s.hx;
                if (i == info->mx-1) {
                    F[k][j][i] = u[k][j][i] - ag[k][j][i];
                } else if (i == 0 || j == 0 || j == info->my-1) {
                    F[k][j][i] = u[k][j][i];
                } else {
                    uu = u[k][j][i];
                    uxx = (u[k][j][i-1] - 2.0 * uu + u[k][j][i+1]) / s.hx2;
                    uyy = (u[k][j-1][i] - 2.0 * uu + u[k][j+1][i]) / s.hy2;
                    uzz = (u[k-1][j][i] - 2.0 * uu + u[k+1][j][i]) / s.hz2;
                    W = getWind(x,y,z);
                    if (usr->upwind) {
                        Wux = (W.x > 0) ? uu - u[k][j][i-1]
                              : u[k][j][i+1] - uu;
                        Wux *= W.x / s.hx;
                        Wuy = (W.y > 0) ? uu - u[k][j-1][i]
                              : u[k][j+1][i] - uu;
                        Wuy *= W.y / s.hy;
                        Wuz = (W.z > 0) ? uu - u[k-1][j][i]
                              : u[k+1][j][i] - uu;
                        Wuz *= W.z / s.hz;
                    } else {
                        Wux = W.x * (u[k][j][i+1] - u[k][j][i-1]) / (2.0*s.hx);
                        Wuy = W.y * (u[k][j+1][i] - u[k][j-1][i]) / (2.0*s.hy);
                        Wuz = W.z * (u[k+1][j][i] - u[k-1][j][i]) / (2.0*s.hz);
                    }
                    F[k][j][i] = - e * (uxx + uyy + uzz) + Wux + Wuy + Wuz
                                 - af[k][j][i];
                }
            }
        }
    }
    ierr = DMDAVecRestoreArray(usr->da, usr->f, &af);
    CHKERRQ(ierr);
    ierr = DMDAVecRestoreArray(usr->da, usr->g, &ag);
    CHKERRQ(ierr);
    return 0;
}
コード例 #4
0
PetscErrorCode formUexFG(DMDALocalInfo *info, Ctx *usr, Vec uex) {
    PetscErrorCode  ierr;
    int          i, j, k;
    Spacings     s;
    const double E = PETSC_PI / 2.0,  F = 2.0 * PETSC_PI,
                 lam2 = E*E + F*F; // lambda = sqrt(17.0) * PETSC_PI / 2.0
    double       x, y, z, QQ, UU, ***auex, ***af, ***ag;

    getSpacings(info,&s);
    ierr = DMDAVecGetArray(usr->da, uex, &auex);
    CHKERRQ(ierr);
    ierr = DMDAVecGetArray(usr->da, usr->f, &af);
    CHKERRQ(ierr);
    ierr = DMDAVecGetArray(usr->da, usr->g, &ag);
    CHKERRQ(ierr);
    for (k=info->zs; k<info->zs+info->zm; k++) {
        z = -1.0 + k * s.hz;
        for (j=info->ys; j<info->ys+info->ym; j++) {
            y = -1.0 + j * s.hy;
            QQ = sin(E*(y+1.0)) * sin(F*(z+1.0));
            for (i=info->xs; i<info->xs+info->xm; i++) {
                x = -1.0 + i * s.hx;
                UU = exp((x+1)/usr->eps) - 1.0;
                UU /= exp(2.0/usr->eps) - 1.0;
                auex[k][j][i] = UU * QQ;
                af[k][j][i] = usr->eps * lam2 * auex[k][j][i];
                if (i == info->mx-1)
                    ag[k][j][i] = QQ;
                else
                    ag[k][j][i] = 0.0;
            }
        }
    }
    ierr = DMDAVecRestoreArray(usr->da, uex, &auex);
    CHKERRQ(ierr);
    ierr = DMDAVecRestoreArray(usr->da, usr->f, &af);
    CHKERRQ(ierr);
    ierr = DMDAVecRestoreArray(usr->da, usr->g, &ag);
    CHKERRQ(ierr);
    return 0;
}
コード例 #5
0
PetscErrorCode FormJacobianLocal(DMDALocalInfo *info, PetscScalar ***u,
                                 Mat J, Mat Jpre, Ctx *usr) {
    PetscErrorCode  ierr;
    int          i,j,k,q;
    double       v[7],diag,x,y,z;
    const double e = usr->eps;
    MatStencil   col[7],row;
    Spacings     s;
    Wind         W;

    getSpacings(info,&s);
    diag = e * 2.0 * (1.0/s.hx2 + 1.0/s.hy2 + 1.0/s.hz2);
    for (k=info->zs; k<info->zs+info->zm; k++) {
        z = -1.0 + k * s.hz;
        row.k = k;
        col[0].k = k;
        for (j=info->ys; j<info->ys+info->ym; j++) {
            y = -1.0 + j * s.hy;
            row.j = j;
            col[0].j = j;
            for (i=info->xs; i<info->xs+info->xm; i++) {
                x = -1.0 + i * s.hx;
                row.i = i;
                col[0].i = i;
                if (i == 0 || j == 0 || i == info->mx-1 || j == info->my-1) {
                    v[0] = 1.0;
                    q = 1;
                } else {
                    W = getWind(x,y,z);
                    v[0] = diag;
                    if (usr->upwind) {
                        v[0] += (W.x / s.hx) * ((W.x > 0.0) ? 1.0 : -1.0);
                        v[0] += (W.y / s.hy) * ((W.y > 0.0) ? 1.0 : -1.0);
                        v[0] += (W.z / s.hz) * ((W.z > 0.0) ? 1.0 : -1.0);
                    }
                    v[1] = - e / s.hz2;
                    if (usr->upwind) {
                        if (W.z > 0.0)
                            v[q] -= W.z / s.hz;
                    } else
                        v[q] -= W.z / (2.0 * s.hz);
                    col[1].k = k-1;
                    col[1].j = j;
                    col[1].i = i;
                    v[2] = - e / s.hz2;
                    if (usr->upwind) {
                        if (W.z <= 0.0)
                            v[q] += W.z / s.hz;
                    } else
                        v[q] += W.z / (2.0 * s.hz);
                    col[2].k = k+1;
                    col[2].j = j;
                    col[2].i = i;
                    q = 3;
                    if (i-1 != 0) {
                        v[q] = - e / s.hx2;
                        if (usr->upwind) {
                            if (W.x > 0.0)
                                v[q] -= W.x / s.hx;
                        } else
                            v[q] -= W.x / (2.0 * s.hx);
                        col[q].k = k;
                        col[q].j = j;
                        col[q].i = i-1;
                        q++;
                    }
                    if (i+1 != info->mx-1) {
                        v[q] = - e / s.hx2;
                        if (usr->upwind) {
                            if (W.x <= 0.0)
                                v[q] += W.x / s.hx;
                        } else
                            v[q] += W.x / (2.0 * s.hx);
                        col[q].k = k;
                        col[q].j = j;
                        col[q].i = i+1;
                        q++;
                    }
                    if (j-1 != 0) {
                        v[q] = - e / s.hy2;
                        if (usr->upwind) {
                            if (W.y > 0.0)
                                v[q] -= W.y / s.hy;
                        } else
                            v[q] -= W.y / (2.0 * s.hy);
                        col[q].k = k;
                        col[q].j = j-1;
                        col[q].i = i;
                        q++;
                    }
                    if (j+1 != info->my-1) {
                        v[q] = - e / s.hy2;
                        if (usr->upwind) {
                            if (W.y <= 0.0)
                                v[q] += W.y / s.hy;
                        } else
                            v[q] += W.y / (2.0 * s.hy);
                        col[q].k = k;
                        col[q].j = j+1;
                        col[q].i = i;
                        q++;
                    }
                }
                ierr = MatSetValuesStencil(Jpre,1,&row,q,col,v,INSERT_VALUES);
                CHKERRQ(ierr);
            }
        }
    }
    ierr = MatAssemblyBegin(Jpre,MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    ierr = MatAssemblyEnd(Jpre,MAT_FINAL_ASSEMBLY);
    CHKERRQ(ierr);
    if (J != Jpre) {
        ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);
        CHKERRQ(ierr);
        ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);
        CHKERRQ(ierr);
    }
    return 0;
}