290 lines
9.1 KiB
C
Executable File
290 lines
9.1 KiB
C
Executable File
/*
|
|
Unit tests for geometry module.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include "minunit.h"
|
|
#include "../lib/geometry.h"
|
|
#include "../lib/constants.h"
|
|
|
|
/* To store fail messages */
|
|
char msg[1000];
|
|
|
|
|
|
static char * test_split_tess()
|
|
{
|
|
TESSEROID tess = {1, 2, 4, -1, 1, 5, 7},
|
|
expect[] = {{1, 2, 3, -1, 0, 5, 6}, {1, 3, 4, -1, 0, 5, 6},
|
|
{1, 2, 3, 0, 1, 5, 6}, {1, 3, 4, 0, 1, 5, 6},
|
|
{1, 2, 3, -1, 0, 6, 7}, {1, 3, 4, -1, 0, 6, 7},
|
|
{1, 2, 3, 0, 1, 6, 7}, {1, 3, 4, 0, 1, 6, 7}},
|
|
res[8];
|
|
int i, n;
|
|
|
|
n = split_tess(tess, 2, 2, 2, res);
|
|
sprintf(msg, "splitting in %d instead of 8", n);
|
|
mu_assert(n == 8, msg);
|
|
for(i = 0; i < 8; i++)
|
|
{
|
|
sprintf(msg, "failed for split %d: %g %g %g %g %g %g %g", i, res[i].w,
|
|
res[i].e, res[i].s, res[i].n, res[i].r1, res[i].r2,
|
|
res[i].density);
|
|
mu_assert(res[i].w == expect[i].w && res[i].e == expect[i].e &&
|
|
res[i].s == expect[i].s && res[i].n == expect[i].n &&
|
|
res[i].r1 == expect[i].r1 && res[i].r2 == expect[i].r2 &&
|
|
res[i].density == expect[i].density, msg);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
static char * test_split_uneven_tess()
|
|
{
|
|
TESSEROID tess = {1, 2, 4, -1, 1, 5, 7},
|
|
expect[] = {{1, 2, 3, -1, 0, 5, 7}, {1, 3, 4, -1, 0, 5, 7},
|
|
{1, 2, 3, 0, 1, 5, 7}, {1, 3, 4, 0, 1, 5, 7}},
|
|
res[4];
|
|
int i, n;
|
|
|
|
n = split_tess(tess, 2, 2, 1, res);
|
|
sprintf(msg, "splitting in %d instead of 4", n);
|
|
mu_assert(n == 4, msg);
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
sprintf(msg, "failed for split %d: %g %g %g %g %g %g %g", i, res[i].w,
|
|
res[i].e, res[i].s, res[i].n, res[i].r1, res[i].r2,
|
|
res[i].density);
|
|
mu_assert(res[i].w == expect[i].w && res[i].e == expect[i].e &&
|
|
res[i].s == expect[i].s && res[i].n == expect[i].n &&
|
|
res[i].r1 == expect[i].r1 && res[i].r2 == expect[i].r2 &&
|
|
res[i].density == expect[i].density, msg);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static char * test_prism_volume()
|
|
{
|
|
PRISM prisms[4] = {
|
|
{0,0,1,0,1,0,1,0,0,0},
|
|
{0,0,2,0,1,0,1,0,0,0},
|
|
{0,0,2,0,2,0,2,0,0,0},
|
|
{0,1,2,-1,1,2,3,0,0,0}};
|
|
double pvolumes[4] = {1, 2, 8, 2};
|
|
double res;
|
|
int i;
|
|
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
res = prism_volume(prisms[i]);
|
|
sprintf(msg, "(prism %d) expected %g, got %g", i, pvolumes[i], res);
|
|
mu_assert(res == pvolumes[i], msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static char * test_tess_volume()
|
|
{
|
|
TESSEROID tesses[4] = {{0,0,360,-90,90,0,1}, {0,0,360,0,90,0,1},
|
|
{0,180,360,0,90,0,1}, {0,0,90,-90,0,0,1}};
|
|
double tvolumes[4] = {4.188790205, 2.094395102, 1.047197551, 0.523598776};
|
|
double res;
|
|
int i;
|
|
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
res = tess_volume(tesses[i]);
|
|
sprintf(msg, "(tess %d) expected %g, got %g", i, tvolumes[i], res);
|
|
mu_assert_almost_equals(res, tvolumes[i], pow(10, -8), msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static char * test_tess_total_mass()
|
|
{
|
|
TESSEROID tesses[4] = {{1,0,360,-90,90,0,1}, {1,0,360,0,90,0,1},
|
|
{1,180,360,0,90,0,1}, {1,0,90,-90,0,0,1}};
|
|
double tvolumes[4] = {4.188790205, 2.094395102, 1.047197551, 0.523598776};
|
|
double res, expect;
|
|
int i;
|
|
|
|
res = tess_total_mass(tesses, 4);
|
|
|
|
for(expect = 0, i = 0; i < 4; i++)
|
|
{
|
|
expect += tvolumes[i];
|
|
}
|
|
|
|
sprintf(msg, "(tess %d) expected %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals(res, expect, pow(10, -6), msg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static char * test_tess_range_mass()
|
|
{
|
|
TESSEROID tesses[4] = {{1,0,360,-90,90,0,1}, {-1,0,360,0,90,0,1},
|
|
{-1,180,360,0,90,0,1}, {1,0,90,-90,0,0,1}};
|
|
double tvolumes[4] = {4.188790205, 2.094395102, 1.047197551, 0.523598776};
|
|
double res, expect;
|
|
|
|
res = tess_range_mass(tesses, 4, 0, 1);
|
|
expect = tvolumes[0] + tvolumes[3];
|
|
sprintf(msg, "Expected %g, got %g", expect, res);
|
|
mu_assert_almost_equals(res, expect, pow(10, -6), msg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static char * test_tess2prism()
|
|
{
|
|
int i;
|
|
double expect, res;
|
|
double lons[4] = {0.5, 185, 180, -2.5},
|
|
lats[4] = {0.5, 82.5, -80, 4},
|
|
rs[4] = {6001000, 6301000, 6000000, 6505000},
|
|
zs[4] = {1000, 1000, 500000, 5000};
|
|
PRISM prism;
|
|
TESSEROID tesses[4] = {
|
|
{1,0,1,0,1,6000000,6001000},
|
|
{1,180,190,80,85,6300000,6301000},
|
|
{1,160,200,-90,-70,5500000,6000000},
|
|
{1,-10,5,-7,15,6500000,6505000}};
|
|
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
tess2prism(tesses[i], &prism);
|
|
/* check the volume */
|
|
res = prism_volume(prism);
|
|
expect = tess_volume(tesses[i]);
|
|
sprintf(msg, "(tess %d) expected volume %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals((double)(res - expect)/expect, 0., 0.01, msg);
|
|
/* check the mass */
|
|
res *= prism.density;
|
|
expect *= tesses[i].density;
|
|
sprintf(msg, "(tess %d) expected mass %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals((double)(res - expect)/expect, 0., 0.01, msg);
|
|
/* check the coordinates */
|
|
res = prism.lon;
|
|
expect = lons[i];
|
|
sprintf(msg, "(tess %d) expected lon %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals((double)(res - expect)/expect, 0., 0.0001, msg);
|
|
res = prism.lat;
|
|
expect = lats[i];
|
|
sprintf(msg, "(tess %d) expected lat %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals((double)(res - expect)/expect, 0., 0.0001, msg);
|
|
res = prism.r;
|
|
expect = rs[i];
|
|
sprintf(msg, "(tess %d) expected r %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals((double)(res - expect)/expect, 0., 0.0001, msg);
|
|
res = prism.z1;
|
|
expect = 0.;
|
|
sprintf(msg, "(tess %d) expected z1 %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals(res, 0., 0.000000000000001, msg);
|
|
res = prism.z2;
|
|
expect = zs[i];
|
|
sprintf(msg, "(tess %d) expected z2 %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals((double)(res - expect)/expect, 0., 0.0001, msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static char * test_tess2prism_flatten()
|
|
{
|
|
double expect, res;
|
|
PRISM prism;
|
|
int i;
|
|
TESSEROID tesses[4] = {
|
|
{1,0,1,0,1,6000000,6001000},
|
|
{1,180,190,80,85,6300000,6301000},
|
|
{1,160,200,-90,-70,5500000,6000000},
|
|
{1,-10,5,-7,15,6500000,6505000}};
|
|
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
tess2prism_flatten(tesses[i], &prism);
|
|
res = prism_volume(prism)*prism.density;
|
|
expect = tess_volume(tesses[i])*tesses[i].density;
|
|
sprintf(msg, "(tess %d) expected mass %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals((double)(res - expect)/expect, 0., 0.01, msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static char * test_tess2sphere()
|
|
{
|
|
double expect, res;
|
|
SPHERE sphere;
|
|
int i;
|
|
TESSEROID tesses[4] = {
|
|
{1,0,1,0,1,6000000,6001000},
|
|
{1,180,190,80,85,6300000,6301000},
|
|
{1,160,200,-90,-70,5500000,6000000},
|
|
{1,-10,5,-7,15,6500000,6505000}};
|
|
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
tess2sphere(tesses[i], &sphere);
|
|
res = sphere_volume(sphere);
|
|
expect = tess_volume(tesses[i]);
|
|
sprintf(msg, "(tess %d) expected volume %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals(res/expect, 1., 0.01, msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static char * test_prism2sphere()
|
|
{
|
|
double expect, res;
|
|
SPHERE sphere;
|
|
int i;
|
|
PRISM prisms[4] = {
|
|
{1,0,1000,0,2000,100,2000,0,0,0},
|
|
{1,-500,200,300,500,-1000,4000,0,0,0},
|
|
{1,-10000000,5000000,5000000,8000000,0,3000000,0,0,0},
|
|
{1,-1000000,50000,500000,800000,0,300000,0,0,0}};
|
|
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
prism2sphere(prisms[i], 0., 0., 0., &sphere);
|
|
res = sphere_volume(sphere);
|
|
expect = prism_volume(prisms[i]);
|
|
sprintf(msg, "(prism %d) expected volume %g, got %g", i, expect, res);
|
|
mu_assert_almost_equals(res/expect, 1., 0.001, msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int geometry_run_all()
|
|
{
|
|
int failed = 0;
|
|
failed += mu_run_test(test_prism_volume, "prism_volume return correct results");
|
|
failed += mu_run_test(test_tess_volume, "tess_volume return correct results");
|
|
failed += mu_run_test(test_tess_total_mass, "tess_total_mass returns correct result");
|
|
failed += mu_run_test(test_tess_range_mass, "tess_range_mass returns correct result");
|
|
failed += mu_run_test(test_tess2prism, "tess2prism produces prism with right volume");
|
|
failed += mu_run_test(test_tess2prism_flatten,
|
|
"tess2prism_flatten produces prism with right mass");
|
|
failed += mu_run_test(test_tess2sphere,
|
|
"tess2sphere produces sphere with right volume");
|
|
failed += mu_run_test(test_prism2sphere,
|
|
"prism2sphere produces sphere with right volume");
|
|
failed += mu_run_test(test_split_tess, "split_tess returns correct results for 2, 2, 2 split");
|
|
failed += mu_run_test(test_split_uneven_tess, "split_tess returns correct results for 2, 2, 1 split");
|
|
return failed;
|
|
}
|