40 #include "meshes/one_d_mesh.h" 44 using namespace oomph;
65 bool operator()(
const complex<T> &x,
const complex<T> &y)
const 69 if(std::abs(std::abs(x) - std::abs(y)) > 1.0e-10 )
70 {
return std::abs(x) < std::abs(y);}
72 else if(std::abs(x.real() - y.real()) > 1.0e-10)
73 {
return x.real() < y.real();}
76 {
return x.imag() < y.imag();}
102 virtual inline double u(
const unsigned& n)
const 103 {
return nodal_value(n,0);}
106 virtual inline double w(
const unsigned& n)
const 107 {
return nodal_value(n,1);}
113 output(outfile,nplot);
118 void output(ostream &outfile,
const unsigned &nplot)
124 outfile << tecplot_zone_string(nplot);
127 unsigned num_plot_points=nplot_points(nplot);
128 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
131 get_s_plot(iplot,nplot,s);
133 outfile << interpolated_x(s,0) <<
" " << interpolated_u(s)
134 <<
" " << interpolated_w(s) << std::endl;
137 write_tecplot_zone_footer(outfile,nplot);
143 Vector<double> &residuals,
144 DenseMatrix<double> &jacobian, DenseMatrix<double> &mass_matrix)
147 unsigned n_node = nnode();
151 DShape dpsidx(n_node,1);
154 unsigned n_intpt = integral_pt()->nweight();
157 int local_eqn=0, local_unknown=0;
160 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
163 double w = integral_pt()->weight(ipt);
166 double J = dshape_eulerian_at_knot(ipt,psi,dpsidx);
173 for(
unsigned l=0;l<n_node;l++)
176 local_eqn = u_local_eqn(l,0);
181 for(
unsigned l2=0;l2<n_node;l2++)
183 local_unknown = u_local_eqn(l2,0);
185 if(local_unknown >= 0)
188 mass_matrix(local_eqn, local_unknown) += psi(l2)*psi(l)*W;
190 local_unknown = u_local_eqn(l2,1);
192 if(local_unknown >= 0)
195 jacobian(local_eqn,local_unknown) += dpsidx(l2,0)*psi(l)*W;
201 local_eqn = u_local_eqn(l,1);
206 for(
unsigned l2=0;l2<n_node;l2++)
208 local_unknown = u_local_eqn(l2,0);
210 if(local_unknown >= 0)
213 jacobian(local_eqn,local_unknown) += dpsidx(l2,0)*psi(l)*W;
215 local_unknown = u_local_eqn(l2,1);
217 if(local_unknown >= 0)
220 mass_matrix(local_eqn, local_unknown) += psi(l2)*psi(l)*W;
222 jacobian(local_eqn,local_unknown) +=
234 unsigned n_node = nnode();
243 double interpolated_u = 0.0;
246 for(
unsigned l=0;l<n_node;l++) {interpolated_u+=u(l)*psi[l];}
249 return(interpolated_u);
255 unsigned n_node = nnode();
264 double interpolated_u = 0.0;
267 for(
unsigned l=0;l<n_node;l++) {interpolated_u+=w(l)*psi[l];}
270 return(interpolated_u);
278 virtual double dshape_eulerian(
const Vector<double> &s,
280 DShape &dpsidx)
const=0;
284 virtual double dshape_eulerian_at_knot(
const unsigned &ipt,
286 DShape &dpsidx)
const=0;
291 virtual inline int u_local_eqn(
const unsigned &n,
const unsigned &i)
292 {
return nodal_local_eqn(n,i);}
305 template <
unsigned NNODE_1D>
326 void output(ostream &outfile,
const unsigned &Nplot)
335 DShape &dpsidx)
const 336 {
return QElement<1,NNODE_1D>::dshape_eulerian(s,psi,dpsidx);}
343 DShape &dpsidx)
const 344 {
return QElement<1,NNODE_1D>::dshape_eulerian_at_knot(ipt,psi,dpsidx);}
352 template<
class ELEMENT,
class EIGEN_SOLVER>
362 delete this->eigen_solver_pt();}
365 void solve(
const unsigned &label);
369 void doc_solution(
const unsigned& label);
380 template<
class ELEMENT,
class EIGEN_SOLVER>
382 const unsigned& n_element)
385 this->eigen_solver_pt() =
new EIGEN_SOLVER;
388 static_cast<EIGEN_SOLVER*
>(eigen_solver_pt())
389 ->get_eigenvalues_right_of_shift();
395 Problem::mesh_pt() =
new OneDMesh<ELEMENT>(n_element,L);
403 mesh_pt()->boundary_node_pt(0,0)->pin(0);
407 mesh_pt()->boundary_node_pt(1,0)->pin(0);
410 assign_eqn_numbers();
419 template<
class ELEMENT,
class EIGEN_SOLVER>
421 const unsigned& label)
432 sprintf(filename,
"soln%i.dat",label);
433 some_file.open(filename);
434 mesh_pt()->output(some_file,npts);
442 template<
class ELEMENT,
class EIGEN_SOLVER>
447 Vector<complex<double> > eigenvalues;
449 Vector<DoubleVector> eigenvectors;
456 this->solve_eigenproblem(n_eval,eigenvalues,eigenvectors);
461 Vector<complex<double> > sorted_eigenvalues = eigenvalues;
462 sort(sorted_eigenvalues.begin(),sorted_eigenvalues.end(),
466 complex<double> temp_evalue = sorted_eigenvalues[0];
467 unsigned smallest_index=0;
470 for(
unsigned i=0;i<eigenvalues.size();i++)
474 if(eigenvalues[i] == temp_evalue) {smallest_index=i;
break;}
480 unsigned dim = eigenvectors[smallest_index].nrow();
483 for(
unsigned i=0;i<dim;i++)
486 length += std::pow(eigenvectors[smallest_index][i],2.0);
489 length = sqrt(length);
491 if(eigenvectors[smallest_index][0] < 0) {length *= -1.0;}
493 for(
unsigned i=0;i<dim;i++)
495 eigenvectors[smallest_index][i] /= length;
500 this->assign_eigenvector_to_dofs(eigenvectors[smallest_index]);
502 this->doc_solution(label);
505 sprintf(filename,
"eigenvalues%i.dat",label);
508 ofstream evalues(filename);
509 for(
unsigned i=0;i<n_eval;i++)
512 cout << sorted_eigenvalues[i].real() <<
" " 513 << sorted_eigenvalues[i].imag() << std::endl;
515 evalues << sorted_eigenvalues[i].real() <<
" " 516 << sorted_eigenvalues[i].imag() << std::endl;
531 int main(
int argc,
char **argv)
536 MPI_Helpers::init(argc,argv);
540 unsigned n_element=100;
542 clock_t t_start1 = clock();
548 std::cout <<
"Matrix size " << problem.ndof() << std::endl;
552 clock_t t_end1 = clock();
554 clock_t t_start2 = clock();
562 clock_t t_end2 = clock();
564 #ifdef OOMPH_HAS_TRILINOS 565 clock_t t_start3 = clock();
571 clock_t t_end3 = clock();
574 std::cout <<
"ARPACK TIME: " << (double)(t_end1 - t_start1)/CLOCKS_PER_SEC
577 std::cout <<
"LAPACK TIME: " << (double)(t_end2 - t_start2)/CLOCKS_PER_SEC
580 #ifdef OOMPH_HAS_TRILINOS 581 std::cout <<
"ANASAZI TIME: " << (double)(t_end3 - t_start3)/CLOCKS_PER_SEC
586 MPI_Helpers::finalize();
ComplexHarmonicProblem(const unsigned &n_element)
Constructor: Pass number of elements and pointer to source function.
unsigned required_nvalue(const unsigned &n) const
Required # of `values' (pinned or dofs) at node n. Here there are two (u and w)
double interpolated_w(const Vector< double > &s) const
Return FE representation of function value w(s) at local coordinate s.
1D ComplexHarmonic problem in unit interval.
void solve(const unsigned &label)
Solve the problem.
~ComplexHarmonicProblem()
Destructor. Clean up the mesh and solver.
int main(int argc, char **argv)
Driver for 1D Poisson problem.
ComplexHarmonicEquations()
Empty Constructor.
bool operator()(const complex< T > &x, const complex< T > &y) const
Comparison in terms of magnitude of complex number.
virtual double w(const unsigned &n) const
Second eigenfunction value at local node n.
void output(ostream &outfile)
Output function overloaded from ComplexHarmonicEquations.
virtual double u(const unsigned &n) const
Access function: First eigenfunction value at local node n Note that solving the eigenproblem does no...
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. Return Jacobian.
void doc_solution(const unsigned &label)
Doc the solution, pass the number of the case considered, so that output files can be distinguished...
void output(ostream &outfile)
Output the eigenfunction with default number of plot points.
double interpolated_u(const Vector< double > &s) const
Return FE representation of function value u(s) at local coordinate s.
virtual int u_local_eqn(const unsigned &n, const unsigned &i)
Access function that returns the local equation number of the unknown in the problem. Default is to assume that it is the first (only) value stored at the node.
QComplexHarmonicElement()
Constructor: Call constructors for QElement and Poisson equations.
void output(ostream &outfile, const unsigned &Nplot)
Output function overloaded from ComplexHarmonicEquations.
void output(ostream &outfile, const unsigned &nplot)
Output FE representation of soln: x,y,u or x,y,z,u at Nplot plot points.
void fill_in_contribution_to_jacobian_and_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix)
Assemble the contributions to the jacobian and mass matrices.
double dshape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx) const
Shape, test functions & derivs. w.r.t. to global coords. Return Jacobian.
Namespace for the shift applied to the eigenproblem.