// // Compile with: make helmholtz // // Sample runs: helmholtz -m ../data/one-hex.mesh // helmholtz -m ../data/fichera.mesh // helmholtz -m ../data/fichera-mixed.mesh // // Description: This example code demonstrates the use of MFEM to define a // simple finite element discretization of the Helmholtz problem // -Delta p - omega^2 p = 1 with impedance boundary condition. // #include "mfem.hpp" #include #include #include "DiagST.hpp" // #include "DST.hpp" using namespace std; using namespace mfem; // Exact solution and r.h.s., see below for implementation. double f_exact_Re(const Vector &x); double f_exact_Im(const Vector &x); double wavespeed(const Vector &x); int dim; double omega; int sol = 1; bool pml = false; double length = 1.0; double pml_length = 0.25; bool scatter = false; Array2Dcomp_bdr; #ifndef MFEM_USE_SUPERLU #error This example requires that MFEM is built with MFEM_USE_PETSC=YES #endif int main(int argc, char *argv[]) { // 2. Parse command-line options. // geometry file const char *mesh_file = "../../data/one-hex.mesh"; // finite element order of approximation int order = 1; // static condensation flag bool static_cond = false; bool visualization = 1; // number of wavelengths double k = 0.5; // number of mg levels int ref = 1; // dimension int nd = 2; // optional command line inputs OptionsParser args(argc, argv); args.AddOption(&mesh_file, "-m", "--mesh", "Mesh file to use."); args.AddOption(&order, "-o", "--order", "Finite element order (polynomial degree) or -1 for" " isoparametric space."); args.AddOption(&nd, "-nd", "--dim","Problem space dimension"); args.AddOption(&sol, "-sol", "--exact", "Exact solution flag - 0:polynomial, 1: plane wave, -1: unknown exact"); args.AddOption(&k, "-k", "--wavelengths", "Number of wavelengths."); args.AddOption(&pml, "-pml", "--pml", "-no-pml", "--no-pml", "Enable PML."); args.AddOption(&pml_length, "-pml_length", "--pml_length", "Length of the PML region in each direction"); args.AddOption(&length, "-length", "--length", "length of the domainin in each direction."); args.AddOption(&ref, "-ref", "--ref", "Number of Refinements."); args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc", "--no-static-condensation", "Enable static condensation."); args.AddOption(&scatter, "-scat", "--scattering-prob", "-no-scat", "--no-scattering", "Solve a scattering problem"); args.AddOption(&visualization, "-vis", "--visualization", "-no-vis", "--no-visualization", "Enable or disable GLVis visualization."); args.Parse(); // check if the inputs are correct if (!args.Good()) { args.PrintUsage(cout); return 1; } args.PrintOptions(cout); // Angular frequency omega = 2.0 * M_PI * k; // 3. Read the mesh from the given mesh file. Mesh *mesh; if (nd == 2) { // mesh = new Mesh(mesh_file,1,1); mesh = new Mesh(4, 4, Element::QUADRILATERAL, true, length, length, false); } else { mesh = new Mesh(1, 1, 1, Element::HEXAHEDRON, true, length, length, length,false); } // 3. Executing uniform h-refinement for (int i = 0; i < ref; i++ ) { mesh->UniformRefinement(); } dim = mesh->Dimension(); double hl = GetUniformMeshElementSize(mesh); Vector pmin, pmax; mesh->GetBoundingBox(pmin,pmax); double domain_length = pmax[0] - pmin[0]; double pml_thickness = 0.125/domain_length; int nrlayers = pml_thickness/hl; // int nrlayers = 1; Array directions; for (int i = 0; iHeight() << " x " << A->Width() << endl; DiagST S(&a,lengths, omega, &ws, nrlayers); S.SetOperator(*A); // S.SetLoadVector(B); // X = 0.0; // GMRESSolver gmres; // gmres.SetPreconditioner(S); // gmres.SetOperator(*A); // gmres.SetRelTol(1e-8); // gmres.SetMaxIter(50); // gmres.SetPrintLevel(1); // gmres.Mult(B, X); int n= 1; X = 0.0; Vector z(X.Size()); z = 0.0; Vector r(B); Vector ztemp(r.Size()); Vector Ax(X.Size()); double tol = 1e-8; cout << endl; for (int i = 0; iMult(X,Ax); Ax *=-1.0; r = b; r+=Ax; cout << " ST Solver Iteration : " << i <<" || r || = " << r.Norml2() << endl; if (r.Norml2() < tol) { cout << "Convergence in " << i+1 << " iterations" << endl; break; } S.Mult(r,z); X += z; // X1-=z; // p_gf = 0.0; // a.RecoverFEMSolution(X,B,p_gf); // char vishost[] = "localhost"; // int visport = 19916; // string keys; // if (dim ==2 ) // { // keys = "keys mrRljc\n"; // } // else // { // keys = "keys mc\n"; // } // socketstream sol1_sock_re(vishost, visport); // sol1_sock_re.precision(8); // sol1_sock_re << "solution\n" << *mesh_ext << p_gf.real() << // "window_title 'Numerical Pressure (real part)' " // << keys << flush; // cin.get(); } KLUSolver klu(*A); Vector X1(X.Size()); klu.Mult(B,X1); X1-= X; a.RecoverFEMSolution(X1,B,p_gf); if (visualization) { char vishost[] = "localhost"; int visport = 19916; string keys; if (dim ==2 ) { keys = "keys mrRljc\n"; } else { keys = "keys mc\n"; } socketstream sol_sock_re(vishost, visport); sol_sock_re.precision(8); sol_sock_re << "solution\n" << *mesh_ext << p_gf.real() << "window_title 'Numerical Pressure (real part from KLU)' " << keys << flush; // << keys << "valuerange -0.1 0.1 \n" << flush; // socketstream diff_sock_re(vishost, visport); // diff_sock_re.precision(8); // diff_sock_re << "solution\n" << *mesh_ext << p_gf1.real() << // "window_title 'Numerical Pressure (real part from KLU)' " // << keys << flush; } delete fespace; delete fec; delete mesh_ext; delete mesh; return 0; } //calculate RHS from exact solution f = - \Delta u double f_exact_Re(const Vector &x) { double f_re = 0.0; double x0 = length/2.0; double x1 = length/2.0; double x2 = length/2.0; // x0 = 0.59; // x0 = 0.19; x0 = 0.2; // x1 = 0.768; // x1 = 0.168; x1 = 0.5; double alpha,beta; // double n = 5.0*omega/M_PI; double n = 4.0*omega/M_PI; // double n = 1.0; // double coeff = pow(n,2)/M_PI; beta = pow(x0-x(0),2) + pow(x1-x(1),2); if (dim == 3) { beta += pow(x2-x(2),2); } // alpha = -pow(n,2) * beta; // double coeff = pow(n,2)/M_PI; double coeff = 16.0*omega*omega/M_PI/M_PI/M_PI; alpha = -pow(n,2) * beta; f_re = coeff*exp(alpha); x0 = 0.85; x1 = 0.85; beta = pow(x0-x(0),2) + pow(x1-x(1),2); if (dim == 3) { beta += pow(x2-x(2),2); } alpha = -pow(n,2) * beta; // f_re += coeff*exp(alpha); // x0 = 0.5; // x1 = 0.8; // beta = pow(x0-x(0),2) + pow(x1-x(1),2); // if (dim == 3) { beta += pow(x2-x(2),2); } // alpha = -pow(n,2) * beta; // f_re += coeff*exp(alpha); bool in_pml = false; for (int i = 0; i=comp_bdr(i,1)) { in_pml = true; break; } } if (in_pml) f_re = 0.0; return f_re; } double f_exact_Im(const Vector &x) { double f_im; f_im = 0.0; return f_im; } double wavespeed(const Vector &x) { double ws; // if (x(0) <= 0.25) // { // ws = 1.0; // } // else if(x(0)<=0.5) // { // ws = 1.0; // } // else if(x(0)<=0.75) // { // ws = 0.75; // // ws = 0.5; // } // else // { // ws = 0.75; // // ws = 1.0; // } // if (x(1) <= 1.0/3.0) // { // ws = 2.0; // } // else if(x(1)<=2.0/3.0) // { // ws = 1.0; // } // else // { // // ws = 0.75; // ws = 0.25; // } // if (x(0) <= 0.33) // { // ws = 1.0; // } // else if(x(0)<=0.66) // { // ws = -0.65 + 5.0*x(0); // } // else // { // ws = 2.65; // // ws = 0.5; // } ws = 1.0; return ws; }