double testInterplationErr(T* Atree, int Ns, int Nf) { Atree->buildFMMTree(); int i, j, k=0; vector3 source[Ns]; // Position array for the source points vector3 field[Nf]; // Position array for the field points double q[Ns*Atree->dof->s]; // Source array for (i=0;i<Ns;i++) { for (j=0; j<Atree->dof->s; j++, k++){ q[k] = frand(0,1); } } double size = Atree->L/4; //generate random points in well seperated box. for (i=0;i<Ns;i++) { source[i].x = frand(-0.5,0.5)*size - 1.5*size; source[i].y = frand(-0.5,0.5)*size - 1.5*size; source[i].z = frand(-0.5,0.5)*size - 1.5*size; } // Randomly set field points for (i=0;i<Nf;i++) { field[i].x = frand(-0.5,0.5)*size + 0.5*size; field[i].y = frand(-0.5,0.5)*size + 0.5*size; field[i].z = frand(-0.5,0.5)*size + 0.5*size; } double *stress = new double[Nf*Atree->dof->f];// Field array (BBFMM calculation) double *stress_dir = new double[Nf*Atree->dof->f];// Field array (direct O(N^2) calculation) H2_3D_Compute<T> compute(Atree, field, source, Ns, Nf, q,1, stress); DirectCalc3D(Atree, field, Nf, source, q, 1, Ns, Atree->dof,0 ,0, stress_dir); double err = ComputeError(stress,stress_dir,Nf,Atree->dof,1); delete []stress; delete []stress_dir; cout << "Interplation error is: " << err << endl; return err; }
int main(int argc, char *argv[]) { /**********************************************************/ /* */ /* Initializing the problem */ /* */ /**********************************************************/ double L; // Length of simulation cell (assumed to be a cube) int n; // Number of Chebyshev nodes per dimension doft dof; int Ns; // Number of sources in simulation cell int Nf; // Number of field points in simulation cell int m; int level; double eps; int use_chebyshev = 1; SetMetaData(L, n, dof, Ns, Nf, m, level, eps); vector3* source = new vector3[Ns]; // Position array for the source points vector3* field = new vector3[Nf]; // Position array for the field points double *q = new double[Ns*dof.s*m]; // Source array SetSources(field,Nf,source,Ns,q,m,&dof,L); double err; double *stress = new double[Nf*dof.f*m];// Field array (BBFMM calculation) double *stress_dir = new double[Nf*dof.f*m];// Field array (direct O(N^2) calculation) /**********************************************************/ /* */ /* Fast matrix vector product */ /* */ /**********************************************************/ /***** Pre Computation ******/ clock_t t0 = clock(); myKernel Atree(&dof,L,level, n, eps, use_chebyshev); Atree.buildFMMTree(); clock_t t1 = clock(); double tPre = t1 - t0; /***** FMM Computation *******/ t0 = clock(); H2_3D_Compute<myKernel> compute(&Atree, field, source, Ns, Nf, q,m, stress); t1 = clock(); double tFMM = t1 - t0; /***** output result to binary file ******/ // string outputfilename = "../output/stress.bin"; // write_Into_Binary_File(outputfilename, stress, m*Nf*dof.f); /**********************************************************/ /* */ /* Exact matrix vector product */ /* */ /**********************************************************/ t0 = clock(); DirectCalc3D(&Atree, field, Nf, source, q, m, Ns, &dof,0 , L, stress_dir); t1 = clock(); double tExact = t1 - t0; cout << "Pre-computation time: " << double(tPre) / double(CLOCKS_PER_SEC) << endl; cout << "FMM computing time: " << double(tFMM) / double(CLOCKS_PER_SEC) << endl; cout << "FMM total time: " << double(tFMM+tPre) / double(CLOCKS_PER_SEC) << endl; cout << "Exact computing time: " << double(tExact) / double(CLOCKS_PER_SEC) << endl; //Compute the 2-norm error err = ComputeError(stress,stress_dir,Nf,&dof,m); cout << "Relative Error: " << err << endl; /******* Clean Up *******/ delete []stress; delete []stress_dir; delete []q; delete []source; delete []field; return 0; }
int main(int argc, char *argv[]) { /**********************************************************/ /* */ /* Initializing the problem */ /* */ /**********************************************************/ double L; // Length of simulation cell (assumed to be a cube) int n; // Number of Chebyshev nodes per dimension doft dof; int Ns; // Number of sources in simulation cell int Nf; // Number of field points in simulation cell int m; int level; double eps; int use_chebyshev = 1; SetMetaData(L, n, dof, Ns, Nf, m, level, eps); vector3* source = new vector3[Ns]; // Position array for the source points vector3* field = new vector3[Nf]; // Position array for the field points double *q = new double[Ns*dof.s*m]; // Source array SetSources(field,Nf,source,Ns,q,m,&dof,L); double err; double *stress = new double[Nf*dof.f*m];// Field array (BBFMM calculation) double *stress_dir = new double[Nf*dof.f*m];// Field array (direct O(N^2) calculation)*/ /**********************************************************/ /* */ /* Fast matrix vector product */ /* */ /**********************************************************/ /***** Pre Computation ******/ clock_t t0 = clock(); kernel_Gaussian Atree(&dof,L,level, n, eps, use_chebyshev); Atree.buildFMMTree(); clock_t t1 = clock(); double tPre = t1 - t0; /***** FMM Computation *******/ t0 = clock(); H2_3D_Compute<kernel_Gaussian> compute(&Atree, field, source, Ns, Nf, q,m, stress); t1 = clock(); double tFMM = t1 - t0; /***** You can repeat this part with different source, field points and charges *****/ /*vector3* source1 = new vector3[Ns]; // Position array for the source points vector3* field1 = new vector3[Nf]; // Position array for the field points double *q1 = new double[Ns*dof.s*m]; // Source array SetSources(field1,Nf,source1,Ns,q1,m,&dof,L); double *stress1 = new double[Nf*dof.f*m];// Field array (BBFMM calculation) H2_3D_Compute<kernel_LaplacianForce> compute1(&Atree, field1, source1, Ns, Nf, q1,m, stress1);*/ /**** Test interplation error *****/ // kernel_Gaussian testTree(&dof,1.0/4 ,2, n, eps, use_chebyshev); // double errtest = testInterplationErr(&testTree, 100, 100); /***** output result to binary file ******/ // string outputfilename = "../output/stress.bin"; // write_Into_Binary_File(outputfilename, stress, m*Nf*dof.f); /**********************************************************/ /* */ /* Exact matrix vector product */ /* */ /**********************************************************/ // string inputfilename = "../output/stress_dir05gaussian.bin"; // read_Stress(inputfilename, stress_dir, Nf*dof.f*m); t0 = clock(); DirectCalc3D(&Atree, field, Nf, source, q, m, Ns, &dof,0 , L, stress_dir); t1 = clock(); double tExact = t1 - t0; string outputfilename = "../output/stress_dir06gaussian.bin"; write_Into_Binary_File(outputfilename, stress, m*Nf*dof.f); cout << "Pre-computation time: " << double(tPre) / double(CLOCKS_PER_SEC) << endl; cout << "FMM computing time: " << double(tFMM) / double(CLOCKS_PER_SEC) << endl; cout << "FMM total time: " << double(tPre+tFMM) / double(CLOCKS_PER_SEC) << endl; cout << "Exact computing time: " << double(tExact) / double(CLOCKS_PER_SEC) << endl; // Compute the 2-norm error err = ComputeError(stress,stress_dir,Nf,&dof,m); cout << "Relative Error: " << err << endl; /******* Clean Up *******/ delete []stress; delete []stress_dir; delete []source; delete []field; delete []q; //delete []stress1; return 0; }
void mexFunction(int nlhs,mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /**********************************************************/ /* */ /* Initializing the problem */ /* */ /**********************************************************/ #define QH_OUT plhs[0] #define QHexact_OUT plhs[1] #define source_IN prhs[0] #define field_IN prhs[1] #define charge_IN prhs[2] #define nCheb_IN prhs[3] #define level_IN prhs[4] #define L_IN prhs[5] #define use_cheby_IN prhs[6] #define singular_IN prhs[7] // Check number of argument if(nrhs != 7) { mexErrMsgTxt("Wrong number of input arguments"); }else if(nlhs > 2){ mexErrMsgTxt("Too many output arguments"); } if( !IS_REAL_2D_FULL_DOUBLE(source_IN)) { mexErrMsgTxt("Third input argument is not a real 2D full double array."); } if( !IS_REAL_2D_FULL_DOUBLE(field_IN)) { mexErrMsgTxt("Third input argument is not a real 2D full double array."); } if( !IS_REAL_2D_FULL_DOUBLE(charge_IN)) { mexErrMsgTxt("Third input argument is not a real 2D full double array."); } if( !IS_REAL_SCALAR(nCheb_IN)){ mexErrMsgTxt("nChebnotes must be a real double scalar"); } if( !IS_REAL_SCALAR(level_IN)){ mexErrMsgTxt("level must be a real double scalar"); } if( !IS_REAL_SCALAR(L_IN)){ mexErrMsgTxt("L must be a real double scalar"); } if( !IS_REAL_SCALAR(use_cheby_IN)){ mexErrMsgTxt("use_cheby must be a real double scalar"); } double L = *mxGetPr(L_IN); // Length of simulation cell (assumed to be a cube) int n = *mxGetPr(nCheb_IN); // Number of Chebyshev nodes per dimension doft dof; dof.f = 1; dof.s = 1; int Ns = mxGetM(source_IN); // Number of sources in simulation cell int Nf = mxGetM(field_IN); // Number of field points in simulation cell int m = mxGetN(charge_IN); // Number of r.h.s. int level = *mxGetPr(level_IN); double eps = 1e-9; int use_chebyshev = *mxGetPr(use_cheby_IN); vector3* source = new vector3[Ns]; // Position array for the source points vector3* field = new vector3[Nf]; // Position array for the field points read_data(source_IN, field_IN, Ns, Nf, source, field); double * charges; charges = mxGetPr(charge_IN); double err; QH_OUT = mxCreateDoubleMatrix(Nf*dof.f, m, mxREAL); double* stress = mxGetPr(QH_OUT); /**********************************************************/ /* */ /* Fast matrix vector product */ /* */ /**********************************************************/ mexPrintf("\nStarting FMM computation...\n"); /***** Pre Computation ******/ clock_t t0 = clock(); kernel_Exp Atree(&dof,L,level, n, eps, use_chebyshev); //myKernel Atree(&dof,L,level, n, eps, use_chebyshev); Atree.buildFMMTree(); clock_t t1 = clock(); double tPre = t1 - t0; /***** FMM Computation *******/ t0 = clock(); //H2_3D_Compute<myKernel> compute(&Atree, field, source, Ns, Nf, charges,m, stress); H2_3D_Compute<kernel_Exp> compute(&Atree, field, source, Ns, Nf, charges,m, stress); t1 = clock(); double tFMM = t1 - t0; /**********************************************************/ /* */ /* Exact matrix vector product */ /* */ /**********************************************************/ mexPrintf("\nPre-computation time: %.4f\n",double(tPre) / double(CLOCKS_PER_SEC)); mexPrintf("FMM computing time: %.4f\n",double(tFMM) / double(CLOCKS_PER_SEC)); mexPrintf("FMM total time: %.4f\n",double(tFMM+tPre) / double(CLOCKS_PER_SEC)); if (nlhs == 2) { mexPrintf("\nStarting direct computation...\n"); t0 = clock(); QHexact_OUT = mxCreateDoubleMatrix(Nf*dof.f, m, mxREAL); double* stress_dir = mxGetPr(QHexact_OUT); DirectCalc3D(&Atree, field, Nf, source, charges, m, Ns, &dof,0 , L, stress_dir); t1 = clock(); double tExact = t1 - t0; mexPrintf("Exact computing time: %.4f\n",double(tExact) / double(CLOCKS_PER_SEC)); // Compute the 2-norm error err = ComputeError(stress,stress_dir,Nf,&dof,m); mexPrintf("Relative Error: %e\n",err); } /******* Clean Up *******/ delete []source; delete []field; return; }