Beispiel #1
0
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;
}
Beispiel #2
0
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();
}
Beispiel #4
0
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;
	}
}
Beispiel #5
0
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);
}