#pragma once #include "mfem.hpp" #include #include #include "complex_additive_schwarz.hpp" using namespace std; using namespace mfem; class STPmlPatchAssembly { FiniteElementSpace *fespace=nullptr; SesquilinearForm *bf=nullptr; double omega = 0.5; int nrlayers = 4; public: int nrpatch, nx, ny, nz; MeshPartition * p; Array patch_fespaces; Array patch_fespaces_ext; Array patch_meshes_ext; std::vector> patch_dof_map; std::vector> complex_patch_dof_map; std::vector> dof2extdof_map; Array patch_mat; Array patch_mat_ext; Array patch_mat_inv_ext; Array patch_mat_inv; std::vector> ess_tdof_list; std::vector> ess_tdof_list_ext; // constructor STPmlPatchAssembly(SesquilinearForm * bf_, Array & ess_tdofs, double omega_, int nrlayers_, int part); ~STPmlPatchAssembly(); }; class SourceTransferPrecond : public Solver// { private: int nrpatch; int maxit = 1; SesquilinearForm *bf=nullptr; int type = 0; double theta = 0.5; double omega = 0.5; int nrlayers; int part; STPmlPatchAssembly * p; const Operator * A; Vector B; void PlotSolution(Vector & sol, socketstream & sol_sock, int ip) const; void GetCutOffSolution(Vector & sol, int ip) const; public: SourceTransferPrecond(SesquilinearForm * bf_, Array & ess_tdofs, double omega_, int nrlayers_, int i = 0); void SetNumSmoothSteps(const int iter) { maxit = iter;} void SetLoadVector(Vector load) { B = load;} void SetSmoothType(int itype) { type = itype;} void SetDumpingParam(const double & dump_param) {theta = dump_param;} void SetOmega(const double & omega_) {omega = omega_;} virtual void SetOperator(const Operator &op) {A = &op;} virtual void Mult(const Vector &r, Vector &z) const; virtual ~SourceTransferPrecond(); }; // Function coefficient that takes the boundingbox of the mesh as an input class CutOffFunctionCoefficient : public Coefficient { private: double (*Function)(const Vector &, const Vector &, const Vector &, const Array2D &); Vector pmin, pmax; Array2D h; // specify the with of the cutoff function (h in each direction) public: CutOffFunctionCoefficient(double (*F)(const Vector &, const Vector &, const Vector &, const Array2D &), const Vector & pmin_, const Vector & pmax_, Array2D & h_) : Function(F), pmin(pmin_), pmax(pmax_), h(h_) {} virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) { double x[3]; Vector transip(x, 3); T.Transform(ip, transip); return ((*Function)(transip, pmin, pmax, h)); } }; double CutOffFn(const Vector &x, const Vector &pmax, const Vector &pmin, const Array2D & h_);