Nektar++
Loading...
Searching...
No Matches
ContField.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: ContField.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: Field definition for a continuous domain with boundary
32// conditions
33//
34///////////////////////////////////////////////////////////////////////////////
35
38#include <tuple>
39
40using namespace std;
41
43{
44/**
45 * @class ContField
46 * The class #ContField is
47 * able to incorporate the boundary conditions imposed to the problem
48 * to be solved. Therefore, the class is equipped with three additional
49 * data members:
50 * - #m_bndCondExpansions
51 * - #m_bndTypes
52 * - #m_bndCondEquations
53 *
54 * The first data structure, #m_bndCondExpansions, contains the
55 * one-dimensional spectral/hp expansion on the boundary, #m_bndTypes
56 * stores information about the type of boundary condition on the
57 * different parts of the boundary while #m_bndCondEquations holds the
58 * equation of the imposed boundary conditions.
59 *
60 * Furthermore, in case of Dirichlet boundary conditions, this class is
61 * capable of lifting a known solution satisfying these boundary
62 * conditions. If we denote the unknown solution by
63 * \f$u^{\mathcal{H}}(\boldsymbol{x})\f$ and the known Dirichlet
64 * boundary conditions by \f$u^{\mathcal{D}}(\boldsymbol{x})\f$, the
65 * expansion then can be decomposed as
66 * \f[ u^{\delta}(\boldsymbol{x}_i)=u^{\mathcal{D}}(\boldsymbol{x}_i)+
67 * u^{\mathcal{H}}(\boldsymbol{x}_i)=\sum_{n=0}^{N^{\mathcal{D}}-1}
68 * \hat{u}_n^{\mathcal{D}}\Phi_n(\boldsymbol{x}_i)+
69 * \sum_{n={N^{\mathcal{D}}}}^{N_{\mathrm{dof}}-1}
70 * \hat{u}_n^{\mathcal{H}} \Phi_n(\boldsymbol{x}_i).\f]
71 * This lifting is accomplished by ordering the known global degrees of
72 * freedom, prescribed by the Dirichlet boundary conditions, first in
73 * the global array
74 * \f$\boldsymbol{\hat{u}}\f$, that is,
75 * \f[\boldsymbol{\hat{u}}=\left[ \begin{array}{c}
76 * \boldsymbol{\hat{u}}^{\mathcal{D}}\\
77 * \boldsymbol{\hat{u}}^{\mathcal{H}}
78 * \end{array} \right].\f]
79 * Such kind of expansions are also referred to as continuous fields.
80 * This class should be used when solving 2D problems using a standard
81 * Galerkin approach.
82 */
83
84/**
85 *
86 */
88 : DisContField(), m_locToGloMap(), m_globalMat(),
89 m_globalLinSysManager(
90 std::bind(&ContField::GenGlobalLinSys, this, std::placeholders::_1),
91 std::string("GlobalLinSys")),
92 m_GJPData(nullptr)
93{
94}
95
96/**
97 * Given a mesh \a graph, containing information about the domain and
98 * the spectral/hp element expansion, this constructor fills the list
99 * of local expansions #m_exp with the proper expansions, calculates
100 * the total number of quadrature points \f$\boldsymbol{x}_i\f$ and
101 * local expansion coefficients \f$\hat{u}^e_n\f$ and allocates memory
102 * for the arrays #m_coeffs and #m_phys. Furthermore, it constructs the
103 * mapping array (contained in #m_locToGloMap) for the transformation
104 * between local elemental level and global level, it calculates the
105 * total number global expansion coefficients \f$\hat{u}_n\f$ and
106 * allocates memory for the array #m_contCoeffs. The constructor also
107 * discretises the boundary conditions, specified by the argument \a
108 * bcs, by expressing them in terms of the coefficient of the expansion
109 * on the boundary.
110 *
111 * @param graph A mesh, containing information about the domain
112 * and the spectral/hp element expansion.
113 * @param bcs The boundary conditions.
114 * @param variable An optional parameter to indicate for which
115 * variable the field should be constructed.
116 */
119 const std::string &variable,
120 const bool DeclareCoeffPhysArrays,
121 const bool CheckIfSingularSystem,
123 : DisContField(pSession, graph, variable, false, DeclareCoeffPhysArrays,
124 ImpType),
125 m_globalMat(MemoryManager<GlobalMatrixMap>::AllocateSharedPtr()),
126 m_globalLinSysManager(
127 std::bind(&ContField::GenGlobalLinSys, this, std::placeholders::_1),
128 std::string("GlobalLinSys"))
129{
132 CheckIfSingularSystem, variable, m_periodicVerts, m_periodicEdges,
134
135 if (m_session->DefinesCmdLineArgument("verbose"))
136 {
137 m_locToGloMap->PrintStats(std::cout, variable);
138 }
139}
140
141/**
142 * Given a mesh \a graph, containing information about the domain and
143 * the spectral/hp element expansion, this constructor fills the list
144 * of local expansions #m_exp with the proper expansions, calculates
145 * the total number of quadrature points \f$\boldsymbol{x}_i\f$ and
146 * local expansion coefficients \f$\hat{u}^e_n\f$ and allocates memory
147 * for the arrays #m_coeffs and #m_phys. Furthermore, it constructs the
148 * mapping array (contained in #m_locToGloMap) for the transformation
149 * between local elemental level and global level, it calculates the
150 * total number global expansion coefficients \f$\hat{u}_n\f$ and
151 * allocates memory for the array #m_coeffs. The constructor also
152 * discretises the boundary conditions, specified by the argument \a
153 * bcs, by expressing them in terms of the coefficient of the expansion
154 * on the boundary.
155 *
156 * @param In Existing ContField object used to provide the
157 * local to global mapping information and
158 * global solution type.
159 * @param graph A mesh, containing information about the domain
160 * and the spectral/hp element expansion.
161 * @param bcs The boundary conditions.
162 * @param bc_loc
163 */
166 const std::string &variable, bool DeclareCoeffPhysArrays,
167 const bool CheckIfSingularSystem)
168 : DisContField(In, graph, variable, false, DeclareCoeffPhysArrays),
169 m_globalMat(MemoryManager<GlobalMatrixMap>::AllocateSharedPtr()),
170 m_globalLinSysManager(
171 std::bind(&ContField::GenGlobalLinSys, this, std::placeholders::_1),
172 std::string("GlobalLinSys")),
173 m_GJPData(In.m_GJPData)
174{
175 if (!SameTypeOfBoundaryConditions(In) || CheckIfSingularSystem)
176 {
179 CheckIfSingularSystem, variable, m_periodicVerts, m_periodicEdges,
181
182 if (m_session->DefinesCmdLineArgument("verbose"))
183 {
184 m_locToGloMap->PrintStats(std::cout, variable);
185 }
186 }
187 else
188 {
190 }
191}
192
193/**
194 * Initialises the object as a copy of an existing ContField object.
195 * @param In Existing ContField object.
196 * @param DeclareCoeffPhysArrays bool to declare if \a m_phys
197 * and \a m_coeffs should be declared. Default is true
198 */
199ContField::ContField(const ContField &In, bool DeclareCoeffPhysArrays)
200 : DisContField(In, DeclareCoeffPhysArrays), m_locToGloMap(In.m_locToGloMap),
201 m_globalMat(In.m_globalMat),
202 m_globalLinSysManager(In.m_globalLinSysManager), m_GJPData(In.m_GJPData)
203{
204}
205
206/**
207 * Constructs a continuous field as a copy of an existing
208 * explist field and adding all the boundary conditions.
209 *
210 * @param In Existing explist1D field .
211 */
213 const ExpList &In)
214 : DisContField(In), m_locToGloMap(),
215 m_globalLinSysManager(
216 std::bind(&ContField::GenGlobalLinSys, this, std::placeholders::_1),
217 std::string("GlobalLinSys"))
218{
220 pSession, m_ncoeffs, In);
221}
222
223/**
224 *
225 */
229
230/**
231 * Given a function \f$f(\boldsymbol{x})\f$ defined at the quadrature
232 * points, this function determines the unknown global coefficients
233 * \f$\boldsymbol{\hat{u}}^{\mathcal{H}}\f$ employing a discrete
234 * Galerkin projection from physical space to coefficient
235 * space. The operation is evaluated by the function #GlobalSolve using
236 * the global mass matrix.
237 *
238 * The values of the function \f$f(\boldsymbol{x})\f$ evaluated at the
239 * quadrature points \f$\boldsymbol{x}_i\f$ should be contained in the
240 * variable #inarray of the ExpList object \a Sin. The resulting global
241 * coefficients \f$\hat{u}_g\f$ are stored in the array #outarray.
242 */
244 Array<OneD, NekDouble> &outarray)
245
246{
247 // Inner product of forcing
249 IProductWRTBase(inarray, wsp);
250
251 // Solve the system
253
254 GlobalSolve(key, wsp, outarray);
255}
256
257/**
258 *
259 */
261{
262 int Ncoeffs = m_locToGloMap->GetNumLocalCoeffs();
263 Array<OneD, NekDouble> tmp1(Ncoeffs);
264 Array<OneD, NekDouble> tmp2(Ncoeffs);
265
266 IProductWRTBase(field, tmp1);
267 MultiplyByInvMassMatrix(tmp1, tmp2);
268 BwdTrans(tmp2, field);
269}
270
271/**
272 * Computes the matrix vector product
273 * @f$ \mathbf{y} = \mathbf{M}^{-1}\mathbf{x} @f$.
274 *
275 * @param inarray Input vector @f$\mathbf{x}@f$.
276 * @param outarray Output vector @f$\mathbf{y}@f$.
277 */
279 const Array<OneD, const NekDouble> &inarray,
280 Array<OneD, NekDouble> &outarray)
281
282{
284 GlobalSolve(key, inarray, outarray);
285}
286
287/**
288 * Consider the two dimensional Laplace equation,
289 * \f[\nabla\cdot\left(\boldsymbol{\sigma}\nabla
290 * u(\boldsymbol{x})\right) = f(\boldsymbol{x}),\f] supplemented with
291 * appropriate boundary conditions (which are contained in the data
292 * member #m_bndCondExpansions). In the equation above
293 * \f$\boldsymbol{\sigma}\f$ is the (symmetric positive definite)
294 * diffusion tensor:
295 * \f[ \sigma = \left[ \begin{array}{cc}
296 * \sigma_{00}(\boldsymbol{x},t) & \sigma_{01}(\boldsymbol{x},t) \\
297 * \sigma_{01}(\boldsymbol{x},t) & \sigma_{11}(\boldsymbol{x},t)
298 * \end{array} \right]. \f]
299 * Applying a \f$C^0\f$ continuous Galerkin discretisation, this
300 * equation leads to the following linear system:
301 * \f[\boldsymbol{L}
302 * \boldsymbol{\hat{u}}_g=\boldsymbol{\hat{f}}\f]
303 * where \f$\boldsymbol{L}\f$ is the Laplacian matrix. This function
304 * solves the system above for the global coefficients
305 * \f$\boldsymbol{\hat{u}}\f$ by a call to the function #GlobalSolve.
306 *
307 * The values of the function \f$f(\boldsymbol{x})\f$ evaluated at the
308 * quadrature points \f$\boldsymbol{x}_i\f$ should be contained in the
309 * variable #inarray
310 *
311 * @param inarray An Array<OneD, NekDouble> containing the discrete
312 * evaluation of the forcing function
313 * \f$f(\boldsymbol{x})\f$ at the quadrature
314 * points.
315 *
316 * @param outarray An Array<OneD, NekDouble> containing the
317 * coefficients of the solution
318 *
319 * @param variablecoeffs The (optional) parameter containing the
320 * coefficients evaluated at the quadrature
321 * points. It is an Array of (three) arrays which
322 * stores the laplacian coefficients in the
323 * following way
324 * \f[\mathrm{variablecoeffs} = \left[ \begin{array}{c}
325 * \left[\sigma_{00}(\boldsymbol{x_i},t)\right]_i \\
326 * \left[\sigma_{01}(\boldsymbol{x_i},t)\right]_i \\
327 * \left[\sigma_{11}(\boldsymbol{x_i},t)\right]_i
328 * \end{array}\right]
329 * \f]
330 * If this argument is not passed to the function, the following
331 * equation will be solved:
332 * \f[\nabla^2u(\boldsymbol{x}) = f(\boldsymbol{x}),\f]
333 *
334 * @param time The time-level at which the coefficients are
335 * evaluated
336 */
338 const Array<OneD, const NekDouble> &inarray,
339 Array<OneD, NekDouble> &outarray,
340 const Array<OneD, const NekDouble> &dirForcing,
341 const Array<OneD, Array<OneD, NekDouble>> &variablecoeffs, NekDouble time)
342{
343 // Inner product of forcing
345 IProductWRTBase(inarray, wsp);
346
347 // Note -1.0 term necessary to invert forcing function to
348 // be consistent with matrix definition
349 Vmath::Neg(m_ncoeffs, wsp, 1);
350
351 // Forcing function with weak boundary conditions
352 int i, j;
353 int bndcnt = 0;
355 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsSign();
356 const Array<OneD, const int> map =
357 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsMap();
358
359 // Add weak boundary conditions to forcing
360 for (i = 0; i < m_bndCondExpansions.size(); ++i)
361 {
362 if (m_bndConditions[i]->GetBoundaryConditionType() ==
364 m_bndConditions[i]->GetBoundaryConditionType() ==
366 {
367
368 const Array<OneD, const NekDouble> bndcoeff =
370
371 if (m_locToGloMap->GetSignChange())
372 {
373 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
374 {
375 wsp[map[bndcnt + j]] += sign[bndcnt + j] * bndcoeff[j];
376 }
377 }
378 else
379 {
380 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
381 {
382 wsp[map[bndcnt + j]] += bndcoeff[bndcnt + j];
383 }
384 }
385 }
386
387 bndcnt += m_bndCondExpansions[i]->GetNcoeffs();
388 }
389
390 StdRegions::VarCoeffMap varcoeffs;
391 varcoeffs[StdRegions::eVarCoeffD00] = variablecoeffs[0];
392 varcoeffs[StdRegions::eVarCoeffD01] = variablecoeffs[1];
393 varcoeffs[StdRegions::eVarCoeffD11] = variablecoeffs[3];
394 varcoeffs[StdRegions::eVarCoeffD22] = variablecoeffs[5];
396 factors[StdRegions::eFactorTime] = time;
397
398 // Solve the system
400 varcoeffs);
401
402 GlobalSolve(key, wsp, outarray, dirForcing);
403}
404
405/**
406 * Constructs the GlobalLinearSysKey for the linear advection operator
407 * with the supplied parameters, and computes the eigenvectors and
408 * eigenvalues of the associated matrix.
409 * @param ax Advection parameter, x.
410 * @param ay Advection parameter, y.
411 * @param Real Computed eigenvalues, real component.
412 * @param Imag Computed eigenvalues, imag component.
413 * @param Evecs Computed eigenvectors.
414 */
419{
420 // Solve the system
424 vel[0] = vel_x;
425 vel[1] = vel_y;
426
427 StdRegions::VarCoeffMap varcoeffs;
428 varcoeffs[StdRegions::eVarCoeffVelX] =
430 varcoeffs[StdRegions::eVarCoeffVelY] =
433 factors[StdRegions::eFactorTime] = 0.0;
435 factors, varcoeffs);
436
438 Gmat->EigenSolve(Real, Imag, Evecs);
439}
440
441/**
442 * Given a linear system specified by the key \a key,
443 * \f[\boldsymbol{M}\boldsymbol{\hat{u}}_g=\boldsymbol{\hat{f}},\f]
444 * this function solves this linear system taking into account the
445 * boundary conditions specified in the data member
446 * #m_bndCondExpansions. Therefore, it adds an array
447 * \f$\boldsymbol{\hat{g}}\f$ which represents the non-zero surface
448 * integral resulting from the weak boundary conditions (e.g. Neumann
449 * boundary conditions) to the right hand side, that is,
450 * \f[\boldsymbol{M}\boldsymbol{\hat{u}}_g=\boldsymbol{\hat{f}}+
451 * \boldsymbol{\hat{g}}.\f]
452 * Furthermore, it lifts the known degrees of freedom which are
453 * prescribed by the Dirichlet boundary conditions. As these known
454 * coefficients \f$\boldsymbol{\hat{u}}^{\mathcal{D}}\f$ are numbered
455 * first in the global coefficient array \f$\boldsymbol{\hat{u}}_g\f$,
456 * the linear system can be decomposed as,
457 * \f[\left[\begin{array}{cc}
458 * \boldsymbol{M}^{\mathcal{DD}}&\boldsymbol{M}^{\mathcal{DH}}\\
459 * \boldsymbol{M}^{\mathcal{HD}}&\boldsymbol{M}^{\mathcal{HH}}
460 * \end{array}\right]
461 * \left[\begin{array}{c}
462 * \boldsymbol{\hat{u}}^{\mathcal{D}}\\
463 * \boldsymbol{\hat{u}}^{\mathcal{H}}
464 * \end{array}\right]=
465 * \left[\begin{array}{c}
466 * \boldsymbol{\hat{f}}^{\mathcal{D}}\\
467 * \boldsymbol{\hat{f}}^{\mathcal{H}}
468 * \end{array}\right]+
469 * \left[\begin{array}{c}
470 * \boldsymbol{\hat{g}}^{\mathcal{D}}\\
471 * \boldsymbol{\hat{g}}^{\mathcal{H}}
472 * \end{array}\right]
473 * \f]
474 * which will then be solved for the unknown coefficients
475 * \f$\boldsymbol{\hat{u}}^{\mathcal{H}}\f$ as,
476 * \f[
477 * \boldsymbol{M}^{\mathcal{HH}}\boldsymbol{\hat{u}}^{\mathcal{H}}=
478 * \boldsymbol{\hat{f}}^{\mathcal{H}}+
479 * \boldsymbol{\hat{g}}^{\mathcal{H}}-
480 * \boldsymbol{M}^{\mathcal{HD}}\boldsymbol{\hat{u}}^{\mathcal{D}}\f]
481 *
482 * @param mkey This key uniquely defines the linear system to
483 * be solved.
484 * @param locrhs contains the forcing term in local coefficient space
485 * @note inout contains initial guess and final output in local coeffs.
486 */
488 const Array<OneD, const NekDouble> &locrhs,
490 const Array<OneD, const NekDouble> &dirForcing)
491{
492 int NumDirBcs = m_locToGloMap->GetNumGlobalDirBndCoeffs();
493 int contNcoeffs = m_locToGloMap->GetNumGlobalCoeffs();
494
495 // STEP 1: SET THE DIRICHLET DOFS TO THE RIGHT VALUE
496 // IN THE SOLUTION ARRAY
498
499 // STEP 2: CALCULATE THE HOMOGENEOUS COEFFICIENTS
500 if (contNcoeffs - NumDirBcs > 0)
501 {
503 LinSys->Solve(locrhs, inout, m_locToGloMap, dirForcing);
504 }
505}
506
507/**
508 * Returns the global matrix associated with the given GlobalMatrixKey.
509 * If the global matrix has not yet been constructed on this field,
510 * it is first constructed using GenGlobalMatrix().
511 * @param mkey Global matrix key.
512 * @returns Assocated global matrix.
513 */
515{
517 "To use method must have a AssemblyMap "
518 "attached to key");
519
520 GlobalMatrixSharedPtr glo_matrix;
521 auto matrixIter = m_globalMat->find(mkey);
522
523 if (matrixIter == m_globalMat->end())
524 {
525 glo_matrix = GenGlobalMatrix(mkey, m_locToGloMap);
526 (*m_globalMat)[mkey] = glo_matrix;
527 }
528 else
529 {
530 glo_matrix = matrixIter->second;
531 }
532
533 return glo_matrix;
534}
535
536/**
537 * The function searches the map #m_globalLinSys to see if the
538 * global matrix has been created before. If not, it calls the function
539 * #GenGlobalLinSys to generate the requested global system.
540 *
541 * @param mkey This key uniquely defines the requested
542 * linear system.
543 */
548
550{
552 "To use method must have a AssemblyMap "
553 "attached to key");
555}
556
558{
559 int i, j;
560 int bndcnt = 0;
561
563 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsSign();
564 const Array<OneD, const int> map =
565 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsMap();
566
567 for (i = 0; i < m_bndCondExpansions.size(); ++i)
568 {
569 if (m_bndConditions[i]->GetBoundaryConditionType() ==
571 {
572
573 const Array<OneD, const NekDouble> bndcoeff =
575
576 if (m_locToGloMap->GetSignChange())
577 {
578 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
579 {
580 outarray[map[bndcnt + j]] = sign[bndcnt + j] * bndcoeff[j];
581 }
582 }
583 else
584 {
585 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
586 {
587 outarray[map[bndcnt + j]] = bndcoeff[j];
588 }
589 }
590 }
591 bndcnt += m_bndCondExpansions[i]->GetNcoeffs();
592 }
593
594 // communicate local Dirichlet coeffs that are just
595 // touching a dirichlet boundary on another partition
596 set<int> &ParallelDirBndSign = m_locToGloMap->GetParallelDirBndSign();
597
598 for (auto &it : ParallelDirBndSign)
599 {
600 outarray[it] *= -1;
601 }
602
603 m_locToGloMap->UniversalAbsMaxBnd(outarray);
604
605 for (auto &it : ParallelDirBndSign)
606 {
607 outarray[it] *= -1;
608 }
609
610 set<ExtraDirDof> &copyLocalDirDofs = m_locToGloMap->GetCopyLocalDirDofs();
611 for (auto &it : copyLocalDirDofs)
612 {
613 outarray[std::get<0>(it)] = outarray[std::get<1>(it)] * std::get<2>(it);
614 }
615}
616
618{
619 int bndcnt = 0;
620
622 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsSign();
623 const Array<OneD, const int> bndmap =
624 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsMap();
625
626 for (int i = 0; i < m_bndCondExpansions.size(); ++i)
627 {
628 Array<OneD, NekDouble> &bcoeffs =
629 m_bndCondExpansions[i]->UpdateCoeffs();
630
631 if (m_locToGloMap->GetSignChange())
632 {
633 for (int j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); ++j)
634 {
635 bcoeffs[j] = sign[bndcnt + j] * coeffs[bndmap[bndcnt + j]];
636 }
637 }
638 else
639 {
640 for (int j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); ++j)
641 {
642 bcoeffs[j] = coeffs[bndmap[bndcnt + j]];
643 }
644 }
645
646 bndcnt += m_bndCondExpansions[i]->GetNcoeffs();
647 }
648}
649
651 const Array<OneD, NekDouble> coeffs)
652{
653 int bndcnt = 0;
654
655 ASSERTL1(nreg < m_bndCondExpansions.size(),
656 "nreg is out or range since this many boundary "
657 "regions to not exist");
658
660 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsSign();
661 const Array<OneD, const int> bndmap =
662 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsMap();
663
664 // Now fill in all other Dirichlet coefficients.
665 Array<OneD, NekDouble> &bcoeffs = m_bndCondExpansions[nreg]->UpdateCoeffs();
666
667 for (int j = 0; j < nreg; ++j)
668 {
669 bndcnt += m_bndCondExpansions[j]->GetNcoeffs();
670 }
671
672 if (m_locToGloMap->GetSignChange())
673 {
674 for (int j = 0; j < (m_bndCondExpansions[nreg])->GetNcoeffs(); ++j)
675 {
676 bcoeffs[j] = sign[bndcnt + j] * coeffs[bndmap[bndcnt + j]];
677 }
678 }
679 else
680 {
681 for (int j = 0; j < (m_bndCondExpansions[nreg])->GetNcoeffs(); ++j)
682 {
683 bcoeffs[j] = coeffs[bndmap[bndcnt + j]];
684 }
685 }
686}
687
688/**
689 * This operation is evaluated as:
690 * \f{tabbing}
691 * \hspace{1cm} \= Do \= $e=$ $1, N_{\mathrm{el}}$ \\
692 * > > Do \= $i=$ $0,N_m^e-1$ \\
693 * > > > $\boldsymbol{\hat{u}}^{e}[i] = \mbox{sign}[e][i] \cdot
694 * \boldsymbol{\hat{u}}_g[\mbox{map}[e][i]]$ \\
695 * > > continue \\
696 * > continue
697 * \f}
698 * where \a map\f$[e][i]\f$ is the mapping array and \a
699 * sign\f$[e][i]\f$ is an array of similar dimensions ensuring the
700 * correct modal connectivity between the different elements (both
701 * these arrays are contained in the data member #m_locToGloMap). This
702 * operation is equivalent to the scatter operation
703 * \f$\boldsymbol{\hat{u}}_l=\mathcal{A}\boldsymbol{\hat{u}}_g\f$,
704 * where \f$\mathcal{A}\f$ is the
705 * \f$N_{\mathrm{eof}}\times N_{\mathrm{dof}}\f$ permutation matrix.
706 *
707 */
709 Array<OneD, NekDouble> &outarray)
710{
711 m_locToGloMap->GlobalToLocal(inarray, outarray);
712}
713
715{
716 m_locToGloMap->GlobalToLocal(m_coeffs, m_coeffs);
717}
718
719/**
720 * This operation is evaluated as:
721 * \f{tabbing}
722 * \hspace{1cm} \= Do \= $e=$ $1, N_{\mathrm{el}}$ \\
723 * > > Do \= $i=$ $0,N_m^e-1$ \\
724 * > > > $\boldsymbol{\hat{u}}_g[\mbox{map}[e][i]] +=
725 * \mbox{invMultiplicityWithign}[e][i] \cdot \boldsymbol{\hat{u}}^{e}[i]$\\
726 * > > continue\\
727 * > continue
728 * \f}
729 * where \a map\f$[e][i]\f$ is the mapping array and \a
730 * invMultiplicityWithSign\f$[e][i]\f$ is an array of similar dimensions
731 * ensuring the correct modal connectivity between the different elements
732 * divided by the multiplicity of the degree of freedom(both these arrays are
733 * contained in the data member #m_locToGloMap).
734 *
735 */
737 Array<OneD, NekDouble> &outarray, bool useComm)
738{
739 m_locToGloMap->AvgAssemble(inarray, outarray, useComm);
740}
741
742void ContField::v_AvgAssemble(bool useComm)
743
744{
745 m_locToGloMap->AvgAssemble(m_coeffs, m_coeffs, useComm);
746}
747
748/**
749 * This operation is evaluated as:
750 * \f{tabbing}
751 * \hspace{1cm} \= Do \= $e=$ $1, N_{\mathrm{el}}$ \\
752 * > > Do \= $i=$ $0,N_m^e-1$ \\
753 * > > > $\boldsymbol{\hat{u}}_g[\mbox{map}[e][i]] =
754 * \mbox{sign}[e][i] \cdot \boldsymbol{\hat{u}}^{e}[i]$\\
755 * > > continue\\
756 * > continue
757 * \f}
758 * where \a map\f$[e][i]\f$ is the mapping array and \a
759 * sign\f$[e][i]\f$ is an array of similar dimensions ensuring the
760 * correct modal connectivity between the different elements (both
761 * these arrays are contained in the data member #m_locToGloMap).
762 *
763 */
765 Array<OneD, NekDouble> &outarray, bool useComm)
766{
767 m_locToGloMap->LocalToGlobal(inarray, outarray, useComm);
768}
769
771
772{
773 m_locToGloMap->LocalToGlobal(m_coeffs, m_coeffs, useComm);
774}
775
776/**
777 * Consider the two dimensional Helmholtz equation,
778 * \f[\nabla^2u(\boldsymbol{x})-\lambda u(\boldsymbol{x})
779 * = f(\boldsymbol{x}),\f] supplemented with appropriate boundary
780 * conditions (which are contained in the data member
781 * #m_bndCondExpansions). Applying a \f$C^0\f$ continuous Galerkin
782 * discretisation, this equation leads to the following linear system:
783 * \f[\left(\boldsymbol{L}+\lambda\boldsymbol{M}\right)
784 * \boldsymbol{\hat{u}}_g=\boldsymbol{\hat{f}}\f] where
785 * \f$\boldsymbol{L}\f$ and \f$\boldsymbol{M}\f$ are the Laplacian and
786 * mass matrix respectively. This function solves the system above for
787 * the global coefficients \f$\boldsymbol{\hat{u}}\f$ by a call to the
788 * function #GlobalSolve.
789 *
790 * @param inarray An Array<OneD, NekDouble> , containing the discrete
791 * evaluation of the forcing function
792 * \f$f(\boldsymbol{x})\f$ at the quadrature
793 * points
794 * @param factors The parameter \f$\lambda\f$ of the Helmholtz
795 * equation is specified through the factors map
796 */
798 const Array<OneD, const NekDouble> &inarray,
799 Array<OneD, NekDouble> &outarray, const StdRegions::ConstFactorMap &factors,
800 const StdRegions::VarCoeffMap &pvarcoeff,
801 const StdRegions::VarFactorsMap &pvarfactors,
802 const Array<OneD, const NekDouble> &dirForcing, const bool PhysSpaceForcing)
803{
804 int i, j;
805
806 //----------------------------------
807 // Setup RHS Inner product
808 //----------------------------------
809 // Inner product of forcing
811 if (PhysSpaceForcing)
812 {
813 IProductWRTBase(inarray, wsp);
814 // Note -1.0 term necessary to invert forcing function to
815 // be consistent with matrix definition
816 Vmath::Neg(m_ncoeffs, wsp, 1);
817 }
818 else
819 {
820 Vmath::Smul(m_ncoeffs, -1.0, inarray, 1, wsp, 1);
821 }
822
823 int bndcnt = 0;
825 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsSign();
826 const Array<OneD, const int> map =
827 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsMap();
828 // Add weak boundary conditions to forcing
829 for (i = 0; i < m_bndCondExpansions.size(); ++i)
830 {
831 if (m_bndConditions[i]->GetBoundaryConditionType() ==
833 m_bndConditions[i]->GetBoundaryConditionType() ==
835 {
836
837 const Array<OneD, const NekDouble> bndcoeff =
839
840 if (m_locToGloMap->GetSignChange())
841 {
842 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
843 {
844 wsp[map[bndcnt + j]] += sign[bndcnt + j] * bndcoeff[j];
845 }
846 }
847 else
848 {
849 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
850 {
851 wsp[map[bndcnt + j]] += bndcoeff[j];
852 }
853 }
854 }
855 bndcnt += m_bndCondExpansions[i]->GetNcoeffs();
856 }
857
859
860 StdRegions::VarCoeffMap varcoeff(pvarcoeff);
861 StdRegions::VarFactorsMap varfactors(pvarfactors);
862 if (factors.count(StdRegions::eFactorGJP))
863 {
865 timer.Start();
866
867 // initialize if required
868 if (!m_GJPData)
869 {
872 }
873 timer.Stop();
874 timer.AccumulateRegion("GJP:Initialize", 10);
875
876 if (m_GJPData->IsSemiImplicit())
877 {
878 timer.Start();
880 // set up varcoeff
881
883 m_GJPData->GetTraceWeightVarFactors();
884 timer.Stop();
885 timer.AccumulateRegion("GJP:GetTraceWeights", 10);
886 }
887
888 // add GJP forcing if explicit of semi-implicit
889 if (m_GJPData->IsExplicit() || m_GJPData->IsSemiImplicit())
890 {
891 timer.Start();
892 // to set up forcing need initial guess in physical space
894 BwdTrans(outarray, phys);
895 NekDouble scale =
896 -1.0 * factors.find(StdRegions::eFactorGJP)->second;
897
898 m_GJPData->Apply(
899 phys, wsp,
900 pvarcoeff.count(StdRegions::eVarCoeffGJPNormVel)
901 ? pvarcoeff.find(StdRegions::eVarCoeffGJPNormVel)
902 ->second.GetValue()
904 scale);
905
906 varcoeff.erase(StdRegions::eVarCoeffGJPNormVel);
907 timer.Stop();
908 timer.AccumulateRegion("GJP:Apply", 10);
909 }
910
911 if (m_GJPData->IsImplicit())
912 {
913 timer.Start();
915 m_GJPData->GetTraceWeightVarFactors();
916 timer.Stop();
917 timer.AccumulateRegion("GJP:GetTraceWeights", 10);
918 }
919 }
920
921 GlobalLinSysKey key(mtype, m_locToGloMap, factors, varcoeff, varfactors);
922
923 GlobalSolve(key, wsp, outarray, dirForcing);
924
925 return key;
926}
927
928/**
929 * First compute the inner product of forcing function with respect to
930 * base, and then solve the system with the linear advection operator.
931 * @param velocity Array of advection velocities in physical space
932 * @param inarray Forcing function.
933 * @param outarray Result.
934 * @param lambda reaction coefficient
935 * @param dirForcing Dirichlet Forcing.
936 */
937
938// could combine this with HelmholtzCG.
940 const Array<OneD, const NekDouble> &inarray,
941 Array<OneD, NekDouble> &outarray, const StdRegions::ConstFactorMap &factors,
942 const StdRegions::VarCoeffMap &pvarcoeff,
943 const StdRegions::VarFactorsMap &pvarfactors,
944 const Array<OneD, const NekDouble> &dirForcing, const bool PhysSpaceForcing)
945{
946 // Inner product of forcing
948 if (PhysSpaceForcing)
949 {
950 IProductWRTBase(inarray, wsp);
951 // Note -1.0 term necessary to invert forcing function to
952 // be consistent with matrix definition
953 Vmath::Neg(m_ncoeffs, wsp, 1);
954 }
955 else
956 {
957 Vmath::Smul(m_ncoeffs, -1.0, inarray, 1, wsp, 1);
958 }
959
960 // Forcing function with weak boundary conditions
961 int i, j;
962 int bndcnt = 0;
964 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsSign();
965 const Array<OneD, const int> map =
966 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsMap();
967 // Add weak boundary conditions to forcing
968 for (i = 0; i < m_bndCondExpansions.size(); ++i)
969 {
970 if (m_bndConditions[i]->GetBoundaryConditionType() ==
972 m_bndConditions[i]->GetBoundaryConditionType() ==
974 {
975
976 const Array<OneD, const NekDouble> bndcoeff =
978
979 if (m_locToGloMap->GetSignChange())
980 {
981 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
982 {
983 wsp[map[bndcnt + j]] += sign[bndcnt + j] * bndcoeff[j];
984 }
985 }
986 else
987 {
988 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
989 {
990 wsp[map[bndcnt + j]] += bndcoeff[j];
991 }
992 }
993 }
994
995 bndcnt += m_bndCondExpansions[i]->GetNcoeffs();
996 }
997
1000
1001 StdRegions::VarCoeffMap varcoeff(pvarcoeff);
1002 StdRegions::VarFactorsMap varfactors(pvarfactors);
1003 if (factors.count(StdRegions::eFactorGJP))
1004 {
1005 LibUtilities::Timer timer;
1006 timer.Start();
1007
1008 // initialize if required
1009 if (!m_GJPData)
1010 {
1013 }
1014 timer.Stop();
1015 timer.AccumulateRegion("GJP:Initialize", 10);
1016
1017 if (m_GJPData->IsSemiImplicit())
1018 {
1019 timer.Start();
1021
1023 m_GJPData->GetTraceWeightVarFactors();
1024 timer.Stop();
1025 timer.AccumulateRegion("GJP:GetTraceWeights", 10);
1026 }
1027
1028 if (m_GJPData->IsExplicit() || m_GJPData->IsSemiImplicit())
1029 {
1030 timer.Start();
1031 // Set up forcing need initial guess in physical space
1033 BwdTrans(outarray, phys);
1034 NekDouble scale =
1035 -1.0 * factors.find(StdRegions::eFactorGJP)->second;
1036
1037 m_GJPData->Apply(
1038 phys, wsp,
1039 pvarcoeff.count(StdRegions::eVarCoeffGJPNormVel)
1040 ? pvarcoeff.find(StdRegions::eVarCoeffGJPNormVel)
1041 ->second.GetValue()
1043 scale);
1044 // erase VarCoeffGJPNormVel in temporary arrya so not used in key
1045 // below
1046 varcoeff.erase(StdRegions::eVarCoeffGJPNormVel);
1047 timer.Stop();
1048 timer.AccumulateRegion("GJP:Apply", 10);
1049 }
1050
1051 if (m_GJPData->IsImplicit())
1052 {
1053 timer.Start();
1055 m_GJPData->GetTraceWeightVarFactors();
1056 timer.Stop();
1057 timer.AccumulateRegion("GJP:GetTraceWeights", 10);
1058 }
1059 }
1060
1061 // Solve the system
1062 GlobalLinSysKey key(mtype, m_locToGloMap, factors, varcoeff, varfactors);
1063
1064 GlobalSolve(key, wsp, outarray, dirForcing);
1065
1066 return key;
1067}
1068
1069/**
1070 * First compute the inner product of forcing function with respect to
1071 * base, and then solve the system with the linear advection operator.
1072 * @param velocity Array of advection velocities in physical space
1073 * @param inarray Forcing function.
1074 * @param outarray Result.
1075 * @param lambda reaction coefficient
1076 * @param dirForcing Dirichlet Forcing.
1077 */
1079 const Array<OneD, const NekDouble> &inarray,
1080 Array<OneD, NekDouble> &outarray, const StdRegions::ConstFactorMap &factors,
1081 const StdRegions::VarCoeffMap &pvarcoeff,
1082 const StdRegions::VarFactorsMap &pvarfactors,
1083 const Array<OneD, const NekDouble> &dirForcing, const bool PhysSpaceForcing)
1084{
1085 // Inner product of forcing
1087 if (PhysSpaceForcing)
1088 {
1089 IProductWRTBase(inarray, wsp);
1090 // Note -1.0 term necessary to invert forcing function to
1091 // be consistent with matrix definition
1092 Vmath::Neg(m_ncoeffs, wsp, 1);
1093 }
1094 else
1095 {
1096 Vmath::Smul(m_ncoeffs, -1.0, inarray, 1, wsp, 1);
1097 }
1098
1099 // Forcing function with weak boundary conditions
1100 int i, j;
1101 int bndcnt = 0;
1103 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsSign();
1104 const Array<OneD, const int> map =
1105 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsMap();
1106 // Add weak boundary conditions to forcing
1107 for (i = 0; i < m_bndCondExpansions.size(); ++i)
1108 {
1109 if (m_bndConditions[i]->GetBoundaryConditionType() ==
1111 m_bndConditions[i]->GetBoundaryConditionType() ==
1113 {
1114
1115 const Array<OneD, const NekDouble> bndcoeff =
1117
1118 if (m_locToGloMap->GetSignChange())
1119 {
1120 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
1121 {
1122 wsp[map[bndcnt + j]] += sign[bndcnt + j] * bndcoeff[j];
1123 }
1124 }
1125 else
1126 {
1127 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
1128 {
1129 wsp[map[bndcnt + j]] += bndcoeff[j];
1130 }
1131 }
1132 }
1133
1134 bndcnt += m_bndCondExpansions[i]->GetNcoeffs();
1135 }
1136
1138
1139 StdRegions::VarCoeffMap varcoeff(pvarcoeff);
1140 StdRegions::VarFactorsMap varfactors(pvarfactors);
1141 if (factors.count(StdRegions::eFactorGJP))
1142 {
1143 LibUtilities::Timer timer;
1144 timer.Start();
1145
1146 // initialize if required
1147 if (!m_GJPData)
1148 {
1151 }
1152 timer.Stop();
1153 timer.AccumulateRegion("GJP:Initialize", 10);
1154
1155 if (m_GJPData->IsSemiImplicit())
1156 {
1157 timer.Start();
1158 ASSERTL0(false, "SemiImplicit GJPStabilisation not implemented for "
1159 "LinearAdvectionReactionSolve().")
1160
1162 m_GJPData->GetTraceWeightVarFactors();
1163 timer.Stop();
1164 timer.AccumulateRegion("GJP:GetTraceWeights", 10);
1165 }
1166
1167 if (m_GJPData->IsExplicit() || m_GJPData->IsSemiImplicit())
1168 {
1169 timer.Start();
1170 // Set up forcing need initial guess in physical space
1171 // add GJP forcing
1173 BwdTrans(outarray, phys);
1174 NekDouble scale =
1175 -1.0 * factors.find(StdRegions::eFactorGJP)->second;
1176
1177 m_GJPData->Apply(
1178 phys, wsp,
1179 pvarcoeff.count(StdRegions::eVarCoeffGJPNormVel)
1180 ? pvarcoeff.find(StdRegions::eVarCoeffGJPNormVel)
1181 ->second.GetValue()
1183 scale);
1184
1185 varcoeff.erase(StdRegions::eVarCoeffGJPNormVel);
1186 timer.Stop();
1187 timer.AccumulateRegion("GJP:Apply", 10);
1188 }
1189
1190 if (m_GJPData->IsImplicit())
1191 {
1192 timer.Start();
1194 m_GJPData->GetTraceWeightVarFactors();
1195 timer.Stop();
1196 timer.AccumulateRegion("GJP:GetTraceWeights", 10);
1197 }
1198 }
1199
1200 // Solve the system
1201 GlobalLinSysKey key(mtype, m_locToGloMap, factors, varcoeff, varfactors);
1202
1203 GlobalSolve(key, wsp, outarray, dirForcing);
1204
1205 return key;
1206}
1207
1208/**
1209 * Reset the GlobalLinSys Manager
1210 */
1212{
1213 m_globalLinSysManager.ClearManager("GlobalLinSys");
1214}
1215
1216/**
1217 * Get the pool count for the specified poolName
1218 */
1219int ContField::v_GetPoolCount(std::string poolName)
1220{
1221 return m_globalLinSysManager.PoolCount(poolName);
1222}
1223
1224/**
1225 * Clear all memory for GlobalLinSys
1226 * including StaticCond Blocks and LocalMatrix Blocks.
1227 * Avoids memory leakage if matrices are updated in time
1228 */
1230 bool clearLocalMatrices)
1231{
1232 // Get GlobalLinSys from key
1234
1235 // Loop all expansions
1236 for (int n = 0; n < m_exp->size(); ++n)
1237 {
1238 LinSys->DropStaticCondBlock(n);
1239
1240 if (clearLocalMatrices)
1241 {
1242 LinSys->DropBlock(n);
1243 }
1244 }
1245
1246 m_globalLinSysManager.DeleteObject(key);
1247}
1248
1250{
1251 int i, j;
1252 int bndcnt = 0;
1254 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsSign();
1255 const Array<OneD, const int> map =
1256 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsMap();
1257 // Add weak boundary conditions to forcing
1258 for (i = 0; i < m_bndCondExpansions.size(); ++i)
1259 {
1260 if (m_bndConditions[i]->GetBoundaryConditionType() ==
1262 {
1263
1264 const Array<OneD, const NekDouble> bndcoeff =
1266
1267 if (m_locToGloMap->GetSignChange())
1268 {
1269 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
1270 {
1271 outarray[map[bndcnt + j]] += sign[bndcnt + j] * bndcoeff[j];
1272 }
1273 }
1274 else
1275 {
1276 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
1277 {
1278 outarray[map[bndcnt + j]] += bndcoeff[j];
1279 }
1280 }
1281 }
1282 bndcnt += m_bndCondExpansions[i]->GetNcoeffs();
1283 }
1284}
1285
1287{
1288 int i, j;
1289 int bndcnt = 0;
1291 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsSign();
1292 const Array<OneD, const int> map =
1293 m_locToGloMap->GetBndCondCoeffsToLocalCoeffsMap();
1294 // Add weak boundary conditions to forcing
1295 for (i = 0; i < m_bndCondExpansions.size(); ++i)
1296 {
1297 if (m_bndConditions[i]->GetBoundaryConditionType() ==
1299 {
1300
1301 const Array<OneD, const NekDouble> bndcoeff =
1303
1304 if (m_locToGloMap->GetSignChange())
1305 {
1306 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
1307 {
1308 outarray[map[bndcnt + j]] += sign[bndcnt + j] * bndcoeff[j];
1309 }
1310 }
1311 else
1312 {
1313 for (j = 0; j < (m_bndCondExpansions[i])->GetNcoeffs(); j++)
1314 {
1315 outarray[map[bndcnt + j]] += bndcoeff[j];
1316 }
1317 }
1318 }
1319 bndcnt += m_bndCondExpansions[i]->GetNcoeffs();
1320 }
1321}
1322
1323} // namespace Nektar::MultiRegions
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define sign(a, b)
return the sign(b)*a
Definition Polylib.cpp:47
void AccumulateRegion(std::string, int iolevel=0)
Accumulate elapsed time for a region.
Definition Timer.cpp:70
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
This class is the abstraction of a global continuous two- dimensional spectral/hp element expansion w...
Definition ContField.h:55
~ContField() override
The default destructor.
void v_FillBndCondFromField(const Array< OneD, NekDouble > coeffs) override
LibUtilities::NekManager< GlobalLinSysKey, GlobalLinSys > m_globalLinSysManager
A manager which collects all the global linear systems being assembled, such that they should be cons...
Definition ContField.h:163
void v_ImposeRobinConditions(Array< OneD, NekDouble > &outarray) override
Add Robin Boundary Conditions forcing to outarray.
void LaplaceSolve(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray, const Array< OneD, Array< OneD, NekDouble > > &variablecoeffs=NullNekDoubleArrayOfArray, NekDouble time=0.0)
Solves the two-dimensional Laplace equation, subject to the boundary conditions specified.
GlobalLinSysKey v_LinearAdvectionDiffusionReactionSolve(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff, const StdRegions::VarFactorsMap &varfactors, const Array< OneD, const NekDouble > &dirForcing, const bool PhysSpaceForcing) override
GlobalLinSysSharedPtr GenGlobalLinSys(const GlobalLinSysKey &mkey)
AssemblyMapCGSharedPtr m_locToGloMap
(A shared pointer to) the object which contains all the required information for the transformation f...
Definition ContField.h:152
void v_FwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Template method virtual forwarder for FwdTrans().
int v_GetPoolCount(std::string) override
void v_SmoothField(Array< OneD, NekDouble > &field) override
Template method virtual forwarded for SmoothField().
GlobalLinSysKey v_HelmSolve(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff, const StdRegions::VarFactorsMap &varfactors, const Array< OneD, const NekDouble > &dirForcing, const bool PhysSpaceForcing) override
Solves the two-dimensional Helmholtz equation, subject to the boundary conditions specified.
void v_ClearGlobalLinSysManager(void) override
void v_GlobalToLocal(void) override
void v_UnsetGlobalLinSys(GlobalLinSysKey, bool) override
void v_LocalToGlobal(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool useComm) override
Gathers the global coefficients from the local coefficients .
GlobalLinSysKey v_LinearAdvectionReactionSolve(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff, const StdRegions::VarFactorsMap &varfactors, const Array< OneD, const NekDouble > &dirForcing, const bool PhysSpaceForcing) override
void v_ImposeNeumannConditions(Array< OneD, NekDouble > &outarray) override
Add Neumann Boundary Conditions forcing to outarray.
GlobalMatrixMapShPtr m_globalMat
(A shared pointer to) a list which collects all the global matrices being assembled,...
Definition ContField.h:157
void v_AvgAssemble(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, bool useComm) override
Assembly and average of the global coefficients from the local coefficients .
GlobalLinSysSharedPtr GetGlobalLinSys(const GlobalLinSysKey &mkey)
Returns the linear system specified by the key mkey.
void v_ImposeDirichletConditions(Array< OneD, NekDouble > &outarray) override
Impose the Dirichlet Boundary Conditions on outarray.
void v_MultiplyByInvMassMatrix(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray) override
Template method virtual forwarder for MultiplyByInvMassMatrix().
GlobalMatrixSharedPtr GetGlobalMatrix(const GlobalMatrixKey &mkey)
Returns the global matrix specified by mkey.
ContField()
The default constructor.
Definition ContField.cpp:87
void LinearAdvectionEigs(const NekDouble ax, const NekDouble ay, Array< OneD, NekDouble > &Real, Array< OneD, NekDouble > &Imag, Array< OneD, NekDouble > &Evecs=NullNekDouble1DArray)
Compute the eigenvalues of the linear advection operator.
void GlobalSolve(const GlobalLinSysKey &key, const Array< OneD, const NekDouble > &rhs, Array< OneD, NekDouble > &inout, const Array< OneD, const NekDouble > &dirForcing=NullNekDouble1DArray)
Solves the linear system specified by the key key.
GJPStabilisationSharedPtr m_GJPData
Data for Gradient Jump Penalisation (GJP) stabilisaiton.
Definition ContField.h:166
This class is the abstractio n of a global discontinuous two- dimensional spectral/hp element expansi...
PeriodicMap m_periodicEdges
A map which identifies pairs of periodic edges.
PeriodicMap m_periodicFaces
A map which identifies pairs of periodic faces.
bool SameTypeOfBoundaryConditions(const DisContField &In)
Check to see if expansion has the same BCs as In.
Array< OneD, SpatialDomains::BoundaryConditionShPtr > m_bndConditions
An array which contains the information about the boundary condition structure definition on the diff...
PeriodicMap m_periodicVerts
A map which identifies groups of periodic vertices.
Array< OneD, MultiRegions::ExpListSharedPtr > m_bndCondExpansions
An object which contains the discretised boundary conditions.
Base class for all multi-elemental spectral/hp expansions.
Definition ExpList.h:98
Array< OneD, NekDouble > m_coeffs
Concatenation of all local expansion coefficients.
Definition ExpList.h:1149
void IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function calculates the inner product of a function with respect to all local expansion modes .
Definition ExpList.h:1749
int GetNcoeffs(void) const
Returns the total number of local degrees of freedom .
Definition ExpList.h:1607
std::shared_ptr< GlobalLinSys > GenGlobalLinSys(const GlobalLinSysKey &mkey, const std::shared_ptr< AssemblyMapCG > &locToGloMap)
This operation constructs the global linear system of type mkey.
std::shared_ptr< DNekMat > GenGlobalMatrixFull(const GlobalLinSysKey &mkey, const std::shared_ptr< AssemblyMapCG > &locToGloMap)
const Array< OneD, const NekDouble > & GetCoeffs() const
This function returns (a reference to) the array (implemented as m_coeffs) containing all local expa...
Definition ExpList.h:2046
std::shared_ptr< ExpList > GetSharedThisPtr()
Returns a shared pointer to the current object.
Definition ExpList.h:985
std::shared_ptr< LocalRegions::ExpansionVector > m_exp
The list of local expansions.
Definition ExpList.h:1184
int m_ncoeffs
The total number of local degrees of freedom. m_ncoeffs .
Definition ExpList.h:1129
LibUtilities::SessionReaderSharedPtr m_session
Session.
Definition ExpList.h:1124
void MultiplyByInvMassMatrix(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
Definition ExpList.h:1824
void BwdTrans(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray)
This function elementally evaluates the backward transformation of the global spectral/hp element exp...
Definition ExpList.h:1816
std::shared_ptr< GlobalMatrix > GenGlobalMatrix(const GlobalMatrixKey &mkey, const std::shared_ptr< AssemblyMapCG > &locToGloMap)
Generates a global matrix from the given key and map.
Describes a matrix with ordering defined by a local to global map.
bool LocToGloMapIsDefined() const
Returns true if a local to global map is defined.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< GlobalLinSys > GlobalLinSysSharedPtr
Pointer to a GlobalLinSys object.
std::shared_ptr< GlobalMatrix > GlobalMatrixSharedPtr
Shared pointer to a GlobalMatrix object.
std::map< GlobalMatrixKey, GlobalMatrixSharedPtr > GlobalMatrixMap
Mapping from global matrix keys to global matrices.
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition MeshGraph.h:224
std::map< StdRegions::ConstFactorType, Array< OneD, NekDouble > > VarFactorsMap
std::map< ConstFactorType, NekDouble > ConstFactorMap
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
static Array< OneD, NekDouble > NullNekDouble1DArray
std::shared_ptr< DNekMat > DNekMatSharedPtr
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition Vmath.hpp:292
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition Vmath.hpp:100
STL namespace.