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
37namespace dolfin
38{
39
48
49 template <typename T>
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
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>
296 MeshValueCollection<T>::MeshValueCollection(std::shared_ptr<const Mesh> mesh,
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>
381 void MeshValueCollection<T>::init(std::size_t dim)
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>
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
A Cell is a MeshEntity of topological codimension 0.
Definition: Cell.h:43
Definition: File.h:46
Definition: MeshConnectivity.h:42
std::size_t size() const
Return total number of connections.
Definition: MeshConnectivity.h:62
bool empty() const
Return true if the total number of connections is equal to zero.
Definition: MeshConnectivity.h:58
Definition: MeshEntity.h:43
std::size_t index() const
Definition: MeshEntity.h:113
std::size_t num_entities(std::size_t dim) const
Definition: MeshEntity.h:140
Definition: MeshFunction.h:58
std::shared_ptr< const Mesh > mesh() const
Definition: MeshFunction.h:491
std::size_t dim() const
Definition: MeshFunction.h:498
std::size_t size() const
Definition: MeshFunction.h:510
Definition: MeshValueCollection.h:51
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
std::size_t dim() const
Definition: MeshValueCollection.h:389
bool empty() const
Definition: MeshValueCollection.h:396
T get_value(std::size_t cell_index, std::size_t local_entity)
Definition: MeshValueCollection.h:498
~MeshValueCollection()
Destructor.
Definition: MeshValueCollection.h:89
bool set_value(std::size_t cell_index, std::size_t local_entity, const T &value)
Definition: MeshValueCollection.h:415
void clear()
Clear all values.
Definition: MeshValueCollection.h:534
MeshValueCollection()
Definition: MeshValueCollection.h:227
std::size_t size() const
Definition: MeshValueCollection.h:402
MeshValueCollection< T > & operator=(const MeshFunction< T > &mesh_function)
Definition: MeshValueCollection.h:308
std::map< std::pair< std::size_t, std::size_t >, T > & values()
Definition: MeshValueCollection.h:521
std::string str(bool verbose) const
Definition: MeshValueCollection.h:540
Common base class for DOLFIN variables.
Definition: Variable.h:36
Definition: adapt.h:30
void warning(std::string msg,...)
Print warning.
Definition: log.cpp:115
void dolfin_error(std::string location, std::string task, std::string reason,...)
Definition: log.cpp:129