29 #ifndef OOMPH_QSPECTRAL_ELEMENT_HEADER
30 #define OOMPH_QSPECTRAL_ELEMENT_HEADER
34 #include <oomph-lib-config.h>
48 static std::map<unsigned, Vector<double>>
z;
54 if (
z.find(order) ==
z.end())
70 using namespace Orthpoly;
72 unsigned p = order - 1;
74 for (
unsigned i = 0;
i < order;
i++)
100 unsigned p = order - 1;
104 for (
unsigned i = 0;
i < order;
i++)
106 unsigned rootnum = 0;
107 for (
unsigned j = 0; j < order; j++)
118 if (
i == rootnum &&
i == 0)
120 (*this)[
i] = -(1.0 + p) * p / 4.0;
122 else if (
i == rootnum &&
i == p)
124 (*this)[
i] = (1.0 + p) * p / 4.0;
126 else if (
i == rootnum)
172 if (Spectral_data_pt != 0)
174 delete Spectral_data_pt;
175 Spectral_data_pt = 0;
184 return (*Spectral_data_pt)[
i];
201 unsigned n_spectral = nspectral();
204 for (
unsigned n = 0; n < n_spectral; n++)
207 Node* cast_node_pt =
dynamic_cast<Node*
>(spectral_data_pt(n));
210 std::stringstream conversion;
211 conversion <<
" of Node " << n << current_string;
218 Data* data_pt = spectral_data_pt(n);
219 std::stringstream conversion;
220 conversion <<
" of Data " << n << current_string;
230 const bool& store_local_dof_pt)
236 unsigned n_spectral = nspectral();
240 unsigned local_eqn_number = ndof();
243 unsigned max_n_value = spectral_data_pt(0)->nvalue();
246 for (
unsigned n = 1; n < n_spectral; n++)
248 unsigned n_value = spectral_data_pt(n)->nvalue();
249 if (n_value > max_n_value)
251 max_n_value = n_value;
257 Spectral_local_eqn.
resize(
261 std::set<Data*> set_of_node_pt;
262 unsigned n_node = nnode();
263 for (
unsigned n = 0; n < n_node; n++)
265 set_of_node_pt.insert(node_pt(n));
269 std::deque<unsigned long> global_eqn_number_queue;
272 for (
unsigned n = 0; n < n_spectral; n++)
278 Node* cast_node_pt =
dynamic_cast<Node*
>(spectral_data_pt(n));
279 if ((cast_node_pt) &&
280 (set_of_node_pt.find(cast_node_pt) != set_of_node_pt.end()))
283 unsigned n_value = cast_node_pt->
nvalue();
285 for (
unsigned j = 0; j < n_value; j++)
287 Spectral_local_eqn(n, j) =
288 nodal_local_eqn(get_node_number(cast_node_pt), j);
291 set_of_node_pt.erase(cast_node_pt);
296 Data*
const data_pt = spectral_data_pt(n);
297 unsigned n_value = data_pt->
nvalue();
299 for (
unsigned j = 0; j < n_value; j++)
309 global_eqn_number_queue.push_back(eqn_number);
311 if (store_local_dof_pt)
317 Spectral_local_eqn(n, j) = local_eqn_number;
331 add_global_eqn_numbers(global_eqn_number_queue,
334 if (store_local_dof_pt)
344 if (Spectral_data_pt == 0)
350 return Spectral_data_pt->size();
361 template<
unsigned DIM,
unsigned NNODE_1D>
370 template<
unsigned NNODE_1D>
387 this->set_n_node(NNODE_1D);
388 Spectral_order.resize(1, NNODE_1D);
389 Nodal_spectral_order.resize(1, NNODE_1D);
391 this->set_dimension(1);
393 this->set_integration_scheme(&integral);
420 unsigned n_node_1d = nnode_1d();
425 nod_pt = this->node_pt(0);
428 nod_pt = this->node_pt(n_node_1d - 1);
431 std::ostringstream error_message;
432 error_message <<
"Vertex node number is " << j
433 <<
" but must be from 0 to 1\n";
436 OOMPH_CURRENT_FUNCTION,
437 OOMPH_EXCEPTION_LOCATION);
452 this->local_coordinate_of_node(n, s_fraction);
454 s_fraction[0] = 0.5 * (s_fraction[0] + 1.0);
487 return FiniteElement::invert_jacobian<1>(jacobian, inverse_jacobian);
504 void output(FILE* file_pt,
const unsigned& n_plot)
510 void output(std::ostream& outfile);
513 void output(std::ostream& outfile,
const unsigned& n_plot);
519 const unsigned& nplot,
521 const bool& use_equally_spaced_interior_sample_points =
false)
const
525 s[0] = -1.0 + 2.0 * double(
i) / double(nplot - 1);
526 if (use_equally_spaced_interior_sample_points)
529 double dx_new = range / double(nplot);
530 double range_new = double(nplot - 1) * dx_new;
531 s[0] = -1.0 + 0.5 * dx_new + range_new * (1.0 +
s[0]) / range;
544 std::ostringstream header;
545 header <<
"ZONE I=" << nplot <<
"\n";
555 for (
unsigned i = 0;
i < DIM;
i++)
567 void build_face_element(
const int& face_index,
575 template<
unsigned NNODE_1D>
585 for (
unsigned i = 0;
i < NNODE_1D;
i++)
594 template<
unsigned NNODE_1D>
607 for (
unsigned l = 0; l < NNODE_1D; l++)
610 dpsids(l, 0) = dpsi1ds[l];
618 template<
unsigned NNODE_1D>
624 std::ostringstream error_message;
626 <<
"\nd2shpe_local currently not implemented for this element\n";
628 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
648 template<
unsigned NNODE_1D>
665 this->set_n_node(NNODE_1D * NNODE_1D);
666 Spectral_order.resize(2, NNODE_1D);
667 Nodal_spectral_order.resize(2, NNODE_1D);
669 this->set_dimension(2);
671 this->set_integration_scheme(&integral);
698 unsigned n_node_1d = nnode_1d();
703 nod_pt = this->node_pt(0);
706 nod_pt = this->node_pt(n_node_1d - 1);
709 nod_pt = this->node_pt(n_node_1d * (n_node_1d - 1));
712 nod_pt = this->node_pt(n_node_1d * n_node_1d - 1);
715 std::ostringstream error_message;
716 error_message <<
"Vertex node number is " << j
717 <<
" but must be from 0 to 3\n";
720 OOMPH_CURRENT_FUNCTION,
721 OOMPH_EXCEPTION_LOCATION);
731 unsigned n0 = n % NNODE_1D;
732 unsigned n1 = unsigned(
double(n) /
double(NNODE_1D));
740 this->local_coordinate_of_node(n, s_fraction);
742 s_fraction[0] = 0.5 * (s_fraction[0] + 1.0);
743 s_fraction[1] = 0.5 * (s_fraction[1] + 1.0);
778 return FiniteElement::invert_jacobian<2>(jacobian, inverse_jacobian);
795 void output(FILE* file_pt,
const unsigned& n_plot)
801 void output(std::ostream& outfile);
804 void output(std::ostream& outfile,
const unsigned& n_plot);
810 const unsigned& nplot,
812 const bool& use_equally_spaced_interior_sample_points =
false)
const
816 unsigned i0 =
i % nplot;
817 unsigned i1 = (
i - i0) / nplot;
819 s[0] = -1.0 + 2.0 * double(i0) / double(nplot - 1);
820 s[1] = -1.0 + 2.0 * double(i1) / double(nplot - 1);
821 if (use_equally_spaced_interior_sample_points)
824 double dx_new = range / double(nplot);
825 double range_new = double(nplot - 1) * dx_new;
826 s[0] = -1.0 + 0.5 * dx_new + range_new * (1.0 +
s[0]) / range;
827 s[1] = -1.0 + 0.5 * dx_new + range_new * (1.0 +
s[1]) / range;
842 std::ostringstream header;
843 header <<
"ZONE I=" << nplot <<
", J=" << nplot <<
"\n";
853 for (
unsigned i = 0;
i < DIM;
i++)
867 void build_face_element(
const int& face_index,
875 template<
unsigned NNODE_1D>
885 for (
unsigned i = 0;
i < NNODE_1D;
i++)
887 for (
unsigned j = 0; j < NNODE_1D; j++)
889 psi(NNODE_1D *
i + j) = psi2[
i] * psi1[j];
897 template<
unsigned NNODE_1D>
912 for (
unsigned i = 0;
i < NNODE_1D;
i++)
914 for (
unsigned j = 0; j < NNODE_1D; j++)
917 dpsids(index, 0) = psi2[
i] * dpsi1ds[j];
918 dpsids(index, 1) = dpsi2ds[
i] * psi1[j];
919 psi[index] = psi2[
i] * psi1[j];
933 template<
unsigned NNODE_1D>
939 std::ostringstream error_message;
941 <<
"\nd2shpe_local currently not implemented for this element\n";
943 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
963 template<
unsigned NNODE_1D>
980 this->set_n_node(NNODE_1D * NNODE_1D * NNODE_1D);
981 Spectral_order.resize(3, NNODE_1D);
982 Nodal_spectral_order.resize(3, NNODE_1D);
984 this->set_dimension(3);
986 this->set_integration_scheme(&integral);
1013 unsigned n_node_1d = nnode_1d();
1018 nod_pt = this->node_pt(0);
1021 nod_pt = this->node_pt(n_node_1d - 1);
1024 nod_pt = this->node_pt(n_node_1d * (n_node_1d - 1));
1027 nod_pt = this->node_pt(n_node_1d * n_node_1d - 1);
1030 nod_pt = this->node_pt(n_node_1d * n_node_1d * (n_node_1d - 1));
1033 nod_pt = this->node_pt(n_node_1d * n_node_1d * (n_node_1d - 1) +
1037 nod_pt = this->node_pt(n_node_1d * n_node_1d * n_node_1d - n_node_1d);
1040 nod_pt = this->node_pt(n_node_1d * n_node_1d * n_node_1d - 1);
1043 std::ostringstream error_message;
1044 error_message <<
"Vertex node number is " << j
1045 <<
" but must be from 0 to 7\n";
1048 OOMPH_CURRENT_FUNCTION,
1049 OOMPH_EXCEPTION_LOCATION);
1059 unsigned n0 = n % NNODE_1D;
1060 unsigned n1 = unsigned(
double(n) /
double(NNODE_1D)) % NNODE_1D;
1061 unsigned n2 = unsigned(
double(n) /
double(NNODE_1D * NNODE_1D));
1070 this->local_coordinate_of_node(n, s_fraction);
1072 s_fraction[0] = 0.5 * (s_fraction[0] + 1.0);
1073 s_fraction[1] = 0.5 * (s_fraction[1] + 1.0);
1074 s_fraction[2] = 0.5 * (s_fraction[2] + 1.0);
1113 return FiniteElement::invert_jacobian<3>(jacobian, inverse_jacobian);
1129 void output(FILE* file_pt,
const unsigned& n_plot)
1135 void output(std::ostream& outfile);
1138 void output(std::ostream& outfile,
const unsigned& nplot);
1144 const unsigned& nplot,
1146 const bool& use_equally_spaced_interior_sample_points =
false)
const
1150 unsigned i01 =
i % (nplot * nplot);
1151 unsigned i0 = i01 % nplot;
1152 unsigned i1 = (i01 - i0) / nplot;
1153 unsigned i2 = (
i - i01) / (nplot * nplot);
1155 s[0] = -1.0 + 2.0 * double(i0) / double(nplot - 1);
1156 s[1] = -1.0 + 2.0 * double(i1) / double(nplot - 1);
1157 s[2] = -1.0 + 2.0 * double(i2) / double(nplot - 1);
1158 if (use_equally_spaced_interior_sample_points)
1161 double dx_new = range / double(nplot);
1162 double range_new = double(nplot - 1) * dx_new;
1163 s[0] = -1.0 + 0.5 * dx_new + range_new * (1.0 +
s[0]) / range;
1164 s[1] = -1.0 + 0.5 * dx_new + range_new * (1.0 +
s[1]) / range;
1165 s[2] = -1.0 + 0.5 * dx_new + range_new * (1.0 +
s[2]) / range;
1181 std::ostringstream header;
1182 header <<
"ZONE I=" << nplot <<
", J=" << nplot <<
", K=" << nplot
1184 return header.str();
1193 for (
unsigned i = 0;
i < DIM;
i++)
1209 void build_face_element(
const int& face_index,
1217 template<
unsigned NNODE_1D>
1228 for (
unsigned i = 0;
i < NNODE_1D;
i++)
1230 for (
unsigned j = 0; j < NNODE_1D; j++)
1232 for (
unsigned k = 0; k < NNODE_1D; k++)
1234 psi(NNODE_1D * NNODE_1D *
i + NNODE_1D * j + k) =
1235 psi3[
i] * psi2[j] * psi1[k];
1244 template<
unsigned NNODE_1D>
1263 for (
unsigned i = 0;
i < NNODE_1D;
i++)
1265 for (
unsigned j = 0; j < NNODE_1D; j++)
1267 for (
unsigned k = 0; k < NNODE_1D; k++)
1270 dpsids(index, 0) = psi3[
i] * psi2[j] * dpsi1ds[k];
1271 dpsids(index, 1) = psi3[
i] * dpsi2ds[j] * psi1[k];
1272 dpsids(index, 2) = dpsi3ds[
i] * psi2[j] * psi1[k];
1273 psi[index] = psi3[
i] * psi2[j] * psi1[k];
1291 template<
unsigned NNODE_1D>
1297 std::ostringstream error_message;
1299 <<
"\nd2shpe_local currently not implemented for this element\n";
1301 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1321 template<
unsigned DIM>
Base class for all brick elements.
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
A class that represents a collection of data; each Data object may contain many different individual ...
long & eqn_number(const unsigned &i)
Return the equation number of the i-th stored variable.
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...
static long Is_pinned
Static "Magic number" used in place of the equation number to indicate that the value is pinned.
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...
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
static long Is_unclassified
Static "Magic number" used in place of the equation number to denote a value that hasn't been classif...
void resize(const unsigned long &n)
Resize to a square nxn matrix; any values already present will be transfered.
FaceElements are elements that coincide with the faces of higher-dimensional "bulk" elements....
A general Finite Element class.
virtual void output(std::ostream &outfile)
Output the element data — typically the values at the nodes in a format suitable for post-processing.
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 ...
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 std::deque< double * > Dof_pt_deque
Static storage for deque used to add_global_equation_numbers when pointers to the dofs in each elemen...
Base class for all line elements.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
OneDLegendreDShapeParam(const unsigned &order, const double &s)
Class that returns the shape functions associated with legendre.
static void calculate_nodal_positions(const unsigned &order)
Static function used to populate the stored positions.
static std::map< unsigned, Vector< double > > z
static double nodal_position(const unsigned &order, const unsigned &n)
OneDLegendreShapeParam(const unsigned &order, const double &s)
Constructor.
Class that returns the shape functions associated with legendre.
static double nodal_position(const unsigned &n)
static void calculate_nodal_positions()
Static function used to populate the stored positions.
An OomphLibError object which should be thrown when an run-time error is encountered....
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....
static GaussLobattoLegendre< 1, NNODE_1D > integral
Default integration rule: Gaussian integration of same 'order' as the element.
std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction)
double s_min() const
Min. value of local coordinate.
double local_one_d_fraction_of_node(const unsigned &n1d, const unsigned &i)
The local one-d fraction is the same.
unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (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.
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.
void output(FILE *file_pt)
C-style output.
unsigned nnode_1d() const
Number of nodes along each element edge.
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, const unsigned &n_plot)
C_style output at n_plot points.
double s_max() const
Max. value of local coordinate.
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 nplot points in each "coordinate direc...
unsigned nvertex_node() const
Number of vertex nodes 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.
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.
std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction)
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....
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 nplot points in each "coordinate direc...
QSpectralElement()
Constructor.
void local_fraction_of_node(const unsigned &n, Vector< double > &s_fraction)
Get the local fractino of node j in the element.
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.
unsigned nvertex_node() const
Number of vertex nodes in the element.
double s_max() const
Max. value of local coordinate.
double s_min() const
Min. value of local coordinate.
static GaussLobattoLegendre< 2, NNODE_1D > integral
Default integration rule: Gaussian integration of same 'order' as the element.
double local_one_d_fraction_of_node(const unsigned &n1d, const unsigned &i)
The local one-d fraction is the same.
void output(FILE *file_pt, const unsigned &n_plot)
C_style output at n_plot points.
QSpectralElement()
Constructor.
void output(FILE *file_pt)
C-style output.
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 nplot points in each "coordinate direc...
static GaussLobattoLegendre< 3, NNODE_1D > integral
Default integration rule: Gaussian integration of same 'order' as the element.
void local_fraction_of_node(const unsigned &n, Vector< double > &s_fraction)
Get the local fractino of node j in the element.
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.
double s_min() const
Min. value of local coordinate.
double local_one_d_fraction_of_node(const unsigned &n1d, const unsigned &i)
The local one-d fraction is the same.
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....
double s_max() const
Max. value of local coordinate.
unsigned nvertex_node() const
Number of vertex nodes in the element.
unsigned nnode_1d() const
Number of nodes along each element edge.
std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction)
unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction)
General QLegendreElement class.
Base class for all quad elements.
A class that is used to template the refineable Q spectral elements by dimension. It's really nothing...
RefineableQSpectralElement()
Empty constuctor.
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
Vector< Data * > * Spectral_data_pt
Additional Storage for shared spectral data.
DenseMatrix< int > Spectral_local_eqn
Local equation numbers for the spectral degrees of freedom.
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...
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 ...
unsigned nspectral() const
virtual ~SpectralElement()
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.
Vector< unsigned > Nodal_spectral_order
Vector that represents the nodal spectral order.
Vector< unsigned > Spectral_order
Vector that represents the spectral order in each dimension.
void output()
Doc the command line arguments.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
double dlegendre(const unsigned &p, const double &x)
Calculates first derivative of Legendre polynomial of degree p at x using three term recursive formul...
double ddlegendre(const unsigned &p, const double &x)
Calculates second derivative of Legendre polynomial of degree p at x using three term recursive formu...
double legendre(const unsigned &p, const double &x)
Calculates Legendre polynomial of degree p at x using the three term recurrence relation .
void gll_nodes(const unsigned &Nnode, Vector< double > &x)
Calculates the Gauss Lobatto Legendre abscissas for degree p = NNode-1.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...