oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT > Class Template Reference

#include <navier_stokes_elements_with_singularity.h>

+ Inheritance diagram for oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >:

Public Member Functions

 NavierStokesElementWithSingularity ()
 Constructor. More...
 
void impose_velocity_dirichlet_bc_on_node (const unsigned &j, const unsigned &d)
 
void undo_velocity_dirichlet_bc_on_node (const unsigned &j, const unsigned &d)
 
void set_velocity_dirichlet_value_on_node (const unsigned &j, const unsigned &d, const double &value)
 
void impose_dirichlet_bc_on_pressure_dof (const unsigned &j)
 Impose Dirichlet BC at the j-th pressure dof. More...
 
void undo_dirichlet_bc_on_pressure_dof (const unsigned &j)
 Undo Dirichlet BC at the j-th pressure dof. More...
 
void set_dirichlet_value_on_pressure_dof (const unsigned &j, const double &value)
 Specify Dirichlet boundary value for the j-th pressure dof. More...
 
Vector< SingularNavierStokesSolutionElement< NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT > > * > c_equation_elements_pt ()
 Access function to vector of pointers to SingularNavierStokesSolutionElements. More...
 
void add_c_equation_element_pt (SingularNavierStokesSolutionElement< NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT > > *c_pt)
 
double dpdx_fe_only (Vector< double > s, const unsigned *direction_pt)
 Derivative of pressure in direction indicated by pointer to unsigned. More...
 
void fill_in_contribution_to_residuals (Vector< double > &residuals)
 Add the element's contribution to its residual vector (wrapper) More...
 
void fill_in_contribution_to_jacobian (Vector< double > &residuals, DenseMatrix< double > &jacobian)
 
void output (std::ostream &outfile, const unsigned &nplot)
 
void compute_error (std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, const bool &include_pressure, double &error, double &norm)
 Overloaded compute error function; uses FE+singular parts. More...
 
Vector< doubleinterpolated_u_nst (const Vector< double > &s) const
 
double interpolated_p_nst (const Vector< double > &s) const
 Version of interpolated pressure including the singular contributions. More...
 

Private Member Functions

Vector< doubleu_bar (const unsigned &i, const Vector< double > &x) const
 
Vector< doubleu_bar (const Vector< double > &x) const
 
Vector< Vector< double > > grad_u_bar (const unsigned &i, const Vector< double > &x) const
 
Vector< Vector< double > > grad_u_bar (const Vector< double > &x) const
 
Vector< doublevelocity_singular_function (const unsigned &i, const Vector< double > &x) const
 Evaluate i-th "raw" velocity singular function at Eulerian position x. More...
 
Vector< Vector< double > > grad_velocity_singular_function (const unsigned &i, const Vector< double > &x) const
 
double pressure_singular_function (const unsigned &i, const Vector< double > &x) const
 
double p_bar (const unsigned &i, const Vector< double > &x) const
 
double p_bar (const Vector< double > &x) const
 
Vector< doubleinterpolated_u_nst_fe_only (const Vector< double > &s) const
 
double interpolated_p_nst_fe_only (const Vector< double > &s) const
 
