implicitResidual.hh

Go to the documentation of this file.
1 #ifndef implicitResidual_hh
2 #define implicitResidual_hh
3 
4 #include "estimator.hh"
5 
6 //TODO: Precise the includes
7 #include "hp2D.hh"
8 #include "formula.hh"
9 #include "basics/exceptions.hh"
10 
11 #define COMPUTE_D 0
12 
13 using concepts::Real;
14 
15 namespace estimator{
16 
17 
18 
36 template<class F>
37 class ImplicitResidual: public LocalEstimator<F>{
38 
39 public:
40 
41 
42 
43  virtual ImplicitResidual<F>* clone() const = 0;
44 
66  {
67  // DEBUGL(1, " add boundary data");
68  g_.push_back(&g);
69  gAttrbs_.push_back(nSet);
70 
71  //eAttrbs_ = eAttrbs_ || nSet;
72  //DEBUGL(1, "all used attributes : " << eAttrbs_);
73  //DEBUGL(1, " done... ");
74  }
75 
76 
77 
78 
79 
100  const concepts::ElementFormula<F>& h2)
101  {
102  throw conceptsException(concepts::MissingFeature("Not Supported"));
103  }
104 
105 
106 
107 protected:
108 
109 
126  const concepts::Vector<F>& sol):
127  LocalEstimator<F>(spc, sol){};
128 
129  virtual std::ostream& info(std::ostream& os) const{
130  return os << "Implicit Residual Error Estimator()";
131  }
132 
133  //structure for the billinearforms of the local problems, with multiplikatives constant
134  //concepts::Sequence< concepts::BilinearForm<F>* > bforms_;
135  //const coeffs of the bforms
136  //concepts::Sequence< F > c_bforms_;
137 
138  //local reference to the residual
139  //const concepts::ElementFormula<F>& res_;
140 
141  //Neumann formulas
143  //Neumann Attributes
145 
146 
147  //all used edge attributes on that error estimates are placed.
149 
150  //map from edge attribute to the corresponding boundary formula, i.e. the neumann rhs
151  //concepts::HashMap<const concepts::ElementFormula<F>* > g_;
152 
153 
154 };
155 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166 
214 template<class F>
216 
217 
218 
219 public:
220 
221 
235  const concepts::Vector<F>& sol,
236  const concepts::ElementFormula<F>* a = 0):
237  ImplicitResidual<F>(spc, sol), a_(a), sol_(sol){
238 
239 
240 
241  }
242 
243  //starts the error computation
244  void compute(){
245  computeError_();
246  }
247 
248 
249  void addRhs(concepts::LinearForm<F>& lform, Real w = 1.0){
250  lforms_.push_back(&lform);
251  lws_.push_back(w);
252  //DEBUGL(1, "lforms updated : " << lforms_);
253  }
254 
255  void addLhs(concepts::BilinearForm<F>& bform, Real w = 1.0){
256  bforms_.push_back(&bform);
257  ws_.push_back(w);
258  //DEBUGL(1, "bforms updated : " << bforms_);
259  }
260 
261 
262  //add information on how to compute the norm of local problem,
263  //e.g. energynorm, h1norm
264 
265  // if no weight is given, it is assumed to be constant 1
266 
267  //up to now everything in L2 norm
268  //
269  // example 1)
270  // func = Grad, w = 0 , s = 1.0
271  // implies norm contribution
272  // || Grad[u_{hp}] ||_{L^2(K)}
273  // on each element K.
274  //
275  // example 2)
276  // func = Value, w = ParsedFormula("(1/sqrt(x^2+y^2))") s = lambda
277  // implies the contribution
278  // lambda * || w * u_{hp} ||_{L^2(K)}
279  // on each element K where u_h is the approximate solution
281  norm_fs_.push_back(&func);
282  norm_ws_.push_back(w);
283  norm_s_.push_back(s);
284 
285  if( dynamic_cast<hp2D::Value<F>* >(&func))
286  norm_d_.push_back(1);
287  else if( dynamic_cast<hp2D::Grad<F>* >(&func) )
288  norm_d_.push_back(2);
289  else{
290  //easy extendable for Curl in 2d add dim = 2, for laplace 1 etc...
291  throw conceptsException(concepts::MissingFeature("Other function types currently not setted"));
292  }
293 
294  //DEBUGL(1, "functions updated : "<< norm_fs_)
295  }
296 
297 
298 
299 
300 
301  virtual const Real operator()() const {return this->operator()();}
302 
303  virtual ImplicitResidual2D<F>* clone() const{return new ImplicitResidual2D<F>(*this);}
304 
305 
306 protected:
307  virtual std::ostream& info(std::ostream& os) const {
308  return os << "Implicit Residual Error Estimator 2D()";
309  }
310 
311 private:
312 
313  //isotropic scalar coefficient function in higest derivative operator
315 
316  //the needed information to build local problems, i.e. the lfhs consisting of billinearforms
319 
320 
323 
324 
325 
326 
327 // //norm construction stuff
332 
333 
334 
335 
336 
337 
338 
340 
341  virtual void computeError_(){
342 
343  //mean should be multiplied, thats all from inside
344  //the billinearforms must be builded from outside anyway
345  if(a_)
346  throw conceptsException(concepts::MissingFeature("Coefficient not supported"));
347 
348 
349  //set up needed size fore errors
350  LocalEstimator<F>::locError_.resize(this->spc_.nelm());
351  concepts::Set<uint> zero; zero.insert(0);
352 
353 
354  //at this time we assume all inner edges have attribute 0.
355  hp2D::NeumannTraceSpace ntspc(this->spc_, zero , concepts::EdgeTraceType::MEAN);
356  concepts::ElementFormulaVector<1> apprxMean(ntspc,this->sol_, hp2D::Value<Real>());
357  //l form due to the apprx Mean
358  hp1D::Riesz<Real> lform_mean(apprxMean);
359 
360 
361 
362  const hp2D::hpAdaptiveSpaceH1* spc =dynamic_cast<const hp2D::hpAdaptiveSpaceH1*> (&(this->spc_));
364 
365  const concepts::BoundaryConditions& bc = *(spc->helper().bc());
366 
367  DEBUGL(COMPUTE_D, "start iteration");
368 
369  std::auto_ptr<hp2D::hpAdaptiveSpaceH1::Scan> sc(spc->scan());
370  while (!sc->eos()) {
371  concepts::ElementWithCell<Real>& element = (*sc)++;
372  const hp2D::Quad<Real>* quad = dynamic_cast<const hp2D::Quad<Real>*> (&element);
374 
376  msh.addCell(&quad->cell(),false);
377 
378  uint K = quad->support().key();
379 
380 
382 
383  //flag that marks cell intersects a boundary part that is free in sense
384  //of dof, i.e no Dirichlet Boundary, but for example a Neumann Boundary
385  //bool bnd_free = false; // <=> below set is non empty
386  //attributes of edges intersection those boundaries
387  concepts::Set<uint> bnd_free_attrb;
388 
389  const concepts::Edge* edge = 0;
390  for(uint i = 0 ; (edge = quad->support().edge(i)) != 0; ++i){
391 
392  //edge has a non default attribute, e.g. a setted boundary edge
393  // that is free in sense of dof, or a setted inner edge
394  if(edge->attrib().attrib() != 0){
395  //edge is free, so no dirichlet
396  if(bc(edge->attrib()).type() != concepts::Boundary::DIRICHLET)
397  bnd_free_attrb.insert(edge->attrib().attrib());
398  //copy global boundary conditions to the local
399  bc_K.add(edge->attrib().attrib(), bc( edge->attrib()).type());
400  //FIXME: if inner edges are not zero attributed,
401  // on the local problem this inner edge, as boundary edge
402  // is marked as FREE, this is ok in the freedom of dofs
403  // on that edge, but may lack in consistency
404  }
405  //edge is a default inner edge
406  else{
407  //we add neumann condition, as local problems will be defined as
408  bc_K.add(edge->attrib().attrib(), concepts::Boundary::NEUMANN);
409  }
410  }//for edges
411 
412  //the local polynomial degree, by default + 2
413  uint lP = 3;
414  const ushort* p = spc->prebuild().innerDof(quad->support());
415  if(p){
416  conceptsAssert( p[0] == p[1] , concepts::Assertion());
417  lP = p[0] + lP - 1 ;
418  }
419 
420  DEBUGL(COMPUTE_D, "on Cell K = " << K << " +++++++++++");
421 
422  //all neumann conditions
423  hp2D::hpAdaptiveSpaceH1 lSpc(msh, 0, lP, &bc_K);
424  lSpc.rebuild();
425 
426  //the current solution vector
427  concepts::Vector<Real> sol(lSpc.dim());
428  //the rhs vector
429  concepts::Vector<Real> rhs(lSpc.dim());
430 
431 
432  DEBUGL(COMPUTE_D, "start build system matrix ");
433 
434  concepts::SparseMatrix<F> A(lSpc.dim());
435  //build local system matrix
436  for(uint k = 0 ; k < bforms_.size(); ++k){
437  concepts::SparseMatrix<F> A_k(lSpc,*bforms_[k]);
438  A_k.addInto(A, ws_[k]);
439  }
440 
441  DEBUGL(COMPUTE_D, "done ...");
442 
443  //build rhs due to weak residual
444  for(uint l = 0 ; l < lforms_.size(); ++l)
445  rhs += (concepts::Vector<F>(lSpc, *(lforms_[l])) * lws_[l] );
446 
447  DEBUGL(COMPUTE_D, "rhs weak residual = " << rhs);
448 
449  //complete rhs with integral about the neumann part.
450 
451  if(ntspc.nelm()){
452  //tracespace on bdn edges, with attribute 0;
453  hp2D::TraceSpace tspc_mean(lSpc, zero);
454  DEBUGL(COMPUTE_D, " mean tracespace = " << tspc_mean);
455  concepts::Vector<F> rhs_mean(tspc_mean.dim());
456  std::auto_ptr<hp2D::TraceSpace::Scan> tsc(tspc_mean.scan());
457  while ( *(tsc.get()) ) {
458 
459  hp1D::BaseElement<F>& elm = (*tsc)++;
460 
461  DEBUGL(COMPUTE_D, " scan " << elm);
462  //hp space and therefore traceSpace are Real
463  const concepts::TMatrixBase<Real>& T = elm.T();
464  if (T.m() > 0) {
465  DEBUGL(COMPUTE_D, " T.m() > 0 ");
466  //key of first underlying element
467  //DEBUGL(COMPUTE_D, " uelm : " << ntspc.uelm(elm.support()));
468 
469  bool isFirst = ntspc.isFirstUelm(elm.support(), K);
470  DEBUGL(COMPUTE_D, "is First = " << isFirst);
471 
472  //uint K1 = ntspc.uelm(elm.support())[0].elm->support().key();
473  //scalar for the mean, depends on the first underlying element
474  Real s = (isFirst) ? 1.0 : -1.0;
475  DEBUGL(COMPUTE_D, " s = " << s);
478  DEBUGL(COMPUTE_D, " compute mean application");
479  lform_mean(elm, A);
480  DEBUGL(COMPUTE_D, " transpose and write into B");
481  A.transpose(); T(A, B); B.transpose();
482  DEBUGL(COMPUTE_D, " done ...");
483  DEBUGL(COMPUTE_D, " B = " << B);
484  for(int i = T.n(); i--;){
485  DEBUGL(COMPUTE_D, "write into rhs at " << T.index(i) << " while size = "<< rhs_mean.size());
486  rhs_mean[T.index(i)] += s * B(i,0);
487  }
488  }
489  DEBUGL(COMPUTE_D, "current contribution done ...");
490  }
491 
492 
493  DEBUGL(COMPUTE_D, "rhs mean residual = " << rhs_mean);
494  //update rhs;
495  rhs += rhs_mean;
496  }//if neumanntrace elements
497 
498  //Cell boundary intersects Domain boundary, e.g. dirichlet/neumann Boundary
499  //or a edge is inner edge, but setted with non-zero attribute
500  if(bnd_free_attrb.size()){
501  //neumann boundary data or sth else must be added
502  conceptsAssert(this->g_.size(), concepts::Assertion());
503 
504  for(uint i = 0 ; i < this->gAttrbs_.size(); ++i){
505  //cell has an edge for which neumann contribution must be taken into account
506  if((bnd_free_attrb&&this->gAttrbs_[i]).size()){
507 
508  //DEBUGL(1, "Found Neumann Cell, compute on it");
509 
510  hp2D::TraceSpace tspc_g(lSpc, this->gAttrbs_[i]);
511  hp1D::Riesz<F> lform_g(*(this->g_[i]));
512  //add local neumann data contribution
513  rhs += concepts::Vector<F>(tspc_g, lform_g);
514  }
515  }
516  }
517 
518  DEBUGL(COMPUTE_D, "final rhs = " << rhs);
519 
520 
521  //solve the problem
522  try {
523  // Solver
524  std::auto_ptr<concepts::Operator<F> > solver(0);
526  solver.reset(new concepts::Mumps<F>(A));
527  conceptsAssert(solver.get(), concepts::Assertion());
528  (*solver)(rhs, sol);
529  } catch (concepts::ExceptionBase& e) {
530  std::cout << e << std::endl;
531  throw conceptsException(concepts::MissingFeature("Local problem seems not to be solveable, not supported"));
532  return;
533  }
534 
535  //DEBUGL(1, "sol = " << sol);
536 
537  //set the error of the solution in the requested norm
538  Real error_K = 0;
539  for(uint n = 0; n < norm_fs_.size(); ++n){
540  const uint dim = norm_d_[n];
541  if(dim == 1){
542  concepts::ElementFormulaVector<1> sol_frm(lSpc, sol, *(norm_fs_[n]));
543  if(norm_ws_[n]){
544  Real contr = norm_s_[n] * concepts::L2product(lSpc, *(norm_ws_[n]) * sol_frm);
545  //DEBUGL(1, " contr(1) = " << contr << " s = " << norm_s_[n]);
546  error_K += contr;
547  }
548  else
549  error_K += norm_s_[n] * concepts::L2product(lSpc, sol_frm);
550  }
551  if(dim == 2){
552  concepts::ElementFormulaVector<2> sol_frm(lSpc, sol, *(norm_fs_[n]));
553  if(norm_ws_[n])
554  error_K += norm_s_[n] * concepts::L2product(lSpc, *(norm_ws_[n]) * sol_frm);
555  else{
556  Real contr = norm_s_[n] * concepts::L2product(lSpc, sol_frm);
557  //DEBUGL(1, " contr(2) = " << contr);
558  error_K += contr;
559  }
560  }
561  //DEBUGL(1, "current error : "<< error_K);
562  }
563 
564  //add current error squared
565  this->globError_ += error_K;
566 
567  //here the global error must be increased and later square rooted
568  LocalEstimator<F>::locError_[K] = std::sqrt(error_K);
569  DEBUGL(COMPUTE_D, "estimated error on K = " << K << " : " << LocalEstimator<F>::locError_[K])
570 
571  }//while
572 
573  // n^2 = sum n_K^2
574  this->globError_ = std::sqrt(this->globError_);
575  }
576 };
577 
578 
579 
580 
581 
582 
583 
584 
585 
586 
587 
588 
589 
590 
591 
592 //namespace hp3D{
593 //
594 //class ExplicitResidual3D: concepts::ExplicitResidual{
595 //public:
596 //
597 // template<typename F>
598 // ExplicitResidual3D(const concepts::SpaceOnCells<F>& spc, const concepts::Vector<F>& sol, const concepts::ElementFormula<F>& res);
599 //
600 //protected:
601 // virtual std::ostream& info(std::ostream& os) const{
602 // return os << "Explicit Residual Error Estimator()";
603 // }
604 //
605 //
606 //private:
607 // virtual void computeError_(const concepts::ElementFormula<F>& res, concepts::HashMap<Real>& jumpResidual);
608 // virtual void computeJumpPart_(concepts::HashMap<Real>& jumpResidual) const;
609 //};
610 //
611 //}
612 
613 
614 
615 
616 
617 
618 } // namespace estimator
619 
620 #endif // implicitResidual_hh
virtual uint index(const uint i) const =0
Maps the local index i to the global index.
concepts::Sequence< const concepts::ElementFormula< F > * > norm_ws_
The approximated function in a FE space.
Definition: function.hh:33
concepts::Sequence< concepts::BilinearForm< F > * > bforms_
bool transpose()
Transposes the matrix.
Definition: element.hh:277
concepts::Sequence< uint > norm_d_
Builds the trace space of an FE space.
Definition: traces.hh:52
const concepts::Vector< F > & sol_
concepts::Sequence< concepts::Set< uint > > gAttrbs_
virtual const Real operator()() const
const Attribute & attrib() const
Returns the attribute of the connector.
Definition: connector.hh:108
uint attrib() const
Returns the attribute.
Definition: connector.hh:38
#define conceptsException(exc)
Prepares an exception for throwing.
Definition: exceptions.hh:344
Base class for exceptions.
Definition: exceptions.hh:86
virtual uint nelm() const
Returns the number of NeumannTraceElements in the Space.
virtual const ushort * innerDof(const concepts::Connector2 &cntr) const
Returns a pointer to the maximal polynomial degrees of the inner degree of freedom in the cell quad.
void add(const Set< Attribute > &attrib, const Boundary &bcObject)
Adds a boundary condition with this attribute to the list of boundary conditions.
Real L2product(const ElementWithCell< G > &elm, const ElementFormula< F, G > &u, const ElementFormula< Real > *c=0, const Real t=0.0, IntegrationCell::intFormType form=IntegrationCell::ZERO)
Returns the L2 product or with c weighted L2 product of an element formula u over the cell belonging ...
Definition: integral.hh:214
Class for holding a general mutable mesh of 2D cell where cells and other 2D meshes can be added.
Definition: mutableMesh.hh:142
concepts::Sequence< Real > lws_
A the NeumannTrace space of a given 2D - Finite Element space.
#define conceptsAssert(cond, exc)
Assert that a certain condition is fulfilled.
Definition: exceptions.hh:394
virtual ImplicitResidual< F > * clone() const =0
virtual std::ostream & info(std::ostream &os) const
Abstract class representing the implicit residual a posteriori error estimator.
Timer and resource monitor.
concepts::Sequence< concepts::ElementFunction< F > * > norm_fs_
uint size() const
Definition: vector.hh:147
concepts::Sequence< Real > ws_
void addInto(Matrix< H > &dest, const I fact, const uint rowoffset=0, const uint coloffset=0) const
This matrix is added as block to the given matrix dest.
#define DEBUGL(doit, msg)
virtual uint dim() const
Definition: traces.hh:91
ImplicitResidual(const concepts::SpaceOnCells< F > &spc, const concepts::Vector< F > &sol)
Constructur of the explicit residual a posteriori error estimator.
Linear form on edges in nD.
Definition: linearForm.hh:67
Given a elliptic equation:
#define COMPUTE_D
const concepts::SubspaceHelper< F, SpacePreBuilder > & helper() const
void addLhs(concepts::BilinearForm< F > &bform, Real w=1.0)
uint m() const
Returns the number of rows.
Definition: tmatrix.hh:388
Vectorial formula created from a FE function.
concepts::Sequence< Real > norm_s_
Exception class for assertions.
Definition: exceptions.hh:258
void addBoundaryData(const concepts::Set< uint > &rSet, const concepts::ElementFormula< F > &h1, const concepts::ElementFormula< F > &h2)
Add boundary informations (i.e.
concepts::Sequence< concepts::LinearForm< F > * > lforms_
ImplicitResidual2D(const concepts::SpaceOnCells< F > &spc, const concepts::Vector< F > &sol, const concepts::ElementFormula< F > *a=0)
Constructor of the 2d implicit residual a posteriori Error estimator.
void rebuild(bool sameIndices=false)
Rebuilds the mesh and the elements due to adjustment orders.
Sequence with operations, output operator, and method of the particular element types.
Definition: sequence.hh:39
virtual std::ostream & info(std::ostream &os) const
virtual const concepts::Edge & support() const
Definition: element.hh:91
virtual const TMatrixBase< F > & T() const =0
Returns the T matrix of the element.
virtual Scan * scan() const
Returns a scanner to iterate over the elements of the space.
void setErrorNorm(concepts::ElementFunction< F > &func, const concepts::ElementFormula< F > *w=0, Real s=1.0)
Abstract class for a space.
Definition: space.hh:81
concepts::Set< uint > eAttrbs_
MUMPS : MUltifrontal Massively Parallel sparse direct Solver.
Definition: mumps.hh:72
Element matrix.
Definition: linearForm.hh:18
unsigned short ushort
Abbreviation for unsigned short.
Definition: typedefs.hh:48
Exception class to express a missing feature.
Definition: exceptions.hh:206
void addBoundaryData(const concepts::Set< uint > &nSet, const concepts::ElementFormula< F > &g)
Add boundary informations (i.e.
concepts::Sequence< const concepts::ElementFormula< F > * > g_
virtual ImplicitResidual2D< F > * clone() const
virtual Scan * scan() const
Returns a scanner to iterate over the elements of the space.
Definition: traces.hh:97
const concepts::ElementFormula< F > * a_
The gradient of the approximated function in a FE space.
Definition: function.hh:108
An edge in the topology.
Definition: topology.hh:73
uint n() const
Returns the number of columns.
Definition: tmatrix.hh:393
virtual uint dim() const
Returns the dimension of the space.
virtual void addCell(Cell *cell, bool holding=true)
Adds a cell to the mesh, which is by default hold by this object and will be deleted by its destructo...
double Real
Type normally used for a floating point number.
Definition: typedefs.hh:36
void addRhs(concepts::LinearForm< F > &lform, Real w=1.0)
Page URL: http://wiki.math.ethz.ch/bin/view/Concepts/WebHome
21 August 2020
© 2020 Eidgenössische Technische Hochschule Zürich