예제 #1
0
int main(int argc, char* argv[])
{
  bool success = true;
  HermesCommonApi.set_integral_param_value(numThreads, 1);

  // Load the mesh.
  MeshSharedPtr mesh(new Mesh);
  Hermes::Hermes2D::MeshReaderH2DXML mloader;
  mloader.load("domain.xml", mesh);

  mesh->refine_element_id(0);
  mesh->refine_element_id(2, 1);
  mesh->refine_all_elements();
  mesh->refine_all_elements();
  mesh->refine_all_elements();

  // Initialize essential boundary conditions.
  Hermes::Hermes2D::DefaultEssentialBCConst<double> bc_essential_r("Bdy", 0.);
  Hermes::Hermes2D::DefaultEssentialBCConst<complex> bc_essential_c("Bdy", complex(.132, -.12));
  Hermes::Hermes2D::EssentialBCs<double> bcs_r(&bc_essential_r);
  Hermes::Hermes2D::EssentialBCs<complex> bcs_c(&bc_essential_c);

  // Initialize space.
  SpaceSharedPtr<double> space_r( new Hermes::Hermes2D::H1Space<double>(mesh, &bcs_r, 2));
  SpaceSharedPtr<double> space_l2( new Hermes::Hermes2D::L2Space<double>(mesh, 0));
  SpaceSharedPtr<complex> space_c( new Hermes::Hermes2D::H1Space<complex>(mesh, &bcs_c, 2));

  // Initialize the weak formulation.
  WeakFormsH1::DefaultWeakFormPoissonLinear<double> wf_r(HERMES_ANY, nullptr);
  WeakFormsH1::DefaultWeakFormPoissonLinear<complex> wf_c(HERMES_ANY, nullptr);

  // Initialize the solution.
  MeshFunctionSharedPtr<double> sln_r(new Solution<double>);
  MeshFunctionSharedPtr<double> sln1_r(new Solution<double>);
  MeshFunctionSharedPtr<double> sln2_r(new Solution<double>);

  MeshFunctionSharedPtr<complex> sln_c(new Solution<complex>);
  MeshFunctionSharedPtr<complex> sln1_c(new Solution<complex>);
  MeshFunctionSharedPtr<complex> sln2_c(new Solution<complex>);

  // Initialize linear solver.
  Hermes::Hermes2D::LinearSolver<double> linear_solver_r(&wf_r, space_r);
  Hermes::Hermes2D::LinearSolver<complex> linear_solver_c(&wf_c, space_c);

#ifdef SHOW_OUTPUT
  Views::ScalarView s;
#endif

  // 1st - save & load real solution.
  linear_solver_r.solve();
  Solution<double>::vector_to_solution(linear_solver_r.get_sln_vector(), space_r, sln_r);
  sln_r.get_solution()->save("saved_sln_r.xml");
  sln1_r.get_solution()->load("saved_sln_r.xml", space_r);
  sln1_r.get_solution()->save("saved_sln_r-final.xml");
#ifdef SHOW_OUTPUT
  s.set_title("Real - Original");
  s.show(sln_r);
  s.wait_for_keypress();
  s.set_title("Real - XML");
  s.show(sln1_r);
  s.wait_for_keypress();
#endif

#ifdef WITH_BSON
  sln1_r.get_solution()->save_bson("saved_sln_r.bson");
  sln2_r.get_solution()->load_bson("saved_sln_r.bson", space_r);
  sln2_r.get_solution()->save_bson("saved_sln_r-final.bson");
#ifdef SHOW_OUTPUT
  s.set_title("Real - BSON");
  s.show(sln2_r);
  s.wait_for_keypress();
#endif
#endif

  // 2nd - save & load complex one.
  linear_solver_c.solve();
  Solution<complex>::vector_to_solution(linear_solver_c.get_sln_vector(), space_c, sln_c);
  sln_c.get_solution()->save("saved_sln_c.xml");
  sln1_c.get_solution()->load("saved_sln_c.xml", space_c);
  sln1_c.get_solution()->save("saved_sln_c-final.xml");
#ifdef SHOW_OUTPUT
  MeshFunctionSharedPtr<double> filter(new RealFilter(sln_c));
  MeshFunctionSharedPtr<double> filter_1(new RealFilter(sln1_c));

  s.set_title("Complex - Original");
  s.show(filter);
  s.wait_for_keypress();
  s.set_title("Complex - XML");
  s.show(filter_1);
  s.wait_for_keypress();
#endif

#ifdef WITH_BSON
  sln1_c.get_solution()->save_bson("saved_sln_c.bson");
  sln2_c.get_solution()->load_bson("saved_sln_c.bson", space_c);
  sln2_c.get_solution()->save_bson("saved_sln_c-final.bson");
  MeshFunctionSharedPtr<double> filter_2(new RealFilter(sln2_c));
#ifdef SHOW_OUTPUT
  s.set_title("Complex - BSON");
  s.show(filter_2);
  s.wait_for_keypress();
#endif
#endif

  // 3th - save & load constant one.
  // 3.1 - bad one.
  MeshFunctionSharedPtr<double> initial_condition_bad(new CustomInitialCondition(mesh));
  bool local_success = false;
  try
  {
    initial_condition_bad.get_solution()->save("this-will-fail");
  }
  catch(Hermes::Exceptions::Exception& e)
  {
    local_success = true;
    std::string s = "Arbitrary exact solution can not be saved to disk. Only constant one can. Project to a space to get a saveable solution.";
    std::string s1 = e.info();
    if(s.compare(s1))
      success = false;
  }
  if(!local_success)
  {
    throw Exceptions::Exception("Exception not caught correctly.");
    success = false;
  }

  // 3.2 - good one.
  MeshFunctionSharedPtr<double> initial_condition_good(new ConstantSolution<double>(mesh, 3.1415926));
  MeshFunctionSharedPtr<double> test_solution_1(new Solution<double>());
  MeshFunctionSharedPtr<double> test_solution_2(new Solution<double>());
  initial_condition_good.get_solution()->save("constant_sln.xml");
  test_solution_1.get_solution()->load("constant_sln.xml", space_l2);
  test_solution_1.get_solution()->save("constant_sln-final.xml");
#ifdef SHOW_OUTPUT
  s.set_title("Exact - Original");
  s.show(initial_condition_good);
  s.wait_for_keypress();
  s.set_title("Exact - XML");
  s.show(test_solution_1);
  s.wait_for_keypress();
#endif
#ifdef WITH_BSON
  initial_condition_good.get_solution()->save_bson("constant_sln.bson");
  test_solution_2.get_solution()->load_bson("constant_sln.bson", space_l2);
  test_solution_2.get_solution()->save_bson("constant_sln-final.bson");
#ifdef SHOW_OUTPUT
  s.set_title("Exact - BSON");
  s.show(test_solution_2);
  s.wait_for_keypress();
#endif
#endif

/// \todo re-do the test files, but with some higher precision of stored numbers, this way it usually crashes on different truncation
/*
#if defined (_WINDOWS) || defined (WIN32) || defined (_MSC_VER)
  success = Testing::compare_files("saved_sln_r-final.xml", "win\\saved_sln_r-template.xml") && success;
  success = Testing::compare_files("saved_sln_r-final.bson", "win\\saved_sln_r-template.bson") &&  success;
  success = Testing::compare_files("saved_sln_c-final.xml", "win\\saved_sln_c-template.xml") &&  success;
  success = Testing::compare_files("saved_sln_c-final.bson", "win\\saved_sln_c-template.bson") &&  success;
  success = Testing::compare_files("constant_sln-final.xml", "win\\constant_sln-template.xml") &&  success;
  success = Testing::compare_files("constant_sln-final.bson", "win\\constant_sln-template.bson") && success;
#else
  success = Testing::compare_files("saved_sln_r-final.xml", "linux/saved_sln_r-template.xml") && success;
  success = Testing::compare_files("saved_sln_r-final.bson", "linux/saved_sln_r-template.bson") &&  success;
  success = Testing::compare_files("saved_sln_c-final.xml", "linux/saved_sln_c-template.xml") &&  success;
  success = Testing::compare_files("saved_sln_c-final.bson", "linux/saved_sln_c-template.bson") &&  success;
  success = Testing::compare_files("constant_sln-final.xml", "linux/constant_sln-template.xml") &&  success;
  success = Testing::compare_files("constant_sln-final.bson", "linux/constant_sln-template.bson") && success;
#endif
*/
  if(success)
  {
    printf("Success!");
    return 0;
  }
  else
  {
    printf("Failure!");
    return -1;
  }
}
예제 #2
0
int main(int argc, char* args[])
{
    // Load the mesh.
    Mesh mesh;
    MeshReaderH2D mloader;
    mloader.load("square.mesh", &mesh);

    // Perform initial mesh refinement.
    for (int i=0; i<INIT_REF; i++)
        mesh.refine_all_elements();

    mesh.refine_by_criterion(criterion, INIT_REF_CRITERION);

    MeshView m;
    m.show(&mesh);

    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type);
    Vector<double>* rhs = create_vector<double>(matrix_solver_type);
    LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs);

    ScalarView view1("Solution - Discontinuous Galerkin FEM", new WinGeom(900, 0, 450, 350));
    ScalarView view2("Solution - Standard continuous FEM", new WinGeom(900, 400, 450, 350));

    if(WANT_DG)
    {
        // Create an L2 space.
        L2Space<double> space_l2(&mesh, P_INIT);

        // Initialize the solution.
        Solution<double> sln_l2;

        // Initialize the weak formulation.
        CustomWeakForm wf_l2(BDY_BOTTOM_LEFT);


        // Initialize the FE problem.
        DiscreteProblem<double> dp_l2(&wf_l2, &space_l2);

        info("Assembling Discontinuous Galerkin (nelem: %d, ndof: %d).", mesh.get_num_active_elements(), space_l2.get_num_dofs());
        dp_l2.assemble(matrix, rhs);

        // Solve the linear system. If successful, obtain the solution.
        info("Solving Discontinuous Galerkin.");
        if(solver->solve())
            if(DG_SHOCK_CAPTURING)
            {
                FluxLimiter flux_limiter(FluxLimiter::Kuzmin, solver->get_sln_vector(), &space_l2, true);

                flux_limiter.limit_second_orders_according_to_detector();

                flux_limiter.limit_according_to_detector();

                flux_limiter.get_limited_solution(&sln_l2);

                view1.set_title("Solution - limited Discontinuous Galerkin FEM");
            }
            else
                Solution<double>::vector_to_solution(solver->get_sln_vector(), &space_l2, &sln_l2);
        else
            error ("Matrix solver failed.\n");

        // View the solution.
        view1.show(&sln_l2);
    }
    if(WANT_FEM)
    {
        // Create an H1 space.
        H1Space<double> space_h1(&mesh, P_INIT);

        // Initialize the solution.
        Solution<double> sln_h1;

        // Initialize the weak formulation.
        CustomWeakForm wf_h1(BDY_BOTTOM_LEFT, false);


        // Initialize the FE problem.
        DiscreteProblem<double> dp_h1(&wf_h1, &space_h1);

        // Set up the solver, matrix, and rhs according to the solver selection.
        SparseMatrix<double>* matrix = create_matrix<double>(matrix_solver_type);
        Vector<double>* rhs = create_vector<double>(matrix_solver_type);
        LinearSolver<double>* solver = create_linear_solver<double>(matrix_solver_type, matrix, rhs);

        info("Assembling Continuous FEM (nelem: %d, ndof: %d).", mesh.get_num_active_elements(), space_h1.get_num_dofs());
        dp_h1.assemble(matrix, rhs);

        // Solve the linear system. If successful, obtain the solution.
        info("Solving Continuous FEM.");
        if(solver->solve())
            Solution<double>::vector_to_solution(solver->get_sln_vector(), &space_h1, &sln_h1);
        else
            error ("Matrix solver failed.\n");

        // View the solution.
        view2.show(&sln_h1);
    }

    // Clean up.
    delete solver;
    delete matrix;
    delete rhs;

    // Wait for keyboard or mouse input.
    View::wait();
    return 0;
}
예제 #3
0
int main(int argc, char* args[])
{
    // Load the mesh.
    MeshSharedPtr mesh(new Mesh);
    MeshReaderH2D mloader;
    mloader.load("square.mesh", mesh);

    // Perform initial mesh refinement.
    for (int i=0; i<INIT_REF; i++)
        mesh->refine_all_elements();

    mesh->refine_by_criterion(criterion, INIT_REF_CRITERION);

    ScalarView view1("Solution - Discontinuous Galerkin FEM", new WinGeom(900, 0, 450, 350));
    ScalarView view2("Solution - Standard continuous FEM", new WinGeom(900, 400, 450, 350));

    if(WANT_DG)
    {
        // Create an L2 space.
        SpaceSharedPtr<double> space_l2(new L2Space<double>(mesh, P_INIT));

        // Initialize the solution.
        MeshFunctionSharedPtr<double> sln_l2(new Solution<double>);

        // Initialize the weak formulation.
        CustomWeakForm wf_l2(BDY_BOTTOM_LEFT);

        // Initialize the FE problem.
        DiscreteProblem<double> dp_l2(&wf_l2, space_l2);
        dp_l2.set_linear();

        // Initialize linear solver.
        Hermes::Hermes2D::LinearSolver<double> linear_solver(&dp_l2);

        Hermes::Mixins::Loggable::Static::info("Assembling Discontinuous Galerkin (nelem: %d, ndof: %d).", mesh->get_num_active_elements(), space_l2->get_num_dofs());

        // Solve the linear system. If successful, obtain the solution.
        Hermes::Mixins::Loggable::Static::info("Solving Discontinuous Galerkin.");
        try
        {
            linear_solver.solve();
            if(DG_SHOCK_CAPTURING)
            {
                FluxLimiter flux_limiter(FluxLimiter::Kuzmin, linear_solver.get_sln_vector(), space_l2, true);

                flux_limiter.limit_second_orders_according_to_detector();

                flux_limiter.limit_according_to_detector();

                flux_limiter.get_limited_solution(sln_l2);

                view1.set_title("Solution - limited Discontinuous Galerkin FEM");
            }
            else
                Solution<double>::vector_to_solution(linear_solver.get_sln_vector(), space_l2, sln_l2);

            // View the solution.
            view1.show(sln_l2);
        }
        catch(std::exception& e)
        {
            std::cout << e.what();

        }
    }
    if(WANT_FEM)
    {
        // Create an H1 space.
        SpaceSharedPtr<double> space_h1(new H1Space<double>(mesh, P_INIT));

        // Initialize the solution.
        MeshFunctionSharedPtr<double> sln_h1(new Solution<double>);

        // Initialize the weak formulation.
        CustomWeakForm wf_h1(BDY_BOTTOM_LEFT, false);

        // Initialize the FE problem.
        DiscreteProblem<double> dp_h1(&wf_h1, space_h1);
        dp_h1.set_linear();

        Hermes::Mixins::Loggable::Static::info("Assembling Continuous FEM (nelem: %d, ndof: %d).", mesh->get_num_active_elements(), space_h1->get_num_dofs());

        // Initialize linear solver.
        Hermes::Hermes2D::LinearSolver<double> linear_solver(&dp_h1);

        // Solve the linear system. If successful, obtain the solution.
        Hermes::Mixins::Loggable::Static::info("Solving Continuous FEM.");
        try
        {
            linear_solver.solve();
            Solution<double>::vector_to_solution(linear_solver.get_sln_vector(), space_h1, sln_h1);

            // View the solution.
            view2.show(sln_h1);
        }
        catch(std::exception& e)
        {
            std::cout << e.what();
        }
    }

    // Wait for keyboard or mouse input.
    View::wait();
    return 0;
}