1 #pragma once // Ensure that file is included only once in a single compilation.
19 template <
unsigned int hyEdge_dimT,
20 unsigned int space_dim,
21 unsigned int poly_deg,
22 unsigned int quad_deg,
23 typename lSol_float_t = double,
24 typename diffusion_sol_t =
25 DiffusionUniform<hyEdge_dimT, poly_deg, quad_deg, lSol_float_t> >
65 typedef std::array<lSol_float_t, 1U>
error_t;
71 std::array<lSol_float_t, 1U> summed_error;
72 summed_error.fill(0.);
80 for (
unsigned int k = 0; k < summed_error.size(); ++k)
81 summed_error[k] += new_error[k];
89 for (
unsigned int k = 0; k < summed_error.size(); ++k)
90 summed_error[k] = std::sqrt(summed_error[k]);
99 static constexpr
unsigned int hyEdge_dim() {
return hyEdge_dimT; }
129 template <
class hyEdgeT,
typename SmallMatT>
130 inline std::array<std::array<double, diffusion_sol_t::n_glob_dofs_per_node()>, 2 * hyEdge_dimT>
133 std::array<std::array<double, diffusion_sol_t::n_glob_dofs_per_node()>, 2 * hyEdge_dimT> result;
134 hy_assert(result.size() == 2,
"Only implemented in one dimension!");
135 for (
unsigned int i = 0; i < result.size(); ++i)
137 hy_assert(result[i].size() == 1,
"Only implemented in one dimension!");
144 for (
unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
145 for (
unsigned int dim = 0; dim < space_dim; ++dim)
146 result[i][0] += normal_vector[dim] * lambda[i][dim];
153 template <
class hyEdgeT,
typename SmallMatInT,
typename SmallMatOutT>
155 SmallMatOutT& lambda_values_out,
156 hyEdgeT& hyper_edge)
const
158 hy_assert(diffusion_sol_t::n_glob_dofs_per_node() == 1,
"This should be 1!");
162 for (
unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
163 for (
unsigned int dim = 0; dim < space_dim; ++dim)
164 lambda_values_out[i][dim] += normal_vector[dim] * lambda[i][0];
166 return lambda_values_out;
192 template <
class hyEdgeT,
typename SmallMatInT,
typename SmallMatOutT>
194 SmallMatOutT& lambda_values_out,
196 const lSol_float_t time = 0.)
const
198 static_assert(hyEdge_dimT == 1,
"Elastic graphs must be graphs, not hypergraphs!");
199 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>, 2 *hyEdge_dimT>
202 for (
unsigned int i = 0; i < lambda_new.size(); ++i)
203 lambda_new[i].fill(0.);
205 if constexpr (has_trace_to_flux<
207 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>,
209 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>,
211 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>,
212 2 * hyEdge_dimT>&)>::value)
213 diffusion.trace_to_flux(lambda_old, lambda_new, time);
215 diffusion.trace_to_flux(lambda_old, lambda_new, hyper_edge, time);
222 template <
class hyEdgeT,
typename SmallMatInT,
typename SmallMatOutT>
224 SmallMatOutT& lambda_values_out,
226 const lSol_float_t time = 0.)
const
228 static_assert(hyEdge_dimT == 1,
"Elastic graphs must be graphs, not hypergraphs!");
229 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>, 2 *hyEdge_dimT>
232 for (
unsigned int i = 0; i < lambda_new.size(); ++i)
233 lambda_new[i].fill(0.);
235 if constexpr (has_residual_flux<
237 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>,
239 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>,
241 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>,
242 2 * hyEdge_dimT>&)>::value)
243 diffusion.residual_flux(lambda_old, lambda_new, time);
245 diffusion.residual_flux(lambda_old, lambda_new, hyper_edge, time);
259 template <
class hyEdgeT,
typename SmallMatT>
260 std::array<lSol_float_t, 1U>
errors(
const SmallMatT& lambda_values,
262 const lSol_float_t time = 0.)
const
264 lSol_float_t error = 0.;
265 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>, 2 * hyEdge_dimT>
268 if constexpr (has_errors<
270 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>,
272 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>,
274 std::array<std::array<lSol_float_t, diffusion_sol_t::n_glob_dofs_per_node()>,
275 2 * hyEdge_dimT>&)>::value)
278 error =
diffusion.errors(lambda, hyper_edge, time);
280 return std::array<lSol_float_t, 1U>({error});
295 template <
typename abscissa_
float_t, std::
size_t sizeT,
class input_array_t,
class hyEdgeT>
297 std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
300 const input_array_t& lambda_values,
302 const lSol_float_t time = 0.)
const
305 std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
314 for (
unsigned int dim = 0; dim < result.size(); ++dim)
315 for (
unsigned int q = 0; q < result[dim].size(); ++q)
316 result[dim][q] = bulk[1][q] * normal_vector[dim];
328 template <
unsigned int hyEdge_dimT,
329 unsigned int space_dim,
330 unsigned int poly_deg,
331 unsigned int quad_deg,
332 typename lSol_float_t = double,
333 typename bilaplacian_sol_t =
334 BilaplacianUniform<hyEdge_dimT, poly_deg, quad_deg, lSol_float_t> >
380 std::array<lSol_float_t, 1U> summed_error;
381 summed_error.fill(0.);
389 for (
unsigned int k = 0; k < summed_error.size(); ++k)
390 summed_error[k] += new_error[k];
398 for (
unsigned int k = 0; k < summed_error.size(); ++k)
399 summed_error[k] = std::sqrt(summed_error[k]);
408 static constexpr
unsigned int hyEdge_dim() {
return hyEdge_dimT; }
438 template <
class hyEdgeT,
typename SmallMatT>
439 inline std::array<std::array<double, bilaplacian_sol_t::n_glob_dofs_per_node()>, 2 * hyEdge_dimT>
442 const unsigned int outer_index)
const
444 std::array<std::array<double, bilaplacian_sol_t::n_glob_dofs_per_node()>, 2 * hyEdge_dimT>
446 hy_assert(result.size() == 2,
"Only implemented in one dimension!");
447 for (
unsigned int i = 0; i < result.size(); ++i)
449 hy_assert(result[i].size() == 2,
"Only implemented in one dimension!");
456 for (
unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
457 for (
unsigned int dim = 0; dim < space_dim; ++dim)
459 result[i][0] += normal_vector[dim] * lambda[i][dim];
460 result[i][1] += normal_vector[dim] * lambda[i][space_dim + dim];
468 template <
class hyEdgeT,
typename SmallMatT>
470 const std::array<std::array<
double, bilaplacian_sol_t::n_glob_dofs_per_node()>,
471 2 * hyEdge_dimT>& lambda,
472 SmallMatT& lambda_values_out,
474 const unsigned int outer_index)
const
476 hy_assert(bilaplacian_sol_t::n_glob_dofs_per_node() == 2,
"This should be 1*2!");
480 for (
unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
481 for (
unsigned int dim = 0; dim < space_dim; ++dim)
483 lambda_values_out[i][dim] += normal_vector[dim] * lambda[i][0];
484 lambda_values_out[i][space_dim + dim] += normal_vector[dim] * lambda[i][1];
487 return lambda_values_out;
513 template <
class hyEdgeT,
typename SmallMatInT,
typename SmallMatOutT>
515 SmallMatOutT& lambda_values_out,
517 const lSol_float_t time = 0.)
const
519 static_assert(hyEdge_dimT == 1,
"The beam must be one-dimensional!");
520 std::array<std::array<lSol_float_t, bilaplacian_sol_t::n_glob_dofs_per_node()>, 2 * hyEdge_dimT>
521 lambda_old, lambda_new;
523 for (
unsigned int dim = 0; dim < space_dim - hyEdge_dimT; ++dim)
526 for (
unsigned int i = 0; i < lambda_new.size(); ++i)
527 lambda_new[i].fill(0.);
532 std::array<std::array<lSol_float_t, bilaplacian_sol_t::n_glob_dofs_per_node()>,
534 std::array<std::array<lSol_float_t, bilaplacian_sol_t::n_glob_dofs_per_node()>,
536 std::array<std::array<lSol_float_t, bilaplacian_sol_t::n_glob_dofs_per_node()>,
537 2 * hyEdge_dimT>&)>::value)
545 return lambda_values_out;
550 template <
class hyEdgeT,
typename SmallMatInT,
typename SmallMatOutT>
552 SmallMatOutT& lambda_values_out,
554 const lSol_float_t time = 0.)
const
556 static_assert(hyEdge_dimT == 1,
"The beam must be one-dimensional!");
557 std::array<std::array<lSol_float_t, bilaplacian_sol_t::n_glob_dofs_per_node()>, 2 * hyEdge_dimT>
558 lambda_old, lambda_new;
560 for (
unsigned int dim = 0; dim < space_dim - hyEdge_dimT; ++dim)
563 for (
unsigned int i = 0; i < lambda_new.size(); ++i)
564 lambda_new[i].fill(0.);
579 return lambda_values_out;
590 template <
class hyEdgeT>
595 const lSol_float_t time = 0.)
const
597 lSol_float_t error = 0.;
598 std::array<std::array<lSol_float_t, bilaplacian_sol_t::n_glob_dofs_per_node()>, 2 * hyEdge_dimT>
600 for (
unsigned int dim = 0; dim < space_dim - hyEdge_dimT; ++dim)
615 return std::array<lSol_float_t, 1U>({error});
630 template <
typename abscissa_
float_t, std::
size_t sizeT,
class input_array_t,
class hyEdgeT>
631 std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
635 const input_array_t& lambda_values,
637 const lSol_float_t time = 0.)
const
639 std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
system_dimension()>
641 for (
unsigned int i = 0; i < values.size(); ++i)
644 for (
unsigned int dim_on = 0; dim_on < space_dim - hyEdge_dimT; ++dim_on)
651 for (
unsigned int dim = 0; dim < values.size(); ++dim)
652 for (
unsigned int q = 0; q < values[dim].size(); ++q)
653 values[dim][q] += bulk[1][q] * normal_vector[dim];
667 template <
unsigned int hyEdge_dimT,
668 unsigned int space_dim,
669 unsigned int poly_deg,
670 unsigned int quad_deg,
671 typename lSol_float_t =
double>
704 std::array<lSol_float_t, 1U> summed_error;
705 summed_error.fill(0.);
713 for (
unsigned int k = 0; k < summed_error.size(); ++k)
714 summed_error[k] += new_error[k];
722 for (
unsigned int k = 0; k < summed_error.size(); ++k)
723 summed_error[k] = std::sqrt(summed_error[k]);
732 static constexpr
unsigned int hyEdge_dim() {
return hyEdge_dimT; }
781 template <
class hyEdgeT,
typename SmallMatInT,
typename SmallMatOutT>
783 SmallMatOutT& lambda_values_out,
785 const lSol_float_t time = 0.)
const
787 static_assert(hyEdge_dimT == 1,
"A beam must be one-dimensional!");
789 len_beam.trace_to_flux(lambda_values_in, lambda_values_out, hyper_edge, time);
790 ben_beam.trace_to_flux(lambda_values_in, lambda_values_out, hyper_edge, time);
792 return lambda_values_out;
797 template <
class hyEdgeT,
typename SmallMatInT,
typename SmallMatOutT>
799 SmallMatOutT& lambda_values_out,
801 const lSol_float_t time = 0.)
const
803 static_assert(hyEdge_dimT == 1,
"A beam must be one-dimensional!");
805 len_beam.residual_flux(lambda_values_in, lambda_values_out, hyper_edge, time);
806 ben_beam.residual_flux(lambda_values_in, lambda_values_out, hyper_edge, time);
808 return lambda_values_out;
819 template <
class hyEdgeT>
824 const lSol_float_t time = 0.)
const
826 lSol_float_t error = 0.;
827 error +=
len_beam.errors(lambda_values, hyper_edge, time);
828 error +=
ben_beam.errors(lambda_values, hyper_edge, time);
829 return std::array<lSol_float_t, 1U>({error});
844 template <
typename abscissa_
float_t, std::
size_t sizeT,
class input_array_t,
class hyEdgeT>
845 std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
system_dimension()>
847 const input_array_t& lambda_values,
849 const lSol_float_t time = 0.)
const
851 std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
system_dimension()>
853 result =
len_beam.bulk_values(abscissas, lambda_values, hyper_edge, time);
854 auxiliary =
ben_beam.bulk_values(abscissas, lambda_values, hyper_edge, time);
857 for (
unsigned int j = 0; j < Hypercube<hyEdge_dimT>::pow(sizeT); ++j)
858 result[i][j] += auxiliary[i][j];