Skip to content
Snippets Groups Projects
Commit ab6ab5bb authored by Pietro Incardona's avatar Pietro Incardona
Browse files

Added p2m and m2p for interpolation

parent a52a73e5
No related branches found
No related tags found
No related merge requests found
......@@ -134,6 +134,38 @@ public:
private:
// Encapsulation of the b term as constant
struct constant_b
{
typename Sys_eqs::stype scal;
constant_b(typename Sys_eqs::stype scal)
{
this->scal = scal;
}
typename Sys_eqs::stype get(grid_dist_key_dx<Sys_eqs::dims> & key)
{
return scal;
}
};
// Encapsulation of the b term as grid
template<typename grid, unsigned int prp>
struct grid_b
{
grid & gr;
grid_b(grid & gr)
:gr(gr)
{}
typename Sys_eqs::stype get(grid_dist_key_dx<Sys_eqs::dims> & key)
{
return gr.template get<prp>(key);
}
};
//! Padding
Padding<Sys_eqs::dims> pd;
......@@ -247,34 +279,36 @@ private:
nz_rows.resize(row_b);
for (size_t i = 0 ; i < trpl.size() ; i++)
{
nz_rows.get(trpl.get(i).row()) = true;
}
nz_rows.get(trpl.get(i).row() - s_pnt*Sys_eqs::nvar) = true;
// Indicate all the non zero colums
openfpm::vector<unsigned> nz_cols;
nz_cols.resize(row_b);
// This check can be done only on single processor
for (size_t i = 0 ; i < trpl.size() ; i++)
Vcluster & v_cl = create_vcluster();
if (v_cl.getProcessingUnits() == 1)
{
nz_cols.get(trpl.get(i).col()) = true;
}
openfpm::vector<unsigned> nz_cols;
nz_cols.resize(row_b);
// 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)
for (size_t i = 0 ; i < trpl.size() ; i++)
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++)
{
key_and_eq ke = from_row_to_key(i);
std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix row " << i << " is not filled, position " << ke.key.to_string() << " equation: " << ke.eq << "\n";
if (nz_rows.get(i) == false)
{
key_and_eq ke = from_row_to_key(i);
std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix row " << i << " is not filled, position " << ke.key.to_string() << " equation: " << ke.eq << "\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";
// 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";
}
}
}
......@@ -328,6 +362,178 @@ private:
}
}
/*! \brief Copy a given solution vector in a normal grid
*
* \tparam Vct Vector type
* \tparam Grid_dst target grid
* \tparam pos set of property
*
* \param v Vector
* \param g_dst target normal grid
*
*/
template<typename Vct, typename Grid_dst ,unsigned int ... pos> void copy_normal(Vct & v, Grid_dst & g_dst)
{
// check that g_dst is staggered
if (g_dst.is_staggered() == true)
std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid must be normal " << std::endl;
#ifdef SE_CLASS1
if (g_map.getLocalDomainSize() != g_dst.getLocalDomainSize())
std::cerr << __FILE__ << ":" << __LINE__ << " The destination grid in size does not match the mapping grid" << std::endl;
#endif
// sub-grid iterator over the grid map
auto g_map_it = g_map.getDomainIterator();
// Iterator over the destination grid
auto g_dst_it = g_dst.getDomainIterator();
while (g_map_it.isNext() == true)
{
typedef typename to_boost_vmpl<pos...>::type vid;
typedef boost::mpl::size<vid> v_size;
auto key_src = g_map_it.get();
size_t lin_id = g_map.template get<0>(key_src);
// destination point
auto key_dst = g_dst_it.get();
// Transform this id into an id for the vector
copy_ele<Sys_eqs_typ, Grid_dst,Vct> cp(key_dst,g_dst,v,lin_id,g_map.size());
boost::mpl::for_each_ref<boost::mpl::range_c<int,0,v_size::value>>(cp);
++g_map_it;
++g_dst_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(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();
// 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();
// std::cout << "\n";
// if SE_CLASS1 is defined check the position
#ifdef SE_CLASS1
// T::position(key,gs,s_pos);
#endif
++row;
++row_b;
++it;
}
}
/*! \brief Construct the gmap structure
*
*/
void construct_gmap()
{
Vcluster & v_cl = create_vcluster();
// Calculate the size of the local domain
size_t sz = g_map.getLocalDomainSize();
// 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);
// resize b if needed
b.resize(Sys_eqs::nvar * g_map.size(),Sys_eqs::nvar * sz);
// Calculate the starting point
// Counter
size_t cnt = 0;
// Create the re-mapping grid
auto it = g_map.getDomainIterator();
while (it.isNext())
{
auto key = it.get();
g_map.template get<0>(key) = cnt + s_pnt;
++cnt;
++it;
}
// sync the ghost
g_map.template ghost_get<0>();
}
public:
/*! \brief set the staggered position for each property
......@@ -382,12 +588,14 @@ public:
}
/*! \brief Constructor
*
* The periodicity is given by the grid b_g
*
* \param pd Padding, how many points out of boundary are present
* \param stencil how many ghost points are required for this calculation
* \param stencil maximum extension of the stencil on each directions
* \param domain the domain
* \param gs grid infos where Finite differences work
* \param b_g maximum extension of the stencil on each directions
* \param b_g Finite difference grid (it is not important what it contain only its decomposition is used)
*
*/
FDScheme(Padding<Sys_eqs::dims> & pd,
......@@ -397,49 +605,18 @@ public:
const typename Sys_eqs::b_grid & b_g)
:pd(pd),gs(gs),g_map(b_g,stencil,pd),row(0),row_b(0)
{
Vcluster & v_cl = b_g.getDecomposition().getVC();
// Calculate the size of the local domain
size_t sz = g_map.getLocalDomainSize();
// 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);
// resize b if needed
b.resize(Sys_eqs::nvar * g_map.size(),Sys_eqs::nvar * sz);
// Calculate the starting point
// Counter
size_t cnt = 0;
// Create the re-mapping grid
auto it = g_map.getDomainIterator();
while (it.isNext())
{
auto key = it.get();
g_map.template get<0>(key) = cnt + s_pnt;
++cnt;
++it;
}
// sync the ghost
g_map.template ghost_get<0>();
construct_gmap();
// Create a CellDecomposer and calculate the spacing
size_t sz_g[Sys_eqs::dims];
for (size_t i = 0 ; i < Sys_eqs::dims ; i++)
sz_g[i] = gs.getSize()[i] - 1;
{
if (Sys_eqs::boundary[i] == NON_PERIODIC)
sz_g[i] = gs.getSize()[i] - 1;
else
sz_g[i] = gs.getSize()[i];
}
CellDecomposer_sm<Sys_eqs::dims,typename Sys_eqs::stype> cd(domain,sz_g,0);
......@@ -495,7 +672,9 @@ public:
if (increment == true)
++it;
impose(op,num,id,it);
constant_b b(num);
impose(op,b,id,it);
}
......@@ -514,64 +693,39 @@ 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)
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)
{
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();
// 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;
constant_b b(num);
cols.clear();
// std::cout << "\n";
impose(op,b,id,it_d);
}
// if SE_CLASS1 is defined check the position
#ifdef SE_CLASS1
// T::position(key,gs,s_pos);
#endif
/*! \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<unsigned int prp, typename T, typename b_term, typename iterator> void impose(const T & op ,
b_term & b_t,
long int id ,
const iterator & it_d)
{
grid_b<b_term,prp> b(b_t);
++row;
++row_b;
++it;
}
impose(op,b,id,it_d);
}
//! type of the sparse matrix
......@@ -587,7 +741,9 @@ public:
#ifdef SE_CLASS1
consistency();
#endif
A.resize(g_map.size()*Sys_eqs::nvar,g_map.size()*Sys_eqs::nvar,g_map.getLocalDomainSize()*Sys_eqs::nvar,g_map.getLocalDomainSize()*Sys_eqs::nvar);
A.resize(g_map.size()*Sys_eqs::nvar,g_map.size()*Sys_eqs::nvar,
g_map.getLocalDomainSize()*Sys_eqs::nvar,
g_map.getLocalDomainSize()*Sys_eqs::nvar);
return A;
......@@ -632,7 +788,17 @@ public:
{
// Create a temporal staggered grid and copy the data there
auto & g_map = this->getMap();
staggered_grid_dist<Grid_dst::dims,typename Grid_dst::stype,typename Grid_dst::value_type,typename Grid_dst::decomposition::extended_type, typename Grid_dst::memory_type, typename Grid_dst::device_grid_type> stg(g_dst,g_map.getDecomposition().getGhost(),this->getPadding());
// Convert the ghost in grid units
Ghost<Grid_dst::dims,long int> g_int;
for (size_t i = 0 ; i < Grid_dst::dims ; i++)
{
g_int.setLow(i,g_map.getDecomposition().getGhost().getLow(i) / g_map.spacing(i));
g_int.setHigh(i,g_map.getDecomposition().getGhost().getHigh(i) / g_map.spacing(i));
}
staggered_grid_dist<Grid_dst::dims,typename Grid_dst::stype,typename Grid_dst::value_type,typename Grid_dst::decomposition::extended_type, typename Grid_dst::memory_type, typename Grid_dst::device_grid_type> stg(g_dst,g_int,this->getPadding());
stg.setDefaultStagPosition();
copy_staggered<Vct,decltype(stg),pos...>(v,stg);
......@@ -641,6 +807,10 @@ public:
stg.template to_normal<Grid_dst,pos...>(g_dst,this->getPadding(),start,stop);
}
}
else
{
copy_normal<Vct,Grid_dst,pos...>(v,g_dst);
}
}
};
......
......@@ -12,7 +12,8 @@ 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 \
Draw/DrawParticles.hpp Draw/PointIterator.hpp Draw/PointIteratorSkin.hpp
Draw/DrawParticles.hpp Draw/PointIterator.hpp Draw/PointIteratorSkin.hpp \
interpolation/interpolation.hpp interpolation/mp4_kernel.hpp interpolation/z_spline.hpp
.cu.o :
$(NVCC) $(NVCCFLAGS) -o $@ -c $<
......
......@@ -103,31 +103,36 @@ public:
private:
// Size of the matrix
//! Number of matrix row (global)
size_t g_row;
//! Number of matrix colums (global)
size_t g_col;
// Local size of the matrix
//! Number of matrix row (local)
size_t l_row;
//! Number of matrix colums (local)
size_t l_col;
// starting row for this processor
//! starting row for this processor
size_t start_row;
// indicate if the matrix has been created
//! indicate if the matrix has been created
bool m_created = false;
// PETSC Matrix
//! PETSC Matrix
Mat mat;
//! Triplets of the matrix
openfpm::vector<triplet_type> trpl;
openfpm::vector<triplet_type> trpl_recv;
// temporary list of values
//! temporary list of values
mutable openfpm::vector<PetscScalar> vals;
// temporary list of colums
//! temporary list of colums
mutable openfpm::vector<PetscInt> cols;
// PETSC d_nnz and o_nnz
//! PETSC d_nnz
mutable openfpm::vector<PetscInt> d_nnz;
//! PETSC o_nnz
mutable openfpm::vector<PetscInt> o_nnz;
/*! \brief Fill the petsc Matrix
......@@ -152,7 +157,7 @@ private:
{
PetscInt row = trpl.get(i).row();
while(row == trpl.get(i).row() && i < trpl.size())
while(i < trpl.size() && row == trpl.get(i).row())
{
if ((size_t)trpl.get(i).col() >= start_row && (size_t)trpl.get(i).col() < start_row + l_row)
d_nnz.get(row - start_row)++;
......@@ -176,7 +181,7 @@ private:
PetscInt row = trpl.get(i).row();
while(row == trpl.get(i).row() && i < trpl.size())
while(i < trpl.size() && row == trpl.get(i).row())
{
vals.add(trpl.get(i).value());
cols.add(trpl.get(i).col());
......@@ -237,7 +242,7 @@ public:
{PETSC_SAFE_CALL(MatDestroy(&mat));}
}
/*! \brief Get the Matrix triplets bugger
/*! \brief Get the Matrix triplets buffer
*
* It return a buffer that can be filled with triplets
*
......
......@@ -16,6 +16,8 @@
#include <petscksp.h>
#include <petsctime.h>
#include "Plot/GoogleChart.hpp"
#include "Matrix/SparseMatrix.hpp"
#include "Vector/Vector.hpp"
#define UMFPACK_NONE 0
......
......@@ -16,3 +16,4 @@
#include "PSE/Kernels_unit_tests.hpp"
#include "Operators/Vector/vector_dist_operators_unit_tests.hpp"
#include "Draw/DrawParticles_unit_tests.hpp"
#include "interpolation/interpolation_unit_tests.hpp"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment