#ifndef _SURFACE_OP_HPP_ #define _SURFACE_OP_HPP_ #include #include #include namespace biest { template class SurfaceOp { static constexpr sctl::Integer COORD_DIM = 3; public: SurfaceOp(const sctl::Comm& comm = sctl::Comm::Self(), sctl::Long Nt = 0, sctl::Long Np = 0); SurfaceOp(const SurfaceOp& Op); SurfaceOp& operator=(const SurfaceOp& Op); static void Upsample(const sctl::Vector& X0_, sctl::Long Nt0, sctl::Long Np0, sctl::Vector& X1_, sctl::Long Nt1, sctl::Long Np1); void Grad2D(sctl::Vector& dX, const sctl::Vector& X) const; Real SurfNormalAreaElem(sctl::Vector* normal, sctl::Vector* area_elem, const sctl::Vector& dX, const sctl::Vector* X) const; void SurfCurl(sctl::Vector& DivF, const sctl::Vector& dX, const sctl::Vector& normal, const sctl::Vector& F) const; void SurfGrad(sctl::Vector& GradFvec, const sctl::Vector& dXvec_, const sctl::Vector& Fvec) const; void SurfDiv(sctl::Vector& DivF, const sctl::Vector& dX, const sctl::Vector& F) const; void SurfLap(sctl::Vector& LapF, const sctl::Vector& dX, const sctl::Vector& F) const; void SurfInteg(sctl::Vector& I, const sctl::Vector& area_elem, const sctl::Vector& F) const; void ProjZeroMean(sctl::Vector& Fproj, const sctl::Vector& dX, const sctl::Vector& F) const; void InvSurfLap(sctl::Vector& InvLapF, const sctl::Vector& dX, const sctl::Vector& d2X, const sctl::Vector& F, Real tol, sctl::Integer max_iter = -1, Real upsample = 1.0) const; void GradInvSurfLap(sctl::Vector& GradInvLapF, const sctl::Vector& dX, const sctl::Vector& d2X, const sctl::Vector& F, Real tol, sctl::Integer max_iter = -1, Real upsample = 1.0) const; void InvSurfLapPrecond(sctl::Vector& InvLapF, std::function&, const sctl::Vector&)> LeftPrecond, std::function&, const sctl::Vector&)> RightPrecond, const sctl::Vector& dX, const sctl::Vector& F, Real tol, sctl::Integer max_iter = -1) const; template void EvalSurfInteg(sctl::Vector& Utrg, const sctl::Vector& Xtrg, const sctl::Vector& Xsrc, const sctl::Vector& Xn_src, const sctl::Vector& Xa_src, const sctl::Vector& Fsrc, const KernelFunction& ker) const; template void SetupSingularCorrection(sctl::Vector& singular_correction, sctl::Integer TRG_SKIP, const sctl::Vector& Xsrc, const sctl::Vector& dXsrc, const Kernel& ker, Real normal_scal = 1.0) const; template void EvalSingularCorrection(sctl::Vector& U, const sctl::Vector& singular_correction, sctl::Integer kdim0, sctl::Integer kdim1, const sctl::Vector& F) const; void HodgeDecomp(sctl::Vector& Vn, sctl::Vector& Vd, sctl::Vector& Vc, sctl::Vector& Vh, const sctl::Vector& V, const sctl::Vector& dX, const sctl::Vector& d2X, const sctl::Vector& normal, Real tol, sctl::Long max_iter = -1) const; static void test_SurfGrad(sctl::Long Nt, sctl::Long Np, SurfType surf_type, const sctl::Comm& comm); static void test_SurfLap(sctl::Long Nt, sctl::Long Np, SurfType surf_type, const sctl::Comm& comm); static void test_InvSurfLap(sctl::Long Nt, sctl::Long Np, SurfType surf_type, Real gmres_tol, sctl::Long gmres_iter, std::function&, const sctl::Vector&)>* LeftPrecond, std::function&, const sctl::Vector&)>* RightPrecond, const sctl::Comm& comm); static void test_HodgeDecomp(sctl::Long Nt, sctl::Long Np, SurfType surf_type, const sctl::Comm& comm); private: void Init(const sctl::Comm& comm, sctl::Long Nt, sctl::Long Np); static Real compute_area_elem(sctl::StaticArray& xn, const sctl::StaticArray& xt, const sctl::StaticArray& xp); static Real max_norm(const sctl::Vector& x); void LaplaceBeltramiReference(sctl::Vector& f0, sctl::Vector& u0, const sctl::Vector& X, const sctl::Vector& dX, const sctl::Vector& d2X) const; sctl::Comm comm_; sctl::Long Nt_, Np_; mutable sctl::FFT fft_r2c, fft_c2r; mutable sctl::ParallelSolver solver; }; } #include #endif //_SURFACE_OP_HPP_