31 #ifndef OOMPH_NAVIER_STOKES_FLUX_CONTROL_ELEMENTS 32 #define OOMPH_NAVIER_STOKES_FLUX_CONTROL_ELEMENTS 36 #include <oomph-lib-config.h> 40 #include "../generic/nodes.h" 41 #include "../navier_stokes/navier_stokes_surface_power_elements.h" 120 double* prescribed_flux_value_pt) :
121 Flux_control_mesh_pt(flux_control_mesh_pt),
122 Prescribed_flux_value_pt(prescribed_flux_value_pt)
125 Pressure_data_pt =
new Data(1);
136 unsigned n_el = Flux_control_mesh_pt->nelement();
137 for (
unsigned e=0;
e<n_el;
e++)
151 Dof_number_for_unknown = UINT_MAX;
189 fill_in_generic_residual_contribution_flux_control(residuals);
200 fill_in_generic_residual_contribution_flux_control(residuals);
211 if (Dof_number_for_unknown==UINT_MAX)
213 std::ostringstream error_message;
214 error_message <<
"Dof_number_for_unknown hasn't been set yet!\n" 215 <<
"Please do so using the dof_number_for_unknown()\n" 216 <<
"access function\n";
218 OOMPH_CURRENT_FUNCTION,
219 OOMPH_EXCEPTION_LOCATION);
222 return Dof_number_for_unknown+1;
251 std::list<std::pair<unsigned long, unsigned> >& dof_lookup_list)
const 254 if (Dof_number_for_unknown==UINT_MAX)
256 std::ostringstream error_message;
257 error_message <<
"Dof_number_for_unknown hasn't been set yet!\n" 258 <<
"Please do so using the dof_number_for_unknown()\n" 259 <<
"access function\n";
261 OOMPH_CURRENT_FUNCTION,
262 OOMPH_EXCEPTION_LOCATION);
267 std::pair<unsigned,unsigned> dof_lookup;
270 dof_lookup.second = Dof_number_for_unknown;
273 dof_lookup_list.push_front(dof_lookup);
285 double volume_flux = 0.0;
288 unsigned n_el = Flux_control_mesh_pt->nelement();
289 for (
unsigned e=0;
e<n_el;
e++)
300 if (flux_control_el_pt==0)
303 "Element must be used with a mesh of NavierStokesFluxControlElements",
304 OOMPH_CURRENT_FUNCTION,
305 OOMPH_EXCEPTION_LOCATION);
313 residuals[0] += *Prescribed_flux_value_pt - volume_flux;
359 template <
class ELEMENT>
368 const int &face_index,
370 called_from_refineable_constructor=
false) :
376 if (!called_from_refineable_constructor)
378 ELEMENT* elem_pt =
new ELEMENT;
380 if(elem_pt->dim()==3)
383 if(dynamic_cast<RefineableElement*>(elem_pt))
386 std::ostringstream error_message;
388 <<
"This element does not work properly with refineable bulk \n" 389 <<
"elements in 3D. Please use the refineable version\n" 393 OOMPH_CURRENT_FUNCTION,
394 OOMPH_EXCEPTION_LOCATION);
403 Dim = this->node_pt(0)->ndim();
413 fill_in_generic_residual_contribution_fluid_traction(
425 fill_in_generic_residual_contribution_fluid_traction(residuals,jacobian,1);
443 {
return this->nodal_local_eqn(n,i);}
452 unsigned n_node = this->nnode();
454 this->shape_at_knot(ipt,psi);
456 for(
unsigned i=0;
i<n_node;
i++) {test[
i] = psi[
i];}
458 return this->J_eulerian_at_knot(ipt);
472 unsigned n_node = this->nnode();
475 Shape psif(n_node), testf(n_node);
478 unsigned n_intpt = this->integral_pt()->nweight();
487 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
490 double w = this->integral_pt()->weight(ipt);
494 double J = shape_and_test_at_knot(ipt,psif,testf);
501 this->outer_unit_normal(ipt, unit_normal);
505 for (
unsigned i=0;
i<
Dim;
i++)
507 traction[
i] = -pressure*unit_normal[
i];
511 for(
unsigned l=0;l<n_node;l++)
514 for(
unsigned i=0;
i<
Dim;
i++)
516 local_eqn = u_local_eqn(l,
i);
522 residuals[local_eqn] += traction[
i]*testf[l]*
W;
536 if(local_unknown >= 0)
539 double jac_contribution = -unit_normal[
i]*testf[l]*
W;
540 jacobian(local_eqn,local_unknown) += jac_contribution;
543 jacobian(local_unknown,local_eqn) += jac_contribution;
579 template <
class ELEMENT>
588 const int &face_index) :
602 return dynamic_cast<ELEMENT*
>(this->bulk_element_pt())->
603 ncont_interpolated_values();
610 refineable_fill_in_generic_residual_contribution_fluid_traction(
622 refineable_fill_in_generic_residual_contribution_fluid_traction(residuals,
639 unsigned u_nodal_index[this->
Dim];
640 for(
unsigned i=0;
i<this->
Dim;
i++)
642 u_nodal_index[
i] =
dynamic_cast<ELEMENT*
>(
643 this->bulk_element_pt())->u_index_nst(
i);
650 unsigned n_node = this->nnode();
653 Shape psif(n_node), testf(n_node);
656 unsigned n_intpt = this->integral_pt()->nweight();
665 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
668 double w = this->integral_pt()->weight(ipt);
672 double J = this->shape_and_test_at_knot(ipt,psif,testf);
679 this->outer_unit_normal(ipt, unit_normal);
683 for (
unsigned i=0;
i<this->
Dim;
i++)
685 traction[
i] = -pressure*unit_normal[
i];
691 unsigned n_master=1;
double hang_weight=1.0;
695 for(
unsigned l=0;l<n_node;l++)
698 bool is_node_hanging = this->node_pt(l)->is_hanging();
703 hang_info_pt = this->node_pt(l)->hanging_pt();
706 n_master = hang_info_pt->
nmaster();
715 for(
unsigned m=0;m<n_master;m++)
718 for(
unsigned i=0;
i<this->
Dim;
i++)
734 local_eqn = this->nodal_local_eqn(l,u_nodal_index[
i]);
745 residuals[local_eqn] += traction[
i]*testf[l]*W*hang_weight;
759 if(local_unknown >= 0)
762 double jac_contribution=-unit_normal[
i]*testf[l]*W*
764 jacobian(local_eqn,local_unknown) += jac_contribution;
767 jacobian(local_unknown,local_eqn) += jac_contribution;
unsigned Dim
The highest dimension of the problem.
A Generalised Element class.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
This function returns the residuals and the Jacobian including the Jacobian contribution from the flu...
double value(const unsigned &i) const
Return i-th stored value. This function is not virtual so that it can be inlined. This means that if ...
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector: i.e. the flux constraint.
TemplateFreeNavierStokesFluxControlElementBase()
Empty constructor.
Mesh * Flux_control_mesh_pt
Mesh of elements which impose the pressure which controls the net flux.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
unsigned Dof_number_for_unknown
The id number of the "DOF type" to which the degree of freedom in this element is added to...
void fill_in_contribution_to_residuals(Vector< double > &residuals)
This function returns just the residuals.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
This function returns the residuals and the Jacobian including the Jacobian contribution from the flu...
NetFluxControlElement(const NetFluxControlElement &dummy)
Broken copy constructor.
double get_volume_flux()
Function to get the integral of the volume flux.
A general Finite Element class.
~NavierStokesFluxControlElement()
Destructor should not delete anything.
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
unsigned nmaster() const
Return the number of master nodes.
Data * pressure_data_pt() const
Function to return a pointer to the Data object whose single value is the pressure applied by the Nav...
void fill_in_generic_residual_contribution_fluid_traction(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)
This function returns the residuals for the traction function flag=1(or 0): do (or don't) compute the...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
This function returns the residuals, but adds nothing to the Jacobian as this element's Jacobian cont...
unsigned add_external_data(Data *const &data_pt, const bool &fd=true)
unsigned Dim
Dimension of zeta tuples (set by get_dim_helper) – needed because we store the scalar coordinates in...
unsigned ncont_interpolated_values() const
Number of continuously interpolated values are the same as those in the bulk element.
double get_volume_flux()
Get integral of volume flux.
unsigned & dof_number_for_unknown()
Function to set / get the nodal value of the "DOF type" to which the degree of freedom in this elemen...
virtual double get_volume_flux()=0
Pure virtual function to calculate integral of the volume flux.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
This function returns just the residuals.
void fill_in_generic_residual_contribution_flux_control(Vector< double > &residuals)
This function returns the residuals for the flux control master element.
virtual int u_local_eqn(const unsigned &n, const unsigned &i)
Access function that returns the local equation numbers for velocity components. u_local_eqn(n,i) = local equation number or < 0 if pinned. The default is to asssume that n is the local node number and the i-th velocity component is the i-th unknown stored at the node.
NavierStokesFluxControlElement(FiniteElement *const &element_pt, const int &face_index, const bool &called_from_refineable_constructor=false)
Constructor, which takes a "bulk" element and face index.
void refineable_fill_in_generic_residual_contribution_fluid_traction(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)
This function returns the residuals for the traction function flag=1(or 0): do (or don't) compute the...
unsigned & pressure_data_id()
Access function gives id of external Data object whose single value is the pressure applied by the el...
unsigned long eqn_number(const unsigned &ieqn_local) const
Return the global equation number corresponding to the ieqn_local-th local equation number...
NetFluxControlElement(Mesh *flux_control_mesh_pt, double *prescribed_flux_value_pt)
Constructor takes a mesh of TemplateFreeNavierStokesFluxControlElementBase elements that impose the p...
A class that represents a collection of data; each Data object may contain many different individual ...
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
RefineableNavierStokesFluxControlElement(FiniteElement *const &element_pt, const int &face_index)
Constructor, which takes a "bulk" element and the face index.
Class that contains data for hanging nodes.
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned > > &dof_lookup_list) const
Create a list of pairs for all unknowns in this element, so that the first entry in each pair contain...
~NetFluxControlElement()
Empty Destructor - Data gets deleted automatically.
Data *& external_data_pt(const unsigned &i)
Return a pointer to i-th external data object.
unsigned Pressure_data_id
Id of external Data object whose single value is the pressure applied by the elements.
unsigned Dim
spatial dim of NS system
unsigned add_internal_data(Data *const &data_pt, const bool &fd=true)
Add a (pointer to an) internal data object to the element and return the index required to obtain it ...
void add_pressure_data(Data *pressure_data_pt)
Function adds to the external data the Data object whose single value is the pressure applied by the ...
~RefineableNavierStokesFluxControlElement()
Destructor should not delete anything.
virtual ~TemplateFreeNavierStokesFluxControlElementBase()
Empty virtual destructor.
unsigned ndof_types() const
The number of "DOF types" that degrees of freedom in this element are sub-divided into - it's set to ...
double shape_and_test_at_knot(const unsigned &ipt, Shape &psi, Shape &test) const
Function to compute the shape and test functions and to return the Jacobian of mapping.
int external_local_eqn(const unsigned &i, const unsigned &j)
Return the local equation number corresponding to the j-th value stored at the i-th external data...
unsigned dim() const
Broken assignment operator.
static DenseMatrix< double > Dummy_matrix
Empty dense matrix used as a dummy argument to combined residual and jacobian functions in the case w...
double * Prescribed_flux_value_pt
Pointer to the value that stores the prescribed flux.
Data * Pressure_data_pt
Data object whose single value is the pressure applied by the elements in the Flux_control_mesh_pt.