From 040f4125301012eba294306ffd7dc0fa3967a4bf Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 29 Mar 2018 16:25:05 -0600 Subject: [PATCH] Add a test. --- .../integrate_difference_02_nan.cc | 140 ++++++++++++++++++ .../integrate_difference_02_nan.output | 18 +++ 2 files changed, 158 insertions(+) create mode 100644 tests/vector_tools/integrate_difference_02_nan.cc create mode 100644 tests/vector_tools/integrate_difference_02_nan.output diff --git a/tests/vector_tools/integrate_difference_02_nan.cc b/tests/vector_tools/integrate_difference_02_nan.cc new file mode 100644 index 0000000000..fa8c761e94 --- /dev/null +++ b/tests/vector_tools/integrate_difference_02_nan.cc @@ -0,0 +1,140 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2003 - 2017 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + + +// Test integrate_difference +// +// The VectorTools::integrate_difference() function allows users +// to provide a weight function that can also serve as a component mask +// to select individual components of the solution vector for error +// computation. For components not selected, such a mask would then +// simply be zero. +// +// In some cases, the solution vector contains NaN numbers, for example +// when one uses the FE_FaceQ element for certain components of the +// solution vector and uses a quadrature formula for error evaluation +// that has quadrature points in the interior of the cell. For any +// "regular" solution component for which the component mask has a zero +// weight, the value of that component will be multiplied by zero and +// consequently does not add anything to the error computation. However, +// if the NaNs of a FE_FaceQ are multiplied with zero weights, the result +// is still a NaN, and adding it to the values times weights of the other +// components results in NaNs -- in effect rendering it impossible to get +// any information out of the VectorTools::integrate_difference() +// function if one of the finite elements involved is FE_FaceQ. +// +// This is now fixed by simply skipping vector components for which the +// weight vector is zero. This has the same result as before for all +// "normal" situations, but also properly skips the NaN case outlined +// above. + + +#include "../tests.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace dealii; + + +template +void test(VectorTools::NormType norm, double exp = 2.0) +{ + Triangulation tria; + GridGenerator::hyper_cube(tria); + tria.refine_global(2); + + FESystem fe(FE_Q(1), 1, + FE_FaceQ(1), 1); + DoFHandler dofh(tria); + dofh.distribute_dofs(fe); + + // Create a zero vector. (The values in there are not important, + // just that the difference between this and later the exact + // solution happens to have signaling_nans in it. It will have these + // values because FE_FaceQ refuses to fill FEValues values -- + // because it's a face element, so this refusal actually makes sense + // -- and thus leaves the signaling NaNs from the original invalid + // initialization.) + Vector solution (dofh.n_dofs ()); + + Vector cellwise_errors (tria.n_active_cells()); + QIterated quadrature (QTrapez<1>(), 2); + + const ComponentSelectFunction component_mask (1, 2); + VectorTools::integrate_difference (dofh, + solution, + ZeroFunction(2), + cellwise_errors, + quadrature, + norm, + &component_mask, + exp); + + const double error + = VectorTools::compute_global_error(tria, cellwise_errors, norm, exp); + + deallog << "computed: " << error + << std::endl; +} + + + +template +void test() +{ + deallog << "L2_norm:" << std::endl; + test(VectorTools::L2_norm); + + deallog << "H1_seminorm:" << std::endl; + test(VectorTools::H1_seminorm); + + deallog << "H1_norm:" << std::endl; + test(VectorTools::H1_norm); + + deallog << "L1_norm:" << std::endl; + test(VectorTools::L1_norm); + + deallog << "Linfty_norm:" << std::endl; + test(VectorTools::Linfty_norm); + + deallog << "mean:" << std::endl; + test(VectorTools::mean); + + deallog << "Lp_norm:" << std::endl; + test(VectorTools::Lp_norm, 3.0); + + deallog << "W1p_seminorm:" << std::endl; + test(VectorTools::W1p_seminorm, 3.0); + + deallog << "OK" << std::endl; +} + + +int main (int argc, char **argv) +{ + initlog(); + test<3>(); +} diff --git a/tests/vector_tools/integrate_difference_02_nan.output b/tests/vector_tools/integrate_difference_02_nan.output new file mode 100644 index 0000000000..9e9cfe129c --- /dev/null +++ b/tests/vector_tools/integrate_difference_02_nan.output @@ -0,0 +1,18 @@ + +DEAL::L2_norm: +DEAL::computed: 0.00000 +DEAL::H1_seminorm: +DEAL::computed: 0.00000 +DEAL::H1_norm: +DEAL::computed: 0.00000 +DEAL::L1_norm: +DEAL::computed: 0.00000 +DEAL::Linfty_norm: +DEAL::computed: 0.00000 +DEAL::mean: +DEAL::computed: 0.00000 +DEAL::Lp_norm: +DEAL::computed: 0.00000 +DEAL::W1p_seminorm: +DEAL::computed: 0.00000 +DEAL::OK -- 2.39.5