36 #include "meshes/one_d_mesh.h"
40 using namespace oomph;
61 bool operator()(
const complex<T> &x,
const complex<T> &y)
const
65 if(std::abs(std::abs(x) - std::abs(y)) > 1.0e-10 )
66 {
return std::abs(x) < std::abs(y);}
68 else if(std::abs(x.real() - y.real()) > 1.0e-10)
69 {
return x.real() < y.real();}
72 {
return x.imag() < y.imag();}
88 class ComplexHarmonicEquations :
public virtual FiniteElement
93 ComplexHarmonicEquations() {}
98 virtual inline double u(
const unsigned& n)
const
99 {
return nodal_value(n,0);}
102 virtual inline double w(
const unsigned& n)
const
103 {
return nodal_value(n,1);}
106 void output(ostream &outfile)
109 output(outfile,nplot);
114 void output(ostream &outfile,
const unsigned &nplot)
120 outfile << tecplot_zone_string(nplot);
123 unsigned num_plot_points=nplot_points(nplot);
124 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
127 get_s_plot(iplot,nplot,s);
129 outfile << interpolated_x(s,0) <<
" " << interpolated_u(s)
130 <<
" " << interpolated_w(s) << std::endl;
133 write_tecplot_zone_footer(outfile,nplot);
138 void fill_in_contribution_to_jacobian_and_mass_matrix(
139 Vector<double> &residuals,
140 DenseMatrix<double> &jacobian, DenseMatrix<double> &mass_matrix)
143 unsigned n_node = nnode();
147 DShape dpsidx(n_node,1);
150 unsigned n_intpt = integral_pt()->nweight();
153 int local_eqn=0, local_unknown=0;
156 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
159 double w = integral_pt()->weight(ipt);
162 double J = dshape_eulerian_at_knot(ipt,psi,dpsidx);
169 for(
unsigned l=0;l<n_node;l++)
172 local_eqn = u_local_eqn(l,0);
177 for(
unsigned l2=0;l2<n_node;l2++)
179 local_unknown = u_local_eqn(l2,0);
181 if(local_unknown >= 0)
184 mass_matrix(local_eqn, local_unknown) += psi(l2)*psi(l)*W;
186 local_unknown = u_local_eqn(l2,1);
188 if(local_unknown >= 0)
191 jacobian(local_eqn,local_unknown) += dpsidx(l2,0)*psi(l)*W;
197 local_eqn = u_local_eqn(l,1);
202 for(
unsigned l2=0;l2<n_node;l2++)
204 local_unknown = u_local_eqn(l2,0);
206 if(local_unknown >= 0)
209 jacobian(local_eqn,local_unknown) += dpsidx(l2,0)*psi(l)*W;
211 local_unknown = u_local_eqn(l2,1);
213 if(local_unknown >= 0)
216 mass_matrix(local_eqn, local_unknown) += psi(l2)*psi(l)*W;
218 jacobian(local_eqn,local_unknown) +=
228 inline double interpolated_u(
const Vector<double> &s)
const
230 unsigned n_node = nnode();
239 double interpolated_u = 0.0;
242 for(
unsigned l=0;l<n_node;l++) {interpolated_u+=u(l)*psi[l];}
245 return(interpolated_u);
249 inline double interpolated_w(
const Vector<double> &s)
const
251 unsigned n_node = nnode();
260 double interpolated_u = 0.0;
263 for(
unsigned l=0;l<n_node;l++) {interpolated_u+=w(l)*psi[l];}
266 return(interpolated_u);
274 virtual double dshape_eulerian(
const Vector<double> &s,
276 DShape &dpsidx)
const=0;
280 virtual double dshape_eulerian_at_knot(
const unsigned &ipt,
282 DShape &dpsidx)
const=0;
287 virtual inline int u_local_eqn(
const unsigned &n,
const unsigned &i)
288 {
return nodal_local_eqn(n,i);}
301 template <
unsigned NNODE_1D>
303 public ComplexHarmonicEquations
311 ComplexHarmonicEquations() {}
319 {ComplexHarmonicEquations::output(outfile);}
322 void output(ostream &outfile,
const unsigned &Nplot)
323 {ComplexHarmonicEquations::output(outfile,Nplot);}
331 DShape &dpsidx)
const
332 {
return QElement<1,NNODE_1D>::dshape_eulerian(s,psi,dpsidx);}
339 DShape &dpsidx)
const
340 {
return QElement<1,NNODE_1D>::dshape_eulerian_at_knot(ipt,psi,dpsidx);}
348 template<
class ELEMENT,
class EIGEN_SOLVER>
358 delete this->eigen_solver_pt();}
361 void solve(
const unsigned &label);
365 void doc_solution(
const unsigned& label);
376 template<
class ELEMENT,
class EIGEN_SOLVER>
378 const unsigned& n_element)
381 this->eigen_solver_pt() =
new EIGEN_SOLVER;
387 Problem::mesh_pt() =
new OneDMesh<ELEMENT>(n_element,L);
395 mesh_pt()->boundary_node_pt(0,0)->pin(0);
399 mesh_pt()->boundary_node_pt(1,0)->pin(0);
402 assign_eqn_numbers();
411 template<
class ELEMENT,
class EIGEN_SOLVER>
413 const unsigned& label)
424 sprintf(filename,
"soln%i.dat",label);
425 some_file.open(filename);
426 mesh_pt()->output(some_file,npts);
434 template<
class ELEMENT,
class EIGEN_SOLVER>
436 solve(
const unsigned& label)
439 Vector<complex<double> > eigenvalues;
441 Vector<DoubleVector> eigenvector_real;
442 Vector<DoubleVector> eigenvector_imag;
449 this->solve_eigenproblem(n_eval,eigenvalues,eigenvector_real,eigenvector_imag);
454 Vector<complex<double> > sorted_eigenvalues = eigenvalues;
455 sort(sorted_eigenvalues.begin(),sorted_eigenvalues.end(),
459 complex<double> temp_evalue = sorted_eigenvalues[0];
460 unsigned smallest_index=0;
463 for(
unsigned i=0;i<eigenvalues.size();i++)
467 if(eigenvalues[i] == temp_evalue) {smallest_index=i;
break;}
473 unsigned dim = eigenvector_real[smallest_index].nrow();
476 for(
unsigned i=0;i<dim;i++)
479 length += std::pow(eigenvector_real[smallest_index][i],2.0);
482 length = sqrt(length);
484 if(eigenvector_real[smallest_index][0] < 0) {length *= -1.0;}
486 for(
unsigned i=0;i<dim;i++)
488 eigenvector_real[smallest_index][i] /= length;
493 this->assign_eigenvector_to_dofs(eigenvector_real[smallest_index]);
495 this->doc_solution(label);
498 sprintf(filename,
"eigenvalues%i.dat",label);
501 ofstream evalues(filename);
502 for(
unsigned i=0;i<n_eval;i++)
505 cout << sorted_eigenvalues[i].real() <<
" "
506 << sorted_eigenvalues[i].imag() << std::endl;
508 evalues << sorted_eigenvalues[i].real() <<
" "
509 << sorted_eigenvalues[i].imag() << std::endl;
524 int main(
int argc,
char **argv)
529 MPI_Helpers::init(argc,argv);
533 unsigned n_element=100;
535 clock_t t_start1 = clock();
544 clock_t t_end1 = clock();
546 #ifdef OOMPH_HAS_TRILINOS
547 clock_t t_start2 = clock();
553 clock_t t_end2 = clock();
556 std::cout <<
"LAPACK TIME: " << (double)(t_end1 - t_start1)/CLOCKS_PER_SEC
559 #ifdef OOMPH_HAS_TRILINOS
560 std::cout <<
"ANASAZI TIME: " << (double)(t_end2 - t_start2)/CLOCKS_PER_SEC
565 MPI_Helpers::finalize();
1D ComplexHarmonic problem in unit interval.
~ComplexHarmonicProblem()
Destructor. Clean up the mesh and solver.
void solve(const unsigned &label)
Solve the problem.
void doc_solution(const unsigned &label)
Doc the solution, pass the number of the case considered, so that output files can be distinguished.
ComplexHarmonicProblem(const unsigned &n_element)
Constructor: Pass number of elements and pointer to source function.
Function-type-object to perform comparison of complex data types Needed to sort the complex eigenvalu...
bool operator()(const complex< T > &x, const complex< T > &y) const
Comparison in terms of magnitude of complex number.
QComplexHarmonicElement<NNODE_1D> elements are 1D Elements with NNODE_1D nodal points that are used t...
unsigned required_nvalue(const unsigned &n) const
Required # of ‘values’ (pinned or dofs) at node n. Here there are two (u and w)
double dshape_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidx) const
Shape, test functions & derivs. w.r.t. to global coords. at integration point ipt....
double dshape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx) const
Shape, test functions & derivs. w.r.t. to global coords. Return Jacobian.
void output(ostream &outfile, const unsigned &Nplot)
Output function overloaded from ComplexHarmonicEquations.
void output(ostream &outfile)
Output function overloaded from ComplexHarmonicEquations.
QComplexHarmonicElement()
Constructor: Call constructors for QElement and Poisson equations.
int main(int argc, char **argv)
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
Namespace for the shift applied to the eigenproblem.