void setup_coeffs4(BoxArray& bs, MultiFab& alpha, MultiFab& beta, const Geometry& geom) { ParmParse pp; Real sigma, w; pp.get("sigma", sigma); pp.get("w", w); for ( MFIter mfi(alpha); mfi.isValid(); ++mfi ) { const Box& bx = mfi.validbox(); const int* alo = alpha[mfi].loVect(); const int* ahi = alpha[mfi].hiVect(); const Box& abx = alpha[mfi].box(); FORT_SET_ALPHA(alpha[mfi].dataPtr(),ARLIM(alo),ARLIM(ahi), abx.loVect(),abx.hiVect(),dx); const int* clo = beta[mfi].loVect(); const int* chi = beta[mfi].hiVect(); FORT_SET_CC_COEF(beta[mfi].dataPtr(),ARLIM(clo),ARLIM(chi), bx.loVect(),bx.hiVect(),dx, sigma, w); } if (plot_beta == 1) { writePlotFile("BETA4", beta, geom); } }
void setup_coeffs(BoxArray& bs, MultiFab& alpha, PArray<MultiFab>& beta, const Geometry& geom, MultiFab& cc_coef) { BL_PROFILE("setup_coeffs()"); ParmParse pp; Real sigma, w; pp.get("sigma", sigma); pp.get("w", w); for ( MFIter mfi(alpha); mfi.isValid(); ++mfi ) { const Box& bx = mfi.validbox(); const int* alo = alpha[mfi].loVect(); const int* ahi = alpha[mfi].hiVect(); FORT_SET_ALPHA(alpha[mfi].dataPtr(),ARLIM(alo),ARLIM(ahi), bx.loVect(),bx.hiVect(),dx); const int* clo = cc_coef[mfi].loVect(); const int* chi = cc_coef[mfi].hiVect(); FORT_SET_CC_COEF(cc_coef[mfi].dataPtr(),ARLIM(clo),ARLIM(chi), bx.loVect(),bx.hiVect(),dx, sigma, w); } BoxLib::average_cellcenter_to_face(beta, cc_coef, geom); if (plot_beta == 1) { writePlotFile("BETA", cc_coef, geom); } }
void setup_rhs(MultiFab& rhs, const Geometry& geom) { BL_PROFILE("setup_rhs()"); ParmParse pp; Real a, b, sigma, w; pp.get("a", a); pp.get("b", b); pp.get("sigma", sigma); pp.get("w", w); int ibnd = static_cast<int>(bc_type); // We test the sum of the RHS to check solvability Real sum_rhs = 0.; for ( MFIter mfi(rhs); mfi.isValid(); ++mfi ) { const int* rlo = rhs[mfi].loVect(); const int* rhi = rhs[mfi].hiVect(); const Box& bx = rhs[mfi].box(); FORT_SET_RHS(rhs[mfi].dataPtr(),ARLIM(rlo),ARLIM(rhi), bx.loVect(),bx.hiVect(),dx, a, b, sigma, w, ibnd); sum_rhs += rhs[mfi].sum(0,1); } for (int n=0; n < BL_SPACEDIM; n++) { sum_rhs *= dx[n]; } ParallelDescriptor::ReduceRealSum(sum_rhs, ParallelDescriptor::IOProcessorNumber()); if (ParallelDescriptor::IOProcessor()) { std::cout << "Sum of RHS : " << sum_rhs << std::endl; } if (plot_rhs == 1) { writePlotFile("RHS", rhs, geom); } }
/****************************************************************************** mergingAndClustering() : Clustering of GMMs and Realignment; Merging of states inputs : features - pointer to all feature vectors, allMixtureMeans, allMixtureVars numstates, numMixEachState, totalNumFeatures, posterior - posterior probability matrix, mixtureElemCount - Element count in each mixture outputs : Perform viterbi realignment, clustering and merging of states or GMMs ******************************************************************************/ void ClusteringAndMerging(VECTOR_OF_F_VECTORS *features, VECTOR_OF_F_VECTORS *allMixtureMeans, VECTOR_OF_F_VECTORS *allMixtureVars, int *numStates, int *numMixEachState, int totalNumFeatures, float **posterior, float **mixtureElemCount, int *numElemEachState, float *Pi, float *mixtureWeight) { // local Variable declaration int VQIter = 7, GMMIter = 23, mergeIter=0, maxMergeIter = 16; int viterbiIter = 5; int i = 0, j = 0, k = 0,s= 0, flag = 1; float *T1[MAX_NUM_STATES]; int *T2[MAX_NUM_STATES]; int *newStateSeq; float *deltaBIC[MAX_NUM_STATES]; for(i = 0; i < (*numStates); i++){ deltaBIC[i] = (float *)calloc((*numStates), sizeof(float)); } for(i = 0; i < (*numStates); i++){ T1[i] = (float *)calloc(totalNumFeatures, sizeof(float)); T2[i] = (int *)calloc(totalNumFeatures, sizeof(int)); } // Merge two GMM States or two mixture models //perform the steps repeatedly till there are no more states to be merged while(flag && mergeIter < maxMergeIter){ printf("\nClustering and Merging Iteration: %d...........\n", mergeIter); printf("starting with, States: %d \n", *numStates); mergeIter++; for(s = 0; s < *numStates; s++) printf("state[%d] : %d \n", s, numElemEachState[s]); for(i = 0; i < viterbiIter; i++){ //perform Viterbi Realignment printf("performing viterbi realignment....\n"); newStateSeq = viterbi( features , numStates, allMixtureMeans, allMixtureVars, numMixEachState, totalNumFeatures, posterior, numElemEachState, T1, T2, Pi, mixtureWeight); printf("Viterbi realignment has successfully completed...\n"); //find number of elements in each state //FindNumberOfElemInEachState(newStateSeq, numStates, totalNumFeatures, numElemEachState, Pi); //perform GMM clustering for all states for(s = 0; s < (*numStates); s++){ // find all elements present in state s using viterbi_realignment int count = 0, d = 0; // to count number of features in a state for(j = 0; j < totalNumFeatures; j++){ if(newStateSeq[j] == s){ for(d = 0; d < DIM; d++){ featuresForClustering[count]->array[d] = features[j]->array[d]; featuresForClustering[count]->numElements = DIM; } count++;//increment count } } extern VECTOR_OF_F_VECTORS *mixtureMeans, *mixtureVars; extern float probScaleFactor; extern int varianceNormalize, ditherMean; int numFeatures = count; //printf("count: %d num: %d\n", count, numElemEachState[s]); int numMix = numMixEachState[s]; // Cluster using GMM ComputeGMM(featuresForClustering, numFeatures, mixtureMeans, mixtureVars, mixtureElemCount[s], numMix , VQIter, GMMIter, probScaleFactor, ditherMean, varianceNormalize, time(NULL)); int mixCount = 0, k=0; //store current mean and variance into all means and variance for(j = 0; j < s; j++) mixCount += numMixEachState[j]; for(j = mixCount; j < mixCount + numMixEachState[s]; j++){ for(k = 0; k < DIM; k++){ allMixtureMeans[j]->array[k] = mixtureMeans[j-mixCount]->array[k]; allMixtureVars[j]->array[k] = mixtureVars[j-mixCount]->array[k]; } float mix_wt = mixtureElemCount[s][j-mixCount] / numElemEachState[s]; mixtureWeight[j] = mix_wt; } }//GMM Clustering for each state has completed //calculate posterior probabilities PrintAllDetails(numStates, numMixEachState, numElemEachState, mixtureElemCount, allMixtureMeans, mixtureWeight); ComputePosteriorProb(features, posterior, allMixtureMeans, allMixtureVars, numStates, numMixEachState, totalNumFeatures, mixtureWeight); } // PrintAllDetails(numStates, numMixEachState, numElemEachState, // mixtureElemCount, allMixtureMeans, mixtureWeight); // Calculate BIC Value between Each state CalculateBIC(deltaBIC, features , allMixtureMeans, allMixtureVars, numStates, totalNumFeatures, newStateSeq, numMixEachState , numElemEachState, posterior); int min_i =0, min_j = 0; float min = 99999999; // find minimum delta BIC states for(j = 0; j < *numStates; j++){ for(k = j+1; k < *numStates; k++){ if(deltaBIC[j][k] < min){ min = deltaBIC[j][k]; min_i = j; min_j = k; } } } printf("min_i: %d min_j: %d minDBIC: %f\n", min_i, min_j, deltaBIC[min_i][min_j]); // if no two states can be merged set the flag to False to terminate process if(deltaBIC[min_i][min_j] >= 0){ printf("We need to stop now ..... Final no of states: %d\n", *numStates); flag = 0; } // Merge two states if(flag) MergeTwoStates( min_i, min_j, allMixtureMeans, allMixtureVars, numStates, numMixEachState, numElemEachState, Pi, totalNumFeatures, features, newStateSeq, mixtureWeight); /*printf("Means after Merging of two states.................\n"); PrintAllDetails(numStates, numMixEachState, numElemEachState, mixtureElemCount, allMixtureMeans);*/ for(i = 0; i < *numStates; i++) printf("mix[%d]: %d\n", i, numMixEachState[i]); } //WRITE PLOT_File to plot distribution of each data point writePlotFile(posterior, totalNumFeatures, numStates); //WRITE RTTM FILE writeRTTMFile(newStateSeq, numStates, totalNumFeatures, numElemEachState); }
int main (int argc, char* argv[]) { BoxLib::Initialize(argc,argv); // What time is it now? We'll use this to compute total run time. Real strt_time = ParallelDescriptor::second(); std::cout << std::setprecision(15); // ParmParse is way of reading inputs from the inputs file ParmParse pp; int verbose = 0; pp.query("verbose", verbose); // We need to get n_cell from the inputs file - this is the number of cells on each side of // a square (or cubic) domain. int n_cell; pp.get("n_cell",n_cell); int max_grid_size; pp.get("max_grid_size",max_grid_size); // Default plot_int to 1, allow us to set it to something else in the inputs file // If plot_int < 0 then no plot files will be written int plot_int = 1; pp.query("plot_int",plot_int); // Default nsteps to 0, allow us to set it to something else in the inputs file int nsteps = 0; pp.query("nsteps",nsteps); pp.query("do_tiling", do_tiling); // Define a single box covering the domain IntVect dom_lo(0,0,0); IntVect dom_hi(n_cell-1,n_cell-1,n_cell-1); Box domain(dom_lo,dom_hi); // Initialize the boxarray "bs" from the single box "bx" BoxArray bs(domain); // Break up boxarray "bs" into chunks no larger than "max_grid_size" along a direction bs.maxSize(max_grid_size); // This defines the physical size of the box. Right now the box is [-1,1] in each direction. RealBox real_box; for (int n = 0; n < BL_SPACEDIM; n++) { real_box.setLo(n,-1.0); real_box.setHi(n, 1.0); } // This says we are using Cartesian coordinates int coord = 0; // This sets the boundary conditions to be doubly or triply periodic int is_per[BL_SPACEDIM]; for (int i = 0; i < BL_SPACEDIM; i++) is_per[i] = 1; // This defines a Geometry object which is useful for writing the plotfiles Geometry geom(domain,&real_box,coord,is_per); // This defines the mesh spacing Real dx[BL_SPACEDIM]; for ( int n=0; n<BL_SPACEDIM; n++ ) dx[n] = ( geom.ProbHi(n) - geom.ProbLo(n) )/domain.length(n); // Nghost = number of ghost cells for each array int Nghost = 1; // Ncomp = number of components for each array int Ncomp = 1; pp.query("ncomp", Ncomp); // Allocate space for the old_phi and new_phi -- we define old_phi and new_phi as PArray < MultiFab > phis(2, PArrayManage); phis.set(0, new MultiFab(bs, Ncomp, Nghost)); phis.set(1, new MultiFab(bs, Ncomp, Nghost)); MultiFab* old_phi = &phis[0]; MultiFab* new_phi = &phis[1]; // Initialize both to zero (just because) old_phi->setVal(0.0); new_phi->setVal(0.0); // Initialize phi by calling a Fortran routine. // MFIter = MultiFab Iterator #ifdef _OPENMP #pragma omp parallel #endif for ( MFIter mfi(*new_phi,true); mfi.isValid(); ++mfi ) { const Box& bx = mfi.tilebox(); init_phi(bx.loVect(),bx.hiVect(), BL_TO_FORTRAN((*new_phi)[mfi]),Ncomp, dx,geom.ProbLo(),geom.ProbHi()); } // Call the compute_dt routine to return a time step which we will pass to advance Real dt = compute_dt(dx[0]); // Write a plotfile of the initial data if plot_int > 0 (plot_int was defined in the inputs file) if (plot_int > 0) { int n = 0; const std::string& pltfile = BoxLib::Concatenate("plt",n,5); writePlotFile(pltfile, *new_phi, geom); } Real adv_start_time = ParallelDescriptor::second(); for (int n = 1; n <= nsteps; n++) { // Swap the pointers so we don't have to allocate and de-allocate data std::swap(old_phi, new_phi); // new_phi = old_phi + dt * (something) advance(old_phi, new_phi, dx, dt, geom); // Tell the I/O Processor to write out which step we're doing if (verbose && ParallelDescriptor::IOProcessor()) std::cout << "Advanced step " << n << std::endl; // Write a plotfile of the current data (plot_int was defined in the inputs file) if (plot_int > 0 && n%plot_int == 0) { const std::string& pltfile = BoxLib::Concatenate("plt",n,5); writePlotFile(pltfile, *new_phi, geom); } } // Call the timer again and compute the maximum difference between the start time and stop time // over all processors Real advance_time = ParallelDescriptor::second() - adv_start_time; Real stop_time = ParallelDescriptor::second() - strt_time; const int IOProc = ParallelDescriptor::IOProcessorNumber(); ParallelDescriptor::ReduceRealMax(stop_time,IOProc); ParallelDescriptor::ReduceRealMax(advance_time,IOProc); ParallelDescriptor::ReduceRealMax(kernel_time,IOProc); ParallelDescriptor::ReduceRealMax(FB_time,IOProc); // Tell the I/O Processor to write out the "run time" if (ParallelDescriptor::IOProcessor()) { std::cout << "Kernel time = " << kernel_time << std::endl; std::cout << "FB time = " << FB_time << std::endl; std::cout << "Advance time = " << advance_time << std::endl; std::cout << "Total run time = " << stop_time << std::endl; } // Say goodbye to MPI, etc... BoxLib::Finalize(); }
void main_main () { // What time is it now? We'll use this to compute total run time. Real strt_time = ParallelDescriptor::second(); std::cout << std::setprecision(15); int n_cell, max_grid_size, nsteps, plot_int, is_periodic[BL_SPACEDIM]; // Boundary conditions Array<int> lo_bc(BL_SPACEDIM), hi_bc(BL_SPACEDIM); // inputs parameters { // ParmParse is way of reading inputs from the inputs file ParmParse pp; // We need to get n_cell from the inputs file - this is the number of cells on each side of // a square (or cubic) domain. pp.get("n_cell",n_cell); // Default nsteps to 0, allow us to set it to something else in the inputs file pp.get("max_grid_size",max_grid_size); // Default plot_int to 1, allow us to set it to something else in the inputs file // If plot_int < 0 then no plot files will be written plot_int = 1; pp.query("plot_int",plot_int); // Default nsteps to 0, allow us to set it to something else in the inputs file nsteps = 0; pp.query("nsteps",nsteps); // Boundary conditions - default is periodic (INT_DIR) for (int i = 0; i < BL_SPACEDIM; ++i) { lo_bc[i] = hi_bc[i] = INT_DIR; // periodic boundaries are interior boundaries } pp.queryarr("lo_bc",lo_bc,0,BL_SPACEDIM); pp.queryarr("hi_bc",hi_bc,0,BL_SPACEDIM); } // make BoxArray and Geometry BoxArray ba; Geometry geom; { IntVect dom_lo(IntVect(D_DECL(0,0,0))); IntVect dom_hi(IntVect(D_DECL(n_cell-1, n_cell-1, n_cell-1))); Box domain(dom_lo, dom_hi); // Initialize the boxarray "ba" from the single box "bx" ba.define(domain); // Break up boxarray "ba" into chunks no larger than "max_grid_size" along a direction ba.maxSize(max_grid_size); // This defines the physical size of the box. Right now the box is [-1,1] in each direction. RealBox real_box; for (int n = 0; n < BL_SPACEDIM; n++) { real_box.setLo(n,-1.0); real_box.setHi(n, 1.0); } // This says we are using Cartesian coordinates int coord = 0; // This sets the boundary conditions to be doubly or triply periodic int is_periodic[BL_SPACEDIM]; for (int i = 0; i < BL_SPACEDIM; i++) { is_periodic[i] = 0; if (lo_bc[i] == 0 && hi_bc[i] == 0) { is_periodic[i] = 1; } } // This defines a Geometry object geom.define(domain,&real_box,coord,is_periodic); } // Boundary conditions PhysBCFunct physbcf; BCRec bcr(&lo_bc[0], &hi_bc[0]); physbcf.define(geom, bcr, BndryFunctBase(phifill)); // phifill is a fortran function // define dx[] const Real* dx = geom.CellSize(); // Nghost = number of ghost cells for each array int Nghost = 1; // Ncomp = number of components for each array int Ncomp = 1; // time = starting time in the simulation Real time = 0.0; // we allocate two phi multifabs; one will store the old state, the other the new // we swap the indices each time step to avoid copies of new into old PArray<MultiFab> phi(2, PArrayManage); phi.set(0, new MultiFab(ba, Ncomp, Nghost)); phi.set(1, new MultiFab(ba, Ncomp, Nghost)); // Initialize both to zero (just because) phi[0].setVal(0.0); phi[1].setVal(0.0); // Initialize phi[init_index] by calling a Fortran routine. // MFIter = MultiFab Iterator int init_index = 0; for ( MFIter mfi(phi[init_index]); mfi.isValid(); ++mfi ) { const Box& bx = mfi.validbox(); init_phi(phi[init_index][mfi].dataPtr(), bx.loVect(), bx.hiVect(), &Nghost, geom.CellSize(), geom.ProbLo(), geom.ProbHi()); } // compute the time step Real dt = 0.9*dx[0]*dx[0] / (2.0*BL_SPACEDIM); // Write a plotfile of the initial data if plot_int > 0 (plot_int was defined in the inputs file) if (plot_int > 0) { int n = 0; const std::string& pltfile = BoxLib::Concatenate("plt",n,5); writePlotFile(pltfile, phi[init_index], geom, time); } // build the flux multifabs PArray<MultiFab> flux(BL_SPACEDIM, PArrayManage); for (int dir = 0; dir < BL_SPACEDIM; dir++) { // flux(dir) has one component, zero ghost cells, and is nodal in direction dir BoxArray edge_ba = ba; edge_ba.surroundingNodes(dir); flux.set(dir, new MultiFab(edge_ba, 1, 0)); } int old_index = init_index; for (int n = 1; n <= nsteps; n++, old_index = 1 - old_index) { int new_index = 1 - old_index; // new_phi = old_phi + dt * (something) advance(phi[old_index], phi[new_index], flux, time, dt, geom, physbcf, bcr); time = time + dt; // Tell the I/O Processor to write out which step we're doing if (ParallelDescriptor::IOProcessor()) std::cout << "Advanced step " << n << std::endl; // Write a plotfile of the current data (plot_int was defined in the inputs file) if (plot_int > 0 && n%plot_int == 0) { const std::string& pltfile = BoxLib::Concatenate("plt",n,5); writePlotFile(pltfile, phi[new_index], geom, time); } } // Call the timer again and compute the maximum difference between the start time and stop time // over all processors Real stop_time = ParallelDescriptor::second() - strt_time; const int IOProc = ParallelDescriptor::IOProcessorNumber(); ParallelDescriptor::ReduceRealMax(stop_time,IOProc); // Tell the I/O Processor to write out the "run time" if (ParallelDescriptor::IOProcessor()) { std::cout << "Run time = " << stop_time << std::endl; } }
int main (int argc, char* argv[]) { BoxLib::Initialize(argc,argv); // What time is it now? We'll use this to compute total run time. Real strt_time = ParallelDescriptor::second(); std::cout << std::setprecision(15); // ParmParse is way of reading inputs from the inputs file ParmParse pp; // We need to get n_cell from the inputs file - this is the number of cells on each side of // a square (or cubic) domain. int n_cell; pp.get("n_cell",n_cell); // Default nsteps to 0, allow us to set it to something else in the inputs file int max_grid_size; pp.get("max_grid_size",max_grid_size); // Default plot_int to 1, allow us to set it to something else in the inputs file // If plot_int < 0 then no plot files will be written int plot_int = 1; pp.query("plot_int",plot_int); // Default nsteps to 0, allow us to set it to something else in the inputs file int nsteps = 0; pp.query("nsteps",nsteps); // Define a single box covering the domain #if (BL_SPACEDIM == 2) IntVect dom_lo(0,0); IntVect dom_hi(n_cell-1,n_cell-1); #else IntVect dom_lo(0,0,0); IntVect dom_hi(n_cell-1,n_cell-1,n_cell-1); #endif Box domain(dom_lo,dom_hi); // Initialize the boxarray "bs" from the single box "bx" BoxArray bs(domain); // Break up boxarray "bs" into chunks no larger than "max_grid_size" along a direction bs.maxSize(max_grid_size); // This defines the physical size of the box. Right now the box is [-1,1] in each direction. RealBox real_box; for (int n = 0; n < BL_SPACEDIM; n++) { real_box.setLo(n,-1.0); real_box.setHi(n, 1.0); } // This says we are using Cartesian coordinates int coord = 0; // This sets the boundary conditions to be doubly or triply periodic int is_per[BL_SPACEDIM]; for (int i = 0; i < BL_SPACEDIM; i++) is_per[i] = 1; // This defines a Geometry object which is useful for writing the plotfiles Geometry geom(domain,&real_box,coord,is_per); // This defines the mesh spacing Real dx[BL_SPACEDIM]; for ( int n=0; n<BL_SPACEDIM; n++ ) dx[n] = ( geom.ProbHi(n) - geom.ProbLo(n) )/domain.length(n); // Nghost = number of ghost cells for each array int Nghost = 1; // Ncomp = number of components for each array int Ncomp = 1; // Make sure we can fill the ghost cells from the adjacent grid if (Nghost > max_grid_size) std::cout << "NGHOST < MAX_GRID_SIZE -- grids are too small! " << std::endl; // Allocate space for the old_phi and new_phi -- we define old_phi and new_phi as // pointers to the MultiFabs MultiFab* old_phi = new MultiFab(bs, Ncomp, Nghost); MultiFab* new_phi = new MultiFab(bs, Ncomp, Nghost); // Initialize both to zero (just because) old_phi->setVal(0.0); new_phi->setVal(0.0); // Initialize the old_phi by calling a Fortran routine. // MFIter = MultiFab Iterator for ( MFIter mfi(*new_phi); mfi.isValid(); ++mfi ) { const Box& bx = mfi.validbox(); FORT_INIT_PHI((*new_phi)[mfi].dataPtr(), bx.loVect(),bx.hiVect(), &Nghost, dx,geom.ProbLo(),geom.ProbHi()); } // Call the compute_dt routine to return a time step which we will pass to advance Real dt = compute_dt(dx[0]); // Write a plotfile of the initial data if plot_int > 0 (plot_int was defined in the inputs file) if (plot_int > 0) { int n = 0; const std::string& pltfile = BoxLib::Concatenate("plt",n,5); writePlotFile(pltfile, *new_phi, geom); } // build the flux multifabs MultiFab* flux = new MultiFab[BL_SPACEDIM]; for (int dir = 0; dir < BL_SPACEDIM; dir++) { BoxArray edge_grids(bs); // flux(dir) has one component, zero ghost cells, and is nodal in direction dir edge_grids.surroundingNodes(dir); flux[dir].define(edge_grids,1,0,Fab_allocate); } for (int n = 1; n <= nsteps; n++) { // Swap the pointers so we don't have to allocate and de-allocate data std::swap(old_phi, new_phi); // new_phi = old_phi + dt * (something) advance(old_phi, new_phi, flux, dx, dt, geom); // Tell the I/O Processor to write out which step we're doing if (ParallelDescriptor::IOProcessor()) std::cout << "Advanced step " << n << std::endl; // Write a plotfile of the current data (plot_int was defined in the inputs file) if (plot_int > 0 && n%plot_int == 0) { const std::string& pltfile = BoxLib::Concatenate("plt",n,5); writePlotFile(pltfile, *new_phi, geom); } } // Call the timer again and compute the maximum difference between the start time and stop time // over all processors Real stop_time = ParallelDescriptor::second() - strt_time; const int IOProc = ParallelDescriptor::IOProcessorNumber(); ParallelDescriptor::ReduceRealMax(stop_time,IOProc); // Tell the I/O Processor to write out the "run time" if (ParallelDescriptor::IOProcessor()) std::cout << "Run time = " << stop_time << std::endl; // Say goodbye to MPI, etc... BoxLib::Finalize(); }
int main(int argc, char* argv[]) { BoxLib::Initialize(argc,argv); BL_PROFILE_VAR("main()", pmain); std::cout << std::setprecision(15); ParmParse ppmg("mg"); ppmg.query("v", verbose); ppmg.query("maxorder", maxorder); ParmParse pp; { std::string solver_type_s; pp.get("solver_type",solver_type_s); if (solver_type_s == "BoxLib_C") { solver_type = BoxLib_C; } else if (solver_type_s == "BoxLib_C4") { solver_type = BoxLib_C4; } else if (solver_type_s == "BoxLib_F") { #ifdef USE_F90_SOLVERS solver_type = BoxLib_F; #else BoxLib::Error("Set USE_FORTRAN=TRUE in GNUmakefile"); #endif } else if (solver_type_s == "Hypre") { #ifdef USEHYPRE solver_type = Hypre; #else BoxLib::Error("Set USE_HYPRE=TRUE in GNUmakefile"); #endif } else if (solver_type_s == "All") { solver_type = All; } else { if (ParallelDescriptor::IOProcessor()) { std::cout << "Don't know this solver type: " << solver_type << std::endl; } BoxLib::Error(""); } } { std::string bc_type_s; pp.get("bc_type",bc_type_s); if (bc_type_s == "Dirichlet") { bc_type = Dirichlet; #ifdef USEHPGMG domain_boundary_condition = BC_DIRICHLET; #endif } else if (bc_type_s == "Neumann") { bc_type = Neumann; #ifdef USEHPGMG BoxLib::Error("HPGMG does not support Neumann boundary conditions"); #endif } else if (bc_type_s == "Periodic") { bc_type = Periodic; #ifdef USEHPGMG domain_boundary_condition = BC_PERIODIC; #endif } else { if (ParallelDescriptor::IOProcessor()) { std::cout << "Don't know this boundary type: " << bc_type << std::endl; } BoxLib::Error(""); } } pp.query("tol_rel", tolerance_rel); pp.query("tol_abs", tolerance_abs); pp.query("maxiter", maxiter); pp.query("plot_rhs" , plot_rhs); pp.query("plot_beta", plot_beta); pp.query("plot_soln", plot_soln); pp.query("plot_asol", plot_asol); pp.query("plot_err", plot_err); pp.query("comp_norm", comp_norm); Real a, b; pp.get("a", a); pp.get("b", b); pp.get("n_cell",n_cell); pp.get("max_grid_size",max_grid_size); // Define a single box covering the domain IntVect dom_lo(D_DECL(0,0,0)); IntVect dom_hi(D_DECL(n_cell-1,n_cell-1,n_cell-1)); Box domain(dom_lo,dom_hi); // Initialize the boxarray "bs" from the single box "bx" BoxArray bs(domain); // Break up boxarray "bs" into chunks no larger than "max_grid_size" along a direction bs.maxSize(max_grid_size); // This defines the physical size of the box. Right now the box is [0,1] in each direction. RealBox real_box; for (int n = 0; n < BL_SPACEDIM; n++) { real_box.setLo(n, 0.0); real_box.setHi(n, 1.0); } // This says we are using Cartesian coordinates int coord = 0; // This sets the boundary conditions to be periodic or not Array<int> is_per(BL_SPACEDIM,1); if (bc_type == Dirichlet || bc_type == Neumann) { if (ParallelDescriptor::IOProcessor()) { std::cout << "Using Dirichlet or Neumann boundary conditions." << std::endl; } for (int n = 0; n < BL_SPACEDIM; n++) is_per[n] = 0; } else { if (ParallelDescriptor::IOProcessor()) { std::cout << "Using periodic boundary conditions." << std::endl; } for (int n = 0; n < BL_SPACEDIM; n++) is_per[n] = 1; } // This defines a Geometry object which is useful for writing the plotfiles Geometry geom(domain,&real_box,coord,is_per.dataPtr()); for ( int n=0; n<BL_SPACEDIM; n++ ) { dx[n] = ( geom.ProbHi(n) - geom.ProbLo(n) )/domain.length(n); } if (ParallelDescriptor::IOProcessor()) { std::cout << "Grid resolution : " << n_cell << " (cells)" << std::endl; std::cout << "Domain size : " << real_box.hi(0) - real_box.lo(0) << " (length unit) " << std::endl; std::cout << "Max_grid_size : " << max_grid_size << " (cells)" << std::endl; std::cout << "Number of grids : " << bs.size() << std::endl; } // Allocate and define the right hand side. bool do_4th = (solver_type==BoxLib_C4 || solver_type==All); int ngr = (do_4th ? 1 : 0); MultiFab rhs(bs, Ncomp, ngr); setup_rhs(rhs, geom); // Set up the Helmholtz operator coefficients. MultiFab alpha(bs, Ncomp, 0); PArray<MultiFab> beta(BL_SPACEDIM, PArrayManage); for ( int n=0; n<BL_SPACEDIM; ++n ) { BoxArray bx(bs); beta.set(n, new MultiFab(bx.surroundingNodes(n), Ncomp, 0, Fab_allocate)); } // The way HPGMG stores face-centered data is completely different than the // way BoxLib does it, and translating between the two directly via indexing // magic is a nightmare. Happily, the way this tutorial calculates // face-centered values is by first calculating cell-centered values and then // interpolating to the cell faces. HPGMG can do the same thing, so rather // than converting directly from BoxLib's face-centered data to HPGMG's, just // give HPGMG the cell-centered data and let it interpolate itself. MultiFab beta_cc(bs,Ncomp,1); // cell-centered beta setup_coeffs(bs, alpha, beta, geom, beta_cc); MultiFab alpha4, beta4; if (do_4th) { alpha4.define(bs, Ncomp, 4, Fab_allocate); beta4.define(bs, Ncomp, 3, Fab_allocate); setup_coeffs4(bs, alpha4, beta4, geom); } MultiFab anaSoln; if (comp_norm || plot_err || plot_asol) { anaSoln.define(bs, Ncomp, 0, Fab_allocate); compute_analyticSolution(anaSoln,Array<Real>(BL_SPACEDIM,0.5)); if (plot_asol) { writePlotFile("ASOL", anaSoln, geom); } } // Allocate the solution array // Set the number of ghost cells in the solution array. MultiFab soln(bs, Ncomp, 1); MultiFab soln4; if (do_4th) { soln4.define(bs, Ncomp, 3, Fab_allocate); } MultiFab gphi(bs, BL_SPACEDIM, 0); #ifdef USEHYPRE if (solver_type == Hypre || solver_type == All) { if (ParallelDescriptor::IOProcessor()) { std::cout << "----------------------------------------" << std::endl; std::cout << "Solving with Hypre " << std::endl; } solve(soln, anaSoln, gphi, a, b, alpha, beta, beta_cc, rhs, bs, geom, Hypre); } #endif if (solver_type == BoxLib_C || solver_type == All) { if (ParallelDescriptor::IOProcessor()) { std::cout << "----------------------------------------" << std::endl; std::cout << "Solving with BoxLib C++ solver " << std::endl; } solve(soln, anaSoln, gphi, a, b, alpha, beta, beta_cc, rhs, bs, geom, BoxLib_C); } if (solver_type == BoxLib_C4 || solver_type == All) { if (ParallelDescriptor::IOProcessor()) { std::cout << "----------------------------------------" << std::endl; std::cout << "Solving with BoxLib C++ 4th order solver " << std::endl; } solve4(soln4, anaSoln, a, b, alpha4, beta4, rhs, bs, geom); } #ifdef USE_F90_SOLVERS if (solver_type == BoxLib_F || solver_type == All) { if (ParallelDescriptor::IOProcessor()) { std::cout << "----------------------------------------" << std::endl; std::cout << "Solving with BoxLib F90 solver " << std::endl; } solve(soln, anaSoln, gphi, a, b, alpha, beta, beta_cc, rhs, bs, geom, BoxLib_F); } #endif #ifdef USEHPGMG if (solver_type == HPGMG || solver_type == All) { if (ParallelDescriptor::IOProcessor()) { std::cout << "----------------------------------------" << std::endl; std::cout << "Solving with HPGMG solver " << std::endl; } solve(soln, anaSoln, gphi, a, b, alpha, beta, beta_cc, rhs, bs, geom, HPGMG); } #endif if (ParallelDescriptor::IOProcessor()) { std::cout << "----------------------------------------" << std::endl; } BL_PROFILE_VAR_STOP(pmain); BoxLib::Finalize(); }
void solve_with_HPGMG(MultiFab& soln, MultiFab& gphi, Real a, Real b, MultiFab& alpha, PArray<MultiFab>& beta, MultiFab& beta_cc, MultiFab& rhs, const BoxArray& bs, const Geometry& geom, int n_cell) { BndryData bd(bs, 1, geom); set_boundary(bd, rhs, 0); ABecLaplacian abec_operator(bd, dx); abec_operator.setScalars(a, b); abec_operator.setCoefficients(alpha, beta); int minCoarseDim; if (domain_boundary_condition == BC_PERIODIC) { minCoarseDim = 2; // avoid problems with black box calculation of D^{-1} for poisson with periodic BC's on a 1^3 grid } else { minCoarseDim = 1; // assumes you can drop order on the boundaries } level_type level_h; mg_type MG_h; int numVectors = 12; int my_rank = 0, num_ranks = 1; #ifdef BL_USE_MPI MPI_Comm_size (MPI_COMM_WORLD, &num_ranks); MPI_Comm_rank (MPI_COMM_WORLD, &my_rank); #endif /* BL_USE_MPI */ const double h0 = dx[0]; // Create the geometric structure of the HPGMG grid using the RHS MultiFab as // a template. This doesn't copy any actual data. CreateHPGMGLevel(&level_h, rhs, n_cell, max_grid_size, my_rank, num_ranks, domain_boundary_condition, numVectors, h0); // Set up the coefficients for the linear operator L. SetupHPGMGCoefficients(a, b, alpha, beta_cc, &level_h); // Now that the HPGMG grid is built, populate it with RHS data. ConvertToHPGMGLevel(rhs, n_cell, max_grid_size, &level_h, VECTOR_F); #ifdef USE_HELMHOLTZ if (ParallelDescriptor::IOProcessor()) { std::cout << "Creating Helmholtz (a=" << a << ", b=" << b << ") test problem" << std::endl;; } #else if (ParallelDescriptor::IOProcessor()) { std::cout << "Creating Poisson (a=" << a << ", b=" << b << ") test problem" << std::endl;; } #endif /* USE_HELMHOLTZ */ if (level_h.boundary_condition.type == BC_PERIODIC) { double average_value_of_f = mean (&level_h, VECTOR_F); if (average_value_of_f != 0.0) { if (ParallelDescriptor::IOProcessor()) { std::cerr << "WARNING: Periodic boundary conditions, but f does not sum to zero... mean(f)=" << average_value_of_f << std::endl; } //shift_vector(&level_h,VECTOR_F,VECTOR_F,-average_value_of_f); } } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - rebuild_operator(&level_h,NULL,a,b); // i.e. calculate Dinv and lambda_max MGBuild(&MG_h,&level_h,a,b,minCoarseDim,ParallelDescriptor::Communicator()); // build the Multigrid Hierarchy //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (ParallelDescriptor::IOProcessor()) std::cout << std::endl << std::endl << "===== STARTING SOLVE =====" << std::endl << std::flush; MGResetTimers (&MG_h); zero_vector (MG_h.levels[0], VECTOR_U); #ifdef USE_FCYCLES FMGSolve (&MG_h, 0, VECTOR_U, VECTOR_F, a, b, tolerance_abs, tolerance_rel); #else MGSolve (&MG_h, 0, VECTOR_U, VECTOR_F, a, b, tolerance_abs, tolerance_rel); #endif /* USE_FCYCLES */ MGPrintTiming (&MG_h, 0); // don't include the error check in the timing results //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (ParallelDescriptor::IOProcessor()) std::cout << std::endl << std::endl << "===== Performing Richardson error analysis ==========================" << std::endl; // solve A^h u^h = f^h // solve A^2h u^2h = f^2h // solve A^4h u^4h = f^4h // error analysis... MGResetTimers(&MG_h); const double dtol = tolerance_abs; const double rtol = tolerance_rel; int l;for(l=0;l<3;l++){ if(l>0)restriction(MG_h.levels[l],VECTOR_F,MG_h.levels[l-1],VECTOR_F,RESTRICT_CELL); zero_vector(MG_h.levels[l],VECTOR_U); #ifdef USE_FCYCLES FMGSolve(&MG_h,l,VECTOR_U,VECTOR_F,a,b,dtol,rtol); #else MGSolve(&MG_h,l,VECTOR_U,VECTOR_F,a,b,dtol,rtol); #endif } richardson_error(&MG_h,0,VECTOR_U); // Now convert solution from HPGMG back to rhs MultiFab. ConvertFromHPGMGLevel(soln, &level_h, VECTOR_U); const double norm_from_HPGMG = norm(&level_h, VECTOR_U); const double mean_from_HPGMG = mean(&level_h, VECTOR_U); const Real norm0 = soln.norm0(); const Real norm2 = soln.norm2(); if (ParallelDescriptor::IOProcessor()) { std::cout << "mean from HPGMG: " << mean_from_HPGMG << std::endl; std::cout << "norm from HPGMG: " << norm_from_HPGMG << std::endl; std::cout << "norm0 of RHS copied to MF: " << norm0 << std::endl; std::cout << "norm2 of RHS copied to MF: " << norm2 << std::endl; } // Write the MF to disk for comparison with the in-house solver if (plot_soln) { writePlotFile("SOLN-HPGMG", soln, geom); } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MGDestroy(&MG_h); destroy_level(&level_h); //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PArray<MultiFab> grad_phi(BL_SPACEDIM, PArrayManage); for (int n = 0; n < BL_SPACEDIM; ++n) grad_phi.set(n, new MultiFab(BoxArray(soln.boxArray()).surroundingNodes(n), 1, 0)); #if (BL_SPACEDIM == 2) abec_operator.compFlux(grad_phi[0],grad_phi[1],soln); #elif (BL_SPACEDIM == 3) abec_operator.compFlux(grad_phi[0],grad_phi[1],grad_phi[2],soln); #endif // Average edge-centered gradients to cell centers. BoxLib::average_face_to_cellcenter(gphi, grad_phi, geom); }
void solve(MultiFab& soln, const MultiFab& anaSoln, MultiFab& gphi, Real a, Real b, MultiFab& alpha, PArray<MultiFab>& beta, MultiFab& beta_cc, MultiFab& rhs, const BoxArray& bs, const Geometry& geom, solver_t solver) { BL_PROFILE("solve()"); std::string ss; soln.setVal(0.0); const Real run_strt = ParallelDescriptor::second(); if (solver == BoxLib_C) { ss = "CPP"; solve_with_Cpp(soln, gphi, a, b, alpha, beta, rhs, bs, geom); } #ifdef USE_F90_SOLVERS else if (solver == BoxLib_F) { ss = "F90"; solve_with_F90(soln, gphi, a, b, alpha, beta, rhs, bs, geom); } #endif #ifdef USEHYPRE else if (solver == Hypre) { ss = "Hyp"; solve_with_hypre(soln, a, b, alpha, beta, rhs, bs, geom); } #endif #ifdef USEHPGMG else if (solver == HPGMG) { ss = "HPGMG"; solve_with_HPGMG(soln, gphi, a, b, alpha, beta, beta_cc, rhs, bs, geom, n_cell); } #endif else { BoxLib::Error("Invalid solver"); } Real run_time = ParallelDescriptor::second() - run_strt; ParallelDescriptor::ReduceRealMax(run_time, ParallelDescriptor::IOProcessorNumber()); if (ParallelDescriptor::IOProcessor()) { std::cout << " Run time : " << run_time << std::endl; } if (plot_soln) { writePlotFile("SOLN-"+ss, soln, geom); writePlotFile("GPHI-"+ss, gphi, geom); } if (plot_err || comp_norm) { soln.minus(anaSoln, 0, Ncomp, 0); // soln contains errors now MultiFab& err = soln; if (plot_err) { writePlotFile("ERR-"+ss, soln, geom); } if (comp_norm) { Real twoNorm = err.norm2(); Real maxNorm = err.norm0(); err.setVal(1.0); Real vol = err.norm2(); twoNorm /= vol; if (ParallelDescriptor::IOProcessor()) { std::cout << " 2 norm error : " << twoNorm << std::endl; std::cout << " max norm error: " << maxNorm << std::endl; } } } }
void solve4(MultiFab& soln, const MultiFab& anaSoln, Real a, Real b, MultiFab& alpha, MultiFab& beta, MultiFab& rhs, const BoxArray& bs, const Geometry& geom) { std::string ss = "CPP"; soln.setVal(0.0); const Real run_strt = ParallelDescriptor::second(); BndryData bd(bs, 1, geom); set_boundary(bd, rhs, 0); ABec4 abec_operator(bd, dx); abec_operator.setScalars(a, b); MultiFab betaca(bs,1,2); ABec4::cc2ca(beta,betaca,0,0,1); MultiFab alphaca(bs,1,2); ABec4::cc2ca(alpha,alphaca,0,0,1); abec_operator.setCoefficients(alphaca, betaca); MultiFab rhsca(bs,1,0); ABec4::cc2ca(rhs,rhsca,0,0,1); MultiFab out(bs,1,0); compute_analyticSolution(soln,Array<Real>(BL_SPACEDIM,0.5)); MultiFab solnca(bs,1,2); solnca.setVal(0); MultiGrid mg(abec_operator); mg.setVerbose(verbose); mg.solve(solnca, rhsca, tolerance_rel, tolerance_abs); Real run_time = ParallelDescriptor::second() - run_strt; ParallelDescriptor::ReduceRealMax(run_time, ParallelDescriptor::IOProcessorNumber()); if (ParallelDescriptor::IOProcessor()) { std::cout << " Run time : " << run_time << std::endl; } if (plot_soln) { writePlotFile("SOLN-"+ss, solnca, geom); } if (plot_err || comp_norm) { soln.minus(anaSoln, 0, Ncomp, 0); // soln contains errors now MultiFab& err = soln; if (plot_err) { writePlotFile("ERR-"+ss, soln, geom); } if (comp_norm) { Real twoNorm = err.norm2(); Real maxNorm = err.norm0(); err.setVal(1.0); Real vol = err.norm2(); twoNorm /= vol; if (ParallelDescriptor::IOProcessor()) { std::cout << " 2 norm error : " << twoNorm << std::endl; std::cout << " max norm error: " << maxNorm << std::endl; } } } }
void SMC::evolve () { int istep = 0; int last_plt_written = -1; if (plot_int > 0) { writePlotFile(istep); last_plt_written = istep; } int init_step = 1; if (ParallelDescriptor::IOProcessor()) { std::cout << "\n" << "BEGIN MAIN EVOLUTION LOOP" << "\n" << std::endl; } ParallelDescriptor::Barrier(); Real wt0 = ParallelDescriptor::second(); if ( (max_step >= init_step) && (t < stop_time || stop_time < 0.0) ) { for (istep = init_step; istep <= max_step; ++istep) { if (ParallelDescriptor::IOProcessor()) { std::cout << "Advancing time step " << istep << " time = " << t << "\n"; } advance(istep); t = t + dt; if (ParallelDescriptor::IOProcessor()) { std::cout << "End of step " << istep << " time = " << t << "\n" << std::endl; } if (plot_int > 0 && istep%plot_int == 0) { writePlotFile(istep); last_plt_written = istep; } if (stop_time >= 0.0 && t >= stop_time) { break; } } if (istep > max_step) istep = max_step; if (plot_int > 0 && last_plt_written != istep) { writePlotFile(istep); } } #ifdef BL_USE_UPCXX upcxx::barrier(); #else ParallelDescriptor::Barrier(); #endif Real wt1 = ParallelDescriptor::second(); Real wt_fb = wt_fb1 + wt_fb2; Real wt_chem = wt_chem1 + wt_chem2; ParallelDescriptor::ReduceRealMax(wt_fb , ParallelDescriptor::IOProcessorNumber()); ParallelDescriptor::ReduceRealMax(wt_chem , ParallelDescriptor::IOProcessorNumber()); ParallelDescriptor::ReduceRealMax(wt_hypdiff, ParallelDescriptor::IOProcessorNumber()); if (ParallelDescriptor::IOProcessor()) { std::cout << "======================================" << std::endl; std::cout << " Total Time : " << wt1-wt0 << "\n"; std::cout << " Communication time: " << wt_fb << "\n"; std::cout << " Chemistry time: " << wt_chem << "\n"; std::cout << " Hyp-Diff time: " << wt_hypdiff << "\n"; std::cout << "======================================" << std::endl; } }