double L2Norm(const Mesh& mesh, const CellFilter& domain, const Expr& f, const QuadratureFamily& quad, const WatchFlag& watch) { Expr I2 = Integral(domain, f*f, quad, watch); return sqrt(evaluateIntegral(mesh, I2)); }
double H1Norm( const Mesh& mesh, const CellFilter& filter, const Expr& f, const QuadratureFamily& quad, const WatchFlag& watch) { Expr grad = gradient(mesh.spatialDim()); Expr g = grad*f; Expr I2 = Integral(filter, f*f + g*g, quad, watch); return sqrt(evaluateIntegral(mesh, I2)); }
bool DuffingFloquet() { int np = MPIComm::world().getNProc(); TEUCHOS_TEST_FOR_EXCEPT(np != 1); const double pi = 4.0*atan(1.0); /* We will do our linear algebra using Epetra */ VectorType<double> vecType = new EpetraVectorType(); /* Create a periodic mesh */ int nx = 128; MeshType meshType = new PeriodicMeshType1D(); MeshSource mesher = new PeriodicLineMesher(0.0, 2.0*pi, 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,2.0*pi)); /* Create unknown and test functions, discretized using first-order * Lagrange interpolants */ Expr u1 = new UnknownFunction(new Lagrange(1), "u1"); Expr u2 = new UnknownFunction(new Lagrange(1), "u2"); Expr v1 = new TestFunction(new Lagrange(1), "v1"); Expr v2 = new TestFunction(new Lagrange(1), "v2"); /* Create differential operator and coordinate function */ Expr dx = new Derivative(0); Expr x = new CoordExpr(0); /* We need a quadrature rule for doing the integrations */ QuadratureFamily quad = new GaussianQuadrature(4); double F0 = 0.5; double gamma = 2.0/3.0; double a0 = 1.0; double w0 = 1.0; double eps = 0.5; Expr u1Guess = -0.75*cos(x) + 0.237*sin(x); Expr u2Guess = 0.237*cos(x) + 0.75*sin(x); DiscreteSpace discSpace(mesh, List(new Lagrange(1), new Lagrange(1)), vecType); L2Projector proj(discSpace, List(u1Guess, u2Guess)); Expr u0 = proj.project(); Expr rhs1 = u2; Expr rhs2 = -w0*w0*u1 - gamma*u2 - eps*w0*w0*pow(u1,3.0)/a0/a0 + F0*w0*w0*sin(x); /* Define the weak form */ Expr eqn = Integral(interior, v1*(dx*u1 - rhs1) + v2*(dx*u2 - rhs2), quad); Expr dummyBC ; NonlinearProblem prob(mesh, eqn, dummyBC, List(v1,v2), List(u1,u2), u0, vecType); ParameterXMLFileReader reader("nox.xml"); ParameterList solverParams = reader.getParameters(); Out::root() << "finding periodic solution" << endl; NOXSolver solver(solverParams); prob.solve(solver); /* unfold the solution onto a non-periodic mesh */ Expr uP = unfoldPeriodicDiscreteFunction(u0, "u_p"); Out::root() << "uP=" << uP << endl; Mesh unfoldedMesh = DiscreteFunction::discFunc(uP)->mesh(); DiscreteSpace unfDiscSpace = DiscreteFunction::discFunc(uP)->discreteSpace(); FieldWriter writer = new MatlabWriter("Floquet.dat"); writer.addMesh(unfoldedMesh); writer.addField("u_p[0]", new ExprFieldWrapper(uP[0])); writer.addField("u_p[1]", new ExprFieldWrapper(uP[1])); Array<Expr> a(2); a[0] = new Sundance::Parameter(0.0, "a1"); a[1] = new Sundance::Parameter(0.0, "a2"); Expr bc = EssentialBC(left, v1*(u1-uP[0]-a[0]) + v2*(u2-uP[1]-a[1]), quad); NonlinearProblem unfProb(unfoldedMesh, eqn, bc, List(v1,v2), List(u1,u2), uP, vecType); unfProb.setEvalPoint(uP); LinearOperator<double> J = unfProb.allocateJacobian(); Vector<double> b = J.domain().createMember(); LinearSolver<double> linSolver = LinearSolverBuilder::createSolver("amesos.xml"); SerialDenseMatrix<int, double> F(a.size(), a.size()); for (int i=0; i<a.size(); i++) { Out::root() << "doing perturbed orbit #" << i << endl; for (int j=0; j<a.size(); j++) { if (i==j) a[j].setParameterValue(1.0); else a[j].setParameterValue(0.0); } unfProb.computeJacobianAndFunction(J, b); Vector<double> w = b.copy(); linSolver.solve(J, b, w); Expr w_i = new DiscreteFunction(unfDiscSpace, w); for (int j=0; j<a.size(); j++) { Out::root() << "postprocessing" << i << endl; writer.addField("w[" + Teuchos::toString(i) + ", " + Teuchos::toString(j) + "]", new ExprFieldWrapper(w_i[j])); Expr g = Integral(right, w_i[j], quad); F(j,i) = evaluateIntegral(unfoldedMesh, g); } } writer.write(); Out::root() << "Floquet matrix = " << endl << F << endl; Out::root() << "doing eigenvalue analysis" << endl; Array<double> ew_r(a.size()); Array<double> ew_i(a.size()); int lWork = 6*a.size(); Array<double> work(lWork); int info = 0; LAPACK<int, double> lapack; lapack.GEEV('N','N', a.size(), F.values(), a.size(), &(ew_r[0]), &(ew_i[0]), 0, 1, 0, 1, &(work[0]), lWork, &info); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::runtime_error, "LAPACK GEEV returned error code =" << info); Array<double> ew(a.size()); for (int i=0; i<a.size(); i++) { ew[i] = sqrt(ew_r[i]*ew_r[i]+ew_i[i]*ew_i[i]); Out::root() << setw(5) << i << setw(16) << ew_r[i] << setw(16) << ew_i[i] << setw(16) << ew[i] << endl; } double err = ::fabs(ew[0] - 0.123); return SundanceGlobal::checkTest(err, 0.001); }
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); }
int main(int argc, char** argv) { try { Sundance::init(&argc, &argv); /* We will do our linear algebra using Epetra */ VectorType<double> vecType = new EpetraVectorType(); /* Create a mesh. It will be of type BasisSimplicialMesh, and will * be built using a PartitionedLineMesher. */ MeshType meshType = new BasicSimplicialMeshType(); MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, 10, 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(); /* Create unknown and test functions, discretized using first-order * Lagrange interpolants */ Expr u = new UnknownFunction(new Lagrange(1), "u"); Expr v = new TestFunction(new Lagrange(1), "v"); /* We need a quadrature rule for doing the integrations */ QuadratureFamily quad = new GaussianQuadrature(2); /* Define the weak form */ Expr eqn = Integral(interior, v*(u-1.0), quad); Expr bc; /* We can now set up the linear problem! */ std::cerr << "setting up linear problem" << std::endl; LinearProblem prob(mesh, eqn, bc, v, u, vecType); #ifdef HAVE_CONFIG_H ParameterXMLFileReader reader(searchForFile("SolverParameters/bicgstab.xml")); #else ParameterXMLFileReader reader("bicgstab.xml"); #endif ParameterList solverParams = reader.getParameters(); std::cerr << "params = " << solverParams << std::endl; LinearSolver<double> solver = LinearSolverBuilder::createSolver(solverParams); std::cerr << "solving problem" << std::endl; Expr soln = prob.solve(solver); Expr exactSoln = 1.0; Expr errExpr = Integral(interior, pow(soln-exactSoln, 2), new GaussianQuadrature(4)); std::cerr << "setting up norm" << std::endl; double errorSq = evaluateIntegral(mesh, errExpr); std::cerr << "error norm = " << sqrt(errorSq) << std::endl << std::endl; double tol = 1.0e-12; Sundance::passFailTest(sqrt(errorSq), tol); } catch(std::exception& e) { std::cerr << e.what() << std::endl; } Sundance::finalize(); return Sundance::testStatus(); }