From 0e8a33a989ba0d6ce9a5b57e77f8e7e6ea77e530 Mon Sep 17 00:00:00 2001 From: bangerth Date: Tue, 2 Apr 2013 21:24:25 +0000 Subject: [PATCH] Patch by Spencer Patty: New class VectorFunctionFromTensorFunction. git-svn-id: https://svn.dealii.org/trunk@29151 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/doc/news/changes.h | 6 ++ deal.II/include/deal.II/base/function.h | 116 ++++++++++++++++++++++++ deal.II/source/base/function.cc | 100 +++++++++++++++++++- tests/base/functions_08.cc | 86 ++++++++++++++++++ tests/base/functions_08/cmp/generic | 4 + 5 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 tests/base/functions_08.cc create mode 100644 tests/base/functions_08/cmp/generic diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index af36ae7ade..c6c59816ac 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -88,6 +88,12 @@ this function.

Specific improvements

    +
  1. New: There is a class VectorFunctionFromTensorFunction that converts +between objects of type TensorFunction and Function. +
    +(Spencer Patty, 2013/4/2) +
  2. +
  3. Fixed: The ParameterHandler class could not deal with parameters named "value" (and a few other names). This is now fixed. diff --git a/deal.II/include/deal.II/base/function.h b/deal.II/include/deal.II/base/function.h index bf0c08183f..9698e24419 100644 --- a/deal.II/include/deal.II/base/function.h +++ b/deal.II/include/deal.II/base/function.h @@ -24,7 +24,10 @@ #include DEAL_II_NAMESPACE_OPEN + + template class Vector; +template class TensorFunction; /** * This class is a model for a general function. It serves the purpose @@ -893,6 +896,119 @@ private: }; +/** + * This class is built as a means of translating + * the Tensor<1,dim> values produced by objects of type + * TensorFunction and returning them as a multiple + * component version of the same thing as a Vector for use in, for example, + * the VectorTools::interpolate or the many other functions taking Function objects. + * It allows the user to place the desired components into an n_components + * long vector starting at the selected_component location in that vector and have all other + * components be 0. + * + * For example: Say you created a class called + * @code + * class RightHandSide : public TensorFunction + * @endcode + * which extends the TensorFunction class and you have an object + * @code + * RightHandSide<1,dim> rhs; + * @endcode + * of that class which you want to interpolate onto your mesh using the + * VectorTools::interpolate function, but the finite element you use for the DoFHandler + * object has 3 copies of a finite element with dim components, for a total of 3*dim + * components. To interpolate onto that DoFHandler, you need an object of type Function + * that has 3*dim vector components. Creating such an object from the existing rhs + * object is done using this piece of code: + * @code + * RighHandSide<1,dim> rhs; + * VectorFunctionFromTensorFunction rhs_vector_function (rhs, 0, 3*dim); + * @endcode + * where the dim components of the tensor function are placed into + * the first dim components of the function object. + * + * @author Spencer Patty, 2013 + */ +template +class VectorFunctionFromTensorFunction : public Function +{ +public: + /** Given a TensorFunction object that takes a Point and returns a Tensor<1,dim> + * value, convert this into an object that matches the Function@ + * interface. + * + * By default, create a Vector object of the same size as tensor_function + * returns, i.e., with dim components. + * + * @param tensor_function The TensorFunction that will form one component + * of the resulting Vector Function object. + * @param n_components The total number of vector components of the + * resulting TensorFunction object. + * @param selected_component The first component that should be + * filled by the first argument. This should be such that the entire tensor_function + * fits inside the n_component length return vector. + */ + VectorFunctionFromTensorFunction (const TensorFunction<1,dim> &tensor_function, + const unsigned int selected_component=0, + const unsigned int n_components=dim); + + /** + * This destructor is defined as + * virtual so as to coincide with all + * other aspects of class. + */ + virtual ~VectorFunctionFromTensorFunction(); + + /** + * Return a single component of a + * vector-valued function at a + * given point. + */ + virtual double value (const Point &p, + const unsigned int component = 0) const; + + /** + * Return all components of a + * vector-valued function at a + * given point. + * + * values shall have the right + * size beforehand, + * i.e. #n_components. + */ + virtual void vector_value (const Point &p, + Vector &values) const; + + /** + * Return all components of a + * vector-valued function at a + * list of points. + * + * value_list shall be the same + * size as points and each element + * of the vector will be passed to + * vector_value() to evaluate + * the function + */ + virtual void vector_value_list (const std::vector > &points, + std::vector > &value_list) const; + +private: + /** + * The TensorFunction object which we call when this class's vector_value() + * or vector_value_list() functions are called. + **/ + const TensorFunction<1,dim> & tensor_function; + + /** + * The first vector component whose value is to be filled by the + * given TensorFunction. The values will be placed in components + * selected_component to selected_component+dim-1 for a TensorFunction<1,dim> object. + */ + const unsigned int selected_component; +}; + + DEAL_II_NAMESPACE_CLOSE #endif diff --git a/deal.II/source/base/function.cc b/deal.II/source/base/function.cc index 19a5994190..27436923ee 100644 --- a/deal.II/source/base/function.cc +++ b/deal.II/source/base/function.cc @@ -13,6 +13,7 @@ #include +#include #include #include #include @@ -585,6 +586,101 @@ vector_value (const Point &p, +/** + * The constructor for VectorFunctionFromTensorFunction which initiates the return vector + * to be size n_components. + */ +template +VectorFunctionFromTensorFunction::VectorFunctionFromTensorFunction (const TensorFunction<1,dim>& tensor_function, + const unsigned int selected_component, + const unsigned int n_components) +: +Function (n_components), +tensor_function (tensor_function), +selected_component (selected_component) +{ + + // Verify that the Tensor<1,dim> will fit in the given length selected_components + // and not hang over the end of the vector. + Assert (0 <= selected_component, + ExcIndexRange (selected_component,0,0)); + Assert (selected_component + dim - 1 < this->n_components, + ExcIndexRange (selected_component, 0, this->n_components)); +} + + +template +VectorFunctionFromTensorFunction::~VectorFunctionFromTensorFunction () +{} + + +template +inline +double VectorFunctionFromTensorFunction::value (const Point &p, + const unsigned int component) const +{ + Assert (componentn_components, + ExcIndexRange(component, 0, this->n_components)); + + // if the requested component is out of the range selected, then we + // can return early + if ((component < selected_component) + || + (component >= selected_component+dim)) + return 0; + + // otherwise retrieve the values from the tensor_function to be + // placed at the selected_component to selected_component + dim - 1 + // elements of the Vector values and pick the correct one + const Tensor<1,dim> tensor_value = tensor_function.value (p); + + return tensor_value[component-selected_component]; +} + + +template +inline +void VectorFunctionFromTensorFunction::vector_value (const Point &p, + Vector &values) const +{ + Assert(values.size() == this->n_components, + ExcDimensionMismatch(values.size(),this->n_components)); + + // Retrieve the values from the tensor_function to be + // placed at the selected_component to selected_component + dim - 1 + // elements of the Vector values. + const Tensor<1,dim> tensor_value = tensor_function.value (p); + + // First we make all elements of values = 0 + values = 0; + + // Second we adjust the desired components to take on the values in tensor_value. + for (unsigned int i=0; ivector_value_list is the interface for giving a list of + * points (vector >) of which to evaluate using the vector_value + * member function. Again, this function is written so as to not replicate the function definition + * but passes each point on to vector_value to be evaluated. + */ +template +void VectorFunctionFromTensorFunction::vector_value_list (const std::vector > &points, + std::vector > &value_list) const +{ + Assert (value_list.size() == points.size(), + ExcDimensionMismatch (value_list.size(), points.size())); + + const unsigned int n_points = points.size(); + + for (unsigned int p=0; p::vector_value (points[p], value_list[p]); +} + + + + // explicit instantiations template class Function<1>; @@ -593,6 +689,7 @@ template class ConstantFunction<1>; template class ComponentSelectFunction<1>; template class ScalarFunctionFromFunctionObject<1>; template class VectorFunctionFromScalarFunctionObject<1>; +template class VectorFunctionFromTensorFunction<1>; template class Function<2>; template class ZeroFunction<2>; @@ -600,6 +697,7 @@ template class ConstantFunction<2>; template class ComponentSelectFunction<2>; template class ScalarFunctionFromFunctionObject<2>; template class VectorFunctionFromScalarFunctionObject<2>; +template class VectorFunctionFromTensorFunction<2>; template class Function<3>; template class ZeroFunction<3>; @@ -607,6 +705,6 @@ template class ConstantFunction<3>; template class ComponentSelectFunction<3>; template class ScalarFunctionFromFunctionObject<3>; template class VectorFunctionFromScalarFunctionObject<3>; - +template class VectorFunctionFromTensorFunction<3>; DEAL_II_NAMESPACE_CLOSE diff --git a/tests/base/functions_08.cc b/tests/base/functions_08.cc new file mode 100644 index 0000000000..7b4f6675a2 --- /dev/null +++ b/tests/base/functions_08.cc @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2007, 2008, 2010, 2011, 2013 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//----------------------------------------------------------------------------- + +// Test VectorFunctionTensorFunction + +#include "../tests.h" +#include +#include +#include + + +template +class X : public TensorFunction<1,dim> +{ +public: + virtual Tensor<1,dim> value (const Point &p) const + { + return p; + } +}; + + +template +void check1 () +{ + X x; + VectorFunctionFromTensorFunction + object (x, 1, dim+2); + + Assert (object.n_components == dim+2, ExcInternalError()); + + for (unsigned int i=0; i<10; ++i) + { + Point p; + for (unsigned int d=0; d v(dim+2); + object.vector_value (p, v); + for (unsigned int c=0; c (); + check1<2> (); + check1<3> (); +} + + diff --git a/tests/base/functions_08/cmp/generic b/tests/base/functions_08/cmp/generic new file mode 100644 index 0000000000..fb71de2867 --- /dev/null +++ b/tests/base/functions_08/cmp/generic @@ -0,0 +1,4 @@ + +DEAL::OK +DEAL::OK +DEAL::OK -- 2.39.5