int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // initial mesh refinements for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1,INIT_BDY_REF_NUM); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // create an H1 space H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_uniform_order(P_INIT); space.assign_dofs(); // previous solution for the Newton's iteration Solution u_prev; // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(jac), UNSYM, ANY, 1, &u_prev); wf.add_liform(0, callback(res), ANY, 1, &u_prev); // initialize the nonlinear system and solver UmfpackSolver umfpack; NonlinSystem nls(&wf, &umfpack); nls.set_spaces(1, &space); nls.set_pss(1, &pss); // use a constant function as the initial guess u_prev.set_const(&mesh, 3.0); nls.set_ic(&u_prev, &u_prev, PROJ_TYPE); // Newton's loop if (!nls.solve_newton_1(&u_prev, NEWTON_TOL, NEWTON_MAX_ITER)) error("Newton's method did not converge."); // visualise the solution and mesh ScalarView sview("Solution", 0, 0, 800, 600); OrderView oview("Mesh", 820, 0, 800, 600); char title[100]; sprintf(title, "Solution"); sview.set_title(title); sview.show(&u_prev); sprintf(title, "Mesh"); oview.set_title(title); oview.show(&space); // wait for keyboard or mouse input View::wait(); return 0; }
int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // initial mesh refinements for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1,INIT_BDY_REF_NUM); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // create an H1 space H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_uniform_order(P_INIT); space.assign_dofs(); // previous solution for the Newton's iteration Solution u_prev; // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(jac), UNSYM, ANY, 1, &u_prev); wf.add_liform(0, callback(res), ANY, 1, &u_prev); // initialize the nonlinear system and solver UmfpackSolver umfpack; NonlinSystem nls(&wf, &umfpack); nls.set_spaces(1, &space); nls.set_pss(1, &pss); // use a constant function as the initial guess u_prev.set_const(&mesh, 3.0); nls.set_ic(&u_prev, &u_prev, PROJ_TYPE); // Newton's loop bool success = nls.solve_newton_1(&u_prev, NEWTON_TOL, NEWTON_MAX_ITER); #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 if (success) { // should pass with NEWTON_MAX_ITER = 8 and fail with NEWTON_MAX_ITER = 7 printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }
/* add initialization statements to blocks as needed */ static void sinitbuild(SemBlock *b) { SemBlock *yes, *no, *then; SemInit *si; ASTNode *p; SemVar *nv, *v; SemTrigger *t; for(t = sinits; t != nil; t = t->next) { yes = newblock(); no = newblock(); then = newblock(); yes->cont = node(ASTBLOCK, nil); then->phi = node(ASTBLOCK, nil); b->jump = node(ASTIF, t->trigger, node(ASTSEMGOTO, yes), node(ASTSEMGOTO, no)); yes->jump = node(ASTSEMGOTO, then); no->jump = node(ASTSEMGOTO, then); mkftlist(b, 1, yes, no, nil); mkftlist(yes, 0, b, nil); mkftlist(yes, 1, then, nil); mkftlist(no, 0, b, nil); mkftlist(no, 1, then, nil); mkftlist(then, 0, yes, no, nil); for(si = t->first; si != nil; si = si->tnext) { v = mkvar(si->var->sym, 1); if(--si->var->nsinits > 0) nv = mkvar(si->var->sym, 1); else nv = si->var->sym->semc[1]; yes->cont->nl = nlcat(yes->cont->nl, nl(node(ASTASS, OPNOP, node(ASTSSA, v), si->val))); p = node(ASTPHI); p->nl = nls(node(ASTSSA, v), node(ASTSSA, ssaget(sinitvars, v->sym, 1)), nil); then->phi->nl = nlcat(then->phi->nl, nl(node(ASTASS, OPNOP, node(ASTSSA, nv), p))); defsadd(sinitvars, nv, 1); } b = then; } }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh, basemesh; basemesh.load("square.mesh"); for(int i = 0; i < REF_INIT; i++) basemesh.refine_all_elements(); mesh.copy(&basemesh); mesh.refine_towards_boundary(1,3); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_bc_values(bc_values); space.set_uniform_order(P_INIT); space.assign_dofs(); // enumerate basis functions space.assign_dofs(); Solution Tprev, // previous time step solution, for the time integration method Titer; // solution converging during the Newton's iteration // initialize the weak formulation WeakForm wf(1); if(TIME_DISCR == 1) { wf.add_biform(0, 0, callback(J_euler), UNSYM, ANY, 1, &Titer); wf.add_liform(0, callback(F_euler), ANY, 2, &Titer, &Tprev); } else { wf.add_biform(0, 0, callback(J_cranic), UNSYM, ANY, 1, &Titer); wf.add_liform(0, callback(F_cranic), ANY, 2, &Titer, &Tprev); } // matrix solver UmfpackSolver solver; // nonlinear system class NonlinSystem nls(&wf, &solver); nls.set_spaces(1, &space); nls.set_pss(1, &pss); // visualize solution and mesh ScalarView view("", 0, 0, 700, 600); view.fix_scale_width(80); OrderView ordview("", 700, 0, 700, 600); // error estimate as a function of physical time GnuplotGraph graph_err; graph_err.set_captions("","Time step","Error"); graph_err.add_row(); // error estimate as a function of DOF GnuplotGraph graph_dofs; graph_dofs.set_captions("","Time step","DOFs"); graph_dofs.add_row(); // initial condition at zero time level //Tprev.set_const(&mesh, 0.0); Tprev.set_dirichlet_lift(&space, &pss); Titer.set_dirichlet_lift(&space, &pss); nls.set_ic(&Titer, &Titer, PROJ_TYPE); // view initial guess for Newton's method // satisfies BC conditions char title[100]; sprintf(title, "Initial iteration"); view.set_title(title); view.show(&Titer); ordview.show(&space); //view.wait_for_keypress(); // this may cause graphics problems // time stepping loop int nstep = (int)(T_FINAL/TAU + 0.5); double cpu = 0.0; Solution sln_coarse, sln_fine; for(int n = 1; n <= nstep; n++) { info("\n---- Time step %d -----------------------------------------------------------------", n); // time measurement begin_time(); // perform periodic unrefinements if (n % UNREF_FREQ == 0) { mesh.copy(&basemesh); space.set_uniform_order(P_INIT); space.assign_dofs(); } // adaptivity loop int at = 0, ndofs; bool done = false; double err_est, cpu; do { info("\n---- Time step %d, adaptivity step %d ---------------------------------------------\n", n, ++at); // Newton's loop for coarse mesh solution int it = 1; double res_l2_norm; if (n > 1 || at > 1) nls.set_ic(&sln_fine, &Titer); else nls.set_ic(&Titer, &Titer); do { info("\n---- Time step %d, adaptivity step %d, Newton step %d (Coarse mesh solution)-------\n", n, at, it++); nls.assemble(); nls.solve(1, &sln_coarse); res_l2_norm = nls.get_residuum_l2_norm(); info("Residuum L2 norm: %g", res_l2_norm); Titer.copy(&sln_coarse); } while (res_l2_norm > NEWTON_TOL_COARSE); // Newton's loop for fine mesh solution it = 1; RefNonlinSystem rs(&nls); rs.prepare(); if (n > 1 || at > 1) rs.set_ic(&sln_fine, &Titer); else rs.set_ic(&Titer, &Titer); do { info("\n---- Time step %d, adaptivity step %d, Newton step %d (Fine mesh solution) --------\n", n, at, it++); rs.assemble(); rs.solve(1, &sln_fine); res_l2_norm = rs.get_residuum_l2_norm(); info("Residuum L2 norm: %g", res_l2_norm); Titer.copy(&sln_fine); } while (res_l2_norm > NEWTON_TOL_REF); // calculate error estimate wrt. fine mesh solution H1OrthoHP hp(1, &space); err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Error estimate: %g%", err_est); // visualization of solution on the n-th time level sprintf(title, "Temperature, time level %d", n); //view.set_min_max_range(0,100); view.set_title(title); //view.show(&Titer); // to see reference solution view.show(&sln_fine); // to see the solution // visualization of mesh on the n-th time level sprintf(title, "hp-mesh, time level %d", n); ordview.set_title(title); ordview.show(&space); // to see hp-mesh //view.wait_for_keypress(); // if err_est too large, adapt the mesh if (err_est < SPACE_H1_TOL) done = true; else { hp.adapt(THRESHOLD, STRATEGY, ADAPT_TYPE, ISO_ONLY, MESH_REGULARITY); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (!done); // add entry to both time and DOF error graphs graph_err.add_values(0, n, err_est); graph_err.save("error.txt"); graph_dofs.add_values(0, n, space.get_num_dofs()); graph_dofs.save("dofs.txt"); // copying result of the Newton's iteration into Tprev Tprev.copy(&Titer); } // time measurement cpu += end_time(); verbose("Total running time: %g sec", cpu); // wait for keyboard or mouse input View::wait("Waiting for keyboard or mouse input."); return 0; }
int main(int argc, char* argv[]) { Mesh mesh; mesh.load("square.mesh"); for(int i = 0; i < REF_INIT; i++) mesh.refine_all_elements(); H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_bc_values(bc_values); space.set_uniform_order(P_INIT); space.assign_dofs(); WeakForm wf(1); if(TIME_DISCR == 1) { wf.add_biform(0, 0, bilinear_form_0_0_euler, UNSYM, ANY, 1, &Psi_iter); wf.add_liform(0, linear_form_0_euler, ANY, 2, &Psi_iter, &Psi_prev); } else { wf.add_biform(0, 0, bilinear_form_0_0_cranic, UNSYM, ANY, 1, &Psi_iter); wf.add_liform(0, linear_form_0_cranic, ANY, 2, &Psi_iter, &Psi_prev); } UmfpackSolver umfpack; NonlinSystem nls(&wf, &umfpack); nls.set_spaces(1, &space); nls.set_pss(1, &pss); char title[100]; ScalarView view("", 0, 0, 700, 600); //view.set_min_max_range(-0.5,0.5); // setting initial condition at zero time level Psi_prev.set_exact(&mesh, fn_init); nls.set_ic(&Psi_prev, &Psi_prev, PROJ_TYPE); Psi_iter.copy(&Psi_prev); // view initial guess for Newton's method /* sprintf(title, "Initial guess for the Newton's method"); view.set_title(title); view.show(&Psi_iter); view.wait_for_keypress(); */ Solution sln; // time stepping int nstep = (int)(T_FINAL/TAU + 0.5); for(int n = 1; n <= nstep; n++) { info("\n---- Time step %d -----------------------------------------------", n); // set initial condition for the Newton's iteration // actually needed only when space changes // otherwise initial solution vector is that one // from the previous time level //nls.set_ic(&Psi_iter, &Psi_iter); int it = 1; double res_l2_norm; do { info("\n---- Time step %d, Newton iter %d ---------------------------------\n", n, it++); nls.assemble(); nls.solve(1, &sln); res_l2_norm = nls.get_residuum_l2_norm(); info("Residuum L2 norm: %g\n", res_l2_norm); // want to see Newtons iterations /* sprintf(title, "Time level %d, Newton iteration %d", n, it-1); view.set_title(title); view.show(&sln); view.wait_for_keypress(); */ Psi_iter = sln; } while (res_l2_norm > NEWTON_TOL); // visualization of solution on the n-th time level sprintf(title, "Time level %d", n); //view.set_min_max_range(90,100); view.set_title(title); view.show(&Psi_iter); //view.wait_for_keypress(); // uncomment one of the following lines to generate a series of video frames //view.save_numbered_screenshot("sol%03d.bmp", n, true); //pview.save_numbered_screenshot("pressure%03d.bmp", i, true); // the frames can then be converted to a video file with the command // mencoder "mf://velocity*.bmp" -mf fps=20 -o velocity.avi -ovc lavc -lavcopts vcodec=mpeg4 // copying result of the Newton's iteration into Psi_prev Psi_prev.copy(&Psi_iter); } printf("Click into the image window and press 'q' to finish.\n"); View::wait(); return 0; }
int main (int argc, char* argv[]) { // load the mesh file Mesh Cmesh, phimesh, basemesh; H2DReader mloader; #ifdef CIRCULAR mloader.load("../circular.mesh", &basemesh); basemesh.refine_all_elements(0); basemesh.refine_towards_boundary(TOP_MARKER, 2); basemesh.refine_towards_boundary(BOT_MARKER, 4); MeshView mview("Mesh", 0, 600, 400, 400); mview.show(&basemesh); #else mloader.load("../small.mesh", &basemesh); basemesh.refine_all_elements(1); //basemesh.refine_all_elements(1); // when only p-adapt is used //basemesh.refine_all_elements(1); // when only p-adapt is used basemesh.refine_towards_boundary(TOP_MARKER, REF_INIT); //basemesh.refine_towards_boundary(BOT_MARKER, (REF_INIT - 1) + 8); // when only p-adapt is used basemesh.refine_towards_boundary(BOT_MARKER, REF_INIT - 1); #endif Cmesh.copy(&basemesh); phimesh.copy(&basemesh); // Spaces for concentration and the voltage H1Space Cspace(&Cmesh, C_bc_types, C_essential_bc_values, P_INIT); H1Space phispace(MULTIMESH ? &phimesh : &Cmesh, phi_bc_types, phi_essential_bc_values, P_INIT); // The weak form for 2 equations WeakForm wf(2); Solution C_prev_time, // prveious time step solution, for the time integration C_prev_newton, // solution convergin during the Newton's iteration phi_prev_time, phi_prev_newton; // Add the bilinear and linear forms // generally, the equation system is described: if (TIME_DISCR == 1) { // Implicit Euler. wf.add_vector_form(0, callback(Fc_euler), H2D_ANY, Tuple<MeshFunction*>(&C_prev_time, &C_prev_newton, &phi_prev_newton)); wf.add_vector_form(1, callback(Fphi_euler), H2D_ANY, Tuple<MeshFunction*>(&C_prev_newton, &phi_prev_newton)); wf.add_matrix_form(0, 0, callback(J_euler_DFcDYc), H2D_UNSYM, H2D_ANY, &phi_prev_newton); wf.add_matrix_form(0, 1, callback(J_euler_DFcDYphi), H2D_UNSYM, H2D_ANY, &C_prev_newton); wf.add_matrix_form(1, 0, callback(J_euler_DFphiDYc), H2D_UNSYM); wf.add_matrix_form(1, 1, callback(J_euler_DFphiDYphi), H2D_UNSYM); } else { wf.add_vector_form(0, callback(Fc_cranic), H2D_ANY, Tuple<MeshFunction*>(&C_prev_time, &C_prev_newton, &phi_prev_newton, &phi_prev_time)); wf.add_vector_form(1, callback(Fphi_cranic), H2D_ANY, Tuple<MeshFunction*>(&C_prev_newton, &phi_prev_newton)); wf.add_matrix_form(0, 0, callback(J_cranic_DFcDYc), H2D_UNSYM, H2D_ANY, Tuple<MeshFunction*>(&phi_prev_newton, &phi_prev_time)); wf.add_matrix_form(0, 1, callback(J_cranic_DFcDYphi), H2D_UNSYM, H2D_ANY, Tuple<MeshFunction*>(&C_prev_newton, &C_prev_time)); wf.add_matrix_form(1, 0, callback(J_cranic_DFphiDYc), H2D_UNSYM); wf.add_matrix_form(1, 1, callback(J_cranic_DFphiDYphi), H2D_UNSYM); } // Nonlinear solver NonlinSystem nls(&wf, Tuple<Space*>(&Cspace, &phispace)); phi_prev_time.set_exact(MULTIMESH ? &phimesh : &Cmesh, voltage_ic); C_prev_time.set_exact(&Cmesh, concentration_ic); C_prev_newton.copy(&C_prev_time); phi_prev_newton.copy(&phi_prev_time); // Project the function init_cond() on the FE space // to obtain initial coefficient vector for the Newton's method. info("Projecting initial conditions to obtain initial vector for the Newton'w method."); nls.project_global(Tuple<MeshFunction*>(&C_prev_time, &phi_prev_time), Tuple<Solution*>(&C_prev_newton, &phi_prev_newton)); //VectorView vview("electric field [V/m]", 0, 0, 600, 600); ScalarView Cview("Concentration [mol/m3]", 0, 0, 800, 800); ScalarView phiview("Voltage [V]", 650, 0, 600, 600); phiview.show(&phi_prev_time); Cview.show(&C_prev_time); char title[100]; int nstep = (int) (T_FINAL / TAU + 0.5); for (int n = 1; n <= nstep; n++) { verbose("\n---- Time step %d ----", n); bool verbose = true; // Default is false. if (!nls.solve_newton(Tuple<Solution*>(&C_prev_newton, &phi_prev_newton), NEWTON_TOL, NEWTON_MAX_ITER, verbose)) error("Newton's method did not converge."); sprintf(title, "time step = %i", n); phiview.set_title(title); phiview.show(&phi_prev_newton); Cview.set_title(title); Cview.show(&C_prev_newton); phi_prev_time.copy(&phi_prev_newton); C_prev_time.copy(&C_prev_newton); } View::wait(); return 0; }
int main (int argc, char* argv[]) { bool adaptive = false; if (argc > 1) { std::string arg0(argv[1]); if (USE_ADAPTIVE.compare(arg0) == 0) { adaptive = true; info("Using adaptive solution"); } else { error("Illegal argument %s", argv[1]); return -1; } } else { info("Using NON-adaptive solution"); } // load the mesh file Mesh Cmesh, phimesh, basemesh; H2DReader mloader; mloader.load("small.mesh", &basemesh); basemesh.refine_towards_boundary(TOP_MARKER, REF_INIT); basemesh.refine_towards_boundary(BOT_MARKER, REF_INIT - 1); Cmesh.copy(&basemesh); phimesh.copy(&basemesh); // create the shapeset H1Shapeset shapeset; PrecalcShapeset Cpss(&shapeset); PrecalcShapeset phipss(&shapeset); // Spaces for concentration and the voltage H1Space C(&Cmesh, &shapeset); H1Space phi(MULTIMESH ? &phimesh : &Cmesh, &shapeset); // Initialize boundary conditions C.set_bc_types(C_bc_types); phi.set_bc_types(phi_bc_types); phi.set_bc_values(phi_bc_values); //C.set_bc_values(C_bc_values); // set polynomial degrees C.set_uniform_order(P_INIT); phi.set_uniform_order(P_INIT); // assign degrees of freedom int ndofs = 0; ndofs += C.assign_dofs(ndofs); ndofs += phi.assign_dofs(ndofs); info("ndofs: %d", ndofs); // The weak form for 2 equations WeakForm wf(2); Solution Cp, // prveious time step solution, for the time integration Ci, // solution convergin during the Newton's iteration phip, phii; // Add the bilinear and linear forms // generally, the equation system is described: // a11(u1, v1) + a12(u2, v1) + a1n(un, v1) = l1(v1) // a21(u1, v2) + a22(u2, v2) + a2n(un, v2) = l2(v2) // an1(u1, vn) + an2(u2, vn) + ann(un, vn) = ln(vn) wf.add_biform(0, 0, callback(J_euler_DFcDYc), UNSYM, ANY, 1, &phii); wf.add_biform(1, 1, callback(J_euler_DFphiDYphi), UNSYM); wf.add_biform(0, 1, callback(J_euler_DFcDYphi), UNSYM, ANY, 1, &Ci); wf.add_biform(1, 0, callback(J_euler_DFphiDYc), UNSYM); wf.add_liform(0, callback(Fc_euler), ANY, 3, &Cp, &Ci, &phii); wf.add_liform(1, callback(Fphi_euler), ANY, 2, &Ci, &phii); wf.add_liform_surf(1, callback(linear_form_surf_top), TOP_MARKER); // Nonlinear solver UmfpackSolver umfpack; NonlinSystem nls(&wf, &umfpack); nls.set_spaces(2, &C, &phi); if (MULTIMESH) { nls.set_pss(2, &Cpss, &phipss); } else { nls.set_pss(1, &Cpss); } info("UmfpackSolver initialized"); //Cp.set_dirichlet_lift(&C, &Cpss); //phip.set_dirichlet_lift(&phi, MULTIMESH ? &phipss : &Cpss); Cp.set_const(&Cmesh, C_CONC); phip.set_const(MULTIMESH ? &phimesh : &Cmesh, 0); Ci.copy(&Cp); phii.copy(&phip); nls.set_ic(&Ci, &phii, &Ci, &phii); if (adaptive) { solveAdaptive(Cmesh, phimesh, basemesh, nls, C, phi, Cp, Ci, phip, phii); } else { solveNonadaptive(Cmesh, nls, Cp, Ci, phip, phii); } return 0; }
int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; H2DReader mloader; mloader.load("square.mesh", &mesh); // initial mesh refinements for(int i = 0; i < INIT_GLOB_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(1,INIT_BDY_REF_NUM); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset pss(&shapeset); // create an H1 space H1Space space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_bc_values(bc_values); space.set_uniform_order(P_INIT); space.assign_dofs(); // previous solution for the Newton's iteration Solution u_prev; // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(jac), UNSYM, ANY, 1, &u_prev); wf.add_liform(0, callback(res), ANY, 1, &u_prev); // initialize the nonlinear system and solver UmfpackSolver umfpack; NonlinSystem nls(&wf, &umfpack); nls.set_spaces(1, &space); nls.set_pss(1, &pss); // DOF and CPU convergence graphs SimpleGraph graph_dof, graph_cpu; // project the function init_cond() on the mesh // to obtain initial guess u_prev for the Newton's method nls.set_ic(init_cond, &mesh, &u_prev, PROJ_TYPE); // visualise the initial ocndition ScalarView view("Initial condition", 0, 0, 700, 600); view.show(&u_prev); OrderView oview("Initial mesh", 720, 0, 700, 600); oview.show(&space); //printf("Click into the image window and press any key to proceed.\n"); //view.wait_for_keypress(); // adaptivity loop double cpu = 0.0, err_est; int a_step = 1; bool done = false; do { a_step++; // Newton's loop on the coarse mesh int it = 1; double res_l2_norm; Solution sln_coarse; do { info("\n---- Adapt step %d, Newton iter %d (coarse mesh) ---------------------------------\n", a_step, it++); printf("ndof = %d\n", space.get_num_dofs()); // time measurement begin_time(); // assemble the Jacobian matrix and residual vector, // solve the system nls.assemble(); nls.solve(1, &sln_coarse); // calculate the l2-norm of residual vector res_l2_norm = nls.get_residuum_l2_norm(); info("Residuum L2 norm: %g\n", res_l2_norm); // time measurement cpu += end_time(); // visualise the solution char title[100]; sprintf(title, "Temperature (coarse mesh), Newton iteration %d", it-1); view.set_title(title); view.show(&sln_coarse); sprintf(title, "Coarse mesh, Newton iteration %d", it-1); oview.set_title(title); oview.show(&space); //printf("Click into the image window and press any key to proceed.\n"); //view.wait_for_keypress(); // save the new solution as "previous" for the // next Newton's iteration u_prev.copy(&sln_coarse); } while (res_l2_norm > NEWTON_TOL); // Setting initial guess for the Newton's method on the fine mesh Solution sln_fine, u_prev_fine; RefNonlinSystem rs(&nls); rs.prepare(); rs.set_ic(&u_prev, &u_prev); // Newton's loop on the fine mesh it = 1; do { info("\n---- Adapt step %d, Newton iter %d (fine mesh) ---------------------------------\n", a_step, it++); // time measurement begin_time(); // assemble the Jacobian matrix and residual vector, // solve the system rs.assemble(); rs.solve(1, &sln_fine); // calculate the l2-norm of residual vector res_l2_norm = rs.get_residuum_l2_norm(); info("Residuum L2 norm: %g\n", res_l2_norm); // time measurement cpu += end_time(); // visualise the solution char title[100]; sprintf(title, "Temperature (fine mesh), Newton iteration %d", it-1); view.set_title(title); view.show(&sln_fine); sprintf(title, "Fine mesh, Newton iteration %d", it-1); oview.set_title(title); oview.show(rs.get_ref_space(0)); //printf("Click into the image window and press any key to proceed.\n"); //view.wait_for_keypress(); u_prev.copy(&sln_fine); } while (res_l2_norm > NEWTON_TOL_REF); // time measurement begin_time(); // calculate element errors and total error estimate H1OrthoHP hp(1, &space); err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Error estimate: %g%%", err_est); // add entry to DOF convergence graph graph_dof.add_values(space.get_num_dofs(), err_est); graph_dof.save("conv_dof.dat"); // add entry to CPU convergence graph graph_cpu.add_values(cpu, err_est); graph_cpu.save("conv_cpu.dat"); // if err_est too large, adapt the mesh if (err_est < ERR_STOP) done = true; else { hp.adapt(THRESHOLD, STRATEGY, ADAPT_TYPE, ISO_ONLY, MESH_REGULARITY); int ndof = space.assign_dofs(); if (ndof >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (!done); verbose("Total running time: %g sec", cpu); // wait for keyboard or mouse input View::wait(); return 0; }
int main(int argc, char* argv[]) { // load the mesh file Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); // a-priori mesh refinements mesh.refine_all_elements(); mesh.refine_towards_boundary(5, 4, false); mesh.refine_towards_boundary(1, 4); mesh.refine_towards_boundary(3, 4); // initialize shapesets and the cache H1ShapesetBeuchler h1_shapeset; PrecalcShapeset h1_pss(&h1_shapeset); #ifdef PRESSURE_IN_L2 L2Shapeset l2_shapeset; PrecalcShapeset l2_pss(&l2_shapeset); #endif // spaces for velocities and pressure H1Space xvel_space(&mesh, &h1_shapeset); H1Space yvel_space(&mesh, &h1_shapeset); #ifdef PRESSURE_IN_L2 L2Space p_space(&mesh, &l2_shapeset); #else H1Space p_space(&mesh, &h1_shapeset); #endif // initialize boundary conditions xvel_space.set_bc_types(xvel_bc_type); xvel_space.set_bc_values(xvel_bc_value); yvel_space.set_bc_types(yvel_bc_type); p_space.set_bc_types(p_bc_type); // set velocity and pressure polynomial degrees xvel_space.set_uniform_order(P_INIT_VEL); yvel_space.set_uniform_order(P_INIT_VEL); p_space.set_uniform_order(P_INIT_PRESSURE); // assign degrees of freedom int ndofs = 0; ndofs += xvel_space.assign_dofs(ndofs); ndofs += yvel_space.assign_dofs(ndofs); ndofs += p_space.assign_dofs(ndofs); // solutions for the Newton's iteration and time stepping Solution xvel_prev_time, yvel_prev_time, xvel_prev_newton, yvel_prev_newton, p_prev; xvel_prev_time.set_zero(&mesh); yvel_prev_time.set_zero(&mesh); xvel_prev_newton.set_zero(&mesh); yvel_prev_newton.set_zero(&mesh); p_prev.set_zero(&mesh); // set up weak formulation WeakForm wf(3); if (NEWTON) { wf.add_biform(0, 0, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(0, 0, callback(newton_bilinear_form_unsym_0_0), UNSYM, ANY, 2, &xvel_prev_newton, &yvel_prev_newton); wf.add_biform(0, 1, callback(newton_bilinear_form_unsym_0_1), UNSYM, ANY, 1, &xvel_prev_newton); wf.add_biform(0, 2, callback(bilinear_form_unsym_0_2), ANTISYM); wf.add_biform(1, 0, callback(newton_bilinear_form_unsym_1_0), UNSYM, ANY, 1, &yvel_prev_newton); wf.add_biform(1, 1, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(1, 1, callback(newton_bilinear_form_unsym_1_1), UNSYM, ANY, 2, &xvel_prev_newton, &yvel_prev_newton); wf.add_biform(1, 2, callback(bilinear_form_unsym_1_2), ANTISYM); wf.add_liform(0, callback(newton_F_0), ANY, 5, &xvel_prev_time, &yvel_prev_time, &xvel_prev_newton, &yvel_prev_newton, &p_prev); wf.add_liform(1, callback(newton_F_1), ANY, 5, &xvel_prev_time, &yvel_prev_time, &xvel_prev_newton, &yvel_prev_newton, &p_prev); wf.add_liform(2, callback(newton_F_2), ANY, 2, &xvel_prev_newton, &yvel_prev_newton); } else { wf.add_biform(0, 0, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(0, 0, callback(simple_bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xvel_prev_time, &yvel_prev_time); wf.add_biform(1, 1, callback(bilinear_form_sym_0_0_1_1), SYM); wf.add_biform(1, 1, callback(simple_bilinear_form_unsym_0_0_1_1), UNSYM, ANY, 2, &xvel_prev_time, &yvel_prev_time); wf.add_biform(0, 2, callback(bilinear_form_unsym_0_2), ANTISYM); wf.add_biform(1, 2, callback(bilinear_form_unsym_1_2), ANTISYM); wf.add_liform(0, callback(simple_linear_form), ANY, 1, &xvel_prev_time); wf.add_liform(1, callback(simple_linear_form), ANY, 1, &yvel_prev_time); } // visualization VectorView vview("velocity [m/s]", 0, 0, 1500, 470); ScalarView pview("pressure [Pa]", 0, 530, 1500, 470); vview.set_min_max_range(0, 1.6); vview.fix_scale_width(80); //pview.set_min_max_range(-0.9, 1.0); pview.fix_scale_width(80); pview.show_mesh(true); // matrix solver UmfpackSolver umfpack; // linear system LinSystem ls(&wf, &umfpack); // nonlinear system NonlinSystem nls(&wf, &umfpack); if (NEWTON) { // set up the nonlinear system nls.set_spaces(3, &xvel_space, &yvel_space, &p_space); #ifdef PRESSURE_IN_L2 nls.set_pss(3, &h1_pss, &h1_pss, &l2_pss); #else nls.set_pss(1, &h1_pss); #endif } else { // set up the linear system ls.set_spaces(3, &xvel_space, &yvel_space, &p_space); #ifdef PRESSURE_IN_L2 ls.set_pss(3, &h1_pss, &h1_pss, &l2_pss); #else ls.set_pss(1, &h1_pss); #endif } // time-stepping loop char title[100]; int num_time_steps = T_FINAL / TAU; for (int i = 1; i <= num_time_steps; i++) { TIME += TAU; info("\n---- Time step %d, time = %g:\n", i, TIME); // this is needed to update the time-dependent boundary conditions ndofs = 0; ndofs += xvel_space.assign_dofs(ndofs); ndofs += yvel_space.assign_dofs(ndofs); ndofs += p_space.assign_dofs(ndofs); if (NEWTON) { // Newton's method if (!nls.solve_newton_3(&xvel_prev_newton, &yvel_prev_newton, &p_prev, NEWTON_TOL, NEWTON_MAX_ITER)) error("Newton's method did not converge."); // show the solution at the end of time step sprintf(title, "Velocity, time %g", TIME); vview.set_title(title); vview.show(&xvel_prev_newton, &yvel_prev_newton, EPS_LOW); sprintf(title, "Pressure, time %g", TIME); pview.set_title(title); pview.show(&p_prev); // copy the result of the Newton's iteration into the // previous time level solutions xvel_prev_time.copy(&xvel_prev_newton); yvel_prev_time.copy(&yvel_prev_newton); } else { // assemble and solve Solution xvel_sln, yvel_sln, p_sln; ls.assemble(); ls.solve(3, &xvel_sln, &yvel_sln, &p_sln); // show the solution at the end of time step sprintf(title, "Velocity, time %g", TIME); vview.set_title(title); vview.show(&xvel_sln, &yvel_sln, EPS_LOW); sprintf(title, "Pressure, time %g", TIME); pview.set_title(title); pview.show(&p_sln); // this copy destroys xvel_sln and yvel_sln // which are no longer needed xvel_prev_time = xvel_sln; yvel_prev_time = yvel_sln; } } // wait for keyboard or mouse input View::wait(); return 0; }