33 #ifndef OOMPH_QSPECTRAL_ELEMENT_HEADER 34 #define OOMPH_QSPECTRAL_ELEMENT_HEADER 38 #include <oomph-lib-config.h> 53 static std::map<unsigned,Vector<double> >
z;
59 if(z.find(order)==z.end())
65 static inline double nodal_position(
const unsigned &order,
const unsigned &n)
72 using namespace Orthpoly;
76 for(
unsigned i=0;
i<order;
i++)
87 (p*(p+1)*
legendre(p,z[order][i])*(z[order][
i] -
s));
101 unsigned p = order - 1;
105 for(
unsigned i=0;
i<order;
i++)
108 for(
unsigned j=0;j<order;j++)
119 if(
i==rootnum &&
i==0)
121 (*this)[
i]=-(1.0+p)*p/4.0;
123 else if(
i==rootnum &&
i==p)
125 (*this)[
i]=(1.0+p)*p/4.0;
178 if(Spectral_data_pt!=0)
180 delete Spectral_data_pt;
189 {
return (*Spectral_data_pt)[
i];}
205 unsigned n_spectral = nspectral();
208 for(
unsigned n=0;n<n_spectral;n++)
211 Node* cast_node_pt =
dynamic_cast<Node*
>(spectral_data_pt(n));
214 std::stringstream conversion;
215 conversion <<
" of Node "<<n<<current_string;
222 Data* data_pt = spectral_data_pt(n);
223 std::stringstream conversion;
224 conversion <<
" of Data "<<n<<current_string;
234 const bool &store_local_dof_pt)
240 unsigned n_spectral = nspectral();
244 unsigned local_eqn_number = ndof();
247 unsigned max_n_value = spectral_data_pt(0)->nvalue();
249 for(
unsigned n=1;n<n_spectral;n++)
251 unsigned n_value = spectral_data_pt(n)->nvalue();
252 if(n_value > max_n_value) {max_n_value = n_value;}
260 std::set<Data*> set_of_node_pt;
261 unsigned n_node = nnode();
262 for(
unsigned n=0;n<n_node;n++) {set_of_node_pt.insert(node_pt(n));}
265 std::deque<unsigned long> global_eqn_number_queue;
268 for(
unsigned n=0;n<n_spectral;n++)
274 Node* cast_node_pt =
dynamic_cast<Node*
>(spectral_data_pt(n));
276 (set_of_node_pt.find(cast_node_pt)!=set_of_node_pt.end()))
279 unsigned n_value = cast_node_pt->
nvalue();
281 for(
unsigned j=0;j<n_value;j++)
283 Spectral_local_eqn(n,j) =
284 nodal_local_eqn(get_node_number(cast_node_pt),j);
287 set_of_node_pt.erase(cast_node_pt);
292 Data*
const data_pt = spectral_data_pt(n);
293 unsigned n_value = data_pt->
nvalue();
295 for(
unsigned j=0;j<n_value;j++)
305 global_eqn_number_queue.push_back(eqn_number);
307 if(store_local_dof_pt)
313 Spectral_local_eqn(n,j) = local_eqn_number;
327 add_global_eqn_numbers(global_eqn_number_queue,
330 if(store_local_dof_pt)
338 if(Spectral_data_pt==0) {
return 0;}
341 return Spectral_data_pt->size();
354 template<
unsigned DIM,
unsigned NNODE_1D>
363 template<
unsigned NNODE_1D>
381 this->set_n_node(NNODE_1D);
382 Spectral_order.resize(1,NNODE_1D);
383 Nodal_spectral_order.resize(1,NNODE_1D);
385 this->set_dimension(1);
387 this->set_integration_scheme(&integral);
406 unsigned n_node_1d = nnode_1d();
411 nod_pt = this->node_pt(0);
414 nod_pt = this->node_pt(n_node_1d-1);
417 std::ostringstream error_message;
418 error_message <<
"Vertex node number is " << j <<
419 " but must be from 0 to 1\n";
422 OOMPH_CURRENT_FUNCTION,
423 OOMPH_EXCEPTION_LOCATION);
438 this->local_coordinate_of_node(n,s_fraction);
440 s_fraction[0] = 0.5*(s_fraction[0] + 1.0);
469 {
return FiniteElement::invert_jacobian<1>(jacobian,inverse_jacobian);}
480 void output(FILE* file_pt,
const unsigned &n_plot)
484 void output(std::ostream &outfile);
487 void output(std::ostream &outfile,
const unsigned &n_plot);
493 const unsigned& nplot,
495 const bool& use_equally_spaced_interior_sample_points=
false)
const 499 s[0]=-1.0+2.0*double(i)/double(nplot-1);
500 if (use_equally_spaced_interior_sample_points)
503 double dx_new=range/double(nplot);
504 double range_new=double(nplot-1)*dx_new;
505 s[0]=-1.0+0.5*dx_new+range_new*(1.0+s[0])/range;
518 std::ostringstream header;
519 header <<
"ZONE I=" << nplot <<
"\n";
529 for (
unsigned i=0;
i<DIM;
i++) {np*=nplot;}
538 void build_face_element(
const int &face_index,
547 template <
unsigned NNODE_1D>
557 for(
unsigned i=0;
i<NNODE_1D;
i++) {psi(
i) = psi1[
i];}
563 template <
unsigned NNODE_1D>
576 for(
unsigned l=0;l<NNODE_1D;l++)
579 dpsids(l,0) = dpsi1ds[l];
587 template <
unsigned NNODE_1D>
591 std::ostringstream error_message;
592 error_message <<
"\nd2shpe_local currently not implemented for this element\n";
594 OOMPH_CURRENT_FUNCTION,
595 OOMPH_EXCEPTION_LOCATION);
615 template<
unsigned NNODE_1D>
633 this->set_n_node(NNODE_1D*NNODE_1D);
634 Spectral_order.resize(2,NNODE_1D);
635 Nodal_spectral_order.resize(2,NNODE_1D);
637 this->set_dimension(2);
639 this->set_integration_scheme(&integral);
658 unsigned n_node_1d = nnode_1d();
663 nod_pt = this->node_pt(0);
666 nod_pt = this->node_pt(n_node_1d-1);
669 nod_pt = this->node_pt(n_node_1d*(n_node_1d-1));
672 nod_pt = this->node_pt(n_node_1d*n_node_1d-1);
675 std::ostringstream error_message;
676 error_message <<
"Vertex node number is " << j <<
677 " but must be from 0 to 3\n";
680 OOMPH_CURRENT_FUNCTION,
681 OOMPH_EXCEPTION_LOCATION);
691 unsigned n0 = n%NNODE_1D;
692 unsigned n1 = unsigned(
double(n)/
double(NNODE_1D));
700 this->local_coordinate_of_node(n,s_fraction);
702 s_fraction[0] = 0.5*(s_fraction[0] + 1.0);
703 s_fraction[1] = 0.5*(s_fraction[1] + 1.0);
734 {
return FiniteElement::invert_jacobian<2>(jacobian,inverse_jacobian);}
745 void output(FILE* file_pt,
const unsigned &n_plot)
749 void output(std::ostream &outfile);
752 void output(std::ostream &outfile,
const unsigned &n_plot);
758 const unsigned& nplot,
760 const bool& use_equally_spaced_interior_sample_points=
false)
const 765 unsigned i1=(i-i0)/nplot;
767 s[0]=-1.0+2.0*double(i0)/double(nplot-1);
768 s[1]=-1.0+2.0*double(i1)/double(nplot-1);
769 if (use_equally_spaced_interior_sample_points)
772 double dx_new=range/double(nplot);
773 double range_new=double(nplot-1)*dx_new;
774 s[0]=-1.0+0.5*dx_new+range_new*(1.0+s[0])/range;
775 s[1]=-1.0+0.5*dx_new+range_new*(1.0+s[1])/range;
790 std::ostringstream header;
791 header <<
"ZONE I=" << nplot <<
", J=" << nplot <<
"\n";
801 for (
unsigned i=0;
i<DIM;
i++) {np*=nplot;}
812 void build_face_element(
const int &face_index,
820 template <
unsigned NNODE_1D>
830 for(
unsigned i=0;
i<NNODE_1D;
i++)
832 for(
unsigned j=0;j<NNODE_1D;j++)
834 psi(NNODE_1D*
i + j) = psi2[
i]*psi1[j];
842 template <
unsigned NNODE_1D>
857 for(
unsigned i=0;
i<NNODE_1D;
i++)
859 for(
unsigned j=0;j<NNODE_1D;j++)
862 dpsids(index,0) = psi2[
i]*dpsi1ds[j];
863 dpsids(index,1) = dpsi2ds[
i]*psi1[j];
864 psi[index] = psi2[
i]*psi1[j];
878 template <
unsigned NNODE_1D>
882 std::ostringstream error_message;
883 error_message <<
"\nd2shpe_local currently not implemented for this element\n";
885 OOMPH_CURRENT_FUNCTION,
886 OOMPH_EXCEPTION_LOCATION);
906 template<
unsigned NNODE_1D>
924 this->set_n_node(NNODE_1D*NNODE_1D*NNODE_1D);
925 Spectral_order.resize(3,NNODE_1D);
926 Nodal_spectral_order.resize(3,NNODE_1D);
928 this->set_dimension(3);
930 this->set_integration_scheme(&integral);
949 unsigned n_node_1d = nnode_1d();
954 nod_pt = this->node_pt(0);
957 nod_pt=this->node_pt(n_node_1d-1);
960 nod_pt=this->node_pt(n_node_1d*(n_node_1d-1));
963 nod_pt=this->node_pt(n_node_1d*n_node_1d-1);
966 nod_pt=this->node_pt(n_node_1d*n_node_1d*(n_node_1d-1));
969 nod_pt=this->node_pt(n_node_1d*n_node_1d*(n_node_1d-1)+(n_node_1d-1));
972 nod_pt=this->node_pt(n_node_1d*n_node_1d*n_node_1d-n_node_1d);
975 nod_pt=this->node_pt(n_node_1d*n_node_1d*n_node_1d-1);
978 std::ostringstream error_message;
979 error_message <<
"Vertex node number is " << j <<
980 " but must be from 0 to 7\n";
983 OOMPH_CURRENT_FUNCTION,
984 OOMPH_EXCEPTION_LOCATION);
994 unsigned n0 = n%NNODE_1D;
995 unsigned n1 = unsigned(
double(n)/
double(NNODE_1D))%NNODE_1D;
996 unsigned n2 = unsigned(
double(n)/
double(NNODE_1D*NNODE_1D));
1005 this->local_coordinate_of_node(n,s_fraction);
1007 s_fraction[0] = 0.5*(s_fraction[0] + 1.0);
1008 s_fraction[1] = 0.5*(s_fraction[1] + 1.0);
1009 s_fraction[2] = 0.5*(s_fraction[2] + 1.0);
1044 {
return FiniteElement::invert_jacobian<3>(jacobian,inverse_jacobian);}
1054 void output(FILE* file_pt,
const unsigned &n_plot)
1058 void output(std::ostream &outfile);
1061 void output(std::ostream &outfile,
const unsigned& nplot);
1067 const unsigned& nplot,
1069 const bool& use_equally_spaced_interior_sample_points=
false)
const 1073 unsigned i01=i%(nplot*nplot);
1074 unsigned i0=i01%nplot;
1075 unsigned i1=(i01-i0)/nplot;
1076 unsigned i2=(i-i01)/(nplot*nplot);
1078 s[0]=-1.0+2.0*double(i0)/double(nplot-1);
1079 s[1]=-1.0+2.0*double(i1)/double(nplot-1);
1080 s[2]=-1.0+2.0*double(i2)/double(nplot-1);
1081 if (use_equally_spaced_interior_sample_points)
1084 double dx_new=range/double(nplot);
1085 double range_new=double(nplot-1)*dx_new;
1086 s[0]=-1.0+0.5*dx_new+range_new*(1.0+s[0])/range;
1087 s[1]=-1.0+0.5*dx_new+range_new*(1.0+s[1])/range;
1088 s[2]=-1.0+0.5*dx_new+range_new*(1.0+s[2])/range;
1105 std::ostringstream header;
1106 header <<
"ZONE I=" << nplot <<
", J=" << nplot <<
", K=" 1108 return header.str();
1117 for (
unsigned i=0;
i<DIM;
i++) {np*=nplot;}
1130 void build_face_element(
const int &face_index,
1138 template <
unsigned NNODE_1D>
1149 for(
unsigned i=0;
i<NNODE_1D;
i++)
1151 for(
unsigned j=0;j<NNODE_1D;j++)
1153 for(
unsigned k=0;k<NNODE_1D;k++)
1155 psi(NNODE_1D*NNODE_1D*
i + NNODE_1D*j + k) = psi3[
i]*psi2[j]*psi1[k];
1164 template <
unsigned NNODE_1D>
1183 for(
unsigned i=0;
i<NNODE_1D;
i++)
1185 for(
unsigned j=0;j<NNODE_1D;j++)
1187 for(
unsigned k=0;k<NNODE_1D;k++)
1190 dpsids(index,0) = psi3[
i]*psi2[j]*dpsi1ds[k];
1191 dpsids(index,1) = psi3[
i]*dpsi2ds[j]*psi1[k];
1192 dpsids(index,2) = dpsi3ds[
i]*psi2[j]*psi1[k];
1193 psi[index] = psi3[
i]*psi2[j]*psi1[k];
1211 template <
unsigned NNODE_1D>
1215 std::ostringstream error_message;
1216 error_message <<
"\nd2shpe_local currently not implemented for this element\n";
1218 OOMPH_CURRENT_FUNCTION,
1219 OOMPH_EXCEPTION_LOCATION);
1239 template<
unsigned DIM>
void local_fraction_of_node(const unsigned &n, Vector< double > &s_fraction)
Get the local fractino of node j in the element.
double local_one_d_fraction_of_node(const unsigned &n1d, const unsigned &i)
The local one-d fraction is the same.
static GaussLobattoLegendre< 2, NNODE_1D > integral
Default integration rule: Gaussian integration of same 'order' as the element.
void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &use_equally_spaced_interior_sample_points=false) const
Get cector of local coordinates of plot point i (when plotting.
Base class for all line elements.
unsigned nvertex_node() const
Number of vertex nodes in the element.
virtual void assign_all_generic_local_eqn_numbers(const bool &store_local_dof_pt)
Overloaded version of the calculation of the local equation numbers. If the boolean argument is true ...
double dlegendre(const unsigned &p, const double &x)
Calculates first derivative of Legendre polynomial of degree p at x using three term recursive formul...
unsigned nvertex_node() const
Number of vertex nodes in the element.
double invert_jacobian_mapping(const DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Overload the template-free interface for the calculation of inverse jacobian matrix. This is a one-dimensional element, so use the 3D version.
unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction) ...
virtual void output(std::ostream &outfile)
Output the element data — typically the values at the nodes in a format suitable for post-processing...
double invert_jacobian_mapping(const DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Overload the template-free interface for the calculation of inverse jacobian matrix. This is a one-dimensional element, so use the 1D version.
DenseMatrix< int > Spectral_local_eqn
Local equation numbers for the spectral degrees of freedom.
double * value_pt(const unsigned &i) const
Return the pointer to the i-the stored value. Typically this is required when direct access to the st...
double s_min() const
Min. value of local coordinate.
unsigned nspectral() const
Base class for all brick elements.
virtual void describe_local_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the local dofs of the element[s]. The ostream specifies the output stream to whi...
static GaussLobattoLegendre< 3, NNODE_1D > integral
Default integration rule: Gaussian integration of same 'order' as the element.
QSpectralElement()
Constructor.
double s_max() const
Max. value of local coordinate.
A general Finite Element class.
double s_max() const
Max. value of local coordinate.
unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction) ...
static std::map< unsigned, Vector< double > > z
double legendre(const unsigned &p, const double &x)
Calculates Legendre polynomial of degree p at x using the three term recurrence relation ...
double s_max() const
Max. value of local coordinate.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double invert_jacobian_mapping(const DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Overload the template-free interface for the calculation of inverse jacobian matrix. This is a one-dimensional element, so use the 1D version.
virtual ~SpectralElement()
static double nodal_position(const unsigned &n)
long & eqn_number(const unsigned &i)
Return the equation number of the i-th stored variable.
OneDLegendreShapeParam(const unsigned &order, const double &s)
Constructor.
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
virtual void describe_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the dofs of the Node. The ostream specifies the output stream to which the descr...
unsigned nnode_1d() const
Number of nodes along each element edge.
QSpectralElement()
Constructor.
void local_coordinate_of_node(const unsigned &n, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size.
RefineableQSpectralElement()
Empty constuctor.
virtual void assign_all_generic_local_eqn_numbers(const bool &store_local_dof_pt)
Assign the local equation numbers. If the boolean argument is true then store degrees of freedom at D...
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
double local_one_d_fraction_of_node(const unsigned &n1d, const unsigned &i)
The local one-d fraction is the same.
void local_fraction_of_node(const unsigned &n, Vector< double > &s_fraction)
Get the local fractino of node j in the element.
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
Base class for all quad elements.
virtual void describe_local_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the local dofs of the element. The ostream specifies the output stream to which ...
void gll_nodes(const unsigned &Nnode, Vector< double > &x)
Calculates the Gauss Lobatto Legendre abscissas for degree p = NNode-1.
void local_coordinate_of_node(const unsigned &n, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size.
Class that returns the shape functions associated with legendre.
double local_one_d_fraction_of_node(const unsigned &n1d, const unsigned &i)
The local one-d fraction is the same.
double ddlegendre(const unsigned &p, const double &x)
Calculates second derivative of Legendre polynomial of degree p at x using three term recursive formu...
void output(FILE *file_pt, const unsigned &n_plot)
C_style output at n_plot points.
double s_min() const
Min. value of local coordinate.
static long Is_pinned
Static "Magic number" used in place of the equation number to indicate that the value is pinned...
double s_min() const
Min. value of local coordinate.
unsigned nnode_1d() const
Number of nodes along each element edge.
Vector< unsigned > Spectral_order
Vector that represents the spectral order in each dimension.
std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction) ...
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &use_equally_spaced_interior_sample_points=false) const
Get cector of local coordinates of plot point i (when plotting.
OneDLegendreDShapeParam(const unsigned &order, const double &s)
A class that represents a collection of data; each Data object may contain many different individual ...
unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction) ...
unsigned nnode_1d() const
Number of nodes along each element edge.
Vector< unsigned > Nodal_spectral_order
Vector that represents the nodal spectral order.
Data * spectral_data_pt(const unsigned &i) const
Return the i-th data object associated with the polynomials of order p. Note that i <= p...
static GaussLobattoLegendre< 1, NNODE_1D > integral
Default integration rule: Gaussian integration of same 'order' as the element.
void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &use_equally_spaced_interior_sample_points=false) const
Get cector of local coordinates of plot point i (when plotting.
void local_coordinate_of_node(const unsigned &n, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size.
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
void output(std::ostream &outfile)
Output with default number of plot points.
void output(FILE *file_pt, const unsigned &n_plot)
C_style output at n_plot points.
void output(FILE *file_pt)
C-style output.
void output(FILE *file_pt)
C-style output.
static void calculate_nodal_positions(const unsigned &order)
Static function used to populate the stored positions.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
static long Is_unclassified
Static "Magic number" used in place of the equation number to denote a value that hasn't been classif...
static void calculate_nodal_positions()
Static function used to populate the stored positions.
static std::deque< double * > Dof_pt_deque
Static storage for deque used to add_global_equation_numbers when pointers to the dofs in each elemen...
std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction) ...
QSpectralElement()
Constructor.
void local_fraction_of_node(const unsigned &n, Vector< double > &s_fraction)
Get the local fractino of node j in the element.
void output(FILE *file_pt)
C-style output.
void output(FILE *file_pt, const unsigned &n_plot)
C_style output at n_plot points.
Vector< Data * > * Spectral_data_pt
Additional Storage for shared spectral data.
std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction) ...
unsigned nvertex_node() const
Number of vertex nodes in the element.
Class that returns the shape functions associated with legendre.
static double nodal_position(const unsigned &order, const unsigned &n)
void resize(const unsigned long &n)