* everything after the first
* non-name character will be
* chopped off.
+ *
+ * If the name of the element
+ * already exists, an exception
+ * is thrown. Thus, functionality
+ * of get_fe_from_name() can only
+ * be added, not changed.
+ *
+ * @note This function
+ * manipulates a global table
+ * (one table for each space
+ * dimension). It is thread safe
+ * in the sense that every access
+ * to this table is secured by a
+ * lock. Nevertheless, since each
+ * name can be added only once,
+ * user code has to make sure
+ * that only one thread adds a
+ * new element.
*/
template <int dim>
static void add_fe_name(const std::string& name,
#include <base/quadrature_lib.h>
#include <base/qprojector.h>
#include <base/logstream.h>
+#include <base/thread_management.h>
#include <base/utilities.h>
#include <lac/full_matrix.h>
#include <lac/householder.h>
DEAL_II_NAMESPACE_OPEN
+namespace
+{
+// have a lock that guarantees that at most one thread is changing and
+// accessing the @p{coefficients} arrays of classes implementing
+// polynomials with tables. make this lock local to this file.
+//
+// having only one lock for all of these classes is probably not going
+// to be a problem since we only need it on very rare occasions. if
+// someone finds this is a bottleneck, feel free to replace it by a
+// more fine-grained solution
+ Threads::ThreadMutex fe_name_map_lock;
+
// This is the map used by FETools::get_fe_from_name and
// FETools::add_fe_name. Since FEFactoryBase has a template parameter
// dim, it could not be a member variable of FETools. On the other
// hand, it is only accessed by functions in this file, so it is safe
// to make it a static variable here. It must be static so that we can
// link several dimensions together.
-static std::map<const std::string,
- boost::shared_ptr<const FETools::FEFactoryBase<deal_II_dimension> > >
-fe_name_map;
+ std::map<const std::string,
+ boost::shared_ptr<const FETools::FEFactoryBase<deal_II_dimension> > >
+ fe_name_map;
+}
+
+
+
name.find_first_not_of(std::string("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"));
if (name_end < name.size())
name.erase(name_end);
+ // first make sure that no other
+ // thread intercepts the
+ // operation of this function;
+ // for this, acquire the lock
+ // until we quit this function
+ Threads::ThreadMutex::ScopedLock lock(fe_name_map_lock);
+
+ Assert(fe_name_map.find(name) != fe_name_map.end(),
+ ExcMessage("Cannot change existing element in finite element name list"));
+
// Insert the normalized name into
// the map
fe_name_map.insert(std::make_pair(name, factory));
}
else
{
+ // Make sure no other thread
+ // is just adding an element
+ Threads::ThreadMutex::ScopedLock lock (fe_name_map_lock);
+
typename std::map<const std::string,
boost::shared_ptr<const FETools::FEFactoryBase<dim> > >::const_iterator
entry = fe_name_map.find(name_part);
<h3>deal.II</h3>
<ol>
+
+ <li> <p> Improved: The lookup mechanism in <code
+ class="class">FETools</code>::<code
+ class="member">get_fe_from_name</code> has been changed, so
+ additional custom finite elements can be added using <code
+ class="class">FETools</code>::<code
+ class="member">add_fe_name</code>. In the course of this
+ change, the implementation of the lookup mechanism has been
+ simplified.
+ <br>
+ (GK 2006/10/24)
+ </p>
+
<li> <p>
New: There is a new functions <code
- class="member">GridTools::create_union_triangulation</code>
+ class="class">GridTools</code>::<code
+ class="member">create_union_triangulation</code>
that generates a triangulation that contains the respectively
finest cells of two input triangulations.
<br>