poisson_elements_with_singularity.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7 //LIC//
8 //LIC// This library is free software; you can redistribute it and/or
9 //LIC// modify it under the terms of the GNU Lesser General Public
10 //LIC// License as published by the Free Software Foundation; either
11 //LIC// version 2.1 of the License, or (at your option) any later version.
12 //LIC//
13 //LIC// This library is distributed in the hope that it will be useful,
14 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 //LIC// Lesser General Public License for more details.
17 //LIC//
18 //LIC// You should have received a copy of the GNU Lesser General Public
19 //LIC// License along with this library; if not, write to the Free Software
20 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 //LIC// 02110-1301 USA.
22 //LIC//
23 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 //LIC//
25 //LIC//====================================================================
26 //Header file for Poisson elements with singularity
27 #ifndef OOMPH_POISSON_ELEMENTS_WITH_SINGULARITY_HEADER
28 #define OOMPH_POISSON_ELEMENTS_WITH_SINGULARITY_HEADER
29 
30 
34 
35 //==================CLASS FOR THE ADDITIONAL UNKNOWN==================
48 //=====================================================================
49 template<class WRAPPED_POISSON_ELEMENT>
50 class SingularPoissonSolutionElement : public virtual GeneralisedElement
51 {
52  public :
53 
55  typedef double (*PoissonSingularFctPt)(const Vector<double>& x);
56 
58  typedef Vector<double> (*PoissonGradSingularFctPt)
59  (const Vector<double>& x);
60 
63  {
64  // Initialise Function pointer to singular function
66 
67  // Initialise Function pointer to gradient of the singular function
69 
70  // Initalise pointer to the wrapped Poisson element which will be used to
71  // compute the residual and which includes the point O
73 
74  // Initialise the pointer to the direction of the derivative used
75  // for the residual of this element
76  Direction_pt=0;
77 
78  // Create a single item of internal Data, storing one unknown which
79  // represents the unknown C.
80  add_internal_data(new Data(1));
81 
82  // Safe assumption: Singular fct does not satisfy Laplace's eqn
84 
85  } // End of constructor
86 
87 
92  {
94  }
95 
97  double c() const
98  {
99  return internal_data_pt(0)->value(0);
100  }
101 
105  void set_wrapped_poisson_element_pt(WRAPPED_POISSON_ELEMENT*
106  wrapped_poisson_el_pt,
107  const Vector<double>& s,
108  unsigned* direction_pt)
109  {
110  // Assign the pointer to the variable Wrapped_poisson_el_pt
111  Wrapped_poisson_el_pt = wrapped_poisson_el_pt;
112 
113  // Find number of nodes in the element
114  unsigned nnod=wrapped_poisson_el_pt->nnode();
115 
116  // Loop over the nodes of the element
117  for (unsigned j=0;j<nnod;j++)
118  {
119  // Add the node as external data in the SingularPoissonSolutionElement class
120  // because they affect the slope that we set to zero to
121  // determine the value of the amplitude C
122  add_external_data(Wrapped_poisson_el_pt->node_pt(j));
123  }
124 
125  // Assign the pointer to the local coordinate at which the residual
126  // will be computed
128 
129  // Assign the pointer to the direction at which the derivative used
130  // in the residual will be computed
131  Direction_pt = direction_pt;
132  }
133 
134 
137 
139  double singular_function(const Vector<double>& x) const
140  {
141 #ifdef PARANOID
142  if (Singular_fct_pt==0)
143  {
144  std::stringstream error_stream;
145  error_stream
146  << "Pointer to singular function hasn't been defined!"
147  << std::endl;
148  throw OomphLibError(
149  error_stream.str(),
152  }
153 #endif
154 
155  // Evaluate singular function
156  return (*Singular_fct_pt)(x);
157  }
158 
161  double u_bar(const Vector<double>& x)
162  {
163  // Find the value of C
164  double c=internal_data_pt(0)->value(0);
165 
166  // Value of ubar at the position x
167  return c*singular_function(x);
168  } // End of function
169 
172  {return Grad_singular_fct_pt;}
173 
175  Vector<double> grad_singular_function(const Vector<double>& x) const
176  {
177  // Find the dimension of the problem
178  unsigned cached_dim=Wrapped_poisson_el_pt->dim();
179 
180  // Declare the gradient of sing
181  Vector<double> dsingular(cached_dim);
182 
183 #ifdef PARANOID
184  if (Grad_singular_fct_pt==0)
185  {
186  std::stringstream error_stream;
187  error_stream
188  << "Pointer to gradient of singular function hasn't been defined!"
189  << std::endl;
190  throw OomphLibError(
191  error_stream.str(),
194  }
195 #endif
196 
197  // Evaluate gradient of the sing function
198  return (*Grad_singular_fct_pt)(x);
199  }
200 
202  Vector<double> grad_u_bar(const Vector<double>& x)
203  {
204  // Compute the gradient of sing
205  Vector<double> dsingular = grad_singular_function(x);
206 
207  // Initialise the gradient of ubar
208  unsigned cached_dim=Wrapped_poisson_el_pt->dim();
209  Vector<double> dubar(cached_dim);
210 
211  // Find the value of C
212  double c=internal_data_pt(0)->value(0);
213  for (unsigned i=0;i<cached_dim;i++)
214  {
215  dubar[i] = c*dsingular[i];
216  }
217 
218  return dubar;
219  } // End of function
220 
221 
222  // Compute local residual
223  void fill_in_contribution_to_residuals(Vector<double>& residual)
224  {
226  (residual,GeneralisedElement::Dummy_matrix,0);
227  }
228 
229  // Compute local residual and jacobian
230  void fill_in_contribution_to_jacobian(Vector<double>& residual,
231  DenseMatrix<double> &jacobian)
232  {
233  fill_in_generic_contribution_to_residuals(residual,jacobian,1);
234  }
235 
236 
237  private:
238 
240  void fill_in_generic_contribution_to_residuals(Vector<double>& residual,
241  DenseMatrix<double> &jacobian,
242  const unsigned& flag)
243  {
244  // Get the local eqn number of our one-and-only
245  // unknown
246  int eqn_number=internal_local_eqn(0,0);
247 
248  // Get the derivative
249  unsigned cached_dim=Wrapped_poisson_el_pt->dim();
250  Vector<double> flux(cached_dim);
252  double derivative = flux[*Direction_pt];
253 
254  // fill in the contribution to the residual
255  residual[eqn_number] = derivative;
256 
257  if (flag)
258  {
259  // Find the number of nodes in the Poisson element associated to the
260  // SingularPoissonSolutionElement class
261  unsigned n_node = Wrapped_poisson_el_pt->nnode();
262 
263  // Compute the derivatives of the shape functions of the poisson
264  // element associated to the SingularPoissonSolutionElement at the
265  // local coordinate S_in_wrapped_poisson_element_pt
266  Shape psi(n_node);
267  DShape dpsidx(n_node,cached_dim);
268  Wrapped_poisson_el_pt->dshape_eulerian(
269  S_in_wrapped_poisson_element,psi,dpsidx);
270 
271  // Loop over the nodes
272  for (unsigned j=0;j<n_node;j++)
273  {
274  // Find the local equation number of the node
275  int node_eqn_number = external_local_eqn(j,0);
276  if (node_eqn_number>=0)
277  {
278  // Add the contribution of the node to the local jacobian
279  jacobian(eqn_number,node_eqn_number) = dpsidx(j,*Direction_pt);
280  }
281 
282  }
283  }
284 
285  }
286 
288  WRAPPED_POISSON_ELEMENT* Wrapped_poisson_el_pt;
289 
292 
295 
298 
300  unsigned* Direction_pt;
301 
304 
305 }; // End of SingularPoissonSolutionElement Class
306 
307 
311 
312 
313 //=======================================================================
323 //=======================================================================
324 template<class BASIC_POISSON_ELEMENT>
326 {
327 
328  public:
329 
332  {
333  // Find the number of nodes in the element
334  unsigned n_node = this->nnode();
335 
336  // Initialise the vector of booleans indicating which
337  // node is subject to Dirichlet BC. The size of the
338  // vector is equal to the number
339  // of nodes in the element. By default, no node is subject
340  // to Dirichlet BC, so the vector is full of false.
341  Node_is_subject_to_dirichlet_bc.resize(n_node);
342  for (unsigned j=0;j<n_node;j++)
343  {
345  }
346 
347  // Initialise the vector of imposed values on the nodes subject
348  // to Dirichlet BC. The size of the vector is equal to the number
349  // of nodes in the element. If a node is not subject to Dirichlet
350  // BC, its imposed value is zero. By default, no node is subject
351  // to Dirichlet BC so the vector is full of zeros
352  Imposed_value_at_node.resize(n_node);
353  for (unsigned j=0;j<n_node;j++)
354  {
355  Imposed_value_at_node[j] = 0.0;
356  }
357 
358  } // End of constructor
359 
360 
363  void impose_dirichlet_bc_on_node(const unsigned& j)
364  {
366  }
367 
369  void undo_dirichlet_bc_on_node(const unsigned& j)
370  {
372  }
373 
376  {
377  unsigned n_node = this->nnode();
378  for (unsigned j=0;j<n_node;j++)
379  {
381  }
382  }
383 
385  void set_dirichlet_value_on_node(const unsigned& j,
386  const double& value)
387  {
389  }
390 
391 
398  {
399  return C_equation_elements_pt;
400  }
401 
402 
410  <BASIC_POISSON_ELEMENT> >* c_pt)
411  {
412  // Add the element
413  C_equation_elements_pt.push_back(c_pt);
414 
415  // Add the additional unknown of this object as external data in the
416  // Poisson element
417  this->add_external_data(c_pt->internal_data_pt(0));
418  }
419 
422  double u_bar(const unsigned& i,const Vector<double>& x) const
423  {
424  return C_equation_elements_pt[i]->u_bar(x);
425  }
426 
428  double singular_function(const unsigned& i, const Vector<double>& x) const
429  {
430  return C_equation_elements_pt[i]->singular_function(x);
431  }
432 
435  Vector<double> grad_u_bar(const unsigned i,const Vector<double>& x) const
436  {
437  return C_equation_elements_pt[i]->grad_u_bar(x);
438  }
439 
441  Vector<double> grad_singular_function(const unsigned& i,
442  const Vector<double>& x) const
443  {
444  return C_equation_elements_pt[i]->grad_singular_function(x);
445  }
446 
447 
450  double interpolated_u_poisson_fe_only(const Vector<double> &s) const
451  {
452  //Find number of nodes
453  const unsigned n_node = this->nnode();
454 
455  //Get the index at which the poisson unknown is stored
456  const unsigned u_nodal_index = this->u_index_poisson();
457 
458  //Local shape function
459  Shape psi(n_node);
460 
461  //Find values of shape function
462  this->shape(s,psi);
463 
464  //Initialise value of u
465  double interpolated_u = 0.0;
466 
467  // Add the contribution of u_FE
468  //Loop over the local nodes and sum
469  for(unsigned l=0;l<n_node;l++)
470  {
471  interpolated_u += this->nodal_value(l,u_nodal_index)*psi[l];
472  }
473 
474  return interpolated_u;
475  }
476 
478  inline double interpolated_u_poisson(const Vector<double> &s) const
479  {
480  //Find number of nodes
481  const unsigned n_node = this->nnode();
482 
483  //Get the index at which the poisson unknown is stored
484  const unsigned u_nodal_index = this->u_index_poisson();
485 
486  //Local shape function
487  Shape psi(n_node);
488 
489  //Find values of shape function
490  this->shape(s,psi);
491 
492  //Initialise value of u
493  double interpolated_u = 0.0;
494 
495  // Calculate the global coordinate associated to s
496  unsigned cached_dim=this->dim();
497  Vector<double> x(cached_dim,0.0);
498 
499  // Add the contribution of u_FE
500  //Loop over the local nodes and sum
501  for(unsigned l=0;l<n_node;l++)
502  {
503  interpolated_u += this->nodal_value(l,u_nodal_index)*psi[l];
504  for (unsigned i=0;i<cached_dim;i++)
505  {
506  x[i]+=this->raw_nodal_position(l,i)*psi(l);
507  }
508  }
509 
510  // Loop over the singularities
511  unsigned n_sing=C_equation_elements_pt.size();
512  for (unsigned i=0;i<n_sing;i++)
513  {
514  // Add the contribution of ubari
515  interpolated_u += u_bar(i,x);
516  }
517 
518  return(interpolated_u);
519  }
520 
522  void fill_in_contribution_to_residuals(Vector<double> &residuals)
523  {
524  //Call the generic residuals function with flag set to 0
525  //using a dummy matrix argument
527  residuals,GeneralisedElement::Dummy_matrix,0);
528  }
529 
532  void fill_in_contribution_to_jacobian(Vector<double> &residuals,
533  DenseMatrix<double> &jacobian)
534  {
535  //Call the generic routine with the flag set to 1
537  }
538 
539 
541  void output(std::ostream &outfile,const unsigned &nplot)
542  {
543  // Find the dimension of the problem
544  unsigned cached_dim = this->dim();
545 
546  //Vector of local coordinates
547  Vector<double> s(cached_dim);
548 
549  // Tecplot header info
550  outfile << this->tecplot_zone_string(nplot);
551 
552  // Loop over plot points
553  unsigned num_plot_points=this->nplot_points(nplot);
554  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
555  {
556 
557  // Get local coordinates of plot point
558  this->get_s_plot(iplot,nplot,s);
559 
560  Vector<double> x(cached_dim);
561  for(unsigned i=0;i<cached_dim;i++)
562  {
563  outfile << this->interpolated_x(s,i) << " ";
564  x[i] = this->interpolated_x(s,i);
565  }
566 
567  outfile << interpolated_u_poisson(s) << " "
570  << std::endl;
571 
572  }
573 
574  // Write tecplot footer (e.g. FE connectivity lists)
575  this->write_tecplot_zone_footer(outfile,nplot);
576  }
577 
578 
580  void compute_error(std::ostream &outfile,
581  FiniteElement::SteadyExactSolutionFctPt exact_soln_pt,
582  double& error, double& norm)
583  {
584 
585  // Initialise
586  error=0.0;
587  norm=0.0;
588 
589  // Find the dimension of the problem
590  unsigned cached_dim = this->dim();
591 
592  //Vector of local coordinates
593  Vector<double> s(cached_dim);
594 
595  // Vector for coordintes
596  Vector<double> x(cached_dim);
597 
598  //Find out how many nodes there are in the element
599  unsigned n_node = this->nnode();
600 
601  Shape psi(n_node);
602 
603  //Set the value of n_intpt
604  unsigned n_intpt = this->integral_pt()->nweight();
605 
606  // Tecplot
607  outfile << "ZONE" << std::endl;
608 
609  // Exact solution Vector (here a scalar)
610  Vector<double> exact_soln(1);
611 
612  //Loop over the integration points
613  for(unsigned ipt=0;ipt<n_intpt;ipt++)
614  {
615 
616  //Assign values of s
617  for(unsigned i=0;i<cached_dim;i++)
618  {
619  s[i] = this->integral_pt()->knot(ipt,i);
620  }
621 
622  //Get the integral weight
623  double w = this->integral_pt()->weight(ipt);
624 
625  // Get jacobian of mapping
626  double J=this->J_eulerian(s);
627 
628  //Premultiply the weights and the Jacobian
629  double W = w*J;
630 
631  // Get x position as Vector
632  this->interpolated_x(s,x);
633 
634  // Get FE function value
635  double u_fe=interpolated_u_poisson(s);
636 
637  // Get exact solution at this point
638  (*exact_soln_pt)(x,exact_soln);
639 
640  //Output x,y,...,error
641  for(unsigned i=0;i<cached_dim;i++)
642  {
643  outfile << x[i] << " ";
644  }
645  outfile << exact_soln[0] << " " << exact_soln[0]-u_fe << std::endl;
646 
647  // Add to error and norm
648  norm+=exact_soln[0]*exact_soln[0]*W;
649  error+=(exact_soln[0]-u_fe)*(exact_soln[0]-u_fe)*W;
650  }
651  }
652 
653 
654  private:
655 
658  Vector<double> &residuals,
659  DenseMatrix<double> &jacobian,
660  const unsigned& flag)
661  {
662  // Get the contribution from the underlying wrapped element first
663  BASIC_POISSON_ELEMENT::fill_in_generic_residual_contribution_poisson
664  (residuals,jacobian,flag);
665 
666  // Do all the singular functions satisfy laplace's eqn?
667  bool all_singular_functions_satisfy_laplace_equation=true;
668 
669  // Find the number of singularities
670  unsigned n_sing = C_equation_elements_pt.size();
671 
672  //Index at which the poisson unknown is stored
673  const unsigned u_nodal_index = this->u_index_poisson();
674 
675  // Find the dimension of the problem
676  unsigned cached_dim=this->dim();
677 
678  //Find out how many nodes there are
679  const unsigned n_node = this->nnode();
680 
681  // Find the local equation number of the additional unknowns
682  Vector<int> local_equation_number_C(n_sing);
683  for (unsigned i=0;i<n_sing;i++)
684  {
685  local_equation_number_C[i] =
686  this->external_local_eqn(i,0);
687  if (!(C_equation_elements_pt[i]->
688  singular_function_satisfies_laplace_equation()))
689  {
690  all_singular_functions_satisfy_laplace_equation=false;
691  }
692  }
693 
694  // Do we need to add the singular function's contribution to the
695  // residuals or do they vanish by themselves (mathematically)
696  if (!all_singular_functions_satisfy_laplace_equation)
697  {
698 
699  //Set up memory for the shape and test functions
700  Shape psi(n_node), test(n_node);
701  DShape dpsidx(n_node,cached_dim), dtestdx(n_node,cached_dim);
702 
703  //Set the value of n_intpt
704  const unsigned n_intpt = this->integral_pt()->nweight();
705 
706  //Integers to store the local equation and unknown numbers
707  int local_eqn=0;
708 
709  //Loop over the integration points
710  for(unsigned ipt=0;ipt<n_intpt;ipt++)
711 
712  {
713  //Get the integral weight
714  double w = this->integral_pt()->weight(ipt);
715 
716  //Call the derivatives of the shape and test functions
717  double J = this->dshape_and_dtest_eulerian_at_knot_poisson(ipt,psi,dpsidx,
718  test,dtestdx);
719 
720  //Premultiply the weights and the Jacobian
721  double W = w*J;
722 
723  //Calculate the global coordinate of the integration point
724  Vector<double> interpolated_x(cached_dim,0.0);
725  // Loop over nodes
726  for(unsigned l=0;l<n_node;l++)
727  {
728  // Loop over directions
729  for(unsigned j=0;j<cached_dim;j++)
730  {
731  interpolated_x[j] += this->raw_nodal_position(l,j)*psi(l);
732  }
733  }
734 
735  // Precompute singular fcts
736  Vector<Vector<double> > grad_u_bar_local(n_sing);
737  for (unsigned i=0;i<n_sing;i++)
738  {
739  grad_u_bar_local[i]=grad_u_bar(i,interpolated_x);
740  }
741  Vector<Vector<double> > grad_singular_function_local(n_sing);
742  for (unsigned i=0;i<n_sing;i++)
743  {
744  grad_singular_function_local[i]=grad_singular_function(i,interpolated_x);
745  }
746 
747  // Assemble residuals and Jacobian
748  //--------------------------------
749 
750  // The interior nodes
751  //-------------------
752 
753  // Loop over the test functions
754  for(unsigned l=0;l<n_node;l++)
755  {
756  //Get the local equation number
757  local_eqn = this->nodal_local_eqn(l,u_nodal_index);
758 
759  // If it is not pinned
760  if (local_eqn >= 0)
761  {
762  // IF it's not a boundary condition
764  {
765  // Add the contribution of the additional unknowns to the residual
766  for(unsigned i=0;i<n_sing;i++)
767  {
768  if (!(C_equation_elements_pt[i]->
769  singular_function_satisfies_laplace_equation()))
770  {
771  for (unsigned k=0;k<cached_dim;k++)
772  {
773  residuals[local_eqn] +=
774  grad_u_bar_local[i][k]*dtestdx(l,k)*W;
775  }
776  }
777  }
778 
779  // Calculate the jacobian
780  //-----------------------
781  if(flag)
782  {
783  // Loop over the singularities and add the
784  // contributions of the additional
785  // unknowns associated with them to the
786  // jacobian if they are not pinned
787  for (unsigned i=0;i<n_sing;i++)
788  {
789  if (!(C_equation_elements_pt[i]->
790  singular_function_satisfies_laplace_equation()))
791  {
792  if (local_equation_number_C[i]>=0)
793  {
794  for(unsigned d=0;d<cached_dim;d++)
795  {
796  jacobian(local_eqn,local_equation_number_C[i])
797  += grad_singular_function_local[i][d]*
798  dtestdx(l,d)*W;
799  }
800  }
801  }
802  }
803  }
804  }
805  }
806  } // end of loop over shape functions
807 
808  } // End of loop over integration points
809 
810  }
811 
812  // The Dirichlet nodes
813  //--------------------
814 
815  // Loop over the nodes to see if there is a node subject to
816  // Dirichlet BC
817  for (unsigned j=0;j<n_node;j++)
818  {
819  // If it is a dirichlet boundary condition
821  {
822  // Find the global coordinate of the node
823  Vector<double> global_coordinate_boundary_node(cached_dim);
824  for (unsigned d=0;d<cached_dim;d++)
825  {
826  global_coordinate_boundary_node[d] = this->raw_nodal_position(j,d);
827  }
828 
829  // If it is not pinned
830  int local_eqn_number_boundary_node =
831  this->nodal_local_eqn(j,u_nodal_index);
832  if (local_eqn_number_boundary_node >= 0)
833  {
834  // Add the contribution of the node unknown to the residual
835  residuals[local_eqn_number_boundary_node] =
836  this->raw_nodal_value(j,u_nodal_index);
837 
838  // Add the contribution of the additional unknowns to the residual
839  for (unsigned i=0;i<n_sing;i++)
840  {
841  residuals[local_eqn_number_boundary_node] +=
842  u_bar(i,global_coordinate_boundary_node);
843  }
844 
845  // Substract the value imposed by the Dirichlet BC from the residual
846  residuals[local_eqn_number_boundary_node] -= Imposed_value_at_node[j];
847 
848  if (flag)
849  {
850  // Loop over the nodes
851  for (unsigned l=0;l<n_node;l++)
852  {
853  // Find the equation number of the node
854  int local_unknown = this->nodal_local_eqn(l,u_nodal_index);
855 
856  // If it is not pinned
857  if (local_unknown >=0)
858  {
859  // Put to 0 the corresponding jacobian component
860  jacobian(local_eqn_number_boundary_node,local_unknown)=0.0;
861  }
862  }
863 
864  // Find the contribution of the node to the local jacobian
865  jacobian(local_eqn_number_boundary_node,
866  local_eqn_number_boundary_node) += 1.0;
867 
868  // Loop over the singularities
869  for (unsigned i=0;i<n_sing;i++)
870  {
871  // Find the contribution of the additional unknowns to the jacobian
872  int local_unknown=local_equation_number_C[i];
873  if (local_unknown>=0)
874  {
875  jacobian(local_eqn_number_boundary_node,
876  local_unknown) +=
877  singular_function(i,global_coordinate_boundary_node);
878  }
879  }
880 
881  }
882  } // End of check of the pin status of the node
883  } // End of check if the node is subject to Dirichlet BC-
884  } // End of loop over the nodes
885  } // End of function
886 
887 
891 
895 
898  Vector<double> Imposed_value_at_node;
899 
900 };
901 
902 
903 
904 #endif
905 
int i
Definition: BiCGSTAB_step_by_step.cpp:9
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
RowVector3d w
Definition: Matrix_resize_int.cpp:3
Definition: poisson_elements_with_singularity.h:326
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: poisson_elements_with_singularity.h:532
double singular_function(const unsigned &i, const Vector< double > &x) const
Evaluate i-th "raw" singular function at Eulerian position x.
Definition: poisson_elements_with_singularity.h:428
void fill_in_generic_residual_contribution_wrapped_poisson(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Overloaded fill-in function.
Definition: poisson_elements_with_singularity.h:657
Vector< double > grad_u_bar(const unsigned i, const Vector< double > &x) const
Definition: poisson_elements_with_singularity.h:435
void undo_dirichlet_bc_on_all_nodes()
Undo Dirichlet BCs on all nodes.
Definition: poisson_elements_with_singularity.h:375
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector (wrapper)
Definition: poisson_elements_with_singularity.h:522
double interpolated_u_poisson(const Vector< double > &s) const
Overloaded version including the singular contributions.
Definition: poisson_elements_with_singularity.h:478
void add_c_equation_element_pt(SingularPoissonSolutionElement< PoissonElementWithSingularity< BASIC_POISSON_ELEMENT > > *c_pt)
Definition: poisson_elements_with_singularity.h:408
PoissonElementWithSingularity()
Constructor.
Definition: poisson_elements_with_singularity.h:331
vector< bool > Node_is_subject_to_dirichlet_bc
Definition: poisson_elements_with_singularity.h:894
void set_dirichlet_value_on_node(const unsigned &j, const double &value)
Specify Dirichlet boundary value for j-th local node.
Definition: poisson_elements_with_singularity.h:385
Vector< SingularPoissonSolutionElement< PoissonElementWithSingularity< BASIC_POISSON_ELEMENT > > * > C_equation_elements_pt
Vector of pointers to SingularPoissonSolutionElement objects.
Definition: poisson_elements_with_singularity.h:890
void undo_dirichlet_bc_on_node(const unsigned &j)
Undo Dirichlet BCs on jth node.
Definition: poisson_elements_with_singularity.h:369
Vector< SingularPoissonSolutionElement< PoissonElementWithSingularity< BASIC_POISSON_ELEMENT > > * > c_equation_elements_pt()
Definition: poisson_elements_with_singularity.h:397
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Compute error.
Definition: poisson_elements_with_singularity.h:580
void impose_dirichlet_bc_on_node(const unsigned &j)
Definition: poisson_elements_with_singularity.h:363
double interpolated_u_poisson_fe_only(const Vector< double > &s) const
Definition: poisson_elements_with_singularity.h:450
double u_bar(const unsigned &i, const Vector< double > &x) const
Definition: poisson_elements_with_singularity.h:422
Vector< double > Imposed_value_at_node
Definition: poisson_elements_with_singularity.h:898
void output(std::ostream &outfile, const unsigned &nplot)
Overloaded output fct: x, y [,z], u, u_fe_only, u-u_fe_only.
Definition: poisson_elements_with_singularity.h:541
Vector< double > grad_singular_function(const unsigned &i, const Vector< double > &x) const
Evaluate the gradient of the i-th "raw" singular at Eulerian position x.
Definition: poisson_elements_with_singularity.h:441
Definition: poisson_elements_with_singularity.h:51
PoissonGradSingularFctPt & grad_singular_fct_pt()
Access function to pointer to the gradient of sing function.
Definition: poisson_elements_with_singularity.h:171
double u_bar(const Vector< double > &x)
Definition: poisson_elements_with_singularity.h:161
void set_wrapped_poisson_element_pt(WRAPPED_POISSON_ELEMENT *wrapped_poisson_el_pt, const Vector< double > &s, unsigned *direction_pt)
Definition: poisson_elements_with_singularity.h:105
Vector< double > S_in_wrapped_poisson_element
Local coordinates of singularity in the wrapped Poisson element.
Definition: poisson_elements_with_singularity.h:297
double singular_function(const Vector< double > &x) const
Evaluate singular function at Eulerian position x.
Definition: poisson_elements_with_singularity.h:139
WRAPPED_POISSON_ELEMENT * Wrapped_poisson_el_pt
Pointer to Poisson element that contains the singularity.
Definition: poisson_elements_with_singularity.h:288
bool & singular_function_satisfies_laplace_equation()
Definition: poisson_elements_with_singularity.h:91
PoissonGradSingularFctPt Grad_singular_fct_pt
Pointer to the gradient of the singular function.
Definition: poisson_elements_with_singularity.h:294
double c() const
Find the value of the unknown C.
Definition: poisson_elements_with_singularity.h:97
void fill_in_generic_contribution_to_residuals(Vector< double > &residual, DenseMatrix< double > &jacobian, const unsigned &flag)
Compute local residual, and, if flag=1, local jacobian matrix.
Definition: poisson_elements_with_singularity.h:240
bool Singular_function_satisfies_laplace_equation
Does singular fct satisfy Laplace's eqn?
Definition: poisson_elements_with_singularity.h:303
unsigned * Direction_pt
Direction of the derivative used for the residual of the element.
Definition: poisson_elements_with_singularity.h:300
Vector< double > grad_singular_function(const Vector< double > &x) const
Evaluate the gradient of the sing function at Eulerian position x.
Definition: poisson_elements_with_singularity.h:175
PoissonSingularFctPt Singular_fct_pt
Pointer to singular function.
Definition: poisson_elements_with_singularity.h:291
SingularPoissonSolutionElement()
Constructor.
Definition: poisson_elements_with_singularity.h:62
PoissonSingularFctPt & singular_fct_pt()
Access function to pointer to singular function.
Definition: poisson_elements_with_singularity.h:136
void fill_in_contribution_to_residuals(Vector< double > &residual)
Definition: poisson_elements_with_singularity.h:223
Vector< double >(* PoissonGradSingularFctPt)(const Vector< double > &x)
Function pointer to the gradient of the singular function:
Definition: poisson_elements_with_singularity.h:59
double(* PoissonSingularFctPt)(const Vector< double > &x)
Function pointer to the singular function:
Definition: poisson_elements_with_singularity.h:55
void fill_in_contribution_to_jacobian(Vector< double > &residual, DenseMatrix< double > &jacobian)
Definition: poisson_elements_with_singularity.h:230
Vector< double > grad_u_bar(const Vector< double > &x)
Gradient of ubar (including the constant!)
Definition: poisson_elements_with_singularity.h:202
Matrix< Type, Size, 1 > Vector
\cpp11 SizeƗ1 vector of type Type.
Definition: Eigen/Eigen/src/Core/Matrix.h:515
RealScalar s
Definition: level1_cplx_impl.h:130
char char char int int * k
Definition: level2_impl.h:374
squared absolute value
Definition: GlobalFunctions.h:87
squared absolute sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2 sa Eigen::abs2 DOXCOMMA Eigen::pow DOXCOMMA ArrayBase::square nearest sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round nearest integer not less than the given sa Eigen::floor DOXCOMMA ArrayBase::ceil not a number test
Definition: GlobalFunctions.h:109
void flux(const double &time, const Vector< double > &x, double &flux)
Get flux applied along boundary x=0.
Definition: pretend_melt.cc:59
void exact_soln(const double &time, const Vector< double > &x, Vector< double > &soln)
Definition: unstructured_two_d_curved.cc:301
int error
Definition: calibrate.py:297
void shape(const double &s, double *Psi)
Definition: shape.h:564
@ W
Definition: quadtree.h:63
list x
Definition: plotDoE.py:28
Definition: indexed_view.cpp:20
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2