Nektar++
CoupledAssemblyMap.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: CoupledAssemblyMap.cpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: Coupled assembly map for linear elasticity solver.
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
38 #include <LocalRegions/SegExp.h>
42 
43 #include <iomanip>
44 
45 namespace Nektar
46 {
47 
48 /**
49  * @brief Take an existing assembly map and create a coupled version suitable
50  * for use in the linear elasticity solver.
51  *
52  * The linear elasticity solver requires a slight reordering of local and global
53  * coefficients to support problems of the form
54  *
55  * [ A B C ] [ u ] = [ f_u ]
56  * [ D E F ] [ v ] [ f_v ]
57  * [ G H I ] [ w ] [ f_w ]
58  */
63  const SpatialDomains::BoundaryConditionsSharedPtr &boundaryConditions,
65  AssemblyMapCG(pSession)
66 {
67  int nVel = fields[0]->GetCoordim(0);
68 
69  // Multi-level static condensation doesn't work yet.
73  "Multi-level static condensation not supported.");
74 
75  // Copy various coefficient counts, and multiply by the dimension of the
76  // problem to obtain our new values.
77  m_numLocalDirBndCoeffs = cgMap->GetNumLocalDirBndCoeffs() * nVel;
78  m_numLocalBndCoeffs = cgMap->GetNumLocalBndCoeffs() * nVel;
79  m_numLocalCoeffs = cgMap->GetNumLocalCoeffs() * nVel;
80  m_numGlobalBndCoeffs = cgMap->GetNumGlobalBndCoeffs() * nVel;
81  m_numGlobalDirBndCoeffs = cgMap->GetNumGlobalDirBndCoeffs() * nVel;
82  m_numGlobalCoeffs = cgMap->GetNumGlobalCoeffs() * nVel;
83  m_signChange = cgMap->GetSignChange();
84  m_systemSingular = cgMap->GetSingularSystem();
85 
86  // Copy static condensation information. TODO: boundary and interior patches
87  // need to be re-ordered in order to allow for multi-level static
88  // condensation support.
89  m_staticCondLevel = cgMap->GetStaticCondLevel();
90  m_lowestStaticCondLevel = cgMap->GetLowestStaticCondLevel();
91  m_numPatches = cgMap->GetNumPatches();
92  m_numLocalBndCoeffsPerPatch = cgMap->GetNumLocalBndCoeffsPerPatch();
93  m_numLocalIntCoeffsPerPatch = cgMap->GetNumLocalIntCoeffsPerPatch();
94 
95  // Set up local to global and boundary condition maps.
96  const int nLocBndCondDofs = cgMap->
97  GetBndCondCoeffsToGlobalCoeffsMap().num_elements() * nVel;
98 
99  // Allocate storage for local to global maps.
105  Array<OneD, int>(nLocBndCondDofs,-1);
106 
107  // Only require a sign map if we are using modal polynomials in the
108  // expansion and the order is >= 3.
109  if (m_signChange)
110  {
116  Array<OneD, NekDouble>(nLocBndCondDofs,1.0);
117  }
118  else
119  {
123  }
124 
125  const LocalRegions::ExpansionVector &locExpVector
126  = *(fields[0]->GetExp());
127 
128  map<int, int> newGlobalIds;
129  int i, j, n, cnt1, cnt2;
130 
131  // Order local boundary degrees of freedom. These are basically fine; we
132  // reorder storage so that we loop over each element and then each component
133  // of velocity, by applying a mapping l2g -> nVel*l2g + n, for 0 <= n <
134  // nVel. Note that Dirichlet ordering is preserved under this
135  // transformation.
136  cnt1 = cnt2 = 0;
137  for (i = 0; i < locExpVector.size(); ++i)
138  {
139  const int nBndCoeffs = locExpVector[i]->NumBndryCoeffs();
140 
141  for (n = 0; n < nVel; ++n)
142  {
143  for (j = 0; j < nBndCoeffs; ++j, ++cnt1)
144  {
145  const int l2g = cgMap->GetLocalToGlobalBndMap()[cnt2+j];
146  m_localToGlobalBndMap[cnt1] = nVel * l2g + n;
147 
148  if (m_signChange)
149  {
150  m_localToGlobalBndSign[cnt1] =
151  cgMap->GetLocalToGlobalBndSign()[cnt2+j];
152  }
153 
154  if (n == 0)
155  {
156  const int l2gnew = m_localToGlobalBndMap[cnt1];
157  if (newGlobalIds.count(l2g))
158  {
159  ASSERTL1(newGlobalIds[l2g] == l2gnew,
160  "Consistency error");
161  }
162  newGlobalIds[l2g] = l2gnew;
163  }
164  }
165  }
166 
167  cnt2 += nBndCoeffs;
168  }
169 
170  // Grab map of extra Dirichlet degrees of freedom for parallel runs
171  // (particularly in 3D).
172  m_extraDirDofs = cgMap->GetExtraDirDofs();
173 
174  // Counter for remaining interior degrees of freedom.
175  int globalId = m_numGlobalBndCoeffs;
176 
177  // Interior degrees of freedom are a bit more tricky -- global linear system
178  // solve relies on them being in the same order as the BinvD, C and invD
179  // matrices.
180  cnt1 = cnt2 = 0;
181  for (i = 0; i < locExpVector.size(); ++i)
182  {
183  const int nCoeffs = locExpVector[i]->GetNcoeffs();
184  const int nBndCoeffs = locExpVector[i]->NumBndryCoeffs();
185 
186  for (n = 0; n < nVel; ++n)
187  {
188  for (j = 0; j < nBndCoeffs; ++j, ++cnt1, ++cnt2)
189  {
190  const int l2g = m_localToGlobalBndMap[cnt2];
191  m_localToGlobalMap[cnt1] = l2g;
192 
193  if (m_signChange)
194  {
196  }
197  }
198  }
199 
200  for (n = 0; n < nVel; ++n)
201  {
202  for (j = 0; j < nCoeffs - nBndCoeffs; ++j, ++cnt1)
203  {
204  m_localToGlobalMap[cnt1] = globalId++;
205  }
206  }
207  }
208 
209  for (i = 0; i < m_localToGlobalMap.num_elements(); ++i)
210  {
211  ASSERTL1(m_localToGlobalMap[i] != -1, "Consistency error");
212  }
213 
214  ASSERTL1(globalId == m_numGlobalCoeffs, "Consistency error");
215 
216  const int nLocalDirBndCoeffs =
217  cgMap->GetBndCondCoeffsToGlobalCoeffsMap().num_elements();
218 
219  cnt1 = 0;
220  for (n = 0; n < nVel; ++n)
221  {
222  for (i = 0; i < nLocalDirBndCoeffs; ++i, ++cnt1)
223  {
224  const int l2g = cgMap->GetBndCondCoeffsToGlobalCoeffsMap()[i];
225  int newId = newGlobalIds[l2g];
226  m_bndCondCoeffsToGlobalCoeffsMap[cnt1] = newId + n;
227 
228  if (m_signChange)
229  {
231  cgMap->GetBndCondCoeffsToGlobalCoeffsSign(i);
232  }
233  }
234  }
235 
236  // Finally, set up global to universal maps.
241 
242  for (i = 0; i < cgMap->GetNumGlobalBndCoeffs(); ++i)
243  {
244  for (n = 0; n < nVel; ++n)
245  {
246  m_globalToUniversalBndMap[i*nVel + n] =
247  cgMap->GetGlobalToUniversalBndMap()[i]*nVel + n;
248  m_globalToUniversalMap[i*nVel + n] =
249  cgMap->GetGlobalToUniversalBndMap()[i]*nVel + n;
250  }
251  }
252 
256  for (unsigned int i = 0; i < m_numGlobalBndCoeffs; ++i)
257  {
258  tmp[i] = m_globalToUniversalBndMap[i];
259  }
260 
261  LibUtilities::CommSharedPtr vCommRow = m_comm->GetRowComm();
262  m_gsh = Gs::Init(tmp, vCommRow);
263  m_bndGsh = Gs::Init(tmp2, vCommRow);
264  Gs::Unique(tmp, vCommRow);
265  for (unsigned int i = 0; i < m_numGlobalCoeffs; ++i)
266  {
267  m_globalToUniversalMapUnique[i] = (tmp[i] >= 0 ? 1 : 0);
268  }
269  for (unsigned int i = 0; i < m_numGlobalBndCoeffs; ++i)
270  {
271  m_globalToUniversalBndMapUnique[i] = (tmp2[i] >= 0 ? 1 : 0);
272  }
273 
274  m_hash = boost::hash_range(
275  m_localToGlobalMap.begin(), m_localToGlobalMap.end());
276 }
277 
278 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
bool m_systemSingular
Flag indicating if the system is singular or not.
Definition: AssemblyMap.h:319
bool m_signChange
Flag indicating if modes require sign reversal.
Definition: AssemblyMap.h:344
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
Definition: AssemblyMap.h:313
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: AssemblyMap.h:305
static Array< OneD, NekDouble > NullNekDouble1DArray
Array< OneD, int > m_globalToUniversalMapUnique
Integer map of unique process coeffs to universal space (signed)
static gs_data * Init(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm)
Initialise Gather-Scatter map.
Definition: GsLib.hpp:150
Array< OneD, int > m_globalToUniversalMap
Integer map of process coeffs to universal space.
int m_numLocalCoeffs
Total number of local coefficients.
Definition: AssemblyMap.h:330
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:50
std::vector< ExpansionSharedPtr > ExpansionVector
Definition: Expansion.h:70
Array< OneD, int > m_localToGlobalMap
Integer map of local coeffs to global space.
size_t m_hash
Hash for map.
Definition: AssemblyMap.h:308
boost::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
map< int, vector< ExtraDirDof > > m_extraDirDofs
Map indicating degrees of freedom which are Dirichlet but whose value is stored on another processor...
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
Definition: AssemblyMap.h:384
GlobalSysSolnType m_solnType
The solution type of the global system.
Definition: AssemblyMap.h:362
Array< OneD, NekDouble > m_bndCondCoeffsToGlobalCoeffsSign
Integer map of bnd cond coeffs to global coefficients.
Definition: AssemblyMap.h:353
int m_numGlobalDirBndCoeffs
Number of Global Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:317
static void Unique(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm)
Updates pId to negate all-but-one references to each universal ID.
Definition: GsLib.hpp:180
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
Definition: AssemblyMap.h:386
int m_lowestStaticCondLevel
Lowest static condensation level.
Definition: AssemblyMap.h:393
Array< OneD, int > m_localToGlobalBndMap
Integer map of local boundary coeffs to global space.
Definition: AssemblyMap.h:347
const Array< OneD, const int > & GetBndCondCoeffsToGlobalCoeffsMap()
Retrieves the global indices corresponding to the boundary expansion modes.
int m_numLocalDirBndCoeffs
Number of Local Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:315
Array< OneD, int > m_bndCondCoeffsToGlobalCoeffsMap
Integer map of bnd cond coeffs to global coefficients.
Definition: AssemblyMap.h:351
int m_numLocalBndCoeffs
Number of local boundary coefficients.
Definition: AssemblyMap.h:311
int m_staticCondLevel
The level of recursion in the case of multi-level static condensation.
Definition: AssemblyMap.h:380
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Definition: AssemblyMap.h:349
Array< OneD, NekDouble > m_localToGlobalSign
Integer sign of local coeffs to global space.
boost::shared_ptr< BoundaryConditions > BoundaryConditionsSharedPtr
Definition: Conditions.h:269
CoupledAssemblyMap(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &graph, const MultiRegions::AssemblyMapCGSharedPtr &cgMap, const SpatialDomains::BoundaryConditionsSharedPtr &boundConds, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields)
Take an existing assembly map and create a coupled version suitable for use in the linear elasticity ...
Array< OneD, int > m_globalToUniversalBndMap
Integer map of process coeffs to universal space.
Definition: AssemblyMap.h:357
Array< OneD, int > m_globalToUniversalBndMapUnique
Integer map of unique process coeffs to universal space (signed)
Definition: AssemblyMap.h:359
int m_numGlobalCoeffs
Total number of global coefficients.
Definition: AssemblyMap.h:341
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:359
boost::shared_ptr< AssemblyMapCG > AssemblyMapCGSharedPtr
Definition: AssemblyMapCG.h:52
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:191
boost::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:432
int m_numPatches
The number of patches (~elements) in the current level.
Definition: AssemblyMap.h:382