00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "Sundance.hpp"
00043 #include "SundanceTransientStepProblem.hpp"
00044 #include "SundanceDoublingStepController.hpp"
00045 #include "SundanceProblemTesting.hpp"
00046
00047 Expr rhsF(const Expr& x, const Expr& t)
00048 {
00049 return -12*pow((1 - x)*cos(t) - x*cos(t),2)
00050 *pow(2 + (1 - x)*x*cos(t),2) +
00051 8*cos(t)*pow(2 + (1 - x)*x*cos(t),3) - (1 - x)*x*sin(t);
00052 }
00053
00054
00055 int main(int argc, char** argv)
00056 {
00057 try
00058 {
00059 int nx = 96;
00060
00061 Sundance::setOption("nx", nx, "Number of elements");
00062
00063 Sundance::init(&argc, &argv);
00064 int np = MPIComm::world().getNProc();
00065
00066
00067 VectorType<double> vecType = new EpetraVectorType();
00068
00069
00070
00071 MeshType meshType = new BasicSimplicialMeshType();
00072 MeshSource mesher = new PartitionedLineMesher(0.0, 1.0, nx*np, meshType);
00073 Mesh mesh = mesher.getMesh();
00074
00075
00076
00077 CellFilter interior = new MaximalCellFilter();
00078 CellFilter points = new DimensionalCellFilter(0);
00079
00080 CellFilter right = points.coordSubset(0, 0.0);
00081 CellFilter left = points.coordSubset(0, 1.0);
00082 CellFilter midpoint = points.coordSubset(0, 0.5);
00083
00084
00085
00086 BasisFamily basis = new Lagrange(1);
00087 Expr u = new UnknownFunction(basis, "u");
00088 Expr v = new TestFunction(basis, "v");
00089
00090
00091
00092
00093 Expr dx = new Derivative(0);
00094 Expr x = new CoordExpr(0);
00095
00096
00097 QuadratureFamily quad = new GaussianQuadrature(4);
00098
00099
00100 Expr tPrev = new Sundance::Parameter(0.0);
00101 Expr t = new Sundance::Parameter(0.0);
00102 Expr dt = new Sundance::Parameter(0.0);
00103
00104 DiscreteSpace ds(mesh, basis, vecType);
00105 L2Projector proj(ds, 2.0+x*(1.0-x)*cos(t));
00106 Expr uPrev = proj.project();
00107 Expr uSoln = copyDiscreteFunction(uPrev);
00108
00109 Expr eqn = Integral(interior, v*(u-uPrev)
00110 + 2.0*dt*(dx*v)*(pow(u,3.0)*(dx*u) + pow(uPrev, 3.0)*(dx*uPrev))
00111 - 0.5*dt*v*(rhsF(x, tPrev) + rhsF(x, t)),
00112 quad);
00113 Expr bc = EssentialBC(left+right, v*(u+uPrev-4.0), quad);
00114
00115 NonlinearProblem stepProb(mesh, eqn, bc, v, u, uSoln, vecType);
00116
00117 TransientStepProblem prob(stepProb, tPrev, uPrev, t, uSoln, dt, 0);
00118
00119
00120 NonlinearSolver<double> solver
00121 = NonlinearSolverBuilder::createSolver("playa-newton-aztec-ml.xml");
00122
00123 double tol = 1.0e-4;
00124 double tFinal = 3.0*M_PI;
00125 StepControlParameters stepControl;
00126 stepControl.tStart_ = 0.0;
00127 stepControl.tStop_ = tFinal;
00128 stepControl.initialStepsize_ = 0.1;
00129 stepControl.maxStepsizeFactor_ = 100.0;
00130 stepControl.minStepsizeFactor_ = 1.0e-4;
00131 stepControl.verbosity_ = 4;
00132 stepControl.tau_ = tol;
00133
00134 FieldWriterFactory wf = new DSVWriterFactory();
00135 OutputControlParameters outputControl(wf, "ControlledTransient1D", tFinal/100.0, 0);
00136
00137 RCP<ExprComparisonBase> compare = rcp(new DefaultExprComparison());
00138
00139 DoublingStepController driver(prob, solver, stepControl, outputControl,
00140 compare);
00141
00142 driver.run();
00143
00144 Expr uFinal = copyDiscreteFunction(prob.uSoln());
00145 Expr uExact = 2.0 + x*(1.0-x)*cos(tFinal);
00146
00147 Expr errExpr = Integral(interior,
00148 pow(uFinal-uExact, 2),
00149 new GaussianQuadrature(2));
00150 double error = sqrt(evaluateIntegral(mesh, errExpr));
00151
00152 Out::root() << "error = " << error << endl;
00153
00154
00155 Sundance::passFailTest(error, tol);
00156 }
00157 catch(std::exception& e)
00158 {
00159 std::cerr << e.what() << std::endl;
00160 }
00161 Sundance::finalize(); return Sundance::testStatus();
00162 }
00163
00164
00165