]> https://gitweb.dealii.org/ - dealii.git/commitdiff
make class ConstantFunction can have different values in each component
authorLei Qiao <qiaol618@gmail.com>
Sat, 8 Aug 2015 23:54:47 +0000 (18:54 -0500)
committerLei Qiao <qiaol618@gmail.com>
Sat, 29 Aug 2015 22:56:56 +0000 (17:56 -0500)
include/deal.II/base/function.h
include/deal.II/base/function.templates.h

index b5310b0c5fead7270b8cada288b6efff6b3ffa5a..d0e99b4671939019a10cc1f03d5be949adf49692 100644 (file)
@@ -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:
  * <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.
    */
@@ -417,27 +429,26 @@ public:
   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
@@ -482,11 +493,25 @@ public:
   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
index addb43fe653ba43bd8d1489e9a1acb2c3f3a5791..26b61b1f16e3b513627beea1b0181755a83f4e30 100644 (file)
@@ -363,30 +363,63 @@ void ZeroFunction<dim, Number>::vector_gradient_list (
 
 //---------------------------------------------------------------------------
 
-
 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];
 }
 
 
@@ -398,7 +431,8 @@ void ConstantFunction<dim, Number>::vector_value (const Point<dim> &,
   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<dim, Number>::vector_value (const Point<dim> &,
 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]);
 }
 
 
@@ -424,16 +458,17 @@ void ConstantFunction<dim, Number>::value_list (
 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());
     };
 }
 
@@ -443,8 +478,8 @@ template <int dim, typename Number>
 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));
 }
 
 //---------------------------------------------------------------------------
@@ -493,6 +528,20 @@ ComponentSelectFunction (const std::pair<unsigned int,unsigned int> &selected,
 
 
 
+
+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> &,
@@ -502,9 +551,9 @@ void ComponentSelectFunction<dim, Number>::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 <int dim, typename Number>
 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>::

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.