]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Fix a bug in cell similarity detection with FESystem
authorMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Tue, 7 Mar 2017 17:24:50 +0000 (18:24 +0100)
committerMartin Kronbichler <kronbichler@lnm.mw.tum.de>
Tue, 7 Mar 2017 21:14:45 +0000 (22:14 +0100)
source/fe/fe_system.cc
tests/numerics/create_mass_matrix_05.cc

index 652470e7e06403832afaeadb233c746479718f0a..53b4a930edfc1667615425b85ff83c5b0d111479 100644 (file)
@@ -1206,61 +1206,62 @@ compute_fill (const Mapping<dim,spacedim>                      &mapping,
         //TODO: Introduce the needed table and loop only over base element shape functions. This here is not efficient at all AND very bad style
         const UpdateFlags base_flags = base_fe_data.update_each;
 
-        // if the current cell is just a translation of the previous one,
-        // the underlying data has not changed, and we don't even need to
-        // enter this section
-        if (cell_similarity != CellSimilarity::translation)
-          for (unsigned int system_index=0; system_index<this->dofs_per_cell;
-               ++system_index)
-            if (this->system_to_base_table[system_index].first.first == base_no)
-              {
-                const unsigned int
-                base_index = this->system_to_base_table[system_index].second;
-                Assert (base_index<base_fe.dofs_per_cell, ExcInternalError());
-
-                // now copy. if the shape function is primitive, then there
-                // is only one value to be copied, but for non-primitive
-                // elements, there might be more values to be copied
-                //
-                // so, find out from which index to take this one value, and
-                // to which index to put
-                unsigned int out_index = 0;
-                for (unsigned int i=0; i<system_index; ++i)
-                  out_index += this->n_nonzero_components(i);
-                unsigned int in_index = 0;
-                for (unsigned int i=0; i<base_index; ++i)
-                  in_index += base_fe.n_nonzero_components(i);
-
-                // then loop over the number of components to be copied
-                Assert (this->n_nonzero_components(system_index) ==
-                        base_fe.n_nonzero_components(base_index),
-                        ExcInternalError());
+        // some base element might involve values that depend on the shape
+        // of the geometry, so we always need to copy the shape values around
+        // also in case we detected a cell similarity (but no heavy work will
+        // be done inside the individual elements in case we have a
+        // translation and simple elements).
+        for (unsigned int system_index=0; system_index<this->dofs_per_cell;
+             ++system_index)
+          if (this->system_to_base_table[system_index].first.first == base_no)
+            {
+              const unsigned int
+              base_index = this->system_to_base_table[system_index].second;
+              Assert (base_index<base_fe.dofs_per_cell, ExcInternalError());
+
+              // now copy. if the shape function is primitive, then there
+              // is only one value to be copied, but for non-primitive
+              // elements, there might be more values to be copied
+              //
+              // so, find out from which index to take this one value, and
+              // to which index to put
+              unsigned int out_index = 0;
+              for (unsigned int i=0; i<system_index; ++i)
+                out_index += this->n_nonzero_components(i);
+              unsigned int in_index = 0;
+              for (unsigned int i=0; i<base_index; ++i)
+                in_index += base_fe.n_nonzero_components(i);
+
+              // then loop over the number of components to be copied
+              Assert (this->n_nonzero_components(system_index) ==
+                      base_fe.n_nonzero_components(base_index),
+                      ExcInternalError());
 
-                if (base_flags & update_values)
-                  for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
-                    for (unsigned int q=0; q<n_q_points; ++q)
-                      output_data.shape_values[out_index+s][q] =
-                        base_data.shape_values(in_index+s,q);
-
-                if (base_flags & update_gradients)
-                  for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
-                    for (unsigned int q=0; q<n_q_points; ++q)
-                      output_data.shape_gradients[out_index+s][q] =
-                        base_data.shape_gradients[in_index+s][q];
-
-                if (base_flags & update_hessians)
-                  for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
-                    for (unsigned int q=0; q<n_q_points; ++q)
-                      output_data.shape_hessians[out_index+s][q] =
-                        base_data.shape_hessians[in_index+s][q];
-
-                if (base_flags & update_3rd_derivatives)
-                  for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
-                    for (unsigned int q=0; q<n_q_points; ++q)
-                      output_data.shape_3rd_derivatives[out_index+s][q] =
-                        base_data.shape_3rd_derivatives[in_index+s][q];
+              if (base_flags & update_values)
+                for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
+                  for (unsigned int q=0; q<n_q_points; ++q)
+                    output_data.shape_values[out_index+s][q] =
+                      base_data.shape_values(in_index+s,q);
+
+              if (base_flags & update_gradients)
+                for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
+                  for (unsigned int q=0; q<n_q_points; ++q)
+                    output_data.shape_gradients[out_index+s][q] =
+                      base_data.shape_gradients[in_index+s][q];
+
+              if (base_flags & update_hessians)
+                for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
+                  for (unsigned int q=0; q<n_q_points; ++q)
+                    output_data.shape_hessians[out_index+s][q] =
+                      base_data.shape_hessians[in_index+s][q];
+
+              if (base_flags & update_3rd_derivatives)
+                for (unsigned int s=0; s<this->n_nonzero_components(system_index); ++s)
+                  for (unsigned int q=0; q<n_q_points; ++q)
+                    output_data.shape_3rd_derivatives[out_index+s][q] =
+                      base_data.shape_3rd_derivatives[in_index+s][q];
 
-              }
+            }
       }
 }
 
index 6f900d4f861d8faf881e7836e1c9a712e96d7bbf..e9ced88c9532b50ee7b80ef5e6b8be29efb20a94 100644 (file)
@@ -122,6 +122,12 @@ int main ()
   deallog << std::fixed;
   deallog.attach(logfile);
 
+  // there used to be a bug in the cell similarity detection for the above
+  // test pattern of an FE_RaviartThomas inside and FESystem, but cell
+  // similarity is only enabled without threads. to make sure this test is
+  // effective, manually set the thread limit 1.
+  MultithreadInfo::set_thread_limit(1);
+
   deallog.push ("2d");
   check<2> ();
   deallog.pop ();

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.