bool FastGauss::AllocateResources(long lines, long cols, double scale) { if(IsAllocated()) FreeResources(); m_i_lines = lines; m_i_cols = cols; if(scale < 0.5) { throw "Scale values lower than 0.5 are not alowed"; } if(scale > 100) { throw "Danger: Bad Approximation for scale values higher than 100"; } m_scale = scale; //allocation of level structures - filter poles, coefficients, residues filt_poles = new complex<double>[5]; //max 5 complex poles //filt_coeffs = (float*)malloc(6*sizeof(float)); //max 6 coeffs : 1 gain + 5 autoregressive terms filt_coeffs = new float[6]; //max 6 coeffs : 1 gain + 5 autoregressive terms //m_resid_step = (float*)malloc(3*sizeof(float)); m_resid_step = new float[3]; //m_resid_ic = (float*)malloc(9*sizeof(float)); m_resid_ic = new float[9]; //allocation of image buffers for computations m_i_stridepix = m_i_cols; stride = m_i_cols*4; //temp = (float*)malloc(m_i_lines*m_i_cols*sizeof(float)); temp = new float[m_i_lines*m_i_cols]; //compute filter poles, coefficients and boundary gaussian residues for each scale calc_poles(3,m_scale,d0_N3_Linf, filt_poles); calc_coeffs(3, filt_poles, filt_coeffs); _compute_gauss3_resids(filt_poles, filt_coeffs, m_resid_ic, m_resid_step); m_bAllocated = true; return true; }
template<class BASE> void pod_simulate<BASE>::init(input_map& inmap, void *gin) { std::string filename,keyword,linebuff; std::ostringstream nstr; std::istringstream instr; int i; /* Initialize base class */ /* If restart is not equal to 0, this will load DNS data */ BASE::init(inmap,gin); inmap.getwdefault(BASE::gbl->idprefix + "_groups",pod_id,0); nstr.str(""); nstr << "pod" << pod_id << "_nmodes"; if (!inmap.get(nstr.str(),nmodes)) inmap.getwdefault("nmodes",nmodes,5); nstr.clear(); vsi ugstore; ugstore.v.reference(BASE::ugbd(0).v); ugstore.s.reference(BASE::ugbd(0).s); ugstore.i.reference(BASE::ugbd(0).i); modes.resize(nmodes); for(i=0;i<nmodes;++i) { nstr.str(""); nstr << i << std::flush; filename = "mode" +nstr.str(); nstr.clear(); modes(i).v.resize(BASE::maxpst,BASE::NV); modes(i).s.resize(BASE::maxpst,BASE::sm0,BASE::NV); modes(i).i.resize(BASE::maxpst,BASE::im0,BASE::NV); BASE::ugbd(0).v.reference(modes(i).v); BASE::ugbd(0).s.reference(modes(i).s); BASE::ugbd(0).i.reference(modes(i).i); BASE::input(filename, BASE::binary); } BASE::ugbd(0).v.reference(ugstore.v); BASE::ugbd(0).s.reference(ugstore.s); BASE::ugbd(0).i.reference(ugstore.i); #ifdef POD_BDRY pod_ebdry.resize(BASE::nebd); /* Count how many boundary modes there are so we can size arrays before initializing boundaries */ /* For each mesh block that is part of this pod block need to know /* # of pod boundaries, ids, and # of pod modes for each unique id */ /* First need to know what block # I am and how many total blocks there are in this pod group */ int localid = sim::blks.allreduce_local_id(pod_id,BASE::gbl->idnum); int npodblk = sim::blks.allreduce_nmember(pod_id); Array<int,1> binfo(npodblk),binfo_recv(npodblk); binfo = 0; for (int i=0;i<BASE::nebd;++i) { /* Not going to initialize until I can resize coeffs & rsdls arrays to accomodate boundary modes */ pod_ebdry(i) = new pod_sim_edge_bdry<BASE>(*this,*BASE::ebdry(i)); keyword = pod_ebdry(i)->base.idprefix +"_pod"; inmap.getwdefault(keyword,pod_ebdry(i)->active,false); if (!pod_ebdry(i)->active) { pod_ebdry(i)->nmodes = 0; continue; } binfo(localid)++; keyword = pod_ebdry(i)->base.idprefix + "_pod_id"; inmap.getwdefault(keyword,pod_ebdry(i)->pod_id,pod_ebdry(i)->base.idnum); nstr.str(""); nstr << "bdry_pod" << pod_ebdry(i)->pod_id << "_nmodes"; if (!inmap.get(nstr.str(),pod_ebdry(i)->nmodes)) inmap.getwdefault("bdry_nmodes",pod_ebdry(i)->nmodes,nmodes); nstr.clear(); } /* Send number of pod boundaries belonging to each block of pod group */ sim::blks.allreduce(binfo.data(), binfo_recv.data(), npodblk,blocks::int_msg, blocks::sum, pod_id); /* Second thing is to pass id, nmodes for each active boundary */ /* Count # of pod_boundaries before this block and total # of pod boundaries in pod group */ int nbefore = 0; for (int i=0;i<localid;++i) { nbefore += binfo_recv(i); } int ntotal = nbefore; for (int i=localid;i<npodblk;++i) { ntotal += binfo_recv(i); } binfo.resize(ntotal*2); binfo_recv.resize(ntotal*2); nbefore *= 2; binfo = 0; for (int i=0;i<BASE::nebd;++i) { if (!pod_ebdry(i)->active) continue; binfo(nbefore++) = pod_ebdry(i)->pod_id; binfo(nbefore++) = pod_ebdry(i)->nmodes; } sim::blks.allreduce(binfo.data(), binfo_recv.data(), ntotal*2,blocks::int_msg, blocks::sum, pod_id); /* Now make a map from pod_id to number of modes & multiplicity */ std::map<int,bd_str> pod_bdry_map; tmodes = nmodes; for (int i=0;i<2*ntotal;i+=2) { if (pod_bdry_map.find(binfo_recv(i)) != pod_bdry_map.end()) { ++pod_bdry_map[binfo_recv(i)].multiplicity; } else { pod_bdry_map[binfo_recv(i)] = bd_str(); pod_bdry_map[binfo_recv(i)].multiplicity = 1; pod_bdry_map[binfo_recv(i)].nmodes = binfo_recv(i+1); tmodes += binfo_recv(i+1); } } *BASE::gbl->log << "#There are " << tmodes << " total modes on pod block " << pod_id << std::endl; multiplicity.resize(tmodes); #else tmodes = nmodes; #endif coeffs.resize(tmodes); rsdls.resize(tmodes); rsdls0.resize(tmodes); rsdls_recv.resize(tmodes); jacobian.resize(tmodes,tmodes); ipiv.resize(tmodes); #ifdef POD_BDRY /* Count total number of boundary modes */ /* and make map be an accrual of previous modes */ multiplicity = 1.0; int bindex = nmodes; for (std::map<int,bd_str>::iterator mi = pod_bdry_map.begin(); mi != pod_bdry_map.end(); ++mi) { int n = mi->second.nmodes; mi->second.nmodes = bindex; multiplicity(Range(bindex,bindex+n-1)) = mi->second.multiplicity; bindex += n; } #endif int load_coeffs; inmap.getwdefault("load_coeffs",load_coeffs,0); if (load_coeffs) { /* This is the old way */ /* This loads coefficient vector made by pod_generate for this timestep */ nstr.str(""); nstr << load_coeffs << std::flush; filename = "coeff" +nstr.str() +"_" +BASE::gbl->idprefix +".bin"; binifstream bin; bin.open(filename.c_str()); if (bin.error()) { *BASE::gbl->log << "couldn't open coefficient input file " << filename << std::endl; sim::abort(__LINE__,__FILE__,BASE::gbl->log); } bin.setFlag(binio::BigEndian,bin.readInt(1)); bin.setFlag(binio::FloatIEEE,bin.readInt(1)); /* CONSTRUCT INITIAL SOLUTION DESCRIPTION */ BASE::ug.v(Range(0,BASE::npnt-1)) = 0.; BASE::ug.s(Range(0,BASE::nseg-1)) = 0.; BASE::ug.i(Range(0,BASE::ntri-1)) = 0.; for (int l=0;l<nmodes;++l) { coeffs(l) = bin.readFloat(binio::Double); BASE::ug.v(Range(0,BASE::npnt-1)) += coeffs(l)*modes(l).v(Range(0,BASE::npnt-1)); BASE::ug.s(Range(0,BASE::nseg-1)) += coeffs(l)*modes(l).s(Range(0,BASE::nseg-1)); BASE::ug.i(Range(0,BASE::ntri-1)) += coeffs(l)*modes(l).i(Range(0,BASE::ntri-1)); } bin.close(); } else { /* THIS IS TO CHANGE THE WAY SNAPSHOT MATRIX ENTRIES ARE FORMED */ scaling.resize(BASE::NV); scaling = 1; if (inmap.getline(BASE::gbl->idprefix + "_scale_vector",linebuff) || inmap.getline("scale_vector",linebuff)) { instr.str(linebuff); for(i=0;i<BASE::NV;++i) instr >> scaling(i); } /* This is the new way */ calc_coeffs(); /* CONSTRUCT INITIAL SOLUTION DESCRIPTION */ BASE::ug.v(Range(0,BASE::npnt-1)) = 0.; BASE::ug.s(Range(0,BASE::nseg-1)) = 0.; BASE::ug.i(Range(0,BASE::ntri-1)) = 0.; for (int l=0;l<nmodes;++l) { BASE::ug.v(Range(0,BASE::npnt-1)) += coeffs(l)*modes(l).v(Range(0,BASE::npnt-1)); BASE::ug.s(Range(0,BASE::nseg-1)) += coeffs(l)*modes(l).s(Range(0,BASE::nseg-1)); BASE::ug.i(Range(0,BASE::ntri-1)) += coeffs(l)*modes(l).i(Range(0,BASE::ntri-1)); } }
/* Init the filters */ void init_iir(void) { calc_coeffs(); }
int main(int argc, char *argv[]) { // Set up batch submission #ifdef BATCH SIM_ROOT_DIR = (char*) malloc(CHAR_BUF_SIZE * sizeof(char)); ROOT_DIR = (char*) malloc(CHAR_BUF_SIZE * sizeof(char)); // arg[0] = program name // arg[1] = SIM_ROOT_DIR if (argc == 2) { sprintf(SIM_ROOT_DIR, "%s", argv[1]); sprintf(ROOT_DIR, "%s/f-rec-part-3D", SIM_ROOT_DIR); } else if (argc != 2) { printf("usage: %s SIM_ROOT_DIR\n", argv[0]); exit(EXIT_FAILURE); } printf("\n SIM_ROOT_DIR = %s\n", SIM_ROOT_DIR); printf(" ROOT_DIR = %s\n\n", ROOT_DIR); #else // prevent compiler warning argc = argc; argv = argv; #endif // Read input file main_read_input(); // Read and sort output directory for finding files within our time limits init_part_files(); // Get number of particles nparts = cgns_read_nparts(); // Initialize partstruct and flow vars parts_init(); // Initialize domain and flow arrays domain_init(); // Allocate arrays alloc_arrays(); // Create output directory get_sigfigs(); create_output(); /* MAIN LOOP */ double kl, km, kn; int ll, mm, nn, corder; // Loop over time for (tt = 0; tt < nFiles; tt++) { // Fill parts with new info cgns_fill_parts(); // Loop over all coefficients l,m,n (x,y,z) for (ll = 0; ll <= orderL; ll++) { kl = 2.*PI*ll/dom.xl; for (mm = 0; mm <= orderM; mm++) { km = 2.*PI*mm/dom.yl; for (nn = 0; nn <= orderN; nn++) { kn = 2.*PI*nn/dom.zl; corder = nn + (orderN + 1)*mm + (orderN + 1)*(orderM + 1)*ll; // Calculate coefficients n_lmn // TODO: need diff for vfrac calc_coeffs(n_lmn, ones, parts, kl, km, kn, corder); //printf("n_lmn[%d] = %f + %fi\n", corder, creal(n_lmn[corder]), cimag(n_lmn[corder])); // does it make sense to not even store n_lmn? // evaluate series for n_lmn at x,y,z // TODO: need diff for vfrac // TODO: parallelize? probably not, is not TOO slow // TODO: is n_rec always real? eval_series(n_rec, n_lmn, kl, km, kn, corder); } } } // Normalize nq by n to find q // make sure to divide by volume... //normalize(nu_ces, n_ces); // // write to file -- TODO take specific nq_rec as input cgns_write_field(); } // Free and exit free_vars(); printf("... Done!\n"); return EXIT_SUCCESS; }