int main(int argc, char *argv[]) { #ifdef HAVE_MPI Teuchos::GlobalMPISession mpiSession(&argc, &argv,0); #endif { // 1D tests CellTopoPtr line_2 = Teuchos::rcp( new shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >() ) ); // let's draw a line vector<double> v0 = makeVertex(0); vector<double> v1 = makeVertex(1); vector<double> v2 = makeVertex(2); vector< vector<double> > vertices; vertices.push_back(v0); vertices.push_back(v1); vertices.push_back(v2); vector<unsigned> line1VertexList; vector<unsigned> line2VertexList; line1VertexList.push_back(0); line1VertexList.push_back(1); line2VertexList.push_back(1); line2VertexList.push_back(2); vector< vector<unsigned> > elementVertices; elementVertices.push_back(line1VertexList); elementVertices.push_back(line2VertexList); vector< CellTopoPtr > cellTopos; cellTopos.push_back(line_2); cellTopos.push_back(line_2); MeshGeometryPtr meshGeometry = Teuchos::rcp( new MeshGeometry(vertices, elementVertices, cellTopos) ); MeshTopologyPtr meshTopology = Teuchos::rcp( new MeshTopology(meshGeometry) ); FunctionPtr x = Function::xn(1); FunctionPtr function = x; FunctionPtr fbdr = Function::restrictToCellBoundary(function); vector<FunctionPtr> functions; functions.push_back(function); functions.push_back(function); vector<string> functionNames; functionNames.push_back("function1"); functionNames.push_back("function2"); { XDMFExporter exporter(meshTopology, "function1", false); exporter.exportFunction(function, "function1"); } { XDMFExporter exporter(meshTopology, "boundary1", false); exporter.exportFunction(fbdr, "boundary1"); } { XDMFExporter exporter(meshTopology, "functions1", false); exporter.exportFunction(functions, functionNames); } } { // 2D tests CellTopoPtr quad_4 = Teuchos::rcp( new shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >() ) ); CellTopoPtr tri_3 = Teuchos::rcp( new shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >() ) ); // let's draw a little house vector<double> v0 = makeVertex(-1,0); vector<double> v1 = makeVertex(1,0); vector<double> v2 = makeVertex(1,2); vector<double> v3 = makeVertex(-1,2); vector<double> v4 = makeVertex(0.0,3); vector< vector<double> > vertices; vertices.push_back(v0); vertices.push_back(v1); vertices.push_back(v2); vertices.push_back(v3); vertices.push_back(v4); vector<unsigned> quadVertexList; quadVertexList.push_back(0); quadVertexList.push_back(1); quadVertexList.push_back(2); quadVertexList.push_back(3); vector<unsigned> triVertexList; triVertexList.push_back(3); triVertexList.push_back(2); triVertexList.push_back(4); vector< vector<unsigned> > elementVertices; elementVertices.push_back(quadVertexList); elementVertices.push_back(triVertexList); vector< CellTopoPtr > cellTopos; cellTopos.push_back(quad_4); cellTopos.push_back(tri_3); MeshGeometryPtr meshGeometry = Teuchos::rcp( new MeshGeometry(vertices, elementVertices, cellTopos) ); MeshTopologyPtr meshTopology = Teuchos::rcp( new MeshTopology(meshGeometry) ); FunctionPtr x2 = Function::xn(2); FunctionPtr y2 = Function::yn(2); FunctionPtr function = x2 + y2; FunctionPtr vect = Function::vectorize(x2, y2); FunctionPtr fbdr = Function::restrictToCellBoundary(function); vector<FunctionPtr> functions; functions.push_back(function); functions.push_back(vect); vector<string> functionNames; functionNames.push_back("function"); functionNames.push_back("vect"); vector<FunctionPtr> bdrfunctions; bdrfunctions.push_back(fbdr); bdrfunctions.push_back(fbdr); vector<string> bdrfunctionNames; bdrfunctionNames.push_back("bdr1"); bdrfunctionNames.push_back("bdr2"); map<int, int> cellIDToNum1DPts; cellIDToNum1DPts[1] = 4; { XDMFExporter exporter(meshTopology, "Grid2D", false); // exporter.exportFunction(function, "function2", 0, 10); // exporter.exportFunction(vect, "vect2", 1, 10, cellIDToNum1DPts); // exporter.exportFunction(fbdr, "boundary2", 0); exporter.exportFunction(functions, functionNames, 1, 10); } { XDMFExporter exporter(meshTopology, "BdrGrid2D", false); // exporter.exportFunction(function, "function2", 0, 10); // exporter.exportFunction(vect, "vect2", 1, 10, cellIDToNum1DPts); // exporter.exportFunction(fbdr, "boundary2", 0); exporter.exportFunction(bdrfunctions, bdrfunctionNames, 1, 10); } //////////////////// DECLARE VARIABLES /////////////////////// // define test variables VarFactory varFactory; VarPtr tau = varFactory.testVar("tau", HDIV); VarPtr v = varFactory.testVar("v", HGRAD); // define trial variables VarPtr uhat = varFactory.traceVar("uhat"); VarPtr fhat = varFactory.fluxVar("fhat"); VarPtr u = varFactory.fieldVar("u"); VarPtr sigma = varFactory.fieldVar("sigma", VECTOR_L2); //////////////////// DEFINE BILINEAR FORM /////////////////////// BFPtr bf = Teuchos::rcp( new BF(varFactory) ); // tau terms: bf->addTerm(sigma, tau); bf->addTerm(u, tau->div()); bf->addTerm(-uhat, tau->dot_normal()); // v terms: bf->addTerm( sigma, v->grad() ); bf->addTerm( fhat, v); //////////////////// BUILD MESH /////////////////////// int H1Order = 4, pToAdd = 2; Teuchos::RCP<Mesh> mesh = Teuchos::rcp( new Mesh (meshTopology, bf, H1Order, pToAdd) ); //////////////////// DEFINE INNER PRODUCT(S) /////////////////////// IPPtr ip = bf->graphNorm(); //////////////////// SPECIFY RHS /////////////////////// RHSPtr rhs = RHS::rhs(); // Teuchos::RCP<RHS> rhs = Teuchos::rcp( new RHS ); FunctionPtr one = Function::constant(1.0); rhs->addTerm( one * v ); //////////////////// CREATE BCs /////////////////////// // Teuchos::RCP<BC> bc = Teuchos::rcp( new BCEasy ); BCPtr bc = BC::bc(); FunctionPtr zero = Function::zero(); SpatialFilterPtr entireBoundary = Teuchos::rcp( new EntireBoundary ); bc->addDirichlet(uhat, entireBoundary, zero); //////////////////// SOLVE & REFINE /////////////////////// Teuchos::RCP<Solution> solution = Teuchos::rcp( new Solution(mesh, bc, rhs, ip) ); solution->solve(false); RefinementStrategy refinementStrategy( solution, 0.2); // Output solution FunctionPtr uSoln = Function::solution(u, solution); FunctionPtr sigmaSoln = Function::solution(sigma, solution); FunctionPtr uhatSoln = Function::solution(uhat, solution); FunctionPtr fhatSoln = Function::solution(fhat, solution); { XDMFExporter exporter(meshTopology, "Poisson", false); exporter.exportFunction(uSoln, "u", 0, 4); exporter.exportFunction(uSoln, "u", 1, 5); exporter.exportFunction(uhatSoln, "uhat", 0, 4); exporter.exportFunction(uhatSoln, "uhat", 1, 5); // exporter.exportFunction(fhatSoln, "fhat", 0, 4); // exporter.exportFunction(fhatSoln, "fhat", 1, 5); } { XDMFExporter exporter(meshTopology, "PoissonSolution", false); exporter.exportSolution(solution, mesh, varFactory, 0, 2, cellIDToSubdivision(mesh, 10)); refinementStrategy.refine(true); solution->solve(false); exporter.exportSolution(solution, mesh, varFactory, 1, 2, cellIDToSubdivision(mesh, 10)); } // exporter.exportFunction(sigmaSoln, "Poisson-s", "sigma", 0, 5); // exporter.exportFunction(uhatSoln, "Poisson-uhat", "uhat", 1, 6); } { // 3D tests CellTopoPtr hex = Teuchos::rcp(new shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() )); // let's draw a little box vector<double> v0 = makeVertex(0,0,0); vector<double> v1 = makeVertex(1,0,0); vector<double> v2 = makeVertex(1,1,0); vector<double> v3 = makeVertex(0,1,0); vector<double> v4 = makeVertex(0,0,1); vector<double> v5 = makeVertex(1,0,1); vector<double> v6 = makeVertex(1,1,1); vector<double> v7 = makeVertex(0,1,1); vector< vector<double> > vertices; vertices.push_back(v0); vertices.push_back(v1); vertices.push_back(v2); vertices.push_back(v3); vertices.push_back(v4); vertices.push_back(v5); vertices.push_back(v6); vertices.push_back(v7); vector<unsigned> hexVertexList; hexVertexList.push_back(0); hexVertexList.push_back(1); hexVertexList.push_back(2); hexVertexList.push_back(3); hexVertexList.push_back(4); hexVertexList.push_back(5); hexVertexList.push_back(6); hexVertexList.push_back(7); // vector<unsigned> triVertexList; // triVertexList.push_back(2); // triVertexList.push_back(3); // triVertexList.push_back(4); vector< vector<unsigned> > elementVertices; elementVertices.push_back(hexVertexList); // elementVertices.push_back(triVertexList); vector< CellTopoPtr > cellTopos; cellTopos.push_back(hex); // cellTopos.push_back(tri_3); MeshGeometryPtr meshGeometry = Teuchos::rcp( new MeshGeometry(vertices, elementVertices, cellTopos) ); MeshTopologyPtr meshTopology = Teuchos::rcp( new MeshTopology(meshGeometry) ); FunctionPtr x = Function::xn(1); FunctionPtr y = Function::yn(1); FunctionPtr z = Function::zn(1); FunctionPtr function = x + y + z; FunctionPtr fbdr = Function::restrictToCellBoundary(function); FunctionPtr vect = Function::vectorize(x, y, z); vector<FunctionPtr> functions; functions.push_back(function); functions.push_back(vect); vector<string> functionNames; functionNames.push_back("function"); functionNames.push_back("vect"); { XDMFExporter exporter(meshTopology, "function3", false); exporter.exportFunction(function, "function3"); } { XDMFExporter exporter(meshTopology, "boundary3", false); exporter.exportFunction(fbdr, "boundary3"); } { XDMFExporter exporter(meshTopology, "vect3", false); exporter.exportFunction(vect, "vect3"); } { XDMFExporter exporter(meshTopology, "functions3", false); exporter.exportFunction(functions, functionNames); } } }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI Teuchos::GlobalMPISession mpiSession(&argc, &argv,0); choice::MpiArgs args( argc, argv ); #else choice::Args args( argc, argv ); #endif int commRank = Teuchos::GlobalMPISession::getRank(); int numProcs = Teuchos::GlobalMPISession::getNProc(); // Required arguments int numRefs = args.Input<int>("--numRefs", "number of refinement steps"); int norm = args.Input<int>("--norm", "0 = graph\n 1 = robust\n 2 = coupled robust"); // Optional arguments (have defaults) bool enforceLocalConservation = args.Input<bool>("--conserve", "enforce local conservation", false); double Re = args.Input("--Re", "Reynolds number", 40); double nu = 1./Re; double lambda = Re/2.-sqrt(Re*Re/4+4*pi*pi); int maxNewtonIterations = args.Input("--maxIterations", "maximum number of Newton iterations", 20); int polyOrder = args.Input("--polyOrder", "polynomial order for field variables", 2); int deltaP = args.Input("--deltaP", "how much to enrich test space", 2); // string saveFile = args.Input<string>("--meshSaveFile", "file to which to save refinement history", ""); // string replayFile = args.Input<string>("--meshLoadFile", "file with refinement history to replay", ""); args.Process(); // if (commRank==0) // { // cout << "saveFile is " << saveFile << endl; // cout << "loadFile is " << replayFile << endl; // } //////////////////// PROBLEM DEFINITIONS /////////////////////// int H1Order = polyOrder+1; //////////////////// DECLARE VARIABLES /////////////////////// // define test variables VarFactory varFactory; VarPtr tau11 = varFactory.testVar("tau11", HGRAD); VarPtr tau12 = varFactory.testVar("tau12", HGRAD); VarPtr tau22 = varFactory.testVar("tau22", HGRAD); VarPtr v1 = varFactory.testVar("v1", HGRAD); VarPtr v2 = varFactory.testVar("v2", HGRAD); // define trial variables VarPtr u1 = varFactory.fieldVar("u1"); VarPtr u2 = varFactory.fieldVar("u2"); VarPtr sigma11 = varFactory.fieldVar("sigma11"); VarPtr sigma12 = varFactory.fieldVar("sigma12"); VarPtr sigma22 = varFactory.fieldVar("sigma22"); VarPtr u1hat = varFactory.traceVar("u1hat"); VarPtr u2hat = varFactory.traceVar("u2hat"); VarPtr t1hat = varFactory.fluxVar("t1hat"); VarPtr t2hat = varFactory.fluxVar("t2hat"); //////////////////// BUILD MESH /////////////////////// BFPtr bf = Teuchos::rcp( new BF(varFactory) ); // define nodes for mesh FieldContainer<double> meshBoundary(4,2); double xmin = -0.5; double xmax = 1.0; double ymin = -0.5; double ymax = 1.5; meshBoundary(0,0) = xmin; // x1 meshBoundary(0,1) = ymin; // y1 meshBoundary(1,0) = xmax; meshBoundary(1,1) = ymin; meshBoundary(2,0) = xmax; meshBoundary(2,1) = ymax; meshBoundary(3,0) = xmin; meshBoundary(3,1) = ymax; int horizontalCells = 6, verticalCells = 8; // create a pointer to a new mesh: Teuchos::RCP<Mesh> mesh = MeshFactory::buildQuadMesh(meshBoundary, horizontalCells, verticalCells, bf, H1Order, H1Order+deltaP); //////////////////////////////////////////////////////////////////// // INITIALIZE BACKGROUND FLOW FUNCTIONS //////////////////////////////////////////////////////////////////// BCPtr nullBC = Teuchos::rcp((BC*)NULL); RHSPtr nullRHS = Teuchos::rcp((RHS*)NULL); IPPtr nullIP = Teuchos::rcp((IP*)NULL); SolutionPtr backgroundFlow = Teuchos::rcp(new Solution(mesh, nullBC, nullRHS, nullIP) ); vector<double> e1(2); // (1,0) e1[0] = 1; vector<double> e2(2); // (0,1) e2[1] = 1; FunctionPtr u1_prev = Function::solution(u1, backgroundFlow); FunctionPtr u2_prev = Function::solution(u2, backgroundFlow); // FunctionPtr sigma11_prev = Function::solution(sigma11, backgroundFlow); // FunctionPtr sigma12_prev = Function::solution(sigma12, backgroundFlow); // FunctionPtr sigma22_prev = Function::solution(sigma22, backgroundFlow); FunctionPtr zero = Teuchos::rcp( new ConstantScalarFunction(0.0) ); FunctionPtr one = Teuchos::rcp( new ConstantScalarFunction(1.0) ); FunctionPtr u1Exact = Teuchos::rcp( new ExactU1(lambda) ); FunctionPtr u2Exact = Teuchos::rcp( new ExactU2(lambda) ); // ==================== SET INITIAL GUESS ========================== map<int, Teuchos::RCP<Function> > functionMap; // functionMap[u1->ID()] = u1Exact; // functionMap[u2->ID()] = u2Exact; functionMap[u1->ID()] = zero; functionMap[u2->ID()] = zero; backgroundFlow->projectOntoMesh(functionMap); //////////////////// DEFINE BILINEAR FORM /////////////////////// // stress equation bf->addTerm( 1./nu*sigma11, tau11 ); bf->addTerm( 1./nu*sigma12, tau12 ); bf->addTerm( 1./nu*sigma12, tau12 ); bf->addTerm( 1./nu*sigma22, tau22 ); bf->addTerm( -0.5/nu*sigma11, tau11 ); bf->addTerm( -0.5/nu*sigma22, tau11 ); bf->addTerm( -0.5/nu*sigma11, tau22 ); bf->addTerm( -0.5/nu*sigma22, tau22 ); bf->addTerm( 2*u1, tau11->dx() ); bf->addTerm( 2*u1, tau12->dy() ); bf->addTerm( 2*u2, tau12->dx() ); bf->addTerm( 2*u2, tau22->dy() ); bf->addTerm( -2*u1hat, tau11->times_normal_x() ); bf->addTerm( -2*u1hat, tau12->times_normal_y() ); bf->addTerm( -2*u2hat, tau12->times_normal_x() ); bf->addTerm( -2*u2hat, tau22->times_normal_y() ); // momentum equation bf->addTerm( -2.*u1_prev*u1, v1->dx() ); bf->addTerm( -u2_prev*u1, v1->dy() ); bf->addTerm( -u1_prev*u2, v1->dy() ); bf->addTerm( -u2_prev*u1, v2->dx() ); bf->addTerm( -u1_prev*u2, v2->dx() ); bf->addTerm( -2.*u2_prev*u2, v2->dy() ); bf->addTerm( sigma11, v1->dx() ); bf->addTerm( sigma12, v1->dy() ); bf->addTerm( sigma12, v2->dx() ); bf->addTerm( sigma22, v2->dy() ); bf->addTerm( t1hat, v1); bf->addTerm( t2hat, v2); //////////////////// SPECIFY RHS /////////////////////// RHSPtr rhs = RHS::rhs(); // stress equation rhs->addTerm( -2*u1_prev * tau11->dx() ); rhs->addTerm( -2*u1_prev * tau12->dy() ); rhs->addTerm( -2*u2_prev * tau12->dx() ); rhs->addTerm( -2*u2_prev * tau22->dy() ); // momentum equation rhs->addTerm( u1_prev*u1_prev * v1->dx() ); rhs->addTerm( u2_prev*u1_prev * v1->dy() ); rhs->addTerm( u2_prev*u1_prev * v2->dx() ); rhs->addTerm( u2_prev*u2_prev * v2->dy() ); //////////////////// DEFINE INNER PRODUCT(S) /////////////////////// IPPtr ip = Teuchos::rcp(new IP); if (norm == 0) { ip = bf->graphNorm(); } else if (norm == 1) { ip->addTerm( 0.5/nu*tau11-0.5/nu*tau22 + v1->dx() ); ip->addTerm( 1./nu*tau12 + v1->dy() ); ip->addTerm( 1./nu*tau12 + v2->dx() ); ip->addTerm( 0.5/nu*tau22-0.5/nu*tau11 + v2->dy() ); ip->addTerm( 2*tau11->dx() + 2*tau12->dy() - 2*u1_prev*v1->dx() - u2_prev*v1->dy() - u2_prev*v2->dx() ); ip->addTerm( 2*tau12->dx() + 2*tau22->dy() - 2*u2_prev*v2->dy() - u1_prev*v1->dy() - u1_prev*v2->dx() ); ip->addTerm( v1 ); ip->addTerm( v2 ); ip->addTerm( tau11 ); ip->addTerm( tau12 ); ip->addTerm( tau12 ); ip->addTerm( tau22 ); } else if (norm == 2) { // ip->addTerm( 0.5/sqrt(nu)*tau11-0.5/nu*tau22 ); // ip->addTerm( 1./sqrt(nu)*tau12 ); // ip->addTerm( 1./sqrt(nu)*tau12 ); // ip->addTerm( 0.5/sqrt(nu)*tau22-0.5/nu*tau11 ); ip->addTerm( tau11 ); ip->addTerm( tau12 ); ip->addTerm( tau12 ); ip->addTerm( tau22 ); ip->addTerm( 2*tau11->dx() + 2*tau12->dy() - 2*u1_prev*v1->dx() - u2_prev*v1->dy() - u2_prev*v2->dx() ); ip->addTerm( 2*tau12->dx() + 2*tau22->dy() - 2*u2_prev*v2->dy() - u1_prev*v1->dy() - u1_prev*v2->dx() ); ip->addTerm( 2*u1_prev*v1->dx() + u2_prev*v1->dy() + u2_prev*v2->dx() ); ip->addTerm( 2*u2_prev*v2->dy() + u1_prev*v1->dy() + u1_prev*v2->dx() ); ip->addTerm( sqrt(nu)*v1->grad() ); ip->addTerm( sqrt(nu)*v2->grad() ); ip->addTerm( v1 ); ip->addTerm( v2 ); } //////////////////// CREATE BCs /////////////////////// BCPtr bc = BC::bc(); // Teuchos::RCP<PenaltyConstraints> pc = Teuchos::rcp( new PenaltyConstraints ); SpatialFilterPtr left = Teuchos::rcp( new ConstantXBoundary(-0.5) ); SpatialFilterPtr right = Teuchos::rcp( new ConstantXBoundary(1) ); SpatialFilterPtr top = Teuchos::rcp( new ConstantYBoundary(-0.5) ); SpatialFilterPtr bottom = Teuchos::rcp( new ConstantYBoundary(1.5) ); bc->addDirichlet(u1hat, left, u1Exact); bc->addDirichlet(u2hat, left, u2Exact); bc->addDirichlet(u1hat, right, u1Exact); bc->addDirichlet(u2hat, right, u2Exact); bc->addDirichlet(u1hat, top, u1Exact); bc->addDirichlet(u2hat, top, u2Exact); bc->addDirichlet(u1hat, bottom, u1Exact); bc->addDirichlet(u2hat, bottom, u2Exact); // bc->addDirichlet(u1hat, left, zero); // bc->addDirichlet(u2hat, left, zero); // bc->addDirichlet(u1hat, right, zero); // bc->addDirichlet(u2hat, right, zero); // bc->addDirichlet(u1hat, top, zero); // bc->addDirichlet(u2hat, top, zero); // bc->addDirichlet(u1hat, bottom, zero); // bc->addDirichlet(u2hat, bottom, zero); // pc->addConstraint(u1hat*u2hat-t1hat == zero, top); // pc->addConstraint(u2hat*u2hat-t2hat == zero, top); Teuchos::RCP<Solution> solution = Teuchos::rcp( new Solution(mesh, bc, rhs, ip) ); // solution->setFilter(pc); // if (enforceLocalConservation) { // solution->lagrangeConstraints()->addConstraint(u1hat->times_normal_x() + u2hat->times_normal_y() == zero); // } // ==================== Register Solutions ========================== mesh->registerSolution(solution); mesh->registerSolution(backgroundFlow); // Teuchos::RCP< RefinementHistory > refHistory = Teuchos::rcp( new RefinementHistory ); // mesh->registerObserver(refHistory); //////////////////// SOLVE & REFINE /////////////////////// double energyThreshold = 0.2; // for mesh refinements RefinementStrategy refinementStrategy( solution, energyThreshold ); HDF5Exporter exporter(mesh, "Kovasznay_np"); ofstream convOut; stringstream convOutFile; convOutFile << "Kovasznay_conv_" << Re <<".txt"; if (commRank == 0) convOut.open(convOutFile.str().c_str()); set<int> nonlinearVars; nonlinearVars.insert(u1->ID()); nonlinearVars.insert(u2->ID()); double nonlinearRelativeEnergyTolerance = 1e-5; // used to determine convergence of the nonlinear solution for (int refIndex=0; refIndex<=numRefs; refIndex++) { double L2Update = 1e10; int iterCount = 0; while (L2Update > nonlinearRelativeEnergyTolerance && iterCount < maxNewtonIterations) { solution->solve(false); double u1L2Update = solution->L2NormOfSolutionGlobal(u1->ID()); double u2L2Update = solution->L2NormOfSolutionGlobal(u2->ID()); L2Update = sqrt(u1L2Update*u1L2Update + u2L2Update*u2L2Update); // Check local conservation if (commRank == 0) { cout << "L2 Norm of Update = " << L2Update << endl; // if (saveFile.length() > 0) { // std::ostringstream oss; // oss << string(saveFile) << refIndex ; // cout << "on refinement " << refIndex << " saving mesh file to " << oss.str() << endl; // refHistory->saveToFile(oss.str()); // } } // line search algorithm double alpha = 1.0; backgroundFlow->addSolution(solution, alpha, nonlinearVars); iterCount++; } exporter.exportSolution(backgroundFlow, varFactory, refIndex, 2, cellIDToSubdivision(mesh, 4)); FunctionPtr u1Soln = Function::solution(u1, backgroundFlow); FunctionPtr u2Soln = Function::solution(u2, backgroundFlow); FunctionPtr u1Sqr = (u1Soln-u1Exact)*(u1Soln-u1Exact); FunctionPtr u2Sqr = (u2Soln-u2Exact)*(u2Soln-u2Exact); double u1L2Error = u1Sqr->integrate(mesh, 1e-5); double u2L2Error = u2Sqr->integrate(mesh, 1e-5); double l2Error = sqrt(u1L2Error+u2L2Error); double energyError = solution->energyErrorTotal(); cout << "L2 Error: " << l2Error << " Energy Error: " << energyError << endl; if (refIndex < numRefs) refinementStrategy.refine(commRank==0); // print to console on commRank 0 } return 0; }