void DiscreteProblem::create_matrix() { // remove any previous matrix free_matrix_indices(); free_matrix_values(); // calculate the total number of DOFs ndofs = 0; for (int i = 0; i < neq; i++) ndofs += spaces[i]->get_num_dofs(); if (!quiet) verbose("Ndofs: %d", ndofs); if (!ndofs) return; // get row and column indices of nonzero matrix elements Page** pages = new Page*[ndofs]; memset(pages, 0, sizeof(Page*) * ndofs); if (!quiet) { verbose("Calculating matrix sparse structure..."); begin_time(); } precalculate_sparse_structure(pages); // initialize the arrays Ap and Ai Ap = (int*) malloc(sizeof(int) * (ndofs+1)); int aisize = get_num_indices(pages, ndofs); Ai = (int*) malloc(sizeof(int) * aisize); if (Ai == NULL) error("Out of memory. Could not allocate the array Ai."); // sort the indices and remove duplicities, insert into Ai int i, pos = 0, num; for (i = 0; i < ndofs; i++) { Ap[i] = pos; pos += sort_and_store_indices(pages[i], Ai + pos, Ai + aisize); } Ap[i] = pos; if (!quiet) verbose(" Nonzeros: %d\n Total matrix size: %0.1lf MB\n (time: %g sec)", pos, (double) get_matrix_size() / (1024*1024), end_time()); delete [] pages; // shrink Ai to the actual size int* oldAi = Ai; Ai = (int*) realloc(Ai, sizeof(int) * pos); if (oldAi != Ai) warn("Realloc moved Ai when shrinking."); // this should not happen // UMFPACK: perform symbolic analysis of the matrix if (!quiet) { verbose("Performing UMFPACK symbolic analysis..."); begin_time(); } int status = umfpack_symbolic(ndofs, ndofs, Ap, Ai, NULL, &Symbolic, NULL, NULL); if (status != UMFPACK_OK) umfpack_status(status); if (!quiet) verbose(" (time: %g sec)", end_time()); equi = (double*) malloc(sizeof(double) * ndofs); if (equi == NULL) error("Out of memory. Error allocating the equilibration vector."); for (int i = 0; i < ndofs; i++) equi[i] = 1.0; is_equi = false; }
int main(int argc, char* argv[]) { // Load the mesh Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // 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); // Enumerate basis functions space.assign_dofs(); // Initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, bilinear_form, bilinear_form_ord, SYM); wf.add_liform(0, linear_form, linear_form_ord); wf.add_liform_surf(0, linear_form_surf, linear_form_surf_ord, 2); // Visualize solution and mesh ScalarView sview("Coarse solution", 0, 100, 798, 700); OrderView oview("Polynomial orders", 800, 100, 798, 700); // Matrix solver UmfpackSolver solver; // Time measurement double cpu = 0; begin_time(); // Solve the problem Solution sln; LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln); // Time measurement cpu += end_time(); // View the solution and mesh sview.show(&sln); oview.show(&space); // Print timing information verbose("Total running time: %g sec", cpu); // wait for all views to be closed View::wait("Waiting for all views to be closed."); return 0; }
/** Nonadaptive solver.*/ void solveNonadaptive(Mesh &mesh, NonlinSystem &nls, Solution &Cp, Solution &Ci, Solution &phip, Solution &phii) { begin_time(); //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); #ifdef CONT_OUTPUT phiview.show(&phii); Cview.show(&Ci); Cview.wait_for_keypress(); #endif Solution Csln, phisln; for (int n = 1; n <= NSTEP; n++) { #ifdef VERBOSE info("\n---- Time step %d ----", n); #endif int it = 1; double res_l2_norm; do { #ifdef VERBOSE info("\n -------- Time step %d, Newton iter %d --------\n", n, it); #endif it++; nls.assemble(); nls.solve(2, &Csln, &phisln); res_l2_norm = nls.get_residuum_l2_norm(); #ifdef VERBOSE info("Residuum L2 norm: %g\n", res_l2_norm); #endif Ci.copy(&Csln); phii.copy(&phisln); } while (res_l2_norm > NEWTON_TOL); #ifdef CONT_OUTPUT phiview.show(&phii); Cview.show(&Ci); #endif phip.copy(&phii); Cp.copy(&Ci); } verbose("\nTotal run time: %g sec", end_time()); Cview.show(&Ci); phiview.show(&phii); //MeshView mview("small.mesh", 100, 30, 800, 800); //mview.show(&mesh); View::wait(); }
void DiscreteProblem::assemble_matrix_and_rhs(bool rhsonly) { int i, j, k, l, m, n; bool bnd[4], nat[neq]; EdgePos ep[4]; if (!ndofs) return; warned_order = false; if (!rhsonly) { alloc_matrix_values(); if (!quiet) { verbose("Assembling stiffness matrix..."); begin_time(); } } else { memset(RHS, 0, sizeof(scalar) * ndofs); if (!quiet) { verbose("Assembling RHS..."); begin_time(); } } // create slave pss's for test functions, init quadrature points PrecalcShapeset* spss[neq]; PrecalcShapeset *fu, *fv; for (i = 0; i < neq; i++) { spss[i] = new PrecalcShapeset(pss[i]); pss [i]->set_quad_2d(&g_quad_2d_std); spss[i]->set_quad_2d(&g_quad_2d_std); } // initialize buffer buffer = NULL; mat_size = 0; get_matrix_buffer(9); // initialize assembly lists, refmap AsmList al[neq], *am, *an; RefMap* refmap = new RefMap[neq]; for (i = 0; i < neq; i++) refmap[i].set_quad_2d(&g_quad_2d_std); for (i = 0; i < num_extern; i++) extern_fns[i]->set_quad_2d(&g_quad_2d_std); // init multi-mesh traversal int nm = neq + num_extern; Mesh* meshes[nm]; Transformable* fn[nm]; for (i = 0; i < neq; i++) meshes[i] = spaces[i]->get_mesh(); memcpy(fn, pss, neq * sizeof(Transformable*)); for (i = 0; i < num_extern; i++) { meshes[neq+i] = extern_fns[i]->get_mesh(); fn[neq+i] = extern_fns[i]; } // todo: kdyz maji nektere slozky stejnou sit, at sdili i refmapy // - ale to bysme potrebovali slave RefMap // loop through all elements Element** e; Traverse trav; trav.begin(nm, meshes, fn); while ((e = trav.get_next_state(bnd, ep)) != NULL) { // set maximum integration order for use in integrals, see limit_order() update_limit_table(e[0]->get_mode()); // obtain assembly lists for the element at all spaces, set appropriate mode for each pss for (i = 0; i < neq; i++) { spaces[i]->get_element_assembly_list(e[i], al + i); // todo: neziskavat znova, pokud se element nezmenil if (is_equi) for (j = 0; j < al[i].cnt; j++) if (al[i].dof[j] >= 0) al[i].coef[j] /= equi[al[i].dof[j]]; spss[i]->set_active_element(e[i]); spss[i]->set_master_transform(); refmap[i].set_active_element(e[i]); refmap[i].force_transform(pss[i]->get_transform(), pss[i]->get_ctm()); } // go through all equation-blocks of the element stiffness matrix, assemble volume integrals for (m = 0, am = al; m < neq; m++, am++) { fv = spss[m]; if (!rhsonly) { for (n = 0, an = al; n < neq; n++, an++) { fu = pss[n]; BiForm* bf = biform[m] + n; if (!bf->sym && !bf->unsym) continue; if (bf->unsym == BF_SYM || bf->unsym == BF_ANTISYM) continue; bool tra = (biform[n][m].unsym == BF_SYM || biform[n][m].unsym == BF_ANTISYM); // assemble the (m,n)-block of the stiffness matrix scalar sy, un, **mat = get_matrix_buffer(std::max(am->cnt, an->cnt)); for (i = 0; i < am->cnt; i++) { if (!tra && (k = am->dof[i]) < 0) continue; fv->set_active_shape(am->idx[i]); // unsymmetric block if (!bf->sym) { for (j = 0; j < an->cnt; j++) { fu->set_active_shape(an->idx[j]); un = bf->unsym(fu, fv, refmap+n, refmap+m) * an->coef[j] * am->coef[i]; if (an->dof[j] < 0) Dir[k] -= un; else mat[i][j] = un; } } // symmetric block else { for (j = 0; j < an->cnt; j++) { scalar coef = an->coef[j] * am->coef[i]; if (an->dof[j] < 0) { fu->set_active_shape(an->idx[j]); un = bf->unsym ? bf->unsym(fu, fv, refmap+n, refmap+m) * coef : 0.0; sy = bf->sym(fu, fv, refmap+n, refmap+m) * coef; Dir[k] -= (un + sy); } if (j >= i) { fu->set_active_shape(an->idx[j]); un = bf->unsym ? bf->unsym(fu, fv, refmap+n, refmap+m) * coef : 0.0; mat[j][i] = sy = bf->sym (fu, fv, refmap+n, refmap+m) * coef; mat[i][j] = (un + sy); } else if (bf->unsym) { fu->set_active_shape(an->idx[j]); mat[i][j] += bf->unsym(fu, fv, refmap+n, refmap+m) * coef; } } } } // insert the local stiffness matrix into the global one insert_matrix(mat, am->dof, an->dof, am->cnt, an->cnt); // insert also the off-diagonal (anti-)symmetric block, if required if (tra) { if (biform[n][m].unsym == BF_ANTISYM) chsgn(mat, am->cnt, an->cnt); transpose(mat, am->cnt, an->cnt); insert_matrix(mat, an->dof, am->dof, an->cnt, am->cnt); // we also need to take care of the RHS... for (j = 0; j < am->cnt; j++) if (am->dof[j] < 0) for (i = 0; i < an->cnt; i++) if (an->dof[i] >= 0) Dir[an->dof[i]] -= mat[i][j]; } } } // assemble rhs (linear form) if (!liform[m].lf) continue; for (i = 0; i < am->cnt; i++) { if (am->dof[i] < 0) continue; fv->set_active_shape(am->idx[i]); RHS[am->dof[i]] += liform[m].lf(fv, refmap+m) * am->coef[i]; } } // assemble surface integrals now: loop through boundary edges of the element if (rhsonly) continue; // fixme for (int edge = 0; edge < e[0]->nvert; edge++) { if (!bnd[edge]) continue; // obtain the list of shape functions which are nonzero on this edge for (i = 0; i < neq; i++) if ((nat[i] = (spaces[i]->bc_type_callback(ep[edge].marker) == BC_NATURAL))) spaces[i]->get_edge_assembly_list(e[i], edge, al + i); // loop through the equation-blocks for (m = 0, am = al; m < neq; m++, am++) { if (!nat[m]) continue; fv = spss[m]; ep[edge].base = trav.get_base(); ep[edge].space_v = spaces[m]; for (n = 0, an = al; n < neq; n++, an++) { if (!nat[n]) continue; BiForm* bf = biform[m] + n; if (!bf->surf) continue; fu = pss[n]; ep[edge].space_u = spaces[n]; // assemble the surface part of the bilinear form scalar bi, **mat = get_matrix_buffer(std::max(am->cnt, an->cnt)); for (i = 0; i < am->cnt; i++) { if ((k = am->dof[i]) < 0) continue; fv->set_active_shape(am->idx[i]); for (j = 0; j < an->cnt; j++) { fu->set_active_shape(an->idx[j]); bi = bf->surf(fu, fv, refmap+n, refmap+m, ep+edge) * an->coef[j] * am->coef[i]; if (an->dof[j] >= 0) mat[i][j] = bi; else Dir[k] -= bi; } } insert_matrix(mat, am->dof, an->dof, am->cnt, an->cnt); } // assemble the surface part of the linear form if (!liform[m].surf) continue; for (i = 0; i < am->cnt; i++) { if (am->dof[i] < 0) continue; fv->set_active_shape(am->idx[i]); RHS[am->dof[i]] += liform[m].surf(fv, refmap+m, ep+edge) * am->coef[i]; } } } } trav.finish(); for (i = 0; i < ndofs; i++) RHS[i] += Dir[i]; if (!quiet) verbose(" (time: %g sec)", end_time()); for (i = 0; i < neq; i++) delete spss[i]; delete [] buffer; delete [] refmap; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("square_quad.mesh", &mesh); // initial mesh refinement for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(); // 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); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form), SYM); wf.add_liform(0, linear_form, linear_form_ord); // visualize solution and mesh ScalarView sview("Coarse solution", 0, 100, 798, 700); OrderView oview("Polynomial orders", 800, 100, 798, 700); // matrix solver UmfpackSolver solver; // prepare selector RefinementSelectors::H1UniformHP selector(ISO_ONLY, ADAPT_TYPE, 1.0, H2DRS_DEFAULT_ORDER, &shapeset); // DOF and CPU convergence graphs SimpleGraph graph_dof_est, graph_dof_exact, graph_cpu_est, graph_cpu_exact; // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // time measurement cpu += end_time(); // calculate error wrt. exact solution ExactSolution exact(&mesh, fndd); double error = h1_error(&sln_coarse, &exact) * 100; info("\nExact solution error: %g%%", error); // view the solution sview.show(&sln_coarse); oview.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&ls); rs.assemble(); rs.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution H1AdaptHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Estimate of error: %g%%", err_est); // add entries to DOF convergence graphs graph_dof_exact.add_values(space.get_num_dofs(), error); graph_dof_exact.save("conv_dof_exact.dat"); graph_dof_est.add_values(space.get_num_dofs(), err_est); graph_dof_est.save("conv_dof_est.dat"); // add entries to CPU convergence graphs graph_cpu_exact.add_values(cpu, error); graph_cpu_exact.save("conv_cpu_exact.dat"); graph_cpu_est.add_values(cpu, err_est); graph_cpu_est.save("conv_cpu_est.dat"); // if err_est too large, adapt the mesh if (err_est < ERR_STOP) done = true; else { hp.adapt(THRESHOLD, STRATEGY, &selector, MESH_REGULARITY); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); //sview.wait_for_keypress(); } while (done == false); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result sview.set_title("Final solution"); sview.show(&sln_fine); // wait for keyboard or mouse input View::wait(); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("square_quad.mesh", &mesh); if(P_INIT == 1) P_INIT++; // this is because there are no degrees of freedom // on the coarse mesh lshape.mesh if P_INIT == 1 // 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); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form), SYM); wf.add_liform(0, callback(linear_form)); // visualize solution and mesh //ScalarView sview("Coarse solution", 0, 0, 500, 400); //OrderView oview("Polynomial orders", 505, 0, 500, 400); // matrix solver UmfpackSolver solver; // prepare selector RefinementSelectors::H1NonUniformHP selector(ISO_ONLY, ADAPT_TYPE, 1.0, H2DRS_DEFAULT_ORDER, &shapeset); // DOF and CPU convergence graphs SimpleGraph graph_dof_est, graph_dof_exact, graph_cpu_est, graph_cpu_exact; // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // time measurement cpu += end_time(); // calculate error wrt. exact solution ExactSolution exact(&mesh, fndd); double error = h1_error(&sln_coarse, &exact) * 100; info("\nExact solution error: %g%%", error); // view the solution //sview.show(&sln_coarse); //oview.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&ls); rs.assemble(); rs.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution H1AdaptHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Estimate of error: %g%%", err_est); // add entries to DOF convergence graphs graph_dof_exact.add_values(space.get_num_dofs(), error); graph_dof_exact.save("conv_dof_exact.dat"); graph_dof_est.add_values(space.get_num_dofs(), err_est); graph_dof_est.save("conv_dof_est.dat"); // add entries to CPU convergence graphs graph_cpu_exact.add_values(cpu, error); graph_cpu_exact.save("conv_cpu_exact.dat"); graph_cpu_est.add_values(cpu, err_est); graph_cpu_est.save("conv_cpu_est.dat"); // if err_est too large, adapt the mesh if (err_est < ERR_STOP) done = true; else { done = hp.adapt(THRESHOLD, STRATEGY, &selector, MESH_REGULARITY); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); // wait for keyboard or mouse input //sview.wait_for_keypress("Click into the mesh window and press any key to proceed."); } while (done == false); verbose("Total running time: %g sec", cpu); #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 int n_dof_allowed = 49; printf("n_dof_actual = %d\n", ndofs); printf("n_dof_allowed = %d\n", n_dof_allowed); // ndofs was 49 at the time this test was created if (ndofs <= n_dof_allowed) { printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; if (ALIGN_MESH) mloader.load("oven_load_circle.mesh", &mesh); else mloader.load("oven_load_square.mesh", &mesh); //mesh.refine_all_elements(); // initialize the shapeset and the cache HcurlShapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space HcurlSpace space(&mesh, &shapeset); space.set_bc_types(e_bc_types); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form)); wf.add_liform_surf(0, callback(linear_form_surf)); // visualize solution and mesh VectorView eview("Electric field",0,0,800, 590); OrderView ord("Order", 800, 0, 700, 590); /* // view the basis functions VectorBaseView bview; vbview.show(&space); vbview.wait_for_keypress(); */ // matrix solver UmfpackSolver solver; // DOF and CPU convergence graphs SimpleGraph graph_dof_est, graph_cpu_est; // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // coarse problem LinSystem sys(&wf, &solver); sys.set_spaces(1, &space); sys.set_pss(1, &pss); sys.assemble(); sys.solve(1, &sln_coarse); // time measurement cpu += end_time(); // show real part of the solution AbsFilter abs(&sln_coarse); eview.set_min_max_range(0, 4e3); eview.show(&abs); ord.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem ref(&sys); ref.assemble(); ref.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution HcurlOrthoHP hp(1, &space); hp.set_biform(0, 0, callback(hcurl_form_kappa)); double err_est_adapt = hp.calc_error(&sln_coarse, &sln_fine) * 100; double err_est_hcurl = hcurl_error(&sln_coarse, &sln_fine) * 100; info("Error estimate (adapt): %g%%", err_est_adapt); info("Error estimate (hcurl): %g%%", err_est_hcurl); // add entries to DOF convergence graphs graph_dof_est.add_values(space.get_num_dofs(), err_est_hcurl); graph_dof_est.save("conv_dof_est.dat"); // add entries to CPU convergence graphs graph_cpu_est.add_values(cpu, err_est_hcurl); graph_cpu_est.save("conv_cpu_est.dat"); // if err_est_adapt too large, adapt the mesh if (err_est_adapt < ERR_STOP) 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 == false); verbose("Total running time: %g sec", cpu); // wait for keyboard or mouse input View::wait("Waiting for all views to be closed."); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("screen-quad.mesh", &mesh); // mloader.load("screen-tri.mesh", &mesh); // initialize the shapeset and the cache HcurlShapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space HcurlSpace space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_bc_values(bc_values); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form), SYM); // visualize solution and mesh ScalarView Xview_r("Electric field X - real", 0, 0, 450, 420); ScalarView Yview_r("Electric field Y - real", 460, 0, 450, 420); ScalarView Xview_i("Electric field X - imag", 920, 0, 450, 420); ScalarView Yview_i("Electric field Y - imag", 1380, 0, 450, 420); OrderView ord("Polynomial Orders", 0, 460, 450, 420); /* // view the basis functions VectorBaseView bview; vbview.show(&space); vbview.wait_for_keypress(); */ // matrix solver UmfpackSolver solver; // DOF and CPU convergence graphs SimpleGraph graph_dof_est, graph_dof_exact, graph_cpu_est, graph_cpu_exact; // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem sys(&wf, &solver); sys.set_spaces(1, &space); sys.set_pss(1, &pss); sys.assemble(); sys.solve(1, &sln_coarse); // time measurement cpu += end_time(); // calculating error wrt. exact solution Solution ex; ex.set_exact(&mesh, exact); double err_exact = 100 * hcurl_error(&sln_coarse, &ex); info("Exact solution error: %g%%", err_exact); // visualization RealFilter real(&sln_coarse); ImagFilter imag(&sln_coarse); Xview_r.set_min_max_range(-3.0, 1.0); //Xview_r.show_scale(false); Xview_r.show(&real, EPS_NORMAL, FN_VAL_0); Yview_r.set_min_max_range(-4.0, 4.0); //Yview_r.show_scale(false); Yview_r.show(&real, EPS_NORMAL, FN_VAL_1); Xview_i.set_min_max_range(-1.0, 4.0); //Xview_i.show_scale(false); Xview_i.show(&imag, EPS_NORMAL, FN_VAL_0); Yview_i.set_min_max_range(-4.0, 4.0); //Yview_i.show_scale(false); Yview_i.show(&imag, EPS_NORMAL, FN_VAL_1); ord.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem ref(&sys); ref.assemble(); ref.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution HcurlOrthoHP hp(1, &space); double err_est_adapt = hp.calc_error(&sln_coarse, &sln_fine) * 100; double err_est_hcurl = hcurl_error(&sln_coarse, &sln_fine) * 100; info("Error estimate (adapt): %g%%", err_est_adapt); info("Error estimate (hcurl): %g%%", err_est_hcurl); // add entries to DOF convergence graphs graph_dof_exact.add_values(space.get_num_dofs(), err_exact); graph_dof_exact.save("conv_dof_exact.dat"); graph_dof_est.add_values(space.get_num_dofs(), err_est_hcurl); graph_dof_est.save("conv_dof_est.dat"); // add entries to CPU convergence graphs graph_cpu_exact.add_values(cpu, err_exact); graph_cpu_exact.save("conv_cpu_exact.dat"); graph_cpu_est.add_values(cpu, err_est_hcurl); graph_cpu_est.save("conv_cpu_est.dat"); // if err_est_adapt too large, adapt the mesh if (err_est_adapt < ERR_STOP) 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); verbose("Total running time: %g sec", cpu); // wait for keyboard or mouse input View::wait("Waiting for all views to be closed."); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("lshape3q.mesh", &mesh); // mloader.load("lshape3t.mesh", &mesh); // initialize the shapeset and the cache HcurlShapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space HcurlSpace space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form), SYM); wf.add_biform_surf(0, 0, callback(bilinear_form_surf)); wf.add_liform_surf(0, linear_form_surf, linear_form_surf_ord); // visualize solution and mesh OrderView ordview("Polynomial Orders", 600, 0, 600, 500); VectorView vecview("Real part of Electric Field - VectorView", 0, 0, 600, 500); /* // view the basis functions VectorBaseView bview; vbview.show(&space); vbview.wait_for_keypress(); */ // matrix solver UmfpackSolver solver; // DOF and CPU convergence graphs SimpleGraph graph_dof_est, graph_dof_exact, graph_cpu_est, graph_cpu_exact; // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem sys(&wf, &solver); sys.set_spaces(1, &space); sys.set_pss(1, &pss); sys.assemble(); sys.solve(1, &sln_coarse); // time measurement cpu += end_time(); // calculating error wrt. exact solution ExactSolution ex(&mesh, exact); double err_exact = 100 * hcurl_error(&sln_coarse, &ex); info("Exact solution error: %g%%", err_exact); // show real part of the solution and mesh ordview.show(&space); RealFilter real(&sln_coarse); vecview.set_min_max_range(0, 1); vecview.show(&real, EPS_HIGH); // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&sys); rs.assemble(); rs.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution HcurlOrthoHP hp(1, &space); double err_est_adapt = hp.calc_error(&sln_coarse, &sln_fine) * 100; double err_est_hcurl = hcurl_error(&sln_coarse, &sln_fine) * 100; info("Error estimate (adapt): %g%%", err_est_adapt); info("Error estimate (hcurl): %g%%", err_est_hcurl); // add entries to DOF convergence graphs graph_dof_exact.add_values(space.get_num_dofs(), err_exact); graph_dof_exact.save("conv_dof_exact.dat"); graph_dof_est.add_values(space.get_num_dofs(), err_est_hcurl); graph_dof_est.save("conv_dof_est.dat"); // add entries to CPU convergence graphs graph_cpu_exact.add_values(cpu, err_exact); graph_cpu_exact.save("conv_cpu_exact.dat"); graph_cpu_est.add_values(cpu, err_est_hcurl); graph_cpu_est.save("conv_cpu_est.dat"); // if err_est_adapt too large, adapt the mesh if (err_est_adapt < ERR_STOP) 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); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result vecview.set_title("Final solution"); vecview.show(&sln_fine); // wait for keyboard or mouse input View::wait("Waiting for all views to be closed."); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; mesh.load("square_quad.mesh"); if(P_INIT == 1) mesh.refine_all_elements(); // this is because there are no degrees of freedom // on the coarse mesh lshape.mesh if P_INIT == 1 // initialize the shapeset and the cache H1ShapesetOrtho shapeset; PrecalcShapeset pss(&shapeset); // create finite element space H1Space space(&mesh, &shapeset); space.set_bc_values(bc_values); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, bilinear_form, SYM); wf.add_liform(0, linear_form); // visualize solution and mesh ScalarView sview("Coarse solution", 0, 100, 798, 700); OrderView oview("Polynomial orders", 800, 100, 798, 700); // matrix solver UmfpackSolver solver; // convergence graph wrt. the number of degrees of freedom GnuplotGraph graph; graph.set_log_y(); graph.set_captions("Error Convergence for the Inner Layer Problem", "Degrees of Freedom", "Error [%]"); graph.add_row("exact error", "k", "-", "o"); graph.add_row("error estimate", "k", "--"); // convergence graph wrt. CPU time GnuplotGraph graph_cpu; graph_cpu.set_captions("Error Convergence for the Inner Layer Problem", "CPU Time", "Error Estimate [%]"); graph_cpu.add_row("exact error", "k", "-", "o"); graph_cpu.add_row("error estimate", "k", "--"); graph_cpu.set_log_y(); // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // time measurement cpu += end_time(); // calculate error wrt. exact solution ExactSolution exact(&mesh, fndd); double error = h1_error(&sln_coarse, &exact) * 100; info("\nExact solution error: %g%%", error); // view the solution and mesh sview.show(&sln_coarse); oview.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&ls); rs.assemble(); rs.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution H1OrthoHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Estimate of error: %g%%", err_est); // add entry to DOF convergence graph graph.add_values(0, space.get_num_dofs(), error); graph.add_values(1, space.get_num_dofs(), err_est); graph.save("conv_dof.gp"); // add entry to CPU convergence graph graph_cpu.add_values(0, cpu, error); graph_cpu.add_values(1, cpu, err_est); graph_cpu.save("conv_cpu.gp"); // 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); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result sview.set_title("Final solution"); sview.show(&sln_fine); // wait for keyboard or mouse input printf("Waiting for keyboard or mouse input.\n"); View::wait(); return 0; }
void Linearizer::process_solution(MeshFunction* sln, int item, double eps, double max_abs, MeshFunction* xdisp, MeshFunction* ydisp, double dmult) { lock_data(); begin_time(); // initialization this->sln = sln; this->item = item; this->eps = eps; this->xdisp = xdisp; this->ydisp = ydisp; this->dmult = dmult; nv = nt = ne = 0; del_slot = -1; if (!item) error("'item' cannot be zero."); get_gv_a_b(item, ia, ib); if (ib >= 6) error("Invalid 'item'."); disp = (xdisp != NULL || ydisp != NULL); if (disp && (xdisp == NULL || ydisp == NULL)) error("Both displacement components must be supplied."); // estimate the required number of vertices and triangles Mesh* mesh = sln->get_mesh(); int nn = mesh->get_num_elements(); int ev = std::max(32 * nn, 10000); // todo: check this int et = std::max(64 * nn, 20000); int ee = std::max(24 * nn, 7500); // check that displacement meshes are the same if (disp) { unsigned seq1 = mesh->get_seq(); unsigned seq2 = xdisp->get_mesh()->get_seq(); unsigned seq3 = ydisp->get_mesh()->get_seq(); if (seq1 != seq2 || seq1 != seq3) error("Displacements must be defined on the same mesh as the solution."); } // reuse or allocate vertex, triangle and edge arrays lin_init_array(verts, double3, cv, ev); lin_init_array(tris, int3, ct, et); lin_init_array(edges, int3, ce, ee); info = (int4*) malloc(sizeof(int4) * cv); // initialize the hash table int size = 0x2000; while (size*2 < cv) size *= 2; hash_table = (int*) malloc(sizeof(int) * size); memset(hash_table, 0xff, sizeof(int) * size); mask = size-1; // select the linearization quadrature Quad2D *old_quad, *old_quad_x, *old_quad_y; old_quad = sln->get_quad_2d(); sln->set_quad_2d(&quad_lin); if (disp) { old_quad_x = xdisp->get_quad_2d(); old_quad_y = ydisp->get_quad_2d(); xdisp->set_quad_2d(&quad_lin); ydisp->set_quad_2d(&quad_lin); } // create all top-level vertices (corresponding to vertex nodes), with // all parent-son relations preserved; this is necessary for regularization to // work on irregular meshes nn = mesh->get_max_node_id(); int* id2id = new int[nn]; memset(id2id, 0xff, sizeof(int) * nn); bool finished; do { finished = true; Node* node; for_all_vertex_nodes(node, mesh) { if (id2id[node->id] < 0 && node->ref != TOP_LEVEL_REF) if (node->p1 < 0) id2id[node->id] = get_vertex(node->id, node->id, node->x, node->y, 0); else if (id2id[node->p1] >= 0 && id2id[node->p2] >= 0) id2id[node->id] = get_vertex(id2id[node->p1], id2id[node->p2], node->x, node->y, 0); else finished = false; } } while (!finished); auto_max = (max_abs < 0.0); max = auto_max ? 0.0 : max_abs; // obtain the solution in vertices, estimate the maximum solution value Element* e; for_all_active_elements(e, mesh) { sln->set_active_element(e); sln->set_quad_order(0, item); scalar* val = sln->get_values(ia, ib); if (val == NULL) error("item not defined in the solution."); scalar *dx, *dy; if (disp) { xdisp->set_active_element(e); ydisp->set_active_element(e); xdisp->set_quad_order(0, FN_VAL); ydisp->set_quad_order(0, FN_VAL); dx = xdisp->get_fn_values(); dy = ydisp->get_fn_values(); } for (unsigned int i = 0; i < e->nvert; i++) { double f = getval(i); if (auto_max && finite(f) && fabs(f) > max) max = fabs(f); int id = id2id[e->vn[i]->id]; verts[id][2] = f; if (disp) { verts[id][0] = e->vn[i]->x + dmult*realpart(dx[i]); verts[id][1] = e->vn[i]->y + dmult*realpart(dy[i]); } } }
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 Mesh mesh; if (ALIGN_MESH) mesh.load("oven_load_circle.mesh"); else mesh.load("oven_load_square.mesh"); // initialize the shapeset and the cache HcurlShapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space HcurlSpace space(&mesh, &shapeset); space.set_bc_types(e_bc_types); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, bilinear_form); wf.add_liform_surf(0, linear_form_surf); // visualize solution and mesh VectorView eview("Electric field",0,0,800, 590); OrderView ord("Order", 800, 0, 700, 590); // matrix solver UmfpackSolver solver; // convergence graph wrt. the number of degrees of freedom GnuplotGraph graph; graph.set_captions("Error Convergence for the Waveguide Problem", "Degrees of Freedom", "Error Estimate [%]"); graph.add_row("error estimate", "-", "o"); graph.set_log_y(); // convergence graph wrt. CPU time GnuplotGraph graph_cpu; graph_cpu.set_captions("Error Convergence for the Waveguide Problem", "CPU Time", "Error Estimate [%]"); graph_cpu.add_row("error estimate", "-", "o"); graph_cpu.set_log_y(); // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // coarse problem LinSystem sys(&wf, &solver); sys.set_spaces(1, &space); sys.set_pss(1, &pss); sys.assemble(); sys.solve(1, &sln_coarse); // time measurement cpu += end_time(); // show real part of the solution AbsFilter abs(&sln_coarse); eview.set_min_max_range(0, 4e3); eview.show(&abs); ord.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem ref(&sys); ref.assemble(); ref.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution HcurlOrthoHP hp(1, &space); hp.set_kappa(sqr(kappa)); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Hcurl error estimate: %g%%", hcurl_error(&sln_coarse, &sln_fine) * 100); info("Adapt error estimate: %g%%", err_est); // add entry to DOF convergence graph graph.add_values(0, space.get_num_dofs(), err_est); graph.save("conv_dof.gp"); // add entry to CPU convergence graph graph_cpu.add_values(0, cpu, err_est); graph_cpu.save("conv_cpu.gp"); // 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); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); // wait for keyboard or mouse input printf("Waiting for keyboard or mouse input.\n"); View::wait(); return 0; }
int main(int argc, char* argv[]) { // Load the mesh Mesh mesh; H2DReader mloader; mloader.load("domain.mesh", &mesh); mesh.refine_all_elements(); // 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); // Enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, bilinear_form, bilinear_form_ord, SYM); wf.add_liform(0, linear_form, linear_form_ord); wf.add_liform_surf(0, linear_form_surf, linear_form_surf_ord, 2); // Visualize solution and mesh ScalarView sview("Coarse solution", 0, 100, 798, 700); OrderView oview("Polynomial orders", 800, 100, 798, 700); // Matrix solver UmfpackSolver solver; // DOF and CPU convergence graphs SimpleGraph graph_dof, graph_cpu; // Adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // Time measurement begin_time(); // Solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // Time measurement cpu += end_time(); // View the solution and mesh sview.show(&sln_coarse); oview.show(&space); // Time measurement begin_time(); // Solve the fine mesh problem RefSystem rs(&ls); rs.assemble(); rs.solve(1, &sln_fine); // Calculate error estimate wrt. fine mesh solution H1OrthoHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Estimate of error: %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); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // Time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); // Show the fine solution - this is the final result sview.set_title("Final solution"); sview.show(&sln_fine); // Wait for keyboard or mouse input View::wait("Waiting for all views to be closed."); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh xmesh, ymesh; H2DReader mloader; mloader.load("bracket.mesh", &xmesh); // create initial mesh for the vertical displacement component, // identical to the mesh for the horizontal displacement // (bracket.mesh becomes a master mesh) ymesh.copy(&xmesh); // initialize the shapeset and the cache H1Shapeset shapeset; PrecalcShapeset xpss(&shapeset); PrecalcShapeset ypss(&shapeset); // create the x displacement space H1Space xdisp(&xmesh, &shapeset); xdisp.set_bc_types(bc_types); xdisp.set_bc_values(bc_values); xdisp.set_uniform_order(P_INIT); // create the y displacement space H1Space ydisp(MULTI ? &ymesh : &xmesh, &shapeset); ydisp.set_bc_types(bc_types); ydisp.set_bc_values(bc_values); ydisp.set_uniform_order(P_INIT); // enumerate basis functions int ndofs = xdisp.assign_dofs(); ndofs += ydisp.assign_dofs(ndofs); // initialize the weak formulation WeakForm wf(2); wf.add_biform(0, 0, callback(bilinear_form_0_0), SYM); // note that only one symmetric part is wf.add_biform(0, 1, callback(bilinear_form_0_1), SYM); // added in the case of symmetric bilinear wf.add_biform(1, 1, callback(bilinear_form_1_1), SYM); // forms wf.add_liform_surf(1, callback(linear_form_surf_1), marker_top); // visualization of solution and meshes OrderView xoview("X polynomial orders", 0, 0, 500, 500); OrderView yoview("Y polynomial orders", 510, 0, 500, 500); ScalarView sview("Von Mises stress [Pa]", 1020, 0, 500, 500); // matrix solver UmfpackSolver umfpack; // DOF and CPU convergence graphs SimpleGraph graph_dof, graph_cpu; // adaptivity loop int it = 1; bool done = false; double cpu = 0.0; Solution x_sln_coarse, y_sln_coarse; Solution x_sln_fine, y_sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); //calculating the number of degrees of freedom ndofs = xdisp.assign_dofs(); ndofs += ydisp.assign_dofs(ndofs); printf("xdof=%d, ydof=%d\n", xdisp.get_num_dofs(), ydisp.get_num_dofs()); // solve the coarse mesh problem LinSystem ls(&wf, &umfpack); ls.set_spaces(2, &xdisp, &ydisp); ls.set_pss(2, &xpss, &ypss); ls.assemble(); ls.solve(2, &x_sln_coarse, &y_sln_coarse); // time measurement cpu += end_time(); // view the solution -- this can be slow; for illustration only VonMisesFilter stress_coarse(&x_sln_coarse, &y_sln_coarse, mu, lambda); sview.set_min_max_range(0, 3e4); sview.show(&stress_coarse); xoview.show(&xdisp); yoview.show(&ydisp); // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&ls); rs.assemble(); rs.solve(2, &x_sln_fine, &y_sln_fine); // calculate element errors and total error estimate H1OrthoHP hp(2, &xdisp, &ydisp); hp.set_biform(0, 0, bilinear_form_0_0<scalar, scalar>, bilinear_form_0_0<Ord, Ord>); hp.set_biform(0, 1, bilinear_form_0_1<scalar, scalar>, bilinear_form_0_1<Ord, Ord>); hp.set_biform(1, 0, bilinear_form_1_0<scalar, scalar>, bilinear_form_1_0<Ord, Ord>); hp.set_biform(1, 1, bilinear_form_1_1<scalar, scalar>, bilinear_form_1_1<Ord, Ord>); double err_est = hp.calc_error_2(&x_sln_coarse, &y_sln_coarse, &x_sln_fine, &y_sln_fine) * 100; info("Estimate of error: %g%%", err_est); // time measurement cpu += end_time(); // add entry to DOF convergence graph graph_dof.add_values(xdisp.get_num_dofs() + ydisp.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, CONV_EXP, MAX_ORDER, SAME_ORDERS); ndofs = xdisp.assign_dofs(); ndofs += ydisp.assign_dofs(ndofs); if (ndofs >= NDOF_STOP) done = true; } } while (!done); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result VonMisesFilter stress_fine(&x_sln_fine, &y_sln_fine, mu, lambda); sview.set_title("Final solution"); sview.set_min_max_range(0, 3e4); sview.show(&stress_fine); // wait for all views to be closed View::wait(); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("motor.mesh", &mesh); // 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); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(biform1), SYM, 1); wf.add_biform(0, 0, callback(biform2), SYM, 2); // visualize solution, gradient, and mesh ScalarView sview("Coarse solution", 0, 0, 600, 1000); VectorView gview("Gradient", 610, 0, 600, 1000); OrderView oview("Polynomial orders", 1220, 0, 600, 1000); //gview.set_min_max_range(0.0, 400.0); // matrix solver UmfpackSolver solver; // DOF and CPU convergence graphs SimpleGraph graph_dof, graph_cpu; // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // time measurement cpu += end_time(); // view the solution -- this can be slow; for illustration only sview.show(&sln_coarse); gview.show(&sln_coarse, &sln_coarse, EPS_NORMAL, FN_DX_0, FN_DY_0); oview.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&ls); rs.assemble(); rs.solve(1, &sln_fine); // calculate element errors and total error estimate H1OrthoHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Error estimate: %g%%", err_est); // time measurement cpu += end_time(); // 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); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } } while (done == false); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result sview.set_title("Final solution"); sview.show(&sln_fine); gview.show(&sln_fine, &sln_fine, EPS_HIGH, FN_DX_0, FN_DY_0); // wait for all views to be closed View::wait(); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("square_quad.mesh", &mesh); // mloader.load("square_tri.mesh", &mesh); for (int i=0; i<INIT_REF_NUM; i++) mesh.refine_all_elements(); // 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); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form), SYM); wf.add_liform(0, callback(linear_form)); // matrix solver UmfpackSolver solver; // prepare selector RefinementSelectors::H1NonUniformHP selector(ISO_ONLY, ADAPT_TYPE, CONV_EXP, H2DRS_DEFAULT_ORDER, &shapeset); // convergence graph wrt. the number of degrees of freedom GnuplotGraph graph; graph.set_log_y(); graph.set_captions("Error Convergence for the Inner Layer Problem", "Degrees of Freedom", "Error [%]"); graph.add_row("exact error", "k", "-", "o"); graph.add_row("error estimate", "k", "--"); // convergence graph wrt. CPU time GnuplotGraph graph_cpu; graph_cpu.set_captions("Error Convergence for the Inner Layer Problem", "CPU Time", "Error Estimate [%]"); graph_cpu.add_row("exact error", "k", "-", "o"); graph_cpu.add_row("error estimate", "k", "--"); graph_cpu.set_log_y(); // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // time measurement cpu += end_time(); // calculate error wrt. exact solution ExactSolution exact(&mesh, fndd); double error = h1_error(&sln_coarse, &exact) * 100; // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&ls); rs.assemble(); rs.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution H1AdaptHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Exact solution error: %g%%", error); info("Estimate of error: %g%%", err_est); // add entry to DOF convergence graph graph.add_values(0, space.get_num_dofs(), error); graph.add_values(1, space.get_num_dofs(), err_est); graph.save("conv_dof.gp"); // add entry to CPU convergence graph graph_cpu.add_values(0, cpu, error); graph_cpu.add_values(1, cpu, err_est); graph_cpu.save("conv_cpu.gp"); // if err_est too large, adapt the mesh if (err_est < ERR_STOP) done = true; else { hp.adapt(THRESHOLD, STRATEGY, &selector, MESH_REGULARITY); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 int n_dof_allowed = 4000; printf("n_dof_actual = %d\n", ndofs); printf("n_dof_allowed = %d\n", n_dof_allowed); if (ndofs <= n_dof_allowed) { printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; mesh.load("screen-quad.mesh"); // mesh.load("screen-tri.mesh"); // initialize the shapeset and the cache HcurlShapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space HcurlSpace space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_bc_values(bc_values); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form), SYM); // visualize solution and mesh ScalarView Xview_r("Electric field X - real", 0, 0, 320, 320); ScalarView Yview_r("Electric field Y - real", 325, 0, 320, 320); ScalarView Xview_i("Electric field X - imag", 650, 0, 320, 320); ScalarView Yview_i("Electric field Y - imag", 975, 0, 320, 320); OrderView ord("Polynomial Orders", 325, 400, 600, 600); // matrix solver UmfpackSolver solver; // convergence graph wrt. the number of degrees of freedom GnuplotGraph graph; graph.set_captions("Error Convergence for the Screen Problem in H(curl)", "Degrees of Freedom", "Error [%]"); graph.add_row("exact error", "k", "-", "o"); graph.add_row("error estimate", "k", "--"); graph.set_log_y(); // convergence graph wrt. CPU time GnuplotGraph graph_cpu; graph_cpu.set_captions("Error Convergence for the Screen Problem in H(curl)", "CPU Time", "Error [%]"); graph_cpu.add_row("exact error", "k", "-", "o"); graph_cpu.add_row("error estimate", "k", "--"); graph_cpu.set_log_y(); // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem sys(&wf, &solver); sys.set_spaces(1, &space); sys.set_pss(1, &pss); sys.assemble(); sys.solve(1, &sln_coarse); // time measurement cpu += end_time(); // calculating error wrt. exact solution Solution ex; ex.set_exact(&mesh, exact); double error = 100 * hcurl_error(&sln_coarse, &ex); info("Exact solution error: %g%%", error); // visualization RealFilter real(&sln_coarse); ImagFilter imag(&sln_coarse); Xview_r.set_min_max_range(-3.0, 1.0); Xview_r.show_scale(false); Xview_r.show(&real, EPS_NORMAL, FN_VAL_0); Yview_r.set_min_max_range(-4.0, 4.0); Yview_r.show_scale(false); Yview_r.show(&real, EPS_NORMAL, FN_VAL_1); Xview_i.set_min_max_range(-1.0, 4.0); Xview_i.show_scale(false); Xview_i.show(&imag, EPS_NORMAL, FN_VAL_0); Yview_i.set_min_max_range(-4.0, 4.0); Yview_i.show_scale(false); Yview_i.show(&imag, EPS_NORMAL, FN_VAL_1); ord.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem ref(&sys); ref.assemble(); ref.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution HcurlOrthoHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Error estimate: %g%%", err_est); // add entry to DOF convergence graph graph.add_values(0, space.get_num_dofs(), error); graph.add_values(1, space.get_num_dofs(), err_est); graph.save("conv_dof.gp"); // add entry to CPU convergence graph graph_cpu.add_values(0, cpu, error); graph_cpu.add_values(1, cpu, err_est); graph_cpu.save("conv_cpu.gp"); // 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); ndofs = space.assign_dofs(); if (ndofs >= 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("Waiting for keyboard or mouse input."); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("domain2.mesh", &mesh); // initial uniform subdivision //mesh.refine_all_elements(); // 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(dir_bc_values); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form_iron), SYM, 3); wf.add_biform(0, 0, callback(bilinear_form_wire), SYM, 2); wf.add_biform(0, 0, callback(bilinear_form_air), SYM, 1); wf.add_liform(0, callback(linear_form_wire), 2); // visualize solution and mesh ScalarView view("Vector potential A", 0, 0, 1000, 600); OrderView oview("Polynomial orders", 1100, 0, 900, 600); // matrix solver UmfpackSolver solver; // DOF and CPU convergence graphs SimpleGraph graph_dof_est, graph_dof_exact, graph_cpu_est, graph_cpu_exact; // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem sys(&wf, &solver); sys.set_spaces(1, &space); sys.set_pss(1, &pss); // time measurement cpu += end_time(); // assemble the stiffness matrix and solve the system sys.assemble(); sys.solve(1, &sln_coarse); // visualize the solution view.show(&sln_coarse, EPS_HIGH); oview.show(&space); // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&sys); rs.assemble(); rs.solve(1, &sln_fine); // calculate element errors and total error estimate H1OrthoHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Error estimate: %g%%", err_est); // add entries to DOF convergence graph graph_dof_est.add_values(space.get_num_dofs(), err_est); graph_dof_est.save("conv_dof.dat"); // add entries to CPU convergence graph graph_cpu_est.add_values(cpu, err_est); graph_cpu_est.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); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result view.set_title("Final solution"); view.show(&sln_fine); // wait for keyboard or mouse input View::wait("Waiting for all views to be closed."); return 0; }
int main(int argc, char* argv[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("lshape3q.mesh", &mesh); // mloader.load("lshape3t.mesh", &mesh); // initialize the shapeset and the cache HcurlShapeset shapeset; PrecalcShapeset pss(&shapeset); // create finite element space HcurlSpace space(&mesh, &shapeset); space.set_bc_types(bc_types); space.set_uniform_order(P_INIT); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form), SYM); wf.add_biform_surf(0, 0, callback(bilinear_form_surf)); wf.add_liform_surf(0, linear_form_surf, linear_form_surf_ord); // matrix solver UmfpackSolver solver; // convergence graph wrt. the number of degrees of freedom GnuplotGraph graph; graph.set_captions("Error Convergence for the Bessel Problem in H(curl)", "Degrees of Freedom", "Error [%]"); graph.add_row("exact error", "k", "-", "o"); graph.add_row("error estimate", "k", "--"); graph.set_log_y(); // convergence graph wrt. CPU time GnuplotGraph graph_cpu; graph_cpu.set_captions("Error Convergence for the Bessel Problem in H(curl)", "CPU Time", "Error [%]"); graph_cpu.add_row("exact error", "k", "-", "o"); graph_cpu.add_row("error estimate", "k", "--"); graph_cpu.set_log_y(); // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem sys(&wf, &solver); sys.set_spaces(1, &space); sys.set_pss(1, &pss); sys.assemble(); sys.solve(1, &sln_coarse); // time measurement cpu += end_time(); // calculating error wrt. exact solution ExactSolution ex(&mesh, exact); double err = 100 * hcurl_error(&sln_coarse, &ex); info("Exact solution error: %g%%", err); // time measurement begin_time(); // solve the fine mesh problem RefSystem rs(&sys); rs.assemble(); rs.solve(1, &sln_fine); // calculate error estimate wrt. fine mesh solution HcurlOrthoHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Error estimate: %g%%", err_est); // add entry to DOF convergence graph graph.add_values(0, space.get_num_dofs(), err); graph.add_values(1, space.get_num_dofs(), err_est); graph.save("conv_dof.gp"); // add entry to CPU convergence graph graph_cpu.add_values(0, cpu, err); graph_cpu.add_values(1, cpu, err_est); graph_cpu.save("conv_cpu.gp"); // 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); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (!done); verbose("Total running time: %g sec", cpu); #define ERROR_SUCCESS 0 #define ERROR_FAILURE -1 int n_dof_allowed = 3000; printf("n_dof_actual = %d\n", ndofs); printf("n_dof_allowed = %d\n", n_dof_allowed);// ndofs was 2680 at the time this test was created if (ndofs <= n_dof_allowed) { printf("Success!\n"); return ERROR_SUCCESS; } else { printf("Failure!\n"); return ERROR_FAILURE; } }
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[]) { // load the mesh Mesh mesh; H2DReader mloader; mloader.load("square_quad.mesh", &mesh); // mloader.load("square_tri.mesh", &mesh); for (int i=0; i<INIT_REF_NUM; i++) mesh.refine_all_elements(); mesh.refine_towards_boundary(2, INIT_REF_NUM_BDY); // 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); // enumerate basis functions space.assign_dofs(); // initialize the weak formulation WeakForm wf(1); wf.add_biform(0, 0, callback(bilinear_form)); if (STABILIZATION_ON == true) { wf.add_biform(0, 0, bilinear_form_stabilization, bilinear_form_stabilization_order); } if (SHOCK_CAPTURING_ON == true) { wf.add_biform(0, 0, bilinear_form_shock_capturing, bilinear_form_shock_capturing_order); } // visualize solution and mesh OrderView oview("Coarse mesh", 0, 0, 500, 400); ScalarView sview("Coarse mesh solution", 510, 0, 500, 400); ScalarView sview2("Fine mesh solution", 1020, 0, 500, 400); // matrix solver UmfpackSolver solver; // DOF convergence graph SimpleGraph graph_dof_est, graph_cpu_est; // prepare selector RefinementSelectors::H1NonUniformHP selector(ISO_ONLY, ADAPT_TYPE, CONV_EXP, H2DRS_DEFAULT_ORDER, &shapeset); // adaptivity loop int it = 1, ndofs; bool done = false; double cpu = 0.0; Solution sln_coarse, sln_fine; do { info("\n---- Adaptivity step %d ---------------------------------------------\n", it++); // time measurement begin_time(); // solve the coarse mesh problem LinSystem ls(&wf, &solver); ls.set_spaces(1, &space); ls.set_pss(1, &pss); ls.assemble(); ls.solve(1, &sln_coarse); // solve the fine mesh problem int p_increase; if (ADAPT_TYPE == RefinementSelectors::H2DRS_CAND_HP) p_increase = 1; else p_increase = 0; RefSystem rs(&ls, p_increase, 1); // the '1' is for one level of global refinement in space rs.assemble(); rs.solve(1, &sln_fine); // time measurement cpu += end_time(); // show fine mesh solution // view the solution and mesh oview.show(&space); sview.show(&sln_coarse); sview2.show(&sln_fine); //sview.wait_for_keypress(); // time measurement begin_time(); // calculate error estimate wrt. fine mesh solution H1AdaptHP hp(1, &space); double err_est = hp.calc_error(&sln_coarse, &sln_fine) * 100; info("Estimate of error: %g%%", err_est); // add entries to DOF and CPU convergence graphs graph_dof_est.add_values(space.get_num_dofs(), err_est); graph_dof_est.save("conv_dof_est.dat"); graph_cpu_est.add_values(cpu, err_est); graph_cpu_est.save("conv_cpu_est.dat"); // if err_est too large, adapt the mesh if (err_est < ERR_STOP) done = true; else { hp.adapt(THRESHOLD, STRATEGY, &selector, MESH_REGULARITY); ndofs = space.assign_dofs(); if (ndofs >= NDOF_STOP) done = true; } // time measurement cpu += end_time(); } while (done == false); verbose("Total running time: %g sec", cpu); // show the fine solution - this is the final result sview.set_title("Final solution"); sview.show(&sln_fine); // wait for keyboard or mouse input View::wait(); return 0; }