34 #include "../generic/complex_matrices.h" 40 template <
unsigned DIM,
class PML_ELEMENT>
41 double PMLTimeHarmonicLinearElasticityEquationsBase<DIM,PML_ELEMENT>::
42 Default_omega_sq_value=1.0;
52 template<
unsigned DIM,
class PML_ELEMENT>
58 if ((strain.ncol()!=DIM)||(strain.nrow()!=DIM))
60 std::ostringstream error_message;
61 error_message <<
"Strain matrix is " << strain.ncol() <<
" x " 62 << strain.nrow() <<
", but dimension of the equations is " 65 OOMPH_CURRENT_FUNCTION,
66 OOMPH_EXCEPTION_LOCATION);
70 unsigned n_position_type = this->nnodal_position_type();
72 if(n_position_type != 1)
74 std::ostringstream error_message;
75 error_message <<
"PMLTimeHarmonicLinearElasticity is not yet " 76 <<
"implemented for more than one position type" 79 OOMPH_CURRENT_FUNCTION,
80 OOMPH_EXCEPTION_LOCATION);
86 unsigned n_node = nnode();
89 std::complex<unsigned> u_nodal_index[DIM];
90 for(
unsigned i=0;
i<DIM;
i++)
92 u_nodal_index[
i] = u_index_time_harmonic_linear_elasticity(
i);
100 (void) dshape_eulerian(s,psi,dpsidx);
104 interpolated_dudx(DIM,DIM,std::complex<double>(0.0,0.0));
107 for(
unsigned l=0;l<n_node;l++)
110 for(
unsigned i=0;
i<DIM;
i++)
113 const std::complex<double> u_value=
114 std::complex<double>(this->nodal_value(l,u_nodal_index[
i].real()),
115 this->nodal_value(l,u_nodal_index[
i].imag()));
118 for(
unsigned j=0;j<DIM;j++)
120 interpolated_dudx(
i,j) += u_value*dpsidx(l,j);
126 for(
unsigned i=0;
i<DIM;
i++)
131 for(
int j=(DIM-1);j>=
static_cast<int>(
i);j--)
134 if(static_cast<int>(
i)!=j)
137 0.5*(interpolated_dudx(
i,j) + interpolated_dudx(j,
i));
142 strain(
i,
i) = interpolated_dudx(
i,
i);
146 for(
int j=(
i-1);j>=0;j--)
148 strain(
i,j) = strain(j,
i);
161 template<
unsigned DIM,
class PML_ELEMENT>
167 if ((stress.ncol()!=DIM)||(stress.nrow()!=DIM))
169 std::ostringstream error_message;
170 error_message <<
"Stress matrix is " << stress.ncol() <<
" x " 171 << stress.nrow() <<
", but dimension of the equations is " 174 OOMPH_CURRENT_FUNCTION,
175 OOMPH_EXCEPTION_LOCATION);
181 this->get_strain(s,strain);
186 for(
unsigned i=0;
i<DIM;
i++)
188 for(
unsigned j=0;j<DIM;j++)
191 for (
unsigned k=0;k<DIM;k++)
193 for (
unsigned l=0;l<DIM;l++)
195 stress(
i,j)+=this->
E(
i,j,k,l)*strain(k,l);
207 template <
unsigned DIM,
class PML_ELEMENT>
213 unsigned n_node = this->nnode();
217 unsigned n_position_type = this->nnodal_position_type();
219 if(n_position_type != 1)
221 std::ostringstream error_message;
222 error_message <<
"PMLTimeHarmonicLinearElasticity is not yet " 223 <<
"implemented for more than one position type" 226 OOMPH_CURRENT_FUNCTION,
227 OOMPH_EXCEPTION_LOCATION);
231 if(this->Elasticity_tensor_pt==0)
234 "No elasticity tensor set.",
235 OOMPH_CURRENT_FUNCTION,
236 OOMPH_EXCEPTION_LOCATION);
241 std::complex<unsigned> u_nodal_index[DIM];
242 for(
unsigned i=0;
i<DIM;
i++)
244 u_nodal_index[
i] = this->u_index_time_harmonic_linear_elasticity(
i);
249 const double omega_sq_local = this->omega_sq();
253 DShape dpsidx(n_node,DIM);
256 unsigned n_intpt = this->integral_pt()->nweight();
262 int local_eqn_real=0, local_unknown_real=0;
263 int local_eqn_imag=0, local_unknown_imag=0;
266 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
269 for(
unsigned i=0;
i<DIM;++
i)
271 s[
i] = this->integral_pt()->knot(ipt,
i);
275 double w = this->integral_pt()->weight(ipt);
278 double J = this->dshape_eulerian_at_knot(ipt,psi,dpsidx);
285 interpolated_u(DIM,std::complex<double>(0.0,0.0));
290 interpolated_dudx(DIM,DIM,std::complex<double>(0.0,0.0));
293 for(
unsigned l=0;l<n_node;l++)
296 for(
unsigned i=0;
i<DIM;
i++)
299 interpolated_x[
i] += this->raw_nodal_position(l,
i)*psi(l);
303 const std::complex<double> u_value
304 = std::complex<double>(
305 this->raw_nodal_value(l,u_nodal_index[
i].real()),
306 this->raw_nodal_value(l,u_nodal_index[
i].imag()));
308 interpolated_u[
i]+=u_value*psi(l);
311 for(
unsigned j=0;j<DIM;j++)
313 interpolated_dudx(
i,j) += u_value*dpsidx(l,j);
320 this->body_force(interpolated_x,body_force_vec);
334 this->pml_transformation_jacobian(ipt, s, interpolated_x,
337 std::complex<double> pml_jacobian_det;
339 this->compute_jacobian_inverse_and_det(pml_jacobian, pml_jacobian_inverse,
344 for(
unsigned l=0;l<n_node;l++)
347 for(
unsigned a=0;a<DIM;a++)
350 local_eqn_real = this->nodal_local_eqn(l,u_nodal_index[a].real());
351 local_eqn_imag = this->nodal_local_eqn(l,u_nodal_index[a].imag());
358 std::complex<double> mass_jacobian_contribution =
359 -omega_sq_local*pml_jacobian_det;
360 std::complex<double> mass_residual_contribution =
361 (-omega_sq_local*interpolated_u[a]-body_force_vec[a])*pml_jacobian_det;
364 std::complex<double> stress_jacobian_contributions[DIM][DIM][DIM];
365 std::complex<double> stress_residual_contributions[DIM];
366 for(
unsigned b=0;b<DIM;b++)
368 stress_residual_contributions[b] = 0.0;
369 for(
unsigned c=0;c<DIM;c++)
371 for(
unsigned d=0;d<DIM;d++)
373 stress_jacobian_contributions[b][c][d] =
374 this->
E(a,b,c,d)*pml_jacobian_det
375 *pml_jacobian_inverse(b,b)
376 *pml_jacobian_inverse(d,d);
378 stress_residual_contributions[b] +=
379 stress_jacobian_contributions[b][c][d]*interpolated_dudx(c,d);
387 if(local_eqn_real >= 0)
390 residuals[local_eqn_real] += mass_residual_contribution.real()
394 for(
unsigned b=0;b<DIM;b++)
397 residuals[local_eqn_real] += stress_residual_contributions[b].real()
405 for(
unsigned l2=0;l2<n_node;l2++)
408 for(
unsigned c=0;c<DIM;c++)
411 this->nodal_local_eqn(l2,u_nodal_index[c].real());
413 this->nodal_local_eqn(l2,u_nodal_index[c].imag());
415 if(local_unknown_real >= 0)
420 jacobian(local_eqn_real,local_unknown_real) +=
421 mass_jacobian_contribution.real()*psi(l)*psi(l2)*
W;
425 for(
unsigned b=0;b<DIM;b++)
427 for(
unsigned d=0;d<DIM;d++)
430 jacobian(local_eqn_real,local_unknown_real) +=
431 stress_jacobian_contributions[b][c][d].real()
432 *dpsidx(l2,d)*dpsidx(l,b)*
W;
437 if(local_unknown_imag >= 0)
442 jacobian(local_eqn_real,local_unknown_imag) -=
443 mass_jacobian_contribution.imag()*psi(l)*psi(l2)*
W;
447 for(
unsigned b=0;b<DIM;b++)
449 for(
unsigned d=0;d<DIM;d++)
452 jacobian(local_eqn_real,local_unknown_imag) -=
453 stress_jacobian_contributions[b][c][d].imag()
454 *dpsidx(l2,d)*dpsidx(l,b)*
W;
467 if(local_eqn_imag >= 0)
470 residuals[local_eqn_imag] += mass_residual_contribution.imag()
474 for(
unsigned b=0;b<DIM;b++)
477 residuals[local_eqn_imag] += stress_residual_contributions[b].imag()
485 for(
unsigned l2=0;l2<n_node;l2++)
488 for(
unsigned c=0;c<DIM;c++)
491 this->nodal_local_eqn(l2,u_nodal_index[c].imag());
493 this->nodal_local_eqn(l2,u_nodal_index[c].real());
495 if(local_unknown_imag >= 0)
500 jacobian(local_eqn_imag,local_unknown_imag) +=
501 mass_jacobian_contribution.real()*psi(l)*psi(l2)*
W;
505 for(
unsigned b=0;b<DIM;b++)
507 for(
unsigned d=0;d<DIM;d++)
510 jacobian(local_eqn_imag,local_unknown_imag) +=
511 stress_jacobian_contributions[b][c][d].real()
512 *dpsidx(l2,d)*dpsidx(l,b)*
W;
517 if(local_unknown_real >= 0)
522 jacobian(local_eqn_imag,local_unknown_real) +=
523 mass_jacobian_contribution.imag()*psi(l)*psi(l2)*
W;
527 for(
unsigned b=0;b<DIM;b++)
529 for(
unsigned d=0;d<DIM;d++)
532 jacobian(local_eqn_imag,local_unknown_real) +=
533 stress_jacobian_contributions[b][c][d].imag()
534 *dpsidx(l2,d)*dpsidx(l,b)*
W;
554 template <
unsigned DIM,
class PML_ELEMENT>
556 std::ostream &outfile,
557 const unsigned &nplot,
567 outfile << this->tecplot_zone_string(nplot);
573 unsigned num_plot_points=this->nplot_points(nplot);
574 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
578 this->get_s_plot(iplot,nplot,s);
581 this->interpolated_x(s,x);
584 (*exact_soln_pt)(x,exact_soln);
587 for(
unsigned i=0;
i<DIM;
i++)
589 outfile << x[
i] <<
" ";
591 for(
unsigned i=0;
i<2*DIM;
i++)
593 outfile << exact_soln[
i] <<
" ";
595 outfile << std::endl;
599 this->write_tecplot_zone_footer(outfile,nplot);
608 template <
unsigned DIM,
class PML_ELEMENT>
610 std::ostream &outfile,
const unsigned &nplot)
618 outfile << this->tecplot_zone_string(nplot);
621 unsigned num_plot_points=this->nplot_points(nplot);
622 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
626 this->get_s_plot(iplot,nplot,s);
629 this->interpolated_x(s,x);
630 this->interpolated_u_time_harmonic_linear_elasticity(s,u);
633 for(
unsigned i=0;
i<DIM;
i++)
634 {outfile << x[
i] <<
" ";}
637 for(
unsigned i=0;
i<DIM;
i++)
638 {outfile << u[
i].real() <<
" ";}
641 for(
unsigned i=0;
i<DIM;
i++)
642 {outfile << u[
i].imag() <<
" ";}
644 outfile << std::endl;
648 this->write_tecplot_zone_footer(outfile,nplot);
665 template <
unsigned DIM,
class PML_ELEMENT>
667 std::ostream &outfile,
670 const unsigned &nplot)
682 outfile << this->tecplot_zone_string(nplot);
685 unsigned num_plot_points=this->nplot_points(nplot);
686 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
689 this->get_s_plot(iplot,nplot,s);
692 this->interpolated_x(s,x);
693 this->interpolated_u_time_harmonic_linear_elasticity(s,u);
696 (*incoming_wave_fct_pt)(x,incoming_soln);
699 for(
unsigned i=0;
i<DIM;
i++)
700 {outfile << x[
i] <<
" ";}
703 for(
unsigned i=0;
i<DIM;
i++)
705 outfile << (u[
i].real()+incoming_soln[2*
i])*cos(phi)+
706 (u[
i].imag()+incoming_soln[2*
i+1])*sin(phi) <<
" ";
709 outfile << std::endl;
714 this->write_tecplot_zone_footer(outfile,nplot);
729 template <
unsigned DIM,
class PML_ELEMENT>
733 const unsigned &nplot)
742 outfile << this->tecplot_zone_string(nplot);
745 unsigned num_plot_points=this->nplot_points(nplot);
746 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
750 this->get_s_plot(iplot,nplot,s);
753 this->interpolated_x(s,x);
754 this->interpolated_u_time_harmonic_linear_elasticity(s,u);
757 for(
unsigned i=0;
i<DIM;
i++)
758 {outfile << x[
i] <<
" ";}
761 for(
unsigned i=0;
i<DIM;
i++)
763 outfile << u[
i].real()*cos(phi)+ u[
i].imag()*sin(phi) <<
" ";
766 outfile << std::endl;
771 this->write_tecplot_zone_footer(outfile,nplot);
786 template <
unsigned DIM,
class PML_ELEMENT>
790 const unsigned &nplot)
799 outfile << this->tecplot_zone_string(nplot);
802 unsigned num_plot_points=this->nplot_points(nplot);
803 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
807 this->get_s_plot(iplot,nplot,s);
810 this->interpolated_x(s,x);
811 this->interpolated_u_time_harmonic_linear_elasticity(s,u);
814 for(
unsigned i=0;
i<DIM;
i++)
815 {outfile << x[
i] <<
" ";}
818 for(
unsigned i=0;
i<DIM;
i++)
820 outfile << u[
i].imag()*cos(phi)- u[
i].real()*sin(phi) <<
" ";
823 outfile << std::endl;
828 this->write_tecplot_zone_footer(outfile,nplot);
836 template <
unsigned DIM,
class PML_ELEMENT>
838 FILE* file_pt,
const unsigned &nplot)
844 fprintf(file_pt,
"%s",this->tecplot_zone_string(nplot).c_str());
847 unsigned num_plot_points=this->nplot_points(nplot);
848 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
851 this->get_s_plot(iplot,nplot,s);
854 for(
unsigned i=0;
i<DIM;
i++)
856 fprintf(file_pt,
"%g ",this->interpolated_x(s,
i));
860 for(
unsigned i=0;
i<DIM;
i++)
862 fprintf(file_pt,
"%g ",
863 this->interpolated_u_time_harmonic_linear_elasticity(s,
i).real());
865 for(
unsigned i=0;
i<DIM;
i++)
867 fprintf(file_pt,
"%g ",
868 this->interpolated_u_time_harmonic_linear_elasticity(s,
i).imag());
871 fprintf(file_pt,
"\n");
874 this->write_tecplot_zone_footer(file_pt,nplot);
882 template <
unsigned DIM,
class PML_ELEMENT>
900 unsigned n_node = this->nnode();
905 unsigned n_intpt = this->integral_pt()->nweight();
908 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
912 for(
unsigned i=0;
i<DIM;
i++)
914 s[
i] = this->integral_pt()->knot(ipt,
i);
918 double w = this->integral_pt()->weight(ipt);
921 double J = this->J_eulerian(s);
927 this->interpolated_u_time_harmonic_linear_elasticity(s,disp);
930 for (
unsigned ii=0;ii<DIM;ii++)
932 norm+=(disp[ii].real()*disp[ii].real()+disp[ii].imag()*disp[ii].imag())*W;
943 template <
unsigned DIM,
class PML_ELEMENT>
945 std::ostream &outfile,
947 double& error,
double& norm)
964 unsigned n_node = this->nnode();
969 unsigned n_intpt = this->integral_pt()->nweight();
975 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
979 for(
unsigned i=0;
i<DIM;
i++)
981 s[
i] = this->integral_pt()->knot(ipt,
i);
985 double w = this->integral_pt()->weight(ipt);
988 double J = this->J_eulerian(s);
994 this->interpolated_x(s,x);
997 (*exact_soln_pt)(x,exact_soln);
1000 this->interpolated_u_time_harmonic_linear_elasticity(s,disp);
1003 for (
unsigned ii=0;ii<DIM;ii++)
1006 error+=((exact_soln[ii]-disp[ii].real())
1007 *(exact_soln[ii]-disp[ii].real())+
1008 (exact_soln[ii+DIM]-disp[ii].imag())
1009 *(exact_soln[ii+DIM]-disp[ii].imag()))*
W;
1010 norm+=(disp[ii].real()*disp[ii].real()+disp[ii].imag()*disp[ii].imag())*W;
1015 template<
unsigned DIM,
class PML_ELEMENT>
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 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...
void compute_norm(double &norm)
Compute norm of solution: square of the L2 norm.
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
void output_real(std::ostream &outfile, const double &phi, const unsigned &n_plot)
Output function for real part of full time-dependent solution u = Re( (u_r +i u_i) exp(-i omega t)) a...
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 output(std::ostream &outfile)
Output: x,y,[z],u_r,v_r,[w_r],u_i,v_i,[w_i].
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as ...
void get_strain(const Vector< double > &s, DenseMatrix< std::complex< double > > &strain) const
Return the strain tensor.
void output_total_real(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt incoming_wave_fct_pt, const double &phi, const unsigned &nplot)
void output_imag(std::ostream &outfile, const double &phi, const unsigned &n_plot)
Output function for imaginary part of full time-dependent solution u = Im( (u_r +i u_i) exp(-i omega ...
Class for dense matrices, storing all the values of the matrix as a pointer to a pointer with assorte...