oomph::SCoupledElement< ELEMENT > Class Template Reference

#include <SCoupledElement.h>

+ Inheritance diagram for oomph::SCoupledElement< ELEMENT >:

Public Member Functions

 SCoupledElement ()
 Constructor: Call constructor of underlying element. More...
 
 ~SCoupledElement ()
 Destructor (empty) More...
 
Nodeconstruct_node (const unsigned &n)
 
Nodeconstruct_node (const unsigned &n, TimeStepper *const &time_stepper_pt)
 
Nodeconstruct_boundary_node (const unsigned &n)
 
Nodeconstruct_boundary_node (const unsigned &n, TimeStepper *const &time_stepper_pt)
 
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)
 Add the element's contribution to its residual vector and Jacobian matrix (wrapper) More...
 
void get_momentum_and_energy (double &mass, Vector< double > &lin_mo, Vector< double > &ang_mo, double &pot_en, double &kin_en)
 
void set_nodal_coupling_residual (const bool &isCoupled, Vector< Vector< double >> &residual)
 
double get_nodal_coupling_residual (const unsigned n, const unsigned d)
 

Protected Member Functions

void output (std::ostream &outfile, const unsigned &n_plot)
 

Protected Attributes

Vector< Vector< double > > nodal_coupling_residual
 Nodal coupling forces. More...
 

Private Member Functions

void add_external_coupling_forces_to_residuals (Vector< double > &residuals)
 Add the point source contribution to the residual vector. More...
 

Detailed Description

template<class ELEMENT>
class oomph::SCoupledElement< ELEMENT >

Wrapper class for solid elements to be coupled with discrete solid particles on the surfaces

Constructor & Destructor Documentation

◆ SCoupledElement()

template<class ELEMENT >
oomph::SCoupledElement< ELEMENT >::SCoupledElement ( )
inline

Constructor: Call constructor of underlying element.

24  {};

◆ ~SCoupledElement()

template<class ELEMENT >
oomph::SCoupledElement< ELEMENT >::~SCoupledElement ( )
inline

Destructor (empty)

28  {};

Member Function Documentation

◆ add_external_coupling_forces_to_residuals()

template<class ELEMENT >
void oomph::SCoupledElement< ELEMENT >::add_external_coupling_forces_to_residuals ( Vector< double > &  residuals)
inlineprivate

Add the point source contribution to the residual vector.