void fill_in_generic_residual_contribution_wrapped_nst (Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
 Overloaded fill-in function. More...
 

Private Attributes

Vector< SingularNavierStokesSolutionElement< NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT > > * > C_equation_elements_pt
 Vector of pointers to SingularNavierStokesSolutionElement objects. More...
 
Vector< std::vector< bool > > Node_is_subject_to_velocity_dirichlet_bcs
 
Vector< Vector< double > > Imposed_velocity_values_at_node
 
std::vector< boolPressure_dof_is_subject_to_dirichlet_bc
 
Vector< doubleImposed_value_at_pressure_dof
 

Detailed Description

template<class BASIC_NAVIER_STOKES_ELEMENT>
class oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >

///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// Templated wrapper to add handling of singularities to the underlying Navier-Stokes element (specified via the template argument). Slightly inefficient because the integration loop is repeated here. The only alternative is to add the additional functionality into the Navier-Stokes elements. Not pretty either! NOTE Element ia assumed to be of Taylor Hood type with pressures stored at nodes.

Dirichlet BCs are applied in hijacking manner and must be imposed from each element that shares a boundary node that is subject to a Dirichlet condition.

Constructor & Destructor Documentation

◆ NavierStokesElementWithSingularity()

Constructor.

497  {
498 
499  // Find the number of nodes in the element
500  unsigned n_node = this->nnode();
501 
502  // Find the dimension of the problem
503  unsigned cached_dim = this->dim();
504 
505  // Initialise the vector indicating which node is subject to velocity
506  // Dirichlet BCs. The size of the vector is equal to the number of nodes
507  // in the element. Each component of the vector is a vector of booleans
508  // indicating if the velocity components at the corresponding node are
509  // subject to Dirichlet BC. By default, no node is subject to Dirichlet BC,
510  // so the vector is full of false.
512  for (unsigned j=0;j<n_node;j++)
513  {
514  Node_is_subject_to_velocity_dirichlet_bcs[j].resize(cached_dim);
515  for (unsigned d=0;d<cached_dim;d++)
516  {
518  }
519  }
520 
521  // Initialise the vector of imposed velocity values on the nodes
522  // subject to Dirichlet BC. The size of the vector is equal to the
523  // number of nodes in the element. Each component of the vector is
524  // a vector of length the dimension of the problem. This vector contains
525  // the imposed values of the velocity vector at the corresponding node.
526  // If a node is not subject to Dirichlet BC, its imposed values are zero.
527  // By default, no node is subject to Dirichlet BC so the vector is full
528  // of zeros
529  Imposed_velocity_values_at_node.resize(n_node);
530  for (unsigned j=0;j<n_node;j++)
531  {
532  Imposed_velocity_values_at_node[j].resize(cached_dim);
533  for (unsigned d=0;d<cached_dim;d++)
534  {
536  }
537  }
538 
539  // Find the number of pressure dofs
540  unsigned n_pres = this->npres_nst();
541 
542  // Initialise the vector indicating which pressure dof is subject to
543  // Dirichlet BCs. The size of the vector is equal to the number of pressure
544  // dofs in the element. Each component of the vector is a boolean
545  // indicating if the corresponding pressure unknown is subject to Dirichlet
546  // BC. By default, no pressure dof is subject to Dirichlet BC, so the vector
547  // is full of false.
549  for (unsigned l=0;l<n_pres;l++)
550  {
552  }
553 
554  // Initialise the vector of imposed values on the pressure dofs
555  // subject to Dirichlet BC. The size of the vector is equal to the
556  // number of pressure dofs in the element. Each component of
557  // the vector contains the imposed value at the corresponding pressure dof.
558  // If a pressure dof is not subject to Dirichlet BC, its imposed value
559  // is zero. By default, no pressure dof is subject to Dirichlet BC
560  // so the vector is full of zeros
561  Imposed_value_at_pressure_dof.resize(n_node);
562  for (unsigned l=0;l<n_pres;l++)
563  {
565  }
566 
567  } // End of constructor
Vector< Vector< double > > Imposed_velocity_values_at_node
Definition: navier_stokes_elements_with_singularity.h:1643
Vector< double > Imposed_value_at_pressure_dof
Definition: navier_stokes_elements_with_singularity.h:1652
std::vector< bool > Pressure_dof_is_subject_to_dirichlet_bc
Definition: navier_stokes_elements_with_singularity.h:1647
Vector< std::vector< bool > > Node_is_subject_to_velocity_dirichlet_bcs
Definition: navier_stokes_elements_with_singularity.h:1638
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Imposed_value_at_pressure_dof, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Imposed_velocity_values_at_node, j, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Node_is_subject_to_velocity_dirichlet_bcs, and oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Pressure_dof_is_subject_to_dirichlet_bc.

Member Function Documentation

◆ add_c_equation_element_pt()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::add_c_equation_element_pt ( SingularNavierStokesSolutionElement< NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT > > *  c_pt)
inline

Add pointer to associated SingularNavierStokesSolutionElement that determines the value of the amplitude of the singular functions (and gives access to the singular functions). The unknown amplitude becomes external Data for this element so assign_eqn_numbers() must be called after this function has been called.

627  {
628  // Add the element
629  C_equation_elements_pt.push_back(c_pt);
630 
631  // Add the additional unknown of this object as external data in the
632  // Navier-Stokes element
633  this->add_external_data(c_pt->internal_data_pt(0));
634  }
Vector< SingularNavierStokesSolutionElement< NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT > > * > C_equation_elements_pt
Vector of pointers to SingularNavierStokesSolutionElement objects.
Definition: navier_stokes_elements_with_singularity.h:1633

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt.

◆ c_equation_elements_pt()

Access function to vector of pointers to SingularNavierStokesSolutionElements.

617  {return C_equation_elements_pt;}

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt.

◆ compute_error()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::compute_error ( std::ostream &  outfile,
FiniteElement::SteadyExactSolutionFctPt  exact_soln_pt,
const bool include_pressure,
double error,
double norm 
)
inline

Overloaded compute error function; uses FE+singular parts.

762 {
763 
764  unsigned cached_dim=this->dim();
765 
766  error=0.0;
767  norm=0.0;
768 
769  //Vector of local coordinates
770  Vector<double> s(cached_dim);
771 
772  // Vector for coordintes
773  Vector<double> x(cached_dim);
774 
775  //Set the value of n_intpt
776  unsigned n_intpt = this->integral_pt()->nweight();
777 
778 
779  outfile << "ZONE" << std::endl;
780 
781  // Exact solution Vector (u,v,[w],p)
782  Vector<double> exact_soln(cached_dim+1);
783  Vector<double> computed_soln(cached_dim+1);
784 
785  //Loop over the integration points
786  for(unsigned ipt=0;ipt<n_intpt;ipt++)
787  {
788 
789  //Assign values of s
790  for(unsigned i=0;i<cached_dim;i++)
791  {
792  s[i] = this->integral_pt()->knot(ipt,i);
793  }
794 
795  //Get the integral weight
796  double w = this->integral_pt()->weight(ipt);
797 
798  // Get jacobian of mapping
799  double J=this->J_eulerian(s);
800 
801  //Premultiply the weights and the Jacobian
802  double W = w*J;
803 
804  // Get x position as Vector
805  this->interpolated_x(s,x);
806 
807  // Get exact solution at this point
808  (*exact_soln_pt)(x,exact_soln);
809  Vector<double> u_comp=interpolated_u_nst(s);
810  for(unsigned i=0;i<cached_dim;i++)
811  {
812  computed_soln[i]=u_comp[i];
813  }
814  unsigned hi_limit=cached_dim;
815  if (include_pressure)
816  {
817  computed_soln[cached_dim]=interpolated_p_nst(s);
818  hi_limit=cached_dim+1;
819  }
820 
821 
822  // Velocity error
823  for(unsigned i=0;i<hi_limit;i++)
824  {
825  norm+=exact_soln[i]*exact_soln[i]*W;
826  error+=(exact_soln[i]-computed_soln[i])*
827  (exact_soln[i]-computed_soln[i])*W;
828  }
829 
830  //Output x,y,...,u_exact,...]
831  for(unsigned i=0;i<cached_dim;i++)
832  {
833  outfile << x[i] << " ";
834  }
835 
836  //Output x,y,[z],u_error,v_error,[w_error], [p_error]
837  for(unsigned i=0;i<hi_limit;i++)
838  {
839  outfile << exact_soln[i]-computed_soln[i] << " ";
840  }
841  outfile << std::endl;
842  }
843 }
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
double interpolated_p_nst(const Vector< double > &s) const
Version of interpolated pressure including the singular contributions.
Definition: navier_stokes_elements_with_singularity.h:893
Vector< double > interpolated_u_nst(const Vector< double > &s) const
Definition: navier_stokes_elements_with_singularity.h:848
RealScalar s
Definition: level1_cplx_impl.h:130
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
@ W
Definition: quadtree.h:63
list x
Definition: plotDoE.py:28

References calibrate::error, ProblemParameters::exact_soln(), i, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_p_nst(), oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_u_nst(), J, s, w, oomph::QuadTreeNames::W, and plotDoE::x.

◆ dpdx_fe_only()

template<class BASIC_NAVIER_STOKES_ELEMENT >
double oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::dpdx_fe_only ( Vector< double s,
const unsigned direction_pt 
)
inline

Derivative of pressure in direction indicated by pointer to unsigned.

639  {
640  // Find the number of pressure dofs in the wrapped Navier-Stokes
641  // element pointed by
642  // the SingularNavierStokesSolutionElement class
643  unsigned n_pres = this->npres_nst();
644 
645  // Find the dimension of the problem
646  unsigned cached_dim=this->dim();
647 
648  // Set up memory for the pressure shape functions and their derivatives
649  Shape psip(n_pres), testp(n_pres);
650  DShape dpsipdx(n_pres,cached_dim), dtestpdx(n_pres,cached_dim);
651 
652  // Compute the pressure shape functions and their derivatives
653  // at the local coordinate S_in_wrapped_navier_stokes_element
654  // (Test fcts not really needed but nobody's got around to writing
655  // a fct that only picks out the basis fcts.
656  this->dpshape_and_dptest_eulerian_nst
657  (s,psip,dpsipdx,testp,dtestpdx);
658 
659  // Initialise the derivative used for the residual
660  double interpolated_dpdx_fe_only=0.0;
661 
662  // Compute the derivative used for the residual. The direction of the
663  // derivative is given by *Direction_pt
664  for (unsigned j=0;j<n_pres;j++)
665  {
666  interpolated_dpdx_fe_only +=
667  this->p_nst(j)*dpsipdx(j,*direction_pt);
668  }
669 
670  return interpolated_dpdx_fe_only;
671  }

References j, and s.

◆ fill_in_contribution_to_jacobian()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_contribution_to_jacobian ( Vector< double > &  residuals,
DenseMatrix< double > &  jacobian 
)
inline

Add the element's contribution to its residual vector and element Jacobian matrix (wrapper)

689  {
690  // Call the generic routine with the flag set to 1 and dummy mass matrix
691  DenseMatrix<double> mass_matrix;
693  jacobian,
694  1);
695 
696  /* // FD version if you want to mess around with anything...*/
697  /* FiniteElement::fill_in_contribution_to_jacobian(residuals,jacobian); */
698  }
void fill_in_generic_residual_contribution_wrapped_nst(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Overloaded fill-in function.
Definition: navier_stokes_elements_with_singularity.h:1111

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_generic_residual_contribution_wrapped_nst().

◆ fill_in_contribution_to_residuals()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_contribution_to_residuals ( Vector< double > &  residuals)
inline

Add the element's contribution to its residual vector (wrapper)

676  {
677  // Call the generic residuals function with flag set to 0
678  // using a dummy matrix argument
680  residuals,
682  0);
683  }
static DenseMatrix< double > Dummy_matrix
Definition: elements.h:227

