//// adapt ///////////////////////////////////////////////////////////////////////////////////////// bool HcurlOrthoHP::adapt(double thr, int strat, int adapt_type, bool iso_only, int regularize, int max_order) { if (!have_errors) error("Element errors have to be calculated first, see calc_error()."); int i, j; Mesh* mesh[10]; for (j = 0; j < num; j++) { mesh[j] = spaces[j]->get_mesh(); rsln[j]->set_quad_2d(&g_quad_2d_std); rsln[j]->enable_transform(false); } bool h_only = adapt_type == 1 ? true : false; double err0 = 1000.0; double processed_error = 0.0; int successfully_refined = 0; for (i = 0; i < nact; i++) { int comp = esort[i][1]; int id = esort[i][0]; double err = errors[comp][id]; // first refinement strategy: // refine elements until prescribed amount of error is processed // if more elements have similar error refine all to keep the mesh symmetric if ((strat == 0) && (processed_error > sqrt(thr) * total_err) && fabs((err - err0)/err0) > 1e-2) break; // second refinement strategy: // refine all elements whose error is bigger than some portion of maximal error if ((strat == 1) && (err < thr * errors[esort[0][1]][esort[0][0]])) break; Element* e; e = mesh[comp]->get_element(id); int split = 0; int p[4]; int current = spaces[comp]->get_element_order(id); // p-adaptivity if (adapt_type == 2) { split = -1; p[0] = std::min(9, get_h_order(current) + 1); if (get_h_order(current) < p[0]) successfully_refined++; } // h-adaptivity else if ((adapt_type == 1 && iso_only) || (adapt_type == 1 && e->is_triangle())) { p[0] = p[1] = p[2] = p[3] = current; } // hp-adaptivity else { get_optimal_refinement(e, current, rsln[comp], split, p, h_only, iso_only, max_order); successfully_refined++; } if (split < 0) spaces[comp]->set_element_order(id, p[0]); else if (split == 0) { mesh[comp]->refine_element(id); for (j = 0; j < 4; j++) spaces[comp]->set_element_order(e->sons[j]->id, p[j]); } else { mesh[comp]->refine_element(id, split); for (j = 0; j < 2; j++) spaces[comp]->set_element_order(e->sons[ (split == 1) ? j : j+2 ]->id, p[j]); } err0 = err; processed_error += err; } bool done = false; if (successfully_refined == 0) { warn("\nNone of the elements selected for refinement could be refined.\nAdaptivity step not successful, returning 'true'."); done = true; } // mesh regularization if (regularize >= 0) { if (regularize == 0) { regularize = 1; warn("Total mesh regularization is not supported in adaptivity. 1-irregular mesh is used instead."); } for (i = 0; i < num; i++) { int* parents; parents = mesh[i]->regularize(regularize); spaces[i]->distribute_orders(mesh[i], parents); delete [] parents; } } for (j = 0; j < num; j++) rsln[j]->enable_transform(true); verbose("Refined %d elements.", successfully_refined); have_errors = false; return done; }
void L2OrthoHP::adapt(double thr, int strat, bool h_only, bool iso_only, double conv_exp, int max_order) { if (!have_errors) error("Element errors have to be calculated first, see calc_error()."); int i, j; Mesh* mesh[10]; for (j = 0; j < num; j++) { mesh[j] = spaces[j]->get_mesh(); rsln[j]->set_quad_2d(&g_quad_2d_std); rsln[j]->enable_transform(false); } double err0 = 1000.0; double processed_error = 0.0; for (i = 0; i < nact; i++) { int comp = esort[i][1]; int id = esort[i][0]; double err = errors[comp][id]; // first refinement strategy: // refine elements until prescribed amount of error is processed // if more elements have similar error refine all to keep the mesh symmetric if ((strat == 0) && (processed_error > sqrt(thr) * total_err) && fabs((err - err0)/err0) > 1e-3) break; // second refinement strategy: // refine all elements whose error is bigger than some portion of maximal error if ((strat == 1) && (err < thr * errors[esort[0][1]][esort[0][0]])) break; Element* e; e = mesh[comp]->get_element(id); int split = 0; int p[4]; int current = spaces[comp]->get_element_order(id); //verbose("Refining element #%d, Component #%d, Error %g%%", e_id, comp, errors[comp][e_id]); if (h_only && iso_only) p[0] = p[1] = p[2] = p[3] = current; else get_optimal_refinement(e, current, rsln[comp], split, p, h_only, iso_only, conv_exp, max_order); //apply found division if (split < 0) { spaces[comp]->set_element_order_internal(id, p[0]); } else if (split == 0) { mesh[comp]->refine_element_id(id); for (j = 0; j < 4; j++) spaces[comp]->set_element_order_internal(e->sons[j]->id, p[j]); } else { mesh[comp]->refine_element_id(id, split); for (j = 0; j < 2; j++) spaces[comp]->set_element_order_internal(e->sons[ (split == 1) ? j : j+2 ]->id, p[j]); } err0 = err; processed_error += err; } for (j = 0; j < num; j++) rsln[j]->enable_transform(true); verbose("Refined %d elements.", i); have_errors = false; }