00001
00002
00003
00004
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include "mpi.h"
00008 #include "cg3d.h"
00009 using namespace cg3d;
00010
00011 double test_vol_mgc(const PointSet3d *ps,const Tet3d &A,const Tet3d &B);
00012 double test_vol_planes(const PointSet3d *ps,const Tet3d &A,const Tet3d &B);
00013 double test_vol_nop(const PointSet3d *ps,const Tet3d &A,const Tet3d &B)
00014 {
00015 return 0.0;
00016 }
00017 typedef double (*test_vol_fn)(const PointSet3d *ps,const Tet3d &A,const Tet3d &B);
00018
00019
00021 double randFloat(void) {
00022 return (rand()&0xffFF)*(1.0/(float)0xffFF);
00023 }
00024
00026 CkVector3d randPoint(void) {
00027 return CkVector3d(randFloat(),randFloat(),randFloat());
00028 }
00029
00032 CkVector3d randPlane(void) {
00033 CkVector3d planeOrigin(0,0,0);
00034 #if 0 // Roundoff-friendly perfectly flat plane
00035 CkVector3d planeX(1,0,0);
00036 CkVector3d planeY(0,1,0);
00037 #else //Roundoff-unfriendly skew plane
00038 CkVector3d planeX(0.7,0.2,0.1);
00039 CkVector3d planeY(0.3,0.8,-0.2);
00040 #endif
00041 return planeOrigin
00042 +randFloat()*planeX +randFloat()*planeY;
00043 }
00044
00045 const int tetTypes=6;
00046
00047
00048 inline Tet3d randTet(int tetType,PointSet3d *ps) {
00049 CkVector3d A,B,C,D;
00050 do {
00051 A=randPoint(); B=randPoint(); C=randPoint();
00052 switch (tetType)
00053 {
00054 case 0:
00055 break;
00056 case 1:
00057 A=randPlane(); B=randPlane(); C=randPlane(); break;
00058 case 2:
00059 A=randPlane(); B=randPlane();break;
00060 case 3:
00061 A=CkVector3d(0.123,0.234,0.456);
00062 case 4:
00063 B=CkVector3d(0.987,0.876,0.765);
00064 case 5:
00065 C=CkVector3d(0.654,0.543,0.432); break;
00066 };
00067 D=randPoint();
00068 } while (tetVolume(A,B,C,D)<1.0e-3);
00069 Tet3d t(ps,A,B,C,D); testShape(t); return t;
00070
00071 }
00072
00073
00074
00075 void matchTest(int firstTest,int lastTest) {
00076 printf("Running random tests from %d to %d\n",firstTest,lastTest);
00077 int nZero=0, nBig=0;
00078 double diff=0;
00079 for (int testNo=firstTest;testNo<lastTest;testNo++) {
00080 if (testNo%(16*1024)==0) {
00081 printf(".");
00082 fflush(stdout);
00083 }
00084 srand(testNo);
00085
00086 int tetType=(int)(0.999*randFloat()*tetTypes);
00087 PointSet3d ps;
00088 Tet3d A(randTet(tetType,&ps));
00089 Tet3d B(randTet(tetType,&ps));
00090
00091 double mvol=test_vol_mgc(&ps,A,B);
00092 double pvol=test_vol_planes(&ps,A,B);
00093 double err=fabs(mvol-pvol);
00094 if (err>1.0e-9)
00095 CmiAbort("Mgc and planes volumes differ!");
00096 if (mvol<1.0e-6) nZero++;
00097 if (mvol>1.0e-2) nBig++;
00098 if (err>diff) diff=err;
00099 }
00100 printf("To %d: (%d zero, %d big) %.3g max error\n",
00101 lastTest,nZero,nBig,diff);
00102 printf("All tests from %d to %d passed\n",firstTest,lastTest);
00103 }
00104
00107 double timePer(test_vol_fn fn,int nTest,int degen) {
00108 double start=MPI_Wtime();
00109 for (int testNo=0;testNo<nTest;testNo++) {
00110 srand(testNo);
00111
00112 int tetType=(int)(0.999*randFloat()*degen);
00113 PointSet3d ps;
00114 Tet3d A(randTet(tetType,&ps));
00115 Tet3d B(randTet(tetType,&ps));
00116
00117 double vol=fn(&ps,A,B);
00118 }
00119 return (MPI_Wtime()-start)/nTest;
00120 }
00121
00122
00123
00124 void timeTest(const char *desc,test_vol_fn fn,int nTest,int degen) {
00125 double zper=timePer(test_vol_nop,nTest/100,degen);
00126 double per=timePer(fn,nTest,degen)-zper;
00127 printf("%20s: %.3f us / intersection (%d)\n",desc,1.0e6*per,nTest);
00128 }
00129
00130 int main(int argc,char *argv[])
00131 {
00132 int firstTest=0, lastTest=100*1000;
00133 if (argc>1) firstTest=atoi(argv[1]);
00134 if (argc>2) lastTest=atoi(argv[2]);
00135 matchTest(firstTest,lastTest);
00136 int nTest=100*1000, degen=0;
00137 timeTest("Mgc",test_vol_mgc,nTest,degen);
00138 timeTest("Planes",test_vol_planes,nTest,degen);
00139 return 0;
00140 }
00141