FiniteVolumeEquation<Vector2D> laplacian(Scalar gamma, VectorFiniteVolumeField &phi, Scalar theta) { FiniteVolumeEquation<Vector2D> eqn(phi); const VectorFiniteVolumeField &phi0 = phi.oldField(0); for (const Cell &cell: phi.cells()) { for (const InteriorLink &nb: cell.neighbours()) { Scalar coeff = gamma * dot(nb.rCellVec(), nb.outwardNorm()) / nb.rCellVec().magSqr(); eqn.add(cell, nb.cell(), theta * coeff); eqn.add(cell, cell, theta * -coeff); eqn.addSource(cell, (1. - theta) * coeff * (phi0(nb.cell()) - phi0(cell))); } for (const BoundaryLink &bd: cell.boundaries()) { Scalar coeff = gamma * dot(bd.rFaceVec(), bd.outwardNorm()) / bd.rFaceVec().magSqr(); switch (phi.boundaryType(bd.face())) { case VectorFiniteVolumeField::FIXED: eqn.add(cell, cell, theta * -coeff); eqn.addSource(cell, theta * coeff * phi(bd.face())); eqn.addSource(cell, (1. - theta) * coeff * (phi0(bd.face()) - phi0(cell))); break; case VectorFiniteVolumeField::NORMAL_GRADIENT: break; case VectorFiniteVolumeField::SYMMETRY: { Vector2D tw = bd.outwardNorm().tangentVec().unitVec(); eqn.add(cell, cell, theta * -coeff); eqn.add(cell, cell, theta * coeff * outer(tw, tw)); eqn.addSource(cell, (1. - theta) * coeff * (dot(phi0(cell), tw) * tw - phi0(cell))); } break; case VectorFiniteVolumeField::PARTIAL_SLIP: { Vector2D tw = bd.outwardNorm().tangentVec().unitVec(); Scalar lambda = phi.boundaryRefValue(bd.face()).x; Scalar a = lambda != 0. ? lambda * coeff / (lambda * coeff - 1.) : 0.; eqn.add(cell, cell, theta * -coeff); eqn.add(cell, cell, theta * a * coeff * outer(tw, tw)); eqn.addSource(cell, (1. - theta) * coeff * (a * dot(phi0(cell), tw) * tw - phi0(cell))); } default: throw Exception("fv", "laplacian<Vector2D>", "unrecognized or unspecified boundary type."); } } } return eqn; }
int main(int argc,char **argv) { progname = basename(argv[0]); eqnexit(eqn(argc, argv)); /*NOTREACHED*/ return 0; }
int main(int argc, char** argv) { // Initialize Tempest TempestInitialize(&argc, &argv); try { // Model cap. double dZtop; // Earth radius scaling parameter. double dEarthScaling; // Deactivate physics bool fNoPhysics; // Bryan Boundary Layer bool fBryanPBL; // Reed-Jablonowksi precipitation bool fReedJablonowskiPrecip; // Parse the command line BeginTempestCommandLine("TropicalCycloneTest"); SetDefaultResolution(20); SetDefaultLevels(30); SetDefaultOutputDeltaT("1h"); SetDefaultDeltaT("200s"); SetDefaultEndTime("10d"); SetDefaultHorizontalOrder(4); SetDefaultVerticalOrder(1); CommandLineDouble(dZtop, "ztop", 30000.0); CommandLineDouble(dEarthScaling, "X", 1.0); CommandLineBool(fNoPhysics, "nophys"); CommandLineBool(fBryanPBL, "bryanpbl"); CommandLineBool(fReedJablonowskiPrecip, "rjprecip"); ParseCommandLine(argc, argv); EndTempestCommandLine(argv) // Setup the Model AnnounceBanner("MODEL SETUP"); EquationSet eqn(EquationSet::PrimitiveNonhydrostaticEquations); eqn.InsertTracer("RhoQv", "RhoQv"); eqn.InsertTracer("RhoQc", "RhoQc"); eqn.InsertTracer("RhoQr", "RhoQr"); UserDataMeta metaUserData; metaUserData.InsertDataItem2D("PRECT"); Model model(eqn, metaUserData); TempestSetupCubedSphereModel(model); // Set the test case for the model AnnounceStartBlock("Initializing test case"); model.SetTestCase( new TropicalCycloneTest( dZtop, dEarthScaling)); AnnounceEndBlock("Done"); // Add DCMIP physics if (!fNoPhysics) { model.AttachWorkflowProcess( new DCMIPPhysics( model, model.GetDeltaT(), 2, (fBryanPBL)?(1):(0), (fReedJablonowskiPrecip)?(1):(0))); } // Begin execution AnnounceBanner("SIMULATION"); model.Go(); // Compute error norms AnnounceBanner("RESULTS"); model.ComputeErrorNorms(); AnnounceBanner(); } catch(Exception & e) { std::cout << e.ToString() << std::endl; } // Deinitialize Tempest TempestDeinitialize(); }
void sdis(char a1, char a2) { int c1, c2; int eqnf; int lct; if(a1 == 'P'){ while(C1 == ' ') ; if(c == '<') { SKIP1; return; } } lct = 0; eqnf = 1; if(c != '\n') SKIP1; for(;;) { while(C1 != '.') if(c == '\n') continue; else SKIP1; if((c1=C1) == '\n') continue; if((c2=C1) == '\n') { if(a1 == 'f' && (c1 == 'P' || c1 == 'H')) return; continue; } if(c1==a1 && c2 == a2) { SKIP1; if(lct != 0){ lct--; continue; } if(eqnf) Bprint(&(bout.Biobufhdr), " ."); Bputc(&(bout.Biobufhdr), '\n'); return; } else if(a1 == 'L' && c2 == 'L') { lct++; SKIP1; } else if(a1 == 'D' && c1 == 'E' && c2 == 'Q') { eqn(); eqnf = 0; } else if(a1 == 'f') { if((mac == MS && c2 == 'P') || (mac == MM && c1 == 'H' && c2 == 'U')){ SKIP1; return; } SKIP1; } else SKIP1; } }
void comline(void) { long c1, c2; while(C==' ' || c=='\t') ; comx: if((c1=c) == '\n') return; c2 = C; if(c1=='.' && c2!='.') inmacro = NO; if(msflag && c1 == '['){ refer(c2); return; } if(c2 == '\n') return; if(c1 == '\\' && c2 == '\"') SKIP; else if (filesp==files && c1=='E' && c2=='Q') eqn(); else if(filesp==files && c1=='T' && (c2=='S' || c2=='C' || c2=='&')) { if(msflag) stbl(); else tbl(); } else if(c1=='T' && c2=='E') intable = NO; else if (!inmacro && ((c1 == 'd' && c2 == 'e') || (c1 == 'i' && c2 == 'g') || (c1 == 'a' && c2 == 'm'))) macro(); else if(c1=='s' && c2=='o') { if(iflag) SKIP; else { getfname(); if(fname[0]) { if(infile = opn(fname)) *++filesp = infile; else infile = *filesp; } } } else if(c1=='n' && c2=='x') if(iflag) SKIP; else { getfname(); if(fname[0] == '\0') exits(0); if(Bfildes(&(infile->Biobufhdr)) != 0) Bterm(&(infile->Biobufhdr)); infile = *filesp = opn(fname); } else if(c1 == 't' && c2 == 'm') SKIP; else if(c1=='h' && c2=='w') SKIP; else if(msflag && c1 == 'T' && c2 == 'L') { SKIP_TO_COM; goto comx; } else if(msflag && c1=='N' && c2 == 'R') SKIP; else if(msflag && c1 == 'A' && (c2 == 'U' || c2 == 'I')){ if(mac==MM)SKIP; else { SKIP_TO_COM; goto comx; } } else if(msflag && c1=='F' && c2=='S') { SKIP_TO_COM; goto comx; } else if(msflag && (c1=='S' || c1=='N') && c2=='H') { SKIP_TO_COM; goto comx; } else if(c1 == 'U' && c2 == 'X') { if(wordflag) Bprint(&(bout.Biobufhdr), "UNIX\n"); else Bprint(&(bout.Biobufhdr), "UNIX "); } else if(msflag && c1=='O' && c2=='K') { SKIP_TO_COM; goto comx; } else if(msflag && c1=='N' && c2=='D') SKIP; else if(msflag && mac==MM && c1=='H' && (c2==' '||c2=='U')) SKIP; else if(msflag && mac==MM && c2=='L') { if(disp || c1=='R') sdis('L', 'E'); else { SKIP; Bprint(&(bout.Biobufhdr), " ."); } } else if(!msflag && c1=='P' && c2=='S') { inpic(); } else if(msflag && (c1=='D' || c1=='N' || c1=='K'|| c1=='P') && c2=='S') { sdis(c1, 'E'); } else if(msflag && (c1 == 'K' && c2 == 'F')) { sdis(c1,'E'); } else if(msflag && c1=='n' && c2=='f') sdis('f','i'); else if(msflag && c1=='c' && c2=='e') sce(); else { if(c1=='.' && c2=='.') { if(msflag) { SKIP; return; } while(C == '.') ; } inmacro++; if(c1 <= 'Z' && msflag) regline(YES,ONE); else { if(wordflag) C; regline(YES,TWO); } inmacro--; } }
bool BlockStochPoissonTest1D() { /* We will do our linear algebra using Epetra */ VectorType<double> vecType = new EpetraVectorType(); /* Read a mesh */ MeshType meshType = new BasicSimplicialMeshType(); int nx = 32; MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, nx, meshType); Mesh mesh = mesher.getMesh(); /* Create a cell filter that will identify the maximal cells * in the interior of the domain */ CellFilter interior = new MaximalCellFilter(); CellFilter pts = new DimensionalCellFilter(0); CellFilter left = pts.subset(new CoordinateValueCellPredicate(0,0.0)); CellFilter right = pts.subset(new CoordinateValueCellPredicate(0,1.0)); Expr x = new CoordExpr(0); /* Create the stochastic coefficients */ int nDim = 1; int order = 6; #ifdef HAVE_SUNDANCE_STOKHOS Out::root() << "using Stokhos hermite basis" << std::endl; SpectralBasis pcBasis = new Stokhos::HermiteBasis<int,double>(order); #else Out::root() << "using George's hermite basis" << std::endl; SpectralBasis pcBasis = new HermiteSpectralBasis(nDim, order); #endif Array<Expr> q(pcBasis.nterms()); Array<Expr> kappa(pcBasis.nterms()); Array<Expr> uEx(pcBasis.nterms()); double a = 0.1; q[0] = -2 + pow(a,2)*(4 - 9*x)*x - 2*pow(a,3)*(-1 + x)*(1 + 3*x*(-3 + 4*x)); q[1] = -(a*(-3 + 10*x + 2*a*(-1 + x*(8 - 9*x + a*(-4 + 3*(5 - 4*x)*x + 12*a*(-1 + x)*(1 + 5*(-1 + x)*x)))))); q[2] = a*(-4 + 6*x + a*(1 - x*(2 + 3*x) + a*(4 - 28*x + 30*pow(x,2)))); q[3] = -(pow(a,2)*(-3 + x*(20 - 21*x + a*(-4 + 3*(5 - 4*x)*x + 24*a*(-1 + x)*(1 + 5*(-1 + x)*x))))); q[4] = pow(a,3)*(1 + x*(-6 + x*(3 + 4*x))); q[5] = -4*pow(a,4)*(-1 + x)*x*(1 + 5*(-1 + x)*x); q[6] = 0.0; uEx[0] = -((-1 + x)*x); uEx[1] = -(a*(-1 + x)*pow(x,2)); uEx[2] = a*pow(-1 + x,2)*x; uEx[3] = pow(a,2)*pow(-1 + x,2)*pow(x,2); uEx[4] = 0.0; uEx[5] = 0.0; uEx[6] = 0.0; kappa[0] = 1.0; kappa[1] = a*x; kappa[2] = -(pow(a,2)*(-1 + x)*x); kappa[3] = 1.0; // unused kappa[4] = 1.0; // unused kappa[5] = 1.0; // unused kappa[6] = 1.0; // unused Array<Expr> uBC(pcBasis.nterms()); for (int i=0; i<pcBasis.nterms(); i++) uBC[i] = 0.0; int L = nDim+2; int P = pcBasis.nterms(); Out::os() << "L = " << L << std::endl; Out::os() << "P = " << P << std::endl; /* Create the unknown and test functions. Do NOT use the spectral * basis here */ Expr u = new UnknownFunction(new Lagrange(4), "u"); Expr v = new TestFunction(new Lagrange(4), "v"); /* Create differential operator and coordinate function */ Expr dx = new Derivative(0); Expr grad = dx; /* We need a quadrature rule for doing the integrations */ QuadratureFamily quad = new GaussianQuadrature(12); /* Now we create problem objects to build each $K_j$ and $f_j$. * There will be L matrix-vector pairs */ Array<Expr> eqn(P); Array<Expr> bc(P); Array<LinearProblem> prob(P); Array<LinearOperator<double> > KBlock(L); Array<Vector<double> > fBlock(P); Array<Vector<double> > solnBlock; for (int j=0; j<P; j++) { eqn[j] = Integral(interior, kappa[j]*(grad*v)*(grad*u) + v*q[j], quad); bc[j] = EssentialBC(left+right, v*(u-uBC[j]), quad); prob[j] = LinearProblem(mesh, eqn[j], bc[j], v, u, vecType); if (j<L) KBlock[j] = prob[j].getOperator(); fBlock[j] = -1.0*prob[j].getSingleRHS(); } /* Read the solver to be used on the diagonal blocks */ LinearSolver<double> diagSolver = LinearSolverBuilder::createSolver("amesos.xml"); double convTol = 1.0e-12; int maxIters = 30; int verb = 1; StochBlockJacobiSolver solver(diagSolver, pcBasis, convTol, maxIters, verb); solver.solve(KBlock, fBlock, solnBlock); /* write the solution */ FieldWriter w = new MatlabWriter("Stoch1D"); w.addMesh(mesh); DiscreteSpace discSpace(mesh, new Lagrange(4), vecType); for (int i=0; i<P; i++) { L2Projector proj(discSpace, uEx[i]); Expr ue_i = proj.project(); Expr df = new DiscreteFunction(discSpace, solnBlock[i]); w.addField("u["+ Teuchos::toString(i)+"]", new ExprFieldWrapper(df)); w.addField("uEx["+ Teuchos::toString(i)+"]", new ExprFieldWrapper(ue_i)); } w.write(); double totalErr2 = 0.0; DiscreteSpace discSpace4(mesh, new Lagrange(4), vecType); for (int i=0; i<P; i++) { Expr df = new DiscreteFunction(discSpace4, solnBlock[i]); Expr errExpr = Integral(interior, pow(uEx[i]-df, 2.0), quad); Expr scaleExpr = Integral(interior, pow(uEx[i], 2.0), quad); double errSq = evaluateIntegral(mesh, errExpr); double scale = evaluateIntegral(mesh, scaleExpr); if (scale > 0.0) Out::os() << "mode i=" << i << " error=" << sqrt(errSq/scale) << std::endl; else Out::os() << "mode i=" << i << " error=" << sqrt(errSq) << std::endl; } double tol = 1.0e-12; return SundanceGlobal::checkTest(sqrt(totalErr2), tol); }