/**
- * 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
* <tt>ZeroFunction</tt> 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 <int dim, typename Number=double>
class ConstantFunction : public ZeroFunction<dim, Number>
{
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 <tt>std::vector<Number></tt> object as an argument. The number
+ * of components is determined by <tt>values.size()</tt>.
+ */
+ ConstantFunction (const std::vector<Number> &values);
+
+ /**
+ * Constructor; takes an <tt>Vector<Number></tt> object as an argument. The number
+ * of components is determined by <tt>values.size()</tt>.
+ */
+ ConstantFunction (const Vector<Number> &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.
*/
virtual Number value (const Point<dim> &p,
const unsigned int component) const;
- virtual void vector_value (const Point<dim> &p,
- Vector<Number> &return_value) const;
+ virtual void vector_value (const Point<dim> &p,
+ Vector<Number> &return_value) const;
virtual void value_list (const std::vector<Point<dim> > &points,
- std::vector<Number> &values,
+ std::vector<Number> &return_values,
const unsigned int component = 0) const;
virtual void vector_value_list (const std::vector<Point<dim> > &points,
- std::vector<Vector<Number> > &values) const;
+ std::vector<Vector<Number> > &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<Number> 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
ComponentSelectFunction (const std::pair<unsigned int, unsigned int> &selected,
const unsigned int n_components);
+
+ /**
+ * Substitute function value with value of a <tt>ConstantFunction<dim, Number> <\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 <tt>ComponentSelectFunction<dim, Number> <\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<dim, Number> &f);
+
/**
* Return the value of the function at the given point for all components.
*/
- virtual void vector_value (const Point<dim> &p,
- Vector<Number> &return_value) const;
+ virtual void vector_value (const Point<dim> &p,
+ Vector<Number> &return_value) const;
/**
* Set <tt>values</tt> to the point values of the function at the
//---------------------------------------------------------------------------
-
template <int dim, typename Number>
ConstantFunction<dim, Number>::ConstantFunction (const Number value,
const unsigned int n_components)
:
ZeroFunction<dim, Number> (n_components),
- function_value (value)
+ function_value_vector (n_components, value)
{}
+template <int dim, typename Number>
+ConstantFunction<dim, Number>::
+ConstantFunction (const std::vector<Number> &values)
+ :
+ ZeroFunction<dim, Number> (values.size()),
+ function_value_vector (values)
+{}
template <int dim, typename Number>
-ConstantFunction<dim, Number>::~ConstantFunction () {}
+ConstantFunction<dim, Number>::
+ConstantFunction (const Vector<Number> &values)
+ :
+ ZeroFunction<dim, Number> (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 <int dim, typename Number>
+ConstantFunction<dim, Number>::
+ConstantFunction (const Number *begin_ptr, const unsigned int n_components)
+ :
+ ZeroFunction<dim, Number> (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 <int dim, typename Number>
+ConstantFunction<dim, Number>::~ConstantFunction ()
+{
+ function_value_vector.clear();
+}
+
+
template <int dim, typename Number>
Number ConstantFunction<dim, Number>::value (const Point<dim> &,
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];
}
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());
}
template <int dim, typename Number>
void ConstantFunction<dim, Number>::value_list (
const std::vector<Point<dim> > &points,
- std::vector<Number> &values,
+ std::vector<Number> &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]);
}
template <int dim, typename Number>
void ConstantFunction<dim, Number>::vector_value_list (
const std::vector<Point<dim> > &points,
- std::vector<Vector<Number> > &values) const
+ std::vector<Vector<Number> > &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; i<points.size(); ++i)
{
- Assert (values[i].size() == this->n_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());
};
}
std::size_t
ConstantFunction<dim, Number>::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));
}
//---------------------------------------------------------------------------
+
+template <int dim, typename Number>
+void
+ComponentSelectFunction<dim, Number>::
+substitute_function_value_with (const ConstantFunction<dim, Number> &f)
+{
+ Point<dim> p;
+ for (unsigned int i=0; i<this->function_value_vector.size(); ++i)
+ this->function_value_vector[i] = f.value(p,i);
+}
+
+
+
+
template <int dim, typename Number>
void ComponentSelectFunction<dim, Number>::vector_value (
const Point<dim> &,
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);
}
std::size_t
ComponentSelectFunction<dim, Number>::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<dim, Number>)
+ + ConstantFunction<dim, Number>::memory_consumption());
}
++//---------------------------------------------------------------------------
template <int dim, typename Number>
ScalarFunctionFromFunctionObject<dim, Number>::