]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Add functions to set the values of degrees of freedom on a cell and/or its children.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Sun, 3 Jan 1999 18:49:28 +0000 (18:49 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Sun, 3 Jan 1999 18:49:28 +0000 (18:49 +0000)
git-svn-id: https://svn.dealii.org/trunk@720 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/deal.II/include/dofs/dof_accessor.h
deal.II/deal.II/source/dofs/dof_accessor.cc

index 05daf444451feae87fac8f3186ba6ffc8f94129f..1b977fc235503a304cd925f2c746f40007b31630 100644 (file)
@@ -586,7 +586,7 @@ class DoFCellAccessor :  public DoFSubstructAccessor<dim> {
     face (const unsigned int i) const;
 
                                     /**
-                                     * Return the value of the given vector
+                                     * Return the values of the given vector
                                      * restricted to the dofs of this
                                      * cell in the standard ordering: dofs
                                      * on vertex 0, dofs on vertex 1, etc,
@@ -594,10 +594,12 @@ class DoFCellAccessor :  public DoFSubstructAccessor<dim> {
                                      * dofs on quad 0, etc.
                                      *
                                      * It is assumed that the vector already
-                                     * has the right size beforehand.
+                                     * has the right size beforehand. This
+                                     * function is only callable for active
+                                     * cells.
                                      */
     void get_dof_values (const dVector &values,
-                        dVector       &dof_values) const;
+                        dVector       &local_values) const;
 
                                     /**
                                      * Return the interpolation of the given
@@ -614,17 +616,122 @@ class DoFCellAccessor :  public DoFSubstructAccessor<dim> {
                                      * class to compute the interpolation
                                      * from the children to the present cell.
                                      *
-                                     * It is assumed that the vector already
-                                     * has the right size beforehand.
+                                     * It is assumed that both vectors already
+                                     * have the right size beforehand. This
+                                     * function assumes the existence of an
+                                     * interpolation from child cells to the
+                                     * mother cell, denoted by the restriction
+                                     * matrices of the finite element class.
+                                     * Futhermore, this interpolation should
+                                     * be possible for each child alone, i.e.
+                                     * it should be possible to compute the
+                                     * restriction by writing values obtained
+                                     * from each child directly into the output
+                                     * vector, without, for example, computing
+                                     * an average over all children.
+                                     * These properties, however, do not exist
+                                     * for all elements; an example is the
+                                     * DG(0) element, which represents
+                                     * piecewise constant elements: for these
+                                     * the restriction to mother cell could
+                                     * be the average of the values of the
+                                     * children, maybe weighted by the measure
+                                     * of each child. It is not yet decided
+                                     * what the this function does in these
+                                     * cases.
                                      */
     void get_interpolated_dof_values (const dVector &values,
                                      dVector       &interpolated_values) const;
-    
 
+                                    /**
+                                     * This function is the counterpart to
+                                     * #get_dof_values#: it takes a vector
+                                     * of values for the degrees of freedom
+                                     * of the cell pointed to by this iterator
+                                     * and writes these values into the global
+                                     * data vector #values#. This function
+                                     * is only callable for active cells.
+                                     *
+                                     * Note that for continuous finite
+                                     * elements, calling this function affects
+                                     * the dof values on neighboring cells as
+                                     * well. It may also violate continuity
+                                     * requirements for hanging nodes, if
+                                     * neighboring cells are less refined than
+                                     * the present one. These requirements
+                                     * are not taken care of and must be
+                                     * enforced by the user afterwards.
+                                     *
+                                     * It is assumed that both vectors already
+                                     * have the right size beforehand.
+                                     */                                       
+    void set_dof_values (const dVector &local_values,
+                        dVector       &values) const;
+
+                                    /**
+                                     * This, again, is the counterpart to
+                                     * #get_interpolated_dof_values#: you
+                                     * specify the dof values on a cell and
+                                     * these are interpolated to the children
+                                     * of the present cell and set on the
+                                     * terminal cells.
+                                     *
+                                     * In principle, it works as follows: if
+                                     * the cell pointed to by this object is
+                                     * terminal, then the dof values are set
+                                     * in the global data vector by calling
+                                     * the #set_dof_values# function;
+                                     * otherwise, the values are prolonged
+                                     * to each of the children and this
+                                     * function is called for each of them.
+                                     *
+                                     * Using the #get_interpolated_dof_values#
+                                     * and this function, you can compute the
+                                     * interpolation of a finite element
+                                     * function to a coarser grid by first
+                                     * getting the interpolated solution on a
+                                     * cell of the coarse grid and afterwards
+                                     * redistributing it using this function.
+                                     *
+                                     * Note that for continuous finite
+                                     * elements, calling this function affects
+                                     * the dof values on neighboring cells as
+                                     * well. It may also violate continuity
+                                     * requirements for hanging nodes, if
+                                     * neighboring cells are less refined than
+                                     * the present one, or if their children are
+                                     * less refined than the children of this
+                                     * cell. These requirements
+                                     * are not taken care of and must be
+                                     * enforced by the user afterwards.
+                                     *
+                                     * It is assumed that both vectors already
+                                     * have the right size beforehand. This
+                                     * function relies on the existence of a
+                                     * natural interpolation property of
+                                     * finite element spaces of a cell to
+                                     * its children, denoted by the
+                                     * prolongation matrices of finite element
+                                     * classes. For some elements, the spaces
+                                     * on coarse and fine grids are not nested,
+                                     * in which case the interpolation to a
+                                     * child is not the identity; refer to the
+                                     * documentation of the respective finite
+                                     * element class for a description of what
+                                     * the prolongation matrices represent in
+                                     * this case.
+                                     */
+    void set_dof_values_by_interpolation (const dVector &local_values,
+                                         dVector       &values) const;
+    
                                     /**
                                      *  Exception
                                      */
     DeclException0 (ExcNotUsefulForThisDimension);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcNotActive);
 };
 
 
