From 6b325bd075061536148c505b38e0992e893a1437 Mon Sep 17 00:00:00 2001 From: Lei Qiao Date: Sat, 8 Aug 2015 18:54:47 -0500 Subject: [PATCH] make class ConstantFunction can have different values in each component --- include/deal.II/base/function.h | 63 ++++++++++---- include/deal.II/base/function.templates.h | 101 +++++++++++++++++----- 2 files changed, 121 insertions(+), 43 deletions(-) diff --git a/include/deal.II/base/function.h b/include/deal.II/base/function.h index b5310b0c5f..d0e99b4671 100644 --- a/include/deal.II/base/function.h +++ b/include/deal.II/base/function.h @@ -376,7 +376,7 @@ public: /** - * Provide a function which always returns the constant value handed to the + * Provide a function which always returns the constant values handed to the * constructor. * * Obviously, the derivates of this function are zero, which is why we derive @@ -389,26 +389,38 @@ public: * ZeroFunction is known at compile time and need not be looked up * somewhere in memory. * - * You can pass to the constructor an integer denoting the number of - * components this function shall have. It defaults to one. If it is greater - * than one, then the function will return the constant value in all its - * components, which might not be overly useful a feature in most cases, - * however. - * * @ingroup functions - * @author Wolfgang Bangerth, 1998, 1999 + * @author Wolfgang Bangerth, 1998, 1999, Lei Qiao, 2015 */ template class ConstantFunction : public ZeroFunction { public: /** - * Constructor; takes the constant function value as an argument. The number - * of components is preset to one. + * Constructor; set values of all components to the provided one. The default number + * of components is one. */ ConstantFunction (const Number value, const unsigned int n_components = 1); + /** + * Constructor; takes an std::vector object as an argument. The number + * of components is determined by values.size(). + */ + ConstantFunction (const std::vector &values); + + /** + * Constructor; takes an Vector object as an argument. The number + * of components is determined by values.size(). + */ + ConstantFunction (const Vector &values); + + /** + * Constructor; uses whatever stores in [begin_ptr, begin_ptr+n_components) + * to initialize a new object. + */ + ConstantFunction (const Number *begin_ptr, const unsigned int n_components); + /** * Virtual destructor; absolutely necessary in this case. */ @@ -417,27 +429,26 @@ public: virtual Number value (const Point &p, const unsigned int component) const; - virtual void vector_value (const Point &p, - Vector &return_value) const; + virtual void vector_value (const Point &p, + Vector &return_value) const; virtual void value_list (const std::vector > &points, - std::vector &values, + std::vector &return_values, const unsigned int component = 0) const; virtual void vector_value_list (const std::vector > &points, - std::vector > &values) const; + std::vector > &return_values) const; std::size_t memory_consumption () const; protected: /** - * Store the constant function value. + * Store the constant function value vector. */ - const Number function_value; + std::vector function_value_vector; }; - /** * This is a constant vector-valued function, in which one or more components * of the vector have a constant value and all other components are zero. It @@ -482,11 +493,25 @@ public: ComponentSelectFunction (const std::pair &selected, const unsigned int n_components); + + /** + * Substitute function value with value of a ConstantFunction <\tt> + * object and keep the current selection pattern. + * + * This is useful if you want to have different values in different components since the + * provided constructors of ComponentSelectFunction <\tt> + * class can only have same value for all components. + * + * @note: we copy the underlaying component value data from @para f from its beginning. + * So the number of components of @para f cannot be less than the calling object. + */ + virtual void substitute_function_value_with (const ConstantFunction &f); + /** * Return the value of the function at the given point for all components. */ - virtual void vector_value (const Point &p, - Vector &return_value) const; + virtual void vector_value (const Point &p, + Vector &return_value) const; /** * Set values to the point values of the function at the diff --git a/include/deal.II/base/function.templates.h b/include/deal.II/base/function.templates.h index addb43fe65..26b61b1f16 100644 --- a/include/deal.II/base/function.templates.h +++ b/include/deal.II/base/function.templates.h @@ -363,30 +363,63 @@ void ZeroFunction::vector_gradient_list ( //--------------------------------------------------------------------------- - template ConstantFunction::ConstantFunction (const Number value, const unsigned int n_components) : ZeroFunction (n_components), - function_value (value) + function_value_vector (n_components, value) {} +template +ConstantFunction:: +ConstantFunction (const std::vector &values) + : + ZeroFunction (values.size()), + function_value_vector (values) +{} template -ConstantFunction::~ConstantFunction () {} +ConstantFunction:: +ConstantFunction (const Vector &values) + : + ZeroFunction (values.size()), + function_value_vector (values.size()) +{ + Assert (values.size() == function_value_vector.size(), + ExcDimensionMismatch (values.size(), function_value_vector.size())); + std::copy (values.begin(),values.end(),function_value_vector.begin()); +} + + +template +ConstantFunction:: +ConstantFunction (const Number *begin_ptr, const unsigned int n_components) + : + ZeroFunction (n_components), + function_value_vector (n_components) +{ + Assert (begin_ptr != 0, ExcMessage ("Null pointer encountered!")); + std::copy (begin_ptr, begin_ptr+n_components, function_value_vector.begin()); +} +template +ConstantFunction::~ConstantFunction () +{ + function_value_vector.clear(); +} + + template Number ConstantFunction::value (const Point &, const unsigned int component) const { - (void)component; Assert (component < this->n_components, ExcIndexRange (component, 0, this->n_components)); - return function_value; + return function_value_vector[component]; } @@ -398,7 +431,8 @@ void ConstantFunction::vector_value (const Point &, Assert (return_value.size() == this->n_components, ExcDimensionMismatch (return_value.size(), this->n_components)); - std::fill (return_value.begin(), return_value.end(), function_value); + std::copy (function_value_vector.begin(),function_value_vector.end(), + return_value.begin()); } @@ -406,17 +440,17 @@ void ConstantFunction::vector_value (const Point &, template void ConstantFunction::value_list ( const std::vector > &points, - std::vector &values, + std::vector &return_values, const unsigned int component) const { + // To avoid warning of unused parameter (void)points; - (void)component; Assert (component < this->n_components, ExcIndexRange (component, 0, this->n_components)); - Assert (values.size() == points.size(), - ExcDimensionMismatch(values.size(), points.size())); + Assert (return_values.size() == points.size(), + ExcDimensionMismatch(return_values.size(), points.size())) - std::fill (values.begin(), values.end(), function_value); + std::fill (return_values.begin(), return_values.end(), function_value_vector[component]); } @@ -424,16 +458,17 @@ void ConstantFunction::value_list ( template void ConstantFunction::vector_value_list ( const std::vector > &points, - std::vector > &values) const + std::vector > &return_values) const { - Assert (values.size() == points.size(), - ExcDimensionMismatch(values.size(), points.size())); + Assert (return_values.size() == points.size(), + ExcDimensionMismatch(return_values.size(), points.size())); for (unsigned int i=0; in_components, - ExcDimensionMismatch(values[i].size(), this->n_components)); - std::fill (values[i].begin(), values[i].end(), function_value); + Assert (return_values[i].size() == this->n_components, + ExcDimensionMismatch(return_values[i].size(), this->n_components)); + std::copy (function_value_vector.begin(),function_value_vector.end(), + return_values[i].begin()); }; } @@ -443,8 +478,8 @@ template std::size_t ConstantFunction::memory_consumption () const { - // only simple data elements, so use sizeof operator - return sizeof (*this); + // Here we assume Number is a simple type. + return (sizeof(*this) + this->n_components*sizeof(Number)); } //--------------------------------------------------------------------------- @@ -493,6 +528,20 @@ ComponentSelectFunction (const std::pair &selected, + +template +void +ComponentSelectFunction:: +substitute_function_value_with (const ConstantFunction &f) +{ + Point p; + for (unsigned int i=0; ifunction_value_vector.size(); ++i) + this->function_value_vector[i] = f.value(p,i); +} + + + + template void ComponentSelectFunction::vector_value ( const Point &, @@ -502,9 +551,9 @@ void ComponentSelectFunction::vector_value ( ExcDimensionMismatch (return_value.size(), this->n_components)); return_value = 0; - std::fill (return_value.begin()+selected_components.first, - return_value.begin()+selected_components.second, - this->function_value); + std::copy (this->function_value_vector.begin()+selected_components.first, + this->function_value_vector.begin()+selected_components.second, + return_value.begin()+selected_components.first); } @@ -528,10 +577,14 @@ template std::size_t ComponentSelectFunction::memory_consumption () const { - // only simple data elements, so use sizeof operator - return sizeof (*this); + // No new complex data structure is introduced here, just evaluate how much + // more memory is used *inside* the class via sizeof() and add that value to + // parent class's memory_consumption() + return (sizeof(*this) - sizeof(ConstantFunction) + + ConstantFunction::memory_consumption()); } ++//--------------------------------------------------------------------------- template ScalarFunctionFromFunctionObject:: -- 2.39.5