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; }
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; }
//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; }
void simulate(state before, state& next) { vector3 wind_map[2][180][360]; double volume_flux[2][180][360]; double temp_sum[2][180][360]; int i,j,k; for(i=0;i<2;++i) for(j=0;j<180;++j) for(k=0;k<360;++k){ wind_map [i][j][k]=getWind(i,j)*wind_size; volume_flux [i][j][k]=0; temp_sum [i][j][k]=0; } int dir; int next_i, next_j, next_k; double my_out, my_left; int dx,dy,dz; for(i=0;i<2;++i) for(j=0;j<180;++j) for(k=0;k<360;++k){ my_out=0; for(dir=0;dir<26;++dir) { for(dx=-1; dx<=1; ++dx) for(dy=-1; dy<=1; ++dy) for(dz=-1; dz<=1; ++dz){ if(dx==0 && dy==0 && dz==0) continue; next_i = i + dx; next_j = j + dy; next_k = k + dz; if(next_i>=0 && next_j>=0 && next_k>=0 && next_i<2 && next_j<180 && next_k<360){ double cur_volume = dot(wind_map[i][j][k],dr[dir].inv()); if(cur_volume<0) continue; volume_flux[next_i][next_j][next_k]+=cur_volume; temp_sum [next_i][next_j][next_k]+=cur_volume*before.temperature[i][j][k]; my_out+=cur_volume; } } } my_left = total_volume - my_out; volume_flux[i][j][k] += my_left; temp_sum [i][j][k] += my_left*before.temperature[i][j][k]; } for(i=0;i<2;++i) for(j=0;j<180;++j) for(k=0;k<360;++k) next.temperature[i][j][k]=temp_sum[i][j][k]/volume_flux[i][j][k]; next.year = before.year; next.month = before.month; next.day = before.day; next.hour = before.hour + 1; if(next.hour == 24) { ++next.day; next.hour=0; if(next.day > day_in_month(next.year,next.month)){ next.day=1; ++next.month; if(next.month==13){ next.month=1; ++next.year; } } }
QString WeatherPlugin::replace(const QString &text) { QString res = text; QString sun_set, sun_raise, updated; #if COMPAT_QT_VERSION >= 0x030000 QTime tmp_time; QDateTime dt; int h,m; parseTime(getSun_set(),h,m); tmp_time.setHMS(h,m,0,0); sun_set = tmp_time.toString(Qt::LocalDate); sun_set = sun_set.left(sun_set.length() - 3); parseTime(getSun_raise(),h,m); tmp_time.setHMS(h,m,0,0); sun_raise = tmp_time.toString(Qt::LocalDate); sun_raise = sun_raise.left(sun_raise.length() - 3); parseDateTime(getUpdated(),dt); updated = dt.toString(Qt::LocalDate); updated = updated.left(updated.length() - 3); #else sun_set = getSun_set(); sun_raise = getSun_raise(); updated = getUpdated(); #endif /* double Expressions *before* single or better RegExp ! */ res = res.replace(QRegExp("\\%mp"), i18n("moonphase", getMoonPhase())); res = res.replace(QRegExp("\\%mi"), number(getMoonIcon())); res = res.replace(QRegExp("\\%pp"), number(getPrecipitation())); res = res.replace(QRegExp("\\%ut"), i18n("weather", getUV_Description())); res = res.replace(QRegExp("\\%ui"), number(getUV_Intensity())); res = res.replace(QRegExp("\\%t"), QString::number((int)getTemperature()) + QChar((unsigned short)176) + getUT()); res = res.replace(QRegExp("\\%f"), QString::number((int)getFeelsLike()) + QChar((unsigned short)176) + getUT()); res = res.replace(QRegExp("\\%d"), QString::number((int)getDewPoint()) + QChar((unsigned short)176) + getUT()); res = res.replace(QRegExp("\\%h"), number(getHumidity()) + "%"); res = res.replace(QRegExp("\\%w"), number(getWind_speed()) + " " + i18n(getUS())); res = res.replace(QRegExp("\\%x"), QString::number(getWind_speed() * 10 / 36) + " " + i18n("m/s")); res = res.replace(QRegExp("\\%g"), getWindGust() ? QString("(") + i18n("gust ") + number(getWindGust()) + i18n(getUS()) + QString(")") : QString("")); res = res.replace(QRegExp("\\%y"), getWindGust() ? QString("(") + i18n("gust ") + number(getWindGust() * 10 / 36) + QString(" ") + i18n("m/s") + QString(")") : QString("")); res = res.replace(QRegExp("\\%p"), number(getPressure()) + " " + i18n(getUP())); res = res.replace(QRegExp("\\%a"), number(getPressure() * 75 / 100)); res = res.replace(QRegExp("\\%q"), i18n("weather", getPressureD())); res = res.replace(QRegExp("\\%l"), getLocation()); res = res.replace(QRegExp("\\%b"), i18n("weather", getWind())); res = res.replace(QRegExp("\\%u"), updated); res = res.replace(QRegExp("\\%r"), sun_raise); res = res.replace(QRegExp("\\%s"), sun_set); res = res.replace(QRegExp("\\%c"), i18n_conditions(getConditions())); res = res.replace(QRegExp("\\%v"), i18n("weather", getVisibility()) + (atol(getVisibility()) ? QString(" ") + i18n(getUD()) : QString(""))); res = res.replace(QRegExp("\\%i"), number(getIcon())); return res; }
void STKMeshSceneNode::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type) { switch (irr_driver->getPhase()) { case SOLID_NORMAL_AND_DEPTH_PASS: { windDir = getWind(); computeMVP(ModelViewProjectionMatrix); computeTIMV(TransposeInverseModelView); if (type == irr_driver->getShader(ES_NORMAL_MAP)) drawNormalPass(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix); else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir); else drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); break; } case SOLID_LIT_PASS: { if (type == irr_driver->getShader(ES_SPHERE_MAP)) drawSphereMap(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); else if (type == irr_driver->getShader(ES_SPLATTING)) drawSplatting(mesh, ModelViewProjectionMatrix); else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) drawObjectRefPass2(mesh, ModelViewProjectionMatrix, TextureMatrix); else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) drawGrassPass2(mesh, ModelViewProjectionMatrix, windDir); else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT)) drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix); else if (type == irr_driver->getShader(ES_OBJECT_UNLIT)) drawObjectUnlit(mesh, ModelViewProjectionMatrix); else if (mesh.textures[1] && type != irr_driver->getShader(ES_NORMAL_MAP)) drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix); else if (!mesh.textures[0]) drawUntexturedObject(mesh, ModelViewProjectionMatrix); else drawObjectPass2(mesh, ModelViewProjectionMatrix, TextureMatrix); break; } default: { assert(0 && "wrong pass"); } } }
QString WeatherPlugin::replace(const QString &text) { QString res = text; res = res.replace(QRegExp("\\%t"), number(getTemperature()) + QChar((unsigned short)176) + getUT()); res = res.replace(QRegExp("\\%h"), number(getHumidity()) + "%"); res = res.replace(QRegExp("\\%w"), number(getWind_speed()) + " " + getUS()); res = res.replace(QRegExp("\\%i"), number(getPressure()) + " " + getUP()); res = res.replace(QRegExp("\\%l"), getLocation()); res = res.replace(QRegExp("\\%r"), getWind()); res = res.replace(QRegExp("\\%u"), getUpdated()); res = res.replace(QRegExp("\\%p"), getSun_raise()); res = res.replace(QRegExp("\\%q"), getSun_set()); res = res.replace(QRegExp("\\%c"), i18n("weather", getConditions())); return res; }
QString WeatherPlugin::replace(const QString &text) { QString res = text; res = res.replace(QRegExp("\\%f"), number(getTemperature_f())); res = res.replace(QRegExp("\\%s"), number(getTemperature_c())); res = res.replace(QRegExp("\\%h"), number(getHumidity())); res = res.replace(QRegExp("\\%w"), number(getWind_speed_mph())); res = res.replace(QRegExp("\\%x"), number(getWind_speed_km())); res = res.replace(QRegExp("\\%i"), number(getPressure_in())); res = res.replace(QRegExp("\\%a"), number(getPressure_hpa())); res = res.replace(QRegExp("\\%l"), getLocation()); res = res.replace(QRegExp("\\%r"), getWind()); res = res.replace(QRegExp("\\%u"), getUpdated()); res = res.replace(QRegExp("\\%p"), getSun_raise()); res = res.replace(QRegExp("\\%q"), getSun_set()); res = res.replace(QRegExp("\\%c"), i18n("weather", getConditions())); return res; }
QString WeatherPlugin::replace(const QString &text) { QString res = text; res = res.replace(QRegExp("\\%t"), number(getTemperature()) + QChar((unsigned short)176) + getUT()); res = res.replace(QRegExp("\\%f"), number(getFeelsLike()) + QChar((unsigned short)176) + getUT()); res = res.replace(QRegExp("\\%d"), number(getDewPoint()) + QChar((unsigned short)176) + getUT()); res = res.replace(QRegExp("\\%h"), number(getHumidity()) + "%"); res = res.replace(QRegExp("\\%w"), number(getWind_speed()) + " " + getUS()); res = res.replace(QRegExp("\\%g"), getWindGust() ? QString("<") + i18n("gust ") + number(getWindGust()) + ")" : ""); res = res.replace(QRegExp("\\%p"), number(getPressure()) + " " + getUP() + " (" + i18n("weather", getPressureD()) + ")"); res = res.replace(QRegExp("\\%a"), number(getPressure() * 75 / 100)); res = res.replace(QRegExp("\\%l"), getLocation()); res = res.replace(QRegExp("\\%b"), getWind()); res = res.replace(QRegExp("\\%u"), getUpdated()); res = res.replace(QRegExp("\\%r"), getSun_raise()); res = res.replace(QRegExp("\\%s"), getSun_set()); res = res.replace(QRegExp("\\%c"), i18n_conditions(getConditions())); res = res.replace(QRegExp("\\%v"), i18n("weather", getVisibility())); return res; }
void STKMeshSceneNode::drawSolidPass1(const GLMesh &mesh, GeometricMaterial type) { irr_driver->IncreaseObjectCount(); windDir = getWind(); switch (type) { case FPSM_NORMAL_MAP: drawNormalPass(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); break; case FPSM_ALPHA_REF_TEXTURE: drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, mesh.TextureMatrix); break; case FPSM_GRASS: drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir); break; case FPSM_DEFAULT: drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); break; default: assert(0 && "wrong geometric material"); } }
int main (int argc, char ** argv) { int winner ; int windOfRound ; int wind, thewind ; int num ; int number, i, j ; int numSeasonFlowers ; char **fields ; FILE *fp ; char buffer[200] ; windOfRound = getWind (argv[1]) ; fp = fopen (argv[2], "r") ; while (fgets (buffer, 200, fp)) { fields = getFields (buffer, ':') ; if (!fields) continue ; wind = getWind(fields[0]) ; if (!strcasecmp (fields[1], "exposed")) { suits[wind] |= getType (fields[3]) ; if (!strcasecmp (fields[2], "pung")) { if (!strcasecmp (fields[3], "dragon")) { score[wind]+=4 ; doubles[wind]*=2 ; } else if (!strcasecmp (fields[3], "wind")) { score[wind]+=4 ; thewind = getWind (fields[3]) ; if ((thewind == wind) || (thewind == windOfRound)) doubles[wind] *=2 ; } else { num=atoi(fields[4]) ; if ((num == 1) || (num == 9)) { score[wind]+=4 ; numOneNine[wind]++ ; } else { score[wind]+=2 ; numTwoEight[wind]++ ; } } } else if (!strcasecmp (fields[2], "kong")) { if (!strcasecmp (fields[3], "dragon")) { score[wind]+=16 ; doubles[wind]*=2 ; } else if (!strcasecmp (fields[3], "wind")) { score[wind]+=16 ; thewind = getWind (fields[3]) ; if ((thewind == wind) || (thewind == windOfRound)) doubles[wind] *=2 ; } else { num=atoi(fields[4]) ; if ((num == 1) || (num == 9)) { score[wind]+=16 ; numOneNine[wind]++ ; } else { score[wind]+=8 ; numTwoEight[wind]++ ; } } } } else if (!strcasecmp (fields[1], "concealed")) { suits[wind] |= getType (fields[3]) ; if (!strcasecmp (fields[2], "pung")) { if (!strcasecmp (fields[3], "dragon")) { score[wind]+=8 ; doubles[wind]*=2 ; } else if (!strcasecmp (fields[3], "wind")) { score[wind]+=8 ; thewind = getWind (fields[3]) ; if ((thewind == wind) || (thewind == windOfRound)) doubles[wind] *=2 ; } else { num=atoi(fields[4]) ; if ((num == 1) || (num == 9)) { score[wind]+=8 ; numOneNine[wind]++ ; } else { score[wind]+=4 ; numTwoEight[wind]++ ; } } } else if (!strcasecmp (fields[2], "kong")) { if (!strcasecmp (fields[3], "dragon")) { score[wind]+=32 ; doubles[wind]*=2 ; } else if (!strcasecmp (fields[3], "wind")) { score[wind]+=32 ; thewind = getWind (fields[3]) ; if ((thewind == wind) || (thewind == windOfRound)) doubles[wind] *=2 ; } else { num=atoi(fields[4]) ; if ((num == 1) || (num == 9)) { score[wind]+=32 ; numOneNine[wind]++ ; } else { score[wind]+=16 ; numTwoEight[wind]++ ; } } } } else if (!strcasecmp (fields[1], "pair")) { suits[wind] |= getType (fields[2]) ; if (!strcasecmp (fields[2], "dragon")) score[wind]+=2 ; if (!strcasecmp (fields[2], "wind")) { thewind = getWind (fields[3]) ; if ((thewind == wind) || (thewind == windOfRound)) score[wind]+=2 ; } } else if (!strcasecmp (fields[1], "chow")) { chows[wind]++ ; suits[wind] |= getType (fields[2]) ; for (i=3;fields[i];i++) { num=atoi(fields[i]) ; if ((num == 1) || (num == 9)) numOneNine[wind]++ ; else numTwoEight[wind]++ ; } } else if (!strcasecmp (fields[1], "other")) { suits[wind] |= getType (fields[2]) ; for (i=3;fields[i];i++) { num=atoi(fields[i]) ; if ((num == 1) || (num == 9)) numOneNine[wind]++ ; else numTwoEight[wind]++ ; } } else if (!strncasecmp (fields[1], "season", 6)) { for (i=2;i<6 && fields[i];i++) { score[wind]+=4; num=atoi(fields[i]) ; if ((num-1) == wind) doubles[wind]*=2; } if (i == 6) doubles[wind]*=8; } else if (!strncasecmp (fields[1], "flower", 6)) { for (i=2;i<6 && fields[i];i++) { score[wind]+=4; num=atoi(fields[i]) ; if ((num-1) == wind) doubles[wind]*=2; } if (i == 6) doubles[wind]*=8; } else if (!strncasecmp (fields[1], "mahjong", 7)) { winner = wind ; if (!score[wind]) score[wind] += 10 ; /* ten points for no scoring value in hand */ score[wind] += 20 ; /* for mahjong */ if (suits[wind]&DRAGONS || suits[wind]&WINDS) { if ((!(suits[wind]&CHARACTERS)) && (!(suits[wind]&BAMBOO)) && (!(suits[wind]&CIRCLES))) { doubles[wind] *= 8; /* just winds and dragons */ } else if ((!(suits[wind]&CHARACTERS)) && (!(suits[wind]&BAMBOO))) doubles[wind] *= 2; else if ((!(suits[wind]&CHARACTERS)) && (!(suits[wind]&CIRCLES))) doubles[wind] *= 2; else if ((!(suits[wind]&BAMBOO)) && (!(suits[wind]&CIRCLES))) doubles[wind] *= 2; } else if ((suits[wind] == CHARACTERS) || (suits[wind] == BAMBOO) || (suits[wind] == CIRCLES)) { doubles[wind] *= 8 ; /* just one type */ } if (!numTwoEight[wind]) doubles[wind] *= 2 ; if (!chows[wind]) score[wind] += 10 ; for (i=2;fields[i];i++) { if (!strncasecmp (fields[i], "snatch", 6)) doubles[wind] *=2 ; if (!strncasecmp (fields[i], "origin", 6)) doubles[wind] *=8 ; if (!strncasecmp (fields[i], "winwall", 7)) score[wind] += 2 ; if (!strncasecmp (fields[i], "winposs", 7)) score[wind] += 2 ; if (!strncasecmp (fields[i], "winlast", 7)) score[wind] += 10 ; if (!strncasecmp (fields[i], "winloose", 8)) score[wind] += 10 ; if (!strncasecmp (fields[i], "standing", 8)) score[wind] += 100 ; } } } fclose (fp) ; for (i=0;i<4;i++) { score[i] *= doubles[i] ; } printf ("Raw scores are as follows - North %d, South %d, East %d, West %d\n", score[NORTH], score[SOUTH], score[EAST], score [WEST]) ; /* now work out this complicated score settlement business */ for (i=0;i<4;i++) { if (i == winner) { adjScore[i] = 3 * score[i] ; if (i == EAST) adjScore[i] *= 2 ; } else { adjScore[i] = score[i] ; for (j=0;j<4;j++) { if (j == i) continue ; if (j == winner) continue ; if (score[i] > score[j]) adjScore[i] += (score[i] - score[j]) ; } } } printf ("Settled scores are as follows - North %d, South %d, East %d, West %d\n", adjScore[NORTH], adjScore[SOUTH], adjScore[EAST], adjScore [WEST]) ; }
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; }