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;
}
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;
}
Ejemplo n.º 3
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;
}