Alpine3D

Alpine3D Svn Source Tree

Root/trunk/alpine3d/AlpineControl.cc

1/***********************************************************************************/
2/* Copyright 2009-2015 WSL Institute for Snow and Avalanche Research SLF-DAVOS */
3/***********************************************************************************/
4/* This file is part of Alpine3D.
5 Alpine3D is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 Alpine3D is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with Alpine3D. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include <alpine3d/AlpineControl.h>
19#include <alpine3d/AlpineMain.h>
20#include <meteoio/MeteoIO.h>
21
22using namespace mio;
23using namespace std;
24
25/**
26 * @brief Constructs and initialise the time steps loop.
27 * This module calls all the necessary other modules (ie thoese that have been enabled) and runs through the time steps.
28 * @param mysnowpack pointer to the initialized SNOWPACK Manager
29 * @param mysnowdrift pointer to the initialized Snowdrift Manager
30 * @param myeb pointer to the initialized radiation manager
31 * @param myda pointer to the initialized data assimilation Manager
32 * @param myrunoff pointer to the initialized runoff Manager
33 * @param cfg User configuration keys
34 * @param dem DEM defining the simulation
35 */
36AlpineControl::AlpineControl(SnowpackInterface *mysnowpack, SnowDriftA3D *mysnowdrift, EnergyBalance *myeb, DataAssimilation *myda, Runoff *myrunoff, const Config& cfg, const DEMObject& dem)
37 : meteo(cfg, dem), snowpack(mysnowpack), snowdrift(mysnowdrift), eb(myeb), da(myda), runoff(myrunoff),
38 snow_days_between(0.), nocompute(false), out_snow(true)
39{
40cfg.getValue("SNOW_WRITE", "Output", out_snow);
41if (out_snow) {
42cfg.getValue("SNOW_DAYS_BETWEEN", "Output", snow_days_between);
43}
44}
45
46void AlpineControl::Run(Date i_startdate, const unsigned int max_steps)
47{// This function organizes the whole simulation:
48// initializations, time loop, getting input data, computing each time step and finally writing outputs
49Date calcDate(i_startdate); //Date object initialized to julian 0.0 in local time zone with no DST
50const double timeStep = dt_main/86400.;
51Timer elapsed;
52std::vector<MeteoData> vecMeteo; // to transfer meteo information
53mio::Grid2DObject p, psum, psum_ph, vw, dw, rh, ta, ilwr;
54const bool isMaster = MPIControl::instance().master();
55
56if (isMaster) {
57cout << "\n**** Done initializing\n";
58cout << "**** Starting Calculation on date: " << calcDate.toString(Date::ISO) << " using Alpine3D version " << A3D_VERSION << "\n";
59if (nocompute)
60cout << "**** Performing dry run (--no-compute option)\n";
61cout << "\n";
62
63if (nocompute) {
64const Grid2DObject maskGlacier( snowpack->getGrid(SnGrids::GLACIER) );
65meteo.setGlacierMask(maskGlacier);
66}
67}
68
69//if the meteo data would need to be resampled, we try to fill the buffer with a date a little bit before
70if (snowdrift) meteo.setSkipWind(true); //do not fill grids if met3D
71meteo.prepare(i_startdate);
72
73elapsed.start();
74for (unsigned int t_ind=0; t_ind<max_steps; t_ind++) { //main computational loop
75const double elapsed_start = elapsed.getElapsed();
76const double est_completion = elapsed_start * ((double)max_steps/(double)(t_ind+1) - 1.);
77
78if (isMaster) {
79cout << "\nSimulation step " << t_ind+1 << "/" << max_steps << " at time step " << calcDate.toString(mio::Date::ISO_TZ) << "\n";
80cout << std::fixed << "Elapsed time: " << setprecision(1) << elapsed_start << " seconds\nEstimated completion in " << est_completion/3600. << " hours\n";
81}
82
83//for --no-compute, simply check the data and move on
84if (nocompute) {
85meteo.prepare(calcDate); //prepare the current timestep (because it could not be prepared before)
86meteo.checkMeteoForcing(calcDate);
87calcDate += timeStep; //move to next time step
88continue;
89}
90
91//get 1D and 2D meteo for the current time step
92try {
93meteo.get(calcDate, vecMeteo);
94meteo.get(calcDate, ta, rh, psum, psum_ph, vw, dw, p, ilwr);
95} catch (IOException&) {
96//saving state files before bailing out
97if (isMaster) {
98if (out_snow && t_ind>0 && snowpack)
99snowpack->writeOutputSNO(calcDate-1./24.); //output for last hour
100throw;
101}
102}
103
104if (t_ind < (max_steps-1)) {
105meteo.prepare(calcDate+timeStep); //prepare next timestep
106}
107
108if (eb) {
109eb->setStations(vecMeteo);
110}
111
112if (!snowdrift) { //otherwise snowdrift calls snowpack.setMeteo()
113if (snowpack) snowpack->setMeteo(psum, psum_ph, vw, dw, rh, ta, calcDate);
114}
115
116try { //Snowdrift
117if (snowdrift) {
118//meteo1d(MeteoData::TA) : big TODO, see with Christine if we could get rid of it
119snowdrift->setMeteo(t_ind, psum, psum_ph, p, vw, rh, ta, ilwr, calcDate, vecMeteo);
120snowdrift->Compute(calcDate);
121}
122} catch (std::exception& e) {
123cout << "[E] Exception: Snowdrift compute\n";
124cout << e.what() << endl;
125throw;
126}
127
128try {
129if (eb && !snowdrift) { //otherwise snowdrift calls eb.setMeteo()
130eb->setMeteo(ilwr, ta, rh, p, calcDate);
131}
132} catch (std::bad_alloc&) {
133cout << "[E] AlpineControl : Virtual memory exceeded\n";
134} catch (std::exception& e) {
135cout << "[E] Exception: Ebalance compute\n";
136cout << e.what() << endl;
137throw;
138}
139
140try { //Data Assimilation
141if (da) da->Compute(calcDate);
142} catch (std::exception& e) {
143cout << "[E] Exception: Data Assimilation compute\n";
144cout << e.what() << endl;
145throw;
146}
147
148try { //do some outputs
149if ( snowpack && out_snow && (t_ind > 0)) {
150const unsigned int output_step = static_cast<unsigned int>( Optim::round(snow_days_between*24.) );
151if (snow_days_between>0 && (t_ind%output_step)==0)
152snowpack->writeOutputSNO(calcDate);
153}
154} catch (std::exception& e) {
155printf("[e] Exception: time dependent outputs\n");
156cout << e.what() << endl;
157throw;
158}
159
160if (isMaster) {
161cout << "[i] timing (seconds spent): " << std::setprecision(3) << std::fixed<< "\n";
162cout << "\tmeteo=" << meteo.getTiming() << " ";
163
164if (eb) cout << "ebalance=" << eb->getTiming() << " ";
165if (snowdrift) cout << "snowdrift=" << snowdrift->getTiming() << " ";
166if (snowpack) cout << "snowpack=" << snowpack->getTiming() << " ";
167if (runoff) cout << "runoff=" << runoff->getTiming() << " ";
168
169cout << "\n\ttotal=" << elapsed.getElapsed()-elapsed_start << endl;
170}
171
172calcDate += timeStep; //move to next time step
173
174} /* For all times max_steps */
175
176//Finish the program: Write SNO Files and put final output on the screen
177if (snowpack && out_snow && !nocompute){
178if (isMaster) cout << "[i] Simulation finished, writing output files...\n";
179snowpack->writeOutputSNO(calcDate);
180 }
181}
182

Archive Download this file

Revision: HEAD