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 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Coupled assembly map for linear elasticity solver.
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <iomanip>
36 
37 #include <boost/core/ignore_unused.hpp>
38 
42 #include <LocalRegions/SegExp.h>
46 
47 using namespace std;
48 
49 namespace Nektar
50 {
51 
53 
54 /**
55  * @brief Take an existing assembly map and create a coupled version suitable
56  * for use in the linear elasticity solver.
57  *
58  * The linear elasticity solver requires a slight reordering of local and global
59  * coefficients to support problems of the form
60  *
61  * [ A B C ] [ u ] = [ f_u ]
62  * [ D E F ] [ v ] [ f_v ]
63  * [ G H I ] [ w ] [ f_w ]
64  */
65 
66 CoupledAssemblyMap::CoupledAssemblyMap(
70  const Array<OneD, const BoundaryCondShPtr> &boundaryConditions,
72  AssemblyMapCG(pSession)
73 {
74  boost::ignore_unused(graph, boundaryConditions);
75 
76  int nVel = fields[0]->GetCoordim(0);
77 
78  // Multi-level static condensation doesn't work yet.
82  "Multi-level static condensation not supported.");
83 
84  // Copy various coefficient counts, and multiply by the dimension of the
85  // problem to obtain our new values.
86  m_numLocalDirBndCoeffs = cgMap->GetNumLocalDirBndCoeffs() * nVel;
87  m_numLocalBndCoeffs = cgMap->GetNumLocalBndCoeffs() * nVel;
88  m_numLocalCoeffs = cgMap->GetNumLocalCoeffs() * nVel;
89  m_numGlobalBndCoeffs = cgMap->GetNumGlobalBndCoeffs() * nVel;
90  m_numGlobalDirBndCoeffs = cgMap->GetNumGlobalDirBndCoeffs() * nVel;
91  m_numGlobalCoeffs = cgMap->GetNumGlobalCoeffs() * nVel;
92  m_signChange = cgMap->GetSignChange();
93  m_systemSingular = cgMap->GetSingularSystem();
94 
95  // Copy static condensation information. TODO: boundary and interior patches
96  // need to be re-ordered in order to allow for multi-level static
97  // condensation support.
98  m_staticCondLevel = cgMap->GetStaticCondLevel();
99  m_lowestStaticCondLevel = cgMap->GetLowestStaticCondLevel();
100  m_numPatches = cgMap->GetNumPatches();
101  m_numLocalBndCoeffsPerPatch = cgMap->GetNumLocalBndCoeffsPerPatch();
102  m_numLocalIntCoeffsPerPatch = cgMap->GetNumLocalIntCoeffsPerPatch();
103 
104  // Allocate storage for local to global maps.
110 
111  // Only require a sign map if we are using modal polynomials in the
112  // expansion and the order is >= 3.
113  if (m_signChange)
114  {
119  }
120  else
121  {
124  }
125 
126  const LocalRegions::ExpansionVector &locExpVector
127  = *(fields[0]->GetExp());
128 
129  map<int, int> newGlobalIds;
130  int i, j, n, cnt1, cnt2;
131 
132  // Order local boundary degrees of freedom. These are basically fine; we
133  // reorder storage so that we loop over each element and then each component
134  // of velocity, by applying a mapping l2g -> nVel*l2g + n, for 0 <= n <
135  // nVel. Note that Dirichlet ordering is preserved under this
136  // transformation.
137  cnt1 = cnt2 = 0;
138  for (i = 0; i < locExpVector.size(); ++i)
139  {
140  const int nBndCoeffs = locExpVector[i]->NumBndryCoeffs();
141 
142  for (n = 0; n < nVel; ++n)
143  {
144 
145  for (j = 0; j < nBndCoeffs; ++j, ++cnt1)
146  {
147  const int l2g = cgMap->GetLocalToGlobalBndMap()[cnt2+j];
148  m_localToGlobalBndMap[cnt1] = nVel * l2g + n;
149 
150  if (m_signChange)
151  {
152  m_localToGlobalBndSign[cnt1] =
153  cgMap->GetLocalToGlobalBndSign()[cnt2+j];
154  }
155 
156  if (n == 0)
157  {
158  const int l2gnew = m_localToGlobalBndMap[cnt1];
159  if (newGlobalIds.count(l2g))
160  {
161  ASSERTL1(newGlobalIds[l2g] == l2gnew,
162  "Consistency error");
163  }
164  newGlobalIds[l2g] = l2gnew;
165  }
166  }
167  }
168 
169  cnt2 += nBndCoeffs;
170  }
171 
172  // Counter for remaining interior degrees of freedom.
173  int globalId = m_numGlobalBndCoeffs;
174 
175  // Interior degrees of freedom are a bit more tricky -- global linear system
176  // solve relies on them being in the same order as the BinvD, C and invD
177  // matrices.
178 
179  // Also set up the localToBndMap and localTolocalIntMap which just
180  // take out the boundary blocks and interior blocks from the input
181  // ordering where we have bnd and interior for each elements
182  cnt1 = cnt2 = 0;
183  int bnd_cnt = 0;
184  int int_cnt = 0;
185  for (i = 0; i < locExpVector.size(); ++i)
186  {
187  const int nCoeffs = locExpVector[i]->GetNcoeffs();
188  const int nBndCoeffs = locExpVector[i]->NumBndryCoeffs();
189 
190  for (n = 0; n < nVel; ++n)
191  {
192  for (j = 0; j < nBndCoeffs; ++j, ++cnt1, ++cnt2)
193  {
194  m_localToLocalBndMap[bnd_cnt++] = cnt1;
195 
196 
197  const int l2g = m_localToGlobalBndMap[cnt2];
198  m_localToGlobalMap[cnt1] = l2g;
199 
200  if (m_signChange)
201  {
203  }
204  }
205  }
206 
207  for (n = 0; n < nVel; ++n)
208  {
209  for (j = 0; j < nCoeffs - nBndCoeffs; ++j, ++cnt1)
210  {
211  m_localToLocalIntMap[int_cnt++] = cnt1;
212 
213  m_localToGlobalMap[cnt1] = globalId++;
214  }
215  }
216  }
217 
218  for (i = 0; i < m_localToGlobalMap.size(); ++i)
219  {
220  ASSERTL1(m_localToGlobalMap[i] != -1, "Consistency error");
221  }
222 
223  ASSERTL1(globalId == m_numGlobalCoeffs, "Consistency error");
224 
225 
226  // Finally, set up global to universal maps.
231 
232  for (i = 0; i < cgMap->GetNumGlobalBndCoeffs(); ++i)
233  {
234  for (n = 0; n < nVel; ++n)
235  {
236  m_globalToUniversalBndMap[i*nVel + n] =
237  cgMap->GetGlobalToUniversalBndMap()[i]*nVel + n;
238  m_globalToUniversalMap[i*nVel + n] =
239  cgMap->GetGlobalToUniversalBndMap()[i]*nVel + n;
240  }
241  }
242 
246  for (unsigned int i = 0; i < m_numGlobalBndCoeffs; ++i)
247  {
248  tmp[i] = m_globalToUniversalBndMap[i];
249  }
250 
251  LibUtilities::CommSharedPtr vCommRow = m_comm->GetRowComm();
252  m_gsh = Gs::Init(tmp, vCommRow);
253  m_bndGsh = Gs::Init(tmp2, vCommRow);
254  Gs::Unique(tmp, vCommRow);
255  for (unsigned int i = 0; i < m_numGlobalCoeffs; ++i)
256  {
257  m_globalToUniversalMapUnique[i] = (tmp[i] >= 0 ? 1 : 0);
258  }
259  for (unsigned int i = 0; i < m_numGlobalBndCoeffs; ++i)
260  {
261  m_globalToUniversalBndMapUnique[i] = (tmp2[i] >= 0 ? 1 : 0);
262  }
263 
264  m_hash = hash_range(
265  m_localToGlobalMap.begin(), m_localToGlobalMap.end());
266 }
267 
268 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
Constructs mappings for the C0 scalar continuous Galerkin formulation.
Definition: AssemblyMapCG.h:71
Array< OneD, int > m_globalToUniversalMapUnique
Integer map of unique process coeffs to universal space (signed)
Array< OneD, int > m_globalToUniversalMap
Integer map of process coeffs to universal space.
Array< OneD, NekDouble > m_localToGlobalSign
Integer sign of local coeffs to global space.
Array< OneD, int > m_localToGlobalMap
Integer map of local coeffs to global space.
int m_lowestStaticCondLevel
Lowest static condensation level.
Definition: AssemblyMap.h:434
GlobalSysSolnType m_solnType
The solution type of the global system.
Definition: AssemblyMap.h:395
int m_numLocalCoeffs
Total number of local coefficients.
Definition: AssemblyMap.h:357
Array< OneD, int > m_globalToUniversalBndMap
Integer map of process coeffs to universal space.
Definition: AssemblyMap.h:390
bool m_signChange
Flag indicating if modes require sign reversal.
Definition: AssemblyMap.h:371
int m_numGlobalCoeffs
Total number of global coefficients.
Definition: AssemblyMap.h:368
Array< OneD, int > m_localToGlobalBndMap
Integer map of local coeffs to global Boundary Dofs.
Definition: AssemblyMap.h:374
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
Definition: AssemblyMap.h:425
int m_numLocalBndCoeffs
Number of local boundary coefficients.
Definition: AssemblyMap.h:338
int m_staticCondLevel
The level of recursion in the case of multi-level static condensation.
Definition: AssemblyMap.h:421
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Definition: AssemblyMap.h:376
Array< OneD, int > m_localToLocalIntMap
Integer map of local boundary coeffs to local interior system numbering.
Definition: AssemblyMap.h:380
int m_numLocalDirBndCoeffs
Number of Local Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:342
int m_numGlobalDirBndCoeffs
Number of Global Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:344
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
Definition: AssemblyMap.h:427
bool m_systemSingular
Flag indicating if the system is singular or not.
Definition: AssemblyMap.h:346
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: AssemblyMap.h:332
Array< OneD, int > m_localToLocalBndMap
Integer map of local boundary coeffs to local boundary system numbering.
Definition: AssemblyMap.h:378
Array< OneD, int > m_globalToUniversalBndMapUnique
Integer map of unique process coeffs to universal space (signed)
Definition: AssemblyMap.h:392
int m_numPatches
The number of patches (~elements) in the current level.
Definition: AssemblyMap.h:423
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
Definition: AssemblyMap.h:340
static gs_data * Init(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm, bool verbose=true)
Initialise Gather-Scatter map.
Definition: GsLib.hpp:167
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:202
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:54
std::vector< ExpansionSharedPtr > ExpansionVector
Definition: Expansion.h:70
std::shared_ptr< AssemblyMapCG > AssemblyMapCGSharedPtr
Definition: AssemblyMapCG.h:51
std::shared_ptr< BoundaryConditionBase > BoundaryConditionShPtr
Definition: Conditions.h:219
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
std::size_t hash_range(Iter first, Iter last)
Definition: HashUtils.hpp:69
static Array< OneD, NekDouble > NullNekDouble1DArray
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:436