/** set initial condition (a.k.a. set the first energy vector at t=tmin of the * grid) */ void Particles::SetInitialCondition(vector<vector<double> > &Grid, vector<double> EnergyAxis, double startTime) { double t0 = startTime; SetMembers(t0); for (unsigned int i = 0; i < EnergyAxis.size(); i++) { double e = 0.5 * (pow(10, EnergyAxis[i]) + pow(10., EnergyAxis[i + 1])); Grid[0][i] = t0 * yr_to_sec * SourceSpectrum(e); } return; }
/** * Center piece of the class: Numerical solver of the particle spectrum. * It treats cooling as an advective flow in energy space, and uses a piece-wise * linear numerical scheme to transport particles from one energy bin in the * next, * where the (energy-dependent) cooling rate is treated as the flow velocity of * the 'fluid'. To realise sharp edges in the resulting spectra, the 'SuperBee' * and 'MinMod' slope * limiters are available (default: MinMod). This slows down the procedure, and * can manually be * disabled. * TODO: write option to choose between slope limiter methods / disable them */ void Particles::ComputeGrid(vector<vector<double> > &Grid, vector<double> EnergyAxis, double startTime, double Age, vector<double> &TimeAxis, double minTimeBin) { TimeAxis.push_back(startTime); TimeAxis.push_back(0.); double value = 0.; double quot = 0.; double t = 0.; double e1 = 0.; double e2 = 0.; double ebin = 0.; double tbin = 0.; double deltaE1 = 0.; double deltaE2 = 0.; double ElossRate_e1 = 0.; double ElossRate_e2 = 0.; unsigned int Esize = EnergyAxis.size() - 1; int tt = 1; int largestFilledBin = Esize; long int count = 0; /* append a new energy vector that will always hold the energy spectrum at the * next time step and initialise it with zeroes. */ Grid.push_back(vector<double>()); for (unsigned int i = 0; i < EnergyAxis.size(); i++) { Grid[Grid.size() - 1].push_back(0.); } /* info writeout. Disable it by using 'ToggleQuietMode()' */ if (!Type && QUIETMODE == false) cout << "** Evolving Electron Spectrum:" << endl; else if (Type == 1 && QUIETMODE == false) cout << "** Evolving Proton Spectrum:" << endl; /* main loop over time */ for (double T = startTime; T < Age; T += tbin / yr_to_sec) { /* Set Members (CR luminosity, B-field etc.) at time T */ SetMembers(T); /* dynamically determine tbin size. This is a critical step * for the speed of the algorithm. Since the time step size is * proportional to Ebinsize(eMax)/Edot(eMax) and Edot ~ E^2, * eMax - or the largest relevant energy bin - should be chosen * as small as possible. Thus, don't use the energy at eMax, but * but rather of the largest filled energy bin. * This is 'largestFilledBin' which is time-dependent and is defined * in the next for-loop. * If an external emax is specified, always choose the highest energy bin * value */ if (eMaxConstant) largestFilledBin = Esize - 1; e1 = pow(10., EnergyAxis[largestFilledBin - 1]); e2 = pow(10., EnergyAxis[largestFilledBin]); ebin = e2 - e1; /* the tbin size is then simply defined as deltaE/Edot_max */ tbin = ebin / fabs(EnergyLossRate(e2)); /* info writeout */ if (T > 0.01 * tt * (Age - startTime) && QUIETMODE == false) { cout << "\r"; if (tbin / (yr_to_sec * Age) > 1.e-7) { cout << " " " \r" << std::flush; cout << " " << (int)(100. * (T - startTime) / (Age - startTime)) << "\% done \r" << std::flush; } else {
int Ardb::SortCommand(Context& ctx, const Slice& key, SortOptions& options, DataArray& values) { values.clear(); KeyType keytype = KEY_END; GetType(ctx, key, keytype); switch (keytype) { case LIST_META: { ListRange(ctx, key, 0, -1); break; } case SET_META: { SetMembers(ctx, key); break; } case ZSET_META: { ZSetRange(ctx, key, 0, -1, false, false, OP_GET); if (NULL == options.by) { options.nosort = true; } break; } default: { return ERR_INVALID_TYPE; } } DataArray sortvals; if (ctx.reply.MemberSize() > 0) { for (uint32 i = 0; i < ctx.reply.MemberSize(); i++) { Data v; v.SetString(ctx.reply.MemberAt(i).str, true); sortvals.push_back(v); } } if (sortvals.empty()) { return 0; } if (options.with_limit) { if (options.limit_offset < 0) { options.limit_offset = 0; } if ((uint32) options.limit_offset > sortvals.size()) { values.clear(); return 0; } if (options.limit_count < 0) { options.limit_count = sortvals.size(); } } std::vector<SortValue> sortvec; if (!options.nosort) { if (NULL != options.by) { sortvec.reserve(sortvals.size()); } for (uint32 i = 0; i < sortvals.size(); i++) { if (NULL != options.by) { sortvec.push_back(SortValue(&sortvals[i])); if (GetValueByPattern(ctx, options.by, sortvals[i], sortvec[i].cmp) < 0) { DEBUG_LOG("Failed to get value by pattern:%s", options.by); sortvec[i].cmp.Clear(); continue; } } if (options.with_alpha) { if (NULL != options.by) { sortvec[i].cmp.ToString(); } else { sortvals[i].ToString(); } } } if (NULL != options.by) { if (!options.is_desc) { std::sort(sortvec.begin(), sortvec.end(), less_value<SortValue>); } else { std::sort(sortvec.begin(), sortvec.end(), greater_value<SortValue>); } } else { if (!options.is_desc) { std::sort(sortvals.begin(), sortvals.end(), less_value<Data>); } else { std::sort(sortvals.begin(), sortvals.end(), greater_value<Data>); } } } if (!options.with_limit) { options.limit_offset = 0; options.limit_count = sortvals.size(); } uint32 count = 0; for (uint32 i = options.limit_offset; i < sortvals.size() && count < (uint32) options.limit_count; i++, count++) { Data* patternObj = NULL; if (NULL != options.by) { patternObj = sortvec[i].value; } else { patternObj = &(sortvals[i]); } if (options.get_patterns.empty()) { values.push_back(*patternObj); } else { for (uint32 j = 0; j < options.get_patterns.size(); j++) { Data vo; if (GetValueByPattern(ctx, options.get_patterns[j], *patternObj, vo) < 0) { DEBUG_LOG("Failed to get value by pattern for:%s", options.get_patterns[j]); vo.Clear(); } values.push_back(vo); } } } uint32 step = options.get_patterns.empty() ? 1 : options.get_patterns.size(); switch (options.aggregate) { case AGGREGATE_SUM: case AGGREGATE_AVG: { DataArray result; result.resize(step); for (uint32 i = 0; i < result.size(); i++) { for (uint32 j = i; j < values.size(); j += step) { result[i].IncrBy(values[j]); } } if (options.aggregate == AGGREGATE_AVG) { size_t count = values.size() / step; for (uint32 i = 0; i < result.size(); i++) { result[i].SetDouble(result[i].NumberValue() / count); } } values.assign(result.begin(), result.end()); break; } case AGGREGATE_MAX: case AGGREGATE_MIN: { DataArray result; result.resize(step); for (uint32 i = 0; i < result.size(); i++) { for (uint32 j = i; j < values.size(); j += step) { if (result[i].IsNil()) { result[i] = values[j]; } else { if (options.aggregate == AGGREGATE_MIN) { if (values[j] < result[i]) { result[i] = values[j]; } } else { if (values[j] > result[i]) { result[i] = values[j]; } } } } } values.assign(result.begin(), result.end()); break; } case AGGREGATE_COUNT: { size_t size = values.size() / step; values.clear(); Data v; v.SetInt64(size); values.push_back(v); break; } default: { break; } } if (options.store_dst != NULL && !values.empty()) { DeleteKey(ctx, options.store_dst); ValueObject list_meta; list_meta.key.key = options.store_dst; list_meta.key.type = KEY_META; list_meta.key.db = ctx.currentDB; list_meta.type = LIST_META; list_meta.meta.SetEncoding(COLLECTION_ECODING_ZIPLIST); BatchWriteGuard guard(GetKeyValueEngine()); DataArray::iterator it = values.begin(); while (it != values.end()) { if (!it->IsNil()) { std::string tmp; it->GetDecodeString(tmp); ListInsert(ctx, list_meta, NULL, tmp, false, false); } it++; } SetKeyValue(ctx, list_meta); } return 0; }