Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mosaic/software/parallel-computing/openfpm/openfpm_pdata
  • argupta/openfpm_pdata
2 results
Show changes
Showing
with 0 additions and 2219 deletions
#include "Grid/grid_dist_id.hpp"
#include "data_type/aggregate.hpp"
/*! \page grid Grid
*
* \subpage grid_0_simple
* \subpage Grid_1_stencil
* \subpage Grid_2_solve_eq
* \subpage Grid_3_gs
*
*/
/*! \page grid_0_simple Grid 0 simple
[TOC]
# Simple grid example # {#simple_grid_example}
This example show several basic functionalities of the distributed grid
\htmlonly
<a href="#" onclick="if (document.getElementById('grid-video-1').style.display == 'none') {document.getElementById('grid-video-1').style.display = 'block'} else {document.getElementById('grid-video-1').style.display = 'none'}" >Video</a>
<div style="display:none" id="grid-video-1">
<video id="vid1" width="1200" height="576" controls> <source src="http://ppmcore.mpi-cbg.de/upload/video/Lesson1-1.mp4" type="video/mp4"></video><script>document.getElementById('vid1').addEventListener('loadedmetadata', function() {this.currentTime = 236;}, false);</script>
</div>
\endhtmlonly
*/
int main(int argc, char* argv[])
{
/*! \page grid_0_simple Grid 0 simple
*
* ## Initialization ## {#e0_s_initialization}
*
* Here we:
* * Initialize the library
* * Create A 3D box that define our the domain
* * an array of 3 unsigned integer that will define the size of the grid on each dimensions
* * A Ghost object that will define the extension of the ghost part in physical units
*
* \snippet Grid/0_simple/main.cpp initialization
*
*/
//! \cond [initialization] \endcond
// Initialize the library
openfpm_init(&argc,&argv);
// 3D physical domain
Box<3,float> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
// Grid size on eaxh dimension
size_t sz[3] = {100,100,100};
// Ghost part
Ghost<3,float> g(0.01);
//! \cond [initialization] \endcond
/*! \page grid_0_simple Grid 0 simple
*
* ## Grid instantiation ## {#e0_s_grid_inst}
*
* Here we are creating a distributed grid in defined by the following parameters
*
* * 3 dimensionality of the grid
* * float Type used for the spatial coordinates
* * each grid point contain a vector of dimension 3 (float[3]),
* * float[3] is the information stored by each grid point a float[3]
* the list of properties must be put into an aggregate data structure aggregate<prop1,prop2,prop3, ... >
*
* Constructor parameters:
*
* * sz: size of the grid on each dimension
* * domain: where the grid is defined
* * g: ghost extension
*
* \snippet Grid/0_simple/main.cpp grid instantiation
*
*/
//! \cond [grid instantiation] \endcond
grid_dist_id<3, float, aggregate<float[3]>> g_dist(sz,domain,g);
//! \cond [grid instantiation] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Loop over grid points ## {#e0_s_loop_gp}
*
* Get an iterator that go through all the grid points. In this
* example we use iterators. Iterators are convenient way to explore/iterate data-structures in an
* convenient and easy way.
*
* \snippet Grid/0_simple/main.cpp get iterator
* \snippet Grid/0_simple/main.cpp get iterator2
*
*/
//! \cond [get iterator] \endcond
// Get the iterator (No ghost)
auto dom = g_dist.getDomainIterator();
// Counter
size_t count = 0;
// Iterate over all the grid points
while (dom.isNext())
{
//! \cond [get iterator] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Grid coordinates ## {#e0_s_grid_coord}
*
* Get the local grid key, one local grid key* identify one point in the grid and store the local grid coordinates of such point
*
* <sub><sup>(*)Internally a local grid store the sub-domain id (each sub-domain contain a grid) and the local grid point id identified by 2 integers in 2D 3 integer in 3D and so on. These two distinct elements are available with key.getSub() and key.getKey().</sup></sub>
*
* \snippet Grid/0_simple/main.cpp local grid
*
*/
//! \cond [local grid] \endcond
// local grid key from iterator
auto key = dom.get();
//! \cond [local grid] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* **Short explanation**
*
* In oder to get the real/global coordinates of the grid point we have to convert the object key with getGKey
*
*/
/*!
*
* \page grid_0_simple Grid 0 simple
*
\htmlonly <a href="#" onclick="if (document.getElementById('long-explanation-div').style.display == 'none') {document.getElementById('long-explanation-div').style.display = 'block'} else {document.getElementById('long-explanation-div').style.display = 'none'}" >Long Explanation</a> \endhtmlonly
*
*
\htmlonly
<div style="display:none" id="long-explanation-div">
<p>Even if the local grid key identify an unique point in the grid, it does not store the real/global coordinates of the points in grid units.</p>
<p>Consider this scheme</p>
<pre class="fragment">
+-----+-----+--*--+-----+-----+-----+ (6,6)
| | P1,3 |
| P1,1 *--------------------*
| | P1,2 |
+ + + | + + + +
| *--------------------*
*--------------* |
| | |
+ + + | + + + +
| | |
| P0,2 | P1,0 |
| | |
+ + + | # + + +
| | |
*--------------* |
| *--------------------*
+ + + | + + + +
| | |
| P0,0 | P0,1 |
| | |
+-----+-----+--*--+-----+-----+-----+
(0,0) (6,0)
+,# = grid point
*--*
| | = uderline decomposition in sub-domain
*--*
PX,Y Processor X, sub-domain Y</pre><p>The point # has</p>
<ul>
<li>Global/Real coordinates are (3,2)</li>
<li>Local grid coordinates are Sub-domain = 0, grid position = (0,0)</li>
</ul>
<p>Here we convert the local grid coordinates, into global coordinates. key_g internally store 3 integers that identify the position of the grid point in global coordinates</p>
<p>
</div>
\endhtmlonly
*/
/*! \page grid_0_simple Grid 0 simple
*
* \snippet Grid/0_simple/main.cpp global coord
*
*/
//! \cond [global coord] \endcond
auto key_g = g_dist.getGKey(key);
//! \cond [global coord] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Assign properties ## {#grid_assign}
*
* Each grid point has a vector property we write on the vector coordinates the global coordinate of the grid point.
* At the same time we also count the points
*
* \snippet Grid/0_simple/main.cpp assign
*
*/
//! \cond [assign] \endcond
g_dist.template get<0>(key)[0] = key_g.get(0);
g_dist.template get<0>(key)[1] = key_g.get(1);
g_dist.template get<0>(key)[2] = key_g.get(2);
// Count the points
count++;
//! \cond [assign] \endcond
//! \cond [get iterator2] \endcond
//! ...
// next point
++dom;
}
//! \cond [get iterator2] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* Each sub-domain has an extended part, that is materially contained in
* another processor. The function ghost_get guarantee (after return) that this extended part
* is perfectly synchronized with the other processor.
*
* \snippet Grid/0_simple/main.cpp ghost get
*
*/
//! \cond [ghost get] \endcond
g_dist.template ghost_get<0>();
//! \cond [ghost get] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* count contain the number of points the local processor contain, if we are interested to count the total number across the processor
* we can use the function sum, to sum numbers across processors. First we have to get an instance of Vcluster, queue an operation of sum with
* the variable count and finally execute. All the operation are asynchronous, execute work like a barrier and ensure that all the
* queued operations are executed
*
* \snippet Grid/0_simple/main.cpp reduce
*
*/
//! \cond [reduce] \endcond
// Get the VCluster object
Vcluster & vcl = create_vcluster();
// queue an operation of sum for the counter count
vcl.sum(count);
// execute the operation
vcl.execute();
// only master output
if (vcl.getProcessUnitID() == 0)
std::cout << "Number of points: " << count << "\n";
//! \cond [reduce] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## VTK and visualization ## {#e0_s_VTK_vis}
*
* Finally we want a nice output to visualize the information stored by the distributed grid.
* The function write by default produce VTK files. One for each processor that can be visualized
* with the programs like paraview
*
* \snippet Grid/0_simple/main.cpp write
*
*/
//! \cond [write] \endcond
g_dist.write("output");
//! \cond [write] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Decomposition ## {#grid_dec}
*
* For debugging purpose and demonstration we also output the decomposition of the
* space across processor. This function produce VTK files that can be visualized with Paraview
*
* \snippet Grid/0_simple/main.cpp out_dec
*
*/
//! \cond [out_dec] \endcond
g_dist.getDecomposition().write("out_dec");
//! \cond [out_dec] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* ## Finalize ## {#finalize}
*
* At the very end of the program we have always to de-initialize the library
*
* \snippet Vector/0_simple/main.cpp finalize
*
*/
//! \cond [finalize] \endcond
openfpm_finalize();
//! \cond [finalize] \endcond
/*!
* \page grid_0_simple Grid 0 simple
*
* # Full code # {#code}
*
* \include Grid/0_simple/main.cpp
*
*/
}
include ../../example.mk
CC=mpic++
LDIR =
OBJ = main.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
stencil: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: stencil
run: all
mpirun -np 3 ./stencil
.PHONY: clean all run
clean:
rm -f *.o *~ core stencil
[pack]
files = main.cpp Makefile
#include "Grid/grid_dist_id.hpp"
#include "data_type/aggregate.hpp"
#include "Decomposition/CartDecomposition.hpp"
/*!
* \page Grid_1_stencil Grid 1 stencil
*
*
* # Stencil example and ghost # {#e1_st}
*
* This example show how to move grid_key in order to create a Laplacian stencil,
* be careful, the function move is convenient, but not the fastest implementation.
* We also show how to do ghost communications
*
*/
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* Define some convenient constants and types
*
* \snippet Grid/1_stencil/main.cpp useful constant
*
*/
//! \cond [useful constant] \endcond
constexpr size_t x = 0;
constexpr size_t y = 1;
constexpr size_t z = 2;
constexpr size_t A = 0;
constexpr size_t B = 0;
//! \cond [useful constant] \endcond
int main(int argc, char* argv[])
{
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* ## Initialization ## {#e1_st_init}
*
* Initialize the library and several objects
*
* \see \ref e0_s_initialization
*
* \snippet Grid/1_stencil/main.cpp parameters
*
*
*/
//! \cond [parameters] \endcond
openfpm_init(&argc,&argv);
// domain
Box<3,float> domain({0.0,0.0,0.0},{1.0,1.0,1.0});
// grid sizes
size_t sz[3] = {100,100,100};
// ghost extension
Ghost<3,float> g(0.03);
//! \cond [parameters] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* ## Grid create ## {#e1_st_inst}
*
* Create a distributed grid in 3D. With typedef we create an alias name for aggregate<float[3],float[3]>.
* In practice the type of grid_point == aggregate<float[3],float[3]>
*
* \see \ref e0_s_grid_inst
*
* \snippet Grid/1_stencil/main.cpp grid
*
*/
//! \cond [grid] \endcond
// a convenient alias for aggregate<...>
typedef aggregate<float,float> grid_point;
grid_dist_id<3, float, grid_point> g_dist(sz,domain,g);
//! \cond [grid] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* ## Loop over grid points ## {#e1_s_loop_gp}
*
* Get an iterator that go through the point of the domain (No ghost)
*
* \see \ref e0_s_loop_gp
*
* \snippet Grid/1_stencil/main.cpp iterator
* \snippet Grid/1_stencil/main.cpp iterator2
*
*/
//! \cond [iterator] \endcond
auto dom = g_dist.getDomainIterator();
while (dom.isNext())
{
//! \cond [iterator] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* Inside the cycle we get the local grid key
*
* \see \ref e0_s_grid_coord
*
* \snippet Grid/1_stencil/main.cpp local key
*
*/
//! \cond [local key] \endcond
auto key = dom.get();
//! \cond [local key] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* We convert the local grid position, into global position, key_g contain 3 integers that identify the position
* of the grid point in global coordinates
*
* \see \ref e0_s_grid_coord
*
* \snippet Grid/1_stencil/main.cpp global key
*
*/
//! \cond [global key] \endcond
auto key_g = g_dist.getGKey(key);
//! \cond [global key] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* we write on the grid point of position (i,j,k) the value i*i + j*j + k*k on the property A.
* Mathematically is equivalent to the function
*
* \f$ f(x,y,z) = x^2 + y^2 + z^2 \f$
*
* \snippet Grid/1_stencil/main.cpp function
*
*/
//! \cond [function] \endcond
g_dist.template get<A>(key) = key_g.get(0)*key_g.get(0) + key_g.get(1)*key_g.get(1) + key_g.get(2)*key_g.get(2);
//! \cond [function] \endcond
//! \cond [iterator2] \endcond
++dom;
}
//! \cond [iterator2] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* ## Ghost ## {#e1_s_ghost}
*
* Each sub-domain has an extended part, that is materially contained into another processor.
* In general is not synchronized
* ghost_get<A> synchronize the property A in the ghost part
*
* \snippet Grid/1_stencil/main.cpp ghost
*
*/
//! \cond [ghost] \endcond
g_dist.template ghost_get<A>();
//! \cond [ghost] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* Get again another iterator, iterate across all the domain points, calculating a Laplace stencil. Write the
* result on B
*
* \snippet Grid/1_stencil/main.cpp laplacian
*
*/
//! \cond [laplacian] \endcond
auto dom2 = g_dist.getDomainIterator();
while (dom2.isNext())
{
auto key = dom2.get();
// Laplace stencil
g_dist.template get<B>(key) = g_dist.template get<A>(key.move(x,1)) + g_dist.template get<A>(key.move(x,-1)) +
g_dist.template get<A>(key.move(y,1)) + g_dist.template get<A>(key.move(y,-1)) +
g_dist.template get<A>(key.move(z,1)) + g_dist.template get<A>(key.move(z,-1)) -
6*g_dist.template get<A>(key);
++dom2;
}
//! \cond [laplacian] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
*
* Finally we want a nice output to visualize the information stored by the distributed grid
*
* \see \ref e0_s_VTK_vis
*
* \snippet Grid/1_stencil/main.cpp output
*
*/
//! \cond [output] \endcond
g_dist.write("output");
//! \cond [output] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* Deinitialize the library
*
* \snippet Grid/1_stencil/main.cpp finalize
*
*/
//! \cond [finalize] \endcond
openfpm_finalize();
//! \cond [finalize] \endcond
/*!
* \page Grid_1_stencil Grid 1 stencil
*
* # Full code # {#code}
*
* \include Grid/1_stencil/main.cpp
*
*/
}
include ../../example.mk
CC=mpic++
LDIR =
OBJ = main.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
periodic: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: periodic
run: all
mpirun -np 4 ./periodic
.PHONY: clean all run
clean:
rm -f *.o *~ core periodic
[pack]
files = main.cpp Makefile
#include "Grid/grid_dist_id.hpp"
#include "data_type/aggregate.hpp"
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* [TOC]
*
* # Simple example of grid usage to solve an equation # {#e2_solve_eq}
*
* This example show the usage of grid to solve the following equation
*
* \f$\frac{\partial^2 u}{\partial^2 x} + \frac{\partial^2 u}{\partial^2 y} = 1\f$
*
* \f$u(x,y) = 0 \f$
*
* at the boundary
*
*
* ## Field initialization ## {#e2_se_finit}
*
*/
//! \cond [field init] \endcond
void init(grid_dist_id<2,double,aggregate<double> > & g_dist, const size_t (& sz)[2])
{
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* In order to initialize the field U, first we get an iterator that cover
* domain + Ghost to iterate all the grid points.
* Inside the cycle we initialize domain and border (Ghost part to 0.0)
*
* \see \ref e0_s_loop_gp
*
*/
//! \cond [iterator] \endcond
// Get the iterator
auto it = g_dist.getDomainGhostIterator();
// For each point in the grid
while (it.isNext())
{
//! \cond [iterator] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* Get the local grid key
*
* \see \ref e0_s_grid_coord
*
* \snippet Grid/2_solve_eq/main.cpp local key
*
*/
//! \cond [local key] \endcond
auto key = it.get();
//! \cond [local key] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
*
* Here we convert the local grid position, into global position.
* key_g contain 3 integers that identify the position of the grid point
* in global coordinates
*
* \see \ref e0_s_grid_coord
*
* \snippet Grid/2_solve_eq/main.cpp global key
*
*/
//! \cond [global key] \endcond
auto key_g = g_dist.getGKey(key);
//! \cond [global key] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* Initialize to 0, domain + boundary
*
* \snippet Grid/2_solve_eq/main.cpp init field zero
*
* The full function look like this
*
* \snippet Grid/2_solve_eq/main.cpp field init
*
*/
//! \cond [init field zero] \endcond
if (key_g.get(0) == 0 || key_g.get(0) == sz[0] ||
key_g.get(1) == 0 || key_g.get(1) == sz[1])
{
// Boundary part
g_dist.template get<0>(key) = 0.0;
}
else
{
// Internal part
g_dist.template get<0>(key) = 0.0;
}
//! \cond [init field zero] \endcond
//! \cond [iterator2] \endcond
++it;
}
//! \cond [iterator2] \endcond
}
//! \cond [field init] \endcond
constexpr int x = 0;
constexpr int y = 1;
int main(int argc, char* argv[])
{
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* ## Initialization ##
*
* Initialize the library
*
* \see \ref e0_s_initialization
*
* \snippet Grid/2_solve_eq/main.cpp ofp_init
*
*/
//! \cond [ofp_init] \endcond
openfpm_init(&argc,&argv);
//! \cond [ofp_init] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* ## Grid instantiation and initialization ##
*
* Create
* * A 2D box that define the domain
* * an array of 2 unsigned integer that will define the size of the grid on each dimension
* * A Ghost object that will define the extension of the ghost part for each sub-domain in grid point unit
*
* \snippet Grid/2_solve_eq/main.cpp ofp_par
*
*/
//! \cond [ofp_par] \endcond
Box<2,double> domain({-1.0,-1.0},{1.0,1.0});
size_t sz[2] = {64,64};
periodicity<2> bc = {NON_PERIODIC,NON_PERIODIC};
// Ghost in grid unit
Ghost<2,long int> g(1);
//! \cond [ofp_par] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* Create a distributed grid in 2D (1° template parameter) space in with double precision (2° template parameter)
* each grid point contain a scalar (double),
*
* Constructor parameters:
*
* * sz: size of the grid on each dimension
* * domain: where the grid is defined
* * g: ghost extension
* * bc: boundary conditions
*
* \see \ref e0_s_grid_inst
*
* \snippet Grid/2_solve_eq/main.cpp grid inst
*
*/
//! \cond [grid inst] \endcond
grid_dist_id<2, double, aggregate<double>> g_dist(sz,domain,g,bc);
// spacing between two points
double spacing[2] = {g_dist.spacing(0),g_dist.spacing(1)};
//! \cond [grid inst] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* Initialize U and fill the boundary conditions
*
* \see \ref e2_se_field_init
*
* \snippet Grid/2_solve_eq/main.cpp grid init
*
*/
//! \cond [grid init] \endcond
init(g_dist,sz);
//! \cond [grid init] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* ## %Ghost synchronization ##
*
* Before the computation read the ghost point we have to guarantee that they have
* updated values.
*
* \snippet Grid/2_solve_eq/main.cpp ghost sync
*
*/
//! \cond [ghost sync] \endcond
// sync the ghost property 0
g_dist.template ghost_get<0>();
//! \cond [ghost sync] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* ## Red-Black alghorithm ##
*
* Do 10000 iteration of Red-Black Gauss-Siedel iterations
*
*
*/
//! \cond [gs_alg] \endcond
// flag that indicate if we are processing red or black
// we start from red
bool red_black = true;
// 10000 iterations
for (size_t i = 0 ; i < 10000 ; i++)
{
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* Get an iterator that go through the points of the grid (No ghost)
* To compute one iteration.
*
* \see \ref e0_s_loop_gp
* \see \ref e0_s_grid_coord
*
* \snippet Grid/2_solve_eq/main.cpp gs_it
*
*/
//! \cond [gs_it] \endcond
auto dom = g_dist.getDomainIterator();
// Iterate over all the points
while (dom.isNext())
{
// Get the local grid key
auto key = dom.get();
// Here we convert the local grid position, into global position, key_g contain 3 integers that identify the position
// of the grid point in global coordinates
auto key_g = g_dist.getGKey(key);
//
// If we are processing red and is odd jump to the next point
// If we are processing black and is even jump to the next point
//
if (red_black == false && (key_g.get(0) + key_g.get(1)) % 2 == 0)
{++dom; continue;}
else if (red_black == true && (key_g.get(0) + key_g.get(1)) % 2 == 1)
{++dom; continue;}
//
// Update the grid values
//
// P.S. The keyword template is removed, it is possible only if we are in a function
// without template parameters (if you are unsure use the keyword template)
//
g_dist.get<0>(key) = (g_dist.get<0>(key.move(x,1)) + g_dist.template get<0>(key.move(x,-1)) +
g_dist.get<0>(key.move(y,1)) + g_dist.template get<0>(key.move(y,-1)) +
- 1.0)/4.0;
//
// next point (red/black)
++dom;
}
//! \cond [gs_it] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
*
* Once an iteration is done we have to synchronize the ghosts
* to start a new iteration. Consider that we calculated the red points
* in the next iteration the red points in the ghost are used in reading.
* This mean that the ghost must have the updated values
*
* \snippet Grid/2_solve_eq/main.cpp ghost sync2
*
*
*/
//! \cond [ghost sync2] \endcond
g_dist.template ghost_get<0>();
// switch from red to black or black to red
red_black = !red_black;
//! \cond [ghost sync2] \endcond
}
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* The full Algorithm look like this
*
* \snippet Grid/2_solve_eq/main.cpp gs_alg
*/
//! \cond [gs_alg] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* ## Solution statistic ##
*
* Once we got the solution we want to check if it really satisfy the equation,
* and calculate the error (norm infinity)
*
* \snippet Grid/2_solve_eq/main.cpp sol stat
*
*/
//! \cond [sol stat] \endcond
// It contain the error
double error = 0.0;
// Get the iterator
auto dom = g_dist.getDomainIterator();
// Iterate over all the points
while (dom.isNext())
{
// same the the grid point and the global grid point
auto key = dom.get();
// Calculate the error on each point
// The error is how much the solution does not respect the equation
double error_tmp = abs((g_dist.get<0>(key.move(x,1)) + g_dist.get<0>(key.move(x,-1)) +
g_dist.get<0>(key.move(y,1)) + g_dist.get<0>(key.move(y,-1)) +
- 4.0*g_dist.get<0>(key)) - 1.0);
// In the norm infinity the maximum error across all the point is
// important
if (error_tmp > error)
error = error_tmp;
// next point
++dom;
}
// Get the maximum across processor to calculate the norm infinity of the error
// Norm infinity of the error is the maximum error across all the grid points
Vcluster & v_cl = create_vcluster();
v_cl.max(error);
v_cl.execute();
// Only master print the norm infinity
if (v_cl.getProcessUnitID() == 0)
std::cout << "Error norm infinity: " << error << std::endl;
//! \cond [sol stat] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* ## VTK Write and visualization ##
*
* Finally we want a nice output to visualize the information stored by the distributed grid.
* The function write by default produce VTK files. One for each processor that can be visualized
* with the programs like paraview
*
* \see \ref e0_s_VTK_vis
*
* \snippet Grid/2_solve_eq/main.cpp write
*
*/
//! \cond [write] \endcond
g_dist.write("output");
//! \cond [write] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* ## Finalize ##
*
* At the very end of the program we have always to de-initialize the library
*
* \snippet Grid/2_solve_eq/main.cpp finalize
*
*/
//! \cond [finalize] \endcond
openfpm_finalize();
//! \cond [finalize] \endcond
/*!
* \page Grid_2_solve_eq Grid 2 solve eq
*
* # Full code # {#code}
*
* \include Grid/2_solve_eq/main.cpp
*
*/
}
include ../../example.mk
CC=mpic++
LDIR =
OBJ = main.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
gray_scott: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: gray_scott
run: all
mpirun -np 4 ./gray_scott
.PHONY: clean all run
clean:
rm -f *.o *~ core gray_scott
[pack]
files = main.cpp Makefile
This diff is collapsed.
SUBDIRS := $(wildcard */.)
all clean run: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
.PHONY: all clean $(SUBDIRS)
SUBDIRS := $(wildcard */.)
all clean run: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
.PHONY: all clean $(SUBDIRS)
SUBDIRS := $(wildcard */.)
all clean run: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
.PHONY: all clean $(SUBDIRS)
include ../../../example.mk
CC=mpic++
LDIR =
OBJ = main.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
pse_1d: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: pse_1d
run: all
./pse_1d
.PHONY: clean all run
clean:
rm -f *.o *~ core pse_1d
[pack]
files = main.cpp Makefile
This diff is collapsed.
# This example does not work using clang
# Eliminate the comment to activate it
include ../../../example.mk
CC=mpic++
LDIR =
OBJ_128 = main_float128.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
# pse_1d_128: $(OBJ_128)
# $(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS) -lquadmath
#all: pse_1d_128
run: #all
# source $$HOME/openfpm_vars;# ./pse_1d_128
#.PHONY: clean all run
clean:
rm -f *.o *~ core pse_1d_128
[pack]
files = main_float128.cpp Makefile
include ../../../example.mk
CC=mpic++
LDIR =
OBJ = main.o
%.o: %.cpp
$(CC) -O3 -c --std=c++11 -o $@ $< $(INCLUDE_PATH)
diff_1d: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS) $(LIBS_PATH) $(LIBS)
all: diff_1d
run: all
mpirun -np 4 ./diff_1d
.PHONY: clean all
clean:
rm -f *.o *~ core diff_1d