Commit 93325b47 authored by incardon's avatar incardon

Fixing interpolation test

parent 03f4261d
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#define CENTRAL_B_ONE_SIDE 1 #define CENTRAL_B_ONE_SIDE 1
#define FORWARD 2 #define FORWARD 2
#define BACKWARD 3 #define BACKWARD 3
#define CENTRAL_SYM 4
#include "util/mathutil.hpp" #include "util/mathutil.hpp"
#include "Vector/map_vector.hpp" #include "Vector/map_vector.hpp"
......
...@@ -234,7 +234,6 @@ private: ...@@ -234,7 +234,6 @@ private:
{ {
ke.eq = row - row_low * Sys_eqs::nvar; ke.eq = row - row_low * Sys_eqs::nvar;
ke.key = g_map.getGKey(it.get()); ke.key = g_map.getGKey(it.get());
ke.key -= pd.getKP1();
return ke; return ke;
} }
...@@ -378,19 +377,22 @@ private: ...@@ -378,19 +377,22 @@ private:
if (g_dst.is_staggered() == true) if (g_dst.is_staggered() == true)
std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid must be normal " << std::endl; std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid must be normal " << std::endl;
#ifdef SE_CLASS1 grid_key_dx<Grid_dst::dims> start;
grid_key_dx<Grid_dst::dims> stop;
if (g_map.getLocalDomainSize() != g_dst.getLocalDomainSize()) for (size_t i = 0 ; i < Grid_dst::dims ; i++)
std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid in size does not match the mapping grid" << std::endl; {
#endif start.set_d(i,pd.getLow(i));
stop.set_d(i,g_map.size(i) - pd.getHigh(i));
}
// sub-grid iterator over the grid map // sub-grid iterator over the grid map
auto g_map_it = g_map.getDomainIterator(); auto g_map_it = g_map.getSubDomainIterator(start,stop);
// Iterator over the destination grid // Iterator over the destination grid
auto g_dst_it = g_dst.getDomainIterator(); auto g_dst_it = g_dst.getDomainIterator();
while (g_map_it.isNext() == true) while (g_dst_it.isNext() == true)
{ {
typedef typename to_boost_vmpl<pos...>::type vid; typedef typename to_boost_vmpl<pos...>::type vid;
typedef boost::mpl::size<vid> v_size; typedef boost::mpl::size<vid> v_size;
...@@ -427,7 +429,88 @@ private: ...@@ -427,7 +429,88 @@ private:
* \param it_d iterator that define where you want to impose * \param it_d iterator that define where you want to impose
* *
*/ */
template<typename T, typename bop, typename iterator> void impose(const T & op , template<typename T, typename bop, typename iterator> void impose_dit(const T & op ,
bop num,
long int id ,
const iterator & it_d)
{
openfpm::vector<triplet> & trpl = A.getMatrixTriplets();
auto it = it_d;
grid_sm<Sys_eqs::dims,void> gs = g_map.getGridInfoVoid();
std::unordered_map<long int,float> cols;
// iterate all the grid points
while (it.isNext())
{
// get the position
auto key = it.get();
// Add padding
for (size_t i = 0 ; i < Sys_eqs::dims ; i++)
key.getKeyRef().set_d(i,key.getKeyRef().get(i) + pd.getLow(i));
// Calculate the non-zero colums
T::value(g_map,key,gs,spacing,cols,1.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() = g_map.template get<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;
// std::cout << "(" << trpl.last().row() << "," << trpl.last().col() << "," << trpl.last().value() << ")" << "\n";
}
// If does not have a diagonal entry put it to zero
if (is_diag == false)
{
trpl.add();
trpl.last().row() = g_map.template get<0>(key)*Sys_eqs::nvar + id;
trpl.last().col() = g_map.template get<0>(key)*Sys_eqs::nvar + id;
trpl.last().value() = 0.0;
}
b(g_map.template get<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;
}
}
/*! \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, bop num,
long int id , long int id ,
const iterator & it_d) const iterator & it_d)
...@@ -477,7 +560,6 @@ private: ...@@ -477,7 +560,6 @@ private:
b(g_map.template get<0>(key)*Sys_eqs::nvar + id) = num.get(key); b(g_map.template get<0>(key)*Sys_eqs::nvar + id) = num.get(key);
cols.clear(); cols.clear();
// std::cout << "\n";
// if SE_CLASS1 is defined check the position // if SE_CLASS1 is defined check the position
#ifdef SE_CLASS1 #ifdef SE_CLASS1
...@@ -674,7 +756,7 @@ public: ...@@ -674,7 +756,7 @@ public:
constant_b b(num); constant_b b(num);
impose(op,b,id,it); impose_git(op,b,id,it);
} }
...@@ -693,14 +775,14 @@ public: ...@@ -693,14 +775,14 @@ public:
* \param it_d iterator that define where you want to impose * \param it_d iterator that define where you want to impose
* *
*/ */
template<typename T> void impose(const T & op , template<typename T> void impose_dit(const T & op ,
typename Sys_eqs::stype num, typename Sys_eqs::stype num,
long int id , long int id ,
grid_dist_iterator_sub<Sys_eqs::dims,typename g_map_type::d_grid> it_d) grid_dist_iterator_sub<Sys_eqs::dims,typename g_map_type::d_grid> it_d)
{ {
constant_b b(num); constant_b b(num);
impose(op,b,id,it_d); impose_dit(op,b,id,it_d);
} }
/*! \brief Impose an operator /*! \brief Impose an operator
...@@ -718,14 +800,14 @@ public: ...@@ -718,14 +800,14 @@ public:
* \param it_d iterator that define where you want to impose * \param it_d iterator that define where you want to impose
* *
*/ */
template<unsigned int prp, typename T, typename b_term, typename iterator> void impose(const T & op , template<unsigned int prp, typename T, typename b_term, typename iterator> void impose_dit(const T & op ,
b_term & b_t, b_term & b_t,
long int id , long int id ,
const iterator & it_d) const iterator & it_d)
{ {
grid_b<b_term,prp> b(b_t); grid_b<b_term,prp> b(b_t);
impose(op,b,id,it_d); impose_dit(op,b,id,it_d);
} }
//! type of the sparse matrix //! type of the sparse matrix
......
...@@ -125,4 +125,77 @@ public: ...@@ -125,4 +125,77 @@ public:
}; };
/*! \brief Laplacian second order approximation CENTRAL Scheme (with central derivative in the single)
*
* \verbatim
1.0
*
| -4.0
1.0 *---+---* 1.0
|
*
1.0
* \endverbatim
*
*
*/
template<typename arg, typename Sys_eqs>
class Lap<arg,Sys_eqs,CENTRAL_SYM>
{
public:
/*! \brief Calculate which colums of the Matrix are non zero
*
* stub_or_real it is just for change the argument type when testing, in normal
* conditions it is a distributed map
*
* \param pos position where the laplacian is calculated
* \param gs Grid info
* \param cols non-zero colums calculated by the function
* \param coeff coefficent (constant in front of the derivative)
*
* ### Example
*
* \snippet FDScheme_unit_tests.hpp Laplacian usage
*
*/
inline static void value(const typename stub_or_real<Sys_eqs,Sys_eqs::dims,typename Sys_eqs::stype,typename Sys_eqs::b_grid::decomposition::extended_type>::type & g_map, grid_dist_key_dx<Sys_eqs::dims> & kmap , const grid_sm<Sys_eqs::dims,void> & gs, typename Sys_eqs::stype (& spacing )[Sys_eqs::dims] , std::unordered_map<long int,typename Sys_eqs::stype > & cols, typename Sys_eqs::stype coeff)
{
// for each dimension
for (size_t i = 0 ; i < Sys_eqs::dims ; i++)
{
long int old_val = kmap.getKeyRef().get(i);
kmap.getKeyRef().set_d(i, kmap.getKeyRef().get(i) + 2);
arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[i]/spacing[i]/4.0);
kmap.getKeyRef().set_d(i,old_val);
old_val = kmap.getKeyRef().get(i);
kmap.getKeyRef().set_d(i, kmap.getKeyRef().get(i) - 2);
arg::value(g_map,kmap,gs,spacing,cols,coeff/spacing[i]/spacing[i]/4.0);
kmap.getKeyRef().set_d(i,old_val);
arg::value(g_map,kmap,gs,spacing,cols, - 2.0 * coeff/spacing[i]/spacing[i]/4.0);
}
}
/*! \brief Calculate the position where the derivative is calculated
*
* In case of non staggered case this function just return a null grid_key, in case of staggered,
* the CENTRAL Laplacian scheme return the position of the staggered property
*
* \param position where we are calculating the derivative
* \param gs Grid info
* \param s_pos staggered position of the properties
*
*/
inline static grid_key_dx<Sys_eqs::dims> position(grid_key_dx<Sys_eqs::dims> & pos, const grid_sm<Sys_eqs::dims,void> & gs, const comb<Sys_eqs::dims> (& s_pos)[Sys_eqs::nvar])
{
return arg::position(pos,gs,s_pos);
}
};
#endif /* OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_LAPLACIAN_HPP_ */ #endif /* OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_LAPLACIAN_HPP_ */
...@@ -696,8 +696,11 @@ class petsc_solver<double> ...@@ -696,8 +696,11 @@ class petsc_solver<double>
public: public:
typedef Vector<double,PETSC_BASE> return_type;
~petsc_solver() ~petsc_solver()
{ {
PETSC_SAFE_CALL(KSPDestroy(&ksp));
} }
petsc_solver() petsc_solver()
...@@ -850,8 +853,14 @@ public: ...@@ -850,8 +853,14 @@ public:
* *
* \tparam impl Implementation of the SparseMatrix * \tparam impl Implementation of the SparseMatrix
* *
* \param A sparse matrix
* \param b vector
* \param initial_guess true if x has the initial guess
*
* \return the solution
*
*/ */
Vector<double,PETSC_BASE> solve(SparseMatrix<double,int,PETSC_BASE> & A, const Vector<double,PETSC_BASE> & b) Vector<double,PETSC_BASE> solve(SparseMatrix<double,int,PETSC_BASE> & A, const Vector<double,PETSC_BASE> & b, bool initial_guess = false)
{ {
Mat & A_ = A.getMat(); Mat & A_ = A.getMat();
const Vec & b_ = b.getVec(); const Vec & b_ = b.getVec();
...@@ -864,6 +873,7 @@ public: ...@@ -864,6 +873,7 @@ public:
PETSC_SAFE_CALL(MatGetSize(A_,&row,&col)); PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc)); PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));
PETSC_SAFE_CALL(KSPSetInitialGuessNonzero(ksp,PETSC_FALSE));
Vector<double,PETSC_BASE> x(row,row_loc); Vector<double,PETSC_BASE> x(row,row_loc);
Vec & x_ = x.getVec(); Vec & x_ = x.getVec();
...@@ -876,6 +886,49 @@ public: ...@@ -876,6 +886,49 @@ public:
x.update(); x.update();
return x; return x;
} }
/*! \brief Here we invert the matrix and solve the system
*
* \warning umfpack is not a parallel solver, this function work only with one processor
*
* \note if you want to use umfpack in a NON parallel, but on a distributed data, use solve with triplet
*
* \tparam impl Implementation of the SparseMatrix
*
* \param A sparse matrix
* \param b vector
* \param x solution and initial guess
* \param initial_guess true if x has the initial guess
*
* \return true if succeed
*
*/
bool solve(SparseMatrix<double,int,PETSC_BASE> & A, Vector<double,PETSC_BASE> & x, const Vector<double,PETSC_BASE> & b)
{
Mat & A_ = A.getMat();
const Vec & b_ = b.getVec();
// We set the size of x according to the Matrix A
PetscInt row;
PetscInt col;
PetscInt row_loc;
PetscInt col_loc;
PETSC_SAFE_CALL(MatGetSize(A_,&row,&col));
PETSC_SAFE_CALL(MatGetLocalSize(A_,&row_loc,&col_loc));
PETSC_SAFE_CALL(KSPSetInitialGuessNonzero(ksp,PETSC_TRUE));
Vec & x_ = x.getVec();
if (try_solve == true)
try_solve_simple(A_,b_,x_);
else
solve_simple(A_,b_,x_);
x.update();
return true;
}
}; };
#endif #endif
......
...@@ -100,7 +100,8 @@ class Vector<T,PETSC_BASE> ...@@ -100,7 +100,8 @@ class Vector<T,PETSC_BASE>
*/ */
void setPetsc() const void setPetsc() const
{ {
PETSC_SAFE_CALL(VecSetFromOptions(v)); if (v_created == false)
{PETSC_SAFE_CALL(VecSetType(v,VECMPI));}
// set the vector // set the vector
...@@ -366,6 +367,18 @@ public: ...@@ -366,6 +367,18 @@ public:
return *this; return *this;
} }
/*! \brief Set to zero all the entries
*
*
*/
void setZero()
{
if (v_created == false)
{PETSC_SAFE_CALL(VecSetType(v,VECMPI));}
v_created = true;
}
}; };
......
...@@ -314,7 +314,7 @@ public: ...@@ -314,7 +314,7 @@ public:
} }
} }
template<unsigned int prp_v, unsigned int prp_g> void m2p(grid & gd, vector & vd) template<unsigned int prp_g, unsigned int prp_v> void m2p(grid & gd, vector & vd)
{ {
#ifdef SE_CLASS1 #ifdef SE_CLASS1
......
...@@ -154,6 +154,10 @@ BOOST_AUTO_TEST_CASE( interpolation_full_test ) ...@@ -154,6 +154,10 @@ BOOST_AUTO_TEST_CASE( interpolation_full_test )
BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001); BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001); BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
// Do a ghost put
auto & v_cl = create_vcluster();
// We have to do a ghost get before interpolating m2p // We have to do a ghost get before interpolating m2p
// Before doing mesh to particle particle must be arranged // Before doing mesh to particle particle must be arranged
// into a grid like // into a grid like
...@@ -191,14 +195,14 @@ BOOST_AUTO_TEST_CASE( interpolation_full_test ) ...@@ -191,14 +195,14 @@ BOOST_AUTO_TEST_CASE( interpolation_full_test )
gd.ghost_get<0>(); gd.ghost_get<0>();
grid_key_dx<2> start({3,3}); grid_key_dx<2> start({3,3});
grid_key_dx<2> stop({(long int)gd.size(0) - 3,(long int)gd.size(1) - 3}); grid_key_dx<2> stop({(long int)gd.size(0) - 4,(long int)gd.size(1) - 4});
auto it6 = gd.getSubDomainIterator(start,stop); auto it6 = gd.getSubDomainIterator(start,stop);
while(it6.isNext()) while(it6.isNext())
{ {
auto key = it6.get(); auto key = it6.get();
gd.get<0>(key) = (double)rand()/RAND_MAX;; gd.get<0>(key) = 5.0/*(double)rand()/RAND_MAX;*/;
++it6; ++it6;
} }
...@@ -211,18 +215,36 @@ BOOST_AUTO_TEST_CASE( interpolation_full_test ) ...@@ -211,18 +215,36 @@ BOOST_AUTO_TEST_CASE( interpolation_full_test )
momenta_grid_domain<decltype(gd),0>(gd,mg); momenta_grid_domain<decltype(gd),0>(gd,mg);
momenta_vector<decltype(vd),0>(vd,mv); momenta_vector<decltype(vd),0>(vd,mv);
v_cl.sum(mg[0]);
v_cl.sum(mg[1]);
v_cl.sum(mv[0]);
v_cl.sum(mv[1]);
v_cl.execute();
BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001); BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001); BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
momenta_grid_domain<decltype(gd),1>(gd,mg); momenta_grid_domain<decltype(gd),1>(gd,mg);
momenta_vector<decltype(vd),1>(vd,mv); momenta_vector<decltype(vd),1>(vd,mv);
v_cl.sum(mg[0]);
v_cl.sum(mg[1]);
v_cl.sum(mv[0]);
v_cl.sum(mv[1]);
v_cl.execute();
BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001); BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001); BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
momenta_grid_domain<decltype(gd),2>(gd,mg); momenta_grid_domain<decltype(gd),2>(gd,mg);
momenta_vector<decltype(vd),2>(vd,mv); momenta_vector<decltype(vd),2>(vd,mv);
v_cl.sum(mg[0]);
v_cl.sum(mg[1]);
v_cl.sum(mv[0]);
v_cl.sum(mv[1]);
v_cl.execute();
BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001); BOOST_REQUIRE_CLOSE(mg[0],mv[0],0.001);
BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001); BOOST_REQUIRE_CLOSE(mg[1],mv[1],0.001);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment