G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsVisitorDg.h
Go to the documentation of this file.
1 
15 #pragma once
16 
17 namespace gismo
18 {
50 template <class T>
52 {
53 public:
54 
57  : m_pde(NULL)
58  {}
59 
63  gsVisitorDg(const gsPde<T> & pde)
64  : m_pde(&pde)
65  {}
66 
69  {
70  gsOptionList options;
71  options.addReal ("DG.Alpha",
72  "Parameter alpha for dG scheme; use 1 for SIPG and NIPG.", 1);
73  options.addReal ("DG.Beta",
74  "Parameter beta for dG scheme; use 1 for SIPG and -1 for NIPG", 1);
75  options.addReal ("DG.Penalty",
76  "Penalty parameter penalty for dG scheme; if negative, default 4(p+d)(p+1) is used.", -1);
77  options.addSwitch("DG.ParameterGridSize",
78  "Use grid size on parameter domain for the penalty term.", false);
79  return options;
80  }
81 
83  void initialize(const gsBasis<T> & basis1,
84  const gsBasis<T> & basis2,
85  const boundaryInterface & bi,
86  const gsOptionList & options,
87  gsQuadRule<T> & rule)
88  {
89  m_side1 = bi.first();
90  m_side2 = bi.second();
91 
92  // Setup Quadrature
93  rule = gsQuadrature::get(basis1, options, m_side1.direction());
94 
95  m_penalty = options.askReal("DG.Penalty",-1);
96  // If not given, use default
97  if (m_penalty<0)
98  {
99  const index_t deg = math::max( basis1.maxDegree(), basis2.maxDegree() );
100  m_penalty = static_cast<T>(4) * static_cast<T>((deg + basis1.dim()) * (deg + 1));
101  }
102 
103  m_alpha = options.askReal("DG.Alpha", 1);
104  m_beta = options.askReal("DG.Beta" , 1);
105 
106  if (options.getSwitch("DG.ParameterGridSize"))
107  {
108  m_h1 = basis1.getMinCellLength();
109  m_h2 = basis2.getMinCellLength();
110  }
111  else
112  {
113  GISMO_ENSURE (m_pde, "gsVisitorDg::initialize: No PDE given.");
115  basis1,
116  m_pde->patches()[m_side1.patch],
117  m_side1
118  );
120  basis2,
121  m_pde->patches()[m_side2.patch],
122  m_side2
123  );
124  }
125 
126  // Set Geometry evaluation flags
127  md1.flags = md2.flags = NEED_VALUE|NEED_JACOBIAN|NEED_GRAD_TRANSFORM;
128  }
129 
131  inline void evaluate(const gsBasis<T> & B1,
132  const gsGeometry<T> & geo1,
133  const gsBasis<T> & B2,
134  const gsGeometry<T> & geo2,
135  const gsMatrix<T> & quNodes1,
136  const gsMatrix<T> & quNodes2)
137  {
138  md1.points = quNodes1;
139  md2.points = quNodes2;
140  // Compute the active basis functions
141  B1.active_into(md1.points.col(0), actives1);
142  B2.active_into(md2.points.col(0), actives2);
143  const index_t numActive1 = actives1.rows();
144  const index_t numActive2 = actives2.rows();
145 
146  // Evaluate basis functions and their first derivatives
147  B1.evalAllDers_into(md1.points, 1, basisData1, true);
148  B2.evalAllDers_into(md2.points, 1, basisData2, true);
149 
150  // Compute image of Gauss nodes under geometry mapping as well as Jacobians
151  geo1.computeMap(md1);
152  geo2.computeMap(md2);
153 
154  // Initialize local matrices
155  B11.setZero(numActive1, numActive1); B12.setZero(numActive1, numActive2);
156  E11.setZero(numActive1, numActive1); E12.setZero(numActive1, numActive2);
157  B22.setZero(numActive2, numActive2); B21.setZero(numActive2, numActive1);
158  E22.setZero(numActive2, numActive2); E21.setZero(numActive2, numActive1);
159  }
160 
162  inline void assemble(gsDomainIterator<T> & /*element1*/,
163  gsDomainIterator<T> & /*element2*/,
164  gsVector<T> & quWeights)
165  {
166  const index_t numActive1 = actives1.rows();
167  const index_t numActive2 = actives2.rows();
168 
169  for (index_t k = 0; k < quWeights.rows(); ++k) // loop over quadrature nodes
170  {
171  // Compute the outer normal vector from patch1
172  outerNormal(md1, k, m_side1, unormal);
173 
174  // Multiply quadrature weight by the geometry measure
175  // Integral transformation and quadrature weight (patch1)
176  // assumed the same on both sides
177  const T weight = quWeights[k] * unormal.norm();
178 
179  // Compute the outer unit normal vector from patch1 in place
180  unormal.normalize();
181 
182  // Take blocks of values and derivatives of basis functions
183  const typename gsMatrix<T>::Block val1 = basisData1[0].block(0,k,numActive1,1);
184  gsMatrix<T> & grads1 = basisData1[1];// all grads
185  const typename gsMatrix<T>::Block val2 = basisData2[0].block(0,k,numActive2,1);
186  gsMatrix<T> & grads2 = basisData2[1];// all grads
187 
188  // Transform the basis gradients
189  transformGradients(md1, k, grads1, phGrad1);
190  transformGradients(md2, k, grads2, phGrad2);
191 
192  // Compute element matrices
193  const T c1 = weight / (T)(2);
194  N1.noalias() = unormal.transpose() * phGrad1;
195  N2.noalias() = unormal.transpose() * phGrad2;
196 
197  B11.noalias() += c1 * ( val1 * N1 );
198  B12.noalias() += c1 * ( val1 * N2 );
199  B21.noalias() -= c1 * ( val2 * N1 );
200  B22.noalias() -= c1 * ( val2 * N2 );
201 
202  const T c2 = weight * m_penalty * (1./m_h1 + 1./m_h2);
203 
204  E11.noalias() += c2 * ( val1 * val1.transpose() );
205  E12.noalias() += c2 * ( val1 * val2.transpose() );
206  E22.noalias() += c2 * ( val2 * val2.transpose() );
207  E21.noalias() += c2 * ( val2 * val1.transpose() );
208 
209  }
210  }
211 
213  inline void localToGlobal(const index_t patch1,
214  const index_t patch2,
215  const std::vector<gsMatrix<T> > & eliminatedDofs,
216  gsSparseSystem<T> & system)
217  {
218  // Map patch-local DoFs to global DoFs
219  system.mapColIndices(actives1, patch1, actives1);
220  system.mapColIndices(actives2, patch2, actives2);
221 
222  m_localRhs1.setZero(actives1.rows(),system.rhsCols());
223  m_localRhs2.setZero(actives2.rows(),system.rhsCols());
224 
225  system.push(-m_alpha*B11 - m_beta*B11.transpose() + E11, m_localRhs1,actives1,actives1,eliminatedDofs.front(),0,0);
226  system.push(-m_alpha*B21 - m_beta*B12.transpose() - E21, m_localRhs2,actives2,actives1,eliminatedDofs.front(),0,0);
227  system.push(-m_alpha*B12 - m_beta*B21.transpose() - E12, m_localRhs1,actives1,actives2,eliminatedDofs.front(),0,0);
228  system.push(-m_alpha*B22 - m_beta*B22.transpose() + E22, m_localRhs2,actives2,actives2,eliminatedDofs.front(),0,0);
229  }
230 
233  const gsGeometry<T> & geo,
234  patchSide side)
235  {
236  T result = 0;
237  bool first = true;
238  typename gsDomainIterator<T>::uPtr domIt = basis.makeDomainIterator(side);
239 
240  for (gsDomainIterator<T>& element = *domIt; element.good(); element.next() )
241  {
242  gsVector<T> parameterCenter = element.centerPoint();
243  const gsMatrix<T> center1 = geo.eval(parameterCenter);
244 
245  parameterCenter(side.direction()) += static_cast<T>( side.parameter() == 0 ? 1 : -1 )
246  * element.getPerpendicularCellSize();
247  const gsMatrix<T> center2 = geo.eval(parameterCenter);
248 
249  const real_t diff = (center1 - center2).norm();
250 
251  if (first || result > diff)
252  result = diff;
253 
254  first = false;
255  }
256  return result;
257  }
258 
259 
260 
261 private:
262 
264  const gsPde<T> * m_pde;
265 
268 
271 
274 
277 
280 
281 private:
282 
283  // Basis values etc
284  std::vector<gsMatrix<T> > basisData1, basisData2;
285  gsMatrix<T> phGrad1 , phGrad2;
286  gsMatrix<index_t> actives1 , actives2;
287 
288  // Outer normal
289  gsVector<T> unormal;
290 
291  // Auxiliary element matrices
292  gsMatrix<T> B11, B12, E11, E12, N1,
293  B22, B21, E22, E21, N2;
294 
295  gsMatrix<T> m_localRhs1, m_localRhs2;
296 
297  gsMapData<T> md1, md2;
298 
299  // Grid sizes
300  T m_h1, m_h2;
301 };
302 
303 
304 } // namespace gismo
gsVisitorDg()
Constructor.
Definition: gsVisitorDg.h:56
Abstract base class representing a geometry map.
Definition: gsGeometry.h:92
Class representing a reference quadrature rule.
Definition: gsQuadRule.h:28
void mapColIndices(const gsMatrix< index_t > &actives, const index_t patchIndex, gsMatrix< index_t > &result, const index_t c=0) const
mapColIndices Maps a set of basis indices by the corresponding dofMapper.
Definition: gsSparseSystem.h:584
T m_beta
Parameter for the bilinear form.
Definition: gsVisitorDg.h:270
Struct which represents a certain side of a patch.
Definition: gsBoundary.h:231
virtual void computeMap(gsMapData< T > &InOut) const
Computes map function data.
Definition: gsFunction.hpp:822
T m_penalty
Parameter for the bilinear form.
Definition: gsVisitorDg.h:273
index_t rhsCols() const
the number of right-hand side vectors
Definition: gsSparseSystem.h:389
T m_alpha
Parameter for the bilinear form.
Definition: gsVisitorDg.h:267
virtual void evalAllDers_into(const gsMatrix< T > &u, int n, std::vector< gsMatrix< T > > &result, bool sameElement=false) const
Evaluate the nonzero functions and their derivatives up to order n at points u into result...
Definition: gsFunctionSet.hpp:81
bool parameter() const
Returns the parameter value (false=0=start, true=1=end) that corresponds to this side.
Definition: gsBoundary.h:128
the gsMapData is a cache of pre-computed function (map) values.
Definition: gsFuncData.h:324
static T estimateSmallestPerpendicularCellSize(const gsBasis< T > &basis, const gsGeometry< T > &geo, patchSide side)
Estimates the gird size perpendicular to the given side on the physical domain, as required for SIPG ...
Definition: gsVisitorDg.h:232
void assemble(gsDomainIterator< T > &, gsDomainIterator< T > &, gsVector< T > &quWeights)
Assemble on element.
Definition: gsVisitorDg.h:162
gsMatrix< T > eval(const gsMatrix< T > &u) const
Evaluate the function,.
Definition: gsFunctionSet.hpp:120
Abstract class representing a PDE (partial differential equation).
Definition: gsPde.h:43
bool good() const
Is the iterator still pointing to a valid element?
Definition: gsDomainIterator.h:112
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
gsVisitorDg(const gsPde< T > &pde)
Constructor.
Definition: gsVisitorDg.h:63
void push(const gsMatrix< T > &localMat, const gsMatrix< T > &localRhs, const gsMatrix< index_t > &actives, const gsMatrix< T > &eliminatedDofs, const size_t r=0, const size_t c=0)
push pushes the local system matrix and rhs for an element to the global system,
Definition: gsSparseSystem.h:972
void initialize(const gsBasis< T > &basis1, const gsBasis< T > &basis2, const boundaryInterface &bi, const gsOptionList &options, gsQuadRule< T > &rule)
Initialize.
Definition: gsVisitorDg.h:83
memory::unique_ptr< gsDomainIterator > uPtr
Unique pointer for gsDomainIterator.
Definition: gsDomainIterator.h:73
virtual T getMinCellLength() const
Get the minimum mesh size, as expected for inverse inequalities.
Definition: gsBasis.hpp:663
static gsQuadRule< T > get(const gsBasis< T > &basis, const gsOptionList &options, short_t fixDir=-1)
Constructs a quadrature rule based on input options.
Definition: gsQuadrature.h:48
Class which enables iteration over all elements of a parameter domain.
Definition: gsDomainIterator.h:67
void evaluate(const gsBasis< T > &B1, const gsGeometry< T > &geo1, const gsBasis< T > &B2, const gsGeometry< T > &geo2, const gsMatrix< T > &quNodes1, const gsMatrix< T > &quNodes2)
Evaluate on element.
Definition: gsVisitorDg.h:131
bool getSwitch(const std::string &label) const
Reads value for option label from options.
Definition: gsOptionList.cpp:51
Real askReal(const std::string &label, const Real &value=0) const
Reads value for option label from options.
Definition: gsOptionList.cpp:139
Jacobian of the object.
Definition: gsForwardDeclarations.h:75
const gsPde< T > * m_pde
The underlying PDE.
Definition: gsVisitorDg.h:264
Value of the object.
Definition: gsForwardDeclarations.h:72
void addReal(const std::string &label, const std::string &desc, const Real &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:211
static gsOptionList defaultOptions()
Default options.
Definition: gsVisitorDg.h:68
patchSide m_side2
Side on second patch that corresponds to interface.
Definition: gsVisitorDg.h:279
Visitor for adding the interface conditions for the interior penalty methods of the Poisson problem...
Definition: gsVisitorDg.h:51
patchSide & second()
second, returns the second patchSide of this interface
Definition: gsBoundary.h:782
virtual short_t maxDegree() const
If the basis is of polynomial or piecewise polynomial type, then this function returns the maximum po...
Definition: gsBasis.hpp:638
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
Gradient transformation matrix.
Definition: gsForwardDeclarations.h:77
Class which holds a list of parameters/options, and provides easy access to them. ...
Definition: gsOptionList.h:32
void localToGlobal(const index_t patch1, const index_t patch2, const std::vector< gsMatrix< T > > &eliminatedDofs, gsSparseSystem< T > &system)
Adds the contributions to the sparse system.
Definition: gsVisitorDg.h:213
void addSwitch(const std::string &label, const std::string &desc, const bool &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:235
virtual domainIter makeDomainIterator() const
Create a domain iterator for the computational mesh of this basis, that points to the first element o...
Definition: gsBasis.hpp:493
index_t patch
The index of the patch.
Definition: gsBoundary.h:234
short_t direction() const
Returns the parametric direction orthogonal to this side.
Definition: gsBoundary.h:113
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78
patchSide m_side1
Side on first patch that corresponds to interface.
Definition: gsVisitorDg.h:276
virtual void active_into(const gsMatrix< T > &u, gsMatrix< index_t > &result) const
Returns the indices of active basis functions at points u, as a list of indices, in result...
Definition: gsBasis.hpp:293
patchSide & first()
first, returns the first patchSide of this interface
Definition: gsBoundary.h:776