35 double h_ref,
int p_ref,
double rho_ref,
36 double h,
double rho,
int p_max)
38 const double sigma_ref = rho_ref / h_ref;
39 const double sigma = rho / h;
41 const double ptmp = h1_formula ? (std::log(B * std::pow(h_ref, p_ref + 1) * rho / (h * rho_ref)) / std::log(h)) : (std::log(B * std::pow(h_ref, p_ref + 1) * sigma * sigma / sigma_ref / sigma_ref) - std::log(h)) / std::log(h);
44 return std::min(std::max(p_ref, (
int)std::round(ptmp)), p_max);
50 const bool h1_formula,
52 const int discr_order_max,
54 Eigen::VectorXi &disc_orders)
60 Eigen::MatrixXd p0, p1;
62 const auto tmp = p0 - p1;
63 const double h_ref = tmp.rowwise().norm().mean();
65 const double rho_ref = sqrt(3.0) / 6.0 * h_ref;
66 const int p_max = std::min(autogen::MAX_P_BASES, discr_order_max);
70 stats.
sigma_min = std::numeric_limits<double>::max();
72 for (
int f = 0; f < mesh2d.
n_faces(); ++f)
85 const double e0n = e0.norm();
86 const double e1n = e1.norm();
87 const double e2n = e2.norm();
89 const double alpha0 = angle2(e0, -e2);
90 const double alpha1 = angle2(e1, -e0);
91 const double alpha2 = angle2(e2, -e1);
93 const double P = e0n + e1n + e2n;
94 const double A = std::abs(e1(0) * e2(1) - e1(1) * e2(0)) / 2;
95 const double rho = 2 * A / P;
96 const double hp = std::max(e0n, std::max(e1n, e2n));
97 const double sigma = rho / hp;
103 const int p =
get_opt_p(h1_formula, B, h_ref, base_p, rho_ref, hp, rho, p_max);
105 if (p > disc_orders[f])
109 for (
int lv = 0; lv < 3; ++lv)
115 if (p > disc_orders[nav.face])
116 disc_orders[nav.face] = p;
129 logger().info(
"using B={} with {} estimate max_angle {}", B, (h1_formula ?
"H1" :
"L2"), stats.
max_angle);
134 logger().info(
"num_p1 {}", (disc_orders.array() == 1).count());
135 logger().info(
"num_p2 {}", (disc_orders.array() == 2).count());
136 logger().info(
"num_p3 {}", (disc_orders.array() == 3).count());
137 logger().info(
"num_p4 {}", (disc_orders.array() == 4).count());
138 logger().info(
"num_p5 {}", (disc_orders.array() == 5).count());
144 const bool h1_formula,
146 const int discr_order_max,
148 Eigen::VectorXi &disc_orders)
152 Eigen::MatrixXd p0, p1;
154 const auto tmp = p0 - p1;
155 const double h_ref = tmp.rowwise().norm().mean();
156 const double rho_ref = sqrt(6.) / 12. * h_ref;
157 const int p_max = std::min(autogen::MAX_P_BASES, discr_order_max);
161 stats.
sigma_min = std::numeric_limits<double>::max();
163 for (
int c = 0; c < mesh3d.
n_cells(); ++c)
173 Eigen::Matrix<double, 6, 3> e;
182 Eigen::Matrix<double, 6, 1> en = e.rowwise().norm();
184 Eigen::Matrix<double, 3 * 4, 1> alpha;
185 alpha(0) = angle3(e.row(0), -e.row(1));
186 alpha(1) = angle3(e.row(1), -e.row(2));
187 alpha(2) = angle3(e.row(2), -e.row(0));
188 alpha(3) = angle3(e.row(0), -e.row(4));
189 alpha(4) = angle3(e.row(4), e.row(3));
190 alpha(5) = angle3(-e.row(3), -e.row(0));
191 alpha(6) = angle3(-e.row(4), -e.row(1));
192 alpha(7) = angle3(e.row(1), -e.row(5));
193 alpha(8) = angle3(e.row(5), e.row(4));
194 alpha(9) = angle3(-e.row(2), -e.row(5));
195 alpha(10) = angle3(e.row(5), e.row(3));
196 alpha(11) = angle3(-e.row(3), e.row(2));
198 const double S = (e.row(0).cross(e.row(1)).norm() + e.row(0).cross(e.row(4)).norm() + e.row(4).cross(e.row(1)).norm() + e.row(2).cross(e.row(5)).norm()) / 2;
199 const double V = std::abs(e.row(3).dot(e.row(2).cross(-e.row(0)))) / 6;
200 const double rho = 3 *
V / S;
201 const double hp = en.maxCoeff();
207 const int p =
get_opt_p(h1_formula, B, h_ref, base_p, rho_ref, hp, rho, p_max);
209 if (p > disc_orders[c])
212 for (
int le = 0; le < 6; ++le)
214 const int e_id = mesh3d.
cell_edge(c, le);
217 for (
auto c_id : cells)
219 if (p > disc_orders[c_id])
220 disc_orders[c_id] = p;
230 logger().info(
"using B={} with {} estimate max_angle {}", B, (h1_formula ?
"H1" :
"L2"), stats.
max_angle);
235 logger().info(
"num_p1 {}", (disc_orders.array() == 1).count());
236 logger().info(
"num_p2 {}", (disc_orders.array() == 2).count());
237 logger().info(
"num_p3 {}", (disc_orders.array() == 3).count());
238 logger().info(
"num_p4 {}", (disc_orders.array() == 4).count());
239 logger().info(
"num_p5 {}", (disc_orders.array() == 5).count());
245 const bool h1_formula,
247 const int discr_order_max,
249 Eigen::VectorXi &disc_orders)
252 p_refine(
static_cast<const Mesh3D &
>(mesh), B, h1_formula, base_p, discr_order_max, stats, disc_orders);
254 p_refine(
static_cast<const Mesh2D &
>(mesh), B, h1_formula, base_p, discr_order_max, stats, disc_orders);