void MeshRefinement::flag_elements_by_mean_stddev (const ErrorVector & error_per_cell,
                                                   const Real refine_frac,
                                                   const Real coarsen_frac,
                                                   const unsigned int max_l)
{
  // The function arguments are currently just there for
  // backwards_compatibility
  if (!_use_member_parameters)
    {
      // If the user used non-default parameters, lets warn
      // that they're deprecated
      if (refine_frac != 0.3 ||
          coarsen_frac != 0.0 ||
          max_l != libMesh::invalid_uint)
        libmesh_deprecated();

      _refine_fraction = refine_frac;
      _coarsen_fraction = coarsen_frac;
      _max_h_level = max_l;
    }

  // Get the mean value from the error vector
  const Real mean = error_per_cell.mean();

  // Get the standard deviation.  This equals the
  // square-root of the variance
  const Real stddev = std::sqrt (error_per_cell.variance());

  // Check for valid fractions
  libmesh_assert_greater_equal (_refine_fraction, 0);
  libmesh_assert_less_equal (_refine_fraction, 1);
  libmesh_assert_greater_equal (_coarsen_fraction, 0);
  libmesh_assert_less_equal (_coarsen_fraction, 1);

  // The refine and coarsen cutoff
  const Real refine_cutoff  =  mean + _refine_fraction  * stddev;
  const Real coarsen_cutoff =  std::max(mean - _coarsen_fraction * stddev, 0.);

  // Loop over the elements and flag them for coarsening or
  // refinement based on the element error
  for (auto & elem : _mesh.active_element_ptr_range())
    {
      const dof_id_type id  = elem->id();

      libmesh_assert_less (id, error_per_cell.size());

      const ErrorVectorReal elem_error = error_per_cell[id];

      // Possibly flag the element for coarsening ...
      if (elem_error <= coarsen_cutoff)
        elem->set_refinement_flag(Elem::COARSEN);

      // ... or refinement
      if ((elem_error >= refine_cutoff) && (elem->level() < _max_h_level))
        elem->set_refinement_flag(Elem::REFINE);
    }
}
예제 #2
0
// The main program
int main(int argc, char** argv)
{
    // Initialize libMesh
    LibMeshInit init(argc, argv);

    // Parameters
    GetPot infile("fem_system_params.in");
    const Real global_tolerance          = infile("global_tolerance", 0.);
    const unsigned int nelem_target      = infile("n_elements", 400);
    const bool transient                 = infile("transient", true);
    const Real deltat                    = infile("deltat", 0.005);
    unsigned int n_timesteps             = infile("n_timesteps", 1);
    //const unsigned int coarsegridsize    = infile("coarsegridsize", 1);
    const unsigned int coarserefinements = infile("coarserefinements", 0);
    const unsigned int max_adaptivesteps = infile("max_adaptivesteps", 10);
    //const unsigned int dim               = 2;

#ifdef LIBMESH_HAVE_EXODUS_API
    const unsigned int write_interval    = infile("write_interval", 5);
#endif

    // Create a mesh, with dimension to be overridden later, distributed
    // across the default MPI communicator.
    Mesh mesh(init.comm());
    GetPot infileForMesh("convdiff_mprime.in");
    std::string find_mesh_here = infileForMesh("mesh","psiLF_mesh.xda");
    mesh.read(find_mesh_here);

    std::cout << "Read in mesh from: " << find_mesh_here << "\n\n";

    // And an object to refine it
    MeshRefinement mesh_refinement(mesh);
    mesh_refinement.coarsen_by_parents() = true;
    mesh_refinement.absolute_global_tolerance() = global_tolerance;
    mesh_refinement.nelem_target() = nelem_target;
    mesh_refinement.refine_fraction() = 0.3;
    mesh_refinement.coarsen_fraction() = 0.3;
    mesh_refinement.coarsen_threshold() = 0.1;

    //mesh_refinement.uniformly_refine(coarserefinements);

    // Print information about the mesh to the screen.
    mesh.print_info();

    // Create an equation systems object.
    EquationSystems equation_systems (mesh);

    // Name system
    ConvDiff_MprimeSys & system =
        equation_systems.add_system<ConvDiff_MprimeSys>("Diff_ConvDiff_MprimeSys");

    // Steady-state problem
    system.time_solver =
        AutoPtr<TimeSolver>(new SteadySolver(system));

    // Sanity check that we are indeed solving a steady problem
    libmesh_assert_equal_to (n_timesteps, 1);

    // Read in all the equation systems data from the LF solve (system, solutions, rhs, etc)
    std::string find_psiLF_here = infileForMesh("psiLF_file","psiLF.xda");
    std::cout << "Looking for psiLF at: " << find_psiLF_here << "\n\n";

    equation_systems.read(find_psiLF_here, READ,
                          EquationSystems::READ_HEADER |
                          EquationSystems::READ_DATA |
                          EquationSystems::READ_ADDITIONAL_DATA);

    // Check that the norm of the solution read in is what we expect it to be
    Real readin_L2 = system.calculate_norm(*system.solution, 0, L2);
    std::cout << "Read in solution norm: "<< readin_L2 << std::endl << std::endl;

    //DEBUG
    //equation_systems.write("right_back_out.xda", WRITE, EquationSystems::WRITE_DATA |
    //		 EquationSystems::WRITE_ADDITIONAL_DATA);
#ifdef LIBMESH_HAVE_GMV
    //GMVIO(equation_systems.get_mesh()).write_equation_systems(std::string("right_back_out.gmv"), equation_systems);
#endif

    // Initialize the system
    //equation_systems.init ();  //already initialized by read-in

    // And the nonlinear solver options
    NewtonSolver *solver = new NewtonSolver(system);
    system.time_solver->diff_solver() = AutoPtr<DiffSolver>(solver);
    solver->quiet = infile("solver_quiet", true);
    solver->verbose = !solver->quiet;
    solver->max_nonlinear_iterations =
        infile("max_nonlinear_iterations", 15);
    solver->relative_step_tolerance =
        infile("relative_step_tolerance", 1.e-3);
    solver->relative_residual_tolerance =
        infile("relative_residual_tolerance", 0.0);
    solver->absolute_residual_tolerance =
        infile("absolute_residual_tolerance", 0.0);

    // And the linear solver options
    solver->max_linear_iterations =
        infile("max_linear_iterations", 50000);
    solver->initial_linear_tolerance =
        infile("initial_linear_tolerance", 1.e-3);

    // Print information about the system to the screen.
    equation_systems.print_info();

    // Now we begin the timestep loop to compute the time-accurate
    // solution of the equations...not that this is transient, but eh, why not...
    for (unsigned int t_step=0; t_step != n_timesteps; ++t_step)
    {
        // A pretty update message
        std::cout << "\n\nSolving time step " << t_step << ", time = "
                  << system.time << std::endl;

        // Adaptively solve the timestep
        unsigned int a_step = 0;
        for (; a_step != max_adaptivesteps; ++a_step)
        {   // VESTIGIAL for now ('vestigial' eh ? ;) )

            std::cout << "\n\n I should be skipped what are you doing here lalalalalalala *!**!*!*!*!*!* \n\n";

            system.solve();
            system.postprocess();
            ErrorVector error;
            AutoPtr<ErrorEstimator> error_estimator;

            // To solve to a tolerance in this problem we
            // need a better estimator than Kelly
            if (global_tolerance != 0.)
            {
                // We can't adapt to both a tolerance and a mesh
                // size at once
                libmesh_assert_equal_to (nelem_target, 0);

                UniformRefinementEstimator *u =
                    new UniformRefinementEstimator;

                // The lid-driven cavity problem isn't in H1, so
                // lets estimate L2 error
                u->error_norm = L2;

                error_estimator.reset(u);
            }
            else
            {
                // If we aren't adapting to a tolerance we need a
                // target mesh size
                libmesh_assert_greater (nelem_target, 0);

                // Kelly is a lousy estimator to use for a problem
                // not in H1 - if we were doing more than a few
                // timesteps we'd need to turn off or limit the
                // maximum level of our adaptivity eventually
                error_estimator.reset(new KellyErrorEstimator);
            }

            // Calculate error
            std::vector<Real> weights(9,1.0);  // based on u, v, p, c, their adjoints, and source parameter

            // Keep the same default norm type.
            std::vector<FEMNormType>
            norms(1, error_estimator->error_norm.type(0));
            error_estimator->error_norm = SystemNorm(norms, weights);

            error_estimator->estimate_error(system, error);

            // Print out status at each adaptive step.
            Real global_error = error.l2_norm();
            std::cout << "Adaptive step " << a_step << ": " << std::endl;
            if (global_tolerance != 0.)
                std::cout << "Global_error = " << global_error
                          << std::endl;
            if (global_tolerance != 0.)
                std::cout << "Worst element error = " << error.maximum()
                          << ", mean = " << error.mean() << std::endl;

            if (global_tolerance != 0.)
            {
                // If we've reached our desired tolerance, we
                // don't need any more adaptive steps
                if (global_error < global_tolerance)
                    break;
                mesh_refinement.flag_elements_by_error_tolerance(error);
            }
            else
            {
                // If flag_elements_by_nelem_target returns true, this
                // should be our last adaptive step.
                if (mesh_refinement.flag_elements_by_nelem_target(error))
                {
                    mesh_refinement.refine_and_coarsen_elements();
                    equation_systems.reinit();
                    a_step = max_adaptivesteps;
                    break;
                }
            }

            // Carry out the adaptive mesh refinement/coarsening
            mesh_refinement.refine_and_coarsen_elements();
            equation_systems.reinit();

            std::cout << "Refined mesh to "
                      << mesh.n_active_elem()
                      << " active elements and "
                      << equation_systems.n_active_dofs()
                      << " active dofs." << std::endl;
        } // End loop over adaptive steps

        // Do one last solve if necessary
        if (a_step == max_adaptivesteps)
        {
            QoISet qois;
            std::vector<unsigned int> qoi_indices;

            qoi_indices.push_back(0);
            qois.add_indices(qoi_indices);

            qois.set_weight(0, 1.0);

            system.assemble_qoi_sides = true; //QoI doesn't involve sides

            std::cout << "\n~*~*~*~*~*~*~*~*~ adjoint solve start ~*~*~*~*~*~*~*~*~\n" << std::endl;
            std::pair<unsigned int, Real> adjsolve = system.adjoint_solve();
            std::cout << "number of iterations to solve adjoint: " << adjsolve.first << std::endl;
            std::cout << "final residual of adjoint solve: " << adjsolve.second << std::endl;
            std::cout << "\n~*~*~*~*~*~*~*~*~ adjoint solve end ~*~*~*~*~*~*~*~*~" << std::endl;

            NumericVector<Number> &dual_solution = system.get_adjoint_solution(0);
            NumericVector<Number> &primal_solution = *system.solution;

            primal_solution.swap(dual_solution);
            ExodusII_IO(mesh).write_timestep("super_adjoint.exo",
                                             equation_systems,
                                             1, /* This number indicates how many time steps
	                                       are being written to the file */
                                             system.time);
            primal_solution.swap(dual_solution);

            system.assemble(); //overwrite residual read in from psiLF solve

            // The total error estimate
            system.postprocess(); //to compute M_HF(psiLF) and M_LF(psiLF) terms
            Real QoI_error_estimate = (-0.5*(system.rhs)->dot(dual_solution)) + system.get_MHF_psiLF() - system.get_MLF_psiLF();
            std::cout << "\n\n 0.5*M'_HF(psiLF)(superadj): " << std::setprecision(17) << 0.5*(system.rhs)->dot(dual_solution) << "\n";
            std::cout << " M_HF(psiLF): " << std::setprecision(17) << system.get_MHF_psiLF() << "\n";
            std::cout << " M_LF(psiLF): " << std::setprecision(17) << system.get_MLF_psiLF() << "\n";
            std::cout << "\n\n Residual L2 norm: " << system.calculate_norm(*system.rhs, L2) << "\n";
            std::cout << " Residual discrete L2 norm: " << system.calculate_norm(*system.rhs, DISCRETE_L2) << "\n";
            std::cout << " Super-adjoint L2 norm: " << system.calculate_norm(dual_solution, L2) << "\n";
            std::cout << " Super-adjoint discrete L2 norm: " << system.calculate_norm(dual_solution, DISCRETE_L2) << "\n";
            std::cout << "\n\n QoI error estimate: " << std::setprecision(17) << QoI_error_estimate << "\n\n";

            //DEBUG
            std::cout << "\n------------ herp derp ------------" << std::endl;
            //libMesh::out.precision(16);
            //dual_solution.print();
            //system.get_adjoint_rhs().print();

            AutoPtr<NumericVector<Number> > adjresid = system.solution->clone();
            (system.matrix)->vector_mult(*adjresid,system.get_adjoint_solution(0));
            SparseMatrix<Number>& adjmat = *system.matrix;
            (system.matrix)->get_transpose(adjmat);
            adjmat.vector_mult(*adjresid,system.get_adjoint_solution(0));
            //std::cout << "******************** matrix-superadj product (libmesh) ************************" << std::endl;
            //adjresid->print();
            adjresid->add(-1.0, system.get_adjoint_rhs(0));
            //std::cout << "******************** superadjoint system residual (libmesh) ***********************" << std::endl;
            //adjresid->print();
            std::cout << "\n\nadjoint system residual (discrete L2): " << system.calculate_norm(*adjresid,DISCRETE_L2) << std::endl;
            std::cout << "adjoint system residual (L2, all): " << system.calculate_norm(*adjresid,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 0): " << system.calculate_norm(*adjresid,0,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 1): " << system.calculate_norm(*adjresid,1,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 2): " << system.calculate_norm(*adjresid,2,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 3): " << system.calculate_norm(*adjresid,3,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 4): " << system.calculate_norm(*adjresid,4,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 5): " << system.calculate_norm(*adjresid,5,L2) << std::endl;
            /*
            	AutoPtr<NumericVector<Number> > sadj_matlab = system.solution->clone();
            	AutoPtr<NumericVector<Number> > adjresid_matlab = system.solution->clone();
            	if(FILE *fp=fopen("superadj_matlab.txt","r")){
              	Real value;
              	int counter = 0;
              	int flag = 1;
              	while(flag != -1){
              		flag = fscanf(fp,"%lf",&value);
              		if(flag != -1){
            				sadj_matlab->set(counter, value);
            				counter += 1;
              		}
              	}
              	fclose(fp);
            	}
            	(system.matrix)->vector_mult(*adjresid_matlab,*sadj_matlab);
            	//std::cout << "******************** matrix-superadj product (matlab) ***********************" << std::endl;
            	//adjresid_matlab->print();
            	adjresid_matlab->add(-1.0, system.get_adjoint_rhs(0));
            	//std::cout << "******************** superadjoint system residual (matlab) ***********************" << std::endl;
            	//adjresid_matlab->print();
            	std::cout << "\n\nmatlab import adjoint system residual (discrete L2): " << system.calculate_norm(*adjresid_matlab,DISCRETE_L2) << "\n" << std::endl;
            */
            /*
            	AutoPtr<NumericVector<Number> > sadj_fwd_hack = system.solution->clone();
            	AutoPtr<NumericVector<Number> > adjresid_fwd_hack = system.solution->clone();
            	if(FILE *fp=fopen("superadj_forward_hack.txt","r")){
              	Real value;
              	int counter = 0;
              	int flag = 1;
              	while(flag != -1){
              		flag = fscanf(fp,"%lf",&value);
              		if(flag != -1){
            				sadj_fwd_hack->set(counter, value);
            				counter += 1;
              		}
              	}
              	fclose(fp);
            	}
            	(system.matrix)->vector_mult(*adjresid_fwd_hack,*sadj_fwd_hack);
            	//std::cout << "******************** matrix-superadj product (fwd_hack) ***********************" << std::endl;
            	//adjresid_fwd_hack->print();
            	adjresid_fwd_hack->add(-1.0, system.get_adjoint_rhs(0));
            	//std::cout << "******************** superadjoint system residual (fwd_hack) ***********************" << std::endl;
            	//adjresid_fwd_hack->print();
            	std::cout << "\n\nfwd_hack import adjoint system residual (discrete L2): " << system.calculate_norm(*adjresid_fwd_hack,DISCRETE_L2) << "\n" << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 0): " << system.calculate_norm(*adjresid_fwd_hack,0,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 1): " << system.calculate_norm(*adjresid_fwd_hack,1,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 2): " << system.calculate_norm(*adjresid_fwd_hack,2,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 3): " << system.calculate_norm(*adjresid_fwd_hack,3,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 4): " << system.calculate_norm(*adjresid_fwd_hack,4,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 5): " << system.calculate_norm(*adjresid_fwd_hack,5,L2) << std::endl;
            */
            //std::cout << "************************ system.matrix ***********************" << std::endl;
            //system.matrix->print();

            std::cout << "\n------------ herp derp ------------" << std::endl;

            // The cell wise breakdown
            ErrorVector cell_wise_error;
            cell_wise_error.resize((system.rhs)->size());
            for(unsigned int i = 0; i < (system.rhs)->size() ; i++)
            {
                if(i < system.get_mesh().n_elem())
                    cell_wise_error[i] = fabs(-0.5*((system.rhs)->el(i) * dual_solution(i))
                                              + system.get_MHF_psiLF(i) - system.get_MLF_psiLF(i));
                else
                    cell_wise_error[i] = fabs(-0.5*((system.rhs)->el(i) * dual_solution(i)));

                /*csv from 'save data' from gmv output gives a few values at each node point (value
                for every element that shares that node), yet paraview display only seems to show one
                of them -> the value in an element is given at each of the nodes that it has, hence the
                repetition; what is displayed in paraview is each element's value; even though MHF_psiLF
                and MLF_psiLF are stored by element this seems to give elemental contributions that
                agree with if we had taken the superadj-residual dot product by integrating over elements*/

                /*at higher mesh resolutions and lower k, weird-looking artifacts start to appear and
                it no longer agrees with output from manual integration of superadj-residual...*/
            }
            // Plot it
            std::ostringstream error_gmv;
            error_gmv << "error.gmv";
            cell_wise_error.plot_error(error_gmv.str(), equation_systems.get_mesh());

            //alternate element-wise breakdown, outputed as values matched to element centroids; for matlab plotz
            primal_solution.swap(dual_solution);
            system.postprocess(1);
            primal_solution.swap(dual_solution);
            system.postprocess(2);
            std::cout << "\n\n -0.5*M'_HF(psiLF)(superadj): " << std::setprecision(17) << system.get_half_adj_weighted_resid() << "\n";
            primal_solution.swap(dual_solution);

            std::string write_error_here = infileForMesh("error_est_output_file", "error_est_breakdown.dat");
            std::ofstream output(write_error_here);
            for(unsigned int i = 0 ; i < system.get_mesh().n_elem(); i++) {
                Point elem_cent = system.get_mesh().elem(i)->centroid();
                if(output.is_open()) {
                    output << elem_cent(0) << " " << elem_cent(1) << " "
                           << fabs(system.get_half_adj_weighted_resid(i) + system.get_MHF_psiLF(i) - system.get_MLF_psiLF(i)) << "\n";
                }
            }
            output.close();

        } // End if at max adaptive steps

#ifdef LIBMESH_HAVE_EXODUS_API
        // Write out this timestep if we're requested to
        if ((t_step+1)%write_interval == 0)
        {
            std::ostringstream file_name;
            /*
                // We write the file in the ExodusII format.
                file_name << "out_"
                          << std::setw(3)
                          << std::setfill('0')
                          << std::right
                          << t_step+1
                          << ".e";
            			//this should write out the primal which should be the same as what's read in...
            			ExodusII_IO(mesh).write_timestep(file_name.str(),
            							                        equation_systems,
            							                        1, //number of time steps written to file
            							                        system.time);
            */
        }
#endif // #ifdef LIBMESH_HAVE_EXODUS_API
    }

    // All done.
    return 0;

} //end main
예제 #3
0
int main(int argc, char** argv)
{
  // Initialize libMesh.
  LibMeshInit init (argc, argv);

  // Adaptive constraint calculations for fine Hermite elements seems
  // to require half-decent precision
#ifdef LIBMESH_DEFAULT_SINGLE_PRECISION
  libmesh_example_assert(false, "double precision");
#endif

  // This example requires Adaptive Mesh Refinement support
#ifndef LIBMESH_ENABLE_AMR
  libmesh_example_assert(false, "--enable-amr");
#else

  // This example requires second derivative calculation support
#ifndef LIBMESH_ENABLE_SECOND_DERIVATIVES
  libmesh_example_assert(false, "--enable-second");
#else

  // Parse the input file
  GetPot input_file("adaptivity_ex4.in");

  // Read in parameters from the input file
  const unsigned int max_r_level = input_file("max_r_level", 10);
  const unsigned int max_r_steps = input_file("max_r_steps", 4);
  const std::string approx_type  = input_file("approx_type",
                                              "HERMITE");
  const unsigned int uniform_refine =
                  input_file("uniform_refine", 0);
  const Real refine_percentage =
                  input_file("refine_percentage", 0.5);
  const Real coarsen_percentage =
                  input_file("coarsen_percentage", 0.5);
  const unsigned int dim =
                  input_file("dimension", 2);
  const unsigned int max_linear_iterations =
                  input_file("max_linear_iterations", 10000);

  // Skip higher-dimensional examples on a lower-dimensional libMesh build
  libmesh_example_assert(dim <= LIBMESH_DIM, "2D/3D support");
  
  // We have only defined 2 and 3 dimensional problems
  libmesh_assert (dim == 2 || dim == 3);

  // Currently only the Hermite cubics give a 3D C^1 basis
  libmesh_assert (dim == 2 || approx_type == "HERMITE");

  // Create a mesh.
  Mesh mesh;
  
  // Output file for plotting the error 
  std::string output_file = "";

  if (dim == 2)
    output_file += "2D_";
  else if (dim == 3)
    output_file += "3D_";

  if (approx_type == "HERMITE")
    output_file += "hermite_";
  else if (approx_type == "SECOND")
    output_file += "reducedclough_";
  else
    output_file += "clough_";

  if (uniform_refine == 0)
    output_file += "adaptive";
  else
    output_file += "uniform";

  std::string exd_file = output_file;
  exd_file += ".e";
  output_file += ".m";

  std::ofstream out (output_file.c_str());
  out << "% dofs     L2-error     H1-error      H2-error\n"
      << "e = [\n";
  
  // Set up the dimension-dependent coarse mesh and solution
  // We build more than one cell so as to avoid bugs on fewer than 
  // 4 processors in 2D or 8 in 3D.
  if (dim == 2)
    {
      MeshTools::Generation::build_square(mesh, 2, 2);
      exact_solution = &exact_2D_solution;
      exact_derivative = &exact_2D_derivative;
      exact_hessian = &exact_2D_hessian;
      forcing_function = &forcing_function_2D;
    }
  else if (dim == 3)
    {
      MeshTools::Generation::build_cube(mesh, 2, 2, 2);
      exact_solution = &exact_3D_solution;
      exact_derivative = &exact_3D_derivative;
      exact_hessian = &exact_3D_hessian;
      forcing_function = &forcing_function_3D;
    }

  // Convert the mesh to second order: necessary for computing with
  // Clough-Tocher elements, useful for getting slightly less 
  // broken visualization output with Hermite elements
  mesh.all_second_order();

  // Convert it to triangles if necessary
  if (approx_type != "HERMITE")
    MeshTools::Modification::all_tri(mesh);

  // Mesh Refinement object
  MeshRefinement mesh_refinement(mesh);
  mesh_refinement.refine_fraction() = refine_percentage;
  mesh_refinement.coarsen_fraction() = coarsen_percentage;
  mesh_refinement.max_h_level() = max_r_level;

  // Create an equation systems object.
  EquationSystems equation_systems (mesh);

  // Declare the system and its variables.
  // Create a system named "Biharmonic"
  LinearImplicitSystem& system =
    equation_systems.add_system<LinearImplicitSystem> ("Biharmonic");

  // Adds the variable "u" to "Biharmonic".  "u"
  // will be approximated using Hermite tensor product squares
  // or (possibly reduced) cubic Clough-Tocher triangles
  if (approx_type == "HERMITE")
    system.add_variable("u", THIRD, HERMITE);
  else if (approx_type == "SECOND")
    system.add_variable("u", SECOND, CLOUGH);
  else if (approx_type == "CLOUGH")
    system.add_variable("u", THIRD, CLOUGH);
  else
    libmesh_error();

  // Give the system a pointer to the matrix assembly
  // function.
  system.attach_assemble_function (assemble_biharmonic);
      
  // Initialize the data structures for the equation system.
  equation_systems.init();

  // Set linear solver max iterations
  equation_systems.parameters.set<unsigned int>
    ("linear solver maximum iterations") = max_linear_iterations;

  // Linear solver tolerance.
  equation_systems.parameters.set<Real>
    ("linear solver tolerance") = TOLERANCE * TOLERANCE;
      
  // Prints information about the system to the screen.
  equation_systems.print_info();

  // Construct ExactSolution object and attach function to compute exact solution
  ExactSolution exact_sol(equation_systems);
  exact_sol.attach_exact_value(exact_solution);
  exact_sol.attach_exact_deriv(exact_derivative);
  exact_sol.attach_exact_hessian(exact_hessian);

  // Construct zero solution object, useful for computing solution norms
  // Attaching "zero_solution" functions is unnecessary
  ExactSolution zero_sol(equation_systems);

  // A refinement loop.
  for (unsigned int r_step=0; r_step<max_r_steps; r_step++)
    {
      mesh.print_info();
      equation_systems.print_info();

      std::cout << "Beginning Solve " << r_step << std::endl;
      
      // Solve the system "Biharmonic", just like example 2.
      system.solve();

      std::cout << "Linear solver converged at step: "
                << system.n_linear_iterations()
                << ", final residual: "
                << system.final_linear_residual()
                << std::endl;

      // Compute the error.
      exact_sol.compute_error("Biharmonic", "u");
      // Compute the norm.
      zero_sol.compute_error("Biharmonic", "u");

      // Print out the error values
      std::cout << "L2-Norm is: "
                << zero_sol.l2_error("Biharmonic", "u")
                << std::endl;
      std::cout << "H1-Norm is: "
                << zero_sol.h1_error("Biharmonic", "u")
                << std::endl;
      std::cout << "H2-Norm is: "
                << zero_sol.h2_error("Biharmonic", "u")
                << std::endl
                << std::endl;
      std::cout << "L2-Error is: "
                << exact_sol.l2_error("Biharmonic", "u")
                << std::endl;
      std::cout << "H1-Error is: "
                << exact_sol.h1_error("Biharmonic", "u")
                << std::endl;
      std::cout << "H2-Error is: "
                << exact_sol.h2_error("Biharmonic", "u")
                << std::endl
                << std::endl;

      // Print to output file
      out << equation_systems.n_active_dofs() << " "
          << exact_sol.l2_error("Biharmonic", "u") << " "
          << exact_sol.h1_error("Biharmonic", "u") << " "
          << exact_sol.h2_error("Biharmonic", "u") << std::endl;

      // Possibly refine the mesh
      if (r_step+1 != max_r_steps)
        {
          std::cout << "  Refining the mesh..." << std::endl;

          if (uniform_refine == 0)
            {
              ErrorVector error;
              LaplacianErrorEstimator error_estimator;

              error_estimator.estimate_error(system, error);
              mesh_refinement.flag_elements_by_elem_fraction (error);

              std::cout << "Mean Error: " << error.mean() <<
                              std::endl;
              std::cout << "Error Variance: " << error.variance() <<
                              std::endl;

              mesh_refinement.refine_and_coarsen_elements();
            }
          else
            {
              mesh_refinement.uniformly_refine(1);
            }
              
          // This call reinitializes the \p EquationSystems object for
          // the newly refined mesh.  One of the steps in the
          // reinitialization is projecting the \p solution,
          // \p old_solution, etc... vectors from the old mesh to
          // the current one.
          equation_systems.reinit ();
        }
    }            
  
#ifdef LIBMESH_HAVE_EXODUS_API
  // Write out the solution
  // After solving the system write the solution
  // to a ExodusII-formatted plot file.
  ExodusII_IO (mesh).write_equation_systems (exd_file,
                                       equation_systems);
#endif // #ifdef LIBMESH_HAVE_EXODUS_API

  // Close up the output file.
  out << "];\n"
      << "hold on\n"
      << "loglog(e(:,1), e(:,2), 'bo-');\n"
      << "loglog(e(:,1), e(:,3), 'ro-');\n"
      << "loglog(e(:,1), e(:,4), 'go-');\n"
      << "xlabel('log(dofs)');\n"
      << "ylabel('log(error)');\n"
      << "title('C1 " << approx_type << " elements');\n"
      << "legend('L2-error', 'H1-error', 'H2-error');\n";
  
  // All done.  
  return 0;
#endif // #ifndef LIBMESH_ENABLE_SECOND_DERIVATIVES
#endif // #ifndef LIBMESH_ENABLE_AMR
}
예제 #4
0
// The main program.
int main (int argc, char** argv)
{
  // Initialize libMesh.
  LibMeshInit init (argc, argv);

  // This example fails without at least double precision FP
#ifdef LIBMESH_DEFAULT_SINGLE_PRECISION
  libmesh_example_assert(false, "--disable-singleprecision");
#endif

#ifndef LIBMESH_ENABLE_AMR
  libmesh_example_assert(false, "--enable-amr");
#else

  // Trilinos solver NaNs by default on the zero pressure block.
  // We'll skip this example for now.
  if (libMesh::default_solver_package() == TRILINOS_SOLVERS)
    {
      std::cout << "We skip fem_system_ex1 when using the Trilinos solvers.\n"
                << std::endl;
      return 0;
    }

  // Parse the input file
  GetPot infile("fem_system_ex1.in");

  // Read in parameters from the input file
  const Real global_tolerance          = infile("global_tolerance", 0.);
  const unsigned int nelem_target      = infile("n_elements", 400);
  const bool transient                 = infile("transient", true);
  const Real deltat                    = infile("deltat", 0.005);
  unsigned int n_timesteps             = infile("n_timesteps", 20);
  const unsigned int write_interval    = infile("write_interval", 5);
  const unsigned int coarsegridsize    = infile("coarsegridsize", 1);
  const unsigned int coarserefinements = infile("coarserefinements", 0);
  const unsigned int max_adaptivesteps = infile("max_adaptivesteps", 10);
  const unsigned int dim               = infile("dimension", 2);

  // Skip higher-dimensional examples on a lower-dimensional libMesh build
  libmesh_example_assert(dim <= LIBMESH_DIM, "2D/3D support");
  
  // We have only defined 2 and 3 dimensional problems
  libmesh_assert (dim == 2 || dim == 3);

  // Create a mesh.
  Mesh mesh;
  
  // And an object to refine it
  MeshRefinement mesh_refinement(mesh);
  mesh_refinement.coarsen_by_parents() = true;
  mesh_refinement.absolute_global_tolerance() = global_tolerance;
  mesh_refinement.nelem_target() = nelem_target;
  mesh_refinement.refine_fraction() = 0.3;
  mesh_refinement.coarsen_fraction() = 0.3;
  mesh_refinement.coarsen_threshold() = 0.1;

  // Use the MeshTools::Generation mesh generator to create a uniform
  // grid on the square [-1,1]^D.  We instruct the mesh generator
  // to build a mesh of 8x8 \p Quad9 elements in 2D, or \p Hex27
  // elements in 3D.  Building these higher-order elements allows
  // us to use higher-order approximation, as in example 3.
  if (dim == 2)
    MeshTools::Generation::build_square (mesh,
                                         coarsegridsize,
                                         coarsegridsize,
                                         0., 1.,
                                         0., 1.,
                                         QUAD9);
  else if (dim == 3)
    MeshTools::Generation::build_cube (mesh,
                                       coarsegridsize,
                                       coarsegridsize,
                                       coarsegridsize,
                                       0., 1.,
                                       0., 1.,
                                       0., 1.,
                                       HEX27);

  mesh_refinement.uniformly_refine(coarserefinements);

  // Print information about the mesh to the screen.
  mesh.print_info();

  // Create an equation systems object.
  EquationSystems equation_systems (mesh);

  // Declare the system "Navier-Stokes" and its variables.
  NavierSystem & system = 
    equation_systems.add_system<NavierSystem> ("Navier-Stokes");

  // Solve this as a time-dependent or steady system
  if (transient)
    system.time_solver =
      AutoPtr<TimeSolver>(new EulerSolver(system));
  else
    {
      system.time_solver =
        AutoPtr<TimeSolver>(new SteadySolver(system));
      libmesh_assert_equal_to (n_timesteps, 1);
    }

  // Initialize the system
  equation_systems.init ();

  // Set the time stepping options
  system.deltat = deltat;

  // And the nonlinear solver options
  DiffSolver &solver = *(system.time_solver->diff_solver().get());
  solver.quiet = infile("solver_quiet", true);
  solver.verbose = !solver.quiet;
  solver.max_nonlinear_iterations =
    infile("max_nonlinear_iterations", 15);
  solver.relative_step_tolerance =
    infile("relative_step_tolerance", 1.e-3);
  solver.relative_residual_tolerance =
    infile("relative_residual_tolerance", 0.0);
  solver.absolute_residual_tolerance =
    infile("absolute_residual_tolerance", 0.0);
    
  // And the linear solver options
  solver.max_linear_iterations =
    infile("max_linear_iterations", 50000);
  solver.initial_linear_tolerance =
    infile("initial_linear_tolerance", 1.e-3);

  // Print information about the system to the screen.
  equation_systems.print_info();

  // Now we begin the timestep loop to compute the time-accurate
  // solution of the equations.
  for (unsigned int t_step=0; t_step != n_timesteps; ++t_step)
    {
      // A pretty update message
      std::cout << "\n\nSolving time step " << t_step << ", time = "
                << system.time << std::endl;

      // Adaptively solve the timestep
      unsigned int a_step = 0;
      for (; a_step != max_adaptivesteps; ++a_step)
        {
          system.solve();

          system.postprocess();

          ErrorVector error;

          AutoPtr<ErrorEstimator> error_estimator;

          // To solve to a tolerance in this problem we
          // need a better estimator than Kelly
          if (global_tolerance != 0.)
            {
              // We can't adapt to both a tolerance and a mesh
              // size at once
              libmesh_assert_equal_to (nelem_target, 0);

              UniformRefinementEstimator *u =
                new UniformRefinementEstimator;

              // The lid-driven cavity problem isn't in H1, so
              // lets estimate L2 error
              u->error_norm = L2;

              error_estimator.reset(u);
            }
          else
            {
              // If we aren't adapting to a tolerance we need a
              // target mesh size
              libmesh_assert_greater (nelem_target, 0);

              // Kelly is a lousy estimator to use for a problem
              // not in H1 - if we were doing more than a few
              // timesteps we'd need to turn off or limit the
              // maximum level of our adaptivity eventually
              error_estimator.reset(new KellyErrorEstimator);
            }

          // Calculate error based on u and v (and w?) but not p
	  std::vector<Real> weights(2,1.0);  // u, v
          if (dim == 3)
            weights.push_back(1.0);          // w
          weights.push_back(0.0);            // p
	  // Keep the same default norm type.
	  std::vector<FEMNormType>
	    norms(1, error_estimator->error_norm.type(0));
	  error_estimator->error_norm = SystemNorm(norms, weights);

          error_estimator->estimate_error(system, error);

          // Print out status at each adaptive step.
          Real global_error = error.l2_norm();
          std::cout << "Adaptive step " << a_step << ": " << std::endl;
          if (global_tolerance != 0.)
            std::cout << "Global_error = " << global_error 
                      << std::endl;
          if (global_tolerance != 0.)
            std::cout << "Worst element error = " << error.maximum()
                      << ", mean = " << error.mean() << std::endl;

          if (global_tolerance != 0.)
            {
              // If we've reached our desired tolerance, we
              // don't need any more adaptive steps
              if (global_error < global_tolerance)
                break;
              mesh_refinement.flag_elements_by_error_tolerance(error);
            }
          else
            {
              // If flag_elements_by_nelem_target returns true, this
              // should be our last adaptive step.
              if (mesh_refinement.flag_elements_by_nelem_target(error))
                {
                  mesh_refinement.refine_and_coarsen_elements();
                  equation_systems.reinit();
                  a_step = max_adaptivesteps;
                  break;
                }
            }

          // Carry out the adaptive mesh refinement/coarsening
          mesh_refinement.refine_and_coarsen_elements();
          equation_systems.reinit();

          std::cout << "Refined mesh to "
                    << mesh.n_active_elem()
                    << " active elements and "
                    << equation_systems.n_active_dofs()
                    << " active dofs." << std::endl;
        }
      // Do one last solve if necessary
      if (a_step == max_adaptivesteps)
        {
          system.solve();

          system.postprocess();
        }

      // Advance to the next timestep in a transient problem
      system.time_solver->advance_timestep();

#ifdef LIBMESH_HAVE_EXODUS_API
      // Write out this timestep if we're requested to
      if ((t_step+1)%write_interval == 0)
        {
          std::ostringstream file_name;

          // We write the file in the ExodusII format.
          file_name << "out_"
                    << std::setw(3)
                    << std::setfill('0')
                    << std::right
                    << t_step+1
                    << ".e";

          ExodusII_IO(mesh).write_timestep(file_name.str(),
					   equation_systems, 
					   1, /* This number indicates how many time steps 
						 are being written to the file */
					   system.time);
        }
#endif // #ifdef LIBMESH_HAVE_EXODUS_API
    }
#endif // #ifndef LIBMESH_ENABLE_AMR
  
  // All done.  
  return 0;
}
예제 #5
0
// The main program.
int main (int argc, char ** argv)
{
  // Initialize libMesh.
  LibMeshInit init (argc, argv);

  // This example requires a linear solver package.
  libmesh_example_requires(libMesh::default_solver_package() != INVALID_SOLVER_PACKAGE,
                           "--enable-petsc, --enable-trilinos, or --enable-eigen");

#ifndef LIBMESH_ENABLE_AMR
  libmesh_example_requires(false, "--enable-amr");
#else

  // This doesn't converge with Eigen BICGSTAB for some reason...
  libmesh_example_requires(libMesh::default_solver_package() != EIGEN_SOLVERS, "--enable-petsc");

  // This doesn't converge without at least double precision
  libmesh_example_requires(sizeof(Real) > 4, "--disable-singleprecision");

  // Parse the input file
  GetPot infile("fem_system_ex4.in");

  // Read in parameters from the input file
  const Real global_tolerance          = infile("global_tolerance", 0.);
  const unsigned int nelem_target      = infile("n_elements", 400);
  const Real deltat                    = infile("deltat", 0.005);
  const unsigned int coarsegridsize    = infile("coarsegridsize", 20);
  const unsigned int coarserefinements = infile("coarserefinements", 0);
  const unsigned int max_adaptivesteps = infile("max_adaptivesteps", 10);
  const unsigned int dim               = infile("dimension", 2);

  // Skip higher-dimensional examples on a lower-dimensional libMesh build
  libmesh_example_requires(dim <= LIBMESH_DIM, "2D/3D support");

  // We have only defined 2 and 3 dimensional problems
  libmesh_assert (dim == 2 || dim == 3);

  // Create a mesh, with dimension to be overridden later, distributed
  // across the default MPI communicator.
  Mesh mesh(init.comm());

  // And an object to refine it
  MeshRefinement mesh_refinement(mesh);
  mesh_refinement.coarsen_by_parents() = true;
  mesh_refinement.absolute_global_tolerance() = global_tolerance;
  mesh_refinement.nelem_target() = nelem_target;
  mesh_refinement.refine_fraction() = 0.3;
  mesh_refinement.coarsen_fraction() = 0.3;
  mesh_refinement.coarsen_threshold() = 0.1;

  // Use the MeshTools::Generation mesh generator to create a uniform
  // grid on the square or cube.  We crop the domain at y=2/3 to allow
  // for a homogeneous Neumann BC in our benchmark there.
  boundary_id_type bcid = 3; // +y in 3D
  if (dim == 2)
    {
      MeshTools::Generation::build_square
        (mesh,
         coarsegridsize,
         coarsegridsize*2/3, // int arithmetic best we can do here
         0., 1.,
         0., 2./3.,
         QUAD9);
      bcid = 2; // +y in 2D
    }
  else if (dim == 3)
    {
      MeshTools::Generation::build_cube
        (mesh,
         coarsegridsize,
         coarsegridsize*2/3,
         coarsegridsize,
         0., 1.,
         0., 2./3.,
         0., 1.,
         HEX27);
    }

  {
    // Add boundary elements corresponding to the +y boundary of our
    // volume mesh
    std::set<boundary_id_type> bcids;
    bcids.insert(bcid);
    mesh.get_boundary_info().add_elements(bcids, mesh);
    mesh.prepare_for_use();
  }

  // To work around ExodusII file format limitations, we need elements
  // of different dimensionality to belong to different subdomains.
  // Our interior elements defaulted to subdomain id 0, so we'll set
  // boundary elements to subdomain 1.
  for (auto & elem : mesh.element_ptr_range())
    if (elem->dim() < dim)
      elem->subdomain_id() = 1;

  mesh_refinement.uniformly_refine(coarserefinements);

  // Print information about the mesh to the screen.
  mesh.print_info();

  // Create an equation systems object.
  EquationSystems equation_systems (mesh);

  // Declare the system "Heat" and its variables.
  HeatSystem & system =
    equation_systems.add_system<HeatSystem> ("Heat");

  // Solve this as a steady system
  system.time_solver = libmesh_make_unique<SteadySolver>(system);

  // Initialize the system
  equation_systems.init ();

  // Set the time stepping options
  system.deltat = deltat;

  // And the nonlinear solver options
  DiffSolver & solver = *(system.time_solver->diff_solver().get());
  solver.quiet = infile("solver_quiet", true);
  solver.verbose = !solver.quiet;
  solver.max_nonlinear_iterations = infile("max_nonlinear_iterations", 15);
  solver.relative_step_tolerance = infile("relative_step_tolerance", 1.e-3);
  solver.relative_residual_tolerance = infile("relative_residual_tolerance", 0.0);
  solver.absolute_residual_tolerance = infile("absolute_residual_tolerance", 0.0);

  // And the linear solver options
  solver.max_linear_iterations = infile("max_linear_iterations", 50000);
  solver.initial_linear_tolerance = infile("initial_linear_tolerance", 1.e-3);

  // Print information about the system to the screen.
  equation_systems.print_info();

  // Adaptively solve the steady solution
  unsigned int a_step = 0;
  for (; a_step != max_adaptivesteps; ++a_step)
    {
      system.solve();

      system.postprocess();

      ErrorVector error;

      std::unique_ptr<ErrorEstimator> error_estimator;

      // To solve to a tolerance in this problem we
      // need a better estimator than Kelly
      if (global_tolerance != 0.)
        {
          // We can't adapt to both a tolerance and a mesh
          // size at once
          libmesh_assert_equal_to (nelem_target, 0);

          UniformRefinementEstimator * u =
            new UniformRefinementEstimator;

          // The lid-driven cavity problem isn't in H1, so
          // lets estimate L2 error
          u->error_norm = L2;

          error_estimator.reset(u);
        }
      else
        {
          // If we aren't adapting to a tolerance we need a
          // target mesh size
          libmesh_assert_greater (nelem_target, 0);

          // Kelly is a lousy estimator to use for a problem
          // not in H1 - if we were doing more than a few
          // timesteps we'd need to turn off or limit the
          // maximum level of our adaptivity eventually
          error_estimator.reset(new KellyErrorEstimator);
        }

      error_estimator->estimate_error(system, error);

      // Print out status at each adaptive step.
      Real global_error = error.l2_norm();
      libMesh::out << "Adaptive step "
                   << a_step
                   << ": "
                   << std::endl;

      if (global_tolerance != 0.)
        libMesh::out << "Global_error = "
                     << global_error
                     << std::endl;

      if (global_tolerance != 0.)
        libMesh::out << "Worst element error = "
                     << error.maximum()
                     << ", mean = "
                     << error.mean()
                     << std::endl;

      if (global_tolerance != 0.)
        {
          // If we've reached our desired tolerance, we
          // don't need any more adaptive steps
          if (global_error < global_tolerance)
            break;
          mesh_refinement.flag_elements_by_error_tolerance(error);
        }
      else
        {
          // If flag_elements_by_nelem_target returns true, this
          // should be our last adaptive step.
          if (mesh_refinement.flag_elements_by_nelem_target(error))
            {
              mesh_refinement.refine_and_coarsen_elements();
              equation_systems.reinit();
              a_step = max_adaptivesteps;
              break;
            }
        }

      // Carry out the adaptive mesh refinement/coarsening
      mesh_refinement.refine_and_coarsen_elements();
      equation_systems.reinit();

      libMesh::out << "Refined mesh to "
                   << mesh.n_active_elem()
                   << " active elements and "
                   << equation_systems.n_active_dofs()
                   << " active dofs."
                   << std::endl;
    }
  // Do one last solve if necessary
  if (a_step == max_adaptivesteps)
    {
      system.solve();

      system.postprocess();
    }


#ifdef LIBMESH_HAVE_EXODUS_API
  ExodusII_IO(mesh).write_equation_systems
    ("out.e", equation_systems);
#endif // #ifdef LIBMESH_HAVE_EXODUS_API

#ifdef LIBMESH_HAVE_GMV
  GMVIO(mesh).write_equation_systems
    ("out.gmv", equation_systems);
#endif // #ifdef LIBMESH_HAVE_GMV

#ifdef LIBMESH_HAVE_FPARSER
  // Check that we got close to the analytic solution
  ExactSolution exact_sol(equation_systems);
  const std::string exact_str = (dim == 2) ?
    "sin(pi*x)*sin(pi*y)" : "sin(pi*x)*sin(pi*y)*sin(pi*z)";
  ParsedFunction<Number> exact_func(exact_str);
  exact_sol.attach_exact_value(0, &exact_func);
  exact_sol.compute_error("Heat", "T");

  Number err = exact_sol.l2_error("Heat", "T");

  // Print out the error value
  libMesh::out << "L2-Error is: " << err << std::endl;

  libmesh_assert_less(libmesh_real(err), 2e-3);

#endif // #ifdef LIBMESH_HAVE_FPARSER

#endif // #ifndef LIBMESH_ENABLE_AMR

  // All done.
  return 0;
}
예제 #6
0
int main(int argc, char** argv){

	//initialize libMesh
	LibMeshInit init(argc, argv);
	
	//parameters
	GetPot infile("fem_system_params.in");
  const Real global_tolerance          = infile("global_tolerance", 0.);
  const unsigned int nelem_target      = infile("n_elements", 400);
  const bool transient                 = infile("transient", true);
  const Real deltat                    = infile("deltat", 0.005);
  unsigned int n_timesteps             = infile("n_timesteps", 1);
  //const unsigned int coarsegridsize    = infile("coarsegridsize", 1);
  const unsigned int coarserefinements = infile("coarserefinements", 0);
  const unsigned int max_adaptivesteps = infile("max_adaptivesteps", 10);
  const unsigned int dim               = 2;
  
#ifdef LIBMESH_HAVE_EXODUS_API
  const unsigned int write_interval    = infile("write_interval", 5);
#endif

  // Create a mesh, with dimension to be overridden later, distributed
  // across the default MPI communicator.
  Mesh mesh(init.comm());
  GetPot infileForMesh("diff_convdiff_inv.in");
  std::string find_mesh_here = infileForMesh("divided_mesh","meep.exo");
	mesh.read(find_mesh_here);

  // And an object to refine it
  MeshRefinement mesh_refinement(mesh);
  mesh_refinement.coarsen_by_parents() = true;
  mesh_refinement.absolute_global_tolerance() = global_tolerance;
  mesh_refinement.nelem_target() = nelem_target;
  mesh_refinement.refine_fraction() = 0.3;
  mesh_refinement.coarsen_fraction() = 0.3;
  mesh_refinement.coarsen_threshold() = 0.1;

  mesh_refinement.uniformly_refine(coarserefinements);
  
  // Print information about the mesh to the screen.
  mesh.print_info();

  // Create an equation systems object.
  EquationSystems equation_systems (mesh);
  
  //name system
  Diff_ConvDiff_InvSys & system = 
  	equation_systems.add_system<Diff_ConvDiff_InvSys>("Diff_ConvDiff_InvSys");
  
  //steady-state problem	
 	system.time_solver =
    AutoPtr<TimeSolver>(new SteadySolver(system));
  libmesh_assert_equal_to (n_timesteps, 1);
  
  std::string linearizeHere = "invHF.xda";
  equation_systems.read(linearizeHere, READ,
		EquationSystems::READ_HEADER |
		EquationSystems::READ_DATA |
		EquationSystems::READ_ADDITIONAL_DATA);
	std::cout << "\n READING IN INITIAL GUESS" << std::endl;
  
  // Initialize the system
  //equation_systems.init ();

  // Set the time stepping options
  system.deltat = deltat; //this is ignored for SteadySolver...right?

  // And the nonlinear solver options
  NewtonSolver *solver = new NewtonSolver(system); 
  system.time_solver->diff_solver() = AutoPtr<DiffSolver>(solver); 
  solver->quiet = infile("solver_quiet", true);
  solver->verbose = !solver->quiet;
  solver->max_nonlinear_iterations =
    infile("max_nonlinear_iterations", 15);
  solver->relative_step_tolerance =
    infile("relative_step_tolerance", 1.e-3);
  solver->relative_residual_tolerance =
    infile("relative_residual_tolerance", 0.0);
  solver->absolute_residual_tolerance =
    infile("absolute_residual_tolerance", 0.0);

  // And the linear solver options
  solver->max_linear_iterations =
    infile("max_linear_iterations", 50000);
  solver->initial_linear_tolerance =
    infile("initial_linear_tolerance", 1.e-3);

  // Print information about the system to the screen.
  equation_systems.print_info();
  
  // Now we begin the timestep loop to compute the time-accurate
  // solution of the equations...not that this is transient, but eh, why not...
	for (unsigned int t_step=0; t_step != n_timesteps; ++t_step){
    // A pretty update message
    std::cout << "\n\nSolving time step " << t_step << ", time = "
              << system.time << std::endl;

    // Adaptively solve the timestep
    unsigned int a_step = 0;
    for (; a_step != max_adaptivesteps; ++a_step)
      {
        system.solve();
        system.postprocess();
        ErrorVector error;
        AutoPtr<ErrorEstimator> error_estimator;

        // To solve to a tolerance in this problem we
        // need a better estimator than Kelly
        if (global_tolerance != 0.)
          {
            // We can't adapt to both a tolerance and a mesh
            // size at once
            libmesh_assert_equal_to (nelem_target, 0);

            UniformRefinementEstimator *u =
              new UniformRefinementEstimator;

            // The lid-driven cavity problem isn't in H1, so
            // lets estimate L2 error
            u->error_norm = L2;

            error_estimator.reset(u);
          }
        else
          {
            // If we aren't adapting to a tolerance we need a
            // target mesh size
            libmesh_assert_greater (nelem_target, 0);

            // Kelly is a lousy estimator to use for a problem
            // not in H1 - if we were doing more than a few
            // timesteps we'd need to turn off or limit the
            // maximum level of our adaptivity eventually
            error_estimator.reset(new KellyErrorEstimator);
          }

        // Calculate error
        std::vector<Real> weights(3,1.0); 

        // Keep the same default norm type.
        std::vector<FEMNormType>
          norms(1, error_estimator->error_norm.type(0));
        error_estimator->error_norm = SystemNorm(norms, weights);

        error_estimator->estimate_error(system, error);

        // Print out status at each adaptive step.
        Real global_error = error.l2_norm();
        std::cout << "Adaptive step " << a_step << ": " << std::endl;
        if (global_tolerance != 0.)
          std::cout << "Global_error = " << global_error
                    << std::endl;
        if (global_tolerance != 0.)
          std::cout << "Worst element error = " << error.maximum()
                    << ", mean = " << error.mean() << std::endl;

        if (global_tolerance != 0.)
          {
            // If we've reached our desired tolerance, we
            // don't need any more adaptive steps
            if (global_error < global_tolerance)
              break;
            mesh_refinement.flag_elements_by_error_tolerance(error);
          }
        else
          {
            // If flag_elements_by_nelem_target returns true, this
            // should be our last adaptive step.
            if (mesh_refinement.flag_elements_by_nelem_target(error))
              {
                mesh_refinement.refine_and_coarsen_elements();
                equation_systems.reinit();
                a_step = max_adaptivesteps;
                break;
              }
          }

        // Carry out the adaptive mesh refinement/coarsening
        mesh_refinement.refine_and_coarsen_elements();
        equation_systems.reinit();

        std::cout << "Refined mesh to "
                  << mesh.n_active_elem()
                  << " active elements and "
                  << equation_systems.n_active_dofs()
                  << " active dofs." << std::endl;
      }
    // Do one last solve if necessary
    if (a_step == max_adaptivesteps)
      {
        using std::chrono::duration_cast;
    		using std::chrono::milliseconds;
    		typedef std::chrono::high_resolution_clock clock;
				
				auto start = clock::now();
        system.solve();
        auto end = clock::now();
        std::cout << "\n  Solve took " << duration_cast<milliseconds>(end-start).count() << " ms\n" << std::endl;

        system.postprocess();
        
        Number QoI_computed = system.get_QoI_value("computed", 0);
        std::cout<< "Computed QoI is " << std::setprecision(17) << QoI_computed << std::endl;
      }

    // Advance to the next timestep in a transient problem
    system.time_solver->advance_timestep();

#ifdef LIBMESH_HAVE_EXODUS_API
    // Write out this timestep if we're requested to
    if ((t_step+1)%write_interval == 0)
      {
        std::ostringstream file_name;

        // We write the file in the ExodusII format.
        file_name << "out_"
                  << std::setw(3)
                  << std::setfill('0')
                  << std::right
                  << t_step+1
                  << ".e";

        ExodusII_IO(mesh).write_timestep(file_name.str(),
                                         equation_systems,
                                         1, /* This number indicates how many time steps
                                               are being written to the file */
                                         system.time);
                                         
       equation_systems.write("invHF.xda", WRITE, EquationSystems::WRITE_DATA | 
               EquationSystems::WRITE_ADDITIONAL_DATA);

      }
#endif // #ifdef LIBMESH_HAVE_EXODUS_API
  }
  
  // All done.
  return 0;
  
} //end main