<h3>General</h3>
<ol>
+ <li><p>New: When computing errors using
+ VectorTools::integrate_difference in codimension one problems, if
+ you specified a norm that requires the computation of the gradients,
+ you'd get in trouble, because on codimension one manifolds we only
+ have information on the <em>tangential</em> gradient. This is now
+ fixed, by discarding the normal component of the provided function,
+ before computing the difference with the finite element function.
+ <br>
+ (Luca Heltai, 2010/12/05)
+ </p></li>
+
+ <li><p>New: We now have a new tutorial program (step-38), written by
+ Andrea Bonito, to compute the Laplace Beltrami operator on
+ a half sphere.
+ <br> (Luca Heltai, 2010/12/03)
+ </p></li>
+
<li><p>New: Added a new constructor for PETScWrappers::Vector that takes
an existing PETSc Vec that was created by the user and is only wrapped for
usage.
return_value[1] = -dPi *sin(dPi * p(0))*sin(dPi * p(1))*exp(p(2));
return_value[2] = sin(dPi * p(0))*cos(dPi * p(1))*exp(p(2));
- // tangential gradient: nabla u - (nabla u nu)nu
- Point<dim> normal;
- double dLength;
-
- dLength = sqrt(p(0)*p(0)+p(1)*p(1)+p(2)*p(2));
-
- normal[0] = p(0)/dLength;
- normal[1] = p(1)/dLength;
- normal[2] = p(2)/dLength;
-
- return return_value - (return_value*normal)*normal;
+ return return_value;
}
template <int dim>
* using the Vector::linfty_norm() function.
*
* For the global <i>H</i><sup>1</sup> norm and seminorm, the same rule applies as for the
- * <i>L</i><sup>2</sup> norm: compute the <i>l</i><sub>2</sub> norm of the cell error vector.
+ * <i>L</i><sup>2</sup> norm: compute the <i>l</i><sub>2</sub> norm
+ * of the cell error vector.
+ *
+ * Note that, in the codimension one case, if you ask for a norm
+ * that requires the computation of a gradient, then the provided
+ * function is automatically projected along the curve, and the
+ * difference is only computed on the tangential part of the
+ * gradient, since no information is available, on the finite
+ * dimensional one, on the normal component of the gradient.
* </ul>
*
* All functions use the finite element given to the DoFHandler object the last
case dealii::VectorTools::W1p_seminorm:
case dealii::VectorTools::W1infty_seminorm:
update_flags |= UpdateFlags (update_gradients);
+ if(spacedim == dim+1) update_flags |= UpdateFlags (update_normal_vectors);
+
break;
case dealii::VectorTools::H1_norm:
case dealii::VectorTools::W1p_norm:
case dealii::VectorTools::W1infty_norm:
update_flags |= UpdateFlags (update_gradients);
+ if(spacedim == dim+1) update_flags |= UpdateFlags (update_normal_vectors);
// no break!
default:
update_flags |= UpdateFlags (update_values);
}
// then subtract finite element
- // function_grads
+ // function_grads. We
+ // need to be careful
+ // in the codimension
+ // one case, since
+ // there we only have
+ // tangential gradients
+ // in the finite
+ // element function,
+ // not the full
+ // gradient. This is
+ // taken care of, by
+ // subtracting the
+ // normal component of
+ // the gradient from
+ // the exact function.
fe_values.get_function_grads (fe_function, function_grads);
- for (unsigned int k=0; k<n_components; ++k)
- for (unsigned int q=0; q<n_q_points; ++q)
- psi_grads[q][k] -= function_grads[q][k];
+ if(update_flags & update_normal_vectors)
+ for (unsigned int k=0; k<n_components; ++k)
+ for (unsigned int q=0; q<n_q_points; ++q)
+ psi_grads[q][k] -= (function_grads[q][k] +
+ (psi_grads[q][k]* // (f.n) n
+ fe_values.normal_vector(q))*
+ fe_values.normal_vector(q));
+ else
+ for (unsigned int k=0; k<n_components; ++k)
+ for (unsigned int q=0; q<n_q_points; ++q)
+ psi_grads[q][k] -= function_grads[q][k];
}
-
+
switch (norm)
{
case dealii::VectorTools::mean: