Exemple #1
0
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") 
Exemple #2
0
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 
}
Exemple #3
0
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);
      }
    }
  }
}
Exemple #4
0
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';
  }
}
Exemple #7
0
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);
  }
}