dune-pdelab  2.5-dev
assemblerutilities.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 #ifndef DUNE_PDELAB_GRIDOPERATOR_COMMON_ASSEMBLERUTILITIES_HH
5 #define DUNE_PDELAB_GRIDOPERATOR_COMMON_ASSEMBLERUTILITIES_HH
6 
7 #include <algorithm>
8 #include <tuple>
9 
12 
13 namespace Dune{
14  namespace PDELab{
15 
21  template<typename GO>
23  {
24 
26  typedef typename GO::Traits::TrialGridFunctionSpace TrialGridFunctionSpace;
27 
29  typedef typename GO::Traits::TestGridFunctionSpace TestGridFunctionSpace;
30 
31 
33  typedef typename GO::Traits::TrialGridFunctionSpaceConstraints TrialGridFunctionSpaceConstraints;
34 
36  typedef typename GO::Traits::TestGridFunctionSpaceConstraints TestGridFunctionSpaceConstraints;
37 
38 
40  typedef typename GO::Traits::MatrixBackend MatrixBackend;
41 
42 
44  typedef typename GO::Traits::DomainField DomainField;
45 
47  typedef typename GO::Traits::Domain Solution;
48 
49 
51  typedef typename GO::Traits::RangeField RangeField;
52 
54  typedef typename GO::Traits::Range Residual;
55 
56 
58  typedef typename GO::Traits::JacobianField JacobianField;
59 
61  typedef typename GO::Traits::Jacobian Jacobian;
62 
64  typedef typename MatrixBackend::template Pattern<
65  Jacobian,
67  TrialGridFunctionSpace
69 
71  typedef typename GO::BorderDOFExchanger BorderDOFExchanger;
72 
73  };
74 
75  // ********************************************************************************
76  // default local pattern implementation
77  // ********************************************************************************
78 
91  class SparsityLink : public std::tuple<int,int>
92  {
93  public:
96  {}
97 
99  SparsityLink (int i, int j)
100  : std::tuple<int,int>(i,j)
101  {}
102 
104  inline int i () const
105  {
106  return std::get<0>(*this);
107  }
108 
110  inline int j () const
111  {
112  return std::get<1>(*this);
113  }
114 
116  void set (int i, int j)
117  {
118  std::get<0>(*this) = i;
119  std::get<1>(*this) = j;
120  }
121  };
122 
130  : public std::vector<SparsityLink>
131  {
132 
133  // make push_back() inaccessible
134  using std::vector<SparsityLink>::push_back;
135 
136  public:
137 
139 
148  template<typename LFSV, typename LFSU>
149  void addLink(const LFSV& lfsv, std::size_t i, const LFSU& lfsu, std::size_t j)
150  {
151  std::vector<SparsityLink>::push_back(
152  SparsityLink(
153  lfsv.localIndex(i),
154  lfsu.localIndex(j)
155  )
156  );
157  }
158 
159  };
160 
161 
162 
163  // ********************************************************************************
164  // Assembler base class
165  // ********************************************************************************
166 
179  template<typename B,
180  typename CU=EmptyTransformation,
181  typename CV=EmptyTransformation>
183  public:
184 
185  typedef typename B::size_type SizeType;
186 
189  : pconstraintsu(&emptyconstraintsu), pconstraintsv(&emptyconstraintsv)
190  {}
191 
193  LocalAssemblerBase (const CU& cu, const CV& cv)
194  :pconstraintsu(&cu), pconstraintsv(&cv)
195  {}
196 
198  const CU& trialConstraints() const
199  {
200  return *pconstraintsu;
201  }
202 
204  const CV& testConstraints() const
205  {
206  return *pconstraintsv;
207  }
208 
209 
215  template<typename X>
216  typename std::enable_if<
217  AlwaysTrue<X>::value && !std::is_same<
218  CV,
220  >::value
221  >::type
222  forwardtransform(X & x, const bool postrestrict = false) const
223  {
224  typedef typename CV::const_iterator global_col_iterator;
225  for (global_col_iterator cit=pconstraintsv->begin(); cit!=pconstraintsv->end(); ++cit){
226  typedef typename global_col_iterator::value_type::first_type GlobalIndex;
227  const GlobalIndex & contributor = cit->first;
228 
229  typedef typename global_col_iterator::value_type::second_type ContributedMap;
230  typedef typename ContributedMap::const_iterator global_row_iterator;
231  const ContributedMap & contributed = cit->second;
232  global_row_iterator it = contributed.begin();
233  global_row_iterator eit = contributed.end();
234 
235  for(;it!=eit;++it)
236  {
237  // typename X::block_type block(x[contributor]);
238  // block *= it->second;
239  // x[it->first] += block;
240  x[it->first] += it->second * x[contributor];
241  }
242  }
243 
244  if(postrestrict)
245  for (global_col_iterator cit=pconstraintsv->begin(); cit!=pconstraintsv->end(); ++cit)
246  x[cit->first]=0.;
247  }
248 
249 
250  // Disable forwardtransform for EmptyTransformation
251  template<typename X>
252  typename std::enable_if<
253  AlwaysTrue<X>::value && std::is_same<
254  CV,
256  >::value
257  >::type
258  forwardtransform(X & x, const bool postrestrict = false) const
259  {}
260 
261 
266  template<typename X>
267  typename std::enable_if<
268  AlwaysTrue<X>::value && !std::is_same<
269  CV,
271  >::value
272  >::type
273  backtransform(X & x, const bool prerestrict = false) const
274  {
275  typedef typename CV::const_iterator global_col_iterator;
276  for (global_col_iterator cit=pconstraintsv->begin(); cit!=pconstraintsv->end(); ++cit){
277  typedef typename global_col_iterator::value_type::first_type GlobalIndex;
278  const GlobalIndex & contributor = cit->first;
279 
280  typedef typename global_col_iterator::value_type::second_type ContributedMap;
281  typedef typename ContributedMap::const_iterator global_row_iterator;
282  const ContributedMap & contributed = cit->second;
283  global_row_iterator it = contributed.begin();
284  global_row_iterator eit = contributed.end();
285 
286  if(prerestrict)
287  x[contributor] = 0.;
288 
289  for(;it!=eit;++it)
290  {
291  // typename X::block_type block(x[it->first]);
292  // block *= it->second;
293  // x[contributor] += block;
294  x[contributor] += it->second * x[it->first]; // PB: 27 Sep 12 this was the old version
295  }
296  }
297  }
298 
299  // disable backtransform for empty transformation
300  template<typename X>
301  typename std::enable_if<
302  AlwaysTrue<X>::value && std::is_same<
303  CV,
305  >::value
306  >::type
307  backtransform(X & x, const bool prerestrict = false) const
308  {}
309 
310 
311  protected:
312 
314  template<typename GCView, typename T>
315  void eread (const GCView& globalcontainer_view, LocalMatrix<T>& localcontainer) const
316  {
317  for (int i = 0; i < localcontainer.N(); ++i)
318  for (int j = 0; j < localcontainer.M(); ++j)
319  localcontainer(i,j) = globalcontainer_view(i,j);
320  }
321 
323  template<typename T, typename GCView>
324  void ewrite (const LocalMatrix<T>& localcontainer, GCView& globalcontainer_view) const
325  {
326  for (int i = 0; i < localcontainer.N(); ++i)
327  for (int j = 0; j < localcontainer.M(); ++j)
328  globalcontainer_view(i,j) = localcontainer(i,j);
329  }
330 
332  template<typename T, typename GCView>
333  void eadd (const LocalMatrix<T>& localcontainer, GCView& globalcontainer_view) const
334  {
335  for (int i = 0; i < localcontainer.N(); ++i)
336  for (int j = 0; j < localcontainer.M(); ++j)
337  globalcontainer_view.add(i,j,localcontainer(i,j));
338  }
339 
341  template<typename M, typename GCView>
342  typename std::enable_if<
343  AlwaysTrue<M>::value && !std::is_same<
344  CV,
346  >::value
347  >::type
348  scatter_jacobian(M& local_container, GCView& global_container_view, bool symmetric_mode) const
349  {
350  typedef typename GCView::RowIndexCache LFSVIndexCache;
351  typedef typename GCView::ColIndexCache LFSUIndexCache;
352 
353  const LFSVIndexCache& lfsv_indices = global_container_view.rowIndexCache();
354  const LFSUIndexCache& lfsu_indices = global_container_view.colIndexCache();
355 
356  if (lfsv_indices.constraintsCachingEnabled() && lfsu_indices.constraintsCachingEnabled())
357  if (symmetric_mode)
358  etadd_symmetric(local_container,global_container_view);
359  else
360  etadd(local_container,global_container_view);
361  else
362  {
363 
364  typedef typename LFSVIndexCache::LocalFunctionSpace LFSV;
365  const LFSV& lfsv = lfsv_indices.localFunctionSpace();
366 
367  typedef typename LFSUIndexCache::LocalFunctionSpace LFSU;
368  const LFSU& lfsu = lfsu_indices.localFunctionSpace();
369 
370  // optionally clear out columns that belong to Dirichlet-constrained DOFs to keep matrix symmetric
371  if (symmetric_mode)
372  {
373  typedef typename LFSUIndexCache::ContainerIndex CI;
374 
375  for (size_t j = 0; j < lfsu_indices.size(); ++j)
376  {
377  const CI& container_index = lfsu_indices.containerIndex(j);
378  const typename CU::const_iterator cit = pconstraintsu->find(container_index);
379  if (cit != pconstraintsu->end())
380  {
381  // make sure we only have Dirichlet constraints
382  assert(cit->second.empty());
383  // clear out the current column
384  for (size_t i = 0; i < lfsv_indices.size(); ++i)
385  {
386  // we do not need to update the residual, since the solution
387  // (i.e. the correction) for the Dirichlet DOF is 0 by definition
388  local_container(lfsv,i,lfsu,j) = 0.0;
389  }
390  }
391  }
392  }
393 
394  // write entries without considering constraints.
395  // Dirichlet-constrained rows will be fixed in a postprocessing step.
396  for (auto it = local_container.begin(); it != local_container.end(); ++it)
397  {
398  // skip 0 entries because they might not be present in the pattern
399  if (*it == 0.0)
400  continue;
401  global_container_view.add(it.row(),it.col(),*it);
402  }
403  }
404  }
405 
406  // specialization for empty constraints container
407  template<typename M, typename GCView>
408  typename std::enable_if<
409  AlwaysTrue<M>::value && std::is_same<
410  CV,
412  >::value
413  >::type
414  scatter_jacobian(M& local_container, GCView& global_container_view, bool symmetric_mode) const
415  {
416  // write entries without considering constraints.
417  // Dirichlet-constrained rows will be fixed in a postprocessing step.
418  for (auto it = local_container.begin(); it != local_container.end(); ++it)
419  {
420  // skip 0 entries because they might not be present in the pattern
421  if (*it == 0.0)
422  continue;
423  global_container_view.add(it.row(),it.col(),*it);
424  }
425  }
426 
430  template<typename M, typename GCView>
431  void etadd_symmetric (M& localcontainer, GCView& globalcontainer_view) const
432  {
433 
434  typedef typename GCView::RowIndexCache LFSVIndexCache;
435  typedef typename GCView::ColIndexCache LFSUIndexCache;
436 
437  const LFSVIndexCache& lfsv_indices = globalcontainer_view.rowIndexCache();
438  const LFSUIndexCache& lfsu_indices = globalcontainer_view.colIndexCache();
439 
440  typedef typename LFSVIndexCache::LocalFunctionSpace LFSV;
441  const LFSV& lfsv = lfsv_indices.localFunctionSpace();
442 
443  typedef typename LFSUIndexCache::LocalFunctionSpace LFSU;
444  const LFSU& lfsu = lfsu_indices.localFunctionSpace();
445 
446  for (size_t j = 0; j < lfsu_indices.size(); ++j)
447  {
448  if (lfsu_indices.isConstrained(j) && lfsu_indices.isDirichletConstraint(j))
449  {
450  // clear out the current column
451  for (size_t i = 0; i < lfsv_indices.size(); ++i)
452  {
453  // we do not need to update the residual, since the solution
454  // (i.e. the correction) for the Dirichlet DOF is 0 by definition
455  localcontainer(lfsv,i,lfsu,j) = 0.0;
456  }
457  }
458  }
459 
460  // hand off to standard etadd() method
461  etadd(localcontainer,globalcontainer_view);
462  }
463 
464 
465  template<typename M, typename GCView>
466  void etadd (const M& localcontainer, GCView& globalcontainer_view) const
467  {
468 
469  typedef typename M::value_type T;
470 
471  typedef typename GCView::RowIndexCache LFSVIndexCache;
472  typedef typename GCView::ColIndexCache LFSUIndexCache;
473 
474  const LFSVIndexCache& lfsv_indices = globalcontainer_view.rowIndexCache();
475  const LFSUIndexCache& lfsu_indices = globalcontainer_view.colIndexCache();
476 
477  typedef typename LFSVIndexCache::LocalFunctionSpace LFSV;
478  const LFSV& lfsv = lfsv_indices.localFunctionSpace();
479 
480  typedef typename LFSUIndexCache::LocalFunctionSpace LFSU;
481  const LFSU& lfsu = lfsu_indices.localFunctionSpace();
482 
483  for (size_t i = 0; i<lfsv_indices.size(); ++i)
484  for (size_t j = 0; j<lfsu_indices.size(); ++j)
485  {
486 
487  if (localcontainer(lfsv,i,lfsu,j) == 0.0)
488  continue;
489 
490  const bool constrained_v = lfsv_indices.isConstrained(i);
491  const bool constrained_u = lfsu_indices.isConstrained(j);
492 
493  typedef typename LFSVIndexCache::ConstraintsIterator VConstraintsIterator;
494  typedef typename LFSUIndexCache::ConstraintsIterator UConstraintsIterator;
495 
496  if (constrained_v)
497  {
498  if (lfsv_indices.isDirichletConstraint(i))
499  continue;
500 
501  for (VConstraintsIterator vcit = lfsv_indices.constraintsBegin(i); vcit != lfsv_indices.constraintsEnd(i); ++vcit)
502  if (constrained_u)
503  {
504  if (lfsu_indices.isDirichletConstraint(j))
505  {
506  T value = localcontainer(lfsv,i,lfsu,j) * vcit->weight();
507  if (value != 0.0)
508  globalcontainer_view.add(vcit->containerIndex(),j,value);
509  }
510  else
511  {
512  for (UConstraintsIterator ucit = lfsu_indices.constraintsBegin(j); ucit != lfsu_indices.constraintsEnd(j); ++ucit)
513  {
514  T value = localcontainer(lfsv,i,lfsu,j) * vcit->weight() * ucit->weight();
515  if (value != 0.0)
516  globalcontainer_view.add(vcit->containerIndex(),ucit->containerIndex(),value);
517  }
518  }
519  }
520  else
521  {
522  T value = localcontainer(lfsv,i,lfsu,j) * vcit->weight();
523  if (value != 0.0)
524  globalcontainer_view.add(vcit->containerIndex(),j,value);
525  }
526  }
527  else
528  {
529  if (constrained_u)
530  {
531  if (lfsu_indices.isDirichletConstraint(j))
532  {
533  T value = localcontainer(lfsv,i,lfsu,j);
534  if (value != 0.0)
535  globalcontainer_view.add(i,j,value);
536  }
537  else
538  {
539  for (UConstraintsIterator ucit = lfsu_indices.constraintsBegin(j); ucit != lfsu_indices.constraintsEnd(j); ++ucit)
540  {
541  T value = localcontainer(lfsv,i,lfsu,j) * ucit->weight();
542  if (value != 0.0)
543  globalcontainer_view.add(i,ucit->containerIndex(),value);
544  }
545  }
546  }
547  else
548  globalcontainer_view.add(i,j,localcontainer(lfsv,i,lfsu,j));
549  }
550  }
551  }
552 
553 
554  template<typename Pattern, typename RI, typename CI>
555  typename std::enable_if<
557  >::type
558  add_diagonal_entry(Pattern& pattern, const RI& ri, const CI& ci) const
559  {
560  if (ri == ci)
561  pattern.add_link(ri,ci);
562  }
563 
564  template<typename Pattern, typename RI, typename CI>
565  typename std::enable_if<
567  >::type
568  add_diagonal_entry(Pattern& pattern, const RI& ri, const CI& ci) const
569  {}
570 
575  template<typename P, typename LFSVIndices, typename LFSUIndices, typename Index>
576  void add_entry(P & globalpattern,
577  const LFSVIndices& lfsv_indices, Index i,
578  const LFSUIndices& lfsu_indices, Index j) const
579  {
580  typedef typename LFSVIndices::ConstraintsIterator VConstraintsIterator;
581  typedef typename LFSUIndices::ConstraintsIterator UConstraintsIterator;
582 
583  const bool constrained_v = lfsv_indices.isConstrained(i);
584  const bool constrained_u = lfsu_indices.isConstrained(j);
585 
586  add_diagonal_entry(globalpattern,
587  lfsv_indices.containerIndex(i),
588  lfsu_indices.containerIndex(j)
589  );
590 
591  if(!constrained_v)
592  {
593  if (!constrained_u || lfsu_indices.isDirichletConstraint(j))
594  {
595  globalpattern.add_link(lfsv_indices.containerIndex(i),lfsu_indices.containerIndex(j));
596  }
597  else
598  {
599  for (UConstraintsIterator gurit = lfsu_indices.constraintsBegin(j); gurit != lfsu_indices.constraintsEnd(j); ++gurit)
600  globalpattern.add_link(lfsv_indices.containerIndex(i),gurit->containerIndex());
601  }
602  }
603  else
604  {
605  if (lfsv_indices.isDirichletConstraint(i))
606  {
607  globalpattern.add_link(lfsv_indices.containerIndex(i),lfsu_indices.containerIndex(j));
608  }
609  else
610  {
611  for(VConstraintsIterator gvrit = lfsv_indices.constraintsBegin(i); gvrit != lfsv_indices.constraintsEnd(i); ++gvrit)
612  {
613  if (!constrained_u || lfsu_indices.isDirichletConstraint(j))
614  {
615  globalpattern.add_link(gvrit->containerIndex(),lfsu_indices.containerIndex(j));
616  }
617  else
618  {
619  for (UConstraintsIterator gurit = lfsu_indices.constraintsBegin(j); gurit != lfsu_indices.constraintsEnd(j); ++gurit)
620  globalpattern.add_link(gvrit->containerIndex(),gurit->containerIndex());
621  }
622  }
623  }
624  }
625  }
626 
630  template<typename GFSV, typename GC, typename C>
631  void set_trivial_rows(const GFSV& gfsv, GC& globalcontainer, const C& c) const
632  {
633  typedef typename C::const_iterator global_row_iterator;
634  for (global_row_iterator cit = c.begin(); cit != c.end(); ++cit)
635  globalcontainer.clear_row(cit->first,1);
636  }
637 
638  template<typename GFSV, typename GC>
639  void set_trivial_rows(const GFSV& gfsv, GC& globalcontainer, const EmptyTransformation& c) const
640  {
641  }
642 
643  template<typename GFSV, typename GC>
644  void handle_dirichlet_constraints(const GFSV& gfsv, GC& globalcontainer) const
645  {
646  globalcontainer.flush();
647  set_trivial_rows(gfsv,globalcontainer,*pconstraintsv);
648  globalcontainer.finalize();
649  }
650 
651  /* constraints */
652  const CU* pconstraintsu;
653  const CV* pconstraintsv;
654  static CU emptyconstraintsu;
655  static CV emptyconstraintsv;
656  };
657 
658  template<typename B, typename CU, typename CV>
660  template<typename B, typename CU, typename CV>
662 
663  } // namespace PDELab
664 } // namespace Dune
665 
666 #endif // DUNE_PDELAB_GRIDOPERATOR_COMMON_ASSEMBLERUTILITIES_HH
GO::Traits::TrialGridFunctionSpace TrialGridFunctionSpace
The trial grid function space.
Definition: assemblerutilities.hh:26
std::enable_if< AlwaysTrue< X >::value &&!std::is_same< CV, EmptyTransformation >::value >::type backtransform(X &x, const bool prerestrict=false) const
Transforms a vector from to . If prerestrict == true then is applied instead of the full transform...
Definition: assemblerutilities.hh:273
std::enable_if< !std::is_same< RI, CI >::value >::type add_diagonal_entry(Pattern &pattern, const RI &ri, const CI &ci) const
Definition: assemblerutilities.hh:568
B::size_type SizeType
Definition: assemblerutilities.hh:185
void set_trivial_rows(const GFSV &gfsv, GC &globalcontainer, const C &c) const
insert dirichlet constraints for row and assemble T^T_U in constrained rows
Definition: assemblerutilities.hh:631
const CV & testConstraints() const
get the constraints on the test grid function space
Definition: assemblerutilities.hh:204
LocalAssemblerBase(const CU &cu, const CV &cv)
construct AssemblerSpace, with constraints
Definition: assemblerutilities.hh:193
GO::Traits::MatrixBackend MatrixBackend
The matrix backend of the grid operator.
Definition: assemblerutilities.hh:40
void set_trivial_rows(const GFSV &gfsv, GC &globalcontainer, const EmptyTransformation &c) const
Definition: assemblerutilities.hh:639
GO::Traits::RangeField RangeField
The field type of the range (residual).
Definition: assemblerutilities.hh:51
void eadd(const LocalMatrix< T > &localcontainer, GCView &globalcontainer_view) const
write local stiffness matrix for entity
Definition: assemblerutilities.hh:333
GO::Traits::DomainField DomainField
The field type of the domain (solution).
Definition: assemblerutilities.hh:44
std::enable_if< AlwaysTrue< M >::value &&!std::is_same< CV, EmptyTransformation >::value >::type scatter_jacobian(M &local_container, GCView &global_container_view, bool symmetric_mode) const
Scatter local jacobian to global container.
Definition: assemblerutilities.hh:348
SparsityLink(int i, int j)
Initialize all components.
Definition: assemblerutilities.hh:99
Definition: assemblerutilities.hh:22
std::enable_if< AlwaysTrue< X >::value &&!std::is_same< CV, EmptyTransformation >::value >::type forwardtransform(X &x, const bool postrestrict=false) const
Transforms a vector from to . If postrestrict == true then is applied instead of the full transfor...
Definition: assemblerutilities.hh:222
For backward compatibility – Do not use this!
Definition: adaptivity.hh:27
GO::Traits::JacobianField JacobianField
The field type of the jacobian.
Definition: assemblerutilities.hh:58
GO::Traits::TestGridFunctionSpaceConstraints TestGridFunctionSpaceConstraints
The type of the test grid function space constraints.
Definition: assemblerutilities.hh:36
void addLink(const LFSV &lfsv, std::size_t i, const LFSU &lfsu, std::size_t j)
Adds a link between DOF i of lfsv and DOF j of lfsu.
Definition: assemblerutilities.hh:149
Layout description for a sparse linear operator.
Definition: assemblerutilities.hh:129
int j() const
Return second component.
Definition: assemblerutilities.hh:110
void etadd_symmetric(M &localcontainer, GCView &globalcontainer_view) const
Add local matrix to global matrix, and apply Dirichlet constraints in a symmetric fashion...
Definition: assemblerutilities.hh:431
void add_entry(P &globalpattern, const LFSVIndices &lfsv_indices, Index i, const LFSUIndices &lfsu_indices, Index j) const
Adding matrix entry to pattern with respect to the constraints contributions. This assembles the entr...
Definition: assemblerutilities.hh:576
GO::Traits::Jacobian Jacobian
The type of the jacobian.
Definition: assemblerutilities.hh:61
int i() const
Return first component.
Definition: assemblerutilities.hh:104
A dense matrix for storing data associated with the degrees of freedom of a pair of LocalFunctionSpac...
Definition: localmatrix.hh:184
static const unsigned int value
Definition: gridfunctionspace/tags.hh:139
const CU * pconstraintsu
Definition: assemblerutilities.hh:652
std::enable_if< std::is_same< RI, CI >::value >::type add_diagonal_entry(Pattern &pattern, const RI &ri, const CI &ci) const
Definition: assemblerutilities.hh:558
std::enable_if< AlwaysTrue< X >::value &&std::is_same< CV, EmptyTransformation >::value >::type backtransform(X &x, const bool prerestrict=false) const
Definition: assemblerutilities.hh:307
std::enable_if< AlwaysTrue< M >::value &&std::is_same< CV, EmptyTransformation >::value >::type scatter_jacobian(M &local_container, GCView &global_container_view, bool symmetric_mode) const
Definition: assemblerutilities.hh:414
GO::Traits::Range Residual
The type of the range (residual).
Definition: assemblerutilities.hh:54
GO::Traits::Domain Solution
The type of the domain (solution).
Definition: assemblerutilities.hh:47
Entry in sparsity pattern.
Definition: assemblerutilities.hh:91
void etadd(const M &localcontainer, GCView &globalcontainer_view) const
Definition: assemblerutilities.hh:466
STL namespace.
MatrixBackend::template Pattern< Jacobian, TestGridFunctionSpace, TrialGridFunctionSpace > MatrixPattern
The matrix pattern.
Definition: assemblerutilities.hh:68
GO::BorderDOFExchanger BorderDOFExchanger
The helper class to exchange data on the processor boundary.
Definition: assemblerutilities.hh:71
void handle_dirichlet_constraints(const GFSV &gfsv, GC &globalcontainer) const
Definition: assemblerutilities.hh:644
const CU & trialConstraints() const
get the constraints on the trial grid function space
Definition: assemblerutilities.hh:198
GO::Traits::TrialGridFunctionSpaceConstraints TrialGridFunctionSpaceConstraints
The type of the trial grid function space constraints.
Definition: assemblerutilities.hh:33
static CU emptyconstraintsu
Definition: assemblerutilities.hh:654
std::enable_if< AlwaysTrue< X >::value &&std::is_same< CV, EmptyTransformation >::value >::type forwardtransform(X &x, const bool postrestrict=false) const
Definition: assemblerutilities.hh:258
Base class for local assembler.
Definition: assemblerutilities.hh:182
SparsityLink()
Standard constructor for uninitialized local index.
Definition: assemblerutilities.hh:95
const CV * pconstraintsv
Definition: assemblerutilities.hh:653
void ewrite(const LocalMatrix< T > &localcontainer, GCView &globalcontainer_view) const
write local stiffness matrix for entity
Definition: assemblerutilities.hh:324
LocalAssemblerBase()
construct AssemblerSpace
Definition: assemblerutilities.hh:188
Definition: constraintstransformation.hh:111
static CV emptyconstraintsv
Definition: assemblerutilities.hh:655
void eread(const GCView &globalcontainer_view, LocalMatrix< T > &localcontainer) const
read local stiffness matrix for entity
Definition: assemblerutilities.hh:315
GO::Traits::TestGridFunctionSpace TestGridFunctionSpace
The test grid function space.
Definition: assemblerutilities.hh:29