Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DisContField1D.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // File DisContField1D.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: Field definition for 1D domain with boundary
33 // conditions using LDG-H
34 //
35 ///////////////////////////////////////////////////////////////////////////////
36 
38 #include <StdRegions/StdSegExp.h>
41 
42 namespace Nektar
43 {
44  namespace MultiRegions
45  {
46  /**
47  * @class DisContField1D
48  * This class augments the list of local expansions inherited from
49  * ExpList1D with boundary conditions. Inter-element boundaries are
50  * handled using an discontinuous Galerkin scheme.
51  */
52 
53  /**
54  * Constructs an empty expansion list with no boundary conditions.
55  */
57  ExpList1D(),
58  m_bndCondExpansions(),
59  m_bndConditions()
60  {
61  }
62 
63 
64  /**
65  * An expansion list for the boundary expansions is generated first for
66  * the field. These are subsequently evaluated for time zero. The trace
67  * map is then constructed.
68  * @param graph1D A mesh, containing information about the domain
69  * and the spectral/hp element expansions.
70  * @param bcs Information about the enforced boundary
71  * conditions.
72  * @param variable The session variable associated with the
73  * boundary conditions to enforce.
74  * @param solnType Type of global system to use.
75  */
79  const std::string &variable,
80  const bool SetUpJustDG)
81  : ExpList1D(pSession,graph1D),
82  m_bndCondExpansions(),
83  m_bndConditions()
84  {
86 
87  GenerateBoundaryConditionExpansion(graph1D,bcs,variable);
88  EvaluateBoundaryConditions(0.0, variable);
89  ApplyGeomInfo();
90  FindPeriodicVertices(bcs,variable);
91 
92  if(SetUpJustDG)
93  {
94  SetUpDG(variable);
95  }
96  else
97  {
98  int i;
99  Array<OneD, int> ElmtID, VertexID;
100  GetBoundaryToElmtMap(ElmtID, VertexID);
101 
102  for(i = 0; i < m_bndCondExpansions.num_elements(); ++i)
103  {
105  locExpList = m_bndCondExpansions[i];
106 
108  (*m_exp)[ElmtID[i]]->
109  as<LocalRegions::Expansion1D>();
111  locExpList->GetExp(0)->
112  as<LocalRegions::Expansion0D>();
113 
114  exp0d->SetAdjacentElementExp(VertexID[i], exp1d);
115  }
116 
118  }
119 
120  }
121 
122  void DisContField1D::SetUpDG(const std::string &variable)
123  {
124  // Check for multiple calls
126  {
127  return;
128  }
129 
131  boost::dynamic_pointer_cast<SpatialDomains::MeshGraph1D>(
132  m_graph);
133 
135 
140  *m_exp,graph1D,
142 
143  m_trace = boost::dynamic_pointer_cast<ExpList>(trace);
144 
146  AllocateSharedPtr(m_session, graph1D, trace, *this,
148  m_periodicVerts, variable);
149 
150  // Scatter trace points to 1D elements. For each element, we find
151  // the trace point associated to each vertex. The element then
152  // retains a pointer to the trace space points, to ensure
153  // uniqueness of normals when retrieving from two adjoining
154  // elements which do not lie in a plane.
155 
156  int ElmtPointGeom = 0;
157  int TracePointGeom = 0;
160  for (int i = 0; i < m_exp->size(); ++i)
161  {
162  exp1d = (*m_exp)[i]->as<LocalRegions::Expansion1D>();
163  for (int j = 0; j < exp1d->GetNverts(); ++j)
164  {
165  ElmtPointGeom = (exp1d->GetGeom1D())->GetVid(j);
166 
167  for (int k = 0; k < m_trace->GetExpSize(); ++k)
168  {
169  TracePointGeom = m_trace->GetExp(k)->GetGeom()->GetVid(0);
170 
171  if (TracePointGeom == ElmtPointGeom)
172  {
173  exp0d = m_trace->GetExp(k)->as<LocalRegions::Expansion0D>();
174  exp0d->SetAdjacentElementExp(j,exp1d);
175  break;
176  }
177  }
178  }
179  }
180 
182 
183  int cnt, n, e;
184 
185  // Identify boundary verts
186  for(cnt = 0, n = 0; n < m_bndCondExpansions.num_elements(); ++n)
187  {
188  if (m_bndConditions[n]->GetBoundaryConditionType() !=
190  {
191  for(e = 0; e < m_bndCondExpansions[n]->GetExpSize(); ++e)
192  {
193  m_boundaryVerts.insert(
194  m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt+e));
195  }
196  }
197  else
198  {
199  ASSERTL0(false,"Periodic verts need setting up");
200  }
201  cnt += m_bndCondExpansions[n]->GetExpSize();
202  }
203 
204  // Set up left-adjacent edge list.
205  m_leftAdjacentVerts.resize(2*((*m_exp).size()));
206 
207  // count size of trace
208  for (cnt = n = 0; n < m_exp->size(); ++n)
209  {
210  for (int v = 0; v < (*m_exp)[n]->GetNverts(); ++v, ++cnt)
211  {
213  }
214  }
215 
216 
217  boost::unordered_map<int,pair<int,int> > perVertToExpMap;
218  boost::unordered_map<int,pair<int,int> >::iterator it2;
219  for (n = 0; n < m_exp->size(); ++n)
220  {
221  for (int v = 0; v < (*m_exp)[n]->GetNverts(); ++v)
222  {
224  (*m_exp)[n]->GetGeom()->GetVid(v));
225 
226  if (it != m_periodicVerts.end())
227  {
228  perVertToExpMap[it->first] = make_pair(n,v);
229  }
230  }
231  }
232 
233 
234  // Set up mapping to copy Fwd of periodic bcs to Bwd of other edge.
235  for (n = 0; n < m_exp->size(); ++n)
236  {
237  for (int v = 0; v < (*m_exp)[n]->GetNverts(); ++v)
238  {
239  int vertGeomId = (*m_exp)[n]->GetGeom()->GetVid(v);
240 
241  // Check to see if this face is periodic.
242  PeriodicMap::iterator it = m_periodicVerts.find(vertGeomId);
243 
244  if (it != m_periodicVerts.end())
245  {
246  const PeriodicEntity &ent = it->second[0];
247  it2 = perVertToExpMap.find(ent.id);
248 
249  if (it2 == perVertToExpMap.end())
250  {
251  if (m_session->GetComm()->GetRowComm()->GetSize() > 1 &&
252  !ent.isLocal)
253  {
254  continue;
255  }
256  else
257  {
258  ASSERTL1(false, "Periodic vert not found!");
259  }
260  }
261 
262  int offset = m_trace->GetPhys_Offset((m_traceMap->GetElmtToTrace())
263  [n][v]->GetElmtId());
264  m_periodicFwdCopy.push_back(offset);
265 
266  int offset2 = m_trace->GetPhys_Offset((m_traceMap->GetElmtToTrace())
267  [it2->second.first]
268  [it2->second.second]->GetElmtId());
269  m_periodicBwdCopy.push_back(offset2);
270  }
271  }
272  }
273  }
274 
275 
276  bool DisContField1D::IsLeftAdjacentVertex(const int n, const int e)
277  {
280  m_traceMap->GetElmtToTrace()[n][e]->as<LocalRegions::Expansion0D>();
281 
282 
283  bool fwd = true;
284  if (traceEl->GetLeftAdjacentElementVertex () == -1 ||
285  traceEl->GetRightAdjacentElementVertex() == -1)
286  {
287  // Boundary edge (1 connected element). Do nothing in
288  // serial.
289  it = m_boundaryVerts.find(traceEl->GetElmtId());
290 
291  // If the edge does not have a boundary condition set on
292  // it, then assume it is a partition edge or periodic.
293  if (it == m_boundaryVerts.end())
294  {
295  int traceGeomId = traceEl->GetGeom0D()->GetGlobalID();
297  traceGeomId);
298 
299  if (pIt != m_periodicVerts.end() && !pIt->second[0].isLocal)
300  {
301  fwd = traceGeomId == min(traceGeomId,pIt->second[0].id);
302  }
303  else
304  {
305  int offset = m_trace->GetPhys_Offset(traceEl->GetElmtId());
306  fwd = m_traceMap->
307  GetTraceToUniversalMapUnique(offset) >= 0;
308  }
309  }
310  }
311  else if (traceEl->GetLeftAdjacentElementVertex () != -1 &&
312  traceEl->GetRightAdjacentElementVertex() != -1)
313  {
314  // Non-boundary edge (2 connected elements).
315  fwd = dynamic_cast<Nektar::StdRegions::StdExpansion*>
316  (traceEl->GetLeftAdjacentElementExp().get()) ==
317  (*m_exp)[n].get();
318  }
319  else
320  {
321  ASSERTL2(false, "Unconnected trace element!");
322  }
323 
324  return fwd;
325  }
326 
327 
328  // Given all boundary regions for the whole solution determine
329  // which ones (if any) are part of domain and ensure all other
330  // conditions are given as UserDefined Dirichlet.
332  const SpatialDomains::CompositeMap &domain,
334  const std::string &variable)
335  {
337 
339 
341  map<int,int> GeometryToRegionsMap;
342 
343  SpatialDomains::BoundaryRegionCollection::const_iterator it;
344 
346  = Allbcs.GetBoundaryRegions();
348  = Allbcs.GetBoundaryConditions();
349 
350  // Set up a map of all boundary regions
351  for(it = bregions.begin(); it != bregions.end(); ++it)
352  {
354  for (bregionIt = it->second->begin();
355  bregionIt != it->second->end(); bregionIt++)
356  {
357  // can assume that all regions only contain one point in 1D
358  // Really do not need loop above
359  int id = (*(bregionIt->second))[0]->GetGlobalID();
360  GeometryToRegionsMap[id] = it->first;
361  }
362  }
363 
365  map<int,SpatialDomains::GeometrySharedPtr> EndOfDomain;
366 
367  // Now find out which points in domain have only one vertex
368  for(domIt = domain.begin(); domIt != domain.end(); ++domIt)
369  {
370  SpatialDomains::Composite geomvector = domIt->second;
371  for(int i = 0; i < geomvector->size(); ++i)
372  {
373  for(int j = 0; j < 2; ++j)
374  {
375  int vid = (*geomvector)[i]->GetVid(j);
376  if(EndOfDomain.count(vid) == 0)
377  {
378  EndOfDomain[vid] = (*geomvector)[i]->GetVertex(j);
379  }
380  else
381  {
382  EndOfDomain.erase(vid);
383  }
384  }
385  }
386  }
387  ASSERTL1(EndOfDomain.size() == 2,"Did not find two ends of domain");
388 
390  int numNewBc = 1;
391  for(regIt = EndOfDomain.begin(); regIt != EndOfDomain.end(); ++regIt)
392  {
393  if(GeometryToRegionsMap.count(regIt->first) != 0) // Set up boundary condition up
394  {
395  map<int,int>::iterator iter = GeometryToRegionsMap.find(regIt->first);
396  ASSERTL1(iter != GeometryToRegionsMap.end(),"Failied to find GeometryToRegionMap");
397  int regionId = iter->second;
398  SpatialDomains::BoundaryRegionCollection::const_iterator bregionsIter = bregions.find(regionId);
399  ASSERTL1(bregionsIter != bregions.end(),"Failed to find boundary region");
400  SpatialDomains::BoundaryRegionShPtr breg = bregionsIter->second;
401  returnval->AddBoundaryRegions (regionId,breg);
402 
403  SpatialDomains::BoundaryConditionCollection::const_iterator bconditionsIter = bconditions.find(regionId);
404  ASSERTL1(bconditionsIter != bconditions.end(),"Failed to find boundary collection");
405  SpatialDomains::BoundaryConditionMapShPtr bcond = bconditionsIter->second;
406  returnval->AddBoundaryConditions(regionId,bcond);
407  }
408  else // Set up an undefined region.
409  {
411 
412  // Set up Composite (GemetryVector) to contain vertex and put into bRegion
414  gvec->push_back(regIt->second);
415  (*breg)[regIt->first] = gvec;
416 
417  returnval->AddBoundaryRegions(bregions.size()+numNewBc,breg);
418 
420 
421  // Set up just boundary condition for this variable.
423  (*bCondition)[variable] = notDefinedCondition;
424 
425  returnval->AddBoundaryConditions(bregions.size()+numNewBc,bCondition);
426  ++numNewBc;
427 
428  }
429  }
430 
431  return returnval;
432  }
433 
434  /**
435  * Constructor for use in multidomain computations where a
436  * domain list can be passed instead of graph1D
437  *
438  * @param domain Subdomain specified in the inputfile from
439  * which the DisContField1D is set up
440  */
442  const LibUtilities::SessionReaderSharedPtr &pSession,
443  const SpatialDomains::MeshGraphSharedPtr &graph1D,
444  const SpatialDomains::CompositeMap &domain,
445  const SpatialDomains::BoundaryConditions &Allbcs,
446  const std::string &variable,
447  bool SetToOneSpaceDimension):
448  ExpList1D(pSession,graph1D,domain, true,variable,SetToOneSpaceDimension),
449  m_bndCondExpansions(),
450  m_bndConditions()
451  {
452  SpatialDomains::BoundaryConditionsSharedPtr DomBCs = GetDomainBCs(domain,Allbcs,variable);
453 
454  GenerateBoundaryConditionExpansion(graph1D,*DomBCs,variable);
455  EvaluateBoundaryConditions(0.0, variable);
456  ApplyGeomInfo();
457  FindPeriodicVertices(*DomBCs,variable);
458 
459  SetUpDG(variable);
460  }
461 
462  /**
463  * Constructs a field as a copy of an existing field.
464  * @param In Existing DisContField1D object to copy.
465  */
467  ExpList1D(In),
468  m_bndCondExpansions(In.m_bndCondExpansions),
469  m_bndConditions(In.m_bndConditions),
470  m_globalBndMat(In.m_globalBndMat),
471  m_trace(In.m_trace),
472  m_traceMap(In.m_traceMap),
473  m_boundaryVerts(In.m_boundaryVerts),
474  m_periodicVerts(In.m_periodicVerts),
475  m_periodicFwdCopy(In.m_periodicFwdCopy),
476  m_periodicBwdCopy(In.m_periodicBwdCopy),
477  m_leftAdjacentVerts(In.m_leftAdjacentVerts)
478  {
479  }
480 
481 
482  /**
483  * Constructs a field as a copy of an existing explist1D field.
484  * @param In Existing ExpList1D object to copy.
485  */
487  ExpList1D(In)
488  {
489  }
490 
491  /**
492  *
493  */
495  {
496  }
497 
498 
499  /**
500  * Generate the boundary condition expansion list
501  * @param graph1D A mesh, containing information about the domain
502  * and the spectral/hp element expansions.
503  * @param bcs Information about the enforced boundary
504  * conditions.
505  * @param variable The session variable associated with the
506  * boundary conditions to enforce.
507  */
509  const SpatialDomains::MeshGraphSharedPtr &graph1D,
511  const std::string variable)
512  {
513  int cnt = 0;
514 
516  = bcs.GetBoundaryRegions();
518  = bcs.GetBoundaryConditions();
519  SpatialDomains::BoundaryRegionCollection::const_iterator it;
520 
521  // count the number of non-periodic boundary points
522  for (it = bregions.begin(); it != bregions.end(); ++it)
523  {
524  const SpatialDomains::BoundaryConditionShPtr boundaryCondition =
525  GetBoundaryCondition(bconditions, it->first, variable);
526  if (boundaryCondition->GetBoundaryConditionType() !=
528  {
530  for (bregionIt = it->second->begin();
531  bregionIt != it->second->end(); bregionIt++)
532  {
533  cnt += bregionIt->second->size();
534  }
535  }
536  }
537 
540 
543 
544  SetBoundaryConditionExpansion(graph1D,bcs,variable,
546  m_bndConditions);
547  }
548 
549 
550  /**
551  * @param graph1D A mesh containing information about the domain
552  * and the spectral/hp element expansion.
553  * @param bcs Information about the boundary conditions.
554  * @param variable Specifies the field.
555  * @param periodicVertices Map into which the list of periodic
556  * vertices is placed.
557  */
560  const std::string variable)
561  {
563  = bcs.GetBoundaryRegions();
565  = bcs.GetBoundaryConditions();
566 
568  = boost::dynamic_pointer_cast<
570  SpatialDomains::BoundaryRegionCollection::const_iterator it;
571 
573  m_session->GetComm()->GetRowComm();
574 
575  int i, region1ID, region2ID;
576 
578 
579  map<int,int> BregionToVertMap;
580 
581  // Construct list of all periodic Region and their global vertex on
582  // this process.
583  for (it = bregions.begin(); it != bregions.end(); ++it)
584  {
585  locBCond = GetBoundaryCondition(bconditions, it->first, variable);
586 
587  if (locBCond->GetBoundaryConditionType()
589  {
590  continue;
591  }
592 
593  int id = (*(it->second->begin()->second))[0]->GetGlobalID();
594 
595  BregionToVertMap[it->first] = id;
596  }
597 
599  set<int> islocal;
600 
601  int n = vComm->GetSize();
602  int p = vComm->GetRank();
603 
604  Array<OneD, int> nregions(n, 0);
605  nregions[p] = BregionToVertMap.size();
606  vComm->AllReduce(nregions, LibUtilities::ReduceSum);
607 
608  int totRegions = Vmath::Vsum(n, nregions, 1);
609 
610  Array<OneD, int> regOffset(n, 0);
611 
612  for (i = 1; i < n; ++i)
613  {
614  regOffset[i] = regOffset[i-1] + nregions[i-1];
615  }
616 
617  Array<OneD, int> bregmap(totRegions, 0);
618  Array<OneD, int> bregid (totRegions, 0);
619  for(i = regOffset[p], iit = BregionToVertMap.begin();
620  iit != BregionToVertMap.end(); ++iit, ++i)
621  {
622  bregid [i] = iit->first;
623  bregmap[i] = iit->second;
624  islocal.insert(iit->first);
625  }
626 
627  vComm->AllReduce(bregmap, LibUtilities::ReduceSum);
628  vComm->AllReduce(bregid, LibUtilities::ReduceSum);
629 
630  for (int i = 0; i < totRegions; ++i)
631  {
632  BregionToVertMap[bregid[i]] = bregmap[i];
633  }
634 
635  // Construct list of all periodic pairs local to this process.
636  for (it = bregions.begin(); it != bregions.end(); ++it)
637  {
638  locBCond = GetBoundaryCondition(bconditions, it->first, variable);
639 
640  if (locBCond->GetBoundaryConditionType()
642  {
643  continue;
644  }
645 
646  // Identify periodic boundary region IDs.
647  region1ID = it->first;
648  region2ID = boost::static_pointer_cast<
650  locBCond)->m_connectedBoundaryRegion;
651 
652  ASSERTL0(BregionToVertMap.count(region1ID) != 0,
653  "Cannot determine vertex of region1ID");
654 
655  ASSERTL0(BregionToVertMap.count(region2ID) != 0,
656  "Cannot determine vertex of region2ID");
657 
658  PeriodicEntity ent(BregionToVertMap[region2ID],
660  islocal.count(region2ID) != 0);
661 
662  m_periodicVerts[BregionToVertMap[region1ID]].push_back(ent);
663  }
664  }
665 
666 
667  /**
668  * @param graph1D A mesh containing information about the domain
669  * and the Spectral/hp element expansion.
670  * @param bcs Information about the boundary conditions.
671  * @param variable Specifies the field.
672  * @param bndCondExpansions Array of ExpList1D objects each
673  * containing a 1D spectral/hp element expansion
674  * on a single boundary region.
675  * @param bncConditions Array of BoundaryCondition objects which
676  * contain information about the boundary
677  * conditions on the different boundary regions.
678  */
680  const SpatialDomains::MeshGraphSharedPtr &graph1D,
682  const std::string variable,
684  &bndCondExpansions,
685  Array<OneD, SpatialDomains
686  ::BoundaryConditionShPtr> &bndConditions)
687  {
688  int k;
689  int cnt = 0;
690 
692  = bcs.GetBoundaryRegions();
694  = bcs.GetBoundaryConditions();
695  SpatialDomains::BoundaryRegionCollection::const_iterator it;
696 
700 
701  cnt = 0;
702  // list Dirichlet boundaries first
703  for (it = bregions.begin(); it != bregions.end(); ++it)
704  {
705  locBCond = GetBoundaryCondition(
706  bconditions, it->first, variable);
707 
708  if (locBCond->GetBoundaryConditionType() ==
710 
711  {
713  for (bregionIt = it->second->begin();
714  bregionIt != it->second->end(); bregionIt++)
715  {
716  for (k = 0; k < bregionIt->second->size(); k++)
717  {
718  if ((vert = boost::dynamic_pointer_cast
720  (*bregionIt->second)[k])))
721  {
722  locPointExp
725  bndCondExpansions[cnt] = locPointExp;
726  bndConditions[cnt++] = locBCond;
727  }
728  else
729  {
730  ASSERTL0(false,
731  "dynamic cast to a vertex failed");
732  }
733  }
734  }
735  }
736  } // end if Dirichlet
737 
738  // then, list the other (non-periodic) boundaries
739  for (it = bregions.begin(); it != bregions.end(); ++it)
740  {
741  locBCond = GetBoundaryCondition(bconditions, it->first, variable);
742 
743  switch(locBCond->GetBoundaryConditionType())
744  {
747  case SpatialDomains::eNotDefined: // presume this will be reused as Neuman, Robin or Dirichlet later
748  {
750  for (bregionIt = it->second->begin();
751  bregionIt != it->second->end(); bregionIt++)
752  {
753  for (k = 0; k < bregionIt->second->size(); k++)
754  {
755  if((vert = boost::dynamic_pointer_cast
757  (*bregionIt->second)[k])))
758  {
759  locPointExp
762  bndCondExpansions[cnt] = locPointExp;
763  bndConditions[cnt++] = locBCond;
764  }
765  else
766  {
767  ASSERTL0(false,
768  "dynamic cast to a vertex failed");
769  }
770  }
771  }
772  }
773  // do nothing for these types
776  break;
777  default:
778  ASSERTL0(false,"This type of BC not implemented yet");
779  break;
780  }
781  }
782  }
783 
784  /**
785  *
786  */
788  const GlobalLinSysKey &mkey)
789  {
791  "Routine currently only tested for HybridDGHelmholtz");
792 
794  "Full matrix global systems are not supported for HDG "
795  "expansions");
796 
798  ==m_traceMap->GetGlobalSysSolnType(),
799  "The local to global map is not set up for the requested "
800  "solution type");
801 
802  GlobalLinSysSharedPtr glo_matrix;
803  GlobalLinSysMap::iterator matrixIter = m_globalBndMat->find(mkey);
804 
805  if (matrixIter == m_globalBndMat->end())
806  {
807  glo_matrix = GenGlobalBndLinSys(mkey,m_traceMap);
808  (*m_globalBndMat)[mkey] = glo_matrix;
809  }
810  else
811  {
812  glo_matrix = matrixIter->second;
813  }
814 
815  return glo_matrix;
816  }
817 
818 
820  {
821  if(m_negatedFluxNormal.size() == 0)
822  {
824  &elmtToTrace = m_traceMap->GetElmtToTrace();
825 
826  m_negatedFluxNormal.resize(2*GetExpSize());
827 
828  for(int i = 0; i < GetExpSize(); ++i)
829  {
830 
831  for(int v = 0; v < 2; ++v)
832  {
833 
835  elmtToTrace[i][v]->as<LocalRegions::Expansion0D>();
836 
837  if(vertExp->GetLeftAdjacentElementExp()->GetGeom()->GetGlobalID() != (*m_exp)[i]->GetGeom()->GetGlobalID())
838  {
839  m_negatedFluxNormal[2*i+v] = true;
840  }
841  else
842  {
843  m_negatedFluxNormal[2*i+v] = false;
844  }
845  }
846  }
847 
848  }
849 
850  return m_negatedFluxNormal;
851  }
852 
853  /**
854  * Generate the forward or backward state for each trace point.
855  * @param Fwd Forward state.
856  * @param Bwd Backward state.
857  */
860  {
861  v_GetFwdBwdTracePhys(m_phys,Fwd,Bwd);
862  }
863 
864 
865  /**
866  * @brief This method extracts the "forward" and "backward" trace data
867  * from the array @a field and puts the data into output vectors @a Fwd
868  * and @a Bwd.
869  *
870  * We first define the convention which defines "forwards" and
871  * "backwards". First an association is made between the vertex of each
872  * element and its corresponding vertex in the trace space using the
873  * mapping #m_traceMap. The element can either be left-adjacent or
874  * right-adjacent to this trace edge (see
875  * Expansion0D::GetLeftAdjacentElementExp). Boundary edges are never
876  * left-adjacent since elemental left-adjacency is populated first.
877  *
878  * If the element is left-adjacent we extract the vertex trace data from
879  * @a field into the forward trace space @a Fwd; otherwise, we place it
880  * in the backwards trace space @a Bwd. In this way, we form a unique
881  * set of trace normals since these are always extracted from
882  * left-adjacent elements.
883  *
884  * @param field is a NekDouble array which contains the 1D data
885  * from which we wish to extract the backward and forward
886  * orientated trace/edge arrays.
887  * @param Fwd The resulting forwards space.
888  * @param Bwd The resulting backwards space.
889  */
890 
892  const Array<OneD, const NekDouble> &field,
895  {
896  // Expansion casts
900 
901  // Counter variables
902  int n, v;
903 
904  // Number of elements
905  int nElements = GetExpSize();
906 
907  // Initial index of each element
908  int phys_offset;
909 
911  &elmtToTrace = m_traceMap->GetElmtToTrace();
912 
913  // Basis shared pointer
915 
916  // Set forward and backard state to zero
917  Vmath::Zero(Fwd.num_elements(), Fwd, 1);
918  Vmath::Zero(Bwd.num_elements(), Bwd, 1);
919 
920  int cnt;
921 
922  // Loop on the elements
923  for (cnt = n = 0; n < nElements; ++n)
924  {
925  exp1D = (*m_exp)[n]->as<LocalRegions::Expansion1D>();
926 
927  // Set the offset of each element
928  phys_offset = GetPhys_Offset(n);
929 
930  Basis = (*m_exp)[n]->GetBasis(0);
931 
932  for(v = 0; v < 2; ++v, ++cnt)
933  {
934  int offset = m_trace->GetPhys_Offset(elmtToTrace[n][v]->GetElmtId());
935 
936  if (m_leftAdjacentVerts[cnt])
937  {
938  (*m_exp)[n]->GetVertexPhysVals(v, field + phys_offset,
939  Fwd[offset]);
940  }
941  else
942  {
943  (*m_exp)[n]->GetVertexPhysVals(v, field + phys_offset,
944  Bwd[offset]);
945  }
946  }
947  }
948 
949  // Fill boundary conditions into missing elements.
950  int id = 0;
951 
952  for(cnt = n = 0; n < m_bndCondExpansions.num_elements(); ++n)
953  {
954  if (m_bndConditions[n]->GetBoundaryConditionType() ==
956  {
957  id = m_trace->GetPhys_Offset(m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt));
958  Bwd[id] = m_bndCondExpansions[n]->GetPhys()[0]; //this is not getting the correct value?
959  cnt++;
960  }
961  else if (m_bndConditions[n]->GetBoundaryConditionType() ==
963  m_bndConditions[n]->GetBoundaryConditionType() ==
965  {
966  ASSERTL0((m_bndCondExpansions[n]->GetPhys())[0]==0.0,
967  "Method not set up for non-zero Neumann "
968  "boundary condition");
969  id = m_trace->GetPhys_Offset(m_traceMap->GetBndCondTraceToGlobalTraceMap(cnt));
970  Bwd[id] = Fwd[id];
971 
972  cnt++;
973  }
974  else if (m_bndConditions[n]->GetBoundaryConditionType() ==
976  {
977  // Do nothing
978  }
979  else if (m_bndConditions[n]->GetBoundaryConditionType() !=
981  {
982  ASSERTL0(false,
983  "Method not set up for this boundary condition.");
984  }
985  }
986 
987  // Copy any periodic boundary conditions.
988  for (n = 0; n < m_periodicFwdCopy.size(); ++n)
989  {
990  Bwd[m_periodicBwdCopy[n]] = Fwd[m_periodicFwdCopy[n]];
991  }
992 
993  // Do parallel exchange for forwards/backwards spaces.
994  m_traceMap->UniversalTraceAssemble(Fwd);
995  m_traceMap->UniversalTraceAssemble(Bwd);
996 
997  }
998 
999 
1001  Array<OneD, NekDouble> &outarray)
1002  {
1003  ASSERTL1(m_physState == true,"local physical space is not true ");
1004  v_ExtractTracePhys(m_phys, outarray);
1005  }
1006 
1007  /**
1008  * @brief This method extracts the trace (verts in 1D) from the field @a
1009  * inarray and puts the values in @a outarray.
1010  *
1011  * It assumes the field is C0 continuous so that it can overwrite the
1012  * edge data when visited by the two adjacent elements.
1013  *
1014  * @param inarray An array containing the 1D data from which we wish
1015  * to extract the edge data.
1016  * @param outarray The resulting edge information.
1017  *
1018  * This will not work for non-boundary expansions
1019  */
1021  const Array<OneD, const NekDouble> &inarray,
1022  Array<OneD, NekDouble> &outarray)
1023  {
1024  // Loop over elemente and collect forward expansion
1025  int nexp = GetExpSize();
1026  int n,p,offset,phys_offset;
1027 
1028  ASSERTL1(outarray.num_elements() >= m_trace->GetExpSize(),
1029  "input array is of insufficient length");
1030 
1031  for (n = 0; n < nexp; ++n)
1032  {
1033  phys_offset = GetPhys_Offset(n);
1034 
1035  for (p = 0; p < (*m_exp)[n]->GetNverts(); ++p)
1036  {
1037  offset = m_trace->GetPhys_Offset(
1038  (m_traceMap->GetElmtToTrace())[n][p]->GetElmtId());
1039  (*m_exp)[n]->GetVertexPhysVals(p, inarray + phys_offset,
1040  outarray[offset]);
1041  }
1042  }
1043  }
1044 
1046  const Array<OneD, const NekDouble> &Fn,
1047  Array<OneD, NekDouble> &outarray)
1048  {
1049  int n,offset, t_offset;
1050 
1052  &elmtToTrace = m_traceMap->GetElmtToTrace();
1053 
1054  // Basis shared pointer
1056 
1057  vector<bool> negatedFluxNormal = GetNegatedFluxNormal();
1058 
1059  for (n = 0; n < GetExpSize(); ++n)
1060  {
1061  // Basis definition on each element
1062  Basis = (*m_exp)[n]->GetBasis(0);
1063 
1064  // Number of coefficients on each element
1065  int e_ncoeffs = (*m_exp)[n]->GetNcoeffs();
1066 
1067  offset = GetCoeff_Offset(n);
1068 
1069  // Implementation for every points except Gauss points
1070  if (Basis->GetBasisType() != LibUtilities::eGauss_Lagrange)
1071  {
1072  t_offset = GetTrace()->GetCoeff_Offset(elmtToTrace[n][0]->GetElmtId());
1073  if(negatedFluxNormal[2*n])
1074  {
1075  outarray[offset] -= Fn[t_offset];
1076  }
1077  else
1078  {
1079  outarray[offset] += Fn[t_offset];
1080  }
1081 
1082  t_offset = GetTrace()->GetCoeff_Offset(elmtToTrace[n][1]->GetElmtId());
1083 
1084  if(negatedFluxNormal[2*n+1])
1085  {
1086  outarray[offset+(*m_exp)[n]->GetVertexMap(1)] -= Fn[t_offset];
1087  }
1088  else
1089  {
1090  outarray[offset+(*m_exp)[n]->GetVertexMap(1)] += Fn[t_offset];
1091  }
1092 
1093  }
1094  else
1095  {
1096 #if 0
1097  DNekMatSharedPtr m_Ixm;
1100  BS_p(e_ncoeffs,LibUtilities::eGaussGaussLegendre);
1102  BS_k(LibUtilities::eGauss_Lagrange,e_ncoeffs,BS_p);
1103 
1104  BASE = LibUtilities::BasisManager()[BS_k];
1105 
1106  Array<OneD, NekDouble> coords(3, 0.0);
1107 
1108  int j;
1109 
1110  for(p = 0; p < 2; ++p)
1111  {
1112  NekDouble vertnorm = 0.0;
1113  for (int i=0; i<((*m_exp)[n]->
1114  GetVertexNormal(p)).num_elements(); i++)
1115  {
1116  vertnorm += ((*m_exp)[n]->GetVertexNormal(p))[i][0];
1117  coords[0] = vertnorm ;
1118  }
1119 
1120  t_offset = GetTrace()->GetPhys_Offset(n+p);
1121 
1122  if (vertnorm >= 0.0)
1123  {
1124  m_Ixm = BASE->GetI(coords);
1125 
1126 
1127  for (j = 0; j < e_ncoeffs; j++)
1128  {
1129  outarray[offset + j] +=
1130  (m_Ixm->GetPtr())[j] * Fn[t_offset];
1131  }
1132  }
1133 
1134  if (vertnorm < 0.0)
1135  {
1136  m_Ixm = BASE->GetI(coords);
1137 
1138  for (j = 0; j < e_ncoeffs; j++)
1139  {
1140  outarray[offset + j] -=
1141  (m_Ixm->GetPtr())[j] * Fn[t_offset];
1142  }
1143  }
1144  }
1145 #else
1146  int j;
1147  static DNekMatSharedPtr m_Ixm, m_Ixp;
1148  static int sav_ncoeffs = 0;
1149  if(!m_Ixm.get() || e_ncoeffs != sav_ncoeffs)
1150  {
1153  BS_p(e_ncoeffs,LibUtilities::eGaussGaussLegendre);
1155  BS_k(LibUtilities::eGauss_Lagrange,e_ncoeffs,BS_p);
1156 
1157  BASE = LibUtilities::BasisManager()[BS_k];
1158 
1159  Array<OneD, NekDouble> coords(1, 0.0);
1160 
1161  coords[0] = -1.0;
1162  m_Ixm = BASE->GetI(coords);
1163 
1164  coords[0] = 1.0;
1165  m_Ixp = BASE->GetI(coords);
1166 
1167  sav_ncoeffs = e_ncoeffs;
1168  }
1169 
1170  t_offset = GetTrace()->GetCoeff_Offset(elmtToTrace[n][0]->GetElmtId());
1171  if(negatedFluxNormal[2*n])
1172  {
1173  for (j = 0; j < e_ncoeffs; j++)
1174  {
1175  outarray[offset + j] -=
1176  (m_Ixm->GetPtr())[j] * Fn[t_offset];
1177  }
1178  }
1179  else
1180  {
1181  for (j = 0; j < e_ncoeffs; j++)
1182  {
1183  outarray[offset + j] +=
1184  (m_Ixm->GetPtr())[j] * Fn[t_offset];
1185  }
1186  }
1187 
1188  t_offset = GetTrace()->GetCoeff_Offset(elmtToTrace[n][1]->GetElmtId());
1189  if (negatedFluxNormal[2*n+1])
1190  {
1191  for (j = 0; j < e_ncoeffs; j++)
1192  {
1193  outarray[offset + j] -=
1194  (m_Ixp->GetPtr())[j] * Fn[t_offset];
1195  }
1196  }
1197  else
1198  {
1199  for (j = 0; j < e_ncoeffs; j++)
1200  {
1201  outarray[offset + j] +=
1202  (m_Ixp->GetPtr())[j] * Fn[t_offset];
1203  }
1204  }
1205 #endif
1206  }
1207  }
1208  }
1209 
1210 
1212  const Array<OneD, const NekDouble> &inarray,
1213  Array<OneD, NekDouble> &outarray,
1214  const FlagList &flags,
1215  const StdRegions::ConstFactorMap &factors,
1216  const StdRegions::VarCoeffMap &varcoeff,
1217  const Array<OneD, const NekDouble> &dirForcing)
1218  {
1219  int i,n,cnt,nbndry;
1220  int nexp = GetExpSize();
1222  DNekVec F(m_ncoeffs,f,eWrapper);
1223  Array<OneD,NekDouble> e_f, e_l;
1224 
1225  //----------------------------------
1226  // Setup RHS Inner product
1227  //----------------------------------
1228  IProductWRTBase(inarray,f);
1229  Vmath::Neg(m_ncoeffs,f,1);
1230 
1231  //----------------------------------
1232  // Solve continuous Boundary System
1233  //----------------------------------
1234  int GloBndDofs = m_traceMap->GetNumGlobalBndCoeffs();
1235  int NumDirBCs = m_traceMap->GetNumLocalDirBndCoeffs();
1236  int e_ncoeffs,id;
1237 
1238  GlobalMatrixKey HDGLamToUKey(
1241  factors,
1242  varcoeff);
1243 
1244  const DNekScalBlkMatSharedPtr &HDGLamToU =
1245  GetBlockMatrix(HDGLamToUKey);
1246 
1247  // Retrieve global trace space storage, \Lambda, from trace expansion
1249  (m_traceMap->GetNumLocalBndCoeffs());
1250 
1251 
1252  Array<OneD,NekDouble> BndRhs(GloBndDofs,0.0);
1253  // Zero trace space
1254  Vmath::Zero(GloBndDofs,BndSol,1);
1255 
1256  int LocBndCoeffs = m_traceMap->GetNumLocalBndCoeffs();
1257  Array<OneD, NekDouble> loc_lambda(LocBndCoeffs);
1258  DNekVec LocLambda(LocBndCoeffs,loc_lambda,eWrapper);
1259 
1260  //----------------------------------
1261  // Evaluate Trace Forcing
1262  //----------------------------------
1263  // Determing <u_lam,f> terms using HDGLamToU matrix
1264  for (cnt = n = 0; n < nexp; ++n)
1265  {
1266  nbndry = (*m_exp)[n]->NumDGBndryCoeffs();
1267 
1268  e_ncoeffs = (*m_exp)[n]->GetNcoeffs();
1269  e_f = f+m_coeff_offset[n];
1270  e_l = loc_lambda + cnt;
1271 
1272  // use outarray as tmp space
1273  DNekVec Floc (nbndry, e_l, eWrapper);
1274  DNekVec ElmtFce (e_ncoeffs, e_f, eWrapper);
1275  Floc = Transpose(*(HDGLamToU->GetBlock(n,n)))*ElmtFce;
1276 
1277  cnt += nbndry;
1278  }
1279 
1280  // Assemble into global operator
1281  m_traceMap->AssembleBnd(loc_lambda,BndRhs);
1282 
1283  cnt = 0;
1284  // Copy Dirichlet boundary conditions into trace space
1285  for (i = 0; i < m_bndCondExpansions.num_elements(); ++i)
1286  {
1287  if (m_bndConditions[i]->GetBoundaryConditionType() ==
1289  {
1290  id = m_traceMap->GetBndCondCoeffsToGlobalCoeffsMap(i);
1291  BndSol[id] = m_bndCondExpansions[i]->GetCoeff(0);
1292  }
1293  else
1294  {
1295  id = m_traceMap->GetBndCondCoeffsToGlobalCoeffsMap(i);
1296  BndRhs[id] += m_bndCondExpansions[i]->GetCoeff(0);
1297  }
1298  }
1299 
1300  //----------------------------------
1301  // Solve trace problem
1302  //----------------------------------
1303  if (GloBndDofs - NumDirBCs > 0)
1304  {
1306  m_traceMap,factors);
1308  LinSys->Solve(BndRhs,BndSol,m_traceMap);
1309  }
1310 
1311  //----------------------------------
1312  // Internal element solves
1313  //----------------------------------
1316  factors);
1317 
1318  const DNekScalBlkMatSharedPtr& InvHDGHelm =
1319  GetBlockMatrix(invHDGhelmkey);
1320  DNekVec out(m_ncoeffs,outarray,eWrapper);
1321  Vmath::Zero(m_ncoeffs,outarray,1);
1322 
1323  // get local trace solution from BndSol
1324  m_traceMap->GlobalToLocalBnd(BndSol,loc_lambda);
1325 
1326  // out = u_f + u_lam = (*InvHDGHelm)*f + (LamtoU)*Lam
1327  out = (*InvHDGHelm)*F + (*HDGLamToU)*LocLambda;
1328  }
1329 
1330  /**
1331  * Based on the expression \f$g(x,t)\f$ for the boundary conditions,
1332  * this function evaluates the boundary conditions for all boundaries
1333  * at time-level \a t.
1334  * @param time The time at which the boundary conditions
1335  * should be evaluated.
1336  * @param bndCondExpansions List of boundary expansions.
1337  * @param bndConditions Information about the boundary conditions.
1338  */
1340  const NekDouble time,
1341  const std::string varName,
1342  const NekDouble x2_in,
1343  const NekDouble x3_in)
1344  {
1345  int i;
1346 
1347  Array<OneD, NekDouble> x0(1);
1348  Array<OneD, NekDouble> x1(1);
1349  Array<OneD, NekDouble> x2(1);
1350 
1351  for (i = 0; i < m_bndCondExpansions.num_elements(); ++i)
1352  {
1353  if (time == 0.0 || m_bndConditions[i]->IsTimeDependent())
1354  {
1355  m_bndCondExpansions[i]->GetCoords(x0, x1, x2);
1356 
1357  if (x2_in != NekConstants::kNekUnsetDouble && x3_in !=
1359  {
1360  x1[0] = x2_in;
1361  x2[0] = x3_in;
1362  }
1363 
1364  if (m_bndConditions[i]->GetBoundaryConditionType() ==
1366  {
1367  m_bndCondExpansions[i]->SetCoeff(0,
1368  (boost::static_pointer_cast<SpatialDomains
1369  ::DirichletBoundaryCondition>(m_bndConditions[i])
1370  ->m_dirichletCondition).Evaluate(x0[0],x1[0],x2[0],time));
1371  m_bndCondExpansions[i]->SetPhys(0,m_bndCondExpansions[i]->GetCoeff(0));
1372  }
1373  else if (m_bndConditions[i]->GetBoundaryConditionType()
1375  {
1376  m_bndCondExpansions[i]->SetCoeff(0,
1377  (boost::static_pointer_cast<SpatialDomains
1378  ::NeumannBoundaryCondition>(m_bndConditions[i])
1379  ->m_neumannCondition).Evaluate(x0[0],x1[0],x2[0],time));
1380  }
1381  else if (m_bndConditions[i]->GetBoundaryConditionType()
1383  {
1384  m_bndCondExpansions[i]->SetCoeff(0,
1385  (boost::static_pointer_cast<SpatialDomains
1386  ::RobinBoundaryCondition>(m_bndConditions[i])
1387  ->m_robinFunction).Evaluate(x0[0],x1[0],x2[0],time));
1388 
1389  m_bndCondExpansions[i]->SetPhys(0,
1390  (boost::static_pointer_cast<SpatialDomains
1391  ::RobinBoundaryCondition>(m_bndConditions[i])
1392  ->m_robinPrimitiveCoeff).Evaluate(x0[0],x1[0],x2[0],time));
1393 
1394  }
1395  else if (m_bndConditions[i]->GetBoundaryConditionType()
1397  {
1398  }
1399  else
1400  {
1401  ASSERTL0(false, "This type of BC not implemented yet");
1402  }
1403  }
1404  }
1405  }
1406 
1407  // Set up a list of element ids and edge ids that link to the
1408  // boundary conditions
1410  Array<OneD, int> &ElmtID, Array<OneD,int> &VertID)
1411  {
1412  map<int, int> VertGID;
1413  int i,n,id;
1414  int bid,cnt,Vid;
1415  int nbcs = m_bndConditions.num_elements();
1416 
1417  // make sure arrays are of sufficient length
1418  if (ElmtID.num_elements() != nbcs)
1419  {
1420  ElmtID = Array<OneD, int>(nbcs,-1);
1421  }
1422  else
1423  {
1424  fill(ElmtID.get(), ElmtID.get()+nbcs, -1);
1425  }
1426 
1427  if (VertID.num_elements() != nbcs)
1428  {
1429  VertID = Array<OneD, int>(nbcs);
1430  }
1431 
1432  // setup map of all global ids along boundary
1433  for (cnt = n = 0; n < m_bndCondExpansions.num_elements(); ++n)
1434  {
1435  Vid = m_bndCondExpansions[n]->GetExp(0)->GetGeom()->GetVertex(0)->GetVid();
1436  VertGID[Vid] = cnt++;
1437  }
1438 
1439  // Loop over elements and find verts that match;
1441  for(cnt = n = 0; n < GetExpSize(); ++n)
1442  {
1443  exp = (*m_exp)[n];
1444  for(i = 0; i < exp->GetNverts(); ++i)
1445  {
1446  id = exp->GetGeom()->GetVid(i);
1447 
1448  if (VertGID.count(id) > 0)
1449  {
1450  bid = VertGID.find(id)->second;
1451  ASSERTL1(ElmtID[bid] == -1,"Edge already set");
1452  ElmtID[bid] = n;
1453  VertID[bid] = i;
1454  cnt ++;
1455  }
1456  }
1457  }
1458 
1459  ASSERTL1(cnt == nbcs,"Failed to visit all boundary condtiions");
1460  }
1461 
1463  boost::shared_ptr<ExpList> &result)
1464  {
1465  int n, cnt, nq;
1466  int offsetOld, offsetNew;
1467  Array<OneD, NekDouble> tmp1, tmp2;
1468  std::vector<unsigned int> eIDs;
1469 
1470  Array<OneD, int> ElmtID,EdgeID;
1471  GetBoundaryToElmtMap(ElmtID,EdgeID);
1472 
1473  // Skip other boundary regions
1474  for (cnt = n = 0; n < i; ++n)
1475  {
1476  cnt += m_bndCondExpansions[n]->GetExpSize();
1477  }
1478 
1479  // Populate eIDs with information from BoundaryToElmtMap
1480  for (n = 0; n < m_bndCondExpansions[i]->GetExpSize(); ++n)
1481  {
1482  eIDs.push_back(ElmtID[cnt+n]);
1483  }
1484 
1485  // Create expansion list
1486  result =
1488 
1489  // Copy phys and coeffs to new explist
1490  for (n = 0; n < result->GetExpSize(); ++n)
1491  {
1492  nq = GetExp(ElmtID[cnt+n])->GetTotPoints();
1493  offsetOld = GetPhys_Offset(ElmtID[cnt+n]);
1494  offsetNew = result->GetPhys_Offset(n);
1495  Vmath::Vcopy(nq, tmp1 = GetPhys()+ offsetOld, 1,
1496  tmp2 = result->UpdatePhys()+ offsetNew, 1);
1497 
1498  nq = GetExp(ElmtID[cnt+n])->GetNcoeffs();
1499  offsetOld = GetCoeff_Offset(ElmtID[cnt+n]);
1500  offsetNew = result->GetCoeff_Offset(n);
1501  Vmath::Vcopy(nq, tmp1 = GetCoeffs()+ offsetOld, 1,
1502  tmp2 = result->UpdateCoeffs()+ offsetNew, 1);
1503  }
1504  }
1505 
1506  /**
1507  * @brief Reset this field, so that geometry information can be updated.
1508  */
1510  {
1511  ExpList::v_Reset();
1512 
1513  // Reset boundary condition expansions.
1514  for (int n = 0; n < m_bndCondExpansions.num_elements(); ++n)
1515  {
1516  m_bndCondExpansions[n]->Reset();
1517  }
1518  }
1519 
1520  /**
1521  * Search through the edge expansions and identify which ones
1522  * have Robin/Mixed type boundary conditions. If find a Robin
1523  * boundary then store the edge id of the boundary condition
1524  * and the array of points of the physical space boundary
1525  * condition which are hold the boundary condition primitive
1526  * variable coefficient at the quatrature points
1527  *
1528  * \return std map containing the robin boundary condition
1529  * info using a key of the element id
1530  *
1531  * There is a next member to allow for more than one Robin
1532  * boundary condition per element
1533  */
1534  map<int, RobinBCInfoSharedPtr> DisContField1D::v_GetRobinBCInfo(void)
1535  {
1536  int i;
1537  map<int, RobinBCInfoSharedPtr> returnval;
1538  Array<OneD, int> ElmtID,VertID;
1539  GetBoundaryToElmtMap(ElmtID,VertID);
1540 
1541  for (i = 0; i < m_bndCondExpansions.num_elements(); ++i)
1542  {
1543  MultiRegions::ExpListSharedPtr locExpList;
1544 
1545  if (m_bndConditions[i]->GetBoundaryConditionType() ==
1547  {
1548  int elmtid;
1549  Array<OneD, NekDouble> Array_tmp;
1550 
1551  locExpList = m_bndCondExpansions[i];
1552 
1553  RobinBCInfoSharedPtr rInfo =
1556  VertID[i],Array_tmp = locExpList->GetPhys());
1557 
1558  elmtid = ElmtID[i];
1559  // make link list if necessary (not likely in
1560  // 1D but needed in 2D & 3D)
1561  if(returnval.count(elmtid) != 0)
1562  {
1563  rInfo->next = returnval.find(elmtid)->second;
1564  }
1565  returnval[elmtid] = rInfo;
1566  }
1567  }
1568 
1569  return returnval;
1570  }
1571  } // end of namespace
1572 } //end of namespace
GlobalSysSolnType GetGlobalSysSolnType() const
Return the associated solution type.
const DNekScalBlkMatSharedPtr & GetBlockMatrix(const GlobalMatrixKey &gkey)
Definition: ExpList.cpp:812
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:1834
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
virtual void v_Reset()
Reset geometry information, metrics, matrix managers and geometry information.
Definition: ExpList.cpp:1435
int GetCoeff_Offset(int n) const
Get the start offset position for a global list of m_coeffs correspoinding to element n...
Definition: ExpList.h:1926
virtual void v_EvaluateBoundaryConditions(const NekDouble time=0.0, const std::string varName="", const NekDouble x2_in=NekConstants::kNekUnsetDouble, const NekDouble x3_in=NekConstants::kNekUnsetDouble)
Evaluate all boundary conditions at a given time..
static ExpListSharedPtr NullExpListSharedPtr
Definition: ExpList.h:1395
void EvaluateBoundaryConditions(const NekDouble time=0.0, const std::string varName="", const NekDouble=NekConstants::kNekUnsetDouble, const NekDouble=NekConstants::kNekUnsetDouble)
Definition: ExpList.h:2091
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
virtual void v_AddTraceIntegral(const Array< OneD, const NekDouble > &Fn, Array< OneD, NekDouble > &outarray)
bool isLocal
Flag specifying if this entity is local to this partition.
int GetPhys_Offset(int n) const
Get the start offset position for a global list of m_phys correspoinding to element n...
Definition: ExpList.h:1934
const BoundaryConditionCollection & GetBoundaryConditions(void) const
Definition: Conditions.h:237
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
Array< OneD, SpatialDomains::BoundaryConditionShPtr > m_bndConditions
An array which contains the information about the boundary condition on the different boundary region...
boost::shared_ptr< RobinBCInfo > RobinBCInfoSharedPtr
virtual map< int, RobinBCInfoSharedPtr > v_GetRobinBCInfo()
void FindPeriodicVertices(const SpatialDomains::BoundaryConditions &bcs, const std::string variable)
Generate a associative map of periodic vertices in a mesh.
const boost::shared_ptr< LocalRegions::ExpansionVector > GetExp() const
This function returns the vector of elements in the expansion.
Definition: ExpList.h:1917
Lagrange Polynomials using the Gauss points .
Definition: BasisType.h:54
SpatialDomains::BoundaryConditionsSharedPtr GetDomainBCs(const SpatialDomains::CompositeMap &domain, const SpatialDomains::BoundaryConditions &Allbcs, const std::string &variable)
vector< int > m_periodicFwdCopy
A vector indicating degress of freedom which need to be copied from forwards to backwards space in ca...
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:251
void SetUpDG(const std::string &variable)
void GetBoundaryToElmtMap(Array< OneD, int > &ElmtID, Array< OneD, int > &EdgeID)
Definition: ExpList.h:2144
Array< OneD, NekDouble > m_phys
The global expansion evaluated at the quadrature points.
Definition: ExpList.h:956
void ApplyGeomInfo()
Apply geometry information to each expansion.
Definition: ExpList.cpp:1422
boost::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:70
int GetExpSize(void)
This function returns the number of elements in the expansion.
Definition: ExpList.h:1896
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:51
boost::shared_ptr< Expansion0D > Expansion0DSharedPtr
Definition: Expansion0D.h:49
boost::shared_ptr< GlobalLinSys > GenGlobalBndLinSys(const GlobalLinSysKey &mkey, const AssemblyMapSharedPtr &locToGloMap)
Generate a GlobalLinSys from information provided by the key "mkey" and the mapping provided in LocTo...
Definition: ExpList.cpp:1192
void SetAdjacentElementExp(int vertex, Expansion1DSharedPtr &v)
Definition: Expansion0D.h:115
1D Gauss-Gauss-Legendre quadrature points
Definition: PointsType.h:47
virtual void v_GetFwdBwdTracePhys(Array< OneD, NekDouble > &Fwd, Array< OneD, NekDouble > &Bwd)
BasisManagerT & BasisManager(void)
GlobalLinSysSharedPtr GetGlobalBndLinSys(const GlobalLinSysKey &mkey)
For a given key, returns the associated global linear system.
Array< OneD, int > m_coeff_offset
Offset of elemental data into the array m_coeffs.
Definition: ExpList.h:988
void SetBoundaryConditionExpansion(const SpatialDomains::MeshGraphSharedPtr &graph1D, const SpatialDomains::BoundaryConditions &bcs, const std::string variable, Array< OneD, MultiRegions::ExpListSharedPtr > &bndCondExpansions, Array< OneD, SpatialDomains::BoundaryConditionShPtr > &bndConditions)
Populates the list of boundary condition expansions.
Base class for all multi-elemental spectral/hp expansions.
Definition: ExpList.h:101
boost::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
The base class for all shapes.
Definition: StdExpansion.h:69
boost::shared_ptr< ExpList > & GetTrace()
Definition: ExpList.h:2001
virtual void v_ExtractTracePhys(Array< OneD, NekDouble > &outarray)
boost::shared_ptr< LocalRegions::ExpansionVector > m_exp
The list of local expansions.
Definition: ExpList.h:977
virtual void v_GetBndElmtExpansion(int i, boost::shared_ptr< ExpList > &result)
DisContField1D()
Default constructor.
std::map< StdRegions::VarCoeffType, Array< OneD, NekDouble > > VarCoeffMap
Definition: StdRegions.hpp:226
int id
Geometry ID of entity.
bool m_physState
The state of the array m_phys.
Definition: ExpList.h:965
int m_ncoeffs
The total number of local degrees of freedom. m_ncoeffs .
Definition: ExpList.h:917
std::map< int, Composite >::const_iterator CompositeMapConstIter
Definition: MeshGraph.h:117
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
Definition: Conditions.h:206
boost::shared_ptr< DNekScalBlkMat > DNekScalBlkMatSharedPtr
Definition: NekTypeDefs.hpp:74
boost::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
This class is the abstraction of a global discontinuous two- dimensional spectral/hp element expansio...
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
SpatialDomains::MeshGraphSharedPtr m_graph
Mesh associated with this expansion list.
Definition: ExpList.h:913
void GenerateBoundaryConditionExpansion(const SpatialDomains::MeshGraphSharedPtr &graph1D, const SpatialDomains::BoundaryConditions &bcs, const std::string variable)
Discretises the boundary conditions.
LibUtilities::SessionReaderSharedPtr m_session
Session.
Definition: ExpList.h:910
AssemblyMapDGSharedPtr m_traceMap
Local to global DG mapping for trace space.
Defines a specification for a set of points.
Definition: Points.h:58
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition: Vmath.cpp:382
double NekDouble
boost::shared_ptr< Expansion > ExpansionSharedPtr
Definition: Expansion.h:68
Defines a list of flags.
std::map< int, BoundaryConditionMapShPtr > BoundaryConditionCollection
Definition: Conditions.h:215
boost::shared_ptr< GeometryVector > Composite
Definition: MeshGraph.h:114
virtual void v_HelmSolve(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, const FlagList &flags, const StdRegions::ConstFactorMap &factors, const StdRegions::VarCoeffMap &varcoeff, const Array< OneD, const NekDouble > &dirForcing)
Solve the Helmholtz equation.
static const NekDouble kNekUnsetDouble
Describe a linear system.
std::map< int, Composite > CompositeMap
Definition: MeshGraph.h:115
StdRegions::MatrixType GetMatrixType() const
Return the matrix type.
Describes a matrix with ordering defined by a local to global map.
const Array< OneD, const NekDouble > & GetPhys() const
This function returns (a reference to) the array (implemented as m_phys) containing the function ev...
Definition: ExpList.h:1887
bool IsLeftAdjacentVertex(const int n, const int e)
GlobalLinSysMapShPtr m_globalBndMat
Global boundary matrix.
boost::shared_ptr< ExpList0D > ExpList0DSharedPtr
Shared pointer to an ExpList0D object.
Definition: ExpList0D.h:54
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
static AssemblyMapSharedPtr NullAssemblyMapSharedPtr
Definition: AssemblyMap.h:55
boost::shared_ptr< BoundaryConditionMap > BoundaryConditionMapShPtr
Definition: Conditions.h:214
vector< bool > & GetNegatedFluxNormal(void)
Array< OneD, MultiRegions::ExpListSharedPtr > m_bndCondExpansions
Discretised boundary conditions.
virtual void v_Reset()
Reset this field, so that geometry information can be updated.
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed t...
Definition: ErrorUtil.hpp:213
NekDouble GetCoeff(int i)
Get the i th value (coefficient) of m_coeffs.
Definition: ExpList.h:1865
boost::shared_ptr< MeshGraph1D > MeshGraph1DSharedPtr
Definition: MeshGraph1D.h:86
std::set< int > m_boundaryVerts
A set storing the global IDs of any boundary edges.
boost::shared_ptr< BoundaryConditions > BoundaryConditionsSharedPtr
Definition: Conditions.h:271
void IProductWRTBase(const Array< OneD, const NekDouble > &inarray, Array< OneD, NekDouble > &outarray, CoeffState coeffstate=eLocal)
Definition: ExpList.h:1559
This class is the abstraction of a one-dimensional multi-elemental expansions which is merely a colle...
Definition: ExpList1D.h:61
ExpListSharedPtr m_trace
Trace space storage for points between elements.
static SpatialDomains::BoundaryConditionShPtr GetBoundaryCondition(const SpatialDomains::BoundaryConditionCollection &collection, unsigned int index, const std::string &variable)
Definition: ExpList.cpp:2858
boost::shared_ptr< GlobalLinSys > GlobalLinSysSharedPtr
Pointer to a GlobalLinSys object.
Definition: GlobalLinSys.h:52
const BoundaryRegionCollection & GetBoundaryRegions(void) const
Definition: Conditions.h:227
boost::shared_ptr< BoundaryConditionBase > BoundaryConditionShPtr
Definition: Conditions.h:208
boost::shared_ptr< Basis > BasisSharedPtr
PeriodicMap m_periodicVerts
A map which identifies groups of periodic vertices.
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
Definition: Vmath.cpp:723
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:359
#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:442
boost::shared_ptr< Expansion1D > Expansion1DSharedPtr
Definition: Expansion1D.h:53
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1047
boost::shared_ptr< BoundaryRegion > BoundaryRegionShPtr
Definition: Conditions.h:204
Describes the specification for a Basis.
Definition: Basis.h:50
boost::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:60
virtual void v_GetBoundaryToElmtMap(Array< OneD, int > &ElmtID, Array< OneD, int > &VertID)