279  {
280  // No further action if no coupling force
281  if (nodal_coupling_residual.size() == 0) return;
282 
283  // Find out how many nodes there are
284  const unsigned n_node = this->nnode();
285  const unsigned DIM = this->dim();
286 
287  //find out how many positional dofs there are
288  unsigned n_position_type = this->nnodal_position_type();
289 
290  // Set up memory for the shape/test functions
291  //Shape psi(n_node);
292 
293  // Loop over all nodes belonging to the element
294  int local_eqn = 0;
295  // Loop over the nodes of the element
296  for (unsigned l = 0; l < n_node; l++)
297  {
298  // Loop of types of dofs
299  for (unsigned k = 0; k < n_position_type; k++)
300  {
301  // Loop over the force components
302  for (unsigned i = 0; i < DIM; i++)
303  {
304  // Get the local equation
305  local_eqn = this->position_local_eqn(l, k, i);
306  // IF it's not a boundary condition and the interpolated force is nonzero
307  if (local_eqn >= 0)
308  {
309  // add the nodal coupling residual to the global residual vector
310  residuals[local_eqn] += nodal_coupling_residual[l][i];
311  }
312  }
313  }
314  }
315  logger(VERBOSE, "Apply nodal_coupling_residual element %", this);
316  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
Vector< Vector< double > > nodal_coupling_residual
Nodal coupling forces.
Definition: SCoupledElement.h:364
char char char int int * k
Definition: level2_impl.h:374
#define DIM
Definition: linearised_navier_stokes_elements.h:44

References DIM, i, k, logger, oomph::SCoupledElement< ELEMENT >::nodal_coupling_residual, and VERBOSE.

Referenced by oomph::SCoupledElement< ELEMENT >::fill_in_contribution_to_jacobian(), and oomph::SCoupledElement< ELEMENT >::fill_in_contribution_to_residuals().

◆ construct_boundary_node() [1/2]

template<class ELEMENT >
Node* oomph::SCoupledElement< ELEMENT >::construct_boundary_node ( const unsigned n)
inline

Construct the local node n and return a pointer to it. in the case when it is a boundary node; that is it MAY be located on a Mesh boundary Needs to be overridden because a SurfaceCoupledElement uses CoupledSolidNode's

73  {
74  // Construct a solid node and assign it to the local node pointer vector.
75  // The dimension and number of values are taken from internal element data
76  // The number of solid pressure dofs are also taken from internal data
77  // The number of timesteps to be stored comes from the problem!
78  this->node_pt(n) = new BoundaryNode<CoupledSolidNode>(
79  this->lagrangian_dimension(),
80  this->nnodal_lagrangian_type(),
81  this->nodal_dimension(),
82  this->nnodal_position_type(),
83  this->required_nvalue(n));
84  // Now return a pointer to the node, so that the mesh can find it
85  return this->node_pt(n);
86  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11

References n.

◆ construct_boundary_node() [2/2]

template<class ELEMENT >
Node* oomph::SCoupledElement< ELEMENT >::construct_boundary_node ( const unsigned n,
TimeStepper *const &  time_stepper_pt 
)
inline

Construct the local node n and return a pointer to it, in the case when the node MAY be located on a boundary. Additionally, create storage for ‘history’ values as required by timestepper Needs to be overridden because a SurfaceCoupledElement uses CoupledSolidNode's

95  {
96  // Construct a solid node and assign it to the local node pointer vector
97  // The dimension and number of values are taken from internal element data
98  // The number of solid pressure dofs are also taken from internal data
99  this->node_pt(n) = new BoundaryNode<CoupledSolidNode>(
100  time_stepper_pt,
101  this->lagrangian_dimension(),
102  this->nnodal_lagrangian_type(),
103  this->nodal_dimension(),
104  this->nnodal_position_type(),
105  this->required_nvalue(n));
106  // Now return a pointer to the node, so that the mesh can find it
107  return this->node_pt(n);
108  }

References n.

◆ construct_node() [1/2]

template<class ELEMENT >
Node* oomph::SCoupledElement< ELEMENT >::construct_node ( const unsigned n)
inline

Construct the local node n and return a pointer to it. Needs to be overridden because a SurfaceCoupledElement uses CoupledSolidNode's

33  {
34  // Construct a solid node and assign it to the local node pointer vector.
35  // The dimension and number of values are taken from internal element data
36  // The number of solid pressure dofs are also taken from internal data
37  // The number of timesteps to be stored comes from the problem!
38  this->node_pt(n) = new CoupledSolidNode(
39  this->lagrangian_dimension(),
40  this->nnodal_lagrangian_type(),
41  this->nodal_dimension(),
42  this->nnodal_position_type(),
43  this->required_nvalue(n));
44  // Now return a pointer to the node, so that the mesh can find it
45  return this->node_pt(n);
46  }

References n.

◆ construct_node() [2/2]

template<class ELEMENT >
Node* oomph::SCoupledElement< ELEMENT >::construct_node ( const unsigned n,
TimeStepper *const &  time_stepper_pt 
)
inline

Construct the local node n and return a pointer to it. Additionally, create storage for ‘history’ values as required by timestepper Needs to be overridden because a SurfaceCoupledElement uses CoupledSolidNode's

53  {
54  // Construct a solid node and assign it to the local node pointer vector
55  // The dimension and number of values are taken from internal element data
56  // The number of solid pressure dofs are also taken from internal data
57  this->node_pt(n) = new CoupledSolidNode(
58  time_stepper_pt,
59  this->lagrangian_dimension(),
60  this->nnodal_lagrangian_type(),
61  this->nodal_dimension(),
62  this->nnodal_position_type(),
63  this->required_nvalue(n));
64  // Now return a pointer to the node, so that the mesh can find it
65  return this->node_pt(n);
66  }

References n.

◆ fill_in_contribution_to_jacobian()

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

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

125  {
126  //Call the generic routine with the flag set to 1
127  ELEMENT::fill_in_generic_contribution_to_residuals_pvd(residuals, jacobian, 1);
128 
129  // Add point source contribution
131  }
void add_external_coupling_forces_to_residuals(Vector< double > &residuals)
Add the point source contribution to the residual vector.
Definition: SCoupledElement.h:278

References oomph::SCoupledElement< ELEMENT >::add_external_coupling_forces_to_residuals().

◆ fill_in_contribution_to_residuals()

template<class ELEMENT >
void oomph::SCoupledElement< ELEMENT >::fill_in_contribution_to_residuals ( Vector< double > &  residuals)
inline

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

113  {
114  // Call the generic residuals function with flag set to 0 using a dummy matrix argument
115  ELEMENT::fill_in_generic_contribution_to_residuals_pvd(
116  residuals, GeneralisedElement::Dummy_matrix, 0);
117 
118  // Add point source contribution
120  }
static DenseMatrix< double > Dummy_matrix
Definition: elements.h:227

References oomph::SCoupledElement< ELEMENT >::add_external_coupling_forces_to_residuals(), and oomph::GeneralisedElement::Dummy_matrix.

◆ get_momentum_and_energy()

template<class ELEMENT >
void oomph::SCoupledElement< ELEMENT >::get_momentum_and_energy ( double mass,
Vector< double > &  lin_mo,
Vector< double > &  ang_mo,
double pot_en,
double kin_en 
)
inline
135  {
136  const unsigned DIM = this->dim();
137  // Initialise mass
138  mass = 0;
139  // Initialise momentum
140  lin_mo.initialise(0);
141  ang_mo.initialise(0);
142  // Initialise energy
143  pot_en = 0;
144  kin_en = 0;
145 
146  //Set the value of n_intpt
147  unsigned n_intpt = this->integral_pt()->nweight();
148 
149  //Set the Vector to hold local coordinates
150  Vector<double> s(DIM);
151 
152  //Find out how many nodes there are
153  const unsigned n_node = this->nnode();
154 
155  //Find out how many positional dofs there are
156  const unsigned n_position_type = this->nnodal_position_type();
157 
158  //Set up memory for the shape functions
159  Shape psi(n_node, n_position_type);
160  DShape dpsidxi(n_node, n_position_type, DIM);
161 
162  // Timescale ratio (non-dim density)
163  double lambda_sq = this->lambda_sq();
164 
165  //Loop over the integration points
166  for (unsigned ipt = 0; ipt < n_intpt; ipt++)
167  {
168  //Assign values of s
169  for (unsigned i = 0; i < DIM; i++)
170  { s[i] = this->integral_pt()->knot(ipt, i); }
171 
172  //Get the integral weight
173  double w = this->integral_pt()->weight(ipt);
174 
175  //Call the derivatives of the shape functions and get Jacobian
176  double J = this->dshape_lagrangian_at_knot(ipt, psi, dpsidxi);
177 
178  //Storage for Lagrangian coordinates and velocity (initialised to zero)
179  Vector<double> interpolated_xi(DIM, 0.0);
180  Vector<double> veloc(DIM, 0.0);
181 
182  //Calculate lagrangian coordinates
183  for (unsigned l = 0; l < n_node; l++)
184  {
185  //Loop over positional dofs
186  for (unsigned k = 0; k < n_position_type; k++)
187  {
188  //Loop over displacement components (deformed position)
189  for (unsigned i = 0; i < DIM; i++)
190  {
191  //Calculate the Lagrangian coordinates
192  interpolated_xi[i] += this->lagrangian_position_gen(l, k, i) * psi(l, k);
193 
194  //Calculate the velocity components (if unsteady solve)
195  if (this->Unsteady)
196  {
197  veloc[i] += this->dnodal_position_gen_dt(l, k, i) * psi(l, k);
198  }
199  }
200  }
201  }
202 
203  //Get isotropic growth factor gamma
204  double gamma = 1.0;
205  this->get_isotropic_growth(ipt, s, interpolated_xi, gamma);
206 
207  //Premultiply the undeformed volume ratio (from the isotropic
208  // growth), the integral weights, the coupling weights, and the Jacobian
209  double W = gamma * w * J;
210 
212  DenseMatrix<double> strain(DIM, DIM);
213 
214  //Now calculate the stress tensor from the constitutive law
215  this->get_stress(s, sigma);
216 
217  // Add pre-stress
218  for (unsigned i = 0; i < DIM; i++)
219  {
220  for (unsigned j = 0; j < DIM; j++)
221  {
222  sigma(i, j) += this->prestress(i, j, interpolated_xi);
223  }
224  }
225 
226  //get the strain
227  this->get_strain(s, strain);
228 
229  // Initialise
230  double local_pot_en = 0;
231  double veloc_sq = 0;
232 
233  // Compute integrals
234  for (unsigned i = 0; i < DIM; i++)
235  {
236  for (unsigned j = 0; j < DIM; j++)
237  {
238  local_pot_en += sigma(i, j) * strain(i, j);
239  }
240  veloc_sq += veloc[i] * veloc[i];
241  }
242 
243  // Mass
244  mass += lambda_sq * W;
245  // Linear momentum and angular momentum
246  Vector<double> cross_product(DIM, 0);
247  VectorHelpers::cross(interpolated_xi, veloc, cross_product);
248  for (unsigned i = 0; i < DIM; i++)
249  {
250  lin_mo[i] += lambda_sq * veloc[i] * W;
251  ang_mo[i] += lambda_sq * cross_product[i] * W;
252  }
253  // Potential energy
254  pot_en += 0.5 * local_pot_en * W;
255  // Kinetic energy
256  kin_en += lambda_sq * 0.5 * veloc_sq * W;
257  }
258  }
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
RowVector3d w
Definition: Matrix_resize_int.cpp:3
void initialise(const _Tp &__value)
Iterate over all values and set to the desired value.
Definition: oomph-lib/src/generic/Vector.h:167
RealScalar s
Definition: level1_cplx_impl.h:130
int sigma
Definition: calibrate.py:179
Mdouble gamma(Mdouble gamma_in)
This is the gamma function returns the true value for the half integer value.
Definition: ExtendedMath.cc:116
@ W
Definition: quadtree.h:63
void cross(const Vector< double > &A, const Vector< double > &B, Vector< double > &C)
Definition: oomph-lib/src/generic/Vector.h:319
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References oomph::VectorHelpers::cross(), DIM, mathsFunc::gamma(), i, oomph::Vector< _Tp >::initialise(), J, j, k, s, calibrate::sigma, w, and oomph::QuadTreeNames::W.

◆ get_nodal_coupling_residual()

template<class ELEMENT >
double oomph::SCoupledElement< ELEMENT >::get_nodal_coupling_residual ( const unsigned  n,
const unsigned  d 
)
inline
268  {
269  if (nodal_coupling_residual.size()>n && nodal_coupling_residual[n].size()>d)
270  return nodal_coupling_residual[n][d];
271  else
272  return 0;
273  }

References n, and oomph::SCoupledElement< ELEMENT >::nodal_coupling_residual.

◆ output()

template<class ELEMENT >
void oomph::SCoupledElement< ELEMENT >::output ( std::ostream &  outfile,
const unsigned n_plot 
)
inlineprotected
319  {
320  const unsigned DIM = this->dim();
321  Vector<double> x(DIM);
322  Vector<double> dxdt(DIM);
323  Vector<double> s(DIM);
324 
325  // Tecplot header info
326  outfile << this->tecplot_zone_string(n_plot);
327 
328  // Loop over plot points
329  unsigned num_plot_points = this->nplot_points(n_plot);
330  for (unsigned iplot = 0; iplot < num_plot_points; iplot++)
331  {
332  // Get local coordinates of plot point
333  this->get_s_plot(iplot, n_plot, s);
334 
335  // Get Eulerian coordinates
336  this->interpolated_x(s, x);
337  SolidFiniteElement* el_pt = dynamic_cast<SolidFiniteElement*>(this);
338  el_pt->interpolated_dxdt(s, 1, dxdt);
339 
340  // Dummy integration point
341  unsigned ipt = 0;
342 
343  // Output x,y,z
344  for (unsigned i = 0; i < DIM; i++)
345  {
346  outfile << x[i] << " ";
347  }
348 
349  // Output velocity dnodal_position_gen_dt
350  for (unsigned i = 0; i < DIM; i++)
351  {
352  outfile << dxdt[i] << " ";
353  }
354 
355  outfile << std::endl;
356  }
357 
358  // Write tecplot footer (e.g. FE connectivity lists)
359  this->write_tecplot_zone_footer(outfile, n_plot);
360  outfile << std::endl;
361  }
list x
Definition: plotDoE.py:28

References DIM, i, oomph::FiniteElement::interpolated_dxdt(), s, and plotDoE::x.

◆ set_nodal_coupling_residual()

template<class ELEMENT >
void oomph::SCoupledElement< ELEMENT >::set_nodal_coupling_residual ( const bool isCoupled,
Vector< Vector< double >> &  residual 
)
inline
261  {
262  if (isCoupled)
263  { nodal_coupling_residual = residual; }
264  else
265  { nodal_coupling_residual.clear(); }
266  }

References oomph::SCoupledElement< ELEMENT >::nodal_coupling_residual.

Member Data Documentation

◆ nodal_coupling_residual


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