DOLFIN
DOLFIN C++ interface
MeshValueCollection.h
1 // Copyright (C) 2011-2013 Anders Logg and Garth N. Wells
2 //
3 // This file is part of DOLFIN.
4 //
5 // DOLFIN is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // DOLFIN is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // Modified by Chris Richardson, 2013.
19 //
20 // First added: 2006-08-30
21 // Last changed: 2013-05-22
22 
23 #ifndef __MESH_VALUE_COLLECTION_H
24 #define __MESH_VALUE_COLLECTION_H
25 
26 #include <map>
27 #include <utility>
28 #include <memory>
29 #include <dolfin/common/NoDeleter.h>
30 #include <dolfin/common/Variable.h>
31 #include <dolfin/log/log.h>
32 #include "Cell.h"
33 #include "Mesh.h"
34 #include "MeshEntity.h"
35 #include "MeshFunction.h"
36 
37 namespace dolfin
38 {
39 
48 
49  template <typename T>
50  class MeshValueCollection : public Variable
51  {
52  public:
53 
57 
62  explicit MeshValueCollection(std::shared_ptr<const Mesh> mesh);
63 
68  explicit MeshValueCollection(const MeshFunction<T>& mesh_function);
69 
77  MeshValueCollection(std::shared_ptr<const Mesh> mesh, std::size_t dim);
78 
86  MeshValueCollection(std::shared_ptr<const Mesh> mesh, const std::string filename);
87 
90 
96  MeshValueCollection<T>& operator=(const MeshFunction<T>& mesh_function);
97 
104  operator=(const MeshValueCollection<T>& mesh_value_collection);
105 
112  void init(std::shared_ptr<const Mesh> mesh, std::size_t dim);
113 
120  void init(std::size_t dim);
121 
126  std::size_t dim() const;
127 
132  std::shared_ptr<const Mesh> mesh() const;
133 
138  bool empty() const;
139 
144  std::size_t size() const;
145 
159  bool set_value(std::size_t cell_index, std::size_t local_entity,
160  const T& value);
161 
172  bool set_value(std::size_t entity_index, const T& value);
173 
184  T get_value(std::size_t cell_index, std::size_t local_entity);
185 
190  std::map<std::pair<std::size_t, std::size_t>, T>& values();
191 
196  const std::map<std::pair<std::size_t, std::size_t>, T>& values() const;
197 
199  void clear();
200 
208  std::string str(bool verbose) const;
209 
210  private:
211 
212  // Associated mesh
213  std::shared_ptr<const Mesh> _mesh;
214 
215  // Topological dimension
216  int _dim;
217 
218  // The values
219  std::map<std::pair<std::size_t, std::size_t>, T> _values;
220 
221  };
222 
223  //---------------------------------------------------------------------------
224  // Implementation of MeshValueCollection
225  //---------------------------------------------------------------------------
226  template <typename T>
228  : Variable("m", "unnamed MeshValueCollection"), _dim(-1)
229  {
230  // Do nothing
231  }
232  //---------------------------------------------------------------------------
233  template <typename T>
235  mesh) : _mesh(mesh), _dim(-1)
236  {
237  // Do nothing
238  }
239  //---------------------------------------------------------------------------
240  template <typename T>
242  mesh, std::size_t dim)
243  : Variable("m", "unnamed MeshValueCollection"), _mesh(mesh), _dim(dim)
244  {
245  // Do nothing
246  }
247  //---------------------------------------------------------------------------
248  template <typename T>
250  mesh_function)
251  : Variable("m", "unnamed MeshValueCollection"), _mesh(mesh_function.mesh()),
252  _dim(mesh_function.dim())
253  {
254  dolfin_assert(_mesh);
255  const std::size_t D = _mesh->topology().dim();
256 
257  // Handle cells as a special case
258  if ((int) D == _dim)
259  {
260  for (std::size_t cell_index = 0; cell_index < mesh_function.size();
261  ++cell_index)
262  {
263  const std::pair<std::size_t, std::size_t> key(cell_index, 0);
264  _values.insert({key, mesh_function[cell_index]});
265  }
266  }
267  else
268  {
269  _mesh->init(_dim, D);
270  const MeshConnectivity& connectivity = _mesh->topology()(_dim, D);
271  dolfin_assert(!connectivity.empty());
272  for (std::size_t entity_index = 0; entity_index < mesh_function.size();
273  ++entity_index)
274  {
275  // Find the cell
276  dolfin_assert(connectivity.size(entity_index) > 0);
277  const MeshEntity entity(*_mesh, _dim, entity_index);
278  for (std::size_t i = 0; i < entity.num_entities(D) ; ++i)
279  {
280  // Create cell
281  const Cell cell(*_mesh, connectivity(entity_index)[i]);
282 
283  // Find the local entity index
284  const std::size_t local_entity = cell.index(entity);
285 
286  // Insert into map
287  const std::pair<std::size_t, std::size_t> key(cell.index(),
288  local_entity);
289  _values.insert({key, mesh_function[entity_index]});
290  }
291  }
292  }
293  }
294  //---------------------------------------------------------------------------
295  template <typename T>
297  const std::string filename)
298  : Variable("m", "unnamed MeshValueCollection"),
299  _mesh(mesh), _dim(-1)
300  {
301  File file(filename);
302  file >> *this;
303  dolfin_assert(_dim > -1);
304  }
305  //---------------------------------------------------------------------------
306  template <typename T>
309  {
310  _mesh = mesh_function.mesh();
311  _dim = mesh_function.dim();
312 
313  dolfin_assert(_mesh);
314  const std::size_t D = _mesh->topology().dim();
315 
316  // FIXME: Use iterators
317 
318  // Handle cells as a special case
319  if ((int) D == _dim)
320  {
321  for (std::size_t cell_index = 0; cell_index < mesh_function.size();
322  ++cell_index)
323  {
324  const std::pair<std::size_t, std::size_t> key(cell_index, 0);
325  _values.insert({key, mesh_function[cell_index]});
326  }
327  }
328  else
329  {
330  _mesh->init(_dim, D);
331  const MeshConnectivity& connectivity = _mesh->topology()(_dim, D);
332  dolfin_assert(!connectivity.empty());
333  for (std::size_t entity_index = 0; entity_index < mesh_function.size();
334  ++entity_index)
335  {
336  // Find the cell
337  dolfin_assert(connectivity.size(entity_index) > 0);
338  const MeshEntity entity(*_mesh, _dim, entity_index);
339  for (std::size_t i = 0; i < entity.num_entities(D) ; ++i)
340  {
341  // Create cell
342  const Cell cell(*_mesh, connectivity(entity_index)[i]);
343 
344  // Find the local entity index
345  const std::size_t local_entity = cell.index(entity);
346 
347  // Insert into map
348  const std::pair<std::size_t, std::size_t> key(cell.index(),
349  local_entity);
350  _values.insert({key, mesh_function[entity_index]});
351  }
352  }
353  }
354 
355  return *this;
356  }
357  //---------------------------------------------------------------------------
358  template <typename T>
361  mesh_value_collection)
362  {
363  _mesh = mesh_value_collection._mesh;
364  _dim = mesh_value_collection.dim();
365  _values = mesh_value_collection.values();
366 
367  return *this;
368  }
369  //---------------------------------------------------------------------------
370  template <typename T>
371  void MeshValueCollection<T>::init(std::shared_ptr<const Mesh> mesh,
372  std::size_t dim)
373  {
374  mesh->init(dim);
375  _mesh = mesh;
376  _dim = dim;
377  _values.clear();
378  }
379  //---------------------------------------------------------------------------
380  template <typename T>
382  {
383  dolfin_assert(_mesh);
384  dolfin_assert(_dim < 0);
385  _dim = dim;
386  }
387  //---------------------------------------------------------------------------
388  template <typename T>
389  std::size_t MeshValueCollection<T>::dim() const
390  {
391  dolfin_assert(_dim >= 0);
392  return _dim;
393  }
394  //---------------------------------------------------------------------------
395  template <typename T>
397  {
398  return _values.empty();
399  }
400  //---------------------------------------------------------------------------
401  template <typename T>
402  std::size_t MeshValueCollection<T>::size() const
403  {
404  return _values.size();
405  }
406  //---------------------------------------------------------------------------
407  template <typename T>
408  std::shared_ptr<const Mesh> MeshValueCollection<T>::mesh() const
409  {
410  dolfin_assert(_mesh);
411  return _mesh;
412  }
413  //---------------------------------------------------------------------------
414  template <typename T>
415  bool MeshValueCollection<T>::set_value(std::size_t cell_index,
416  std::size_t local_entity,
417  const T& value)
418  {
419  dolfin_assert(_dim >= 0);
420  if (!_mesh)
421  {
422  dolfin_error("MeshValueCollection.h",
423  "set value",
424  "A mesh has not been associated with this MeshValueCollection");
425  }
426 
427  const std::pair<std::size_t, std::size_t> pos(cell_index, local_entity);
428  std::pair<typename std::map<std::pair<std::size_t, std::size_t>, T>::iterator, bool>
429  it = _values.insert({pos, value});
430 
431  // If an item with same key already exists the value has not been
432  // set and we need to update it
433  if (!it.second)
434  it.first->second = value;
435 
436  return it.second;
437  }
438  //---------------------------------------------------------------------------
439  template <typename T>
440  bool MeshValueCollection<T>::set_value(std::size_t entity_index,
441  const T& value)
442  {
443  if (!_mesh)
444  {
445  dolfin_error("MeshValueCollection.h",
446  "set value",
447  "A mesh has not been associated with this MeshValueCollection");
448  }
449 
450  dolfin_assert(_dim >= 0);
451 
452  // Special case when d = D
453  const std::size_t D = _mesh->topology().dim();
454  if (_dim == (int) D)
455  {
456  // Set local entity index to zero when we mark a cell
457  const std::pair<std::size_t, std::size_t> pos(entity_index, 0);
458  std::pair<typename std::map<std::pair<std::size_t,
459  std::size_t>, T>::iterator, bool> it;
460  it = _values.insert({pos, value});
461 
462  // If an item with same key already exists the value has not been
463  // set and we need to update it
464  if (!it.second)
465  it.first->second = value;
466 
467  return it.second;
468  }
469 
470  // Get mesh connectivity d --> D
471  _mesh->init(_dim, D);
472  const MeshConnectivity& connectivity = _mesh->topology()(_dim, D);
473 
474  // Find the cell
475  dolfin_assert(!connectivity.empty());
476  dolfin_assert(connectivity.size(entity_index) > 0);
477  const MeshEntity entity(*_mesh, _dim, entity_index);
478  const Cell cell(*_mesh, connectivity(entity_index)[0]); // choose first
479 
480  // Find the local entity index
481  const std::size_t local_entity = cell.index(entity);
482 
483  // Add value
484  const std::pair<std::size_t, std::size_t> pos(cell.index(), local_entity);
485  std::pair<typename std::map<std::pair<std::size_t,
486  std::size_t>, T>::iterator, bool> it;
487  it = _values.insert({pos, value});
488 
489  // If an item with same key already exists the value has not been
490  // set and we need to update it
491  if (!it.second)
492  it.first->second = value;
493 
494  return it.second;
495  }
496  //---------------------------------------------------------------------------
497  template <typename T>
498  T MeshValueCollection<T>::get_value(std::size_t cell_index,
499  std::size_t local_entity)
500  {
501  dolfin_assert(_dim >= 0);
502 
503  const std::pair<std::size_t, std::size_t> pos(cell_index, local_entity);
504  const typename std::map<std::pair<std::size_t,
505  std::size_t>, T>::const_iterator
506  it = _values.find(pos);
507 
508  if (it == _values.end())
509  {
510  dolfin_error("MeshValueCollection.h",
511  "extract value",
512  "No value stored for cell index: %d and local index: %d",
513  cell_index, local_entity);
514  }
515 
516  return it->second;
517  }
518  //---------------------------------------------------------------------------
519  template <typename T>
520  std::map<std::pair<std::size_t, std::size_t>, T>&
522  {
523  return _values;
524  }
525  //---------------------------------------------------------------------------
526  template <typename T>
527  const std::map<std::pair<std::size_t, std::size_t>, T>&
529  {
530  return _values;
531  }
532  //---------------------------------------------------------------------------
533  template <typename T>
535  {
536  _values.clear();
537  }
538  //---------------------------------------------------------------------------
539  template <typename T>
540  std::string MeshValueCollection<T>::str(bool verbose) const
541  {
542  std::stringstream s;
543  if (verbose)
544  {
545  s << str(false) << std::endl << std::endl;
546  warning("Verbose output of MeshValueCollection must be implemented manually.");
547  }
548  else
549  {
550  s << "<MeshValueCollection of topological dimension " << dim()
551  << " containing " << size() << " values>";
552  }
553 
554  return s.str();
555  }
556  //---------------------------------------------------------------------------
557 
558 }
559 
560 #endif
std::map< std::pair< std::size_t, std::size_t >, T > & values()
Definition: MeshValueCollection.h:521
std::size_t dim() const
Definition: MeshFunction.h:498
Definition: adapt.h:41
Common base class for DOLFIN variables.
Definition: Variable.h:35
std::size_t size() const
Definition: MeshFunction.h:510
void warning(std::string msg,...)
Print warning.
Definition: log.cpp:115
void clear()
Clear all values.
Definition: MeshValueCollection.h:534
Definition: adapt.h:29
Definition: File.h:45
Definition: MeshConnectivity.h:39
std::size_t size() const
Return total number of connections.
Definition: MeshConnectivity.h:60
A Cell is a MeshEntity of topological codimension 0.
Definition: Cell.h:42
T get_value(std::size_t cell_index, std::size_t local_entity)
Definition: MeshValueCollection.h:498
std::string str(bool verbose) const
Definition: MeshValueCollection.h:540
bool set_value(std::size_t cell_index, std::size_t local_entity, const T &value)
Definition: MeshValueCollection.h:415
void init(std::shared_ptr< const Mesh > mesh, std::size_t dim)
Definition: MeshValueCollection.h:371
std::shared_ptr< const Mesh > mesh() const
Definition: MeshValueCollection.h:408
bool empty() const
Definition: MeshValueCollection.h:396
MeshValueCollection< T > & operator=(const MeshFunction< T > &mesh_function)
Definition: MeshValueCollection.h:308
Definition: GenericFile.h:38
MeshValueCollection()
Definition: MeshValueCollection.h:227
Definition: MeshEntity.h:42
std::shared_ptr< const Mesh > mesh() const
Definition: MeshFunction.h:491
void dolfin_error(std::string location, std::string task, std::string reason,...)
Definition: log.cpp:129
std::size_t dim() const
Definition: MeshValueCollection.h:389
~MeshValueCollection()
Destructor.
Definition: MeshValueCollection.h:89
std::size_t index() const
Definition: MeshEntity.h:113
bool empty() const
Return true if the total number of connections is equal to zero.
Definition: MeshConnectivity.h:56
std::size_t size() const
Definition: MeshValueCollection.h:402