stp<real_t> *opt_stp( const po::variables_map& vm, const adv<real_t> &advsch, const vel<real_t> &velocity, const ini<real_t> &intcond, const grd<real_t> &grid, eqs<real_t> &eqsys ) { quantity<si::time, real_t> dt=0*si::seconds; if (vm["dt"].as<string>() == "auto" ) { if (vm.count("nt")) error_macro("nt may be specified only if dt != auto") if (vm.count("nout")) error_macro("nout may be specified only if dt != auto") return new stp<real_t>( advsch, velocity, intcond, grid, eqsys, real_cast<real_t>(vm, "dt_out")*si::seconds, real_cast<real_t>(vm, "t_max")*si::seconds ); } else { if (vm.count("t_max")) error_macro("t_max may be specified only if dt == auto")
void out_netcdf<real_t>::record( const string &name, const mtx::arr<real_t> &psi, const mtx::idx &ijk, const unsigned long t // t is the number of the record! ) { #if defined(USE_NETCDF) try { // recording time { vector<size_t> startp = {t}, countp = {1}; float value = real_t(t) * pimpl->dt_out / si::seconds; pimpl->vars["time"].putVar(startp, countp, &value); } // recording the data vector<size_t> startp(4), countp(4, 1); startp[0] = t; countp[1] = ijk.ubound(mtx::i) - ijk.lbound(mtx::i) + 1; startp[1] = ijk.lbound(mtx::i); // due to presence of halos the data to be stored is not contiguous, // hence looping over the two major ranks for (int k_int = ijk.lbound(mtx::k); k_int <= ijk.ubound(mtx::k); ++k_int) // loop over "outer" dimension { startp[3] = k_int; for (int j_int = ijk.lbound(mtx::j); j_int <= ijk.ubound(mtx::j); ++j_int) { startp[2] = j_int; assert((psi)(ijk.i, j_int, k_int).isStorageContiguous()); pimpl->vars[name].putVar(startp, countp, (psi)(ijk.i, j_int, k_int).dataFirst()); } } //if (!f->sync()) warning_macro("failed to synchronise netCDF file") } catch (NcException& e) error_macro(e.what()); #endif }
int main(int ac, char** av) { if (ac != 2) error_macro("expecting 1 argument: CMAKE_BINARY_DIR") std::string dir = string(av[1]) + "/tests/fig_a/", h5 = dir + "out_blk_1m"; auto n = h5n(h5); for (int at = 0; at < n["t"]; ++at) // TODO: mark what time does it actually mean! { for (auto &plt : std::set<std::string>({"rc", "rr"})) { Gnuplot gp; init(gp, h5 + ".plot/" + plt + "/" + zeropad(at * n["outfreq"]) + ".svg", 1, 1, n); if (plt == "rc") { auto rc = h5load(h5, "rc", at * n["outfreq"]) * 1e3; gp << "set title 'cloud water mixing ratio r_c [g/kg]'\n"; gp << "set cbrange [0:1.5]\n"; plot(gp, rc); } if (plt == "rr") { auto rr = h5load(h5, "rr", at * n["outfreq"]) * 1e3; gp << "set logscale cb\n"; gp << "set title 'rain water mixing ratio r_r [g/kg]'\n"; gp << "set cbrange [1e-2:1]\n"; plot(gp, rr); } } } }
void eqs_todo_bulk_ode<real_t>::condevap( const mtx::arr<real_t> &rhod, mtx::arr<real_t> &rhod_th, mtx::arr<real_t> &rhod_rv, mtx::arr<real_t> &rhod_rl, mtx::arr<real_t> &rhod_rr, const quantity<si::time, real_t> dt ) { # if !defined(USE_BOOST_ODEINT) error_macro("eqs_todo_bulk requires icicle to be compiled with Boost.odeint"); # else // odeint::euler< // TODO: opcja? odeint::runge_kutta4< quantity<multiply_typeof_helper<si::mass_density, si::temperature>::type, real_t>, // state_type real_t, // value_type quantity<si::temperature, real_t>, // deriv_type quantity<si::mass_density, real_t>, // time_type odeint::vector_space_algebra, odeint::default_operations, odeint::never_resizer > S; // TODO: would be better to instantiate in the ctor (but what about thread safety! :() typename detail::rhs F; for (int k = rhod.lbound(mtx::k); k <= rhod.ubound(mtx::k); ++k) for (int j = rhod.lbound(mtx::j); j <= rhod.ubound(mtx::j); ++j) for (int i = rhod.lbound(mtx::i); i <= rhod.ubound(mtx::i); ++i) { F.init( rhod(i,j,k) * si::kilograms / si::cubic_metres, rhod_th(i,j,k) * si::kilograms / si::cubic_metres * si::kelvins, rhod_rv(i,j,k) * si::kilograms / si::cubic_metres ); real_t // TODO: quantity<si::mass_density rho_eps = .00002, // TODO: as an option? vapour_excess; real_t drho_rr_max = 0; // TODO: quantity<si::mass_density if (F.rs > F.r && rhod_rr(i,j,k) > 0 && opt_revp) drho_rr_max = (dt / si::seconds) * (1 - F.r / F.rs) * (1.6 + 124.9 * pow(1e-3 * rhod_rr(i,j,k), .2046)) * pow(1e-3 * rhod_rr(i,j,k), .525) / (5.4e2 + 2.55e5 * (1. / (F.p / si::pascals) / F.rs)); // TODO: move to phc!!! bool incloud; // TODO: rethink and document 2*rho_eps!!! while ( // condensation of cloud water if supersaturated (vapour_excess = rhod_rv(i,j,k) - rhod(i,j,k) * F.rs) > rho_eps || (opt_cevp && vapour_excess < -rho_eps && ( // or if subsaturated (incloud = (rhod_rl(i,j,k) > 0)) // cloud evaporation if in cloud || (opt_revp && rhod_rr(i,j,k) > 0) // or rain evaportation if in a rain shaft (and out-of-cloud) )) ) { real_t drho_rv = - copysign(.5 * rho_eps, vapour_excess); drho_rv = (vapour_excess > 0 || incloud) ? std::min(rhod_rl(i,j,k), drho_rv) : std::min(drho_rr_max, std::min(rhod_rr(i,j,k), drho_rv)); // preventing negative mixing ratios assert(drho_rv != 0); // otherwise it should not pass the while condition! // theta is modified by do_step, and hence we cannot pass an expression and we need a temp. var. quantity<multiply_typeof_helper<si::mass_density, si::temperature>::type, real_t> tmp = rhod_th(i,j,k) * si::kilograms / si::cubic_metres * si::kelvins; // integrating the First Law for moist air S.do_step( boost::ref(F), tmp, rhod_rv(i,j,k) * si::kilograms / si::cubic_metres, drho_rv * si::kilograms / si::cubic_metres ); // latent heat source/sink due to evaporation/condensation rhod_th(i,j,k) = tmp / (si::kilograms / si::cubic_metres * si::kelvins); // updating rhod_rv rhod_rv(i,j,k) += drho_rv; assert(rhod_rv(i,j,k) >= 0); assert(isfinite(rhod_rv(i,j,k))); if (vapour_excess > 0 || incloud) { rhod_rl(i,j,k) -= drho_rv; // cloud water assert(rhod_rl(i,j,k) >= 0); assert(isfinite(rhod_rl(i,j,k))); } else // or rain water { assert(opt_revp); // should be guaranteed by the while() condition above rhod_rr(i,j,k) -= drho_rv; assert(rhod_rr(i,j,k) >= 0); assert(isfinite(rhod_rr(i,j,k))); if ((drho_rr_max -= drho_rv) == 0) break; // but not more than Kessler allows } } // hopefully true for RK4 assert(F.r == real_t(rhod_rv(i,j,k) / rhod(i,j,k))); // double-checking.... assert(rhod_rl(i,j,k) >= 0); assert(rhod_rv(i,j,k) >= 0); assert(rhod_rr(i,j,k) >= 0); } # endif }
int main() { // init signalhandler // initialize sigaction struct memset (&act, '\0', sizeof(act)); // define function to be called act.sa_handler = sighandler; act.sa_flags = 0; err = sigemptyset(&act.sa_mask); if (err < 0) { perror("sigemptyset"); } err = sigaction(SIGALRM, &act, NULL); if (err < 0) { perror ("sigaction"); return 1; } err = sigaction(SIGTERM, &act, NULL); if (err < 0) { perror ("sigaction"); return 1; } err = sigaction(SIGINT, &act, NULL); if (err < 0) { perror ("sigaction"); return 1; } // offer the user to unload modules which block LEFT // this program needs to be executed with sudo permissions anyways err = printf("Unload w1_therm, w1_gpio and wire so you can use \ LEFT_GO and LEFT_DIR?\nit is highly recommended\n\ decision (y/n): "); fflush(stdout); if ('y' == getchar()) { err = system("sudo rmmod w1_therm"); printf("w1_therm unloaded\n"); err = system("sudo rmmod w1_gpio"); printf("w1_gpio unloaded\n"); err = system("sudo rmmod wire"); printf("wire unloaded\n"); // fix a strange bug (void) getchar(); } // init stepper lib err = init_steplib(PHASE_A1, PHASE_A2, PHASE_B1, PHASE_B2, 98); if (0 != err) error_macro("steplib"); // begin the stepping while (1) { printf("step? (n or CTRL-C = exit): "); fflush(stdout); if ('n' != getchar()) { printf("fullstep, forwards, 200 * 1.8° = 360°\n"); fullstep(650000000, 200, FORWARDS); printf("fullstep, backwards, 200 * 1.8° = 360°\n"); fullstep(650000000, 200, BACKWARDS); printf("halfstep, forwards, 200 * 1.8° = 360°\n"); halfstep(650000000, 200, FORWARDS); printf("halfstep, backwards, 200 * 1.8° = 360°\n"); halfstep(650000000, 200, BACKWARDS); } } // reset the pins to 0 (LOW) again exit_steplib(); exit(EXIT_SUCCESS); }
int main(int ac, char** av) { if (ac != 2) error_macro("expecting 1 argument: CMAKE_BINARY_DIR") std::string dir = string(av[1]) + "/paper_GMD_2015/fig_a/", h5 = dir + "out_lgrngn", svg = dir + "out_lgrngn_spec.svg"; Gnuplot gp; int off = 2; // TODO!!! float ymin = .4 * .01, ymax = .9 * 10000; const int at = 9000; gp << "set term svg dynamic enhanced fsize 15 size 900, 1500 \n"; gp << "set output '" << svg << "'\n"; gp << "set logscale xy\n"; gp << "set xrange [.002:100]\n"; gp << "set yrange [" << ymin << ":" << ymax << "]\n"; gp << "set ylabel '[mg^{-1} μm^{-1}]'\n"; // TODO: add textual description (PDF?) gp << "set grid\n"; gp << "set nokey\n"; // FSSP range gp << "set arrow from .5," << ymin << " to .5," << ymax << " nohead\n"; gp << "set arrow from 25," << ymin << " to 25," << ymax << " nohead\n"; gp << "set xlabel offset 0,1.5 'particle radius [μm]'\n"; gp << "set key samplen 1.2\n"; gp << "set xtics rotate by 65 right (.01, .1, 1, 10, 100) \n"; // TODO: use dashed lines to allow printing in black and white... same in image plots assert(focus.first.size() == focus.second.size()); gp << "set multiplot layout " << focus.first.size() << ",2 columnsfirst upwards\n"; // focus to the gridbox from where the size distribution is plotted char lbl = 'i'; for (auto &fcs : std::set<std::set<std::pair<int,int>>>({focus.first, focus.second})) { for (auto it = fcs.begin(); it != fcs.end(); ++it) { const int &x = it->first, &y = it->second; gp << "set label 1 '(" << lbl << ")' at graph -.15, 1.02 font ',20'\n"; //gp << "set title 'x=" << x << " y=" << y << "'\n"; std::map<float, float> focus_d; std::map<float, float> focus_w; //info on the number and location of histogram edges vector<quantity<si::length>> left_edges_rd = bins_dry(); int nsd = left_edges_rd.size() - 1; vector<quantity<si::length>> left_edges_rw = bins_wet(); int nsw = left_edges_rw.size() - 1; for (int i = 0; i < nsd; ++i) { const string name = "rd_rng" + zeropad(i) + "_mom0"; blitz::Array<float, 2> tmp_d(1e-6 * h5load(h5, name, at)); focus_d[left_edges_rd[i] / 1e-6 / si::metres] = sum(tmp_d( blitz::Range(x-1, x+1), blitz::Range(y-1, y+1) )) / 9 // mean over 9 gridpoints / ((left_edges_rd[i+1] - left_edges_rd[i]) / 1e-6 / si::metres); // per micrometre } for (int i = 0; i < nsw; ++i) { const string name = "rw_rng" + zeropad(i + off) + "_mom0"; blitz::Array<float, 2> tmp_w(1e-6 * h5load(h5, name, at)); focus_w[left_edges_rw[i] / 1e-6 / si::metres] = sum(tmp_w( blitz::Range(x-1, x+1), blitz::Range(y-1, y+1) )) / 9 / ((left_edges_rw[i+1] - left_edges_rw[i]) / 1e-6 / si::metres); // per micrometre } notice_macro("setting-up plot parameters"); gp << "plot" << "'-' with histeps title 'wet radius' lw 3 lc rgb 'blue'," << "'-' with histeps title 'dry radius' lw 1 lc rgb 'red' " << endl; gp.send(focus_w); gp.send(focus_d); lbl -= 2; } lbl = 'j'; } }
int main(int ac, char** av) { if (ac != 2) error_macro("expecting 1 argument: CMAKE_BINARY_DIR") std::string dir = string(av[1]) + "/tests/fig_a/", h5 = dir + "out_lgrngn.h5", svg = dir + "out_lgrngn.svg"; Gnuplot gp; init(gp, svg, 3, 2); { char lbl = 'i'; for (auto &fcs : std::set<std::set<std::pair<int, int>>>({focus.first, focus.second})) { for (auto &pr : fcs) { auto &x = pr.first; auto &y = pr.second; // black square gp << "set arrow from " << x-1 << "," << y-1 << " to " << x+2 << "," << y-1 << " nohead lw 4 lc rgbcolor '#ffffff' front\n"; gp << "set arrow from " << x-1 << "," << y+2 << " to " << x+2 << "," << y+2 << " nohead lw 4 lc rgbcolor '#ffffff' front\n"; gp << "set arrow from " << x-1 << "," << y-1 << " to " << x-1 << "," << y+2 << " nohead lw 4 lc rgbcolor '#ffffff' front\n"; gp << "set arrow from " << x+2 << "," << y-1 << " to " << x+2 << "," << y+2 << " nohead lw 4 lc rgbcolor '#ffffff' front\n"; // white square gp << "set arrow from " << x-1 << "," << y-1 << " to " << x+2 << "," << y-1 << " nohead lw 2 front\n"; gp << "set arrow from " << x-1 << "," << y+2 << " to " << x+2 << "," << y+2 << " nohead lw 2 front\n"; gp << "set arrow from " << x-1 << "," << y-1 << " to " << x-1 << "," << y+2 << " nohead lw 2 front\n"; gp << "set arrow from " << x+2 << "," << y-1 << " to " << x+2 << "," << y+2 << " nohead lw 2 front\n"; lbl -= 2; } lbl = 'j'; } } // labels { char lbl = 'i'; for (auto &fcs : std::set<std::set<std::pair<int, int>>>({focus.first, focus.second})) { for (auto &pr : fcs) { auto &x = pr.first; auto &y = pr.second; // labels gp << "set label " << int(lbl) << " '" << lbl << "' at " << x+(((lbl+1)/2)%2?-6:+4) << "," << y+.5 << " front font \",20\"\n"; lbl -= 2; } lbl = 'j'; } } // cloud water content { // rho_w kg2g auto tmp = h5load(h5, "rw_rng000_mom3") * 4./3 * 3.14 * 1e3 * 1e3; gp << "set title 'cloud water mixing ratio [g/kg]'\n"; gp << "set cbrange [0:1.5]\n"; plot(gp, tmp); } // rain water content { // rho_w kg2g auto tmp = h5load(h5, "rw_rng001_mom3") * 4./3 * 3.14 * 1e3 * 1e3; gp << "set logscale cb\n"; gp << "set title 'rain water mixing ratio [g/kg]'\n"; gp << "set cbrange [1e-2:1]\n"; plot(gp, tmp); gp << "unset logscale cb\n"; } // cloud particle concentration { auto tmp = 1e-6 * h5load(h5, "rw_rng000_mom0"); gp << "set title 'cloud droplet spec. conc. [mg^{-1}]'\n"; gp << "set cbrange [0:150]\n"; plot(gp, tmp); } // rain particle concentration { auto tmp = 1e-6 * h5load(h5, "rw_rng001_mom0"); gp << "set title 'rain drop spec. conc. [mg^{-1}]'\n"; gp << "set cbrange [.01:10]\n"; gp << "set logscale cb\n"; plot(gp, tmp); gp << "unset logscale cb\n"; } // effective radius { auto r_eff = h5load(h5, "rw_rng000_mom3") / h5load(h5, "rw_rng000_mom2") * 1e6; gp << "set title 'cloud droplet effective radius [μm]'\n"; gp << "set cbrange [1:20]\n"; plot(gp, r_eff); } // radar reflectivity /* { auto m0 = h5load(h5, "rw_rng001_mom0"); auto m6 = h5load(h5, "rw_rng001_mom6"); float minval = -80, maxval = -20; gp << "set cbrange [" << minval << ":" << maxval << "]\n"; auto dbZ = where( // if m0==0, // then minval, // else 10 * log10( // reflectivity -> decibels of reflectivity pow(2e3,6) * // radii in metres -> diameters in milimetres m6 / m0 // sixth moment per unit volume // TODO: now it is "per mass"! ) ); gp << "set title 'radar reflectivity [dB]'\n"; plot(gp, dbZ); } */ // aerosol concentration { blitz::Array<float, 2> tmp(h5load(h5, "rw_rng002_mom0")); vector<quantity<si::length>> left_edges = bins_wet(); for (int i = 1; i < left_edges.size()-1; ++i) { if (left_edges[i + 1] > 1e-6 * si::metres) break; ostringstream str; str << "rw_rng" << std::setw(3) << std::setfill('0') << i + 2 << "_mom0"; tmp = tmp + h5load(h5, str.str()); } gp << "set cbrange [" << 0 << ":" << 150 << "]\n"; gp << "set title 'aerosol concentration [mg^{-1}]'\n"; tmp /= 1e6; plot(gp, tmp); } }