int main(int argc, char* argv[]) { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("square.mesh", mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh->refine_all_elements(); mesh->refine_towards_boundary("Bdy", INIT_BDY_REF_NUM); // Initialize boundary conditions. CustomEssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new H1Space<double>(mesh, &bcs, P_INIT)); int ndof = space->get_num_dofs(); // Initialize previous iteration solution for the Picard's method. MeshFunctionSharedPtr<double> init_condition(new ConstantSolution<double>(mesh, INIT_COND_CONST)); // Initialize the weak formulation. CustomNonlinearity lambda(alpha); Hermes2DFunction<double> src(-heat_src); CustomWeakFormPicard wf(init_condition, &lambda, &src); // Initialize the Picard solver. PicardSolver<double> picard(&wf, space); picard.set_max_allowed_iterations(PICARD_MAX_ITER); logger.info("Default tolerance"); try { picard.solve(init_condition); } catch(std::exception& e) { std::cout << e.what(); } int iter_1 = picard.get_num_iters(); logger.info("Adjusted tolerance without Anderson"); // Perform the Picard's iteration (Anderson acceleration on by default). picard.clear_tolerances(); picard.set_tolerance(PICARD_TOL, Hermes::Solvers::SolutionChangeAbsolute); try { picard.solve(init_condition); } catch(std::exception& e) { std::cout << e.what(); } int iter_2 = picard.get_num_iters(); // Translate the coefficient vector into a Solution. MeshFunctionSharedPtr<double> sln(new Solution<double>); Solution<double>::vector_to_solution(picard.get_sln_vector(), space, sln); logger.info("Default tolerance without Anderson and good initial guess"); PicardSolver<double> picard2(&wf, space); picard2.set_tolerance(1e-3, Hermes::Solvers::SolutionChangeRelative); picard2.set_max_allowed_iterations(PICARD_MAX_ITER); try { picard2.solve(sln); } catch(std::exception& e) { std::cout << e.what(); } int iter_3 = picard2.get_num_iters(); logger.info("Default tolerance with Anderson and good initial guess"); picard2.use_Anderson_acceleration(true); picard2.set_num_last_vector_used(PICARD_NUM_LAST_ITER_USED); picard2.set_anderson_beta(PICARD_ANDERSON_BETA); try { picard2.solve(sln); } catch(std::exception& e) { std::cout << e.what(); } int iter_4 = picard2.get_num_iters(); #ifdef SHOW_OUTPUT // Visualise the solution and mesh. ScalarView s_view("Solution", new WinGeom(0, 0, 440, 350)); s_view.show_mesh(false); s_view.show(sln); OrderView o_view("Mesh", new WinGeom(450, 0, 420, 350)); o_view.show(space); // Wait for all views to be closed. View::wait(); #endif bool success = Testing::test_value(iter_1, 14, "# of iterations 1", 1); // Tested value as of September 2013. success = Testing::test_value(iter_2, 12, "# of iterations 2", 1) & success; // Tested value as of September 2013. success = Testing::test_value(iter_3, 3, "# of iterations 3", 1) & success; // Tested value as of September 2013. success = Testing::test_value(iter_4, 3, "# of iterations 4", 1) & success; // Tested value as of September 2013. if(success) { printf("Success!\n"); return 0; } else { printf("Failure!\n"); return -1; } }
int main(int argc, char* argv[]) { // Define nonlinear magnetic permeability via a cubic spline. Hermes::vector<double> mu_inv_pts(0.0, 0.5, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.6, 1.7, 1.8, 1.9, 3.0, 5.0, 10.0); Hermes::vector<double> mu_inv_val(1/1500.0, 1/1480.0, 1/1440.0, 1/1400.0, 1/1300.0, 1/1150.0, 1/950.0, 1/750.0, 1/250.0, 1/180.0, 1/175.0, 1/150.0, 1/20.0, 1/10.0, 1/5.0); /* // This is for debugging (iron is assumed linear with mu_r = 300.0 Hermes::vector<double> mu_inv_pts(0.0, 10.0); Hermes::vector<double> mu_inv_val(1/300.0, 1/300.0); */ // Create the cubic spline (and plot it for visual control). double bc_left = 0.0; double bc_right = 0.0; bool first_der_left = false; bool first_der_right = false; bool extrapolate_der_left = false; bool extrapolate_der_right = false; CubicSpline mu_inv_iron(mu_inv_pts, mu_inv_val, bc_left, bc_right, first_der_left, first_der_right, extrapolate_der_left, extrapolate_der_right); info("Saving cubic spline into a Pylab file spline.dat."); // The interval of definition of the spline will be // extended by "interval_extension" on both sides. double interval_extension = 1.0; bool plot_derivative = false; mu_inv_iron.plot("spline.dat", interval_extension, plot_derivative); plot_derivative = true; mu_inv_iron.plot("spline_der.dat", interval_extension, plot_derivative); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("actuator.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); //MeshView mv("Mesh", new WinGeom(0, 0, 400, 400)); //mv.show(&mesh); // Initialize boundary conditions. DefaultEssentialBCConst<double> bc_essential(BDY_DIRICHLET, 0.0); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); info("ndof: %d", Space<double>::get_num_dofs(&space)); // Initialize the weak formulation // This determines the increase of integration order // for the axisymmetric term containing 1/r. Default is 3. int order_inc = 3; CustomWeakFormMagnetostatics wf(MAT_IRON_1, MAT_IRON_2, &mu_inv_iron, MAT_AIR, MAT_COPPER, MU_VACUUM, CURRENT_DENSITY, order_inc); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, &space); // Initialize the solution. ConstantSolution<double> sln(&mesh, INIT_COND); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. info("Projecting to obtain initial vector for the Newton's method."); double* coeff_vec = new double[Space<double>::get_num_dofs(&space)] ; OGProjection<double>::project_global(&space, &sln, coeff_vec, matrix_solver_type); // Perform Newton's iteration. Hermes::Hermes2D::NewtonSolver<double> newton(&dp, matrix_solver_type); bool verbose = true; newton.set_verbose_output(verbose); try { newton.solve(coeff_vec, NEWTON_TOL, NEWTON_MAX_ITER); } catch(Hermes::Exceptions::Exception e) { e.printMsg(); error("Newton's iteration failed."); }; // Translate the resulting coefficient vector into the Solution sln. Solution<double>::vector_to_solution(coeff_vec, &space, &sln); // Cleanup. delete [] coeff_vec; // Visualise the solution and mesh. ScalarView s_view1("Vector potencial", new WinGeom(0, 0, 350, 450)); FilterVectorPotencial vector_potencial(Hermes::vector<MeshFunction<double> *>(&sln, &sln), Hermes::vector<int>(H2D_FN_VAL, H2D_FN_VAL)); s_view1.show_mesh(false); s_view1.show(&vector_potencial); ScalarView s_view2("Flux density", new WinGeom(360, 0, 350, 450)); FilterFluxDensity flux_density(Hermes::vector<MeshFunction<double> *>(&sln, &sln)); s_view2.show_mesh(false); s_view2.show(&flux_density); OrderView o_view("Mesh", new WinGeom(720, 0, 350, 450)); o_view.show(&space); // Wait for all views to be closed. View::wait(); return 0; }
int main(int argc, char* argv[]) { // Define nonlinear thermal conductivity lambda(u) via a cubic spline. // Step 1: Fill the x values and use lambda_macro(u) = 1 + u^4 for the y values. #define lambda_macro(x) (1 + Hermes::pow(x, 4)) Hermes::vector<double> lambda_pts(-2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0); Hermes::vector<double> lambda_val; for (unsigned int i = 0; i < lambda_pts.size(); i++) lambda_val.push_back(lambda_macro(lambda_pts[i])); // Step 2: Create the cubic spline (and plot it for visual control). double bc_left = 0.0; double bc_right = 0.0; bool first_der_left = false; bool first_der_right = false; bool extrapolate_der_left = true; bool extrapolate_der_right = true; CubicSpline lambda(lambda_pts, lambda_val, bc_left, bc_right, first_der_left, first_der_right, extrapolate_der_left, extrapolate_der_right); info("Saving cubic spline into a Pylab file spline.dat."); double interval_extension = 3.0; // The interval of definition of the spline will be // extended by "interval_extension" on both sides. lambda.plot("spline.dat", interval_extension); // Load the mesh. Mesh mesh; MeshReaderH2D mloader; mloader.load("square.mesh", &mesh); // Perform initial mesh refinements. for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary("Bdy", INIT_BDY_REF_NUM); // Initialize boundary conditions. CustomEssentialBCNonConst bc_essential("Bdy"); EssentialBCs<double> bcs(&bc_essential); // Create an H1 space with default shapeset. H1Space<double> space(&mesh, &bcs, P_INIT); int ndof = space.get_num_dofs(); info("ndof: %d", ndof); // Initialize the weak formulation. Hermes2DFunction<double> src(-heat_src); DefaultWeakFormPoisson<double> wf(HERMES_ANY, &lambda, &src); // Initialize the FE problem. DiscreteProblem<double> dp(&wf, &space); // Project the initial condition on the FE space to obtain initial // coefficient vector for the Newton's method. // NOTE: If you want to start from the zero vector, just define // coeff_vec to be a vector of ndof zeros (no projection is needed). info("Projecting to obtain initial vector for the Newton's method."); double* coeff_vec = new double[ndof]; CustomInitialCondition init_sln(&mesh); OGProjection<double>::project_global(&space, &init_sln, coeff_vec, matrix_solver); // Initialize Newton solver. NewtonSolver<double> newton(&dp, matrix_solver); // Perform Newton's iteration. bool freeze_jacobian = false; if (!newton.solve(coeff_vec, NEWTON_TOL, NEWTON_MAX_ITER, freeze_jacobian)) error("Newton's iteration failed."); // Translate the resulting coefficient vector into a Solution. Solution<double> sln; Solution<double>::vector_to_solution(newton.get_sln_vector(), &space, &sln); // Get info about time spent during assembling in its respective parts. //dp.get_all_profiling_output(std::cout); // Clean up. delete [] coeff_vec; // Visualise the solution and mesh. ScalarView s_view("Solution", new WinGeom(0, 0, 440, 350)); s_view.show_mesh(false); s_view.show(&sln); OrderView<double> o_view("Mesh", new WinGeom(450, 0, 400, 350)); o_view.show(&space); // Wait for all views to be closed. View::wait(); return 0; }