References oomph::GeneralisedElement::Dummy_matrix, and oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_generic_residual_contribution_wrapped_nst().

◆ fill_in_generic_residual_contribution_wrapped_nst()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_generic_residual_contribution_wrapped_nst ( Vector< double > &  residuals,
DenseMatrix< double > &  jacobian,
const unsigned flag 
)
inlineprivate

Overloaded fill-in function.

1115 {
1116  // Get the contribution from the underlying wrapped element first
1117  BASIC_NAVIER_STOKES_ELEMENT::fill_in_generic_residual_contribution_nst
1118  (residuals,jacobian,GeneralisedElement::Dummy_matrix,flag);
1119 
1120  // Find the dimension of the problem
1121  unsigned cached_dim = this->dim();
1122 
1123  // Do all the singular functions satisfy the Stokes eqn?
1124  bool all_singular_functions_satisfy_stokes_equation=true;
1125 
1126  // Find the number of singularities
1127  unsigned n_sing = C_equation_elements_pt.size();
1128 
1129  // Find the local equation number of the additional unknowns
1130  Vector<int> local_equation_number_C(n_sing);
1131  for (unsigned i=0;i<n_sing;i++)
1132  {
1133  local_equation_number_C[i] = this->external_local_eqn(i,0);
1134  if (!(C_equation_elements_pt[i]->
1135  singular_function_satisfies_stokes_equation()))
1136  {
1137  all_singular_functions_satisfy_stokes_equation=false;
1138  }
1139  }
1140 
1141  // Find out how many nodes there are
1142  unsigned n_node = this->nnode();
1143 
1144  // Find out how many pressure dofs there are
1145  unsigned n_pres = this->npres_nst();
1146 
1147  // Find the indices at which the local velocities are stored
1148  Vector<unsigned> u_nodal_index(cached_dim);
1149  for (unsigned d=0;d<cached_dim;d++)
1150  {
1151  u_nodal_index[d] = this->u_index_nst(d);
1152  }
1153 
1154  // integer to store the local equations
1155  int local_eqn=0, local_unknown=0;
1156 
1157  // Check that there's no time-dependence
1158  for (unsigned j=0;j<n_node;j++)
1159  {
1160  if (!(this->node_pt(j)->time_stepper_pt()->is_steady()))
1161  {
1162  std::stringstream error_stream;
1163  error_stream
1164  << "Currently, the NavierStokesElementWithSingularity elements\n"
1165  << "only work for steady problems, but we have detected a\n"
1166  << "non-steady time-stepper for node " << j << ".\n"
1167  << "If your problem is time-dependent you're welcome to \n"
1168  << "volunteer and implement the required functionality in \n\n"
1169  << " NavierStokesElementWithSingularity::fill_in_generic_residual_contribution_wrapped_nst()\n\n"
1170  << std::endl;
1171  throw OomphLibError(
1172  error_stream.str(),
1175  }
1176  }
1177 
1178 
1179 
1180  // Check that ALE is disabled
1181  if (!this->ALE_is_disabled)
1182  {
1183  std::stringstream error_stream;
1184  error_stream
1185  << "Currently, the NavierStokesElementWithSingularity elements\n"
1186  << "only work on fixed meshes, and to check this we require\n"
1187  << "that you assert that this is the case by calling \n\n"
1188  << " NavierStokesElementWithSingularity::disable_ALE()"
1189  << "\n\n\n"
1190  << "for all bulk Navier-Stokes elements.\n"
1191  << "If your mesh is moving you're welcome to volunteer and implement\n"
1192  << "the required functionality in \n\n"
1193  << " NavierStokesElementWithSingularity::fill_in_generic_residual_contribution_wrapped_nst()\n\n"
1194  << std::endl;
1195  throw OomphLibError(
1196  error_stream.str(),
1199  }
1200 
1201 
1202  // Throw an error for now...
1203  if ((!all_singular_functions_satisfy_stokes_equation)&&(flag==1))
1204  {
1205  std::stringstream error_stream;
1206  error_stream
1207  << "Currently, the analytical computation of the Jacobian for the\n"
1208  << "NavierStokesElementWithSingularity elements\n"
1209  << "only work with singular solutions that satisfy the Stokes eqns.\n"
1210  << "Of course, there's no way of checking this, so you'll have to\n"
1211  << "assert that this is the case by calling \n\n"
1212  << " SingularNavierStokesSolutionElement::singular_function_satisfies_stokes_equation()"
1213  << "\n\n\n"
1214  << "for the SingularNavierStokesSolutionElement that specifies the singular functions.\n"
1215  << "If your singular functions do not satisfy the Stokes equations\n"
1216  << "you're welcome to volunteer and implement the required \n"
1217  << "functionality in \n\n"
1218  << " NavierStokesElementWithSingularity::fill_in_generic_residual_contribution_wrapped_nst()\n\n"
1219  << "Fragments of code are already there...\n"
1220  << "Alternatively, use FD-based setup of Jacobian (still there, commented out, in code).\n"
1221  << "The reason this never got implemented is because this case typically only arises\n"
1222  << "when trying to \"blend\" solutions (to give them finite support) and this didn't\n"
1223  << "seem to work too well and was sort of abandoned. Next person to look at this\n"
1224  << "should consider only adding the non-integrated by parts (source-fct-like) terms\n"
1225  << "arising from the singular functions...\n"
1226  << std::endl;
1227  throw OomphLibError(
1228  error_stream.str(),
1231  }
1232 
1233  // Get Physical Variables from Element
1234  // Reynolds number must be multiplied by the density ratio
1235  double scaled_re = this->re()*this->density_ratio();
1236 
1237  // Do we need extra bulk terms?
1238  if ((scaled_re>0.0)||(!all_singular_functions_satisfy_stokes_equation))
1239  {
1240 
1241  // Set up memory for the velocity shape and test functions
1242  Shape psif(n_node), testf(n_node);
1243  DShape dpsifdx(n_node,cached_dim), dtestfdx(n_node,cached_dim);
1244 
1245  // Set up memory for pressure shape and test functions
1246  Shape psip(n_pres), testp(n_pres);
1247 
1248  // Number of integration points
1249  unsigned n_intpt = this->integral_pt()->nweight();
1250 
1251  // Set the vector to hold local coordinates
1252  Vector<double> s(cached_dim);
1253 
1254  // Cachec viscosity ratio
1255  double visc_ratio = this->viscosity_ratio();
1256 
1257  // Loop over the integration points
1258  for (unsigned ipt=0;ipt<n_intpt;ipt++)
1259  {
1260  // Assign values of s
1261  for (unsigned d=0;d<cached_dim;d++)
1262  {
1263  s[d] = this->integral_pt()->knot(ipt,d);
1264  }
1265 
1266  // Get the integral weight
1267  double w = this->integral_pt()->weight(ipt);
1268 
1269  // Call the derivatives of the velocity shape and test functions
1270  double J =
1271  this->dshape_and_dtest_eulerian_at_knot_nst(ipt,psif,dpsifdx,
1272  testf,dtestfdx);
1273 
1274  // Call the pressure shape and test functions
1275  this->pshape_nst(s,psip,testp);
1276 
1277  // Premultiply the weights and the Jacobian
1278  double W = w*J;
1279 
1280  // Initialise the global coordinate and velocity
1281  Vector<double> interpolated_x(cached_dim,0.0);
1282  Vector<double> interpolated_u(cached_dim,0.0);
1283  DenseMatrix<double> interpolated_dudx(cached_dim,cached_dim,0.0);
1284 
1285  // Calculate the global coordinate associated with s
1286  // Loop over nodes
1287  for (unsigned l=0;l<n_node;l++)
1288  {
1289  // Loop over directions
1290  for (unsigned i=0;i<cached_dim;i++)
1291  {
1292  double u_value = this->raw_nodal_value(l,u_nodal_index[i]);
1293  interpolated_u[i] += u_value*psif[l];
1294  interpolated_x[i] += this->raw_nodal_position(l,i)*psif(l);
1295  for(unsigned j=0;j<cached_dim;j++)
1296  {
1297  interpolated_dudx(i,j) += u_value*dpsifdx(l,j);
1298  }
1299  }
1300  }
1301 
1302  // Get sum of singular functions
1303  Vector<double> u_bar_local=this->u_bar(interpolated_x);
1304  Vector<Vector<double> > grad_u_bar_local=this->grad_u_bar(interpolated_x);
1305  double p_bar_local=this->p_bar(interpolated_x);
1306 
1307  // Singular functions
1308  Vector<Vector<double> > u_hat_local(n_sing);
1309  for (unsigned s=0;s<n_sing;s++)
1310  {
1311  u_hat_local[s]=this->velocity_singular_function(s,interpolated_x);
1312  }
1313  Vector<Vector<Vector<double> > > grad_u_hat_local(n_sing);
1314  for (unsigned s=0;s<n_sing;s++)
1315  {
1316  grad_u_hat_local[s]=
1317  this->grad_velocity_singular_function(s,interpolated_x);
1318  }
1319 
1320  // MOMENTUM EQUATIONS
1321  //-------------------
1322 
1323  // Loop over the velocity test functions
1324  for (unsigned l=0;l<n_node;l++)
1325  {
1326  // Loop over the velocity components
1327  for (unsigned i=0;i<cached_dim;i++)
1328  {
1329  // Find its local equation number
1330  local_eqn = this->nodal_local_eqn(l,u_nodal_index[i]);
1331 
1332  // If it is not pinned
1333  if (local_eqn >= 0)
1334  {
1335  // If it is not a Dirichlet BC
1337  {
1338 
1339 
1340  // Linear terms only needed if singular solution doesn't satisfy
1341  //--------------------------------------------------------------
1342  // Stokes eqn
1343  //-----------
1344  if (!all_singular_functions_satisfy_stokes_equation)
1345  {
1346  residuals[local_eqn]+=p_bar_local*dtestfdx(l,i)*W;
1347  for (unsigned k=0;k<cached_dim;k++)
1348  {
1349  residuals[local_eqn] -= visc_ratio*
1350  (grad_u_bar_local[i][k]+this->Gamma[i]*grad_u_bar_local[k][i])
1351  *dtestfdx(l,k)*W;
1352  }
1353  }
1354 
1355 
1356  // Nonlinear term. Always add (unless Re=0)
1357  //-----------------------------------------
1358  if (scaled_re>0.0)
1359  {
1360  // Add singular convective terms
1361  double sum = 0.0;
1362  for (unsigned k=0;k<cached_dim;k++)
1363  {
1364  sum+=u_bar_local[k]*(grad_u_bar_local[i][k]+interpolated_dudx(i,k))
1365  +interpolated_u[k]*grad_u_bar_local[i][k];
1366  }
1367  residuals[local_eqn] -= scaled_re*sum*testf[l]*W;
1368 
1369  }
1370 
1371  // Calculate the jacobian
1372  //-----------------------
1373  if(flag)
1374  {
1375 
1376  if (scaled_re>0.0)
1377  {
1378  // Loop over the singularities and add the
1379  // contributions of the additional
1380  // unknowns associated with them to the
1381  // jacobian if they are not pinned
1382  for (unsigned ss=0;ss<n_sing;ss++)
1383  {
1384  local_unknown=local_equation_number_C[ss];
1385  if (local_unknown>=0)
1386  {
1387  double sum=0.0;
1388  for (unsigned k=0;k<cached_dim;k++)
1389  {
1390  sum+=u_hat_local[ss][k]*(grad_u_bar_local[i][k]+
1391  interpolated_dudx(i,k))+
1392  grad_u_hat_local[ss][i][k]*
1393  (u_bar_local[k]+interpolated_u[k]);
1394  }
1395  jacobian(local_eqn,local_unknown)-=scaled_re*sum*testf[l]*W;
1396  }
1397  }
1398 
1399 
1400  //Loop over the velocity shape functions again
1401  for(unsigned l2=0;l2<n_node;l2++)
1402  {
1403  //Loop over the velocity components again
1404  for(unsigned i2=0;i2<cached_dim;i2++)
1405  {
1406  //If at a non-zero degree of freedom add in the entry
1407  local_unknown = this->nodal_local_eqn(l2,u_nodal_index[i2]);
1408  if(local_unknown >= 0)
1409  {
1410  double sum=0.0;
1411  if (i==i2)
1412  {
1413  for (unsigned k=0;k<cached_dim;k++)
1414  {
1415  sum+=u_bar_local[k]*dpsifdx(l2,k);
1416  }
1417  }
1418  sum+=psif(l2)*grad_u_bar_local[i][i2];
1419 
1420  //Add contribution to Elemental Matrix
1421  jacobian(local_eqn,local_unknown) -=
1422  scaled_re*sum*testf[l]*W;
1423  }
1424  }
1425  }
1426  }
1427  }
1428  } // End of check of the Dirichlet status
1429  } // End of check of the pin status
1430  } // End of loop over velocity components
1431  } // End of loop over test functions
1432 
1433 
1434 
1435  // Linear terms only needed if singular solution doesn't satisfy
1436  //--------------------------------------------------------------
1437  // Stokes eqn
1438  //-----------
1439  if (!all_singular_functions_satisfy_stokes_equation)
1440  {
1441  // Loop over the pressure test functions
1442  for (unsigned l=0;l<n_pres;l++)
1443  {
1444  local_eqn = this->p_local_eqn(l);
1445 
1446  // If not pinned
1447  if (local_eqn >= 0)
1448  {
1449  // If not subject to Dirichlet BC
1451  {
1452  double aux = 0.0;
1453  // Loop over velocity components
1454  for (unsigned k=0;k<cached_dim;k++)
1455  {
1456  aux += grad_u_bar_local[k][k];
1457  }
1458  residuals[local_eqn] += aux*testp[l]*W;
1459  }
1460  }
1461  }
1462  }
1463 
1464  } // End of loop over integration points
1465 
1466 
1467  }
1468 
1469  // VELOCITY DIRICHLET BCS
1470  //-----------------------
1471  Vector<double> u_bar_at_node(cached_dim);
1472  Vector<Vector<double> > u_hat_at_node(n_sing);
1473  for (unsigned i=0;i<n_sing;i++)
1474  {
1475  u_hat_at_node[i].resize(cached_dim);
1476  }
1477 
1478  // Loop over the nodes
1479  for (unsigned l=0;l<n_node;l++)
1480  {
1481  // Find the global coordinate of the node
1482  Vector<double> global_coordinate(cached_dim);
1483  for (unsigned d=0;d<cached_dim;d++)
1484  {
1485  global_coordinate[d] = this->raw_nodal_position(l,d);
1486  }
1487 
1488  // Get singular velocity at node
1489  u_bar_at_node=this->u_bar(global_coordinate);
1490  for (unsigned i=0;i<n_sing;i++)
1491  {
1492  u_hat_at_node[i]=velocity_singular_function(i,global_coordinate);
1493  }
1494 
1495  // Loop over the velocity components
1496  for (unsigned d=0;d<cached_dim;d++)
1497  {
1498  // Find its local equation number
1499  local_eqn = this->nodal_local_eqn(l,u_nodal_index[d]);
1500 
1501  // If it is not pinned
1502  if (local_eqn >= 0)
1503  {
1504  // If it is a Dirichlet boundary condition
1506  {
1507  // Initialise the residual
1508  residuals[local_eqn] = 0.0;
1509 
1510  // Add the contribution of the nodal value
1511  residuals[local_eqn] += this->raw_nodal_value(l,u_nodal_index[d]);
1512 
1513  // Add the contribution of the singularities (all of them, summed)
1514  residuals[local_eqn] += u_bar_at_node[d];
1515 
1516  // Substract the imposed Dirichlet value
1517  residuals[local_eqn] -= Imposed_velocity_values_at_node[l][d];
1518 
1519  if (flag)
1520  {
1521 
1522  // Wipe the existing entries
1523  unsigned n_dof=this->ndof();
1524  for (unsigned j=0;j<n_dof;j++)
1525  {
1526  jacobian(local_eqn,j)=0.0;
1527  }
1528 
1529  // Add diagonal entry
1530  jacobian(local_eqn,local_eqn) += 1.0;
1531 
1532 
1533  // Add derivative w.r.t. the Cs
1534  for (unsigned i=0;i<n_sing;i++)
1535  {
1536  // Find the contribution of the additional unknowns to
1537  // the jacobian
1538  local_unknown=local_equation_number_C[i];
1539  if (local_unknown>=0)
1540  {
1541  jacobian(local_eqn,local_unknown) +=
1542  u_hat_at_node[i][d];
1543  }
1544  }
1545 
1546  }
1547  }
1548  }
1549  }
1550  }
1551 
1552 
1553  // PRESSURE DIRICHLET BCS
1554  //-----------------------
1555 
1556  // Loop over the pressure dofs
1557  for (unsigned l=0;l<n_pres;l++)
1558  {
1559  // Find its local equation number
1560  local_eqn = this->p_local_eqn(l);
1561 
1562  // If it is not pinned
1563  if (local_eqn >= 0)
1564  {
1565  // If it is subject to a Dirichlet BC
1567  {
1568  // Find its global coordinate
1569  // This conversionly works for Taylor Hood type elements
1570  // but there's not much point assigning pressure dofs
1571  Node* p_nod_pt=this->node_pt(this->Pconv[l]);
1572 
1573  oomph_info << "Constrained pressure node: "
1574  << this->Pconv[l] << " at: ";
1575 
1576  Vector<double> global_coordinate(cached_dim,0.0);
1577  for (unsigned d=0;d<cached_dim;d++)
1578  {
1579  global_coordinate[d] = p_nod_pt->x(d);
1580  oomph_info << global_coordinate[d] << " ";
1581  }
1582  oomph_info << std::endl;
1583 
1584  // Initialise its residual component
1585  residuals[local_eqn] = 0.0;
1586 
1587  // Add the contribution of the pressure unknown
1588  residuals[local_eqn] += this->p_nst(l);
1589 
1590  // Add singular contributions
1591  residuals[local_eqn] += p_bar(global_coordinate);
1592 
1593  // Substract the imposed pressure value
1594  residuals[local_eqn] -= Imposed_value_at_pressure_dof[l];
1595 
1596  if (flag)
1597  {
1598 
1599  // Wipe the existing entries
1600  unsigned n_dof=this->ndof();
1601  for (unsigned j=0;j<n_dof;j++)
1602  {
1603  jacobian(local_eqn,j)=0.0;
1604  }
1605 
1606  // Add diagonal entry
1607  jacobian(local_eqn,local_eqn) += 1.0;
1608 
1609  // Add derivative w.r.t. the Cs
1610  for (unsigned i=0;i<n_sing;i++)
1611  {
1612  // Find the contribution of the additional unknowns to
1613  // the jacobian
1614  local_unknown=local_equation_number_C[i];
1615  if (local_unknown>=0)
1616  {
1617  jacobian(local_eqn,local_unknown) +=
1618  pressure_singular_function(i,global_coordinate);
1619  }
1620  }
1621  }
1622  }
1623  }
1624  }
1625 
1626 
1627  } // End of function
double pressure_singular_function(const unsigned &i, const Vector< double > &x) const
Definition: navier_stokes_elements_with_singularity.h:1015
Vector< Vector< double > > grad_velocity_singular_function(const unsigned &i, const Vector< double > &x) const
Definition: navier_stokes_elements_with_singularity.h:1007
double p_bar(const unsigned &i, const Vector< double > &x) const
Definition: navier_stokes_elements_with_singularity.h:1024
Vector< Vector< double > > grad_u_bar(const unsigned &i, const Vector< double > &x) const
Definition: navier_stokes_elements_with_singularity.h:961
Vector< double > velocity_singular_function(const unsigned &i, const Vector< double > &x) const
Evaluate i-th "raw" velocity singular function at Eulerian position x.
Definition: navier_stokes_elements_with_singularity.h:998
Vector< double > u_bar(const unsigned &i, const Vector< double > &x) const
Definition: navier_stokes_elements_with_singularity.h:931
char char char int int * k
Definition: level2_impl.h:374
double Gamma
Aspect ratio (cylinder height / cylinder radius)
Definition: axisym_navier_stokes/counter_rotating_disks/counter_rotating_disks.cc:70
bool ALE_is_disabled
Definition: gen_axisym_advection_diffusion_elements.h:638
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References oomph::ALE_is_disabled, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt, oomph::GeneralisedElement::Dummy_matrix, GlobalPhysicalVariables::Gamma, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::grad_u_bar(), oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::grad_velocity_singular_function(), i, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Imposed_value_at_pressure_dof, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Imposed_velocity_values_at_node, J, j, k, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Node_is_subject_to_velocity_dirichlet_bcs, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::p_bar(), oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Pressure_dof_is_subject_to_dirichlet_bc, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::pressure_singular_function(), s, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::u_bar(), oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::velocity_singular_function(), w, oomph::QuadTreeNames::W, and oomph::Node::x().

Referenced by oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_contribution_to_jacobian(), and oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_contribution_to_residuals().

◆ grad_u_bar() [1/2]

template<class BASIC_NAVIER_STOKES_ELEMENT >
Vector<Vector<double> > oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::grad_u_bar ( const unsigned i,
const Vector< double > &  x 
) const
inlineprivate

Evaluate i-th grad_u_bar (i-th gradient of velocity singular fct incl. the amplitude) function at Eulerian position x; grad[i][j] = du_i/dx_j

963  {
964  return C_equation_elements_pt[i]->grad_u_bar(x);
965  }

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt, i, and plotDoE::x.

Referenced by oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_generic_residual_contribution_wrapped_nst().

◆ grad_u_bar() [2/2]

template<class BASIC_NAVIER_STOKES_ELEMENT >
Vector<Vector<double> > oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::grad_u_bar ( const Vector< double > &  x) const
inlineprivate

Evaluate gradient of sum of all velocity singular fcts (incl. the amplitudes) at Eulerian position x: grad[i][j] = du_i/dx_j

970  {
971  // Find the number of singularities
972  unsigned n_sing = C_equation_elements_pt.size();
973 
974  // Find the dimension of the problem
975  unsigned cached_dim=this->dim();
976  Vector<Vector<double> > sum(cached_dim);
977  for (unsigned i=0;i<cached_dim;i++)
978  {
979  sum[i].resize(cached_dim,0.0);
980  }
981  for (unsigned s=0;s<n_sing;s++)
982  {
983  Vector<Vector<double> > grad_u_bar_local=
984  C_equation_elements_pt[s]->grad_u_bar(x);
985  for (unsigned i=0;i<cached_dim;i++)
986  {
987  for (unsigned j=0;j<cached_dim;j++)
988  {
989  sum[i][j]+=grad_u_bar_local[i][j];
990  }
991  }
992  }
993  return sum;
994  }

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt, i, j, s, and plotDoE::x.

◆ grad_velocity_singular_function()

template<class BASIC_NAVIER_STOKES_ELEMENT >
Vector<Vector<double> > oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::grad_velocity_singular_function ( const unsigned i,
const Vector< double > &  x 
) const
inlineprivate

Evaluate gradient of i-th "raw" velocity singular function at Eulerian position x

1009  {
1010  return C_equation_elements_pt[i]->grad_velocity_singular_function(x);
1011  }

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt, i, and plotDoE::x.

Referenced by oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_generic_residual_contribution_wrapped_nst().

◆ impose_dirichlet_bc_on_pressure_dof()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::impose_dirichlet_bc_on_pressure_dof ( const unsigned j)
inline

◆ impose_velocity_dirichlet_bc_on_node()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::impose_velocity_dirichlet_bc_on_node ( const unsigned j,
const unsigned d 
)
inline

Impose Dirichlet BC on the d-th component of the velocity (including the singular contribution) at the j-th node

574  {
576  }

References j, and oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Node_is_subject_to_velocity_dirichlet_bcs.

◆ interpolated_p_nst()

template<class BASIC_NAVIER_STOKES_ELEMENT >
double oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_p_nst ( const Vector< double > &  s) const
inline

Version of interpolated pressure including the singular contributions.

894  {
895  // Initialise pressure value with fe part
896  double interpolated_p = interpolated_p_nst_fe_only(s);
897 
898  // Calculate the global coordinate associated with s
899  unsigned cached_dim = this->dim();
900  Vector<double> x(cached_dim,0.0);
901 
902  //Find number of nodes
903  const unsigned n_node = this->nnode();
904 
905  //Local shape function
906  Shape psif(n_node);
907 
908  //Find values of shape function
909  this->shape(s,psif);
910 
911  //Loop over the local nodes and sum
912  for(unsigned j=0;j<n_node;j++)
913  {
914  for (unsigned d=0;d<cached_dim;d++)
915  {
916  x[d]+=this->raw_nodal_position(j,d)*psif(j);
917  }
918  }
919 
920  // Add the singularities contribution (all of them, summed)
921  interpolated_p+=p_bar(x);
922 
923  return interpolated_p;
924 }
double interpolated_p_nst_fe_only(const Vector< double > &s) const
Definition: navier_stokes_elements_with_singularity.h:1084
void shape(const double &s, double *Psi)
Definition: shape.h:564

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_p_nst_fe_only(), j, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::p_bar(), s, oomph::OneDimLagrange::shape(), and plotDoE::x.

Referenced by oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::compute_error(), and oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::output().

◆ interpolated_p_nst_fe_only()

template<class BASIC_NAVIER_STOKES_ELEMENT >
double oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_p_nst_fe_only ( const Vector< double > &  s) const
inlineprivate

Return FE representation of pressure solution WITHOUT singular contributions at local coordinate s

1085  {
1086  // Find number of pressure degrees of freedom
1087  unsigned n_pres = this->npres_nst();
1088 
1089  // Set up memory for pressure shape and test functions
1090  Shape psip(n_pres), testp(n_pres);
1091 
1092  // Compute the values of the pressure shape and test functions at the
1093  // local coordinate s
1094  this->pshape_nst(s,psip,testp);
1095 
1096  // Initialise pressure value
1097  double interpolated_p = 0.0;
1098 
1099  // Add the contribution of p_FE
1100  // Loop over the pressure dof and sum
1101  for (unsigned l=0;l<n_pres;l++)
1102  {
1103  interpolated_p += this->p_nst(l)*psip[l];
1104  }
1105 
1106  return interpolated_p;
1107  }

References s.

Referenced by oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_p_nst(), and oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::output().

◆ interpolated_u_nst()

template<class BASIC_NAVIER_STOKES_ELEMENT >
Vector<double> oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_u_nst ( const Vector< double > &  s) const
inline

Overloaded version of the interpolated velocity solution including the singular contributions

850  {
851  // Find the dimension of the problem
852  unsigned cached_dim=this->dim();
853 
854  //Find number of nodes
855  const unsigned n_node = this->nnode();
856 
857  //Initialise value of u
858  Vector<double> interpolated_u(cached_dim,0.0);
859 
860  // Calculate the global coordinate associated with s
861  Vector<double> x(cached_dim,0.0);
862 
863  //Local shape function
864  Shape psif(n_node);
865 
866  //Find values of shape function
867  this->shape(s,psif);
868 
869  //Loop over the spatial directions
870  for (unsigned d=0;d<cached_dim;d++)
871  {
872  //Get the index at which the unknown is stored
873  const unsigned u_nodal_index = this->u_index_nst(d);
874 
875  //Loop over the local nodes and sum
876  for(unsigned j=0;j<n_node;j++)
877  {
878  interpolated_u[d] += this->nodal_value(j,u_nodal_index)*psif[j];
879  x[d]+=this->raw_nodal_position(j,d)*psif(j);
880  }
881  }
882 
883  // Add the contribution of the singularities (all of them, summed)
884  Vector<double> u_bar_local=u_bar(x);
885  for (unsigned d=0;d<cached_dim;d++)
886  {
887  interpolated_u[d] += u_bar_local[d];
888  }
889  return(interpolated_u);
890  }

References j, oomph::OneDimLagrange::shape(), oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::u_bar(), and plotDoE::x.

Referenced by oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::compute_error(), and oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::output().

◆ interpolated_u_nst_fe_only()

template<class BASIC_NAVIER_STOKES_ELEMENT >
Vector<double> oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_u_nst_fe_only ( const Vector< double > &  s) const
inlineprivate

Return FE representation of velocity solution WITHOUT singular contributions at local coordinate s

1048  {
1049  // Find number of nodes
1050  const unsigned n_node = this->nnode();
1051 
1052  // Find the dimension of the problem
1053  unsigned cached_dim = this->dim();
1054 
1055  //Initialise value of u
1056  Vector<double> interpolated_u(cached_dim,0.0);
1057 
1058  //Local shape function
1059  Shape psif(n_node);
1060 
1061  //Find values of shape function
1062  this->shape(s,psif);
1063 
1064  //Loop over the velocity components
1065  for (unsigned d=0;d<cached_dim;d++)
1066  {
1067  //Get the index at which the unknown is stored
1068  const unsigned u_nodal_index = this->u_index_nst(d);
1069 
1070  // Add the contribution of u_FE
1071  //Loop over the local nodes and sum
1072  for(unsigned j=0;j<n_node;j++)
1073  {
1074  interpolated_u[d] += this->nodal_value(j,u_nodal_index)*psif[j];
1075  }
1076  }
1077 
1078  return interpolated_u;
1079  }

References j, and oomph::OneDimLagrange::shape().

Referenced by oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::output().

◆ output()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::output ( std::ostream &  outfile,
const unsigned nplot 
)
inline

Overload the output function x, y, [z,] u, v, [w], p, u_fe, v_fe, [w_fe], p_fe,

704  {
705  // Find the dimension of the problem
706  unsigned cached_dim = this->dim();
707 
708  //Vector of local coordinates
709  Vector<double> s(cached_dim);
710 
711  // Tecplot header info
712  outfile << this->tecplot_zone_string(nplot);
713 
714  // Loop over plot points
715  unsigned num_plot_points=this->nplot_points(nplot);
716  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
717  {
718  // Get local coordinates of plot point
719  this->get_s_plot(iplot,nplot,s);
720 
721  Vector<double> x(cached_dim);
722  for(unsigned i=0;i<cached_dim;i++)
723  {
724  outfile << this->interpolated_x(s,i) << " ";
725  x[i] = this->interpolated_x(s,i);
726  }
727 
728  Vector<double> velocity = interpolated_u_nst(s);
729  Vector<double> velocity_fe_only = interpolated_u_nst_fe_only(s);
730  for (unsigned i=0;i<cached_dim;i++)
731  {
732  outfile << velocity[i] << " ";
733  }
734  outfile << this->interpolated_p_nst(s) << " ";
735  for (unsigned i=0;i<cached_dim;i++)
736  {
737  outfile << velocity_fe_only[i] << " ";
738  }
739  outfile << this->interpolated_p_nst_fe_only(s) << " ";
740  for (unsigned i=0;i<cached_dim;i++)
741  {
742  outfile << velocity[i] - velocity_fe_only[i] << " ";
743  }
744  outfile
745  << this->interpolated_p_nst(s)-
747  << " " << std::endl;
748 
749  }
750 
751  // Write tecplot footer (e.g. FE connectivity lists)
752  this->write_tecplot_zone_footer(outfile,nplot);
753 
754  }
Vector< double > interpolated_u_nst_fe_only(const Vector< double > &s) const
Definition: navier_stokes_elements_with_singularity.h:1047
double velocity(const double &t)
Angular velocity as function of time t.
Definition: jeffery_orbit.cc:107

References i, oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_p_nst(), oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_p_nst_fe_only(), oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_u_nst(), oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::interpolated_u_nst_fe_only(), s, Jeffery_Solution::velocity(), and plotDoE::x.

◆ p_bar() [1/2]

template<class BASIC_NAVIER_STOKES_ELEMENT >
double oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::p_bar ( const unsigned i,
const Vector< double > &  x 
) const
inlineprivate

◆ p_bar() [2/2]

template<class BASIC_NAVIER_STOKES_ELEMENT >
double oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::p_bar ( const Vector< double > &  x) const
inlineprivate

Evaluate sum of all pressure singular fcts (incl. the amplitudes) at Eulerian position x

1032  {
1033  // Find the number of singularities
1034  unsigned n_sing = C_equation_elements_pt.size();
1035 
1036  double sum=0.0;
1037  for (unsigned i=0;i<n_sing;i++)
1038  {
1039  sum+=C_equation_elements_pt[i]->p_bar(x);
1040  }
1041  return sum;
1042  }

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt, i, and plotDoE::x.

◆ pressure_singular_function()

template<class BASIC_NAVIER_STOKES_ELEMENT >
double oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::pressure_singular_function ( const unsigned i,
const Vector< double > &  x 
) const
inlineprivate

Evaluate i-th pressure singular fct (without the amplitude) at Eulerian position x

1017  {
1018  return C_equation_elements_pt[i]->pressure_singular_function(x);
1019  }

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt, i, and plotDoE::x.

Referenced by oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_generic_residual_contribution_wrapped_nst().

◆ set_dirichlet_value_on_pressure_dof()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::set_dirichlet_value_on_pressure_dof ( const unsigned j,
const double value 
)
inline

Specify Dirichlet boundary value for the j-th pressure dof.

610  {
612  }
squared absolute value
Definition: GlobalFunctions.h:87

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Imposed_value_at_pressure_dof, j, and Eigen::value.

◆ set_velocity_dirichlet_value_on_node()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::set_velocity_dirichlet_value_on_node ( const unsigned j,
const unsigned d,
const double value 
)
inline

Specify Dirichlet boundary value for the d-th velocity component (including the singular contribution) at the j-th local node

590  {
592  }

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Imposed_velocity_values_at_node, j, and Eigen::value.

◆ u_bar() [1/2]

template<class BASIC_NAVIER_STOKES_ELEMENT >
Vector<double> oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::u_bar ( const unsigned i,
const Vector< double > &  x 
) const
inlineprivate

◆ u_bar() [2/2]

template<class BASIC_NAVIER_STOKES_ELEMENT >
Vector<double> oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::u_bar ( const Vector< double > &  x) const
inlineprivate

Evaluate sum of all velocity singular fcts (incl. the amplitude) at Eulerian position x

939  {
940  // Find the number of singularities
941  unsigned n_sing = C_equation_elements_pt.size();
942 
943  // Find the dimension of the problem
944  unsigned cached_dim=this->dim();
945  Vector<double> sum(cached_dim,0.0);
946  for (unsigned s=0;s<n_sing;s++)
947  {
948  Vector<double> u_bar_local=
949  C_equation_elements_pt[s]->u_bar(x);
950  for (unsigned i=0;i<cached_dim;i++)
951  {
952  sum[i]+=u_bar_local[i];
953  }
954  }
955  return sum;
956  }

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt, i, s, and plotDoE::x.

◆ undo_dirichlet_bc_on_pressure_dof()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::undo_dirichlet_bc_on_pressure_dof ( const unsigned j)
inline

◆ undo_velocity_dirichlet_bc_on_node()

template<class BASIC_NAVIER_STOKES_ELEMENT >
void oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::undo_velocity_dirichlet_bc_on_node ( const unsigned j,
const unsigned d 
)
inline

Undo Dirichlet BC on the d-th velocity component (including the singular contribution) of the jth node

581  {
583  }

References j, and oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::Node_is_subject_to_velocity_dirichlet_bcs.

◆ velocity_singular_function()

template<class BASIC_NAVIER_STOKES_ELEMENT >
Vector<double> oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::velocity_singular_function ( const unsigned i,
const Vector< double > &  x 
) const
inlineprivate

Evaluate i-th "raw" velocity singular function at Eulerian position x.

1000  {
1001  return C_equation_elements_pt[i]->velocity_singular_function(x);
1002  }

References oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::C_equation_elements_pt, i, and plotDoE::x.

Referenced by oomph::NavierStokesElementWithSingularity< BASIC_NAVIER_STOKES_ELEMENT >::fill_in_generic_residual_contribution_wrapped_nst().

Member Data Documentation

◆ C_equation_elements_pt

◆ Imposed_value_at_pressure_dof

◆ Imposed_velocity_values_at_node

◆ Node_is_subject_to_velocity_dirichlet_bcs

◆ Pressure_dof_is_subject_to_dirichlet_bc


The documentation for this class was generated from the following file: