]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Implement FE::convert_generalized_support_point_values_to_nodal_values for FESystem. 4187/head
authorWolfgang Bangerth <bangerth@colostate.edu>
Wed, 5 Apr 2017 21:45:27 +0000 (15:45 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Wed, 5 Apr 2017 21:45:53 +0000 (15:45 -0600)
doc/news/changes/minor/20170405Bangerth-2 [new file with mode: 0644]
include/deal.II/fe/fe_system.h
source/fe/fe_system.cc

diff --git a/doc/news/changes/minor/20170405Bangerth-2 b/doc/news/changes/minor/20170405Bangerth-2
new file mode 100644 (file)
index 0000000..68f5332
--- /dev/null
@@ -0,0 +1,6 @@
+New: The class FESystem now implements
+the
+FiniteElement::convert_generalized_support_point_values_to_nodal_values()
+interface.
+<br>
+(Wolfgang Bangerth, 2017/04/05)
index 2b8f9b515f2eef9374baa7a2f7f8f934b71636f3..4fd5c8e6bd42e02adee02b753450f8b14a73fe7c 100644 (file)
@@ -840,6 +840,18 @@ public:
   compare_for_face_domination (const FiniteElement<dim,spacedim> &fe_other) const;
   //@}
 
+  /**
+   * Implementation of the
+   * FiniteElement::convert_generalized_support_point_values_to_nodal_values()
+   * function. The current function simply takes the input argument apart,
+   * passes the pieces to the base elements, and then re-assembles everything
+   * into the output argument.
+   */
+  virtual
+  void
+  convert_generalized_support_point_values_to_nodal_values (const std::vector<Vector<double> > &support_point_values,
+                                                            std::vector<double>                &nodal_values) const;
+
   /**
    * Determine an estimate for the memory consumption (in bytes) of this
    * object.
index f88f90ffa49510c5658df4e10cd4536889783255..1bf683f0fbd95e3c273060f657f9b9fa22455d01 100644 (file)
@@ -2200,6 +2200,73 @@ FESystem<dim,spacedim>::get_constant_modes () const
 
 
 
+template <int dim, int spacedim>
+void
+FESystem<dim,spacedim>::
+convert_generalized_support_point_values_to_nodal_values (const std::vector<Vector<double> > &support_point_values,
+                                                          std::vector<double>                &nodal_values) const
+{
+  // we currently only support the case where each base element has exactly
+  // as many generalized support points as there are dofs in that element.
+  //
+  // in the more general case, if there are more generalized support
+  // points than dofs, we don't have the infrastructure at the time of
+  // writing this to tease apart which support point value
+  // belongs to which element
+  AssertDimension (support_point_values.size(), this->dofs_per_cell);
+  AssertDimension (nodal_values.size(), this->dofs_per_cell);
+
+  // loop over the bases and let them do the work on their
+  // share of the input argument
+  std::vector<Vector<double>> base_support_point_values;
+  std::vector<double>         base_nodal_values;
+  unsigned int                current_vector_component = 0;
+  for (unsigned int base=0; base<base_elements.size(); ++base)
+    {
+      const unsigned int element_multiplicity = this->element_multiplicity(base);
+      for (unsigned int m=0;
+           m<element_multiplicity;
+           ++m, current_vector_component += base_element(base).n_components())
+        {
+          // extract the support points of this base element.
+          // assume that support points are numbered in exactly
+          // the same way as dofs -- this is how the
+          // initialize_unit_support_points() function does it,
+          // at least
+          //
+          // to pick things apart, we could really use a base_to_system_index()
+          // function, but that doesn't exist -- just do it by using
+          // the reverse table -- the amount of work done here is not
+          // worth trying to optimizing this
+          base_support_point_values.resize  (base_element(base).dofs_per_cell);
+          for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+            if (this->system_to_base_index(i).first == std::make_pair(base,m))
+              {
+                const unsigned int base_n_components = base_element(base).n_components();
+                base_support_point_values[this->system_to_base_index(i).second]
+                .reinit (base_n_components, false);
+                for (unsigned int c=0; c<base_n_components; ++c)
+                  base_support_point_values[this->system_to_base_index(i).second][c]
+                    = support_point_values[i][current_vector_component+c];
+              }
+
+          // then call the base element to get its version of the
+          // nodal values
+          base_nodal_values.resize (base_element(base).dofs_per_cell);
+          base_element(base).convert_generalized_support_point_values_to_nodal_values
+          (base_support_point_values, base_nodal_values);
+
+          // finally put these nodal values back into global nodal
+          // values vector. use the same reverse loop as above
+          for (unsigned int i=0; i<this->dofs_per_cell; ++i)
+            if (this->system_to_base_index(i).first == std::make_pair(base,m))
+              nodal_values[i] = base_nodal_values[this->system_to_base_index(i).second];
+        }
+    }
+}
+
+
+
 template <int dim, int spacedim>
 std::size_t
 FESystem<dim,spacedim>::memory_consumption () const

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.