35 template<
unsigned DIM>
48 template<
unsigned DIM>
53 if ((strain.ncol() != DIM) || (strain.nrow() != DIM))
55 std::ostringstream error_message;
56 error_message <<
"Strain matrix is " << strain.ncol() <<
" x "
57 << strain.nrow() <<
", but dimension of the equations is "
60 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
64 unsigned n_position_type = this->nnodal_position_type();
66 if (n_position_type != 1)
68 throw OomphLibError(
"TimeHarmonicLinearElasticity is not yet implemented "
69 "for more than one position type",
70 OOMPH_CURRENT_FUNCTION,
71 OOMPH_EXCEPTION_LOCATION);
77 unsigned n_node = nnode();
80 std::complex<unsigned> u_nodal_index[DIM];
81 for (
unsigned i = 0;
i < DIM;
i++)
83 u_nodal_index[
i] = u_index_time_harmonic_linear_elasticity(
i);
88 DShape dpsidx(n_node, DIM);
91 (void)dshape_eulerian(
s, psi, dpsidx);
95 DIM, DIM, std::complex<double>(0.0, 0.0));
98 for (
unsigned l = 0; l < n_node; l++)
101 for (
unsigned i = 0;
i < DIM;
i++)
104 const std::complex<double> u_value =
105 std::complex<double>(this->nodal_value(l, u_nodal_index[
i].real()),
106 this->nodal_value(l, u_nodal_index[
i].imag()));
109 for (
unsigned j = 0; j < DIM; j++)
111 interpolated_dudx(
i, j) += u_value * dpsidx(l, j);
117 for (
unsigned i = 0;
i < DIM;
i++)
122 for (
int j = (DIM - 1); j >=
static_cast<int>(
i); j--)
125 if (
static_cast<int>(
i) != j)
128 0.5 * (interpolated_dudx(
i, j) + interpolated_dudx(j,
i));
133 strain(
i,
i) = interpolated_dudx(
i,
i);
137 for (
int j = (
i - 1); j >= 0; j--)
139 strain(
i, j) = strain(j,
i);
149 template<
unsigned DIM>
154 if ((stress.ncol() != DIM) || (stress.nrow() != DIM))
156 std::ostringstream error_message;
157 error_message <<
"Stress matrix is " << stress.ncol() <<
" x "
158 << stress.nrow() <<
", but dimension of the equations is "
161 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
167 this->get_strain(
s, strain);
172 for (
unsigned i = 0;
i < DIM;
i++)
174 for (
unsigned j = 0; j < DIM; j++)
177 for (
unsigned k = 0; k < DIM; k++)
179 for (
unsigned l = 0; l < DIM; l++)
181 stress(
i, j) += this->
E(
i, j, k, l) * strain(k, l);
193 template<
unsigned DIM>
199 unsigned n_node = this->nnode();
203 unsigned n_position_type = this->nnodal_position_type();
205 if (n_position_type != 1)
207 throw OomphLibError(
"TimeHarmonicLinearElasticity is not yet implemented "
208 "for more than one position type",
209 OOMPH_CURRENT_FUNCTION,
210 OOMPH_EXCEPTION_LOCATION);
214 if (this->Elasticity_tensor_pt == 0)
217 OOMPH_CURRENT_FUNCTION,
218 OOMPH_EXCEPTION_LOCATION);
223 std::complex<unsigned> u_nodal_index[DIM];
224 for (
unsigned i = 0;
i < DIM;
i++)
226 u_nodal_index[
i] = this->u_index_time_harmonic_linear_elasticity(
i);
231 const double omega_sq_local = this->omega_sq();
235 DShape dpsidx(n_node, DIM);
238 unsigned n_intpt = this->integral_pt()->nweight();
244 int local_eqn = 0, local_unknown = 0;
247 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
250 for (
unsigned i = 0;
i < DIM; ++
i)
252 s[
i] = this->integral_pt()->knot(ipt,
i);
256 double w = this->integral_pt()->weight(ipt);
259 double J = this->dshape_eulerian_at_knot(ipt, psi, dpsidx);
266 DIM, std::complex<double>(0.0, 0.0));
271 DIM, DIM, std::complex<double>(0.0, 0.0));
274 for (
unsigned l = 0; l < n_node; l++)
277 for (
unsigned i = 0;
i < DIM;
i++)
280 interpolated_x[
i] += this->raw_nodal_position(l,
i) * psi(l);
284 const std::complex<double> u_value = std::complex<double>(
285 this->raw_nodal_value(l, u_nodal_index[
i].real()),
286 this->raw_nodal_value(l, u_nodal_index[
i].imag()));
288 interpolated_u[
i] += u_value * psi(l);
291 for (
unsigned j = 0; j < DIM; j++)
293 interpolated_dudx(
i, j) += u_value * dpsidx(l, j);
300 this->body_force(interpolated_x, b);
308 for (
unsigned l = 0; l < n_node; l++)
311 for (
unsigned a = 0; a < DIM; a++)
314 local_eqn = this->nodal_local_eqn(l, u_nodal_index[a].real());
320 residuals[local_eqn] +=
321 (-omega_sq_local * interpolated_u[a].real() - b[a].real()) *
325 for (
unsigned b = 0; b < DIM; b++)
327 for (
unsigned c = 0; c < DIM; c++)
329 for (
unsigned d = 0; d < DIM; d++)
332 residuals[local_eqn] += this->
E(a, b, c, d) *
333 interpolated_dudx(c, d).real() *
343 for (
unsigned l2 = 0; l2 < n_node; l2++)
346 for (
unsigned c = 0; c < DIM; c++)
349 this->nodal_local_eqn(l2, u_nodal_index[c].real());
351 if (local_unknown >= 0)
356 jacobian(local_eqn, local_unknown) -=
357 omega_sq_local * psi(l) * psi(l2) *
W;
361 for (
unsigned b = 0; b < DIM; b++)
363 for (
unsigned d = 0; d < DIM; d++)
366 jacobian(local_eqn, local_unknown) +=
367 this->
E(a, b, c, d) * dpsidx(l2, d) * dpsidx(l, b) *
380 local_eqn = this->nodal_local_eqn(l, u_nodal_index[a].imag());
386 residuals[local_eqn] +=
387 (-omega_sq_local * interpolated_u[a].imag() - b[a].imag()) *
391 for (
unsigned b = 0; b < DIM; b++)
393 for (
unsigned c = 0; c < DIM; c++)
395 for (
unsigned d = 0; d < DIM; d++)
398 residuals[local_eqn] += this->
E(a, b, c, d) *
399 interpolated_dudx(c, d).imag() *
409 for (
unsigned l2 = 0; l2 < n_node; l2++)
412 for (
unsigned c = 0; c < DIM; c++)
415 this->nodal_local_eqn(l2, u_nodal_index[c].imag());
417 if (local_unknown >= 0)
422 jacobian(local_eqn, local_unknown) -=
423 omega_sq_local * psi(l) * psi(l2) *
W;
427 for (
unsigned b = 0; b < DIM; b++)
429 for (
unsigned d = 0; d < DIM; d++)
432 jacobian(local_eqn, local_unknown) +=
433 this->
E(a, b, c, d) * dpsidx(l2, d) * dpsidx(l, b) *
452 template<
unsigned DIM>
454 std::ostream& outfile,
455 const unsigned& nplot,
465 outfile << this->tecplot_zone_string(nplot);
471 unsigned num_plot_points = this->nplot_points(nplot);
472 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
475 this->get_s_plot(iplot, nplot,
s);
478 this->interpolated_x(
s, x);
481 (*exact_soln_pt)(x, exact_soln);
484 for (
unsigned i = 0;
i < DIM;
i++)
486 outfile << x[
i] <<
" ";
488 for (
unsigned i = 0;
i < 2 * DIM;
i++)
490 outfile << exact_soln[
i] <<
" ";
492 outfile << std::endl;
496 this->write_tecplot_zone_footer(outfile, nplot);
503 template<
unsigned DIM>
505 const unsigned& nplot)
513 outfile << this->tecplot_zone_string(nplot);
516 unsigned num_plot_points = this->nplot_points(nplot);
517 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
520 this->get_s_plot(iplot, nplot,
s);
523 this->interpolated_x(
s, x);
524 this->interpolated_u_time_harmonic_linear_elasticity(
s, u);
527 for (
unsigned i = 0;
i < DIM;
i++)
529 outfile << x[
i] <<
" ";
533 for (
unsigned i = 0;
i < DIM;
i++)
535 outfile << u[
i].real() <<
" ";
539 for (
unsigned i = 0;
i < DIM;
i++)
541 outfile << u[
i].imag() <<
" ";
544 outfile << std::endl;
548 this->write_tecplot_zone_footer(outfile, nplot);
555 template<
unsigned DIM>
557 const unsigned& nplot)
563 fprintf(file_pt,
"%s", this->tecplot_zone_string(nplot).c_str());
566 unsigned num_plot_points = this->nplot_points(nplot);
567 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
570 this->get_s_plot(iplot, nplot,
s);
573 for (
unsigned i = 0;
i < DIM;
i++)
575 fprintf(file_pt,
"%g ", this->interpolated_x(
s,
i));
579 for (
unsigned i = 0;
i < DIM;
i++)
584 this->interpolated_u_time_harmonic_linear_elasticity(
s,
i).real());
586 for (
unsigned i = 0;
i < DIM;
i++)
591 this->interpolated_u_time_harmonic_linear_elasticity(
s,
i).imag());
594 fprintf(file_pt,
"\n");
597 this->write_tecplot_zone_footer(file_pt, nplot);
604 template<
unsigned DIM>
620 unsigned n_node = this->nnode();
625 unsigned n_intpt = this->integral_pt()->nweight();
628 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
631 for (
unsigned i = 0;
i < DIM;
i++)
633 s[
i] = this->integral_pt()->knot(ipt,
i);
637 double w = this->integral_pt()->weight(ipt);
640 double J = this->J_eulerian(
s);
646 this->interpolated_u_time_harmonic_linear_elasticity(
s, disp);
649 for (
unsigned ii = 0; ii < DIM; ii++)
651 norm += (disp[ii].real() * disp[ii].real() +
652 disp[ii].imag() * disp[ii].imag()) *
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
//////////////////////////////////////////////////////////////////////////// ////////////////////////...
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as .
An OomphLibError object which should be thrown when an run-time error is encountered....
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
A base class for elements that solve the equations of time-harmonic linear elasticity in Cartesian co...
static double Default_omega_sq_value
Static default value for square of frequency.
void get_strain(const Vector< double > &s, DenseMatrix< std::complex< double >> &strain) const
Return the strain tensor.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
virtual void fill_in_generic_contribution_to_residuals_time_harmonic_linear_elasticity(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)
Private helper function to compute residuals and (if requested via flag) also the Jacobian matrix.
void compute_norm(double &norm)
Compute norm of solution: square of the L2 norm.
void output_fct(std::ostream &outfile, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact solution x,y,[z],u_r,v_r,[w_r],u_i,v_i,[w_i].
void output(std::ostream &outfile)
Output: x,y,[z],u_r,v_r,[w_r],u_i,v_i,[w_i].
void get_stress(const Vector< double > &s, DenseMatrix< std::complex< double >> &sigma) const
Return the Cauchy stress tensor, as calculated from the elasticity tensor at specified local coordina...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...