/** * @file interface_fcs.cpp * @author Julian Iseringhausen * @date Mon Apr 18 12:56:20 2011 * * @brief VMG::InterfaceFCS * */ #ifdef HAVE_CONFIG_H #include #endif #ifndef HAVE_MPI #error MPI is needed to use the Scafacos interface. #endif #include #include "base/object.hpp" #include "comm/comm_serial.hpp" #include "interface/interface_fcs.h" #include "interface/interface_particles.hpp" #include "level/level_operator_cs.hpp" #include "samples/discretization_poisson_fd.hpp" #include "samples/stencils.hpp" #include "samples/techniques.hpp" #include "smoother/gsrb.cpp" #ifdef HAVE_LAPACK #include "solver/dgesv.hpp" #include "solver/dsysv.hpp" #else #include "solver/givens.hpp" #endif #include "solver/solver_dirichlet.hpp" #include "solver/solver_periodic.hpp" using namespace VMG; void VMGInterfaceFCSInit(vmg_int level, vmg_int periodic, vmg_int spline_degree, vmg_int max_iter, vmg_int smoothing_steps, vmg_int gamma, vmg_float precision, vmg_float box_begin, vmg_float box_end, MPI_Comm mpi_comm) { const BC bc = (periodic ? Periodic : Dirichlet); /* * Register all the parameters for later use. */ new ObjectStorage("LEVEL_FCS", level); new ObjectStorage("PERIODIC_FCS", periodic); new ObjectStorage("SPLINE_DEGREE_FCS", spline_degree); new ObjectStorage("MAX_ITER_FCS", max_iter); new ObjectStorage("SMOOTHING_STEPS_FCS", smoothing_steps); new ObjectStorage("GAMMA_FCS", gamma); new ObjectStorage("PRECISION_FCS", precision); new ObjectStorage("BOX_BEGIN_FCS", box_begin); new ObjectStorage("BOX_END_FCS", box_end); new ObjectStorage("MPI_COMM_FCS", mpi_comm); /* * Register communication class. * For now, parallel version is not yet released. */ Comm* comm = new CommSerial(bc); comm->Register("COMM"); /* * Register particle interface. */ Interface* interface = new VMG::InterfaceParticles(bc, 2, level, box_begin, box_end); MG::SetInterface(interface, comm); /* * Use a finite difference discretization of the Poisson equation */ Discretization* discretization = new DiscretizationPoissonFD(); discretization->Register("DISCRETIZATION"); /* * Use a correction scheme multigrid algorithm with full weight stencils. * Since we use the Gauss-Seidel RB smoother here, this may be replaced * with a half-weight version once debugging is finished. */ LevelOperator* lop = new LevelOperatorCS(Stencils::RestrictionFullWeight, Stencils::InterpolationTrilinear); lop->Register("LEVEL_OPERATOR"); /* * Use Gauss-Seidel Red-Black ordering */ Smoother* smoother = new GaussSeidelRB(); smoother->Register("SMOOTHER"); /* * Use LAPACK solver when available, otherwise use Givens rotations. */ #ifdef HAVE_LAPACK Solver* solver = (periodic ? static_cast(new DSYSV()) : static_cast(new DGESV())); #else Solver* solver = (periodic ? static_cast(new Givens()) : static_cast(new Givens())); #endif solver->Register("SOLVER"); /* * Set commands for the actual multigrid cycle */ if (periodic) Techniques::SetCorrectionSchemePeriodic(2, level, gamma); else Techniques::SetCorrectionSchemeDirichlet(2, level, gamma); /* * Register required parameters */ new ObjectStorage("PRESMOOTHSTEPS", smoothing_steps); new ObjectStorage("POSTSMOOTHSTEPS", smoothing_steps); new ObjectStorage("PRECISION", precision); new ObjectStorage("MAX_ITERATION", max_iter); /* * Check whether the library is correctly initialized now. */ MG::IsInitialized(); } void VMGInterfaceFCSRun(vmg_float* x, vmg_float* q, vmg_float* p, vmg_float* f, vmg_int num_particles_local) { /* * Register parameters for later use. */ new ObjectStorage("X_FCS", x); new ObjectStorage("Q_FCS", q); new ObjectStorage("P_FCS", p); new ObjectStorage("F_FCS", f); new ObjectStorage("NUM_PARTICLES_LOCAL_FCS", num_particles_local); /* * Start the multigrid solver */ MG::Solve(); } void VMGInterfaceFCSDestroy(void) { /* * Delete all data. */ MG::Destroy(); }