diff --git a/images/Makefile.am b/images/Makefile.am index 62b67035a449140148e57b9baf38032dfe91a1b9..4634f73c345017c981ad1820beae52fbfad84140 100644 --- a/images/Makefile.am +++ b/images/Makefile.am @@ -48,6 +48,7 @@ images : cart_dec metis_dec dom_box pvbatch vector_scal_vect.py pvbatch vector_particles.py pvbatch particles_maps.py + pvbatch vector_ghost.py dot -Tsvg openfpm.dot -o generated/openfpm.svg avconv -i generated/particles_mooving.ogv -f mp4 generated/particles_mooving.mp4 avconv -i generated/particles_mooving_prc.ogv -f mp4 generated/particles_mooving_prc.mp4 diff --git a/images/vector.cpp b/images/vector.cpp index 70395b09008a7156d19bc03aceaca8b95f9992b8..a1dddd3100fb48e0edededc1d821c14b8c029a20 100644 --- a/images/vector.cpp +++ b/images/vector.cpp @@ -61,6 +61,10 @@ int main(int argc, char* argv[]) vd.write("Vector/vector_after_map"); + vd.ghost_get<0>(); + + vd.write("Vector/vector_ghost_fill"); + vd.getDecomposition().write("Vector/vect_decomposition"); // move the particles diff --git a/images/vector_ghost.py b/images/vector_ghost.py new file mode 100644 index 0000000000000000000000000000000000000000..bc1c2d78e5da027c510b2707099706b5cc3bbbe8 --- /dev/null +++ b/images/vector_ghost.py @@ -0,0 +1,216 @@ +#### import the simple module from the paraview +from paraview.simple import * +#### disable automatic camera reset on 'Show' +paraview.simple._DisableFirstRenderCameraReset() + +# create a new 'CSV Reader' +vector_ghost_fill = CSVReader(FileName=['Vector/vector_ghost_fill0.csv']) + +# get animation scene +animationScene1 = GetAnimationScene() + +# update animation scene based on data timesteps +animationScene1.UpdateAnimationUsingDataTimeSteps() + +# get active view +renderView1 = GetActiveViewOrCreate('RenderView') +# uncomment following to set a specific view size +renderView1.ViewSize = [400, 400] + +# get layout +viewLayout1 = GetLayout() + +# Create a new 'SpreadSheet View' +spreadSheetView1 = CreateView('SpreadSheetView') +spreadSheetView1.BlockSize = 1024L +# uncomment following to set a specific view size +# spreadSheetView1.ViewSize = [400, 400] + +# place view in the layout +viewLayout1.AssignView(2, spreadSheetView1) + +# show data in view +vector_ghost_fillDisplay = Show(vector_ghost_fill, spreadSheetView1) + +# destroy spreadSheetView1 +Delete(spreadSheetView1) +del spreadSheetView1 + +# close an empty frame +viewLayout1.Collapse(2) + +# set active view +SetActiveView(renderView1) + +# create a new 'Table To Points' +tableToPoints1 = TableToPoints(Input=vector_ghost_fill) + +# Properties modified on tableToPoints1 +tableToPoints1.XColumn = 'x[0]' +tableToPoints1.YColumn = 'x[1]' +tableToPoints1.a2DPoints = 1 + +# show data in view +#tableToPoints1Display = Show(tableToPoints1, renderView1) + +# reset view to fit data +renderView1.ResetCamera() + +#changing interaction mode based on data extents +renderView1.InteractionMode = '2D' +renderView1.CameraPosition = [0.499922575, 0.18749537000000002, 10000.0] +renderView1.CameraFocalPoint = [0.499922575, 0.18749537000000002, 0.0] + +# create a new 'Legacy VTK Reader' +vect_decompositionexternal_ghost_0vtk = LegacyVTKReader(FileNames=['Vector/vect_decompositionexternal_ghost_0.vtk']) + +# destroy vect_decompositionexternal_ghost_0vtk +Delete(vect_decompositionexternal_ghost_0vtk) +del vect_decompositionexternal_ghost_0vtk + +# create a new 'CSV Reader' +vector_after_map0csv = CSVReader(FileName=['Vector/vector_after_map0.csv']) + +# Create a new 'SpreadSheet View' +spreadSheetView1 = CreateView('SpreadSheetView') +spreadSheetView1.BlockSize = 1024L +# uncomment following to set a specific view size +# spreadSheetView1.ViewSize = [400, 400] + +# place view in the layout +viewLayout1.AssignView(2, spreadSheetView1) + +# show data in view +vector_after_map0csvDisplay = Show(vector_after_map0csv, spreadSheetView1) + +# destroy spreadSheetView1 +Delete(spreadSheetView1) +del spreadSheetView1 + +# close an empty frame +viewLayout1.Collapse(2) + +# set active view +SetActiveView(renderView1) + +# create a new 'Table To Points' +tableToPoints2 = TableToPoints(Input=vector_after_map0csv) + +# Properties modified on tableToPoints2 +tableToPoints2.XColumn = 'x[0]' +tableToPoints2.YColumn = 'x[1]' +tableToPoints2.a2DPoints = 1 + +# show data in view +tableToPoints2Display = Show(tableToPoints2, renderView1) + +tableToPoints2Display.PointSize = 4.0 + +# create a new 'Legacy VTK Reader' +vect_decompositionsubdomains_0vtk = LegacyVTKReader(FileNames=['Vector/vect_decompositionsubdomains_0.vtk']) + +# show data in view +vect_decompositionsubdomains_0vtkDisplay = Show(vect_decompositionsubdomains_0vtk, renderView1) + +# show color bar/color legend +vect_decompositionsubdomains_0vtkDisplay.SetScalarBarVisibility(renderView1, True) + +# get color transfer function/color map for 'data' +dataLUT = GetColorTransferFunction('data') + +# get opacity transfer function/opacity map for 'data' +dataPWF = GetOpacityTransferFunction('data') + +# hide data in view +Hide(tableToPoints1, renderView1) + +# change representation type +vect_decompositionsubdomains_0vtkDisplay.SetRepresentationType('Points') + +# change representation type +vect_decompositionsubdomains_0vtkDisplay.SetRepresentationType('Wireframe') + +# turn off scalar coloring +ColorBy(vect_decompositionsubdomains_0vtkDisplay, None) + +# set active source +SetActiveSource(tableToPoints2) + +# change representation type +tableToPoints2Display.SetRepresentationType('Points') + +# current camera placement for renderView1 +renderView1.InteractionMode = '2D' +renderView1.CameraPosition = [0.45889311126344623, 0.2866467748466169, 10000.0] +renderView1.CameraFocalPoint = [0.45889311126344623, 0.2866467748466169, 0.0] +renderView1.CameraParallelScale = 0.1742200032569875 + +# create a new 'Legacy VTK Reader' +vect_decompositionexternal_ghost_0vtk = LegacyVTKReader(FileNames=['Vector/vect_decompositionexternal_ghost_0.vtk']) + +# show data in view +vect_decompositionexternal_ghost_0vtkDisplay = Show(vect_decompositionexternal_ghost_0vtk, renderView1) + +# show color bar/color legend +vect_decompositionexternal_ghost_0vtkDisplay.SetScalarBarVisibility(renderView1, False) + +# hide data in view +Hide(vect_decompositionexternal_ghost_0vtk, renderView1) + +# current camera placement for renderView1 +renderView1.InteractionMode = '2D' +renderView1.CameraPosition = [0.4322940474199577, 0.3362326839869475, 10000.0] +renderView1.CameraFocalPoint = [0.4322940474199577, 0.3362326839869475, 0.0] +renderView1.CameraParallelScale = 0.08127491729954842 + +# save screenshot +WriteImage('generated/vector_one_p_zoom.jpg') + +# set active source +SetActiveSource(vect_decompositionexternal_ghost_0vtk) + +# show data in view +vect_decompositionexternal_ghost_0vtkDisplay = Show(vect_decompositionexternal_ghost_0vtk, renderView1) + +# show color bar/color legend +vect_decompositionexternal_ghost_0vtkDisplay.SetScalarBarVisibility(renderView1, True) + +# current camera placement for renderView1 +renderView1.InteractionMode = '2D' +renderView1.CameraPosition = [0.4322940474199577, 0.3362326839869475, 10000.0] +renderView1.CameraFocalPoint = [0.4322940474199577, 0.3362326839869475, 0.0] +renderView1.CameraParallelScale = 0.08127491729954842 + +# save screenshot +WriteImage('generated/vector_one_p_zoom_ghost.jpg') + +# set active source +SetActiveSource(tableToPoints1) + +# show data in view +tableToPoints1Display = Show(tableToPoints1, renderView1) + +# change representation type +#tableToPoints1Display.SetRepresentationType('Points') + +# Properties modified on tableToPoints1Display +tableToPoints1Display.PointSize = 4.0 + +# change solid color +tableToPoints1Display.AmbientColor = [1.0, 0.0, 0.0] + +# current camera placement for renderView1 +renderView1.InteractionMode = '2D' +renderView1.CameraPosition = [0.4322940474199577, 0.3362326839869475, 10000.0] +renderView1.CameraFocalPoint = [0.4322940474199577, 0.3362326839869475, 0.0] +renderView1.CameraParallelScale = 0.08127491729954842 + +#### saving camera placements for all active views + +# save screenshot +WriteImage('generated/vector_one_p_zoom_ghost_part.jpg') + + +#### uncomment the following to render all views +# RenderAllViews() +# alternatively, if you want to write images, you can use SaveScreenshot(...). diff --git a/openfpm_numerics b/openfpm_numerics index 834b07c439b8cb308f535fcf43bddf9cc9ac7823..6c6b3e43a260d6196e8b4aecacf7058068378533 160000 --- a/openfpm_numerics +++ b/openfpm_numerics @@ -1 +1 @@ -Subproject commit 834b07c439b8cb308f535fcf43bddf9cc9ac7823 +Subproject commit 6c6b3e43a260d6196e8b4aecacf7058068378533 diff --git a/src/Decomposition/CartDecomposition.hpp b/src/Decomposition/CartDecomposition.hpp index 8454d6d349e0206cf69b47080269956b965374a2..bf2b8fbb06b6389f184fd83c87bae054c0c4825e 100755 --- a/src/Decomposition/CartDecomposition.hpp +++ b/src/Decomposition/CartDecomposition.hpp @@ -938,8 +938,10 @@ public: /*! \brief Set the parameter of the decomposition * - * \param div_ storing into how many domain to decompose on each dimension + * \param div_ storing into how many sub-sub-domains to decompose on each dimension * \param domain_ domain to decompose + * \param bc_ boundary conditions + * \param ghost Ghost size * */ void setParameters(const size_t (& div_)[dim], ::Box<dim,T> domain_, const size_t (& bc)[dim] ,const Ghost<dim,T> & ghost) diff --git a/src/Grid/grid_dist_id.hpp b/src/Grid/grid_dist_id.hpp index 9902cb07a74e2d92af4097a32f5cfd1030f99a92..18c5d5a2afc3a9a1eb4f7678b3a0c6c96e04da60 100644 --- a/src/Grid/grid_dist_id.hpp +++ b/src/Grid/grid_dist_id.hpp @@ -545,6 +545,37 @@ public: // value_type typedef T value_type; + // Type of space + typedef St stype; + + // Type of Memory + typedef Memory memory_type; + + // Type of device grid + typedef device_grid device_grid_type; + + // Number of dimensions + static const unsigned int dims = dim; + + /*! \brief Get the domain where the grid is defined + * + * + */ + inline const Box<dim,St> getDomain() const + { + return domain; + } + + /*! \brief Get the spacing of the grid in direction i + * + * \return the spacing + * + */ + inline St spacing(size_t i) const + { + return cd_sm.getCellBox().getHigh(i); + } + /*! \brief Return the total number of points in the grid * * \return number of points @@ -593,11 +624,12 @@ public: * something similar, but because of rounding-off error it can happen that it is not perfectly overlapping * * \param g previous grid + * \param Ghost part in grid units * \param ext extension of the grid (must be positive on every direction) * */ - grid_dist_id(const grid_dist_id<dim,St,T,typename Decomposition::base_type,Memory,device_grid> & g, Box<dim,size_t> ext) - :ghost(g.getDecomposition().getGhost()),dec(*global_v_cluster),v_cl(*global_v_cluster) + template<typename H> grid_dist_id(const grid_dist_id<dim,St,H,typename Decomposition::base_type,Memory,grid_cpu<dim,H>> & g, const Ghost<dim,long int> & gh, Box<dim,size_t> ext) + :dec(*global_v_cluster),v_cl(*global_v_cluster) { #ifdef SE_CLASS2 check_new(this,8,GRID_DIST_EVENT,4); @@ -605,26 +637,42 @@ public: this->dec.incRef(); - InitializeCellDecomposer(g.cd_sm,ext); + size_t ext_dim[dim]; + for (size_t i = 0 ; i < dim ; i++) {ext_dim[i] = g.getGridInfoVoid().size(i) + ext.getKP1().get(i) + ext.getKP2().get(i);} + + // Set the grid info of the extended grid + ginfo.setDimensions(ext_dim); + ginfo_v.setDimensions(ext_dim); + + InitializeCellDecomposer(g.getCellDecomposer(),ext); + + ghost = convert_ghost(gh,cd_sm); // Extend the grid by the extension part and calculate the domain for (size_t i = 0 ; i < dim ; i++) { - g_sz[i] = g.g_sz[i] + ext.getLow(i) + ext.getHigh(i); + g_sz[i] = g.size(i) + ext.getLow(i) + ext.getHigh(i); - this->domain.setLow(i,g.domain.getLow(i) - ext.getLow(i) * g.spacing(i) - g.spacing(i) / 2.0); - this->domain.setHigh(i,g.domain.getHigh(i) + ext.getHigh(i) * g.spacing(i) + g.spacing(i) / 2.0); + this->domain.setLow(i,g.getDomain().getLow(i) - ext.getLow(i) * g.spacing(i) - g.spacing(i) / 2.0); + this->domain.setHigh(i,g.getDomain().getHigh(i) + ext.getHigh(i) * g.spacing(i) + g.spacing(i) / 2.0); } - dec.setParameters(g.getDecomposition(),g.getDecomposition().getGhost(),this->domain); + dec.setParameters(g.getDecomposition(),ghost,this->domain); - InitializeStructures(g_sz); + InitializeStructures(g.getGridInfoVoid().getSize()); } - //! constructor + /*! It constructs a grid of a specified size, defined on a specified Box space, forcing to follow a specified decomposition and with a specified ghost size + * + * \param dec Decomposition + * \param g_sz grid size on each dimension + * \param domain Box that contain the grid + * \param ghost Ghost part + * + */ grid_dist_id(const Decomposition & dec, const size_t (& g_sz)[dim], const Box<dim,St> & domain, const Ghost<dim,St> & ghost) - :domain(domain),ghost(ghost),dec(dec),v_cl(*global_v_cluster) + :domain(domain),ghost(ghost),dec(dec),v_cl(*global_v_cluster),ginfo(g_sz),ginfo_v(g_sz) { // Increment the reference counter of the decomposition this->dec.incRef(); @@ -633,9 +681,16 @@ public: InitializeStructures(g_sz); } - //! constructor + /*! It constructs a grid of a specified size, defined on a specified Box space, forcing to follow a specified decomposition and with a specified ghost size + * + * \param dec Decomposition + * \param g_sz grid size on each dimension + * \param domain Box that contain the grid + * \param ghost Ghost part + * + */ grid_dist_id(Decomposition && dec, const size_t (& g_sz)[dim], const Box<dim,St> & domain, const Ghost<dim,St> & ghost) - :domain(domain),ghost(ghost),dec(dec),v_cl(*global_v_cluster) + :domain(domain),ghost(ghost),dec(dec),ginfo(g_sz),ginfo_v(g_sz),v_cl(*global_v_cluster) { #ifdef SE_CLASS2 check_new(this,8,GRID_DIST_EVENT,4); @@ -645,23 +700,16 @@ public: InitializeStructures(g_sz); } - /*! \brief Get the spacing of the grid in direction i + /*! It constructs a grid of a specified size, defined on a specified Box space, forcing to follow a specified decomposition, and having a specified ghost size * - * \return the spacing + * \param dec Decomposition + * \param g_sz grid size on each dimension + * \param domain Box that contain the grid + * \param ghost Ghost part (given in grid units) + * + * \warning In very rare case the ghost part can be one point bigger than the one specified * */ - inline St spacing(size_t i) const - { - return cd_sm.getCellBox().getHigh(i); - } - - /*! \brief Constrcuctor - * - * \param g_sz array with the grid size on each dimension - * \param domain domain where this grid live - * \param g Ghost given in grid units - * - */ grid_dist_id(const Decomposition & dec, const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,long int> & g) :domain(domain),dec(*global_v_cluster),v_cl(*global_v_cluster),ginfo(g_sz),ginfo_v(g_sz) { @@ -678,13 +726,16 @@ public: InitializeStructures(g_sz); } - /*! \brief Constrcuctor - * - * \param g_sz array with the grid size on each dimension - * \param domain domain where this grid live - * \param g Ghost given in grid units - * - */ + /*! It construct a grid of a specified size, defined on a specified Box space, forcing to follow a specified decomposition, and having a specified ghost size + * + * \param dec Decomposition + * \param g_sz grid size on each dimension + * \param domain Box that contain the grid + * \param ghost Ghost part (given in grid units) + * + * \warning In very rare case the ghost part can be one point bigger than the one specified + * + */ grid_dist_id(Decomposition && dec, const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,long int> & g) :domain(domain),dec(dec),v_cl(*global_v_cluster),ginfo(g_sz),ginfo_v(g_sz) { @@ -699,13 +750,15 @@ public: InitializeStructures(g_sz); } - /*! \brief Constrcuctor - * - * \param g_sz array with the grid size on each dimension - * \param domain domain where this grid live - * \param g Ghost - * - */ + /*! It construct a grid of a specified size, defined on a specified Box space, and having a specified ghost size + * + * \param g_sz grid size on each dimension + * \param domain Box that contain the grid + * \param ghost Ghost part (given in grid units) + * + * \warning In very rare case the ghost part can be one point bigger than the one specified + * + */ grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,St> & g) :domain(domain),ghost(g),dec(*global_v_cluster),v_cl(*global_v_cluster),ginfo(g_sz),ginfo_v(g_sz) { @@ -720,13 +773,16 @@ public: InitializeStructures(g_sz); } - /*! \brief Constrcuctor - * - * \param g_sz array with the grid size on each dimension - * \param domain domain where this grid live - * \param g Ghost given in grid units - * - */ + /*! It construct a grid of a specified size, defined on a specified Box space, and having a specified ghost size + * + * \param dec Decomposition + * \param g_sz grid size on each dimension + * \param domain Box that contain the grid + * \param ghost Ghost part of the domain (given in grid units) + * + * \warning In very rare case the ghost part can be one point bigger than the one specified + * + */ grid_dist_id(const size_t (& g_sz)[dim],const Box<dim,St> & domain, const Ghost<dim,long int> & g) :domain(domain),dec(*global_v_cluster),v_cl(*global_v_cluster),ginfo(g_sz),ginfo_v(g_sz) { @@ -748,6 +804,8 @@ public: * \param domain domain where this grid live * \param g Ghost given in grid units * + * \warning In very rare case the ghost part can be one point bigger than the one specified + * */ grid_dist_id(const Decomposition & dec, const std::vector<size_t> & g_sz,const Box<dim,St> & domain, const Ghost<dim,long int> & g) :grid_dist_id(dec,*static_cast<const size_t(*) [dim]>(static_cast<const void*>(&g_sz[0])),domain,g) @@ -761,6 +819,8 @@ public: * \param domain domain where this grid live * \param g Ghost given in grid units * + * \warning In very rare case the ghost part can be one point bigger than the one specified + * */ grid_dist_id(Decomposition && dec,const std::vector<size_t> & g_sz,const Box<dim,St> & domain, const Ghost<dim,long int> & g) :grid_dist_id(dec, *static_cast<const size_t(*) [dim]>(static_cast<const void*>(&g_sz[0])) , domain, g) @@ -824,7 +884,7 @@ public: * \return the cell decomposer * */ - const CellDecomposer_sm<dim,St,shift<dim,St>> & getCellDecomposer() + const CellDecomposer_sm<dim,St,shift<dim,St>> & getCellDecomposer() const { #ifdef SE_CLASS2 check_valid(this,8); @@ -856,7 +916,7 @@ public: * \return The size of the local domain * */ - size_t getLocalDomainSize() + size_t getLocalDomainSize() const { #ifdef SE_CLASS2 check_valid(this,8); @@ -889,7 +949,7 @@ public: * \return the iterator * */ - grid_dist_iterator<dim,device_grid,FREE> getDomainIterator() + grid_dist_iterator<dim,device_grid,FREE> getDomainIterator() const { #ifdef SE_CLASS2 check_valid(this,8); diff --git a/src/Grid/grid_dist_id_iterator.hpp b/src/Grid/grid_dist_id_iterator.hpp index 7c32710e6417b25cf0c46335f2e20616705ec02d..571b6d6acce46c48aeee78c6855821668447b281 100644 --- a/src/Grid/grid_dist_id_iterator.hpp +++ b/src/Grid/grid_dist_id_iterator.hpp @@ -88,7 +88,7 @@ class grid_dist_iterator<dim,device_grid,FREE> const openfpm::vector<device_grid> & gList; //! Extension of each grid: domain and ghost + domain - openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext; + const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext; //! Actual iterator grid_key_dx_iterator_sub<dim> a_it; @@ -118,7 +118,7 @@ class grid_dist_iterator<dim,device_grid,FREE> * \param gk std::vector of the local grid * */ - grid_dist_iterator(const openfpm::vector<device_grid> & gk, openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext, grid_key_dx<dim> stop) + grid_dist_iterator(const openfpm::vector<device_grid> & gk, const openfpm::vector<GBoxes<device_grid::dims>> & gdb_ext, grid_key_dx<dim> stop) :g_c(0),gList(gk),gdb_ext(gdb_ext),stop(stop) { // Initialize the current iterator diff --git a/src/Grid/grid_dist_id_unit_test_ext_dom.hpp b/src/Grid/grid_dist_id_unit_test_ext_dom.hpp index ea91ca57e149996059c1c0a89ce2371314bb5b6e..572dde5d0f052e7403f8ef378ff92bdd40bb6778 100644 --- a/src/Grid/grid_dist_id_unit_test_ext_dom.hpp +++ b/src/Grid/grid_dist_id_unit_test_ext_dom.hpp @@ -50,12 +50,15 @@ void Test3D_extended_grid(const Box<3,float> & domain, long int k) // Extend the grid by 2 points Box<3,size_t> ext({2,2,2},{2,2,2}); + // Ghost size of 1 grid point + Ghost<3,long int> gp(1); + // another grid perfectly overlapping the previous, extended by 2 points - grid_dist_id<3, float, aggregate<size_t[3],size_t>, CartDecomposition_ext<3,float>> g_dist2(g_dist1,ext); + grid_dist_id<3, float, aggregate<size_t[3],size_t>, CartDecomposition_ext<3,float>> g_dist2(g_dist1,gp,ext); - // Given an iterator on grid 1 + // Given an iterator of the grid 1 auto dom_g1 = g_dist1.getDomainIterator(); - // And a sub-iterator on grid 2 overlapping grid 1 + // And a sub-iterator of grid 2 overlapping grid 1 auto dom_g2 = g_dist2.getSubDomainIterator({0,0,0},{k-1,k-1,k-1}); // the 2 iterator must match diff --git a/src/Grid/grid_dist_key.hpp b/src/Grid/grid_dist_key.hpp index 7d69d5b20551fcc6c8a6c309dd87cf15c0d615f1..f3de75096e9bdd3d319ff7f614647af4896eef12 100644 --- a/src/Grid/grid_dist_key.hpp +++ b/src/Grid/grid_dist_key.hpp @@ -77,7 +77,7 @@ public: * \return new key * */ - inline grid_dist_key_dx<dim> move(size_t i,size_t s) + inline grid_dist_key_dx<dim> move(size_t i,size_t s) const { grid_key_dx<dim> key = getKey(); key.set_d(i,key.get(i) + s); @@ -91,7 +91,7 @@ public: * \return new key * */ - inline grid_dist_key_dx<dim> move(const comb<dim> & c) + inline grid_dist_key_dx<dim> move(const comb<dim> & c) const { grid_key_dx<dim> key = getKey(); for (size_t i = 0 ; i < dim ; i++) diff --git a/src/Grid/staggered_dist_grid.hpp b/src/Grid/staggered_dist_grid.hpp index 75809182460dbe54de6068b3885d680ee136f7d1..e82687f7b8b97c700fce5a9b77faa68839bb1d3c 100644 --- a/src/Grid/staggered_dist_grid.hpp +++ b/src/Grid/staggered_dist_grid.hpp @@ -11,7 +11,8 @@ #include "Grid/grid_dist_id.hpp" #include "staggered_dist_grid_util.hpp" #include "VTKWriter/VTKWriter.hpp" - +#include "staggered_dist_grid_copy.hpp" +#include <boost/mpl/vector_c.hpp> /*! \brief Implementation of the staggered grid * @@ -67,6 +68,26 @@ public: typedef T value_type; + // Number of dimensions + static const unsigned int dims = dim; + + /*! \brief This constructor is special, it construct an expanded grid that perfectly overlap with the previous + * + * The key-word here is "perfectly overlap". Using the default constructor you could create + * something similar, but because of rounding-off error it can happen that it is not perfectly overlapping + * + * \param g previous grid + * \param Ghost part in grid units + * \param ext extension of the grid (must be positive on every direction) + * + */ + template<typename H> staggered_grid_dist(const grid_dist_id<dim,St,H,typename Decomposition::base_type,Memory,grid_cpu<dim,H>> & g, + const Ghost<dim,long int> & gh, + Box<dim,size_t> ext) + :grid_dist_id<dim,St,T,Decomposition,Memory,device_grid>(g,gh,ext) + { + } + staggered_grid_dist(const size_t (& g_sz)[dim], const Box<dim,St> & domain, const Ghost<dim,St> & ghost) :grid_dist_id<dim,St,T,Decomposition,Memory,device_grid>(g_sz,domain,ghost) {} @@ -97,6 +118,60 @@ public: boost::mpl::for_each_ref< boost::mpl::range_c<int,0,T::max_prop> >(ssp); } + /*! \brief Copy the staggered grid into a normal one + * + * + * \tparam Grid_dst type of the destination Grid + * \tparam pos destination grid properties to fill + * + */ + template<typename Grid_dst ,unsigned int ... pos> bool to_normal(Grid_dst & g_dst, const Padding<dim> & pd, const long int (& start)[dim], const long int (& stop)[dim]) + { + // interpolation points for each property + openfpm::vector<std::vector<comb<dim>>> interp_pos[sizeof...(pos)]; + + typedef boost::mpl::vector_c<unsigned int,pos ... > v_pos_type; + + interp_points<dim,v_pos_type,typename Grid_dst::value_type::type> itp(interp_pos,c_prp); + boost::mpl::for_each_ref<v_pos_type>(itp); + + // shift the start and stop by the padding + grid_key_dx<dim> start_k = grid_key_dx<dim>(start); + grid_key_dx<dim> stop_k = grid_key_dx<dim>(stop); + + // sub-grid iterator over the grid map + auto g_map_it = this->getSubDomainIterator(start_k,stop_k); + + // Iterator over the destination grid + auto g_dst_it = g_dst.getDomainIterator(); + + // Check that the 2 iterator has the same size + checkIterator<St,decltype(g_map_it),decltype(g_dst_it)>(g_map_it,g_dst_it); + + 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(); + + // destination point + auto key_dst = g_dst_it.get(); + + // Transform this id into an id for the Eigen vector + + interp_ele<vid,Grid_dst,typename std::remove_reference<decltype(*this)>::type,sizeof...(pos)> cp(key_dst,g_dst,*this,key_src,interp_pos); + + // For each property in the target grid + boost::mpl::for_each_ref<boost::mpl::range_c<int,0,v_size::value>>(cp); + + ++g_map_it; + ++g_dst_it; + } + + return true; + } + /*! \brief Get the staggered positions * * \return The vector of the staggered positions @@ -131,6 +206,16 @@ public: return c_prp[prp].size() != 0; } + /*! \brief Return if the grid is staggered + * + * \return true + * + */ + bool is_staggered() + { + return true; + } + friend class stag_create_and_add_grid<dim,staggered_grid_dist<dim,St,T,Decomposition,Memory,device_grid>,St>; }; diff --git a/src/Grid/staggered_dist_grid_util.hpp b/src/Grid/staggered_dist_grid_util.hpp index 5a269985abadcdf4efd169f8d55e733100ad1122..c7d20ec6a1902d11264aa8ceeb7c67119ff368f8 100644 --- a/src/Grid/staggered_dist_grid_util.hpp +++ b/src/Grid/staggered_dist_grid_util.hpp @@ -658,4 +658,102 @@ public: } }; +/*! \brief Check that the size of the iterators match + * + * It check the the boxes that the sub iterator defines has same dimensions, for example + * if the first sub-iterator, iterate from (1,1) to (5,3) and the second from (2,2) to (6,4) + * they match (2,2) to (4,6) they do not match + * + * \tparam Grid_map type of the map grid + * \tparam Grid_dst type of the destination grid + * + * \param it1 Iterator1 + * \param it2 Iterator2 + * + * \return true if they match + * + */ +template<typename Eqs_sys, typename it1_type, typename it2_type> bool checkIterator(const it1_type & it1, const it2_type & it2) +{ +#ifdef SE_CLASS1 + + grid_key_dx<Eqs_sys::dims> it1_k = it1.getStop() - it1.getStart(); + grid_key_dx<Eqs_sys::dims> it2_k = it2.getStop() - it2.getStart(); + + for (size_t i = 0 ; i < Eqs_sys::dims ; i++) + { + if (it1_k.get(i) != it2_k.get(i)) + { + std::cerr << __FILE__ << ":" << __LINE__ << " error src iterator and destination iterator does not match in size\n"; + return false; + } + } + + return true; +#else + + return true; + +#endif +} + +/*! \brief this class is a functor for "for_each" algorithm + * + * This class is a functor for "for_each" algorithm. For each + * element of the boost::vector the operator() is called. + * Is mainly used to calculate the interpolation points for each + * property in a staggered grid + * + * \tparam dim Dimensionality + * \tparam v_prp_id vector of properties id + * \tparam v_prp_type vector with the properties + * + */ +template<unsigned int dim, typename v_prp_id, typename v_prp_type> +struct interp_points +{ + // number of properties we are processing + typedef boost::mpl::size<v_prp_id> v_size; + + // interpolation points for each property + openfpm::vector<std::vector<comb<dim>>> (& interp_pts)[v_size::value]; + + // staggered position for each property + const openfpm::vector<comb<dim>> (&stag_pos)[v_size::value]; + + /*! \brief constructor + * + * It define the copy parameters. + * + * \param inter_pts array that for each property contain the interpolation points for each components + * \param staggered position for each property and components + * + */ + inline interp_points(openfpm::vector<std::vector<comb<dim>>> (& interp_pts)[v_size::value],const openfpm::vector<comb<dim>> (&stag_pos)[v_size::value]) + :interp_pts(interp_pts),stag_pos(stag_pos){}; + + //! It call the copy function for each property + template<typename T> + inline void operator()(T& t) + { + // This is the type of the object we have to copy + typedef typename boost::mpl::at_c<v_prp_type,T::value>::type prp_type; + + interp_pts[T::value].resize(stag_pos[T::value].size()); + + for (size_t i = 0 ; i < stag_pos[T::value].size() ; i++) + { + // Create the interpolation points + interp_pts[T::value].get(i) = SubHyperCube<dim,dim - std::rank<prp_type>::value>::getCombinations_R(stag_pos[T::value].get(i),0); + + // interp_point are -1,0,1, map the -1 to 0 and 1 to -1 + for (size_t j = 0 ; j < interp_pts[T::value].get(i).size() ; j++) + { + for (size_t k = 0 ; k < dim ; k++) + interp_pts[T::value].get(i)[j].getComb()[k] = - ((interp_pts[T::value].get(i)[j].getComb()[k] == -1)?0:interp_pts[T::value].get(i)[j].getComb()[k]); + } + } + } +}; + #endif /* SRC_GRID_STAGGERED_DIST_GRID_UTIL_HPP_ */ diff --git a/src/Vector/vector_dist.hpp b/src/Vector/vector_dist.hpp index 44540b8e9e3ee878b767819a64166fc492d04bfe..ab06e71d64f6d68c860d26e673e31290d5f9957c 100644 --- a/src/Vector/vector_dist.hpp +++ b/src/Vector/vector_dist.hpp @@ -262,8 +262,8 @@ private: | v | (0,0) --> 4 | v | | 3 | | 5 | | | | | - B | | | A | - * | | | * | + B | | | A | + * | | | * | | | | | | | | | | | | | diff --git a/src/gargabe.hpp b/src/gargabe.hpp index 20e091ad5b9e72b1b994f9a9e3143e9fc5eeb4f2..eb05c7e75b013c0680563c01326c4ba079180d9d 100644 --- a/src/gargabe.hpp +++ b/src/gargabe.hpp @@ -621,4 +621,242 @@ public: virtual void destroy(size_t n) = 0; };*/ + + + + + + + + +/*! \brief Impose an operator + * + * This function impose an operator on a particular grid region to produce the system + * + * Ax = b + * + * ## Stokes equation, lid driven cavity with one splipping wall + * + * \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> 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) +{ + //////////////////////// DEBUG ///////////////// + + SparseMatrix<double,int> Al; + Al.load("debug_matrix_single_processor"); + + // Construct the map 3 processors 1 processors + + std::unordered_map<size_t,size_t> map_row; + + auto it2 = g_map.getDomainGhostIterator(); + auto ginfo = g_map.getGridInfoVoid(); + + while (it2.isNext()) + { + auto key = it2.get(); + auto key_g = g_map.getGKey(key); + key_g += pd.getKP1(); + + // To linearize must be positive + bool is_negative = false; + for (size_t i = 0 ; i < Sys_eqs::dims ; i++) + { + if (key_g.get(i) < 0) + is_negative = true; + } + + if (is_negative == true) + { + ++it2; + continue; + } + + // Carefull g map is extended, so the original (0,0) is shifted in g_map by + + if (g_map.template get<0>(key) == 7) + { + int debug = 0; + debug++; + } + + map_row[g_map.template get<0>(key)] = ginfo.LinId(key_g); + + ++it2; + } + + //////////////////////////////////////////////// + + Vcluster & v_cl = *global_v_cluster; + + 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; + + // resize b if needed + b.resize(Sys_eqs::nvar * g_map.size()); + + 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(); + + // Calculate the non-zero colums + T::value(g_map,key,gs,spacing,cols,1.0); + + //////////// DEBUG ////////////////// + + auto g_calc_pos = g_map.getGKey(key); + g_calc_pos += pd.getKP1(); + + ///////////////////////////////////// + + // 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; + + ///////////// DEBUG /////////////////////// + + auto ginfo = g_map.getGridInfoVoid(); + + size_t r = (trpl.last().row() / Sys_eqs::nvar); + size_t r_rest = (trpl.last().row() % Sys_eqs::nvar); + size_t c = (trpl.last().col() / Sys_eqs::nvar); + size_t c_rest = (trpl.last().col() % Sys_eqs::nvar); + double val = trpl.last().value(); + + // Transform + + size_t rf = map_row[r] * 3 + r_rest; + size_t cf = map_row[c] * 3 + c_rest; + + auto position_row = ginfo.InvLinId(rf / 3); + auto position_col = ginfo.InvLinId(cf / 3); + + double valf = Al.getValue(rf,cf); + + if (val != valf) + { + int debug = 0; + debug++; + } + + /////////////////////////////////////////// + +// std::cout << "(" << trpl.last().row() << "," << trpl.last().col() << "," << trpl.last().value() << ")" << "\n"; + } + + b(g_map.template get<0>(key)*Sys_eqs::nvar + id) = num; + + 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; + } +} + +typename Sys_eqs::SparseMatrix_type A; + +/*! \brief produce the Matrix + * + * \return the Sparse matrix produced + * + */ +typename Sys_eqs::SparseMatrix_type & getA() +{ +#ifdef SE_CLASS1 + consistency(); +#endif + A.resize(g_map.size()*Sys_eqs::nvar,g_map.size()*Sys_eqs::nvar); + + ///////////////// DEBUG SAVE ////////////////// + +// A.save("debug_matrix_single_processor"); + + //////////////////////////////////////////////// + + return A; + +} + + +typename Sys_eqs::SparseMatrix_type A; + +/*! \brief produce the Matrix + * + * \return the Sparse matrix produced + * + */ +typename Sys_eqs::SparseMatrix_type & getA() +{ +#ifdef SE_CLASS1 + consistency(); +#endif + A.resize(g_map.size()*Sys_eqs::nvar,g_map.size()*Sys_eqs::nvar); + + ///////////////// DEBUG SAVE ////////////////// + +// A.save("debug_matrix_single_processor"); + + //////////////////////////////////////////////// + + return A; + +} + + +/*! \brief produce the B vector + * + * \return the vector produced + * + */ +typename Sys_eqs::Vector_type & getB() +{ +#ifdef SE_CLASS1 + consistency(); +#endif + + // size of the matrix +// B.resize(g_map.size()*Sys_eqs::nvar); + + // copy the vector +// for (size_t i = 0; i < row_b; i++) +// B.insert(i,b.get(i)); + + return b; +} +}; + #endif /* GARGABE_HPP_ */