From 8868bc4095c096242ba419cd7da28ed8b9b003b4 Mon Sep 17 00:00:00 2001 From: Pietro Incardona <i-bird@private-incardon-3.mpi-cbg.de> Date: Wed, 3 Aug 2016 17:14:28 +0200 Subject: [PATCH] Fixing numeric with latest ExtPreAlloc --- configure.ac | 6 + src/Equations/stoke_flow_eq_3d.hpp | 1 - src/FiniteDifference/FDScheme.hpp | 44 +-- src/FiniteDifference/eq.hpp | 6 + src/Makefile.am | 11 +- src/Matrix/SparseMatrix.hpp | 5 +- src/Matrix/SparseMatrix_Eigen.hpp | 7 +- src/Matrix/SparseMatrix_petsc.hpp | 5 +- src/Matrix/SparseMatrix_unit_tests.hpp | 2 +- .../Vector/vector_dist_operators.hpp | 110 ++++++- .../vector_dist_operators_apply_kernel.hpp | 274 ++++++++++-------- ...dist_operators_apply_kernel_unit_tests.hpp | 124 +++++++- .../vector_dist_operators_functions.hpp | 72 +++++ .../vector_dist_operators_unit_tests.hpp | 210 +++++++++++++- src/Solvers/petsc_solver.hpp | 44 ++- src/Solvers/umfpack_solver.hpp | 9 +- src/Vector/Vector.hpp | 7 +- src/Vector/Vector_petsc.hpp | 11 +- 18 files changed, 741 insertions(+), 207 deletions(-) diff --git a/configure.ac b/configure.ac index f070ad14..e319637a 100755 --- a/configure.ac +++ b/configure.ac @@ -143,6 +143,12 @@ AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE([HAVE_CLOCK_GETTIME],[],[Have clock t OPT_LIBS="$OPT_LIBS -lrt" ]) +########## + +## Check for LIBHILBERT + +AX_LIB_HILBERT([],[echo "Cannot detect libhilbert, use the --with-libhilbert option if it is not installed in the default location" + exit 210]) ####### include OpenFPM_numerics include path" diff --git a/src/Equations/stoke_flow_eq_3d.hpp b/src/Equations/stoke_flow_eq_3d.hpp index a355dc6c..886b6b38 100644 --- a/src/Equations/stoke_flow_eq_3d.hpp +++ b/src/Equations/stoke_flow_eq_3d.hpp @@ -12,7 +12,6 @@ constexpr unsigned int v[] = {0,1,2}; constexpr unsigned int P = 3; -constexpr unsigned int ic = 3; typedef Field<v[x],lid_nn_3d> v_x; typedef Field<v[y],lid_nn_3d> v_y; diff --git a/src/FiniteDifference/FDScheme.hpp b/src/FiniteDifference/FDScheme.hpp index 30b0877f..7686e227 100644 --- a/src/FiniteDifference/FDScheme.hpp +++ b/src/FiniteDifference/FDScheme.hpp @@ -454,13 +454,32 @@ public: */ template<typename T> void impose(const T & op , typename Sys_eqs::stype num ,long int id ,const long int (& start)[Sys_eqs::dims], const long int (& stop)[Sys_eqs::dims], bool skip_first = false) { - // add padding to start and stop - grid_key_dx<Sys_eqs::dims> start_k = grid_key_dx<Sys_eqs::dims>(start); - grid_key_dx<Sys_eqs::dims> stop_k = grid_key_dx<Sys_eqs::dims>(stop); + grid_key_dx<Sys_eqs::dims> start_k; + grid_key_dx<Sys_eqs::dims> stop_k; - auto it = g_map.getSubDomainIterator(start_k,stop_k); + bool increment = false; + if (skip_first == true) + { + start_k = grid_key_dx<Sys_eqs::dims>(start); + stop_k = grid_key_dx<Sys_eqs::dims>(start); + + auto it = g_map.getSubDomainIterator(start_k,stop_k); + + if (it.isNext() == true) + increment++; + } + + // add padding to start and stop + start_k = grid_key_dx<Sys_eqs::dims>(start); + stop_k = grid_key_dx<Sys_eqs::dims>(stop); + + auto it = g_map.getSubDomainIterator(start_k,stop_k); + + if (increment == true) + ++it; + + impose(op,num,id,it); - impose(op,num,id,it,skip_first); } /*! \brief Impose an operator @@ -478,10 +497,8 @@ public: * \param it_d iterator that define where you want to impose * */ - template<typename T> void impose(const T & op , typename Sys_eqs::stype num ,long int id ,grid_dist_iterator_sub<Sys_eqs::dims,typename g_map_type::d_grid> it_d, bool skip_first = false) + template<typename T> void impose(const T & op , typename Sys_eqs::stype num ,long int id ,grid_dist_iterator_sub<Sys_eqs::dims,typename g_map_type::d_grid> it_d) { - Vcluster & v_cl = create_vcluster(); - openfpm::vector<triplet> & trpl = A.getMatrixTriplets(); auto it = it_d; @@ -489,20 +506,9 @@ public: std::unordered_map<long int,float> cols; - bool is_first = skip_first; - // iterate all the grid points while (it.isNext()) { - if (is_first == true && v_cl.getProcessUnitID() == 0) - { - ++it; - is_first = false; - continue; - } - else - is_first = false; - // get the position auto key = it.get(); diff --git a/src/FiniteDifference/eq.hpp b/src/FiniteDifference/eq.hpp index 40925175..183437ea 100644 --- a/src/FiniteDifference/eq.hpp +++ b/src/FiniteDifference/eq.hpp @@ -114,4 +114,10 @@ inline size_t mat_factor(size_t nvar, size_t sz, const size_t ord) return nvar; } +#include "mul.hpp" +#include "Average.hpp" +#include "Derivative.hpp" +#include "sum.hpp" +#include "Laplacian.hpp" + #endif /* OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_EQ_HPP_ */ diff --git a/src/Makefile.am b/src/Makefile.am index dc9b7b8f..e4f8130d 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,17 @@ -LINKLIBS = $(PETSC_LIB) $(SUITESPARSE_LIBS) $(LAPACK_LIBS) $(BLAS_LIBS) $(METIS_LIB) $(PARMETIS_LIB) $(DEFAULT_LIB) $(PTHREAD_LIBS) $(OPT_LIBS) $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) $(BOOST_IOSTREAMS_LIB) $(HDF5_LDFLAGS) $(HDF5_LIBS) $(LIBQUADMATH) +LINKLIBS = $(LIBHILBERT_LIB) $(PETSC_LIB) $(SUITESPARSE_LIBS) $(LAPACK_LIBS) $(BLAS_LIBS) $(METIS_LIB) $(PARMETIS_LIB) $(DEFAULT_LIB) $(PTHREAD_LIBS) $(OPT_LIBS) $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) $(BOOST_IOSTREAMS_LIB) $(HDF5_LDFLAGS) $(HDF5_LIBS) $(LIBQUADMATH) noinst_PROGRAMS = numerics numerics_SOURCES = main.cpp ../../openfpm_vcluster/src/VCluster.cpp ../../openfpm_devices/src/memory/HeapMemory.cpp ../../openfpm_devices/src/memory/PtrMemory.cpp ../../openfpm_devices/src/Memleak_check.cpp -numerics_CXXFLAGS = $(AM_CXXFLAGS) $(HDF5_CPPFLAGS) $(INCLUDES_PATH) $(BOOST_CPPFLAGS) $(SUITESPARSE_INCLUDE) $(METIS_INCLUDE) $(PARMETIS_INCLUDE) $(EIGEN_INCLUDE) $(PETSC_INCLUDE) -Wno-deprecated-declarations -Wno-unused-local-typedefs +numerics_CXXFLAGS = $(LIBHILBERT_INCLUDE) $(AM_CXXFLAGS) $(HDF5_CPPFLAGS) $(INCLUDES_PATH) $(BOOST_CPPFLAGS) $(SUITESPARSE_INCLUDE) $(METIS_INCLUDE) $(PARMETIS_INCLUDE) $(EIGEN_INCLUDE) $(PETSC_INCLUDE) -Wno-deprecated-declarations -Wno-unused-local-typedefs numerics_CFLAGS = $(CUDA_CFLAGS) numerics_LDADD = $(LINKLIBS) -lparmetis -lmetis -nobase_include_HEADERS = PSE/Kernels.hpp PSE/Kernels_test_util.hpp Operators/Vector/vector_dist_operators_extensions.hpp Operators/Vector/vector_dist_operators.hpp Operators/Vector/vector_dist_operators_apply_kernel.hpp Operators/Vector/vector_dist_operators_functions.hpp +nobase_include_HEADERS = Matrix/SparseMatrix.hpp Matrix/SparseMatrix_Eigen.hpp Matrix/SparseMatrix_petsc.hpp \ +Vector/Vector_eigen.hpp Vector/Vector_petsc.hpp Vector/Vector_util.hpp Vector/Vector.hpp \ +Solvers/umfpack_solver.hpp Solvers/petsc_solver.hpp \ +util/petsc_util.hpp util/linalgebra_lib.hpp util/util_num.hpp util/grid_dist_testing.hpp \ +FiniteDifference/Average.hpp FiniteDifference/Derivative.hpp FiniteDifference/eq.hpp FiniteDifference/FDScheme.hpp FiniteDifference/Laplacian.hpp FiniteDifference/mul.hpp FiniteDifference/sum.hpp FiniteDifference/util/common.hpp \ +PSE/Kernels.hpp PSE/Kernels_test_util.hpp Operators/Vector/vector_dist_operators_extensions.hpp Operators/Vector/vector_dist_operators.hpp Operators/Vector/vector_dist_operators_apply_kernel.hpp Operators/Vector/vector_dist_operators_functions.hpp Operators/Vector/vector_dist_operator_assign.hpp .cu.o : $(NVCC) $(NVCCFLAGS) -o $@ -c $< diff --git a/src/Matrix/SparseMatrix.hpp b/src/Matrix/SparseMatrix.hpp index 09d79567..0371e504 100644 --- a/src/Matrix/SparseMatrix.hpp +++ b/src/Matrix/SparseMatrix.hpp @@ -8,6 +8,9 @@ #ifndef OPENFPM_NUMERICS_SRC_MATRIX_SPARSEMATRIX_HPP_ #define OPENFPM_NUMERICS_SRC_MATRIX_SPARSEMATRIX_HPP_ +#include "config/config.h" +#include "util/linalgebra_lib.hpp" + #ifdef HAVE_EIGEN #include <Eigen/Sparse> #define DEFAULT_MATRIX = EIGEN_BASE @@ -93,7 +96,7 @@ public: openfpm::vector<triplet_type> & getMatrixTriplets() {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return stub_vt;} const int & getMat() const {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return stub_i;} int & getMat() {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return stub_i;} - void resize(size_t row, size_t col) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} + void resize(size_t row, size_t col, size_t row_n, size_t col_n) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} T operator()(id_t i, id_t j) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return stub_t;} bool save(const std::string & file) const {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;return true;} bool load(const std::string & file) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return false;} diff --git a/src/Matrix/SparseMatrix_Eigen.hpp b/src/Matrix/SparseMatrix_Eigen.hpp index c919690d..1786fd17 100644 --- a/src/Matrix/SparseMatrix_Eigen.hpp +++ b/src/Matrix/SparseMatrix_Eigen.hpp @@ -212,16 +212,13 @@ public: */ bool save(const std::string & file) const { - std::vector<size_t> pap_prp; + size_t pap_prp; Packer<decltype(trpl),HeapMemory>::packRequest(trpl,pap_prp); - // Calculate how much preallocated memory we need to pack all the objects - size_t req = ExtPreAlloc<HeapMemory>::calculateMem(pap_prp); - // allocate the memory HeapMemory pmem; - pmem.allocate(req); + pmem.allocate(pap_prp); ExtPreAlloc<HeapMemory> mem(pap_prp,pmem); //Packing diff --git a/src/Matrix/SparseMatrix_petsc.hpp b/src/Matrix/SparseMatrix_petsc.hpp index 1a9b6b21..d129624d 100644 --- a/src/Matrix/SparseMatrix_petsc.hpp +++ b/src/Matrix/SparseMatrix_petsc.hpp @@ -8,7 +8,7 @@ #ifndef OPENFPM_NUMERICS_SRC_MATRIX_SPARSEMATRIX_PETSC_HPP_ #define OPENFPM_NUMERICS_SRC_MATRIX_SPARSEMATRIX_PETSC_HPP_ - +#include "util/petsc_util.hpp" #include "Vector/map_vector.hpp" #include <boost/mpl/int.hpp> #include <petscmat.h> @@ -213,7 +213,8 @@ public: ~SparseMatrix() { // Destroy the matrix - PETSC_SAFE_CALL(MatDestroy(&mat)); + if (is_openfpm_init() == true) + {PETSC_SAFE_CALL(MatDestroy(&mat));} } /*! \brief Get the Matrix triplets bugger diff --git a/src/Matrix/SparseMatrix_unit_tests.hpp b/src/Matrix/SparseMatrix_unit_tests.hpp index 5a65fa41..7a9cedea 100644 --- a/src/Matrix/SparseMatrix_unit_tests.hpp +++ b/src/Matrix/SparseMatrix_unit_tests.hpp @@ -407,7 +407,7 @@ BOOST_AUTO_TEST_CASE(sparse_matrix_eigen_petsc_solve) } // Get the petsc Matrix - Mat & matp = sm.getMat(); + sm.getMat(); petsc_solver<double> solver; diff --git a/src/Operators/Vector/vector_dist_operators.hpp b/src/Operators/Vector/vector_dist_operators.hpp index a9b554b1..7adb7900 100644 --- a/src/Operators/Vector/vector_dist_operators.hpp +++ b/src/Operators/Vector/vector_dist_operators.hpp @@ -11,6 +11,7 @@ #include "Vector/vector_dist.hpp" #define PROP_POS (unsigned int)-1 +#define PROP_CUSTOM (unsigned int)-2 #define VECT_SUM 1 #define VECT_SUB 2 @@ -23,12 +24,9 @@ #define VECT_APPLYKER_IN_GEN 10 #define VECT_APPLYKER_OUT_GEN 11 #define VECT_APPLYKER_REDUCE_GEN 12 -#define VECT_APPLYKER_MULTI_IN 13 -#define VECT_APPLYKER_MULTI_OUT 14 -#define VECT_APPLYKER_MULTI_REDUCE 15 -#define VECT_APPLYKER_MULTI_IN_GEN 16 -#define VECT_APPLYKER_MULTI_OUT_GEN 17 -#define VECT_APPLYKER_MULTI_REDUCE_GEN 18 +#define VECT_APPLYKER_IN_SIM 13 +#define VECT_APPLYKER_OUT_SIM 14 +#define VECT_APPLYKER_REDUCE_SIM 15 #define VECT_NORM 56 #define VECT_NORM2 57 @@ -67,6 +65,8 @@ #define VECT_PMUL 91 #define VECT_SUB_UNI 92 +#define VECT_SUM_REDUCE 93 + /*! \brief has_init check if a type has defined a * method called init @@ -338,10 +338,25 @@ class vector_dist_expression public: + typedef vector vtype; + + //! Property id of the point + static const unsigned int prop = prp; + vector_dist_expression(vector & v) :v(v) {} + /*! \brief Return the vector on which is acting + * + * It return the vector used in getVExpr, to get this object + * + */ + vector & getVector() + { + return v; + } + /*! \brief This function must be called before value * * it initialize the expression if needed @@ -375,7 +390,7 @@ public: { auto key = it.get(); - v.template getProp<prp>(key) = v_exp.value(key); + pos_or_prop<vector,prp>::value(v,key) = v_exp.value(key); ++it; } @@ -383,7 +398,6 @@ public: return v; } - /*! \brief Fill the vector property with the evaluated expression * * \param v_exp expression to evaluate @@ -399,7 +413,7 @@ public: { auto key = it.get(); - v.template getProp<prp>(key) = v_exp.value(key); + pos_or_prop<vector,prp>::value(v,key) = v_exp.value(key); ++it; } @@ -420,7 +434,7 @@ public: { auto key = it.get(); - v.template getProp<prp>(key) = d; + pos_or_prop<vector,prp>::value(v,key) = d; ++it; } @@ -454,7 +468,7 @@ class vector_dist_expression<prp,double> public: - inline vector_dist_expression(double & d) + inline vector_dist_expression(const double & d) :d(d) {} @@ -477,6 +491,79 @@ public: } }; +/*! \brief Main class that encapsulate a float constant + * + * \param prp no meaning + * + */ +template<unsigned int prp> +class vector_dist_expression<prp,float> +{ + float d; + +public: + + typedef float vtype; + + inline vector_dist_expression(const float & d) + :d(d) + {} + + /*! \brief This function must be called before value + * + * it initialize the expression if needed + * + */ + inline void init() const + {} + + /*! \brief Evaluate the expression + * + * It just return the velue set in the constructor + * + */ + inline float value(const vect_dist_key_dx & k) const + { + return d; + } +}; + + + +/*! \brief Main class that encapsulate a float constant + * + * \param prp no meaning + * + */ +template<typename T> +class vector_dist_expression<PROP_CUSTOM,T> +{ + +public: + + typedef float vtype; + + inline vector_dist_expression() + {} + + /*! \brief This function must be called before value + * + * it initialize the expression if needed + * + */ + inline void init() const + {} + + /*! \brief Evaluate the expression + * + * It just return the velue set in the constructor + * + */ + inline T value(const vect_dist_key_dx & k) const + { + return T(0.0); + } +}; /* \brief sum two distributed vector expression * @@ -1010,5 +1097,6 @@ operator/(const vector_dist_expression_op<exp1,exp2,op1> & va, const vector_dist #include "vector_dist_operators_apply_kernel.hpp" #include "vector_dist_operators_functions.hpp" #include "vector_dist_operators_extensions.hpp" +#include "Operators/Vector/vector_dist_operator_assign.hpp" #endif /* OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_HPP_ */ diff --git a/src/Operators/Vector/vector_dist_operators_apply_kernel.hpp b/src/Operators/Vector/vector_dist_operators_apply_kernel.hpp index bd10cd81..59bbc478 100644 --- a/src/Operators/Vector/vector_dist_operators_apply_kernel.hpp +++ b/src/Operators/Vector/vector_dist_operators_apply_kernel.hpp @@ -35,6 +35,31 @@ struct apply_kernel_rtype<exp,false> }; +/*! \brief Meta-function to return a compatible zero-element + * + * + */ +template<typename rtype> +struct set_zero +{ + static rtype create() + { + return 0.0; + } +}; + +template<unsigned int dim, typename T> +struct set_zero<Point<dim,T>> +{ + static Point<dim,T> create() + { + Point<dim,T> ret; + + ret.zero(); + return ret; + } +}; + /*! \brief Apply the kernel to particle differently that is a number or is an expression * * @@ -42,10 +67,10 @@ struct apply_kernel_rtype<exp,false> template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype, bool is_exp=is_expression<T>::value> struct apply_kernel_is_number_or_expression { - inline static rtype apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker) + inline static typename std::remove_reference<rtype>::type apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker) { // accumulator - rtype pse = static_cast<rtype>(0.0); + typename std::remove_reference<rtype>::type pse = set_zero<typename std::remove_reference<rtype>::type>::create(); // position of particle p Point<vector::dims,typename vector::stype> p = vd.getPos(key); @@ -80,28 +105,21 @@ struct apply_kernel_is_number_or_expression } }; -template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype> -struct apply_kernel_is_number_or_expression<T,vector,exp,NN_type,Kernel,rtype,false> -{ - /*! \brief Apply the kernel - * - * \param cl Neighborhood of particles - * \param v_exp vector expression - * \param key particle id - * \param lker kernel function - * - */ - inline static rtype apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker) +/*! \brief Apply the kernel to particle differently that is a number or is an expression + * + * + */ +template<typename vector, typename exp,typename NN_type, typename Kernel, typename rtype> +struct apply_kernel_is_number_or_expression_sim +{ + inline static typename std::remove_reference<rtype>::type apply(const vector & vd, NN_type & cl, const vect_dist_key_dx & key, Kernel & lker) { // accumulator - rtype pse = 0; - - // Get f(x) at the position of the particle p - const rtype & prp_p = v_exp.value(key); + typename std::remove_reference<rtype>::type pse = set_zero<typename std::remove_reference<rtype>::type>::create(); // position of particle p - auto & p = vd.getPos(key); + Point<vector::dims,typename vector::stype> p = vd.getPos(key); // Get the neighborhood of the particle auto NN = cl.template getNNIterator<NO_CHECK>(cl.getCell(p)); @@ -113,16 +131,10 @@ struct apply_kernel_is_number_or_expression<T,vector,exp,NN_type,Kernel,rtype,fa // given by the Near particle, exclude itself if (nnp != key.getKey()) { - // Get f(x) at the position of the particle p - const rtype & prp_q = v_exp.value(nnp); - - // Get f(x) at the position of the particle - auto & q = vd.getPos(nnp); - - // W(x-y) - auto ker = lker.value(p,q,prp_p,prp_q); + // position of the particle q + Point<vector::dims,typename vector::stype> q = vd.getPos(nnp); - pse += ker; + pse += lker.value(p,q); } // Next particle @@ -134,6 +146,7 @@ struct apply_kernel_is_number_or_expression<T,vector,exp,NN_type,Kernel,rtype,fa }; + /*! \brief Apply the kernel to particle differently that is a number or is an expression * * @@ -141,64 +154,14 @@ struct apply_kernel_is_number_or_expression<T,vector,exp,NN_type,Kernel,rtype,fa template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype, bool is_exp=is_expression<T>::value> struct apply_kernel_is_number_or_expression_gen { - inline static rtype apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker) + inline static typename std::remove_reference<rtype>::type apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker) { // accumulator - rtype pse = static_cast<rtype>(0.0); - - // position of particle p - Point<vector::dims,typename vector::stype> p = vd.getPos(key); + typename std::remove_reference<rtype>::type pse = set_zero<typename std::remove_reference<rtype>::type>::create(); // property of the particle x rtype prp_p = v_exp.value(key); - // Get the neighborhood of the particle - auto NN = cl.template getNNIterator<NO_CHECK>(cl.getCell(p)); - while(NN.isNext()) - { - auto nnp = NN.get(); - - // Calculate contribution given by the kernel value at position p, - // given by the Near particle, exclude itself - if (nnp != key.getKey()) - { - // property of the particle x - rtype prp_q = v_exp.value(nnp); - - // position of the particle q - Point<vector::dims,typename vector::stype> q = vd.getPos(nnp); - - pse += lker.value(p,q,prp_p,prp_q); - } - - // Next particle - ++NN; - } - - return pse; - } -}; - -template<typename T, typename vector, typename exp,typename NN_type, typename Kernel, typename rtype> -struct apply_kernel_is_number_or_expression_gen<T,vector,exp,NN_type,Kernel,rtype,false> -{ - - /*! \brief Apply the kernel - * - * \param cl Neighborhood of particles - * \param v_exp vector expression - * \param key particle id - * \param lker kernel function - * - */ - inline static rtype apply(const vector & vd, NN_type & cl, const exp & v_exp, const vect_dist_key_dx & key, Kernel & lker) - { - // accumulator - rtype pse = 0; - - // Get f(x) at the position of the particle p - const rtype & prp_p = v_exp.value(key); - // position of particle p auto & p = vd.getPos(key); @@ -212,16 +175,10 @@ struct apply_kernel_is_number_or_expression_gen<T,vector,exp,NN_type,Kernel,rtyp // given by the Near particle, exclude itself if (nnp != key.getKey()) { - // Get f(x) at the position of the particle p - const rtype & prp_q = v_exp.value(nnp); - - // Get f(x) at the position of the particle - auto & q = vd.getPos(nnp); - - // W(x-y) - auto ker = lker.value(vd,p,q,prp_p,prp_q); + // property of the particle x + rtype prp_q = v_exp.value(nnp); - pse += ker; + pse += lker.value(key.getKey(),nnp,prp_p,prp_q,vd); } // Next particle @@ -232,6 +189,7 @@ struct apply_kernel_is_number_or_expression_gen<T,vector,exp,NN_type,Kernel,rtyp } }; + /*! \brief Apply kernel operation * * \tparam exp1 expression1 @@ -273,13 +231,12 @@ public: * \param key where to evaluate the expression * */ - inline rtype value(const vect_dist_key_dx & key) const + inline typename std::remove_reference<rtype>::type value(const vect_dist_key_dx & key) const { return apply_kernel_is_number_or_expression<decltype(o1.value(key)),vector_orig,exp1,NN,Kernel,rtype>::apply(vd,cl,o1,key,ker); } }; - /*! \brief Apply kernel operation * * \tparam exp1 expression1 @@ -287,59 +244,94 @@ public: * */ template <typename exp1,typename vector_type> -class vector_dist_expression_op<exp1,vector_type,VECT_APPLYKER_REDUCE> +class vector_dist_expression_op<exp1,vector_type,VECT_APPLYKER_IN_SIM> { typedef typename boost::mpl::at<vector_type,boost::mpl::int_<0>>::type NN; typedef typename boost::mpl::at<vector_type,boost::mpl::int_<1>>::type Kernel; typedef typename boost::mpl::at<vector_type,boost::mpl::int_<2>>::type vector_orig; - const exp1 o1; NN & cl; Kernel & ker; const vector_orig & vd; - typedef typename apply_kernel_rtype<decltype(o1.value(vect_dist_key_dx(0)))>::rtype rtype; + typedef typename apply_kernel_rtype<decltype(std::declval<Kernel>().value(Point<vector_orig::dims,typename vector_orig::stype>(0.0), Point<vector_orig::dims,typename vector_orig::stype>(0.0) ) )>::rtype rtype; - // calculated value - mutable rtype val; public: - vector_dist_expression_op(const exp1 & o1, NN & cl, Kernel & ker, const vector_orig & vd) - :o1(o1),cl(cl),ker(ker),vd(vd) + /*! \brief This function must be called before value + * + * it initialize the expression if needed + * + */ + inline void init() const + { + } + + vector_dist_expression_op(NN & cl, Kernel & ker, const vector_orig & vd) + :cl(cl),ker(ker),vd(vd) {} - /*! \brief Initialize the calculation + /*! \brief Evaluate the expression * + * \param key where to evaluate the expression * */ - void init() const + inline typename std::remove_reference<rtype>::type value(const vect_dist_key_dx & key) const { - val = 0.0; + return apply_kernel_is_number_or_expression_sim<vector_orig,exp1,NN,Kernel,rtype>::apply(vd,cl,key,ker); + } +}; + + +/*! \brief Apply kernel operation + * + * \tparam exp1 expression1 + * \tparam NN list + * + */ +template <typename exp1,typename vector_type> +class vector_dist_expression_op<exp1,vector_type,VECT_APPLYKER_IN_GEN> +{ + typedef typename boost::mpl::at<vector_type,boost::mpl::int_<0>>::type NN; + typedef typename boost::mpl::at<vector_type,boost::mpl::int_<1>>::type Kernel; + typedef typename boost::mpl::at<vector_type,boost::mpl::int_<2>>::type vector_orig; - auto it = vd.getDomainIterator(); + const exp1 o1; + NN & cl; + Kernel & ker; + const vector_orig & vd; - while (it.isNext()) - { - auto key = it.get(); + typedef typename apply_kernel_rtype<decltype(o1.value(vect_dist_key_dx(0)))>::rtype rtype; - val += apply_kernel_is_number_or_expression<decltype(o1.value(key)),vector_orig,exp1,NN,Kernel,rtype>::apply(vd,cl,o1,key,ker); +public: - ++it; - } + /*! \brief This function must be called before value + * + * it initialize the expression if needed + * + */ + inline void init() const + { + o1.init(); } + vector_dist_expression_op(const exp1 & o1, NN & cl, Kernel & ker, const vector_orig & vd) + :o1(o1),cl(cl),ker(ker),vd(vd) + {} + /*! \brief Evaluate the expression * * \param key where to evaluate the expression * */ - inline rtype value(const vect_dist_key_dx & key) const + inline typename std::remove_reference<rtype>::type value(const vect_dist_key_dx & key) const { - return val; + return apply_kernel_is_number_or_expression_gen<decltype(o1.value(key)),vector_orig,exp1,NN,Kernel,rtype>::apply(vd,cl,o1,key,ker); } }; + ///////////////////////////////////////////// Apply kernel operator //// //////////////////////////////////////////////////////////////////////// @@ -360,6 +352,7 @@ applyKernel_in(const vector_dist_expression_op<exp1,exp2,op1> & va, vector_type return exp_sum; } + /* \brief Apply kernel expression * * \param va vector expression one @@ -369,14 +362,69 @@ applyKernel_in(const vector_dist_expression_op<exp1,exp2,op1> & va, vector_type * */ template<typename exp1, typename exp2, unsigned int op1, typename NN, typename Kernel, typename vector_type> -inline vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_REDUCE> -applyKernel_reduce(const vector_dist_expression_op<exp1,exp2,op1> & va, vector_type & vd, NN & cl, Kernel & ker) +inline vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN_GEN> +applyKernel_in_gen(const vector_dist_expression_op<exp1,exp2,op1> & va, vector_type & vd, NN & cl, Kernel & ker) { - vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_REDUCE> exp_sum(va,cl,ker,vd); + vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN_GEN> exp_sum(va,cl,ker,vd); return exp_sum; } +//////////////////////////////////////// For vector expression /////////////////////// + +/* \brief Apply kernel expression + * + * \param va vector expression one + * \param vb vector expression two + * + * \return an object that encapsulate the expression + * + */ +template<unsigned int prp, typename NN, typename Kernel, typename vector_type> +inline vector_dist_expression_op<vector_dist_expression<prp,vector_type>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN> +applyKernel_in(const vector_dist_expression<prp,vector_type> & va, vector_type & vd, NN & cl, Kernel & ker) +{ + vector_dist_expression_op<vector_dist_expression<prp,vector_type>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN> exp_sum(va,cl,ker,vd); + + return exp_sum; +} + + +/* \brief Apply kernel expression + * + * \param va vector expression one + * \param vb vector expression two + * + * \return an object that encapsulate the expression + * + */ +template<unsigned int prp, typename NN, typename Kernel, typename vector_type> +inline vector_dist_expression_op<vector_dist_expression<prp,vector_type>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN_GEN> +applyKernel_in_gen(const vector_dist_expression<prp,vector_type> & va, vector_type & vd, NN & cl, Kernel & ker) +{ + vector_dist_expression_op<vector_dist_expression<prp,vector_type>,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN_GEN> exp_sum(va,cl,ker,vd); + + return exp_sum; +} + + +/* \brief Apply kernel expression + * + * \param va vector expression one + * \param vb vector expression two + * + * \return an object that encapsulate the expression + * + */ +template<typename NN, typename Kernel, typename vector_type> +inline vector_dist_expression_op<void,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN_SIM> +applyKernel_in_sim(vector_type & vd, NN & cl, Kernel & ker) +{ + vector_dist_expression_op<void,boost::mpl::vector<NN,Kernel,vector_type>,VECT_APPLYKER_IN_SIM> exp_sum(cl,ker,vd); + + return exp_sum; +} + #endif /* OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_APPLY_KERNEL_HPP_ */ diff --git a/src/Operators/Vector/vector_dist_operators_apply_kernel_unit_tests.hpp b/src/Operators/Vector/vector_dist_operators_apply_kernel_unit_tests.hpp index ff345fab..efd7ab9c 100644 --- a/src/Operators/Vector/vector_dist_operators_apply_kernel_unit_tests.hpp +++ b/src/Operators/Vector/vector_dist_operators_apply_kernel_unit_tests.hpp @@ -51,6 +51,9 @@ template <typename vector,typename Kernel, typename NN_type> bool check_values_a base2 += vd.template getProp<C>(p); + if (base1 != base2) + std::cout << "CAZZO " << base1 << " " << base2 << std::endl; + ret &= base1 == base2; ++it2; @@ -176,6 +179,58 @@ template <typename vector,typename Kernel, typename NN_type> bool check_values_a return ret; } +template <typename vector,typename Kernel, typename NN_type> bool check_values_apply_kernel3(vector & vd, Kernel & ker, NN_type & NN) +{ + bool ret = true; + auto it = vd.getDomainIterator(); + + // ### WIKI 13 ### + // + // Check that apply kernel work + // + auto it2 = vd.getDomainIterator(); + while (it2.isNext()) + { + Point<3,float> base2 = 0.0; + auto p = it2.get(); + + Point<3,float> xp = vd.getPos(p); + + Point<3,float> base1 = vd.template getProp<VA>(p); + + Point<3,float> prp_x = vd.template getProp<VC>(p); + + // For each neighborhood particle + auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p))); + + while (Np.isNext()) + { + // Neighborhood particle q + auto q = Np.get(); + + if (q == p.getKey()) {++Np; continue;}; + + // position q + Point<3,float> xq = vd.getPos(q); + + Point<3,float> prp_y = vd.template getProp<VC>(q); + + base2 += ker.value(xp,xq,prp_x,prp_y); + + ++Np; + } + + base2 += vd.template getProp<VC>(p); + + ret &= base1 == base2; + + ++it2; + } + + BOOST_REQUIRE_EQUAL(ret,true); + + return ret; +} template <typename vector,typename Kernel, typename NN_type> bool check_values_apply_kernel2_reduce(vector & vd, Kernel & ker, NN_type & NN) { @@ -238,6 +293,51 @@ template <typename vector,typename Kernel, typename NN_type> bool check_values_a return ret; } +template <typename vector,typename Kernel, typename NN_type> bool check_values_apply_kernel3_reduce(vector & vd, Kernel & ker, NN_type & NN, const Point<2,float> & p) +{ + bool ret = true; + auto it = vd.getDomainIterator(); + + Point<2,float> base2 = 0.0; + + auto it2 = vd.getDomainIterator(); + while (it2.isNext()) + { + auto p = it2.get(); + + Point<3,float> xp = vd.getPos(p); + + Point<2,float> ker_accu = 0.0; + + // For each neighborhood particle + auto Np = NN.template getNNIterator<NO_CHECK>(NN.getCell(vd.getPos(p))); + + while (Np.isNext()) + { + // Neighborhood particle q + auto q = Np.get(); + + if (q == p.getKey()) {++Np; continue;}; + + // position q + Point<3,float> xq = vd.getPos(q); + + ker_accu += ker.value(xp,xq); + + ++Np; + } + + base2 += ker_accu; + + ++it2; + } + + BOOST_REQUIRE_EQUAL(p.get(0),base2.get(0)); + BOOST_REQUIRE_EQUAL(p.get(1),base2.get(1)); + + return ret; +} + BOOST_AUTO_TEST_CASE( vector_dist_operators_apply_kernel_test ) { if (create_vcluster().getProcessingUnits() > 3) @@ -257,7 +357,6 @@ BOOST_AUTO_TEST_CASE( vector_dist_operators_apply_kernel_test ) vector_dist<3,float,aggregate<float,float,float,VectorS<3,float>,VectorS<3,float>,VectorS<3,float>,float>> vd(512,box,bc,ghost); auto vA = getV<A>(vd); - auto vB = getV<B>(vd); auto vC = getV<C>(vd); auto vVA = getV<VA>(vd); @@ -281,23 +380,34 @@ BOOST_AUTO_TEST_CASE( vector_dist_operators_apply_kernel_test ) vVA = applyKernel_in(2.0*vVC + vVB ,vd,cl,ker) + vVC; check_values_apply_kernel2(vd,ker,cl); - vA = applyKernel_reduce(vVC * vVB + norm(vVB),vd,cl,ker) + vC; + vA = rsum(applyKernel_in(vVC * vVB + norm(vVB),vd,cl,ker),vd) + vC; check_values_apply_kernel_reduce(vd,ker,cl); - vVA = applyKernel_reduce(2.0*vVC + vVB ,vd,cl,ker) + vVC; + vVA = rsum(applyKernel_in(2.0*vVC + vVB ,vd,cl,ker),vd) + vVC; check_values_apply_kernel2_reduce(vd,ker,cl); -/* vA = applyKernel_in_gen(vVC * vVB + norm(vVB),vd,cl,ker) + vC; + vA = applyKernel_in_gen(vVC * vVB + norm(vVB),vd,cl,ker) + vC; check_values_apply_kernel(vd,ker,cl); vVA = applyKernel_in_gen(2.0*vVC + vVB ,vd,cl,ker) + vVC; check_values_apply_kernel2(vd,ker,cl); - vA = applyKernel_reduce_gen(vVC * vVB + norm(vVB),vd,cl,ker) + vC; + vA = rsum(applyKernel_in_gen(vVC * vVB + norm(vVB),vd,cl,ker),vd) + vC; check_values_apply_kernel_reduce(vd,ker,cl); - vVA = applyKernel_reduce_gen(2.0*vVC + vVB ,vd,cl,ker) + vVC; - check_values_apply_kernel2_reduce(vd,ker,cl);*/ + vVA = rsum(applyKernel_in_gen(2.0*vVC + vVB ,vd,cl,ker),vd) + vVC; + check_values_apply_kernel2_reduce(vd,ker,cl); + + // Check it compile the code is the same + vVA = applyKernel_in_gen(vVC,vd,cl,ker) + vVC; + check_values_apply_kernel3(vd,ker,cl); + + vVA = applyKernel_in (vVC,vd,cl,ker) + vVC; + check_values_apply_kernel3(vd,ker,cl); + + // just check it compile + Point<2,float> p = rsum(applyKernel_in_sim(vd,cl,ker),vd).get(); + check_values_apply_kernel3_reduce(vd,ker,cl,p); } diff --git a/src/Operators/Vector/vector_dist_operators_functions.hpp b/src/Operators/Vector/vector_dist_operators_functions.hpp index c53919ba..c0d9dfb3 100644 --- a/src/Operators/Vector/vector_dist_operators_functions.hpp +++ b/src/Operators/Vector/vector_dist_operators_functions.hpp @@ -212,4 +212,76 @@ fun_name(double d, const vector_dist_expression_op<exp1,exp2,op1> & va)\ CREATE_VDIST_ARG2_FUNC(pmul,pmul,VECT_PMUL) + +////////// Special function reduce ///////////////////////// + + +template <typename exp1, typename vector_type> +class vector_dist_expression_op<exp1,vector_type,VECT_SUM_REDUCE> +{ + const exp1 o1; + + typedef typename apply_kernel_rtype<decltype(o1.value(vect_dist_key_dx(0)))>::rtype rtype; + + // calculated value + mutable typename std::remove_reference<rtype>::type val; + + const vector_type & vd; + +public: + + vector_dist_expression_op(const exp1 & o1, const vector_type & vd) + :o1(o1), vd(vd) + {} + + inline void init() const + { + o1.init(); + + val = 0.0; + + auto it = vd.getDomainIterator(); + + while (it.isNext()) + { + auto key = it.get(); + + val += o1.value(key); + + ++it; + } + } + + inline typename std::remove_reference<rtype>::type get() + { + init(); + return value(vect_dist_key_dx(0)); + } + + template<typename r_type= typename std::remove_reference<rtype>::type > inline r_type value(const vect_dist_key_dx & key) const + { + return val; + } +}; + + +template<typename exp1, typename exp2_, unsigned int op1, typename vector_type> +inline vector_dist_expression_op<vector_dist_expression_op<exp1,exp2_,op1>,vector_type,VECT_SUM_REDUCE> +rsum(const vector_dist_expression_op<exp1,exp2_,op1> & va, const vector_type & vd) +{ + vector_dist_expression_op<vector_dist_expression_op<exp1,exp2_,op1>,vector_type,VECT_SUM_REDUCE> exp_sum(va,vd); + + return exp_sum; +} + +template<unsigned int prp1, typename v1, typename vector_type> +inline vector_dist_expression_op<vector_dist_expression<prp1,v1>,vector_type,VECT_SUM_REDUCE> +rsum(const vector_dist_expression<prp1,v1> & va, const vector_type & vd) +{ + vector_dist_expression_op<vector_dist_expression<prp1,v1>,vector_type,VECT_SUM_REDUCE> exp_sum(va,vd); + + return exp_sum; +} + + #endif /* OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_FUNCTIONS_HPP_ */ diff --git a/src/Operators/Vector/vector_dist_operators_unit_tests.hpp b/src/Operators/Vector/vector_dist_operators_unit_tests.hpp index 208f7c83..7a0e9040 100644 --- a/src/Operators/Vector/vector_dist_operators_unit_tests.hpp +++ b/src/Operators/Vector/vector_dist_operators_unit_tests.hpp @@ -646,7 +646,8 @@ template <typename vector> void fill_values(vector & v) } } -typedef vector_dist<3,float,aggregate<float,float,float,VectorS<3,float>,VectorS<3,float>,VectorS<3,float>>> vector_type; + +typedef vector_dist<3,float,aggregate<float,float,float,VectorS<3,float>,VectorS<3,float>,VectorS<3,float>,float>> vector_type; //! Exponential kernel struct exp_kernel @@ -671,17 +672,37 @@ struct exp_kernel return (pA + pB) * exp(dist * dist / var); } - inline Point<3,float> value(vector_type & vd1, vector_type & vd2, size_t p, size_t q, float pA, float pB) + inline float value(size_t p, size_t q, float pA, float pB, const vector_type & vd1) { - float dist = norm(p-q); + Point<3,float> pp = vd1.getPos(p); + Point<3,float> pq = vd1.getPos(q); + + float dist = norm(pp-pq); return (pA + pB) * exp(dist * dist / var); } + + inline Point<3,float> value(size_t p, size_t q, const Point<3,float> & pA, const Point<3,float> & pB , const vector_type & vd1) + { + Point<3,float> pp = vd1.getPos(p); + Point<3,float> pq = vd1.getPos(q); + + float dist = norm(pp-pq); + + return (pA + pB) * exp(dist * dist / var); + } + + inline Point<2,float> value(const Point<3,float> & p, const Point<3,float> & q) + { + float dist = norm(p-q); + + return exp(dist * dist / var); + } }; //////////////////////////////////////////////////////////////////////////// -BOOST_AUTO_TEST_SUITE( vector_dist_test ) +BOOST_AUTO_TEST_SUITE( vector_dist_operators_test ) BOOST_AUTO_TEST_CASE( vector_dist_operators_test ) @@ -882,12 +903,12 @@ BOOST_AUTO_TEST_CASE( vector_dist_operators_test ) vA = norm(vPOS); vVA = vPOS + 2.0; vVA = 2.0 + vPOS; -// vVA = vPOS + vPOS; + vVA = vPOS + vPOS; vVA = vPOS - 2.0f; vVA = 2.0 - vPOS; -// vVA = vPOS - vPOS; + vVA = vPOS - vPOS; -/* vVA = vPOS * 2.0; + vVA = vPOS * 2.0; vVA = 2.0 * vPOS; vVA = vPOS * vPOS; @@ -914,11 +935,184 @@ BOOST_AUTO_TEST_CASE( vector_dist_operators_test ) vVA = vPOS / (vPOS + vPOS); vVA = (vPOS + vPOS) / vPOS; - vVA = (vPOS + vPOS) / (vPOS + vPOS);*/ + vVA = (vPOS + vPOS) / (vPOS + vPOS); } #include "vector_dist_operators_apply_kernel_unit_tests.hpp" +void reset(vector_dist<3,float,aggregate<float,float,float,float,float,float,float,float>> & v1) +{ + auto it = v1.getDomainIterator(); + + while (it.isNext()) + { + auto p = it.get(); + + v1.template getProp<0>(p) = -1.0; + v1.template getProp<1>(p) = -1.0; + v1.template getProp<2>(p) = -1.0; + v1.template getProp<3>(p) = -1.0; + v1.template getProp<4>(p) = -1.0; + v1.template getProp<5>(p) = -1.0; + v1.template getProp<6>(p) = -1.0; + v1.template getProp<7>(p) = -1.0; + + ++it; + } +} + +template<unsigned int i> void loop_check(vector_dist<3,float,aggregate<float,float,float,float,float,float,float,float>> & v1, float check) +{ + auto it = v1.getDomainIterator(); + bool ret = true; + + while (it.isNext()) + { + auto p = it.get(); + + ret &= v1.template getProp<i>(p) == check; + + ++it; + } + + BOOST_REQUIRE_EQUAL(ret,true); +} + +void check(vector_dist<3,float,aggregate<float,float,float,float,float,float,float,float>> & v1, size_t i) +{ + float check = -1.0; + + if (0 < i) check = 0.0; + else check = -1.0; + loop_check<0>(v1,check); + + if (1 < i) check = 1.0; + else check = -1.0; + loop_check<1>(v1,check); + + if (2 < i) check = 2.0; + else check = -1.0; + loop_check<2>(v1,check); + + if (3 < i) check = 3.0; + else check = -1.0; + loop_check<3>(v1,check); + + if (4 < i) check = 4.0; + else check = -1.0; + loop_check<4>(v1,check); + + if (5 < i) check = 5.0; + else check = -1.0; + loop_check<5>(v1,check); + + if (6 < i) check = 6.0; + else check = -1.0; + loop_check<6>(v1,check); + + if (7 < i) check = 7.0; + else check = -1.0; + loop_check<7>(v1,check); +} + +BOOST_AUTO_TEST_CASE( vector_dist_operators_assign_test ) +{ + if (create_vcluster().getProcessingUnits() > 3) + return; + + Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); + + // Boundary conditions + size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; + + // ghost + Ghost<3,float> ghost(0.05); + + // vector type + typedef vector_dist<3,float,aggregate<float,float,float,float,float,float,float,float>> vtype; + + vector_dist<3,float,aggregate<float,float,float,float,float,float,float,float>> vd(100,box,bc,ghost); + + auto v1 = getV<0>(vd); + auto v2 = getV<1>(vd); + auto v3 = getV<2>(vd); + auto v4 = getV<3>(vd); + auto v5 = getV<4>(vd); + auto v6 = getV<5>(vd); + auto v7 = getV<6>(vd); + auto v8 = getV<7>(vd); + + reset(vd); + + assign(v1,0.0, + v2,1.0); + + check(vd,2); + + reset(vd); + + assign(v1,0.0, + v2,1.0, + v3,2.0); + + check(vd,3); + + reset(vd); + + assign(v1,0.0, + v2,1.0, + v3,2.0, + v4,3.0); + + check(vd,4); + + reset(vd); + + assign(v1,0.0, + v2,1.0, + v3,2.0, + v4,3.0, + v5,4.0); + + check(vd,5); + + reset(vd); + + assign(v1,0.0, + v2,1.0, + v3,2.0, + v4,3.0, + v5,4.0, + v6,5.0); + + check(vd,6); + + reset(vd); + + assign(v1,0.0, + v2,1.0, + v3,2.0, + v4,3.0, + v5,4.0, + v6,5.0, + v7,6.0); + + check(vd,7); + + reset(vd); + + assign(v1,0.0, + v2,1.0, + v3,2.0, + v4,3.0, + v5,4.0, + v6,5.0, + v7,6.0, + v8,7.0); + + check(vd,8); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/Solvers/petsc_solver.hpp b/src/Solvers/petsc_solver.hpp index 04d0c91e..2a82cb2c 100644 --- a/src/Solvers/petsc_solver.hpp +++ b/src/Solvers/petsc_solver.hpp @@ -96,15 +96,6 @@ class petsc_solver<double> openfpm::vector<itError> res; }; - // KSP Relative tolerance -// PetscReal rtol; - - // KSP Absolute tolerance -// PetscReal abstol; - - // KSP dtol tolerance to determine that the method diverge -// PetscReal dtol; - // KSP Maximum number of iterations PetscInt maxits; @@ -227,7 +218,7 @@ class petsc_solver<double> yn.add(bench.get(i).smethod); } - size_t n_int = 300; + size_t n_int = maxits; // calculate dt @@ -303,18 +294,22 @@ class petsc_solver<double> itError erri(err); erri.it = it; - // - size_t old_size = pts->bench.last().res.size(); - pts->bench.last().res.resize(it+1); + itError err_fill; - if (old_size > 0) - { - for (size_t i = old_size ; i < it-1 ; i++) - pts->bench.last().res.get(i) = pts->bench.last().res.get(i-1); - } + size_t old_size = pts->bench.last().res.size(); + pts->bench.last().res.resize(it+1); + + if (old_size > 0) + err_fill = pts->bench.last().res.get(old_size-1); + else + err_fill = erri; + + for (long int i = old_size ; i < (long int)it ; i++) + pts->bench.last().res.get(i) = err_fill; + + // Add the error per iteration + pts->bench.last().res.get(it) = erri; - // Add the error per iteration - pts->bench.last().res.add(erri); pts->progress(it); @@ -683,7 +678,6 @@ class petsc_solver<double> void initKSP() { PETSC_SAFE_CALL(KSPCreate(PETSC_COMM_WORLD,&ksp)); -// PETSC_SAFE_CALL(KSPGetTolerances(ksp,&rtol,&abstol,&dtol,&maxits)); } /*! \brief initialize the KSP object for solver testing @@ -693,10 +687,8 @@ class petsc_solver<double> void initKSPForTest() { PETSC_SAFE_CALL(KSPCreate(PETSC_COMM_WORLD,&ksp)); -// PETSC_SAFE_CALL(KSPGetTolerances(ksp,&rtol,&abstol,&dtol,&maxits)); -// PETSC_SAFE_CALL(KSPSetTolerances(ksp,rtol,abstol,dtol,300)); - setMaxIter(300); + setMaxIter(maxits); // Disable convergence check PETSC_SAFE_CALL(KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL)); @@ -718,6 +710,7 @@ public: } petsc_solver() + :maxits(300) { initKSP(); @@ -725,7 +718,7 @@ public: solvs.add(std::string(KSPBCGS)); // solvs.add(std::string(KSPIBCGS)); <--- Produce invalid argument - solvs.add(std::string(KSPFBCGS)); +// solvs.add(std::string(KSPFBCGS)); // solvs.add(std::string(KSPFBCGSR)); <--- Nan production problems solvs.add(std::string(KSPBCGSL)); solvs.add(std::string(KSPGMRES)); @@ -831,6 +824,7 @@ public: void setMaxIter(PetscInt n) { PetscOptionsSetValue("-ksp_max_it",std::to_string(n).c_str()); + maxits = n; } /*! For the BiCGStab(L) it define the number of search directions diff --git a/src/Solvers/umfpack_solver.hpp b/src/Solvers/umfpack_solver.hpp index e1b1f4e1..8a05f0ce 100644 --- a/src/Solvers/umfpack_solver.hpp +++ b/src/Solvers/umfpack_solver.hpp @@ -28,9 +28,9 @@ class umfpack_solver { public: - template<typename impl> static Vector<T> solve(const SparseMatrix<T,impl> & A, const Vector<T> & b) + template<unsigned int impl, typename id_type> static Vector<T> solve(const SparseMatrix<T,id_type,impl> & A, const Vector<T> & b) { - std::cerr << "Error Umfpack only suppor double precision" << "/n"; + std::cerr << "Error Umfpack only support double precision, and int ad id type" << "/n"; } }; @@ -84,6 +84,9 @@ public: { // decomposition failed std::cout << __FILE__ << ":" << __LINE__ << " solver failed" << "\n"; + + x.scatter(); + return x; } @@ -136,7 +139,7 @@ class umfpack_solver<double> public: - template<typename impl> static Vector<double> solve(SparseMatrix<double,int,impl> & A, const Vector<double> & b, size_t opt = UMFPACK_NONE) + template<unsigned int impl, typename id_type> static Vector<double> solve(SparseMatrix<double,id_type,impl> & A, const Vector<double> & b, size_t opt = UMFPACK_NONE) { std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use umfpack you must compile OpenFPM with linear algebra support" << "/n"; diff --git a/src/Vector/Vector.hpp b/src/Vector/Vector.hpp index b11b131e..24ef44f6 100644 --- a/src/Vector/Vector.hpp +++ b/src/Vector/Vector.hpp @@ -8,6 +8,7 @@ #ifndef OPENFPM_NUMERICS_SRC_VECTOR_VECTOR_HPP_ #define OPENFPM_NUMERICS_SRC_VECTOR_VECTOR_HPP_ +#include "config/config.h" #include "util/linalgebra_lib.hpp" /*! \brief It store one row value of a vector @@ -43,11 +44,11 @@ class Vector public: Vector(const Vector<T> & v) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} - Vector(const Vector<T> && v) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} + Vector(Vector<T> && v) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} Vector(size_t n) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} Vector() {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} Vector(size_t n, size_t n_row_local) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} - void resize(size_t row) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} + void resize(size_t row, size_t row_n) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} void insert(size_t i, T val) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} inline T & insert(size_t i) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;return stub;} inline const T & insert(size_t i) const {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return stub;} @@ -56,7 +57,7 @@ public: void scatter() {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} void fromFile(std::string file) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl;} Vector<T> & operator=(const Vector<T> & v) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return *this;} - Vector<T> & operator=(const Vector<T> && v) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return *this;} + Vector<T> & operator=(Vector<T> && v) {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return *this;} int & getVec() {std::cerr << __FILE__ << ":" << __LINE__ << " Error in order to use this class you must compile OpenFPM with linear algebra support" << std::endl; return stub_i;} }; diff --git a/src/Vector/Vector_petsc.hpp b/src/Vector/Vector_petsc.hpp index d3b20416..b24981b8 100644 --- a/src/Vector/Vector_petsc.hpp +++ b/src/Vector/Vector_petsc.hpp @@ -131,18 +131,19 @@ public: * \param v vector to copy * */ - Vector(const Vector<T,PETSC_BASE> && v) + Vector(Vector<T,PETSC_BASE> && v) { this->operator=(v); } - /*! \brief Destoroy the vector + /*! \brief Destroy the vector * * */ ~Vector() { - PETSC_SAFE_CALL(VecDestroy(&v)); + if (is_openfpm_init() == true) + {PETSC_SAFE_CALL(VecDestroy(&v));} } /*! \brief Create a vector with n elements @@ -330,7 +331,7 @@ public: // Fill the index and construct the map size_t k = 0; - for (size_t i = low ; i < high ; i++) + for (size_t i = low ; i < (size_t)high ; i++) { row_val.template get<row_id>(k) = i; map[i] = k; @@ -358,7 +359,7 @@ public: * \param v vector to copy * */ - Vector<T,PETSC_BASE> & operator=(const Vector<T,PETSC_BASE> && v) + Vector<T,PETSC_BASE> & operator=(Vector<T,PETSC_BASE> && v) { map.swap(v.map); row_val.swap(v.row_val); -- GitLab