fpoptimizer.cc
)
+IF(DEAL_II_WITH_THREADS)
+ DEAL_II_ADD_DEFINITIONS(obj_functionparser "FP_USE_THREAD_SAFE_EVAL")
+ENDIF()
#
SET(_configuration)
- IF(_file MATCHES "debug")
+ IF(_file MATCHES "\\.debug\\.")
SET(_configuration DEBUG)
- ELSEIF(_file MATCHES "release")
+ ELSEIF(_file MATCHES "\\.release\\.")
SET(_configuration RELEASE)
ENDIF()
+ #
+ # A "binary" in the output file indicates binary output. In this case we
+ # have to switch to plain diff instead of (possibly) numdiff, which can
+ # only work on plain text files.
+ #
+ # TODO: The indirection with ${${_test_diff_variable}} is necessary to
+ # avoid quoting issues with the command line :-/ - come up with a fix for
+ # that
+ #
+
+ SET(_test_diff_variable TEST_DIFF)
+ IF(_file MATCHES "\\.binary\\.")
+ IF(NOT DIFF_EXECUTABLE MATCHES "-NOTFOUND")
+ SET(_test_diff_variable DIFF_EXECUTABLE)
+ ENDIF()
+ ENDIF()
+
#
# Determine whether the test should be run with mpirun:
#
COMMAND rm -f ${_test_directory}/failing_diff
COMMAND touch ${_test_directory}/diff
COMMAND
- ${TEST_DIFF}
+ ${${_test_diff_variable}} # see comment in line 72
${_test_directory}/output
${_comparison_file}
> ${_test_directory}/diff
\"${_comparison}\":
The feature \"DEAL_II_${_feature}\" does not exist.\n"
)
- #SET(_define_test FALSE)
ENDIF()
ENDFOREACH()
# This macro will
#
# - add ${feature}_INCLUDE_DIRS and ${feature}_INCLUDE_PATH
-# to the list of (internal) include
-# directories
+# to the list of (internal) include directories
# - and if ${feature}_ADD_TO_USER_INCLUDE_DIRS is defined also to
# DEAL_II_USER_INCLUDE_DIRS
#
MACRO(REGISTER_FEATURE _feature)
- MESSAGE(STATUS "Register enabled external feature ${_feature}:")
-
# variables for include directories:
FOREACH(_var ${_feature}_INCLUDE_DIRS ${_feature}_INCLUDE_PATH)
IF(DEFINED ${_var})
- MESSAGE(STATUS " ${_var}")
INCLUDE_DIRECTORIES(${${_var}})
IF(${_feature}_ADD_TO_USER_INCLUDE_DIRS)
LIST(APPEND DEAL_II_USER_INCLUDE_DIRS ${${_var}})
# variables for linker flags:
FOREACH(_var ${_feature}_LINKER_FLAGS ${_feature}_LINK_FLAGS)
IF(DEFINED ${_var})
- MESSAGE(STATUS " ${_var}")
ADD_FLAGS(DEAL_II_LINKER_FLAGS "${${_var}}")
ENDIF()
ENDFOREACH()
# variables for compiler flags:
FOREACH(_var ${_feature}_CXX_FLAGS ${_feature}_COMPILE_FLAGS)
IF(DEFINED ${_var})
- MESSAGE(STATUS " ${_var}")
ADD_FLAGS(CMAKE_CXX_FLAGS "${${_var}}")
ENDIF()
ENDFOREACH()
IF(DEFINED ${_feature}_LIBRARIES)
- MESSAGE(STATUS " ${_feature}_LIBRARIES")
#
# Add ${_feature}_LIBRARIES to
# DEAL_II_EXTERNAL_LIBRARIES
# TEST_TIME_LIMIT
# TEST_PICKUP_REGEX
# TEST_OVERRIDE_LOCATION
-# NUMDIFF_DIR
#
# For details, consult the ./README file.
#
#
# We need deal.II and Perl as external packages:
#
+
FIND_PACKAGE(deal.II 8.0 REQUIRED
HINTS ${DEAL_II_BINARY_DIR} ${DEAL_II_DIR}
)
#
# We need a diff tool, preferably numdiff:
#
+
FIND_PROGRAM(DIFF_EXECUTABLE
NAMES diff
+ HINTS ${DIFF_DIR}
+ PATH_SUFFIXES bin
)
FIND_PROGRAM(NUMDIFF_EXECUTABLE
MARK_AS_ADVANCED(DIFF_EXECUTABLE NUMDIFF_EXECUTABLE)
-IF( NUMDIFF_EXECUTABLE MATCHES "-NOTFOUND"
- AND DIFF_EXECUTABLE MATCHES "-NOTFOUND" )
- MESSAGE(FATAL_ERROR
- "Could not find diff or numdiff. One of those are required for running the testsuite."
- )
-ENDIF()
-
IF("${TEST_DIFF}" STREQUAL "")
+ #
+ # No TEST_DIFF is set, specify one:
+ #
+
IF(NOT NUMDIFF_EXECUTABLE MATCHES "-NOTFOUND")
- SET(TEST_DIFF ${NUMDIFF_EXECUTABLE} -a 1e-6 -s ' \\t\\n:')
+ SET(TEST_DIFF ${NUMDIFF_EXECUTABLE} -a 1e-6 -r 1e-8 -s ' \\t\\n:')
+ ELSEIF(NOT DIFF_EXECUTABLE MATCHES "-NOTFOUND")
+ SET(TEST_DIFF ${DIFF_EXECUTABLE})
ELSE()
- SET(TEST_DIFF ${DIFF_EXECUTABLE})
+ MESSAGE(FATAL_ERROR
+ "Could not find diff or numdiff. One of those are required for running the testsuite.\n"
+ "Please specify TEST_DIFF by hand."
+ )
ENDIF()
-ELSE()
- # TODO: I have no idea how to prepare a custom string comming possibly
- # through two layers of command line into a list...
- SEPARATE_ARGUMENTS(TEST_DIFF ${TEST_DIFF})
ENDIF()
#
# Set a default time limit of 600 seconds:
#
+
SET_IF_EMPTY(TEST_TIME_LIMIT 600)
#
# And finally, enable testing:
#
+
ENABLE_TESTING()
#
# A custom target that does absolutely nothing. It is used in the main
# project to trigger a "make rebuild_cache" if necessary.
#
+
ADD_CUSTOM_TARGET(regenerate)
<li><a href="#restrictbuild">Restricting tests for build configurations</a></li>
<li><a href="#restrictfeature">Restricting tests for feature configurations</a></li>
<li><a href="#mpi">Running tests with MPI</a></li>
+ <li><a href="#binary">Tests with binary output</a></li>
<li><a href="#expect">Changing condition for success</a></li>
<li><a href="#layoutaddtests">Adding new tests</a></li>
</ol>
just <code>category/test.output</code>:
<pre>
- category/test.[with_<feature>=<on|off>.]*[mpirun=<x>.][expect=<y>.][<debug|release>.]output
+ category/test.[with_<feature>=<on|off>.]*[mpirun=<x>.][expect=<y>.][binary.][<debug|release>.]output
</pre>
Normally, a test will be set up so that it runs twice, once in debug and
once in release configuration.
files for different numbers of MPI processes.
</p>
+ <a name="binary"></a>
+ <h3>Tests with binary output</h3>
+ <p>
+ If a test produces binary output add <code>binary</code> to the
+ output file to indicate this:
+ <pre>
+
+ category/test.binary.output
+ </pre>
+ The testsuite ensures that a diff tool suitable for comparing binary
+ output files is used instead of the default diff tool, which (as in
+ the case of <code>numdiff</code>) might be unable to compare binary
+ files.
+ </p>
+
<a name="expect"></a>
<h3>Changing condition for success</h3>
<p>
<h3>Specific improvements</h3>
<ol>
+ <li> Fixed: GridGenerator::parallelogram was not instantiated properly
+ on intel compilers.
+ <br>
+ (Timo Heister, 2013/11/17)
+ </li>
+
+ <li>
+ Fixed: MappingQ1::transform_real_to_unit_cell() could fail in some
+ cases with very elongated and twisted cells. This should now be fixed
+ with an algorithm that uses a better method of computing the Newton
+ convergence.
+ <br>
+ (Wolfgang Bangerth, 2013/11/17)
+ </li>
+
+ <li>
+ Fixed: VectorTools::compute_no_normal_flux_constraints had a bug that
+ only appeared in rare cases at vertices of the domain if one adjacent
+ cell had two boundary indicators selected for no normal flux and another
+ had only one. This is now fixed.
+ <br>
+ (Wolfgang Bangerth, 2013/11/17)
+ </li>
+
+ <li> Fixed: dealii::FETools::interpolation_difference was
+ not working for TrilinosWrappers::MPI::Vectors with ghost
+ entries. The TrilinosWrappers::VectorBase class has now a
+ get_mpi_communicator method similar to the PETSc vector
+ classes.
+ <br>
+ (Martin Steigemann, Martin Kronbichler, 2013/11/17)
+ </li>
+
+ <li> Fixed: Bundled fparser is now compiled with FP_USE_THREAD_SAFE_EVAL in
+ case of enabled threading support so that it is thread safe.
+ <br>
+ (Matthias Maier, reported by Francesco Cattoglio 2013/11/16)
+ </li>
+
<li> Fixed: The CellData class now has a default constructor that
sets the material and boundary indicators to zero. This fixes certain
internal errors with the Intel ICC compiler.
<li>
New: parallel::distributed::BlockVector has now methods update_ghost_values,
- compress, set_out_ghosts, and has_ghost_elements that do the respective
+ compress, zero_out_ghosts, and has_ghost_elements that do the respective
operation on each block of parallel::distributed::Vector.
<br>
(Martin Kronbichler, 2013/10/18)
New: All vector classes now have functions <code>extract_subvector_to()</code>
that allow extracting not just a single value but a whole set.
<br>
- (Fahad Alrasched, 2013/09/02)
+ (Fahad Alrashed, 2013/09/02)
</li>
<li>
# SET(PETSC_VERSION_SUBMINOR "z" CACHE STRING "")
# SET(PETSC_VERSION_PATCH "p" CACHE STRING "")
# SET(PETSC_WITH_MPI_UNI FALSE CACHE BOOL "")
+# SET(PETSC_WITH_COMPLEX FALSE CACHE BOOL "")
#
{
namespace internal
{
+ /**
+ * Given two sets of indices that are assumed to be sorted, determine
+ * whether they will have a nonempty intersection. The actual intersection is
+ * not computed.
+ * @param indices1 A set of indices, assumed sorted.
+ * @param indices2 A set of indices, assumed sorted.
+ * @return Whether the two sets of indices do have a nonempty intersection.
+ */
+ inline
+ bool
+ have_nonempty_intersection (const std::vector<types::global_dof_index> &indices1,
+ const std::vector<types::global_dof_index> &indices2)
+ {
+ // we assume that both arrays are sorted, so we can walk
+ // them in lockstep and see if we encounter an index that's
+ // in both arrays. once we reach the end of either array,
+ // we know that there is no intersection
+ std::vector<types::global_dof_index>::const_iterator
+ p = indices1.begin(),
+ q = indices2.begin();
+ while ((p != indices1.end()) && (q != indices2.end()))
+ {
+ if (*p < *q)
+ ++p;
+ else if (*p > *q)
+ ++q;
+ else
+ // conflict found!
+ return true;
+ }
+
+ // no conflict found!
+ return false;
+ }
+
+
/**
* Create a partitioning of the given range of iterators using a simplified
* version of the Cuthill-McKee algorithm (Breadth First Search algorithm).
std::vector<Iterator> new_zone;
for (; previous_zone_it!=previous_zone_end; ++previous_zone_it)
{
- std::vector<types::global_dof_index> conflict_indices = get_conflict_indices(*previous_zone_it);
+ const std::vector<types::global_dof_index>
+ conflict_indices = get_conflict_indices(*previous_zone_it);
+
const unsigned int n_conflict_indices(conflict_indices.size());
for (unsigned int i=0; i<n_conflict_indices; ++i)
{
std::vector<std::vector<types::global_dof_index> > conflict_indices(partition_size);
std::vector<std::vector<unsigned int> > graph(partition_size);
- // Get the conflict indices associated to each iterator. The conflict_indices have to be sorted so
- // set_intersection can be used later.
+ // Get the conflict indices associated to each iterator. The conflict_indices have to
+ // be sorted so we can more easily find conflicts later on
for (unsigned int i=0; i<partition_size; ++i)
{
conflict_indices[i] = get_conflict_indices(partition[i]);
- std::sort(conflict_indices[i].begin(),conflict_indices[i].end());
+ std::sort(conflict_indices[i].begin(), conflict_indices[i].end());
}
// Compute the degree of each vertex of the graph using the
// intersection of the conflict indices.
- std::vector<types::global_dof_index> conflict_indices_intersection;
- std::vector<types::global_dof_index>::iterator intersection_it;
for (unsigned int i=0; i<partition_size; ++i)
for (unsigned int j=i+1; j<partition_size; ++j)
- {
- conflict_indices_intersection.resize(std::max(conflict_indices[i].size(),
- conflict_indices[j].size()));
- intersection_it = std::set_intersection(conflict_indices[i].begin(),
- conflict_indices[i].end(),
- conflict_indices[j].begin(),
- conflict_indices[j].end(),
- conflict_indices_intersection.begin());
// If the two iterators share indices then we increase the degree of the
// vertices and create an ''edge'' in the graph.
- if (intersection_it!=conflict_indices_intersection.begin())
+ if (have_nonempty_intersection (conflict_indices[i], conflict_indices[j]))
{
++degrees[i];
++degrees[j];
graph[i].push_back(j);
graph[j].push_back(i);
}
- }
// Sort the vertices by decreasing degree.
std::vector<int>::iterator degrees_it;
// identifies the FE and the policy
unsigned int n_cells = tria->n_cells();
std::string fe_name = selected_fe->get_name();
- std::string policy_name = typeid(*policy).name();
+ std::string policy_name = policy->to_string();
ar &n_cells &fe_name &policy_name;
}
AssertThrow (fe_name == selected_fe->get_name(),
ExcMessage ("The finite element associated with this DoFHandler does not match "
"the one that was associated with the DoFHandler previously stored."));
- AssertThrow (policy_name == typeid(*policy).name(),
- ExcMessage ("The policy associated with this DoFHandler does not match "
- "the one that was associated with the DoFHandler previously stored."));
+ AssertThrow (policy_name == policy->to_string(),
+ ExcMessage (std::string ("The policy currently associated with this DoFHandler (")
+ + policy->to_string()
+ +std::string(") does not match the one that was associated with the "
+ "DoFHandler previously stored (")
+ + policy_name
+ + ")."));
}
*/
virtual ~PolicyBase ();
+ /**
+ * Convert type of policy to a string. This is used as a
+ * workaround in serialization because the intel compiler can
+ * not handle typeid correctly.
+ */
+ virtual std::string to_string () const = 0;
+
/**
* Distribute degrees of freedom on
* the object given as last argument.
virtual
NumberCache
distribute_dofs (dealii::DoFHandler<dim,spacedim> &dof_handler) const;
+
+ /**
+ * Convert type of policy to a string. This is used as a
+ * workaround in serialization because the intel compiler can
+ * not handle typeid correctly.
+ */
+ virtual std::string to_string () const;
+
/**
* Distribute multigrid DoFs.
NumberCache
distribute_dofs (dealii::DoFHandler<dim,spacedim> &dof_handler) const;
+ /**
+ * Convert type of policy to a string. This is used as a
+ * workaround in serialization because the intel compiler can
+ * not handle typeid correctly.
+ */
+ virtual std::string to_string () const;
+
/**
* Distribute multigrid DoFs.
*/
template <int dim>
void
parallelogram (Triangulation<dim> &tria,
- const Point<dim> (&corners) [dim],
+ const Point<dim> corners[dim],
const bool colorize=false);
/**
}
- // If the calling matrix owns the row to which we want to add values, we
+ // If the calling processor owns the row to which we want to add values, we
// can directly call the Epetra_CrsMatrix input function, which is much
// faster than the Epetra_FECrsMatrix function.
if (row_partitioner().MyGID(static_cast<TrilinosWrappers::types::int_type>(row)) == true)
* consumption in bytes.
*/
std::size_t memory_consumption () const;
+
+ /**
+ * Return a reference to the MPI
+ * communicator object in use with this
+ * object.
+ */
+ const MPI_Comm &get_mpi_communicator () const;
//@}
/**
}
+
+ inline
+ const MPI_Comm &
+ VectorBase::get_mpi_communicator () const
+ {
+ static MPI_Comm comm;
+
+#ifdef DEAL_II_WITH_MPI
+
+ const Epetra_MpiComm *mpi_comm
+ = dynamic_cast<const Epetra_MpiComm *>(&vector->Map().Comm());
+ comm = mpi_comm->Comm();
+
+#else
+
+ comm = MPI_COMM_SELF;
+
+#endif
+
+ return comm;
+ }
+
+
+
#endif // DOXYGEN
}
/**
- * Compute the constraints that correspond to boundary conditions of the
+ * This function computes the constraints that correspond to boundary conditions of the
* form $\vec n \cdot \vec u=0$, i.e. no normal flux if $\vec u$ is a
* vector-valued quantity. These conditions have exactly the form handled by
* the ConstraintMatrix class, so instead of creating a map between boundary
* There are cases where one cell contributes two tangential directions and
* another one only one; for example, this would happen if both top and
* front faces of the left cell belong to the boundary selected whereas only
- * the top face of the right cell belongs to it. This case is not currently
- * implemented.
+ * the top face of the right cell belongs to it, maybe indicating the the entire
+ * front part of the domain is a smooth manifold whereas the top really forms
+ * two separate manifolds that meet in a ridge, and that no-flux boundary
+ * conditions are only desired on the front manifold and the right one on top.
+ * In cases like these, it's difficult to define what should happen. The
+ * current implementation simply ignores the one contribution from the
+ * cell that only contributes one normal vector. In the example shown, this
+ * is acceptable because the normal vector for the front face of the left
+ * cell is the same as the normal vector provided by the front face of
+ * the right cell (the surface is planar) but it would be a problem if the
+ * front manifold would be curved. Regardless, it is unclear how one would
+ * proceed in this case and ignoring the single cell is likely the best
+ * one can do.
*
*
* <h4>Results</h4>
* point_difference() function.
*
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
* this function uses an
* arbitrary mapping to evaluate
* the difference.
- *
+ *
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
* point_difference() function.
*
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
* Same as above for hp.
*
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
* "step-3".
*
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
/**
* Same as above for hp.
- *
+ *
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
* mapping to evaluate the difference.
*
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
* Same as above for hp.
*
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
* mapping to evaluate the difference.
*
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
* Same as above for hp.
*
* @note If the cell in which the point is found
- * is not locally owned, an exception of type
+ * is not locally owned, an exception of type
* VectorTools::ExcPointNotAvailableHere
* is thrown.
*/
};
+ template <int dim>
+ std::ostream & operator << (std::ostream &out,
+ const VectorDoFTuple<dim> &vdt)
+ {
+ for (unsigned int d=0; d<dim; ++d)
+ out << vdt.dof_indices[d] << (d < dim-1 ? " " : "");
+ return out;
+ }
+
+
/**
* Add the constraint
internal::VectorDoFTuple<dim> vector_dofs;
vector_dofs.dof_indices[0] = face_dofs[i];
+ Assert(first_vector_component+dim<=fe.n_components(),
+ ExcMessage("Error: the finite element does not have enough components "
+ "to define a normal direction."));
+
for (unsigned int k=0; k<fe.dofs_per_face; ++k)
if ((k != i)
&&
if (std::fabs(normal_vector[d]) < 1e-13)
normal_vector[d] = 0;
normal_vector /= normal_vector.norm();
-
+
// now enter the (dofs,(normal_vector,cell)) entry into
// the map
dof_to_normals_map
.insert (std::make_pair (vector_dofs,
std::make_pair (normal_vector,
cell)));
+#ifdef DEBUG_NO_NORMAL_FLUX
+ std::cout << "Adding normal vector:" << std::endl
+ << " dofs=" << vector_dofs << std::endl
+ << " cell=" << cell << " at " << cell->center() << std::endl
+ << " normal=" << normal_vector << std::endl;
+#endif
}
}
if (p == dof_to_normals_map.end())
same_dof_range[1] = dof_to_normals_map.end();
+#ifdef DEBUG_NO_NORMAL_FLUX
+ std::cout << "For dof indices <" << p->first << ">, found the following normals"
+ << std::endl;
+ for (typename DoFToNormalsMap::const_iterator
+ q = same_dof_range[0];
+ q != same_dof_range[1]; ++q)
+ std::cout << " " << q->second.first
+ << " from cell " << q->second.second
+ << std::endl;
+#endif
+
+
// now compute the reverse mapping: for each of the cells that
// contributed to the current set of vector dofs, add up the normal
// vectors. the values of the map are pairs of normal vectors and
= std::make_pair ((old_normal * old_count + q->second.first) / (old_count + 1),
old_count + 1);
}
-
Assert (cell_to_normals_map.size() >= 1, ExcInternalError());
+#ifdef DEBUG_NO_NORMAL_FLUX
+ std::cout << " cell_to_normals_map:" << std::endl;
+ for (typename CellToNormalsMap::const_iterator
+ x = cell_to_normals_map.begin();
+ x != cell_to_normals_map.end(); ++x)
+ std::cout << " " << x->first << " -> ("
+ << x->second.first << ',' << x->second.second << ')'
+ << std::endl;
+#endif
+
// count the maximum number of contributions from each cell
unsigned int max_n_contributions_per_cell = 1;
for (typename CellToNormalsMap::const_iterator
// encountered this vector dof exactly once while looping over all
// their faces. as stated in the documentation, this is the case
// where we want to simply average over all normal vectors
+ //
+ // the typical case is in 2d where multiple cells meet at one
+ // vertex sitting on the boundary. same in 3d for a vertex that
+ // is associated with only one of the boundary indicators passed
+ // to this function
case 1:
{
// normal vectors it has contributed. we currently only implement
// if this is dim-1 for all cells (if a single cell has
// contributed dim, or if all adjacent cells have contributed 1
- // normal vector, this is already handled above)
+ // normal vector, this is already handled above).
+ //
+ // we only implement the case that all cells contribute
+ // dim-1 because we assume that we are following an edge
+ // of the domain (think: we are looking at a vertex
+ // located on one of the edges of a refined cube where the
+ // boundary indicators of the two adjacent faces of the
+ // cube are both listed in the set of boundary indicators
+ // passed to this function). in that case, all cells along
+ // that edge of the domain are assumed to have contributed
+ // dim-1 normal vectors. however, there are cases where
+ // this assumption is not justified (see the lengthy
+ // explanation in test no_flux_12.cc) and in those cases
+ // we simply ignore the cell that contributes only
+ // once. this is also discussed at length in the
+ // documentation of this function.
//
// for each contributing cell compute the tangential vector that
// remains unconstrained
contribution != cell_contributions.end();
++contribution)
{
- Assert (contribution->second.size() == dim-1, ExcNotImplemented());
+#ifdef DEBUG_NO_NORMAL_FLUX
+ std::cout << " Treating edge case with dim-1 contributions." << std::endl
+ << " Looking at cell " << contribution->first
+ << " which has contributed these normal vectors:"
+ << std::endl;
+ for (typename std::list<Tensor<1,dim> >::const_iterator
+ t = contribution->second.begin();
+ t != contribution->second.end();
+ ++t)
+ std::cout << " " << *t << std::endl;
+#endif
+
+ // as mentioned above, simply ignore cells that only
+ // contribute once
+ if (contribution->second.size() < dim-1)
+ continue;
Tensor<1,dim> normals[dim-1];
{
// can find constrained ones
unsigned int n_total_constraints_found = 0;
for (typename std::set<std_cxx1x::array<types::global_dof_index,dim>,
- PointComparator<dim> >::const_iterator it=vector_dofs.begin();
+ PointComparator<dim> >::const_iterator it=vector_dofs.begin();
it!=vector_dofs.end(); ++it)
{
unsigned int n_constraints = 0;
PolicyBase<dim,spacedim>::~PolicyBase ()
{}
-
/* --------------------- class Sequential ---------------- */
+
+ template <int dim, int spacedim>
+ std::string
+ Sequential<dim,spacedim>::to_string () const
+ {
+ return "Policy::Sequential<"+Utilities::int_to_string(dim)+
+ ","+Utilities::int_to_string(spacedim)+">";
+ }
+
template <int dim, int spacedim>
#endif // DEAL_II_WITH_P4EST
+ template <int dim, int spacedim>
+ std::string
+ ParallelDistributed<dim,spacedim>::to_string () const
+ {
+ return "Policy::ParallelDistributed<"+Utilities::int_to_string(dim)+
+ ","+Utilities::int_to_string(spacedim)+">";
+ }
template <int dim, int spacedim>
for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
{
-#if deal_II_dimension <= deal_II_space_dimension
+#if deal_II_dimension <= deal_II_space_dimension
namespace DoFRenumbering
\{
namespace boost
void subdomain_wise<DoFHandler<deal_II_dimension,deal_II_space_dimension> >
(DoFHandler<deal_II_dimension,deal_II_space_dimension> &);
+ template
+ void
+ compute_subdomain_wise (std::vector<types::global_dof_index> &new_dof_indices,
+ const DoFHandler<deal_II_dimension,deal_II_space_dimension> &dof_handler);
+
\} // namespace DoFRenumbering
#endif
}
// where applicable and move to codimension cases above also when applicable
for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
{
-#if deal_II_dimension == deal_II_space_dimension
+#if deal_II_dimension == deal_II_space_dimension
namespace DoFRenumbering
\{
namespace boost
compute_minimum_degree (std::vector<dealii::types::global_dof_index> &,
const hp::DoFHandler<deal_II_dimension> &, bool, bool);
\}
-
-
+
+
// non-boost functions:
-
+
template
void Cuthill_McKee<hp::DoFHandler<deal_II_dimension> >
(hp::DoFHandler<deal_II_dimension>&,
template
void downstream
- (DoFHandler<deal_II_dimension>&,
+ (DoFHandler<deal_II_dimension>&,
const unsigned int,
const Point<deal_II_dimension>&,
const bool);
const hp::DoFHandler<deal_II_dimension> &,
const std::vector<bool> &);
-
+
template
void subdomain_wise<hp::DoFHandler<deal_II_dimension> >
(hp::DoFHandler<deal_II_dimension> &);
\} // namespace DoFRenumbering
#endif
}
-
-
-
-
// if u1 is a parallel distributed
// PETSc vector, we check the local
// size of u1 for safety
- Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
- ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
+ Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.n_locally_owned_dofs(),
+ ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.n_locally_owned_dofs()));
};
if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u2) != 0)
if (dynamic_cast<const DoFHandler<dim>*>(&dof2) != 0)
{
- Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u2)->local_size() == dof2.locally_owned_dofs().n_elements(),
- ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u2)->local_size(), dof2.locally_owned_dofs().n_elements()));
+ Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u2)->local_size() == dof2.n_locally_owned_dofs(),
+ ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u2)->local_size(), dof2.n_locally_owned_dofs()));
};
#endif
// allocate vectors at maximal
// if u1 is a parallel distributed
// PETSc vector, we check the local
// size of u1 for safety
- Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
- ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
+ Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.n_locally_owned_dofs(),
+ ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.n_locally_owned_dofs()));
};
if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated) != 0)
if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
{
- Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size() == dof1.locally_owned_dofs().n_elements(),
- ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size(), dof1.locally_owned_dofs().n_elements()));
+ Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size() == dof1.n_locally_owned_dofs(),
+ ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size(), dof1.n_locally_owned_dofs()));
};
#endif
// if u1 is a parallel distributed
// PETSc vector, we check the local
// size of u1 for safety
- Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
- ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
+ Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.n_locally_owned_dofs(),
+ ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.n_locally_owned_dofs()));
};
if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated) != 0)
if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
{
- Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size() == dof1.locally_owned_dofs().n_elements(),
- ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size(), dof1.locally_owned_dofs().n_elements()));
+ Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size() == dof1.n_locally_owned_dofs(),
+ ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_interpolated)->local_size(), dof1.n_locally_owned_dofs()));
};
#endif
DoFTools::extract_locally_relevant_dofs (dof2,
dof2_locally_relevant_dofs);
- PETScWrappers::MPI::Vector u2_out (u1.get_mpi_communicator(),
- dof2_locally_owned_dofs);
+ PETScWrappers::MPI::Vector u2_out (dof2_locally_owned_dofs,
+ u1.get_mpi_communicator());
interpolate(dof1, u1, dof2, constraints2, u2_out);
- PETScWrappers::MPI::Vector u2 (u1.get_mpi_communicator(),
- dof2_locally_owned_dofs,
- dof2_locally_relevant_dofs);
+ PETScWrappers::MPI::Vector u2 (dof2_locally_owned_dofs,
+ dof2_locally_relevant_dofs,
+ u1.get_mpi_communicator());
+ u2 = u2_out;
+ interpolate(dof2, u2, dof1, constraints1, u1_interpolated);
+ }
+#endif
+
+ // special version for Trilinos
+#ifdef DEAL_II_USE_TRILINOS
+ template <int dim, int spacedim>
+ void back_interpolate (const DoFHandler<dim,spacedim> &dof1,
+ const ConstraintMatrix &constraints1,
+ const TrilinosWrappers::MPI::Vector &u1,
+ const DoFHandler<dim,spacedim> &dof2,
+ const ConstraintMatrix &constraints2,
+ TrilinosWrappers::MPI::Vector &u1_interpolated)
+ {
+ // if u1 is a parallel distributed Trilinos vector, we create a
+ // vector u2 with based on the sets of locally owned and relevant
+ // dofs of dof2
+ IndexSet dof2_locally_owned_dofs = dof2.locally_owned_dofs();
+ IndexSet dof2_locally_relevant_dofs;
+ DoFTools::extract_locally_relevant_dofs (dof2,
+ dof2_locally_relevant_dofs);
+
+ TrilinosWrappers::MPI::Vector u2_out (dof2_locally_owned_dofs,
+ u1.get_mpi_communicator());
+ interpolate(dof1, u1, dof2, constraints2, u2_out);
+ TrilinosWrappers::MPI::Vector u2 (dof2_locally_owned_dofs,
+ dof2_locally_relevant_dofs,
+ u1.get_mpi_communicator());
u2 = u2_out;
interpolate(dof2, u2, dof1, constraints1, u1_interpolated);
}
// if u1 is a parallel distributed
// PETSc vector, we check the local
// size of u1 for safety
- Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.locally_owned_dofs().n_elements(),
- ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.locally_owned_dofs().n_elements()));
+ Assert(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size() == dof1.n_locally_owned_dofs(),
+ ExcDimensionMismatch(dynamic_cast<const PETScWrappers::MPI::Vector *>(&u1)->local_size(), dof1.n_locally_owned_dofs()));
};
if (dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference) != 0)
if (dynamic_cast<const DoFHandler<dim>*>(&dof1) != 0)
{
- Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference)->local_size() == dof1.locally_owned_dofs().n_elements(),
- ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference)->local_size(), dof1.locally_owned_dofs().n_elements()));
+ Assert(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference)->local_size() == dof1.n_locally_owned_dofs(),
+ ExcDimensionMismatch(dynamic_cast<PETScWrappers::MPI::Vector *>(&u1_difference)->local_size(), dof1.n_locally_owned_dofs()));
};
#endif
+ namespace internal
+ {
+ namespace
+ {
+ template <int dim, class InVector, class OutVector, int spacedim>
+ void interpolation_difference (const DoFHandler<dim,spacedim> &dof1,
+ const ConstraintMatrix &constraints1,
+ const InVector &u1,
+ const DoFHandler<dim,spacedim> &dof2,
+ const ConstraintMatrix &constraints2,
+ OutVector &u1_difference)
+ {
+ back_interpolate(dof1, constraints1, u1, dof2, constraints2, u1_difference);
+ u1_difference.sadd(-1, u1);
+ }
+
+ // special version for Trilinos
+#ifdef DEAL_II_USE_TRILINOS
+ template <int dim, int spacedim>
+ void interpolation_difference (const DoFHandler<dim,spacedim> &dof1,
+ const ConstraintMatrix &constraints1,
+ const TrilinosWrappers::MPI::Vector &u1,
+ const DoFHandler<dim,spacedim> &dof2,
+ const ConstraintMatrix &constraints2,
+ TrilinosWrappers::MPI::Vector &u1_difference)
+ {
+ back_interpolate(dof1, constraints1, u1, dof2, constraints2, u1_difference);
+
+ // Trilinos vectors with and without ghost entries are very different
+ // and we cannot use the sadd function directly, so we have to create
+ // a completely distributed vector first and copy the local entries
+ // from the vector with ghost entries
+ TrilinosWrappers::MPI::Vector u1_completely_distributed (u1_difference.vector_partitioner ());
+
+ u1_completely_distributed = u1;
+
+ u1_difference.sadd(-1, u1_completely_distributed);
+ }
+#endif
+ }
+ }
+
+
+
template <int dim, class InVector, class OutVector, int spacedim>
void interpolation_difference(const DoFHandler<dim,spacedim> &dof1,
const ConstraintMatrix &constraints1,
interpolation_difference(dof1, u1, dof2.get_fe(), u1_difference);
else
{
- back_interpolate(dof1, constraints1, u1, dof2, constraints2, u1_difference);
- u1_difference.sadd(-1, u1);
+ internal::interpolation_difference(dof1, constraints1, u1, dof2, constraints2, u1_difference);
}
}
// Newton iteration to solve
- // f(x)=p(x)-p=0
- // x_{n+1}=x_n-[f'(x)]^{-1}f(x)
+ // f(x)=p(x)-p=0
+ // where we are looking for 'x' and p(x) is the forward transformation
+ // from unit to real cell. We solve this using a Newton iteration
+ // x_{n+1}=x_n-[f'(x)]^{-1}f(x)
+ // The start value is set to be the linear approximation to the cell
- // The start value was set to be the
- // linear approximation to the cell
-
- // The shape values and derivatives
- // of the mapping at this point are
+ // The shape values and derivatives of the mapping at this point are
// previously computed.
- // For the <2,3> case there is a
- // template specialization.
-
- // f(x)
-
Point<dim> p_unit = initial_p_unit;
compute_shapes(std::vector<Point<dim> > (1, p_unit), mdata);
- Point<spacedim> p_real(transform_unit_to_real_cell_internal(mdata));
+ Point<spacedim> p_real = transform_unit_to_real_cell_internal(mdata);
Point<spacedim> f = p_real-p;
- const double eps = 1.e-12*cell->diameter();
+ // early out if we already have our point
+ if (f.square() < 1e-24 * cell->diameter() * cell->diameter())
+ return p_unit;
+
+ // we need to compare the position of the computed p(x) against the given
+ // point 'p'. We will terminate the iteration and return 'x' if they are
+ // less than eps apart. The question is how to choose eps -- or, put maybe
+ // more generally: in which norm we want these 'p' and 'p(x)' to be eps
+ // apart.
+ //
+ // the question is difficult since we may have to deal with very elongated
+ // cells where we may achieve 1e-12*h for the distance of these two points
+ // in the 'long' direction, but achieving this tolerance in the 'short'
+ // direction of the cell may not be possible
+ //
+ // what we do instead is then to terminate iterations if
+ // \| p(x) - p \|_A < eps
+ // where the A-norm is somehow induced by the transformation of the cell.
+ // in particular, we want to measure distances relative to the sizes of
+ // the cell in its principal directions.
+ //
+ // to define what exactly A should be, note that to first order we have
+ // the following (assuming that x* is the solution of the problem, i.e.,
+ // p(x*)=p):
+ // p(x) - p = p(x) - p(x*)
+ // = -grad p(x) * (x*-x) + higher order terms
+ // This suggest to measure with a norm that corresponds to
+ // A = {[grad p(x]^T [grad p(x)]}^{-1}
+ // because then
+ // \| p(x) - p \|_A \approx \| x - x* \|
+ // Consequently, we will try to enforce that
+ // \| p(x) - p \|_A = \| f \| <= eps
+ //
+ // Note that using this norm is a bit dangerous since the norm changes
+ // in every iteration (A isn't fixed by depends on xk). However, if the
+ // cell is not too deformed (it may be stretched, but not twisted) then
+ // the mapping is almost linear and A is indeed constant or nearly so.
+ const double eps = 1.e-11;
const unsigned int newton_iteration_limit = 20;
unsigned int newton_iteration=0;
- while (f.square()>eps*eps)
+ double last_f_weighted_norm = -1./0.;
+ do
{
+#ifdef DEBUG_TRANSFORM_REAL_TO_UNIT_CELL
+ std::cout << "Newton iteration " << newton_iteration << std::endl;
+#endif
+
// f'(x)
Tensor<2,spacedim> df;
for (unsigned int k=0; k<mdata.n_shape_functions; ++k)
// Solve [f'(x)]d=f(x)
Tensor<1,spacedim> delta;
- contract (delta, invert(df), static_cast<const Tensor<1,spacedim>&>(f));
+ Tensor<2,spacedim> df_inverse = invert(df);
+ contract (delta, df_inverse, static_cast<const Tensor<1,spacedim>&>(f));
+#ifdef DEBUG_TRANSFORM_REAL_TO_UNIT_CELL
+ std::cout << " delta=" << delta << std::endl;
+#endif
+
// do a line search
double step_length = 1;
do
{
- // update of p_unit. The
- // spacedimth component of
- // transformed point is simply
- // ignored in codimension one
- // case. When this component is
- // not zero, then we are
- // projecting the point to the
- // surface or curve identified
- // by the cell.
+ // update of p_unit. The spacedim-th component of transformed point
+ // is simply ignored in codimension one case. When this component is
+ // not zero, then we are projecting the point to the surface or
+ // curve identified by the cell.
Point<dim> p_unit_trial = p_unit;
for (unsigned int i=0; i<dim; ++i)
p_unit_trial[i] -= step_length * delta[i];
Point<spacedim> p_real_trial = transform_unit_to_real_cell_internal(mdata);
const Point<spacedim> f_trial = p_real_trial-p;
+#ifdef DEBUG_TRANSFORM_REAL_TO_UNIT_CELL
+ std::cout << " step_length=" << step_length << std::endl
+ << " ||f || =" << f.norm() << std::endl
+ << " ||f*|| =" << f_trial.norm() << std::endl
+ << " ||f*||_A =" << (df_inverse * f_trial).norm() << std::endl;
+#endif
+
// see if we are making progress with the current step length
// and if not, reduce it by a factor of two and try again
+ //
+ // strictly speaking, we should probably use the same norm as we use
+ // for the outer algorithm. in practice, line search is just a
+ // crutch to find a "reasonable" step length, and so using the l2
+ // norm is probably just fine
if (f_trial.norm() < f.norm())
{
p_real = p_real_trial;
else if (step_length > 0.05)
step_length /= 2;
else
- goto failure;
+ AssertThrow (false,
+ (typename Mapping<dim,spacedim>::ExcTransformationFailed()));
}
while (true);
++newton_iteration;
if (newton_iteration > newton_iteration_limit)
- goto failure;
+ AssertThrow (false,
+ (typename Mapping<dim,spacedim>::ExcTransformationFailed()));
+ last_f_weighted_norm = (df_inverse * f).norm();
}
-
+ while (last_f_weighted_norm > eps);
+
return p_unit;
-
- // if we get to the following label, then we have either run out
- // of Newton iterations, or the line search has not converged.
- // in either case, we need to give up, so throw an exception that
- // can then be caught
-failure:
- AssertThrow (false, (typename Mapping<dim,spacedim>::ExcTransformationFailed()));
-
- // ...the compiler wants us to return something, though we can
- // of course never get here...
- return Point<dim>();
}
}
+
+ template<>
+ void
+ parallelogram (Triangulation<3> &tria,
+ const Point<3> corners[3],
+ const bool colorize)
+ {
+ Assert (false, ExcNotImplemented());
+ }
+
+ template<>
+ void
+ parallelogram (Triangulation<1> &tria,
+ const Point<1> corners[1],
+ const bool colorize)
+ {
+ Assert (false, ExcNotImplemented());
+ }
+
// Implementation for 2D only
template<>
void
parallelogram (Triangulation<2> &tria,
- const Point<2> (&corners)[2],
+ const Point<2> corners[2],
const bool colorize)
{
std::vector<Point<2> > vertices (GeometryInfo<2>::vertices_per_cell);
}
+ template<>
+ void
+ parallelogram (Triangulation<1> &tria,
+ const Tensor<2,1> &corners,
+ const bool colorize)
+ {
+ Assert (false, ExcNotImplemented());
+ }
+
+ template<>
+ void
+ parallelogram (Triangulation<3> &tria,
+ const Tensor<2,3> &corners,
+ const bool colorize)
+ {
+ Assert (false, ExcNotImplemented());
+ }
+
+
template<>
void
parallelogram (Triangulation<2> &tria,
Triangulation<deal_II_dimension> &,
const unsigned int, const double, const double);
+ template
+ void
+ parallelogram (Triangulation<deal_II_dimension> &,
+ const Tensor<2,deal_II_dimension> &,
+ const bool );
+ template
+ void
+ parallelogram (Triangulation<deal_II_dimension> &,
+ const Point<deal_II_dimension> [deal_II_dimension],
+ const bool);
+
template void
subdivided_hyper_rectangle<deal_II_dimension>
(Triangulation<deal_II_dimension> &,
label_cell_index(label_cell_index),
label_material_id(label_material_id),
label_subdomain_id(label_subdomain_id),
+ label_level_subdomain_id(false),
draw_colorbar(draw_colorbar),
draw_legend(draw_legend)
{}
const size_type ,
const bool);
template
+void ChunkSparsityPattern::copy_from<CompressedSparsityPattern> (const CompressedSparsityPattern &,
+ const size_type);
+template
+void ChunkSparsityPattern::copy_from<CompressedSetSparsityPattern> (const CompressedSetSparsityPattern &,
+ const size_type);
+template
+void ChunkSparsityPattern::copy_from<CompressedSimpleSparsityPattern> (const CompressedSimpleSparsityPattern &,
+ const size_type);
+template
void ChunkSparsityPattern::create_from<SparsityPattern>
(const unsigned int,
const unsigned int,
template
void interpolate
- (const Mapping<deal_II_dimension,deal_II_space_dimension>&,
+ (const Mapping<DoFHandler<deal_II_dimension,deal_II_space_dimension>::dimension,DoFHandler<deal_II_dimension,deal_II_space_dimension>::space_dimension>&,
const DoFHandler<deal_II_dimension,deal_II_space_dimension>&,
const Function<deal_II_space_dimension>&,
VEC&);
\}
}
-
-
# of complexity :-(
#
+MESSAGE(STATUS "")
+MESSAGE(STATUS "Setup testsuite with TEST_DIR ${TEST_DIR}")
ADD_SUBDIRECTORY(quick_tests)
#
LIST(APPEND _options -DDEAL_II_SOURCE_DIR=${CMAKE_SOURCE_DIR})
LIST(APPEND _options -DDEAL_II_BINARY_DIR=${CMAKE_BINARY_DIR})
FOREACH(_var
+ DIFF_DIR
NUMDIFF_DIR
TEST_DIFF
TEST_OVERRIDE_LOCATION
ENDIF()
ENDFOREACH()
+# Be as quiet as possible:
+IF(CMAKE_SYSTEM_NAME MATCHES "Windows")
+ SET(_shoo)
+ELSE()
+ SET(_shoo >/dev/null)
+ENDIF()
+
#
# Glob together a list of all subfolders to set up:
#
${CMAKE_CURRENT_BINARY_DIR}/${_category}
COMMAND cd ${CMAKE_CURRENT_BINARY_DIR}/${_category} &&
${CMAKE_COMMAND} -G${CMAKE_GENERATOR} ${_options} ${_category_dir}
- > /dev/null # Shoo!
+ ${_shoo}
DEPENDS ${_category_dir}
COMMENT "Processing tests/${_category}"
)
ADD_CUSTOM_TARGET(regen_tests_${_category}
COMMAND [ ! -d ${_category} ] || ${CMAKE_COMMAND}
--build ${CMAKE_CURRENT_BINARY_DIR}/${_category} --target regenerate
- > /dev/null # Shoo!
+ ${_shoo}
)
ADD_DEPENDENCIES(regen_tests regen_tests_${_category})
ADD_CUSTOM_TARGET(clean_tests_${_category}
COMMAND [ ! -d ${_category} ] || ${CMAKE_COMMAND}
--build ${CMAKE_CURRENT_BINARY_DIR}/${_category} --target clean
- > /dev/null # Shoo!
+ ${_shoo}
)
ADD_DEPENDENCIES(clean_tests clean_tests_${_category})
ENDFOREACH()
MESSAGE(STATUS "Regenerating testsuite subprojects - Done")
+MESSAGE(STATUS "")
# Use the first available build type (this prefers debug mode if available):
LIST(GET DEAL_II_BUILD_TYPES 0 _mybuild)
-MESSAGE(STATUS "")
MESSAGE(STATUS "Setup quick_tests in ${_mybuild} mode")
# define a macro to set up a quick test:
)
ENDIF()
- ADD_CUSTOM_TARGET(${_target}.run
- DEPENDS ${_target}
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_target}-OK
- COMMAND echo "${_target}: PASSED.")
+ ADD_CUSTOM_TARGET(${_target}.run
+ DEPENDS ${_target}
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_target}-OK
+ COMMAND echo "${_target}: PASSED.")
ADD_TEST(NAME ${_target}
COMMAND ${CMAKE_COMMAND} -DTRGT=${_target}.run -DTEST=${_target}
/* ---------------------------------------------------------------------\r
- * $Id: step-petsc.cc $\r
+ * $Id$\r
*\r
* Copyright (C) 2013 by the deal.II authors\r
*\r
// ---------------------------------------------------------------------
-// $Id: affinity.cc 31527 2013-11-03 09:58:45Z maier $
+// $Id$
//
// Copyright (C) 2013 by the deal.II authors
//