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
41#include <LocalRegions/SegExp.h>
44
45using namespace std;
46
47namespace Nektar
48{
49
51
52/**
53 * @brief Take an existing assembly map and create a coupled version suitable
54 * for use in the linear elasticity solver.
55 *
56 * The linear elasticity solver requires a slight reordering of local and global
57 * coefficients to support problems of the form
58 *
59 * [ A B C ] [ u ] = [ f_u ]
60 * [ D E F ] [ v ] [ f_v ]
61 * [ G H I ] [ w ] [ f_w ]
62 */
63
66 [[maybe_unused]] const SpatialDomains::MeshGraphSharedPtr &graph,
68 [[maybe_unused]] const Array<OneD, const BoundaryCondShPtr>
69 &boundaryConditions,
71 : AssemblyMapCG(pSession, fields[0]->GetComm())
72{
73 int nVel = fields[0]->GetCoordim(0);
74
75 // Multi-level static condensation doesn't work yet.
79 "Multi-level static condensation not supported.");
80
81 // Copy various coefficient counts, and multiply by the dimension of the
82 // problem to obtain our new values.
83 m_numLocalDirBndCoeffs = cgMap->GetNumLocalDirBndCoeffs() * nVel;
84 m_numLocalBndCoeffs = cgMap->GetNumLocalBndCoeffs() * nVel;
85 m_numLocalCoeffs = cgMap->GetNumLocalCoeffs() * nVel;
86 m_numGlobalBndCoeffs = cgMap->GetNumGlobalBndCoeffs() * nVel;
87 m_numGlobalDirBndCoeffs = cgMap->GetNumGlobalDirBndCoeffs() * nVel;
88 m_numGlobalCoeffs = cgMap->GetNumGlobalCoeffs() * nVel;
89 m_signChange = cgMap->GetSignChange();
90 m_systemSingular = cgMap->GetSingularSystem();
91
92 // Copy static condensation information. TODO: boundary and interior patches
93 // need to be re-ordered in order to allow for multi-level static
94 // condensation support.
95 m_staticCondLevel = cgMap->GetStaticCondLevel();
96 m_lowestStaticCondLevel = cgMap->GetLowestStaticCondLevel();
97 m_numPatches = cgMap->GetNumPatches();
98 m_numLocalBndCoeffsPerPatch = cgMap->GetNumLocalBndCoeffsPerPatch();
99 m_numLocalIntCoeffsPerPatch = cgMap->GetNumLocalIntCoeffsPerPatch();
100
101 // Allocate storage for local to global maps.
107
108 // Only require a sign map if we are using modal polynomials in the
109 // expansion and the order is >= 3.
110 if (m_signChange)
111 {
115 }
116 else
117 {
120 }
121
122 const LocalRegions::ExpansionVector &locExpVector = *(fields[0]->GetExp());
123
124 map<int, int> newGlobalIds;
125 int i, j, n, cnt1, cnt2;
126
127 // Order local boundary degrees of freedom. These are basically fine; we
128 // reorder storage so that we loop over each element and then each component
129 // of velocity, by applying a mapping l2g -> nVel*l2g + n, for 0 <= n <
130 // nVel. Note that Dirichlet ordering is preserved under this
131 // transformation.
132 cnt1 = cnt2 = 0;
133 for (i = 0; i < locExpVector.size(); ++i)
134 {
135 const int nBndCoeffs = locExpVector[i]->NumBndryCoeffs();
136
137 for (n = 0; n < nVel; ++n)
138 {
139
140 for (j = 0; j < nBndCoeffs; ++j, ++cnt1)
141 {
142 const int l2g = cgMap->GetLocalToGlobalBndMap()[cnt2 + j];
143 m_localToGlobalBndMap[cnt1] = nVel * l2g + n;
144
145 if (m_signChange)
146 {
148 cgMap->GetLocalToGlobalBndSign()[cnt2 + j];
149 }
150
151 if (n == 0)
152 {
153 const int l2gnew = m_localToGlobalBndMap[cnt1];
154 if (newGlobalIds.count(l2g))
155 {
156 ASSERTL1(newGlobalIds[l2g] == l2gnew,
157 "Consistency error");
158 }
159 newGlobalIds[l2g] = l2gnew;
160 }
161 }
162 }
163
164 cnt2 += nBndCoeffs;
165 }
166
167 // Counter for remaining interior degrees of freedom.
168 int globalId = m_numGlobalBndCoeffs;
169
170 // Interior degrees of freedom are a bit more tricky -- global linear system
171 // solve relies on them being in the same order as the BinvD, C and invD
172 // matrices.
173
174 // Also set up the localToBndMap and localTolocalIntMap which just
175 // take out the boundary blocks and interior blocks from the input
176 // ordering where we have bnd and interior for each elements
177 cnt1 = cnt2 = 0;
178 int bnd_cnt = 0;
179 int int_cnt = 0;
180 for (i = 0; i < locExpVector.size(); ++i)
181 {
182 const int nCoeffs = locExpVector[i]->GetNcoeffs();
183 const int nBndCoeffs = locExpVector[i]->NumBndryCoeffs();
184
185 for (n = 0; n < nVel; ++n)
186 {
187 for (j = 0; j < nBndCoeffs; ++j, ++cnt1, ++cnt2)
188 {
189 m_localToLocalBndMap[bnd_cnt++] = cnt1;
190
191 const int l2g = m_localToGlobalBndMap[cnt2];
192 m_localToGlobalMap[cnt1] = l2g;
193
194 if (m_signChange)
195 {
197 }
198 }
199 }
200
201 for (n = 0; n < nVel; ++n)
202 {
203 for (j = 0; j < nCoeffs - nBndCoeffs; ++j, ++cnt1)
204 {
205 m_localToLocalIntMap[int_cnt++] = cnt1;
206
207 m_localToGlobalMap[cnt1] = globalId++;
208 }
209 }
210 }
211
212 for (i = 0; i < m_localToGlobalMap.size(); ++i)
213 {
214 ASSERTL1(m_localToGlobalMap[i] != -1, "Consistency error");
215 }
216
217 ASSERTL1(globalId == m_numGlobalCoeffs, "Consistency error");
218
219 // Finally, set up global to universal maps.
224
225 for (i = 0; i < cgMap->GetNumGlobalBndCoeffs(); ++i)
226 {
227 for (n = 0; n < nVel; ++n)
228 {
229 m_globalToUniversalBndMap[i * nVel + n] =
230 cgMap->GetGlobalToUniversalBndMap()[i] * nVel + n;
231 m_globalToUniversalMap[i * nVel + n] =
232 cgMap->GetGlobalToUniversalBndMap()[i] * nVel + n;
233 }
234 }
235
239 for (unsigned int i = 0; i < m_numGlobalBndCoeffs; ++i)
240 {
241 tmp[i] = m_globalToUniversalBndMap[i];
242 }
243
244 LibUtilities::CommSharedPtr vCommRow = m_comm->GetRowComm();
245 m_gsh = Gs::Init(tmp, vCommRow);
246 m_bndGsh = Gs::Init(tmp2, vCommRow);
247 Gs::Unique(tmp, vCommRow);
248 for (unsigned int i = 0; i < m_numGlobalCoeffs; ++i)
249 {
250 m_globalToUniversalMapUnique[i] = (tmp[i] >= 0 ? 1 : 0);
251 }
252 for (unsigned int i = 0; i < m_numGlobalBndCoeffs; ++i)
253 {
254 m_globalToUniversalBndMapUnique[i] = (tmp2[i] >= 0 ? 1 : 0);
255 }
256
258}
259
260} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
CoupledAssemblyMap(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &graph, const MultiRegions::AssemblyMapCGSharedPtr &cgMap, const Array< OneD, const BoundaryCondShPtr > &boundaryConditions, const Array< OneD, MultiRegions::ExpListSharedPtr > &fields)
Take an existing assembly map and create a coupled version suitable for use in the linear elasticity ...
Constructs mappings for the C0 scalar continuous Galerkin formulation.
Definition: AssemblyMapCG.h:66
Array< OneD, int > m_globalToUniversalMapUnique
Integer map of unique process coeffs to universal space (signed)
Array< OneD, int > m_localToGlobalMap
Integer map of local coeffs to global space.
Array< OneD, NekDouble > m_localToGlobalSign
Integer sign of local coeffs to global space.
Array< OneD, int > m_globalToUniversalMap
Integer map of process coeffs to universal space.
int m_lowestStaticCondLevel
Lowest static condensation level.
Definition: AssemblyMap.h:439
GlobalSysSolnType m_solnType
The solution type of the global system.
Definition: AssemblyMap.h:402
int m_numLocalCoeffs
Total number of local coefficients.
Definition: AssemblyMap.h:364
bool m_signChange
Flag indicating if modes require sign reversal.
Definition: AssemblyMap.h:378
Array< OneD, int > m_localToLocalIntMap
Integer map of local boundary coeffs to local interior system numbering.
Definition: AssemblyMap.h:387
int m_numGlobalCoeffs
Total number of global coefficients.
Definition: AssemblyMap.h:375
Array< OneD, int > m_globalToUniversalBndMap
Integer map of process coeffs to universal space.
Definition: AssemblyMap.h:397
Array< OneD, NekDouble > m_localToGlobalBndSign
Integer sign of local boundary coeffs to global space.
Definition: AssemblyMap.h:383
Array< OneD, unsigned int > m_numLocalBndCoeffsPerPatch
The number of bnd dofs per patch.
Definition: AssemblyMap.h:430
int m_numLocalBndCoeffs
Number of local boundary coefficients.
Definition: AssemblyMap.h:345
int m_staticCondLevel
The level of recursion in the case of multi-level static condensation.
Definition: AssemblyMap.h:426
int m_numLocalDirBndCoeffs
Number of Local Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:349
int m_numGlobalDirBndCoeffs
Number of Global Dirichlet Boundary Coefficients.
Definition: AssemblyMap.h:351
Array< OneD, unsigned int > m_numLocalIntCoeffsPerPatch
The number of int dofs per patch.
Definition: AssemblyMap.h:432
bool m_systemSingular
Flag indicating if the system is singular or not.
Definition: AssemblyMap.h:353
Array< OneD, int > m_localToGlobalBndMap
Integer map of local coeffs to global Boundary Dofs.
Definition: AssemblyMap.h:381
Array< OneD, int > m_globalToUniversalBndMapUnique
Integer map of unique process coeffs to universal space (signed)
Definition: AssemblyMap.h:399
LibUtilities::CommSharedPtr m_comm
Communicator.
Definition: AssemblyMap.h:336
Array< OneD, int > m_localToLocalBndMap
Integer map of local boundary coeffs to local boundary system numbering.
Definition: AssemblyMap.h:385
int m_numPatches
The number of patches (~elements) in the current level.
Definition: AssemblyMap.h:428
int m_numGlobalBndCoeffs
Total number of global boundary coefficients.
Definition: AssemblyMap.h:347
static gs_data * Init(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm, bool verbose=true)
Initialise Gather-Scatter map.
Definition: GsLib.hpp:190
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:225
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:55
std::vector< ExpansionSharedPtr > ExpansionVector
Definition: Expansion.h:68
std::shared_ptr< AssemblyMapCG > AssemblyMapCGSharedPtr
Definition: AssemblyMapCG.h:50
std::shared_ptr< BoundaryConditionBase > BoundaryConditionShPtr
Definition: Conditions.h:212
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::size_t hash_range(Iter first, Iter last)
Definition: HashUtils.hpp:64
static Array< OneD, NekDouble > NullNekDouble1DArray
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.hpp:273