#ifndef	ICOND_H
#define	ICOND_H

/*
 * icond.h - prototypes for routines used while applying
 * initial conditions. All routines use external random number
 * handle 'rhandle', so the later must be already initialized.
 */

extern vhandle_t rhandle;

/*
 * Routine to fill array with uniformly distributed
 * float random numbers. This is a wrapper for ranNextVectorRange().
 */
void uniform_random_vector(vec_t dest[],u32_t nval,vec_t min,vec_t max);

/*
 * Places particles at the nodes of the _regular_ 3D grid; the node
 * choosed randomly. All particles must have equal radius 'particle_radius'.
 * (Caller should add 'min_dist' to the 'particle_radius', if needed).
 */
vboolean distribute_equal_sized_in_box(
	vec3_t mins,vec3_t maxs, /* domain boundaries */
	u32_t npart, /* number of particles */
	vec_t particle_radius, /* radius of each particle */
	vec_t phase_ret[] /* array to hold computed positions */);

/*
 * Places particles at uniformly distributed random positions choosed
 * inside the box [mins..maxs]. If it fails due to timeout (possibly,
 * there can be too many particles for placement and/or particle sizes
 * too big for given domain), it returns 'false'.
 *
 * Note 1: the routine places _centers_ of particles inside the domain;
 * it is possible for some particle to lie partially outside. The
 * caller should shink the domain boundaries if necessary.
 *
 * Note 2: the routine uses last parameter - 'cur_vol_to_domain_vol' -
 * to determine if the generated array 'covers' most of the domain.
 * For example, if the domain boundaries were [-100,-100,-100] to
 * [100,100,100] and bounding box of computed positions are [-50,-50,-50]
 * to [50,50,50] (i.e., all particles are actually in 1/8 of the domain),
 * the generated distribution will be rejected if cur_vol_to_domain_vol
 * is greater then 1/8.
 */
vboolean distribute_in_box(
	vec3_t mins,vec3_t maxs, /* domain boundaries */
	u32_t npart, /* number of particles */
	vec_t particle_radius[], /* radiuses of the particles */
	vec_t min_dist, /* minimal distance between _surfaces_ of the particles */
	vec_t phase_ret[], /* array to hold positions */
	u32_t timeout, /* maximal time to execute in milliseconds */
	vec_t cur_vol_to_domain_vol /* 'coverage' coefficient */);

/*
 * Places particles at uniformly distributed random positions choosed
 * inside the sphere with center 'center' and radius 'radius'.
 *
 * Note: do _not_ set 'cur_vol_to_domain_vol' to close to 1 because
 * routine uses bounding _boxes_ (not _spheres_) to estimate coverage.
 */
vboolean distribute_in_sphere(
	vec3_t center,vec_t radius, /* center and radius of domain */
	u32_t npart,
	vec_t particle_radius[],
	vec_t min_dist,
	vec_t phase_ret[],u32_t timeout,
	vec_t cur_vol_to_domain_vol /* must _not_ be close to 1 */);

/*
 * Places particles at uniformly distributed random positions choosed
 * inside the cylinder with center of the lower base 'lf_center',
 * radius 'radius' and height 'height'. The axis of the cylinder is
 * collinear to Z axis ('vertical' cylinder).
 *
 * For the last parameter see note for distribute_in_sphere().
 */
vboolean distribute_in_cylinder(
	vec3_t lf_center, /* center of the lower base of the cylinder */
	vec_t radius,vec_t height, /* radius and height of cylinder */
	u32_t npart,vec_t particle_radius[],vec_t min_dist,
	vec_t phase_ret[],u32_t timeout,
	vec_t cur_vol_to_domain_vol /* must _not_ be close to 1 */);

#endif	/* !ICOND_H */
