PeriodicMap.h 6.07 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ==  http://www.amdis-fem.org                                              ==
// ==                                                                        ==
// ============================================================================
//
// Software License for AMDiS
//
// Copyright (c) 2010 Dresden University of Technology 
// All rights reserved.
// Authors: Simon Vey, Thomas Witkowski et al.
//
// This file is part of AMDiS
//
// See also license.opensource.txt in the distribution.



/** file PeriodicMap.h */

#ifndef AMDIS_PERIODIC_MAP
#define AMDIS_PERIODIC_MAP

#include <map>
#include <set>
#include <vector>
#include "parallel/ParallelTypes.h"
#include "Boundary.h"
#include "Serializer.h"

namespace AMDiS {

  /// Maps a boundary type, i.e., a boundary identifier index, to a periodic 
  /// DOF mapping. 
  typedef std::map<BoundaryType, DofMapping> PeriodicDofMap;
  
  /// Different FE spaces may have different DOFs on the same mesh. Thus we
  /// need to have a periodic DOF mapping for each FE space.
  typedef std::map<const FiniteElemSpace*, PeriodicDofMap> PeriodicDofMapFeSpace;
  

  /** \brief
   * This class stores information about the periodic DOFs in the (sub)domain.
   * To each DOF on a periodic boundary there is the information to which DOF
   * is is periodic. Here we use global DOF indices. Furtheremore, a DOF can have
   * different periodic mapping. Assume we have a 2D box with all four edges 
   * being periodic. Than, the four corner vertices have all two periodic 
   * mapping. So, a periodic mapping is identified by the global DOF index to be
   * mapped and the boundary index. 
   */ 
  class PeriodicMap {
  public:
    PeriodicMap() {}

    void clear()
    {
      periodicDofMap.clear();
      periodicDofAssociations.clear();
    }


    inline PeriodicDofMap& getPeriodicMap(const FiniteElemSpace *feSpace)
    {
      return periodicDofMap[feSpace];
    }


    inline int map(const FiniteElemSpace *feSpace,
		   BoundaryType type,
		   int globalDofIndex) 
    {
      FUNCNAME("PeriodicMap::map()");

      TEST_EXIT_DBG(periodicDofMap.count(feSpace))("Should not happen!\n");
      TEST_EXIT_DBG(periodicDofMap[feSpace][type].count(globalDofIndex) == 1)
	("There is no periodic association for global DOF %d for boundary type %d!\n",
	 globalDofIndex, type);

      return periodicDofMap[feSpace][type][globalDofIndex];
    }


    inline void add(const FiniteElemSpace *feSpace,
		    BoundaryType type,
		    DegreeOfFreedom dof0, DegreeOfFreedom dof1)
    {
      FUNCNAME("PeriodicMap::map()");

      TEST_EXIT_DBG(periodicDofMap[feSpace][type].count(dof0) == 0 ||
		    periodicDofMap[feSpace][type][dof0] == dof1)
	("Should not happen!\n");

      periodicDofMap[feSpace][type][dof0] = dof1;
      periodicDofAssociations[feSpace][dof0].insert(type);
    }


    /// For a given global DOF index, this function returns the set of periodic
    /// associations, i.e., the boundary types the DOF is associated to, for 
    /// this DOF.
    inline std::set<BoundaryType>& getAssociations(const FiniteElemSpace* feSpace,
						   int globalDofIndex)
    {
      FUNCNAME("PeriodicMap::getAssociations()");

      TEST_EXIT_DBG(periodicDofAssociations.count(feSpace))
	("Should not happen!\n");
      TEST_EXIT_DBG(periodicDofAssociations[feSpace].count(globalDofIndex)) 
 	("Should not happen!\n"); 

      return periodicDofAssociations[feSpace][globalDofIndex];
    }


    /// Returns true, if the DOF (global index) is a periodic DOF.
    inline bool isPeriodic(const FiniteElemSpace *feSpace, int globalDofIndex)
    {
      return (periodicDofAssociations[feSpace].count(globalDofIndex) > 0 &&
	       periodicDofAssociations[feSpace][globalDofIndex].size() > 0);
    }


    inline bool isPeriodicOnBound(const FiniteElemSpace *feSpace,
				  BoundaryType type,
				  int globalDofIndex)
    {
      return periodicDofAssociations[feSpace][globalDofIndex].count(type);
    }


    /// Returns true, if the DOF (global index) of a given FE space is a 
    /// periodic DOF for the given boundary type.
    inline bool isPeriodic(const FiniteElemSpace *feSpace,
			   BoundaryType type,
			   int globalDofIndex)
    {
      return (periodicDofMap[feSpace][type].count(globalDofIndex) > 0);
    }

    /// Write the state of the object to serialization file.
    void serialize(std::ostream &out, 
		   vector<const FiniteElemSpace*> feSpaces);

    /// Read the state of the object from serialization file.
    void deserialize(std::istream &in,
		     vector<const FiniteElemSpace*> feSpaces);

  private:
    /// Write \ref periodicDofMap to serialization file.
    void serialize(std::ostream &out, PeriodicDofMap &data);

    /// Write \ref periodicDofAssociations to serialization file
    void serialize(std::ostream &out, std::map<int, std::set<int> >& data);

    /// Read \ref periodicDofMap from serialization file.
    void deserialize(std::istream &in, PeriodicDofMap &data);
   
    /// Read \ref periodicDofAssociations from serialization file.
    void deserialize(std::istream &in, std::map<int, std::set<int> >& data);
    
    
  private:
    /// This map stores, for each FE space, a mapping from boundary indices
    /// to DOF mappings. So, if an FE space and a boundary index is provided,
    /// we eventually get a mapping from global DOF indices to global DOF
    /// indices.
    PeriodicDofMapFeSpace periodicDofMap;    

    /// This map stores to each periodic DOF the set of periodic boundaries the 
    /// DOF is associated to. In 2D, most DOFs are only on one periodic boundary. 
    // Only, e.g., in a box with all boundaries being periodic, the four corners 
    /// are associated by two different boundaries.
    std::map<const FiniteElemSpace*, std::map<DegreeOfFreedom, std::set<BoundaryType> > > periodicDofAssociations;

    friend class ParallelDebug;
  };
}

#endif