1 #pragma once // Ensure that file is included only once in a single compilation.
25 template <
unsigned int hyEdge_dimT,
26 unsigned int poly_deg,
27 unsigned int quad_deg,
28 typename lSol_float_t =
double>
55 typedef std::array<lSol_float_t, 1U>
error_t;
61 std::array<lSol_float_t, 1U> summed_error;
62 summed_error.fill(0.);
70 for (
unsigned int k = 0; k < summed_error.size(); ++k)
71 summed_error[k] += new_error[k];
79 for (
unsigned int k = 0; k < summed_error.size(); ++k)
80 summed_error[k] = std::sqrt(summed_error[k]);
92 static constexpr
unsigned int hyEdge_dim() {
return hyEdge_dimT; }
187 template <
typename SmallMatT>
196 template <
typename SmallMatT>
198 const SmallMatT& lambda_values)
const
207 <<
"This can happen if quadrature is too inaccurate!");
220 inline std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT>
primal_at_boundary(
221 const std::array<lSol_float_t, n_loc_dofs_>& coeffs)
const;
231 inline std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT>
dual_at_boundary(
232 const std::array<lSol_float_t, 2 * (hyEdge_dimT + 1) *
n_shape_fct_>& coeffs)
const;
263 template <
typename SmallMatInT,
typename SmallMatOutT>
265 SmallMatOutT& lambda_values_out,
266 const lSol_float_t
UNUSED(time) = 0.)
const
268 hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
269 lambda_values_in.size() == 2 * hyEdge_dimT,
270 "Both matrices must be of same size which corresponds to the number of faces!");
271 for (
unsigned int i = 0; i < lambda_values_in.size(); ++i)
273 lambda_values_in[i].size() == lambda_values_out[i].size() &&
275 "Both matrices must be of same size which corresponds to the number of dofs per face!");
279 std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT> primals(
283 for (
unsigned int i = 0; i < lambda_values_out.size(); ++i)
284 for (
unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
285 lambda_values_out[i][j] = duals[i][j] +
tau_ * (primals[i][j] - lambda_values_in[i][j]);
287 return lambda_values_out;
299 template <
typename SmallMatInT,
typename SmallMatOutT>
301 SmallMatOutT& lambda_values_out,
302 const lSol_float_t
UNUSED(time) = 0.)
const
304 return lambda_values_out =
trace_to_flux(lambda_values_in, lambda_values_out);
313 template <
typename SmallMatT>
314 std::array<lSol_float_t, 1U>
errors(
const SmallMatT&
UNUSED(lambda_values),
315 const lSol_float_t
UNUSED(time) = 0.)
const
317 return std::array<lSol_float_t, 1U>({0.});
330 template <
typename abscissa_
float_t, std::
size_t sizeT,
class input_array_t>
332 const std::array<abscissa_float_t, sizeT>& abscissas,
333 const input_array_t& lambda_values,
334 const lSol_float_t
UNUSED(time) = 0.)
const;
354 template <
unsigned int hyEdge_dimT,
355 unsigned int poly_deg,
356 unsigned int quad_deg,
357 typename lSol_float_t>
361 const lSol_float_t tau)
363 constexpr
unsigned int n_dofs_lap = n_loc_dofs_ / 2;
364 lSol_float_t integral;
368 for (
unsigned int i = 0; i < n_shape_fct_; ++i)
370 for (
unsigned int j = 0; j < n_shape_fct_; ++j)
373 integral = integrator::integrate_vol_phiphi(i, j);
374 local_mat(hyEdge_dimT * n_shape_fct_ + i, n_dofs_lap + hyEdge_dimT * n_shape_fct_ + j) -=
376 for (
unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
378 local_mat(dim * n_shape_fct_ + i, dim * n_shape_fct_ + j) += integral;
379 local_mat(n_dofs_lap + dim * n_shape_fct_ + i, n_dofs_lap + dim * n_shape_fct_ + j) +=
383 for (
unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
387 integral = integrator::integrate_vol_Dphiphi(i, j, dim);
388 local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) -= integral;
389 local_mat(dim * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) -= integral;
390 local_mat(n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i,
391 n_dofs_lap + dim * n_shape_fct_ + j) -= integral;
392 local_mat(n_dofs_lap + dim * n_shape_fct_ + i,
393 n_dofs_lap + hyEdge_dimT * n_shape_fct_ + j) -= integral;
396 integral = integrator::integrate_bdr_phiphi(i, j, 2 * dim + 1);
397 local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) += integral;
398 local_mat(n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i,
399 n_dofs_lap + dim * n_shape_fct_ + j) +=
402 local_mat(hyEdge_dimT * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) += tau * integral;
403 local_mat(n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i,
404 n_dofs_lap + hyEdge_dimT * n_shape_fct_ + j) += tau * integral;
406 integral = integrator::integrate_bdr_phiphi(i, j, 2 * dim + 0);
407 local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) -= integral;
408 local_mat(n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i,
409 n_dofs_lap + dim * n_shape_fct_ + j) -=
412 local_mat(hyEdge_dimT * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) += tau * integral;
413 local_mat(n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i,
414 n_dofs_lap + hyEdge_dimT * n_shape_fct_ + j) += tau * integral;
426 template <
unsigned int hyEdge_dimT,
427 unsigned int poly_deg,
428 unsigned int quad_deg,
429 typename lSol_float_t>
430 template <
typename SmallMatT>
434 const SmallMatT& lambda_values)
const
436 constexpr
unsigned int n_dofs_lap = n_loc_dofs_ / 2;
437 lSol_float_t integral;
440 hy_assert(lambda_values.size() == 2 * hyEdge_dimT,
441 "The size of the lambda values should be twice the dimension of a hyperedge.");
442 for (
unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
443 hy_assert(lambda_values[i].size() == 2 * n_shape_bdr_,
444 "The size of lambda should be the amount of ansatz functions at boundary.");
446 for (
unsigned int i = 0; i < n_shape_fct_; ++i)
448 for (
unsigned int j = 0; j < n_shape_bdr_; ++j)
450 for (
unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
452 integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 0);
453 right_hand_side[dim * n_shape_fct_ + i] += lambda_values[2 * dim + 0][j] * integral;
454 right_hand_side[hyEdge_dimT * n_shape_fct_ + i] +=
455 tau_ * lambda_values[2 * dim + 0][j] * integral;
456 right_hand_side[n_dofs_lap + dim * n_shape_fct_ + i] +=
457 lambda_values[2 * dim + 0][n_shape_bdr_ + j] * integral;
458 right_hand_side[n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i] +=
459 tau_ * lambda_values[2 * dim + 0][n_shape_bdr_ + j] * integral;
461 integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 1);
462 right_hand_side[dim * n_shape_fct_ + i] -= lambda_values[2 * dim + 1][j] * integral;
463 right_hand_side[hyEdge_dimT * n_shape_fct_ + i] +=
464 tau_ * lambda_values[2 * dim + 1][j] * integral;
465 right_hand_side[n_dofs_lap + dim * n_shape_fct_ + i] -=
466 lambda_values[2 * dim + 1][n_shape_bdr_ + j] * integral;
467 right_hand_side[n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i] +=
468 tau_ * lambda_values[2 * dim + 1][n_shape_bdr_ + j] * integral;
473 return right_hand_side;
480 template <
unsigned int hyEdge_dimT,
481 unsigned int poly_deg,
482 unsigned int quad_deg,
483 typename lSol_float_t>
485 std::array<lSol_float_t,
489 const std::array<lSol_float_t, n_loc_dofs_>& coeffs)
const
491 constexpr
unsigned int n_dofs_lap = n_loc_dofs_ / 2;
492 std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT> bdr_values;
493 lSol_float_t integral;
495 for (
unsigned int dim_n = 0; dim_n < 2 * hyEdge_dimT; ++dim_n)
496 bdr_values[dim_n].fill(0.);
498 for (
unsigned int i = 0; i < n_shape_fct_; ++i)
500 for (
unsigned int j = 0; j < n_shape_bdr_; ++j)
502 for (
unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
504 integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 0);
505 bdr_values[2 * dim + 0][j] += coeffs[hyEdge_dimT * n_shape_fct_ + i] * integral;
506 bdr_values[2 * dim + 0][n_shape_bdr_ + j] +=
507 coeffs[n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i] * integral;
509 integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 1);
510 bdr_values[2 * dim + 1][j] += coeffs[hyEdge_dimT * n_shape_fct_ + i] * integral;
511 bdr_values[2 * dim + 1][n_shape_bdr_ + j] +=
512 coeffs[n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i] * integral;
524 template <
unsigned int hyEdge_dimT,
525 unsigned int poly_deg,
526 unsigned int quad_deg,
527 typename lSol_float_t>
529 std::array<lSol_float_t,
533 const std::array<lSol_float_t, 2 * (hyEdge_dimT + 1) * n_shape_fct_>& coeffs)
const
535 constexpr
unsigned int n_dofs_lap = n_loc_dofs_ / 2;
536 std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT> bdr_values;
537 lSol_float_t integral;
539 for (
unsigned int dim_n = 0; dim_n < 2 * hyEdge_dimT; ++dim_n)
540 bdr_values[dim_n].fill(0.);
542 for (
unsigned int i = 0; i < n_shape_fct_; ++i)
544 for (
unsigned int j = 0; j < n_shape_bdr_; ++j)
546 for (
unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
548 integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 0);
549 bdr_values[2 * dim + 0][j] -= coeffs[dim * n_shape_fct_ + i] * integral;
550 bdr_values[2 * dim + 0][n_shape_bdr_ + j] -=
551 coeffs[n_dofs_lap + dim * n_shape_fct_ + i] * integral;
553 integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 1);
554 bdr_values[2 * dim + 1][j] += coeffs[dim * n_shape_fct_ + i] * integral;
555 bdr_values[2 * dim + 1][n_shape_bdr_ + j] +=
556 coeffs[n_dofs_lap + dim * n_shape_fct_ + i] * integral;
568 template <
unsigned int hyEdge_dimT,
569 unsigned int poly_deg,
570 unsigned int quad_deg,
571 typename lSol_float_t>
572 template <
typename abscissa_
float_t, std::
size_t sizeT,
class input_array_t>
573 std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
576 const std::array<abscissa_float_t, sizeT>& abscissas,
577 const input_array_t& lambda_values,
578 const lSol_float_t)
const
584 std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
588 for (
unsigned int d = 0; d < system_dim; ++d)
590 for (
unsigned int i = 0; i < coeffs.
size(); ++i)
591 coeffs[i] = coefficients[d * n_shape_fct_ + i];
592 for (
unsigned int pt = 0; pt < Hypercube<hyEdge_dimT>::pow(sizeT); ++pt)
593 point_vals[d][pt] = integrator::shape_fun_t::template lin_comb_fct_val<float>(