p4est 2.8.6
p4est is a software library for parallel adaptive mesh refinement.
points/generate_points2.c

Auxiliary program to generate a file of points in parallel.

Auxiliary program to generate a file of points in parallel.It uses the MPI I/O functionality of libsc to create one large file. The file is written to in parallel and using partitioned file access.

The file contains first a binary integer p4est_gloidx_t storing the global number of points and then the list of point coordinates as 3-tuples of binary type double.

The usage of the program is

p4est_points_generate <configuration> <globalnumpoints> <prefix>

where configuration is one of

and prefix is an output basename or filename to which we append .pts.

/*
This file is part of p4est.
p4est is a C library to manage a collection (a forest) of multiple
connected adaptive quadtrees or octrees in parallel.
Copyright (C) 2010 The University of Texas System
Additional copyright (C) 2011 individual authors
Written by Carsten Burstedde, Lucas C. Wilcox, and Tobin Isaac
p4est is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
p4est is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with p4est; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef P4_TO_P8
#include <p8est_bits.h>
#include <p8est_points.h>
#include <p8est_vtk.h>
#else
#include <p4est_bits.h>
#include <p4est_points.h>
#include <p4est_vtk.h>
#endif /* !P4_TO_P8 */
#include <sc_io.h>
/* Please see doc/example_points.dox for a documentation of this program. */
static void
generate_points (const char *filename,
p4est_gloidx_t global_num_points, sc_MPI_Comm mpicomm)
{
int mpiret;
int num_procs, rank;
int count;
p4est_gloidx_t offset_mine, offset_next;
p4est_locidx_t local_num_points;
double *point_buffer;
double theta;
#ifdef P4_TO_P8
double phi;
#else
double dtheta;
#endif
sc_MPI_File file_handle;
sc_MPI_Offset mpi_offset;
mpiret = sc_MPI_Comm_size (mpicomm, &num_procs);
SC_CHECK_MPI (mpiret);
mpiret = sc_MPI_Comm_rank (mpicomm, &rank);
SC_CHECK_MPI (mpiret);
/* open a file (create if the file does not exist) */
mpiret = sc_io_open (mpicomm, filename, SC_IO_WRITE_CREATE,
sc_MPI_INFO_NULL, &file_handle);
SC_CHECK_MPI (mpiret);
/* local (MPI) number of points */
local_num_points = global_num_points / num_procs;
/* offset to first point of current MPI process */
offset_mine = p4est_partition_cut_gloidx (global_num_points,
rank, num_procs);
/* offset to first point of successor MPI process */
offset_next = p4est_partition_cut_gloidx (global_num_points,
rank + 1, num_procs);
local_num_points = (p4est_locidx_t) (offset_next - offset_mine);
/* allocate buffer for point's coordinates */
point_buffer = P4EST_ALLOC (double, 3 * local_num_points);
/* set file offset (in bytes) for this calling process */
/* *INDENT-OFF* HORRIBLE indent bug */
mpi_offset = (sc_MPI_Offset) offset_mine * 3 * sizeof (double);
/* *INDENT-ON* */
#ifndef P4_TO_P8
/* 2D */
dtheta = (2. * M_PI) / global_num_points;
for (u = 0; u < local_num_points; ++u) {
theta = (offset_mine + u) * dtheta;
point_buffer[3 * u + 0] = 0.5 + 0.25 * cos (theta);
point_buffer[3 * u + 1] = 0.5 + 0.25 * sin (2 * theta);
point_buffer[3 * u + 2] = 0.0;
}
#else
/* 3D */
for (u = 0; u < local_num_points; ++u) {
theta = 2. * M_PI * rand () / (RAND_MAX + 1.0);
phi = M_PI * rand () / (RAND_MAX + 1.0);
point_buffer[3 * u + 0] = 0.5 + 0.25 * cos (theta) * sin (phi);
point_buffer[3 * u + 1] = 0.5 + 0.25 * sin (theta) * sin (phi);
point_buffer[3 * u + 2] = 0.5 + 0.25 * cos (phi);
}
#endif
if (rank == 0) {
/* write the global number number of points */
mpiret = sc_io_write_at (file_handle, 0, &global_num_points,
sizeof (p4est_gloidx_t), sc_MPI_BYTE, &count);
SC_CHECK_MPI (mpiret);
SC_CHECK_ABORT (count == (int) sizeof (p4est_gloidx_t),
"Write number of global points: count mismatch");
}
/* each MPI process writes its data for its own offset */
mpiret =
sc_io_write_at_all (file_handle, mpi_offset + sizeof (p4est_gloidx_t),
&point_buffer[0],
3 * local_num_points * sizeof (double), sc_MPI_BYTE,
&count);
SC_CHECK_MPI (mpiret);
SC_CHECK_ABORT (count == (int) (3 * local_num_points * sizeof (double)),
"Write points: count mismatch");
P4EST_FREE (point_buffer);
/* close the file collectively */
mpiret = sc_io_close (&file_handle);
SC_CHECK_MPI (mpiret);
}
int
main (int argc, char **argv)
{
int mpiret;
int num_procs, rank;
int wrongusage;
char buffer[BUFSIZ];
p4est_gloidx_t global_num_points;
sc_MPI_Comm mpicomm;
const char *usage;
/* initialize MPI and p4est internals */
mpiret = sc_MPI_Init (&argc, &argv);
SC_CHECK_MPI (mpiret);
mpicomm = sc_MPI_COMM_WORLD;
mpiret = sc_MPI_Comm_size (mpicomm, &num_procs);
SC_CHECK_MPI (mpiret);
mpiret = sc_MPI_Comm_rank (mpicomm, &rank);
SC_CHECK_MPI (mpiret);
sc_init (mpicomm, 1, 1, NULL, SC_LP_DEFAULT);
p4est_init (NULL, SC_LP_DEFAULT);
/* process command line arguments */
usage =
"Arguments: <configuration> <globalnumpoints> <prefix>\n"
" Configuration can be any of\n"
#ifndef P4_TO_P8
" unit|brick|three|moebius|star|periodic\n"
#else
" unit|brick|periodic|rotwrap|twocubes|rotcubes\n"
#endif
" Globalnumpoints is the total number of points generated\n"
" over all MPI process, >= 0\n"
" Prefix is for writing a point data file (using MPI-IO)\n";
wrongusage = 0;
if (!wrongusage && argc != 4) {
P4EST_GLOBAL_LERROR ("Invalid command line argument count\n");
wrongusage = 1;
}
conn = NULL;
if (!wrongusage) {
#ifndef P4_TO_P8
if (!strcmp (argv[1], "unit")) {
}
else if (!strcmp (argv[1], "brick")) {
conn = p4est_connectivity_new_brick (2, 3, 0, 0);
}
else if (!strcmp (argv[1], "three")) {
}
else if (!strcmp (argv[1], "moebius")) {
}
else if (!strcmp (argv[1], "star")) {
}
else if (!strcmp (argv[1], "periodic")) {
}
#else
if (!strcmp (argv[1], "unit")) {
}
else if (!strcmp (argv[1], "brick")) {
conn = p8est_connectivity_new_brick (2, 3, 4, 0, 0, 0);
}
else if (!strcmp (argv[1], "periodic")) {
}
else if (!strcmp (argv[1], "rotwrap")) {
}
else if (!strcmp (argv[1], "twocubes")) {
}
else if (!strcmp (argv[1], "rotcubes")) {
}
#endif
else {
P4EST_GLOBAL_LERROR ("Invalid connectivity configuration\n");
wrongusage = 1;
}
}
if (!wrongusage) {
global_num_points = (p4est_gloidx_t) atol (argv[2]);
if (global_num_points <= -1) {
P4EST_GLOBAL_LERROR ("Invalid global number of points\n");
wrongusage = 1;
}
}
if (wrongusage) {
P4EST_GLOBAL_LERROR (usage);
sc_abort_collective ("Usage error");
}
SC_GLOBAL_PRODUCTIONF ("Write %lld total points\n",
(long long) global_num_points);
snprintf (buffer, BUFSIZ, "%s.pts", argv[3]);
generate_points (buffer, conn, global_num_points, mpicomm);
/* in the present version of this program the connectivity is not used */
/* clean up and exit */
sc_finalize ();
mpiret = sc_MPI_Finalize ();
SC_CHECK_MPI (mpiret);
return 0;
}
#define P4EST_FREE(p)
free an allocated array
Definition: p4est_base.h:210
#define P4EST_ALLOC(t, n)
allocate a t-array with n elements
Definition: p4est_base.h:199
int32_t p4est_locidx_t
Typedef for processor-local indexing of quadrants and nodes.
Definition: p4est_base.h:106
void p4est_init(sc_log_handler_t log_handler, int log_threshold)
Registers p4est with the SC Library and sets the logging behavior.
int64_t p4est_gloidx_t
Typedef for globally unique indexing of quadrants.
Definition: p4est_base.h:118
Routines for manipulating quadrants (neighbors, parents, children, etc.)
p4est_connectivity_t * p4est_connectivity_new_corner(void)
Create a connectivity structure for a three-tree mesh around a corner.
void p4est_connectivity_destroy(p4est_connectivity_t *connectivity)
Destroy a connectivity structure.
p4est_connectivity_t * p4est_connectivity_new_unitsquare(void)
Create a connectivity structure for the unit square.
p4est_connectivity_t * p4est_connectivity_new_brick(int mi, int ni, int periodic_a, int periodic_b)
A rectangular m by n array of trees with configurable periodicity.
p4est_connectivity_t * p4est_connectivity_new_star(void)
Create a connectivity structure for a six-tree star.
p4est_connectivity_t * p4est_connectivity_new_moebius(void)
Create a connectivity structure for a five-tree moebius band.
p4est_connectivity_t * p4est_connectivity_new_periodic(void)
Create a connectivity structure for an all-periodic unit square.
Routines for printing a forest and associated fields to VTK format.
Routines for manipulating quadrants (neighbors, parents, children, etc.)
p8est_connectivity_t * p8est_connectivity_new_rotcubes(void)
Create a connectivity structure that contains a few cubes.
p8est_connectivity_t * p8est_connectivity_new_brick(int m, int n, int p, int periodic_a, int periodic_b, int periodic_c)
An m by n by p array with periodicity in x, y, and z if periodic_a, periodic_b, and periodic_c are tr...
p8est_connectivity_t * p8est_connectivity_new_unitcube(void)
Create a connectivity structure for the unit cube.
p8est_connectivity_t * p8est_connectivity_new_twocubes(void)
Create a connectivity structure that contains two cubes.
p8est_connectivity_t * p8est_connectivity_new_periodic(void)
Create a connectivity structure for an all-periodic unit cube.
p8est_connectivity_t * p8est_connectivity_new_rotwrap(void)
Create a connectivity structure for a mostly periodic unit cube.
Routines for printing a forest and associated fields to VTK format.
This structure holds the 2D inter-tree connectivity information.
Definition: p4est_connectivity.h:190