multi_poisson_elements.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 MultiPoisson elements
27 #ifndef OOMPH_MULTI_POISSON_ELEMENTS_HEADER
28 #define OOMPH_MULTI_POISSON_ELEMENTS_HEADER
29 
30 
31 // Config header generated by autoconfig
32 #ifdef HAVE_CONFIG_H
33  #include <oomph-lib-config.h>
34 #endif
35 
36 #include<sstream>
37 
38 //OOMPH-LIB headers
39 #include "../generic/projection.h"
40 #include "../generic/nodes.h"
41 #include "../generic/Qelements.h"
42 #include "../generic/oomph_utilities.h"
43 
44 
45 
46 namespace oomph
47 {
48 
49 //=============================================================
62 //=============================================================
63  template <unsigned DIM, unsigned NFIELDS>
64 class MultiPoissonEquations : public virtual FiniteElement
65 {
66 
67 public:
68 
71  typedef void (*MultiPoissonSourceFctPt)(const Vector<double>& x,
72  Vector<double>& f);
73 
74 
77  {}
78 
81  {
82  BrokenCopy::broken_copy("MultiPoissonEquations");
83  }
84 
92  virtual inline unsigned u_index_multi_poisson(const unsigned& i) const
93  {return i;}
94 
95 
98  unsigned ndof_types() const
99  {
100  return NFIELDS;
101  }
102 
110  std::list<std::pair<unsigned long,unsigned> >& block_lookup_list) const
111  {
112  // temporary pair (used to store block lookup prior to being added to list
113  std::pair<unsigned,unsigned> block_lookup;
114 
115  // number of nodes
116  const unsigned n_node = this->nnode();
117 
118  //Integer storage for local unknown
119  int local_unknown=0;
120 
121  //Loop over the nodes
122  for(unsigned n=0;n<n_node;n++)
123  {
124  //Loop over fields
125  for(unsigned i=0;i<NFIELDS;i++)
126  {
127  //Index at which the multi_poisson unknown is stored
128  unsigned u_nodal_index = u_index_multi_poisson(i);
129 
130  //Get the local equation
131  local_unknown = nodal_local_eqn(n,u_nodal_index);
132 
133  // ignore pinned values
134  if (local_unknown >= 0)
135  {
136  // store block lookup in temporary pair: First entry in pair
137  // is global equation number; second entry is block type
138  block_lookup.first = this->eqn_number(local_unknown);
139  block_lookup.second = i;
140 
141  // add to list
142  block_lookup_list.push_front(block_lookup);
143 
144  }
145  }
146  }
147  }
148 
149 
152  unsigned nscalar_paraview() const
153  {
154  return NFIELDS;
155  }
156 
159  void scalar_value_paraview(std::ofstream& file_out,
160  const unsigned& i,
161  const unsigned& nplot) const
162  {
163 #ifdef PARANOID
164  if (i>=NFIELDS)
165  {
166  std::stringstream error_stream;
167  error_stream
168  << "MultiPoisson elements only stores "
169  << NFIELDS << " fields so i "
170  << i << " is illegal." << std::endl;
171  throw OomphLibError(
172  error_stream.str(),
175  }
176 #endif
177 
178  unsigned local_loop=this->nplot_points_paraview(nplot);
179  for(unsigned j=0;j<local_loop;j++)
180  {
181  // Get the local coordinate of the required plot point
182  Vector<double> s(DIM);
183  this->get_s_plot(j,nplot,s);
184 
185  file_out << this->interpolated_u_multi_poisson(i,s)
186  << std::endl;
187  }
188  }
189 
193  std::string scalar_name_paraview(const unsigned& i) const
194  {
195 
196 #ifdef PARANOID
197  if (i>=NFIELDS)
198  {
199  std::stringstream error_stream;
200  error_stream
201  << "MultiPoisson elements only stores "
202  << NFIELDS << " fields so i "
203  << i << " is illegal." << std::endl;
204  throw OomphLibError(
205  error_stream.str(),
208  }
209 #endif
210 
211  return "MultiPoisson solution"+StringConversion::to_string(i);
212  }
213 
215  void output(std::ostream &outfile)
216  {
217  const unsigned n_plot=5;
218  output(outfile,n_plot);
219  }
220 
223  void output(std::ostream &outfile, const unsigned &n_plot);
224 
226  void output(FILE* file_pt)
227  {
228  const unsigned n_plot=5;
229  output(file_pt,n_plot);
230  }
231 
234  void output(FILE* file_pt, const unsigned &n_plot);
235 
237  void output_fct(std::ostream &outfile, const unsigned &n_plot,
239 
243  virtual void output_fct(std::ostream &outfile, const unsigned &n_plot,
244  const double& time,
246  exact_soln_pt)
247  {
248  throw OomphLibError(
249  "There is no time-dependent output_fct() for MultiPoisson elements ",
252  }
253 
254 
256  void compute_error(std::ostream &outfile,
258  double& error, double& norm);
259 
260 
262  void compute_error(std::ostream &outfile,
264  const double& time, double& error, double& norm)
265  {
266  throw OomphLibError(
267  "There is no time-dependent compute_error() for MultiPoisson elements",
270  }
271 
273  double*& beta_pt() {return Beta_pt;}
274 
277 
280 
285  inline virtual void get_source_multi_poisson(const unsigned& ipt,
286  const Vector<double>& x,
287  Vector<double>& source) const
288  {
289  //If no source function has been set, return zero
290  if(Source_fct_pt==0)
291  {
292  for (unsigned i=0;i<NFIELDS;i++)
293  {
294  source[i] = 0.0;
295  }
296  }
297  else
298  {
299  // Get source strength
300  (*Source_fct_pt)(x,source);
301  }
302  }
303 
304 
307  {
308  abort();
309 
310  /* //Find out how many nodes there are in the element */
311  /* const unsigned n_node = nnode(); */
312 
313  /* //Get the index at which the unknown is stored */
314  /* const unsigned u_nodal_index = u_index_multi_poisson(); */
315 
316  /* //Set up memory for the shape and test functions */
317  /* Shape psi(n_node); */
318  /* DShape dpsidx(n_node,DIM); */
319 
320  /* //Call the derivatives of the shape and test functions */
321  /* dshape_eulerian(s,psi,dpsidx); */
322 
323  /* //Initialise to zero */
324  /* for(unsigned j=0;j<DIM;j++) */
325  /* { */
326  /* flux[j] = 0.0; */
327  /* } */
328 
329  /* // Loop over nodes */
330  /* for(unsigned l=0;l<n_node;l++) */
331  /* { */
332  /* //Loop over derivative directions */
333  /* for(unsigned j=0;j<DIM;j++) */
334  /* { */
335  /* flux[j] += this->nodal_value(l,u_nodal_index)*dpsidx(l,j); */
336  /* } */
337  /* } */
338  }
339 
340 
343  {
344  //Call the generic residuals function with flag set to 0
345  //using a dummy matrix argument
348  }
349 
350 
354  DenseMatrix<double> &jacobian)
355  {
356  //Call the generic routine with the flag set to 1
358  }
359 
360 
361 
364  inline double interpolated_u_multi_poisson(const unsigned& i,
365  const Vector<double> &s) const
366  {
367  //Find number of nodes
368  const unsigned n_node = nnode();
369 
370  //Get the index at which the multi_poisson unknown is stored
371  const unsigned u_nodal_index = u_index_multi_poisson(i);
372 
373  //Local shape function
374  Shape psi(n_node);
375 
376  //Find values of shape function
377  shape(s,psi);
378 
379  //Initialise value of u
380  double interpolated_u = 0.0;
381 
382  //Loop over the local nodes and sum
383  for(unsigned l=0;l<n_node;l++)
384  {
385  interpolated_u += this->nodal_value(l,u_nodal_index)*psi[l];
386  }
387 
388  return(interpolated_u);
389  }
390 
391 
393  unsigned self_test();
394 
395 
396 protected:
397 
401  (const Vector<double> &s,
402  Shape &psi,
403  DShape &dpsidx, Shape &test,
404  DShape &dtestdx) const=0;
405 
406 
410  (const unsigned &ipt,
411  Shape &psi,
412  DShape &dpsidx,
413  Shape &test,
414  DShape &dtestdx)
415  const=0;
416 
421  const unsigned &ipt,
422  Shape &psi,
423  DShape &dpsidx,
424  RankFourTensor<double> &d_dpsidx_dX,
425  Shape &test,
426  DShape &dtestdx,
427  RankFourTensor<double> &d_dtestdx_dX,
428  DenseMatrix<double> &djacobian_dX) const=0;
429 
433  Vector<double> &residuals, DenseMatrix<double> &jacobian,
434  const unsigned& flag);
435 
438 
440  double* Beta_pt;
441 
442 };
443 
444 
445 
446 
447 
448 
452 
453 
454 
455 //======================================================================
458 //======================================================================
459  template <unsigned DIM, unsigned NNODE_1D, unsigned NFIELDS>
460  class QMultiPoissonElement : public virtual QElement<DIM,NNODE_1D>,
461  public virtual MultiPoissonEquations<DIM,NFIELDS>
462 {
463 
464 private:
465 
468  static const unsigned Initial_Nvalue;
469 
470  public:
471 
472 
476  MultiPoissonEquations<DIM,NFIELDS>()
477  {}
478 
481  {
482  BrokenCopy::broken_copy("QMultiPoissonElement");
483  }
484 
487  inline unsigned required_nvalue(const unsigned &n) const
488  {return Initial_Nvalue;}
489 
492  void output(std::ostream &outfile)
494 
495 
498  void output(std::ostream &outfile, const unsigned &n_plot)
500 
501 
504  void output(FILE* file_pt)
506 
507 
510  void output(FILE* file_pt, const unsigned &n_plot)
512 
513 
516  void output_fct(std::ostream &outfile, const unsigned &n_plot,
518  {MultiPoissonEquations<DIM,NFIELDS>::output_fct(outfile,n_plot,exact_soln_pt);}
519 
520 
521 
525  void output_fct(std::ostream &outfile, const unsigned &n_plot,
526  const double& time,
529  exact_soln_pt);}
530 
531 
532  protected:
533 
536  const Vector<double> &s, Shape &psi, DShape &dpsidx,
537  Shape &test, DShape &dtestdx) const;
538 
539 
543  (const unsigned& ipt,
544  Shape &psi,
545  DShape &dpsidx,
546  Shape &test,
547  DShape &dtestdx)
548  const;
549 
554  const unsigned &ipt,
555  Shape &psi,
556  DShape &dpsidx,
557  RankFourTensor<double> &d_dpsidx_dX,
558  Shape &test,
559  DShape &dtestdx,
560  RankFourTensor<double> &d_dtestdx_dX,
561  DenseMatrix<double> &djacobian_dX) const;
562 
563 };
564 
565 
566 
567 
568 //Inline functions:
569 
570 
571 //======================================================================
576 //======================================================================
577  template<unsigned DIM, unsigned NNODE_1D, unsigned NFIELDS>
580  const Vector<double> &s,
581  Shape &psi,
582  DShape &dpsidx,
583  Shape &test,
584  DShape &dtestdx) const
585  {
586  //Call the geometrical shape functions and derivatives
587  const double J = this->dshape_eulerian(s,psi,dpsidx);
588 
589  //Set the test functions equal to the shape functions
590  test = psi;
591  dtestdx= dpsidx;
592 
593  //Return the jacobian
594  return J;
595  }
596 
597 
598 
599 
600 //======================================================================
605 //======================================================================
606 template<unsigned DIM, unsigned NNODE_1D, unsigned NFIELDS>
609  const unsigned &ipt,
610  Shape &psi,
611  DShape &dpsidx,
612  Shape &test,
613  DShape &dtestdx) const
614 {
615  //Call the geometrical shape functions and derivatives
616  const double J = this->dshape_eulerian_at_knot(ipt,psi,dpsidx);
617 
618  //Set the pointers of the test functions
619  test = psi;
620  dtestdx = dpsidx;
621 
622  //Return the jacobian
623  return J;
624 }
625 
626 
627 
628 //======================================================================
635 //======================================================================
636 template<unsigned DIM, unsigned NNODE_1D, unsigned NFIELDS>
639  const unsigned &ipt,
640  Shape &psi,
641  DShape &dpsidx,
642  RankFourTensor<double> &d_dpsidx_dX,
643  Shape &test,
644  DShape &dtestdx,
645  RankFourTensor<double> &d_dtestdx_dX,
646  DenseMatrix<double> &djacobian_dX) const
647  {
648  // Call the geometrical shape functions and derivatives
649  const double J = this->dshape_eulerian_at_knot(ipt,psi,dpsidx,
650  djacobian_dX,d_dpsidx_dX);
651 
652  // Set the pointers of the test functions
653  test = psi;
654  dtestdx = dpsidx;
655  d_dtestdx_dX = d_dpsidx_dX;
656 
657  //Return the jacobian
658  return J;
659 }
660 
661 
662 
666 
667 
668 
669 //=======================================================================
674 //=======================================================================
675 template<unsigned DIM, unsigned NNODE_1D, unsigned NFIELDS>
676  class FaceGeometry<QMultiPoissonElement<DIM,NNODE_1D,NFIELDS> >:
677  public virtual QElement<DIM-1,NNODE_1D>
678 {
679 
680  public:
681 
684  FaceGeometry() : QElement<DIM-1,NNODE_1D>() {}
685 
686 };
687 
691 
692 
693 //=======================================================================
695 //=======================================================================
696 template<unsigned NNODE_1D, unsigned NFIELDS>
697  class FaceGeometry<QMultiPoissonElement<1,NNODE_1D,NFIELDS> >:
698  public virtual PointElement
699  {
700 
701  public:
702 
706 
707 };
708 
709 
710 // hierher re-enable at some point?
711 
715 
716 
717 /* //========================================================== */
718 /* /// MultiPoisson upgraded to become projectable */
719 /* //========================================================== */
720 /* template<class POISSON_ELEMENT> */
721 /* class ProjectableMultiPoissonElement : */
722 /* public virtual ProjectableElement<POISSON_ELEMENT> */
723 /* { */
724 
725 /* public: */
726 
727 /* /// Specify the values associated with field fld. */
728 /* /// The information is returned in a vector of pairs which comprise */
729 /* /// the Data object and the value within it, that correspond to field fld. */
730 /* Vector<std::pair<Data*,unsigned> > data_values_of_field(const unsigned& fld) */
731 /* { */
732 
733 /* #ifdef PARANOID */
734 /* if (fld!=0) */
735 /* { */
736 /* std::stringstream error_stream; */
737 /* error_stream */
738 /* << "MultiPoisson elements only store a single field so fld must be 0 rather" */
739 /* << " than " << fld << std::endl; */
740 /* throw OomphLibError( */
741 /* error_stream.str(), */
742 /* OOMPH_CURRENT_FUNCTION, */
743 /* OOMPH_EXCEPTION_LOCATION); */
744 /* } */
745 /* #endif */
746 
747 /* // Create the vector */
748 /* unsigned nnod=this->nnode(); */
749 /* Vector<std::pair<Data*,unsigned> > data_values(nnod); */
750 
751 /* // Loop over all nodes */
752 /* for (unsigned j=0;j<nnod;j++) */
753 /* { */
754 /* // Add the data value associated field: The node itself */
755 /* data_values[j]=std::make_pair(this->node_pt(j),fld); */
756 /* } */
757 
758 /* // Return the vector */
759 /* return data_values; */
760 /* } */
761 
762 /* /// Number of fields to be projected: Just one */
763 /* unsigned nfields_for_projection() */
764 /* { */
765 /* return 1; */
766 /* } */
767 
768 /* /// Number of history values to be stored for fld-th field */
769 /* /// (includes current value!) */
770 /* unsigned nhistory_values_for_projection(const unsigned &fld) */
771 /* { */
772 /* #ifdef PARANOID */
773 /* if (fld!=0) */
774 /* { */
775 /* std::stringstream error_stream; */
776 /* error_stream */
777 /* << "MultiPoisson elements only store a single field so fld must be 0 rather" */
778 /* << " than " << fld << std::endl; */
779 /* throw OomphLibError( */
780 /* error_stream.str(), */
781 /* OOMPH_CURRENT_FUNCTION, */
782 /* OOMPH_EXCEPTION_LOCATION); */
783 /* } */
784 /* #endif */
785 /* return this->node_pt(0)->ntstorage(); */
786 /* } */
787 
788 /* ///Number of positional history values */
789 /* /// (Note: count includes current value!) */
790 /* unsigned nhistory_values_for_coordinate_projection() */
791 /* { */
792 /* return this->node_pt(0)->position_time_stepper_pt()->ntstorage(); */
793 /* } */
794 
795 /* /// Return Jacobian of mapping and shape functions of field fld */
796 /* /// at local coordinate s */
797 /* double jacobian_and_shape_of_field(const unsigned &fld, */
798 /* const Vector<double> &s, */
799 /* Shape &psi) */
800 /* { */
801 /* #ifdef PARANOID */
802 /* if (fld!=0) */
803 /* { */
804 /* std::stringstream error_stream; */
805 /* error_stream */
806 /* << "MultiPoisson elements only store a single field so fld must be 0 rather" */
807 /* << " than " << fld << std::endl; */
808 /* throw OomphLibError( */
809 /* error_stream.str(), */
810 /* OOMPH_CURRENT_FUNCTION, */
811 /* OOMPH_EXCEPTION_LOCATION); */
812 /* } */
813 /* #endif */
814 /* unsigned n_dim=this->dim(); */
815 /* unsigned n_node=this->nnode(); */
816 /* Shape test(n_node); */
817 /* DShape dpsidx(n_node,n_dim), dtestdx(n_node,n_dim); */
818 /* double J=this->dshape_and_dtest_eulerian_multi_poisson(s,psi,dpsidx, */
819 /* test,dtestdx); */
820 /* return J; */
821 /* } */
822 
823 
824 
825 /* /// Return interpolated field fld at local coordinate s, at time level */
826 /* /// t (t=0: present; t>0: history values) */
827 /* double get_field(const unsigned &t, */
828 /* const unsigned &fld, */
829 /* const Vector<double>& s) */
830 /* { */
831 /* #ifdef PARANOID */
832 /* if (fld!=0) */
833 /* { */
834 /* std::stringstream error_stream; */
835 /* error_stream */
836 /* << "MultiPoisson elements only store a single field so fld must be 0 rather" */
837 /* << " than " << fld << std::endl; */
838 /* throw OomphLibError( */
839 /* error_stream.str(), */
840 /* OOMPH_CURRENT_FUNCTION, */
841 /* OOMPH_EXCEPTION_LOCATION); */
842 /* } */
843 /* #endif */
844 /* //Find the index at which the variable is stored */
845 /* unsigned u_nodal_index = this->u_index_multi_poisson(); */
846 
847 /* //Local shape function */
848 /* unsigned n_node=this->nnode(); */
849 /* Shape psi(n_node); */
850 
851 /* //Find values of shape function */
852 /* this->shape(s,psi); */
853 
854 /* //Initialise value of u */
855 /* double interpolated_u = 0.0; */
856 
857 /* //Sum over the local nodes */
858 /* for(unsigned l=0;l<n_node;l++) */
859 /* { */
860 /* interpolated_u += this->nodal_value(l,u_nodal_index)*psi[l]; */
861 /* } */
862 /* return interpolated_u; */
863 /* } */
864 
865 
866 
867 
868 /* ///Return number of values in field fld: One per node */
869 /* unsigned nvalue_of_field(const unsigned &fld) */
870 /* { */
871 /* #ifdef PARANOID */
872 /* if (fld!=0) */
873 /* { */
874 /* std::stringstream error_stream; */
875 /* error_stream */
876 /* << "MultiPoisson elements only store a single field so fld must be 0 rather" */
877 /* << " than " << fld << std::endl; */
878 /* throw OomphLibError( */
879 /* error_stream.str(), */
880 /* OOMPH_CURRENT_FUNCTION, */
881 /* OOMPH_EXCEPTION_LOCATION); */
882 /* } */
883 /* #endif */
884 /* return this->nnode(); */
885 /* } */
886 
887 
888 /* ///Return local equation number of value j in field fld. */
889 /* int local_equation(const unsigned &fld, */
890 /* const unsigned &j) */
891 /* { */
892 /* #ifdef PARANOID */
893 /* if (fld!=0) */
894 /* { */
895 /* std::stringstream error_stream; */
896 /* error_stream */
897 /* << "MultiPoisson elements only store a single field so fld must be 0 rather" */
898 /* << " than " << fld << std::endl; */
899 /* throw OomphLibError( */
900 /* error_stream.str(), */
901 /* OOMPH_CURRENT_FUNCTION, */
902 /* OOMPH_EXCEPTION_LOCATION); */
903 /* } */
904 /* #endif */
905 /* const unsigned u_nodal_index = this->u_index_multi_poisson(); */
906 /* return this->nodal_local_eqn(j,u_nodal_index); */
907 /* } */
908 
909 /* }; */
910 
911 
912 /* //======================================================================= */
913 /* /// Face geometry for element is the same as that for the underlying */
914 /* /// wrapped element */
915 /* //======================================================================= */
916 /* template<class ELEMENT> */
917 /* class FaceGeometry<ProjectableMultiPoissonElement<ELEMENT> > */
918 /* : public virtual FaceGeometry<ELEMENT> */
919 /* { */
920 /* public: */
921 /* FaceGeometry() : FaceGeometry<ELEMENT>() {} */
922 /* }; */
923 
924 
925 /* //======================================================================= */
926 /* /// Face geometry of the Face Geometry for element is the same as */
927 /* /// that for the underlying wrapped element */
928 /* //======================================================================= */
929 /* template<class ELEMENT> */
930 /* class FaceGeometry<FaceGeometry<ProjectableMultiPoissonElement<ELEMENT> > > */
931 /* : public virtual FaceGeometry<FaceGeometry<ELEMENT> > */
932 /* { */
933 /* public: */
934 /* FaceGeometry() : FaceGeometry<FaceGeometry<ELEMENT> >() {} */
935 /* }; */
936 
937 
938 
939 
940 }
941 
942 
945 // cc code included too since it's all templated
948 
949 
950 namespace oomph
951 {
952 
953 
954 //======================================================================
957 //======================================================================
958  template<unsigned DIM, unsigned NNODE_1D, unsigned NFIELDS>
960  NFIELDS;
961 
962 
963 //======================================================================
970 //======================================================================
971 template <unsigned DIM, unsigned NFIELDS>
974  Vector<double> &residuals,
975  DenseMatrix<double> &jacobian,
976  const unsigned& flag)
977 {
978  //Find out how many nodes there are
979  const unsigned n_node = nnode();
980 
981  //Set up memory for the shape and test functions
982  Shape psi(n_node), test(n_node);
983  DShape dpsidx(n_node,DIM), dtestdx(n_node,DIM);
984 
985  //Set the value of n_intpt
986  const unsigned n_intpt = integral_pt()->nweight();
987 
988  //Integers to store the local equation and unknown numbers
989  int local_eqn=0, local_unknown=0;
990 
991  //Loop over the integration points
992  for(unsigned ipt=0;ipt<n_intpt;ipt++)
993  {
994  //Get the integral weight
995  double w = integral_pt()->weight(ipt);
996 
997  //Call the derivatives of the shape and test functions
998  double J = dshape_and_dtest_eulerian_at_knot_multi_poisson(ipt,psi,dpsidx,
999  test,dtestdx);
1000 
1001  //Premultiply the weights and the Jacobian
1002  double W = w*J;
1003 
1004  //Calculate local values of unknown
1005  //Allocate and initialise to zero
1006  Vector<double> interpolated_u(NFIELDS,0.0);
1007  Vector<double> interpolated_x(DIM,0.0);
1008  Vector<Vector<double> > interpolated_dudx(NFIELDS);
1009 
1010 
1011  //Calculate function value and derivatives:
1012  //-----------------------------------------
1013  for (unsigned i=0;i<NFIELDS;i++)
1014  {
1015  interpolated_dudx[i].resize(DIM);
1016  for (unsigned ii=0;ii<DIM;ii++)
1017  {
1018  interpolated_dudx[i][ii]=0.0;
1019  }
1020  }
1021  // Loop over nodes
1022  for(unsigned l=0;l<n_node;l++)
1023  {
1024  // Loop over directions for coordinates
1025  for(unsigned j=0;j<DIM;j++)
1026  {
1027  interpolated_x[j] += raw_nodal_position(l,j)*psi(l);
1028  }
1029 
1030  // Loop over fields
1031  for (unsigned i=0;i<NFIELDS;i++)
1032  {
1033  //Index at which the multi_poisson unknown is stored
1034  unsigned u_nodal_index = u_index_multi_poisson(i);
1035 
1036  //Get the nodal value of the multi_poisson unknown
1037  double u_value = raw_nodal_value(l,u_nodal_index);
1038  interpolated_u[i] += u_value*psi(l);
1039 
1040  // Loop over directions for derivs
1041  for(unsigned j=0;j<DIM;j++)
1042  {
1043  interpolated_dudx[i][j] += u_value*dpsidx(l,j);
1044  }
1045  }
1046  }
1047 
1048  //Get source function
1049  //-------------------
1050  Vector<double> source(NFIELDS);
1051  get_source_multi_poisson(ipt,interpolated_x,source);
1052 
1053 
1054  // Get interaction parameter
1055 #ifdef PARANOID
1056  if (Beta_pt==0)
1057  {
1058  throw OomphLibError(
1059  "Beta_pt hasn't been set!",
1062  }
1063 #endif
1064  const double beta_local=*Beta_pt;
1065 
1066 
1067  // Assemble residuals and Jacobian
1068  //--------------------------------
1069 
1070  // Loop over the test functions
1071  for(unsigned l=0;l<n_node;l++)
1072  {
1073  for (unsigned i=0;i<NFIELDS;i++)
1074  {
1075  //Index at which the multi_poisson unknown is stored
1076  unsigned u_nodal_index = u_index_multi_poisson(i);
1077 
1078  //Get the local equation
1079  local_eqn = nodal_local_eqn(l,u_nodal_index);
1080 
1081  // IF it's not a boundary condition
1082  if(local_eqn >= 0)
1083  {
1084  // Add body force/source term here
1085  residuals[local_eqn] += source[i]*test(l)*W;
1086 
1087  // The Poisson bit itself
1088  for(unsigned k=0;k<DIM;k++)
1089  {
1090  residuals[local_eqn] +=
1091  double(i+1)*interpolated_dudx[i][k]*dtestdx(l,k)*W;
1092  }
1093 
1094  // The interaction bit:
1095  for(unsigned k=0;k<NFIELDS;k++)
1096  {
1097  residuals[local_eqn] -=
1098  double(i+1)*beta_local*interpolated_u[k]*test(l)*W;
1099  }
1100 
1101  // Calculate the jacobian
1102  //-----------------------
1103  if(flag)
1104  {
1105  //Loop over the velocity shape functions again
1106  for(unsigned l2=0;l2<n_node;l2++)
1107  {
1108  for (unsigned i2=0;i2<NFIELDS;i2++)
1109  {
1110  //Index at which the multi_poisson unknown is stored
1111  unsigned u_nodal_index2 = u_index_multi_poisson(i2);
1112 
1113  local_unknown = nodal_local_eqn(l2,u_nodal_index2);
1114  //If at a non-zero degree of freedom add in the entry
1115  if(local_unknown >= 0)
1116  {
1117  // The Poisson bit
1118  if(i==i2)
1119  {
1120  for(unsigned ii=0;ii<DIM;ii++)
1121  {
1122  jacobian(local_eqn,local_unknown)
1123  += double(i+1)*dpsidx(l2,ii)*dtestdx(l,ii)*W;
1124  }
1125  }
1126  jacobian(local_eqn,local_unknown) -=
1127  double(i+1)*beta_local*psi(l2)*test(l)*W;
1128  }
1129  }
1130  }
1131  }
1132  }
1133  }
1134  }
1135  } // End of loop over integration points
1136 }
1137 
1138 
1139 
1140 
1141 //======================================================================
1143 //======================================================================
1144  template <unsigned DIM, unsigned NFIELDS>
1146 {
1147 
1148  bool passed=true;
1149 
1150  // Check lower-level stuff
1151  if (FiniteElement::self_test()!=0)
1152  {
1153  passed=false;
1154  }
1155 
1156  // Return verdict
1157  if (passed)
1158  {
1159  return 0;
1160  }
1161  else
1162  {
1163  return 1;
1164  }
1165 
1166 }
1167 
1168 
1169 
1170 //======================================================================
1176 //======================================================================
1177 template <unsigned DIM, unsigned NFIELDS>
1179  const unsigned &nplot)
1180 {
1181 
1182  //Vector of local coordinates
1183  Vector<double> s(DIM);
1184 
1185  // Tecplot header info
1186  outfile << tecplot_zone_string(nplot);
1187 
1188  // Loop over plot points
1189  unsigned num_plot_points=nplot_points(nplot);
1190  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
1191  {
1192  // Get local coordinates of plot point
1193  get_s_plot(iplot,nplot,s);
1194 
1195  for(unsigned i=0;i<DIM;i++)
1196  {
1197  outfile << interpolated_x(s,i) << " ";
1198  }
1199  for(unsigned i=0;i<NFIELDS;i++)
1200  {
1201  outfile << interpolated_u_multi_poisson(i,s) << " ";
1202  }
1203  outfile << std::endl;
1204  }
1205 
1206  // Write tecplot footer (e.g. FE connectivity lists)
1207  write_tecplot_zone_footer(outfile,nplot);
1208 
1209 }
1210 
1211 
1212 //======================================================================
1218 //======================================================================
1219 template <unsigned DIM, unsigned NFIELDS>
1221  const unsigned &nplot)
1222 {
1223  //Vector of local coordinates
1224  Vector<double> s(DIM);
1225 
1226  // Tecplot header info
1227  fprintf(file_pt,"%s",tecplot_zone_string(nplot).c_str());
1228 
1229  // Loop over plot points
1230  unsigned num_plot_points=nplot_points(nplot);
1231  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
1232  {
1233  // Get local coordinates of plot point
1234  get_s_plot(iplot,nplot,s);
1235 
1236  for(unsigned i=0;i<DIM;i++)
1237  {
1238  fprintf(file_pt,"%g ",interpolated_x(s,i));
1239  }
1240  for(unsigned i=0;i<NFIELDS;i++)
1241  {
1242  fprintf(file_pt,"%g ",interpolated_u_multi_poisson(i,s));
1243  }
1244  fprintf(file_pt,"\n");
1245  }
1246 
1247  // Write tecplot footer (e.g. FE connectivity lists)
1248  write_tecplot_zone_footer(file_pt,nplot);
1249 }
1250 
1251 
1252 
1253 //======================================================================
1260 //======================================================================
1261  template <unsigned DIM, unsigned NFIELDS>
1263  const unsigned &nplot,
1265 {
1266  //Vector of local coordinates
1267  Vector<double> s(DIM);
1268 
1269  // Vector for coordintes
1270  Vector<double> x(DIM);
1271 
1272  // Tecplot header info
1273  outfile << tecplot_zone_string(nplot);
1274 
1275  // Exact solution Vector
1276  Vector<double> exact_soln(NFIELDS);
1277 
1278  // Loop over plot points
1279  unsigned num_plot_points=nplot_points(nplot);
1280  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
1281  {
1282 
1283  // Get local coordinates of plot point
1284  get_s_plot(iplot,nplot,s);
1285 
1286  // Get x position as Vector
1287  interpolated_x(s,x);
1288 
1289  // Get exact solution at this point
1290  (*exact_soln_pt)(x,exact_soln);
1291 
1292  //Output x,y,...,u_exact
1293  for(unsigned i=0;i<DIM;i++)
1294  {
1295  outfile << x[i] << " ";
1296  }
1297  for(unsigned i=0;i<NFIELDS;i++)
1298  {
1299  outfile << exact_soln[i] << " ";
1300  }
1301  outfile << std::endl;
1302  }
1303 
1304  // Write tecplot footer (e.g. FE connectivity lists)
1305  write_tecplot_zone_footer(outfile,nplot);
1306 }
1307 
1308 
1309 
1310 
1311 //======================================================================
1317 //======================================================================
1318  template <unsigned DIM,unsigned NFIELDS>
1320  std::ostream &outfile,
1322  double& error, double& norm)
1323  {
1324 
1325  // Initialise
1326  error=0.0;
1327  norm=0.0;
1328 
1329  //Vector of local coordinates
1330  Vector<double> s(DIM);
1331 
1332  // Vector for coordintes
1333  Vector<double> x(DIM);
1334 
1335  //Find out how many nodes there are in the element
1336  unsigned n_node = nnode();
1337 
1338  Shape psi(n_node);
1339 
1340  //Set the value of n_intpt
1341  unsigned n_intpt = integral_pt()->nweight();
1342 
1343  // Tecplot
1344  outfile << "ZONE" << std::endl;
1345 
1346  // Exact solution Vector (here a scalar)
1347  Vector<double> exact_soln(NFIELDS);
1348 
1349  //Loop over the integration points
1350  for(unsigned ipt=0;ipt<n_intpt;ipt++)
1351  {
1352  //Assign values of s
1353  for(unsigned i=0;i<DIM;i++)
1354  {
1355  s[i] = integral_pt()->knot(ipt,i);
1356  }
1357 
1358  //Get the integral weight
1359  double w = integral_pt()->weight(ipt);
1360 
1361  // Get jacobian of mapping
1362  double J=J_eulerian(s);
1363 
1364  //Premultiply the weights and the Jacobian
1365  double W = w*J;
1366 
1367  // Get x position as Vector
1368  interpolated_x(s,x);
1369 
1370 
1371  //Output x,y,...
1372  for(unsigned i=0;i<DIM;i++)
1373  {
1374  outfile << x[i] << " ";
1375  }
1376 
1377  // Get exact solution at this point
1378  (*exact_soln_pt)(x,exact_soln);
1379 
1380  for(unsigned i=0;i<NFIELDS;i++)
1381  {
1382  // Get FE function value
1383  double u_fe=interpolated_u_multi_poisson(i,s);
1384  outfile << exact_soln[i] << " " << exact_soln[i]-u_fe << " ";
1385 
1386  // Add to error and norm
1387  norm+=exact_soln[i]*exact_soln[i]*W;
1388  error+=(exact_soln[i]-u_fe)*(exact_soln[i]-u_fe)*W;
1389  }
1390  outfile << std::endl;
1391  }
1392  }
1393 
1394 
1395 
1396 }
1397 
1398 
1399 
1400 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
RowVector3d w
Definition: Matrix_resize_int.cpp:3
Definition: shape.h:278
FaceGeometry()
Definition: multi_poisson_elements.h:705
Definition: elements.h:4998
Definition: elements.h:1313
virtual unsigned nplot_points_paraview(const unsigned &nplot) const
Definition: elements.h:2862
double nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2593
virtual void shape(const Vector< double > &s, Shape &psi) const =0
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Definition: elements.h:1432
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Definition: elements.h:1759
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &shifted_to_interior=false) const
Definition: elements.h:3148
virtual unsigned self_test()
Definition: elements.cc:4440
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Definition: elements.h:1765
unsigned long eqn_number(const unsigned &ieqn_local) const
Definition: elements.h:704
static DenseMatrix< double > Dummy_matrix
Definition: elements.h:227
Definition: multi_poisson_elements.h:65
double * Beta_pt
Pointer to interaction parameter Beta.
Definition: multi_poisson_elements.h:440
void output(std::ostream &outfile)
Output with default number of plot points.
Definition: multi_poisson_elements.h:215
unsigned self_test()
Self-test: Return 0 for OK.
Definition: multi_poisson_elements.h:1145
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Dummy, time dependent error checker.
Definition: multi_poisson_elements.h:262
virtual double dshape_and_dtest_eulerian_at_knot_multi_poisson(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const =0
MultiPoissonSourceFctPt Source_fct_pt
Pointer to source function:
Definition: multi_poisson_elements.h:437
std::string scalar_name_paraview(const unsigned &i) const
Definition: multi_poisson_elements.h:193
double *& beta_pt()
Access function: Pointer to interaction parameter beta.
Definition: multi_poisson_elements.h:273
void get_flux(const Vector< double > &s, Vector< double > &flux) const
Get flux: flux[i] = du/dx_i.
Definition: multi_poisson_elements.h:306
virtual double dshape_and_dtest_eulerian_at_knot_multi_poisson(const unsigned &ipt, Shape &psi, DShape &dpsidx, RankFourTensor< double > &d_dpsidx_dX, Shape &test, DShape &dtestdx, RankFourTensor< double > &d_dtestdx_dX, DenseMatrix< double > &djacobian_dX) const =0
virtual unsigned u_index_multi_poisson(const unsigned &i) const
Definition: multi_poisson_elements.h:92
virtual void get_source_multi_poisson(const unsigned &ipt, const Vector< double > &x, Vector< double > &source) const
Definition: multi_poisson_elements.h:285
MultiPoissonEquations()
Constructor (must initialise the Source_fct_pt to null)
Definition: multi_poisson_elements.h:76
MultiPoissonSourceFctPt source_fct_pt() const
Access function: Pointer to source function. Const version.
Definition: multi_poisson_elements.h:279
double interpolated_u_multi_poisson(const unsigned &i, const Vector< double > &s) const
Definition: multi_poisson_elements.h:364
void(* MultiPoissonSourceFctPt)(const Vector< double > &x, Vector< double > &f)
Definition: multi_poisson_elements.h:71
virtual void fill_in_generic_residual_contribution_multi_poisson(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Definition: multi_poisson_elements.h:973
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact soln: x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points.
Definition: multi_poisson_elements.h:1262
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector (wrapper)
Definition: multi_poisson_elements.h:342
unsigned ndof_types() const
Definition: multi_poisson_elements.h:98
unsigned nscalar_paraview() const
Definition: multi_poisson_elements.h:152
MultiPoissonEquations(const MultiPoissonEquations &dummy)
Broken copy constructor.
Definition: multi_poisson_elements.h:80
void output(FILE *file_pt)
C_style output with default number of plot points.
Definition: multi_poisson_elements.h:226
virtual double dshape_and_dtest_eulerian_multi_poisson(const Vector< double > &s, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const =0
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
Definition: multi_poisson_elements.h:1319
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: multi_poisson_elements.h:353
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned > > &block_lookup_list) const
Definition: multi_poisson_elements.h:109
virtual void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Definition: multi_poisson_elements.h:243
MultiPoissonSourceFctPt & source_fct_pt()
Access function: Pointer to source function.
Definition: multi_poisson_elements.h:276
void scalar_value_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot) const
Definition: multi_poisson_elements.h:159
Definition: oomph_definitions.h:222
Definition: elements.h:3439
Definition: Qelements.h:459
Definition: multi_poisson_elements.h:462
void output(std::ostream &outfile, const unsigned &n_plot)
Definition: multi_poisson_elements.h:498
QMultiPoissonElement(const QMultiPoissonElement< DIM, NNODE_1D, NFIELDS > &dummy)
Broken copy constructor.
Definition: multi_poisson_elements.h:480
void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Definition: multi_poisson_elements.h:525
void output(FILE *file_pt, const unsigned &n_plot)
Definition: multi_poisson_elements.h:510
double dshape_and_dtest_eulerian_at_knot_multi_poisson(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Definition: multi_poisson_elements.h:608
unsigned required_nvalue(const unsigned &n) const
Definition: multi_poisson_elements.h:487
void output(FILE *file_pt)
Definition: multi_poisson_elements.h:504
QMultiPoissonElement()
Definition: multi_poisson_elements.h:475
double dshape_and_dtest_eulerian_multi_poisson(const Vector< double > &s, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Shape, test functions & derivs. w.r.t. to global coords. Return Jacobian.
Definition: multi_poisson_elements.h:579
static const unsigned Initial_Nvalue
Definition: multi_poisson_elements.h:468
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Definition: multi_poisson_elements.h:516
void output(std::ostream &outfile)
Definition: multi_poisson_elements.h:492
A Rank 4 Tensor class.
Definition: matrices.h:1701
Definition: shape.h:76
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
RealScalar s
Definition: level1_cplx_impl.h:130
char char char int int * k
Definition: level2_impl.h:374
#define DIM
Definition: linearised_navier_stokes_elements.h:44
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
void source(const Vector< double > &x, Vector< double > &f)
Source function.
Definition: unstructured_two_d_circle.cc:46
int error
Definition: calibrate.py:297
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
Definition: oomph_utilities.cc:212
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
@ W
Definition: quadtree.h:63
std::string to_string(T object, unsigned float_precision=8)
Definition: oomph_utilities.h:189
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
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