From 27f84e9125b147dd5552595c47b228ca4251a34c Mon Sep 17 00:00:00 2001 From: Serhii Yaskovets <yaskovet@mpi-cbg.de> Date: Mon, 26 Jun 2023 18:24:31 +0200 Subject: [PATCH] Get rid of redundant DCPSE_Solver.cuh; Move to DCPSE_Solver.hpp for GPU --- src/DCPSE/DCPSE_op/DCPSE_Solver.cuh | 801 ---------------------------- src/DCPSE/DCPSE_op/DCPSE_Solver.hpp | 13 +- 2 files changed, 11 insertions(+), 803 deletions(-) delete mode 100644 src/DCPSE/DCPSE_op/DCPSE_Solver.cuh diff --git a/src/DCPSE/DCPSE_op/DCPSE_Solver.cuh b/src/DCPSE/DCPSE_op/DCPSE_Solver.cuh deleted file mode 100644 index 8045214f..00000000 --- a/src/DCPSE/DCPSE_op/DCPSE_Solver.cuh +++ /dev/null @@ -1,801 +0,0 @@ -// -// Created by Serhii -// - -#ifndef OPENFPM_PDATA_DCPSE_SOLVER_CUH -#define OPENFPM_PDATA_DCPSE_SOLVER_CUH - -// #include "DCPSE_op.hpp" -#include "DCPSE/DCPSE_op/DCPSE_op.hpp" -#include "Matrix/SparseMatrix.hpp" -#include "Vector/Vector.hpp" -#include "NN/CellList/CellDecomposer.hpp" -#include "Vector/Vector_util.hpp" -#include "Vector/vector_dist.hpp" -#include "Solvers/umfpack_solver.hpp" -#include "Solvers/petsc_solver.hpp" -#include "util/eq_solve_common.hpp" - -/*enum eq_struct -{ - VECTOR, - SCALAR -};*/ - -//template<unsigned int prp_id> using prop_id = boost::mpl::int_<prp_id>; -/*! \brief Create a Matrix System for Ax=b - * - * This Class is for creating a placeholder for the matrix system - * - * Ax = b - * - * - * \param Sys_eqs Equation Structure which has information about the system. Refer to EqnStruct.cpp for examples - * \param parts Particle set - * - */ -template<typename Sys_eqs, typename particles_type> -class DCPSE_scheme_gpu { - - //! type of the sparse matrix - typename Sys_eqs::SparseMatrix_type A; - - //! Vector b - typename Sys_eqs::Vector_type b; - - //! Sparse matrix triplet type - typedef typename Sys_eqs::SparseMatrix_type::triplet_type triplet; - - //! Distributed grid map - typedef vector_dist_gpu<Sys_eqs::dims, typename Sys_eqs::stype, aggregate<size_t>> p_map_type; - - //! mapping grid - p_map_type p_map; - - //! Grid points that has each processor - openfpm::vector<size_t> pnt; - - //! Particles used to impose the system - particles_type &parts; - - //! colums shift map - //int col_sm[Sys_eqs::nvar]; - - //! Each point in the grid has a global id, to decompose correctly the Matrix each processor contain a - //! contiguos range of global id, example processor 0 can have from 0 to 234 and processor 1 from 235 to 512 - //! no processors can have holes in the sequence, this number indicate where the sequence start for this - //! processor - size_t s_pnt; - - //! row of the matrix - size_t row; - - //! row on b - size_t row_b; - - //! Total number of points - size_t tot; - - //! solver options - options_solver opt; - - size_t offset; - - - /*! \brief Construct the gmap structure - * - */template<typename options> - void construct_pmap(options opt = options_solver::STANDARD) { - Vcluster<> &v_cl = create_vcluster(); - - // Calculate the size of the local domain - size_t sz = p_map.size_local(); - - // Get the total size of the local grids on each processors - v_cl.allGather(sz, pnt); - v_cl.execute(); - s_pnt = 0; - - // calculate the starting point for this processor - for (size_t i = 0; i < v_cl.getProcessUnitID(); i++) - s_pnt += pnt.get(i); - - tot = sz; - v_cl.sum(tot); - v_cl.execute(); - - // resize b if needed - if (opt == options_solver::STANDARD) { - b.resize(Sys_eqs::nvar * tot, Sys_eqs::nvar * sz); - } else if (opt == options_solver::LAGRANGE_MULTIPLIER) { - if (v_cl.rank() == v_cl.size() - 1) { - b.resize(Sys_eqs::nvar * tot + 1, Sys_eqs::nvar * sz + 1); - } else { - b.resize(Sys_eqs::nvar * tot + 1, Sys_eqs::nvar * sz); - } - } - //Use Custom number of constraints using opt as an integer - else { - if (v_cl.rank() == v_cl.size() - 1) { - b.resize(Sys_eqs::nvar * tot - offset, Sys_eqs::nvar * sz - offset); - } else { - b.resize(Sys_eqs::nvar * tot - offset, Sys_eqs::nvar * sz); - } - } - - // Calculate the starting point - - // Counter - size_t cnt = 0; - - // Create the re-mapping grid - auto it = p_map.getDomainIterator(); - - while (it.isNext()) { - auto key = it.get(); - - for (int i = 0; i < particles_type::dims; i++) { - p_map.getPos(key)[i] = parts.getPos(key)[i]; - } - - p_map.template getProp<0>(key) = cnt + s_pnt; - - ++cnt; - ++it; - } - - // sync the ghost - p_map.template ghost_get<0>(); - } - - //! Encapsulation of the b term as constant - struct constant_b { - //! scalar - typename Sys_eqs::stype scal; - - /*! \brief Constrictor from a scalar - * - * \param scal scalar - * - */ - constant_b(typename Sys_eqs::stype scal) { - this->scal = scal; - } - - /*! \brief Get the b term on a grid point - * - * \note It does not matter the grid point it is a scalar - * - * \param key grid position (unused because it is a constant) - * - * \return the scalar - * - */ - typename Sys_eqs::stype get(size_t key) { - return scal; - } - }; - - //! Encapsulation of the b term as constant - template<unsigned int prp_id> - struct variable_b { - //! scalar - typename Sys_eqs::stype scal; - - particles_type &parts; - - /*! \brief Constrictor from a scalar - * - * \param scal scalar - * - */ - variable_b(particles_type &parts) - : parts(parts) {} - - /*! \brief Get the b term on a grid point - * - * \note It does not matter the grid point it is a scalar - * - * \param key grid position (unused because it is a constant) - * - * \return the scalar - * - */ - inline typename Sys_eqs::stype get(size_t key) { - return parts.template getProp<prp_id>(key); - } - }; - - - /*! \brief Check if the Matrix is consistent - * - */ - void consistency() { - openfpm::vector<triplet> &trpl = A.getMatrixTriplets(); - - // A and B must have the same rows - if (row != row_b) { - std::cerr << "Error " << __FILE__ << ":" << __LINE__ - << " the term B and the Matrix A for Ax=B must contain the same number of rows " << row << "!=" << row_b << "\n"; - return; - } - if (row_b != p_map.size_local() * Sys_eqs::nvar) { - std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " your system is underdetermined you set " - << row_b << " conditions " << " but i am expecting " << p_map.size_local() * Sys_eqs::nvar - << std::endl; - return; - } - - // Indicate all the non zero rows - openfpm::vector<unsigned char> nz_rows; - nz_rows.resize(row_b); - - for (size_t i = 0; i < trpl.size(); i++) { - if (trpl.get(i).row() - s_pnt * Sys_eqs::nvar >= nz_rows.size()) { - std::cerr << "Error " << __FILE__ << ":" << __LINE__ - << " It seems that you are setting colums that does not exist \n"; - } - if (trpl.get(i).value() != 0) { nz_rows.get(trpl.get(i).row() - s_pnt * Sys_eqs::nvar) = true; } - } - - // Indicate all the non zero colums - // This check can be done only on single processor - - Vcluster<> &v_cl = create_vcluster(); - if (v_cl.getProcessingUnits() == 1) { - openfpm::vector<unsigned> nz_cols; - nz_cols.resize(row_b); - - for (size_t i = 0; i < trpl.size(); i++) { - if (trpl.get(i).value() != 0) { nz_cols.get(trpl.get(i).col()) = true; } - } - - // all the rows must have a non zero element - for (size_t i = 0; i < nz_rows.size(); i++) { - if (nz_rows.get(i) == false) { - std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix row " << i - << " is not filled " << " equation: " << "\n"; - } - } - - // all the colums must have a non zero element - for (size_t i = 0; i < nz_cols.size(); i++) { - if (nz_cols.get(i) == false) - std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix colum " << i - << " is not filled\n"; - } - } - } - - /*! \brief Solve an equation - * - * \warning exp must be a scalar type - * - * \param exp where to store the result - * - */ - template<typename solType, typename expr_type> - void copy_impl(solType & x, expr_type exp, unsigned int comp) - { - auto & parts = exp.getVector(); - - auto it = parts.getDomainIterator(); - - while (it.isNext()) { - auto p = it.get(); - exp.value(p) = x(p.getKey() * Sys_eqs::nvar + comp + s_pnt * Sys_eqs::nvar); - ++it; - } - } - - template<typename solType, typename exp1, typename ... othersExp> - void copy_nested(solType &x, unsigned int &comp, exp1 exp, othersExp ... exps) { - copy_impl(x, exp, comp); - comp++; - - copy_nested(x, comp, exps ...); - } - - - template<typename solType, typename exp1> - void copy_nested(solType &x, unsigned int &comp, exp1 exp) { - copy_impl(x, exp, comp); - comp++; - } - -public: - - /*! \brief Set the structure of the system of equation - * - * For example for stokes-flow where you are solving for V = velocity (Vector) and P = pressure (scalar) - * - * you should call this function with - * - * setEquationStructure({eq_struct::VECTOR,eq_struct::SCALAR}) - * - */ -/* void setEquationStructure(std::initializer_list<eq_struct> l) - { - int i = 0; - for (eq_struct e : l) - { - if (e == eq_struct::VECTOR) - { - for (int j = 0 ; j < Sys_eqs::dims ; j++) - { - col_sm[i+j] = i; - } - i += Sys_eqs::dims; - } - else - { - col_sm[i] = i; - } - } - }*/ - - - /*! \brief Solve an equation - * - * \warning exp must be a scalar type - * - * \param exp where to store the result - * - */ - template<typename ... expr_type> - void solve(expr_type ... exps) { - if (sizeof...(exps) != Sys_eqs::nvar) { - std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\ - dimensionality, I am expecting " << Sys_eqs::nvar << - " properties " << std::endl; - }; - typename Sys_eqs::solver_type solver; -// umfpack_solver<double> solver; - auto x = solver.solve(getA(opt), getB(opt)); - - unsigned int comp = 0; - copy_nested(x, comp, exps ...); - } - - /*! \brief Solve an equation - * - * \warning exp must be a scalar type - * - * \param Solver Manually created Solver instead from the Equation structure - * \param exp where to store the result - * - */ - template<typename SolverType, typename ... expr_type> - void solve_with_solver(SolverType &solver, expr_type ... exps) { -#ifdef SE_CLASS1 - - if (sizeof...(exps) != Sys_eqs::nvar) { - std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\ - dimensionality, I am expecting " << Sys_eqs::nvar << - " properties " << std::endl; - }; -#endif - auto x = solver.solve(getA(opt), getB(opt)); - - unsigned int comp = 0; - copy_nested(x, comp, exps ...); - } - - /*! \brief Solve an equation - * - * \warning exp must be a scalar type - * - * \param exp where to store the result - * - */ - template<typename SolverType, typename ... expr_type> - void try_solve_with_solver(SolverType &solver, expr_type ... exps) { - if (sizeof...(exps) != Sys_eqs::nvar) { - std::cerr << __FILE__ << ":" << __LINE__ << " Error the number of properties you gave does not match the solution in\ - dimensionality, I am expecting " << Sys_eqs::nvar << - " properties " << std::endl; - }; - - auto x = solver.try_solve(getA(opt), getB(opt)); - - unsigned int comp = 0; - copy_nested(x, comp, exps ...); - } - - void reset_b() - { - row_b = 0; - } - - void reset(particles_type &part, options_solver opt = options_solver::STANDARD) - { - row = 0; - row_b = 0; - - p_map.clear(); - p_map.resize(part.size_local()); - - A.getMatrixTriplets().clear(); - - construct_pmap(opt); - } - - void reset_nodec() - { - row = 0; - row_b = 0; - - A.getMatrixTriplets().clear(); - } - - /*! \brief Constructor for the solver - * - * - * \param parts Particle set - * \param option_solver opt=options_solver::LAGRANGE_MULTIPLIER can be used for purely Neumann system - * - */ - DCPSE_scheme_gpu(particles_type &part, options_solver opt = options_solver::STANDARD) - : parts(part), p_map(part.getDecomposition(), 0), row(0), row_b(0), opt(opt) { - p_map.resize(part.size_local()); - - construct_pmap(opt); - } - - /*DCPSE_scheme_gpu(particles_type &part, int option_num) - : parts(part), p_map(part.getDecomposition(), 0), row(0), row_b(0),opt(options_solver::CUSTOM),offset(option_num) { - p_map.resize(part.size_local()); - construct_pmap(option_num); - }*/ - - - /*! \brief Impose an operator in the Matrix System - * - * This function impose an operator on a particular particle region to produce the system - * - * Ax = b - * - * - * \param op Operator to impose (A term) - * \param subset Vector with indices of particles where the operator has to be imposed - * \param prp_id<>() Property number in the aggregate (Scalar only) for imposing on the RHS b. - * \param id Equation id in the system that we are imposing given by ed_id type - * - */ - template<typename T, typename index_type, unsigned int prp_id> - void impose(const T &op, openfpm::vector<index_type> &subset, - const prop_id<prp_id> &num, - eq_id id = eq_id()) { - auto itd = subset.template getIteratorElements<0>(); - - variable_b<prp_id> vb(parts); - - impose_git(op, vb, id.getId(), itd); - } - - /*! \brief Impose b part only in the Matrix System Ax=b - * - * This function impose RHS of an existing Ax=b system. - * - * - * \param subset Vector with indices of particles where the operator has to be imposed - * \param num right hand side of the term (b term) Constant in this case - * \param id Equation id in the system that we are imposing given by ed_id type - * - */ - template<typename index_type, unsigned int prp_id> - void impose_b(openfpm::vector<index_type> &subset, - const prop_id<prp_id> &num, - eq_id id = eq_id()) { - auto itd = subset.template getIteratorElements<0>(); - - variable_b<prp_id> vb(parts); - - impose_git_b(vb, id.getId(), itd); - } - - /*! \brief Impose an operator in the Matrix System - * - * This function impose an operator on a particular particle region to produce the system - * - * Ax = b - * - * - * \param op Operator to impose (A term) - * \param subset Vector with indices of particles where the operator has to be imposed - * \param RHS Expression of the Vector to be imposed - * \param id Equation id in the system that we are imposing given by ed_id type - * - */ - template<typename T, typename index_type, typename RHS_type, typename sfinae = typename std::enable_if<!std::is_fundamental<RHS_type>::type::value>::type> - void impose(const T &op, openfpm::vector<index_type> &subset, - const RHS_type &rhs, - eq_id id = eq_id()) { - auto itd = subset.template getIteratorElements<0>(); - - impose_git(op, rhs, id.getId(), itd); - } - /*! \brief Impose b part only in the Matrix System Ax=b - * - * This function impose RHS of an existing Ax=b system. - * - * - * - * \param subset Vector with indices of particles where the operator has to be imposed - * \param Expression of the Vector to be imposed - * \param id Equation id in the system that we are imposing given by ed_id type - * - */ - template<typename index_type, typename RHS_type, typename sfinae = typename std::enable_if<!std::is_fundamental<RHS_type>::type::value>::type> - void impose_b(openfpm::vector<index_type> &subset, - const RHS_type &rhs, - eq_id id = eq_id()) { - auto itd = subset.template getIteratorElements<0>(); - impose_git_b(rhs, id.getId(), itd); - } - - /*! \brief Impose an operator in the Matrix System - * - * This function impose an operator on a particular particle region to produce the system - * - * Ax = b - * - * - * \param op Operator to impose (A term) - * \param subset Vector with indices of particles where the operator has to be imposed - * \param num Constant for all the particles - * \param id Equation id in the system that we are imposing given by ed_id type - * - */ - template<typename T, typename index_type> - void impose(const T &op, - openfpm::vector<index_type> &subset, - const typename Sys_eqs::stype num, - eq_id id = eq_id()) { - auto itd = subset.template getIteratorElements<0>(); - - constant_b b(num); - - impose_git(op, b, id.getId(), itd); - } - /*! \brief Impose b part only in the Matrix System Ax=b - * - * This function impose RHS of an existing Ax=b system. - * - * - * - * \param subset Vector with indices of particles where the operator has to be imposed - * \param num Constant for all the particles - * \param id Equation id in the system that we are imposing given by ed_id type - * - */ - template< typename index_type> - void impose_b(openfpm::vector<index_type> &subset, - const typename Sys_eqs::stype num, - eq_id id = eq_id()) { - auto itd = subset.template getIteratorElements<0>(); - - constant_b b(num); - - impose_git_b(b, id.getId(), itd); - } - - /*! \brief produce the Matrix - * - * \return the Sparse matrix produced - * - */ - template<typename options> - typename Sys_eqs::SparseMatrix_type &getA(options opt) { -#ifdef SE_CLASS1 - consistency(); -#endif - if (opt == options_solver::STANDARD) { - A.resize(tot * Sys_eqs::nvar, tot * Sys_eqs::nvar, - p_map.size_local() * Sys_eqs::nvar, - p_map.size_local() * Sys_eqs::nvar); - } - else if (opt == options_solver::LAGRANGE_MULTIPLIER) { - auto &v_cl = create_vcluster(); - openfpm::vector<triplet> &trpl = A.getMatrixTriplets(); - - if (v_cl.rank() == v_cl.size() - 1) { - A.resize(tot * Sys_eqs::nvar + 1, tot * Sys_eqs::nvar + 1, - p_map.size_local() * Sys_eqs::nvar + 1, - p_map.size_local() * Sys_eqs::nvar + 1); - - for (int i = 0; i < tot * Sys_eqs::nvar; i++) { - triplet t1; - - t1.row() = tot * Sys_eqs::nvar; - t1.col() = i; - t1.value() = 1; - - trpl.add(t1); - } - - for (int i = 0; i < p_map.size_local() * Sys_eqs::nvar; i++) { - triplet t2; - - t2.row() = i + s_pnt * Sys_eqs::nvar; - t2.col() = tot * Sys_eqs::nvar; - t2.value() = 1; - - trpl.add(t2); - } - - triplet t3; - - t3.col() = tot * Sys_eqs::nvar; - t3.row() = tot * Sys_eqs::nvar; - t3.value() = 0; - - trpl.add(t3); - - row_b++; - row++; - } - else { - A.resize(tot * Sys_eqs::nvar + 1, tot * Sys_eqs::nvar + 1, - p_map.size_local() * Sys_eqs::nvar, - p_map.size_local() * Sys_eqs::nvar); - - for (int i = 0; i < p_map.size_local() * Sys_eqs::nvar; i++) { - triplet t2; - - t2.row() = i + s_pnt * Sys_eqs::nvar; - t2.col() = tot * Sys_eqs::nvar; - t2.value() = 1; - - trpl.add(t2); - } - } - - - } - - else{ - auto &v_cl = create_vcluster(); - if (v_cl.rank() == v_cl.size() - 1) { - A.resize(tot * Sys_eqs::nvar - offset, tot * Sys_eqs::nvar - offset, - p_map.size_local() * Sys_eqs::nvar - offset, - p_map.size_local() * Sys_eqs::nvar - offset); - } - else { - A.resize(tot * Sys_eqs::nvar - offset, tot * Sys_eqs::nvar - offset, - p_map.size_local() * Sys_eqs::nvar, - p_map.size_local() * Sys_eqs::nvar); - } - } - - return A; - - } - - /*! \brief produce the B vector - * - * \return the vector produced - * - */ - typename Sys_eqs::Vector_type &getB(options_solver opt = options_solver::STANDARD) { -#ifdef SE_CLASS1 - consistency(); -#endif - if (opt == options_solver::LAGRANGE_MULTIPLIER) { - auto &v_cl = create_vcluster(); - if (v_cl.rank() == v_cl.size() - 1) { - - b(tot * Sys_eqs::nvar) = 0; - } - } - return b; - } - - - template<typename bop, typename iterator> - void impose_git_b(bop num, - long int id, - const iterator &it_d) { - auto it = it_d; - // iterate all particles points - while (it.isNext()) { - // get the particle - auto key = it.get(); - // Calculate the non-zero colums - b(p_map.template getProp<0>(key) * Sys_eqs::nvar + id) = num.get(key); -// std::cout << "b=(" << p_map.template getProp<0>(key)*Sys_eqs::nvar + id << "," << num.get(key)<<")" <<"\n"; - - // if SE_CLASS1 is defined check the position -#ifdef SE_CLASS1 - // T::position(key,gs,s_pos); -#endif - ++row_b; - ++it; - } - } - - /*! \brief Impose an operator - * - * This function impose an operator on a particular grid region to produce the system - * - * Ax = b - * - * ## Stokes equation 2D, lid driven cavity with one splipping wall - * \snippet eq_unit_test.hpp Copy the solution to grid - * - * \param op Operator to impose (A term) - * \param num right hand side of the term (b term) - * \param id Equation id in the system that we are imposing - * \param it_d iterator that define where you want to impose - * - */ - template<typename T, typename bop, typename iterator> - void impose_git(const T &op, - bop num, - long int id, - const iterator &it_d) { - openfpm::vector<triplet> &trpl = A.getMatrixTriplets(); - - auto it = it_d; - - //std::unordered_map<long int, typename particles_type::stype> cols; - - tsl::hopscotch_map<long int, typename particles_type::stype> cols; - - // iterate all particles points - while (it.isNext()) { - // get the particle - auto key = it.get(); - -/* - if (key == 298 && create_vcluster().rank() == 1) - { - int debug = 0; - debug++; - } -*/ - - // Calculate the non-zero colums - typename Sys_eqs::stype coeff = 1.0; - op.template value_nz<Sys_eqs>(p_map, key, cols, coeff, 0); - - // indicate if the diagonal has been set - bool is_diag = false; - - // create the triplet - for (auto it = cols.begin(); it != cols.end(); ++it) { - trpl.add(); - trpl.last().row() = p_map.template getProp<0>(key) * Sys_eqs::nvar + id; - trpl.last().col() = it->first; - trpl.last().value() = it->second; - if (trpl.last().row() == trpl.last().col()) - {is_diag = true;} - } - - // If does not have a diagonal entry put it to zero - if (is_diag == false) - { - trpl.add(); - trpl.last().row() = p_map.template getProp<0>(key) * Sys_eqs::nvar + id; - trpl.last().col() = p_map.template getProp<0>(key) * Sys_eqs::nvar + id; - trpl.last().value() = 0.0; - } - b(p_map.template getProp<0>(key) * Sys_eqs::nvar + id) = num.get(key); - cols.clear(); - - // if SE_CLASS1 is defined check the position -#ifdef SE_CLASS1 - // T::position(key,gs,s_pos); -#endif - - ++row; - ++row_b; - ++it; - } - } - -}; - - - -#endif //OPENFPM_PDATA_DCPSE_SOLVER_CUH diff --git a/src/DCPSE/DCPSE_op/DCPSE_Solver.hpp b/src/DCPSE/DCPSE_op/DCPSE_Solver.hpp index 52330de9..faabeaea 100644 --- a/src/DCPSE/DCPSE_op/DCPSE_Solver.hpp +++ b/src/DCPSE/DCPSE_op/DCPSE_Solver.hpp @@ -35,7 +35,10 @@ * \param parts Particle set * */ -template<typename Sys_eqs, typename particles_type> +template<typename Sys_eqs, + typename particles_type, + typename Memory = typename Sys_eqs::b_part::Memory_type, + template<typename> class layout_base = memory_traits_lin> class DCPSE_scheme { //! type of the sparse matrix @@ -51,7 +54,11 @@ class DCPSE_scheme { typedef typename Sys_eqs::SparseMatrix_type::triplet_type triplet; //! Distributed grid map - typedef vector_dist<Sys_eqs::dims, typename Sys_eqs::stype, aggregate<size_t>> p_map_type; + typedef vector_dist< Sys_eqs::dims, + typename Sys_eqs::stype, aggregate<size_t>, + typename Sys_eqs::b_part::Decomposition_type, + typename Sys_eqs::b_part::Memory_type, + layout_base> p_map_type; //! mapping grid p_map_type p_map; @@ -1002,6 +1009,8 @@ public: }; +template<typename Sys_eqs, typename particles_type> using DCPSE_scheme_gpu = DCPSE_scheme<Sys_eqs,particles_type,CudaMemory,memory_traits_inte>; + #include "DCPSE/DCPSE_op/EqnsStruct.hpp" #endif //Eigen #endif //OPENFPM_PDATA_DCPSE_SOLVER_HPP -- GitLab