index b24f7ec9985cb0343ee7c170bd5647a592de260b..66f266706a8fb0a63b3dc1fd334ad6ac84c6cd31 100644 (file)
@@ -441,24 +441,51 @@ DoFCellAccessor<1>::face (const unsigned int) const {
 template <>
 void
 DoFCellAccessor<1>::get_dof_values (const dVector &values,
-                                   dVector       &dof_values) const {
+                                   dVector       &local_values) const {
   Assert (dof_handler != 0, ExcInvalidObject());
   Assert (&dof_handler->get_fe() != 0, ExcInvalidObject());
-  Assert (dof_values.size() == dof_handler->get_fe().total_dofs,
+  Assert (local_values.size() == dof_handler->get_fe().total_dofs,
          ExcVectorDoesNotMatch());
   Assert (values.size() == dof_handler->n_dofs(),
          ExcVectorDoesNotMatch());
+  Assert (active(), ExcNotActive());
+  
+  const unsigned int dofs_per_vertex = dof_handler->get_fe().dofs_per_vertex,
+                    dofs_per_line   = dof_handler->get_fe().dofs_per_line;
+  vector<double>::iterator next_local_value=local_values.begin();
+  for (unsigned int vertex=0; vertex<2; ++vertex)
+    for (unsigned int d=0; d<dofs_per_vertex; ++d)
+      *next_lcoal_value++ = values(vertex_dof_index(vertex,d));
+  for (unsigned int d=0; d<dofs_per_line; ++d)
+    *next_local_value++ = values(dof_index(d));
+};
+
+
 
+template <>
+void
+DoFCellAccessor<1>::set_dof_values (const dVector &local_values,
+                                   dVector       &values) const {
+  Assert (dof_handler != 0, ExcInvalidObject());
+  Assert (&dof_handler->get_fe() != 0, ExcInvalidObject());
+  Assert (local_values.size() == dof_handler->get_fe().total_dofs,
+         ExcVectorDoesNotMatch());
+  Assert (values.size() == dof_handler->n_dofs(),
+         ExcVectorDoesNotMatch());
+  Assert (active(), ExcNotActive());
+  
   const unsigned int dofs_per_vertex = dof_handler->get_fe().dofs_per_vertex,
                     dofs_per_line   = dof_handler->get_fe().dofs_per_line;
-  vector<double>::iterator next_dof_value=dof_values.begin();
+  vector<double>::const_iterator next_local_value=local_values.begin();
   for (unsigned int vertex=0; vertex<2; ++vertex)
     for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next_dof_value++ = values(vertex_dof_index(vertex,d));
+       values(vertex_dof_index(vertex,d)) = *next_local_value++;
   for (unsigned int d=0; d<dofs_per_line; ++d)
-    *next_dof_value++ = values(dof_index(d));
+    values(dof_index(d)) = *next_local_value++;
 };
 
+
+
 #endif
 
 
@@ -476,28 +503,59 @@ DoFCellAccessor<2>::face (const unsigned int i) const {
 template <>
 void
 DoFCellAccessor<2>::get_dof_values (const dVector &values,
-                                   dVector       &dof_values) const {
+                                   dVector       &local_values) const {
   Assert (dof_handler != 0, ExcInvalidObject());
   Assert (&dof_handler->get_fe() != 0, ExcInvalidObject());
-  Assert (dof_values.size() == dof_handler->get_fe().total_dofs,
+  Assert (local_values.size() == dof_handler->get_fe().total_dofs,
          ExcVectorDoesNotMatch());
   Assert (values.size() == dof_handler->n_dofs(),
          ExcVectorDoesNotMatch());
+  Assert (active(), ExcNotActive());
+  
+  const unsigned int dofs_per_vertex = dof_handler->get_fe().dofs_per_vertex,
+                    dofs_per_line   = dof_handler->get_fe().dofs_per_line,
+                    dofs_per_quad   = dof_handler->get_fe().dofs_per_quad;
+  vector<double>::iterator next_local_value=local_values.begin();
+  for (unsigned int vertex=0; vertex<4; ++vertex)
+    for (unsigned int d=0; d<dofs_per_vertex; ++d)
+      *next_local_value++ = values(vertex_dof_index(vertex,d));
+  for (unsigned int line=0; line<4; ++line)
+    for (unsigned int d=0; d<dofs_per_line; ++d)
+      *next_local_value++ = values(this->line(line)->dof_index(d));
+  for (unsigned int d=0; d<dofs_per_quad; ++d)
+    *next_local_value++ = values(dof_index(d));
+};
 
+
+
+template <>
+void
+DoFCellAccessor<2>::set_dof_values (const dVector &local_values,
+                                   dVector       &values) const {
+  Assert (dof_handler != 0, ExcInvalidObject());
+  Assert (&dof_handler->get_fe() != 0, ExcInvalidObject());
+  Assert (local_values.size() == dof_handler->get_fe().total_dofs,
+         ExcVectorDoesNotMatch());
+  Assert (values.size() == dof_handler->n_dofs(),
+         ExcVectorDoesNotMatch());
+  Assert (active(), ExcNotActive());
+  
   const unsigned int dofs_per_vertex = dof_handler->get_fe().dofs_per_vertex,
                     dofs_per_line   = dof_handler->get_fe().dofs_per_line,
                     dofs_per_quad   = dof_handler->get_fe().dofs_per_quad;
-  vector<double>::iterator next_dof_value=dof_values.begin();
+  vector<double>::const_iterator next_local_value=local_values.begin();
   for (unsigned int vertex=0; vertex<4; ++vertex)
     for (unsigned int d=0; d<dofs_per_vertex; ++d)
-      *next_dof_value++ = values(vertex_dof_index(vertex,d));
+      values(vertex_dof_index(vertex,d)) = *next_local_value++;
   for (unsigned int line=0; line<4; ++line)
     for (unsigned int d=0; d<dofs_per_line; ++d)
-      *next_dof_value++ = values(this->line(line)->dof_index(d));
+      values(this->line(line)->dof_index(d)) = *next_local_value++;
   for (unsigned int d=0; d<dofs_per_quad; ++d)
-    *next_dof_value++ = values(dof_index(d));
+    values(dof_index(d)) = *next_local_value++;
 };
 
+
+
 #endif
 
 
@@ -556,6 +614,41 @@ DoFCellAccessor<dim>::get_interpolated_dof_values (const dVector &values,
 
 
 
+template <int dim>
+void
+DoFCellAccessor<dim>::set_dof_values_by_interpolation (const dVector &local_values,
+                                                      dVector       &values) const {
+  const unsigned int total_dofs = dof_handler->get_fe().total_dofs;
+  
+  Assert (dof_handler != 0, ExcInvalidObject());
+  Assert (&dof_handler->get_fe() != 0, ExcInvalidObject());
+  Assert (local_values.size() == total_dofs,
+         ExcVectorDoesNotMatch());
+  Assert (values.size() == dof_handler->n_dofs(),
+         ExcVectorDoesNotMatch());
+
+  if (!has_children())
+                                    // if this cell has no children: simply
+                                    // set the values on this cell
+    set_dof_values (local_values, values);
+  else
+                                    // otherwise distribute them to the children
+    {
+      dVector tmp(total_dofs);
+      
+      for (unsigned int child=0; child<GeometryInfo<dim>::children_per_cell;
+          ++child)
+       {
+                                          // prolong the given data
+                                          // to the present cell
+         dof_handler->get_fe().prolongate(child).vmult (tmp, local_values);
+         this->child(child)->set_dof_values_by_interpolation (tmp, values);
+       };
+    };
+};
+
+
+
 
 
 

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.