Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • gwu479/Summa-Actors
  • numerical_simulations_lab/actors/Summa-Actors
2 results
Show changes
Showing
with 1820 additions and 1346 deletions
#pragma once
extern "C" {
// Initialize HRU data_structures
void summaActors_initialize(
int* indxGRU, int* num_steps,
// Statistics Structures
void* forcStat, void* progStat, void* diagStat, void* fluxStat, void* indxStat, void* bvarStat,
// Primary Data Structures (scalars)
void* timeStruct, void* forcStruct, void* attrStruct, void* typeStruct, void* idStruct,
// primary data structures (variable length vectors)
void* indxStruct, void* mparStruct, void* progStruct, void* diagStruct, void* fluxStruct,
// basin-average structures
void* bparStruct, void* bvarStruct,
// ancillary data structures
void* dparStruct,
// local HRU data
void* startTime, void* finshTime, void* refTime, void* oldTime, int* err);
// SetupParam for HRU
void SetupParam(
int* indxGRU, int* indxHRU,
// primary data structures (scalars)
void* attrStruct, void* typeStruct, void* idStruct,
// primary data structures (variable length vectors)
void* mparStruct, void* bparStruct, void* bvarStruct, void* dparStruct,
// local HRU data
void* startTime, void* oldTime,
// miscellaneous
double* upArea, int* err);
// Setup Restart File if this option has been chosen
void Restart(
int* indxGRU, int* indxHRU,
// primary data structures (variable length vectors)
void* indxStruct, void* mparStruct, void* progStruct, void* diagStruct, void* fluxStruct,
// basin-average structures
void* bvarStruct,
// misc
double* dtInit, int* err);
// Read Forcing for HRU
void Forcing(
int* indxGRU, int* stepIndex,
void* timeStruct, void* forcStruct,
int* iFile, int* forcingStep,
double* fracJulDay, double* tmZoneOffsetFracDay, int* yearLength,
int* err);
// Run the model for one timestep
void RunPhysics(
int* id, int* stepIndex,
// primary data structures (scalars)
void* timeStruct, void* forcStruct, void* attrStruct, void* typeStruct,
// primary data structures (variable length vectors)
void* indxStruct, void* mparStruct, void* progStruct, void* diagStruct, void* fluxStruct,
// basin-average structures
void* bvarStruct,
double* fracJulDay, double* tmZoneOffsetFracDay, int* yearLength,
// misc
int* flag, double* dt, int* dt_int_factor, int* err);
// Write output to the output structure
void WriteOutput(
int* indHRU, int* indxGRU, int* indexStep,
// statistics structures
void* forcStat, void* progStat, void* diagStat, void* fluxStat, void* indxStat, void* bvarStat,
// primary data structures (scalars)
void* timeStruct, void* forcStruct, void* attrStruct, void* typeStruct,
// primary data structures (variable length vectors)
void* indxStruct, void* mparStruct, void* progStruct, void* diagStruct, void* fluxStruct,
// basin-average structures
void* bparStruct, void* bvarStruct,
// local vars
void* statCounter, void* outputTimeStep, void* resetStats, void* finalizeStats,
void* finshTime, void* oldTime, int* outputStep, int* err);
void DeallocateStructures(
void* handle_forcStat, void* handle_progStat, void* handle_diagStat, void* handle_fluxStat,
void* handle_indxStat, void* handle_bvarStat, void* handle_timeStruct, void* handle_forcStruct,
void* handle_attrStruct, void* handle_typeStruct, void* handle_idStruct, void* handle_indxStruct,
void* handle_mparStruct, void* handle_progStruct, void* handle_diagStruct, void* handle_fluxStruct,
void* handle_bparStruct, void* handle_bvarStruct, void* handle_dparStruct,
void* handle_startTime, void* handle_finishTime,
void* handle_refTime, void* handle_oldTime,
void* handle_ncid,
void* handle_statCounter,
void* handle_outputTimeStep,
void* handle_resetStats,
void* handle_finalizeStats,
int* err);
void Write_Param_C(
int* indxGRU, int* indxHRU,
void* handle_attrStruct, void* handle_typeStruct, void* handle_mparStruct, void* handle_bparStruct,
int* err);
}
\ No newline at end of file
#pragma once
#include "caf/all.hpp"
#include <iostream>
#include <fstream>
/*
* Determine the state of the GRU
*/
enum class gru_state {
running,
failed,
succeeded
};
int is_success(const gru_state& state);
/**
* Class that holds information about the running GRUs. This class is held by the job actor
* The GRU/HRU actors that carry out the simulation are held by the GRU class
*/
class GRU {
private:
int global_gru_index; // The index of the GRU in the netcdf file
int local_gru_index; // The index of the GRU within this job
caf::actor gru_actor; // The actor for the GRU
// Modifyable Parameters
int dt_init_factor; // The initial dt for the GRU
double rel_tol; // The relative tolerance for the GRU
double abs_tol; // The absolute tolerance for the GRU
// Status Information
int attempts_left; // The number of attempts left for the GRU to succeed
gru_state state; // The state of the GRU
// Timing Information
double run_time = 0.0; // The total time to run the GRU
double init_duration = 0.0; // The time to initialize the GRU
double forcing_duration = 0.0; // The time to read the forcing data
double run_physics_duration = 0.0; // The time to run the physics
double write_output_duration = 0.0; // The time to write the output
public:
// Constructor
GRU(int global_gru_index, int local_gru_index, caf::actor gru_actor, int dt_init_factor,
double rel_tol, double abs_tol, int max_attempts);
// Deconstructor
~GRU();
// Getters
int getGlobalGRUIndex();
int getLocalGRUIndex();
caf::actor getGRUActor();
double getRunTime();
double getInitDuration();
double getForcingDuration();
double getRunPhysicsDuration();
double getWriteOutputDuration();
double getRelTol();
double getAbsTol();
double getAttemptsLeft();
gru_state getStatus();
bool isFailed();
// Setters
void setRunTime(double run_time);
void setInitDuration(double init_duration);
void setForcingDuration(double forcing_duration);
void setRunPhysicsDuration(double run_physics_duration);
void setWriteOutputDuration(double write_output_duration);
void setRelTol(double rel_tol);
void setAbsTol(double abs_tol);
void setSuccess();
void setFailed();
void setRunning();
void decrementAttemptsLeft();
void setGRUActor(caf::actor gru_actor);
};
#pragma once
#include "caf/all.hpp"
#include <iostream>
#include <fstream>
class GRUinfo {
private:
int refGRU; // This will be the same as the refGRU
int indxGRU;
caf::actor GRU;
// Variable to update
int dt_init;
// Completed Information
int currentAttempt;
int maxAttempts;
bool completed;
bool failed;
// Timing information for the GRU
double runTime;
double initDuration;
double forcingDuration;
double runPhysicsDuration;
double writeOutputDuration;
public:
// Constructor
GRUinfo(int refGRU, int indxGRU, caf::actor gru, int dt_init, int maxAttempts);
// Deconstructor
~GRUinfo();
int getRefGRU();
int getIndxGRU();
int getDt_init();
caf::actor getActor();
void updateGRU(caf::actor gru);
void updateFailed();
void updateCompletedToTrue();
void updateDt_init();
void updateCurrentAttempt();
bool isMaxAttemptsReached();
bool isFailed();
bool isCompleted();
void doneRun(double runTime, double initDuration, double forcingDuration,
double runPhysicsDuration, double writeOutputDuration);
void writeSuccess(std::string fileName);
void writeFail(std::string fileName);
void printOutput();
};
\ No newline at end of file
#pragma once
#include "caf/all.hpp"
#include "caf/io/all.hpp"
#include "GRUinfo.hpp"
#include "GRU.hpp"
#include "timing_info.hpp"
#include "settings_functions.hpp"
#include "global.hpp"
#include "json.hpp"
#include "hru_actor.hpp"
#include "message_atoms.hpp"
#include "file_access_actor.hpp"
#include <unistd.h>
#include <limits.h>
/*********************************************
* Job Actor Fortran Functions
*********************************************/
extern "C" {
void job_init_fortran(char const* file_manager, int* start_gru_index, int* num_gru, int* num_hru, int* err);
void deallocateJobActor(int* err);
}
/*********************************************
* Job Actor state variables
*********************************************/
namespace caf {
using chrono_time = std::chrono::time_point<std::chrono::system_clock>;
// Holds information about the GRUs
struct GRU_Container {
std::vector<GRU*> gru_list;
chrono_time gru_start_time; // Vector of start times for each GRU
int num_gru_done = 0;
int num_gru_failed = 0; // number of grus that are waiting to be restarted
int num_gru_in_run_domain = 0; // number of grus we are currently solving for
int run_attempts_left = 1; // current run attempt for all grus
};
struct job_state {
// Actor References
caf::actor file_access_actor; // actor reference for the file_access_actor
caf::actor parent; // actor reference to the top-level SummaActor
// Job Parameters
int start_gru; // Starting GRU for this job
int num_gru; // Number of GRUs for this job
int start_gru; // Starting GRU for this job
int num_gru; // Number of GRUs for this job
int num_hru;
std::string config_path;
int max_run_attempts = 1; // Max number of attempts to solve a GRU
std::string file_manager; // Path of the fileManager.txt file
GRU_Container gru_container;
// Variables for GRU monitoring
int dt_init_start_factor = 1; // Initial Factor for dt_init (coupled_em)
int max_run_attempts = 3; // Max number of attemtps to solve a GRU
std::vector<GRUinfo*> gru_list; // List of all GRUs under this job actor
int num_gru_done = 0; // The number of GRUs that have completed
int gru_init = 0; // Number of GRUs initalized
int err = 0; // Error Code
int num_gru_failed = 0; // Number of GRUs that have failed
int output_struct_size;
int dt_init_start_factor = 1; // Initial Factor for dt_init (coupled_em)
int num_gru_done = 0; // The number of GRUs that have completed
int num_gru_failed = 0; // Number of GRUs that have failed
// Timing Variables
TimingInfo job_timing;
// Output File Names for Timings
bool output_csv;
std::string csv_out;
std::string csv_path;
std::string success_output_file;
std::string failed_output_file = "failedHRU";
std::string file_access_actor_stats = "fileAccessActor.csv";
std::string hostname;
// settings for all child actors (save in case we need to recover)
File_Access_Actor_Settings file_access_actor_settings;
Job_Actor_Settings job_actor_settings;
HRU_Actor_Settings hru_actor_settings;
};
behavior job_actor(stateful_actor<job_state>* self, int start_gru, int num_gru,
std::string config_path, int output_struct_size, actor parent);
void initCsvOutputFile(stateful_actor<job_state>* self);
/** The Job Actor */
behavior job_actor(stateful_actor<job_state>* self,
int start_gru, int num_gru,
File_Access_Actor_Settings file_access_actor_settings,
Job_Actor_Settings job_actor_settings,
HRU_Actor_Settings hru_actor_settings,
actor parent);
void initalizeGRU(stateful_actor<job_state>* self);
void runGRUs(stateful_actor<job_state>* self);
/*********************************************
* Functions for the Job Actor
*********************************************/
void restartFailures(stateful_actor<job_state>* self);
/** Get the information for the GRUs that will be written to the netcdf file */
std::vector<serializable_netcdf_gru_actor_info> getGruNetcdfInfo(int max_run_attempts,
std::vector<GRU*> &gru_list);
void handleGRUError(stateful_actor<job_state>* self, caf::actor src);
} // end namespace
\ No newline at end of file
#pragma once
extern "C" {
void initGlobals(char const*str1, int* totalGRUs, int* totalHRUs,
int* numGRUs, int* numHRUs, int* startGRUIndex, int* err);
void setTimesDirsAndFiles(char const* file_manager, int* err);
void defineGlobalData(int* start_gru_index, int* err);
void readDimension(int* num_gru, int* num_hru, int* start_gru_index, int* err);
void readIcondNLayers(int* num_gru, int* err);
void allocateTimeStructure(int* err);
void deallocateJobActor(int* err);
}
\ No newline at end of file
#pragma once
#include "caf/all.hpp"
#include <string>
class Batch {
private:
int batch_id_;
int start_hru_;
int num_hru_;
double run_time_;
double read_time_;
double write_time_;
bool assigned_to_actor_;
bool solved_;
public:
Batch(int batch_id = -1, int start_hru = -1, int num_hru = -1);
// Getters
int getBatchID();
int getStartHRU();
int getNumHRU();
double getRunTime();
double getReadTime();
double getWriteTime();
bool isAssigned();
bool isSolved();
std::string getBatchInfoString();
// Setters
void updateRunTime(double run_time);
void updateReadTime(double read_time);
void updateWriteTime(double write_time);
void updateAssigned(bool boolean);
void updateSolved(bool boolean);
void printBatchInfo();
void writeBatchToFile(std::string csv_output, std::string hostname);
std::string toString();
void assignToActor(std::string hostname, caf::actor assigned_actor);
template <class Inspector>
friend bool inspect(Inspector& inspector, Batch& batch) {
return inspector.object(batch).fields(
inspector.field("batch_id", batch.batch_id_),
inspector.field("start_hru", batch.start_hru_),
inspector.field("num_hru", batch.num_hru_),
inspector.field("run_time", batch.run_time_),
inspector.field("read_time", batch.read_time_),
inspector.field("write_time", batch.write_time_),
inspector.field("assigned_to_actor", batch.assigned_to_actor_),
inspector.field("solved", batch.solved_));
}
};
\ No newline at end of file
#include "caf/all.hpp"
#pragma once
#include "client.hpp"
class Batch_Container {
private:
int start_hru_;
int total_hru_count_;
int num_hru_per_batch_;
int batches_remaining_;
std::vector<Batch> batch_list_;
// Assemble the total number of HRUs given by the user into batches.
void assembleBatches();
public:
// Creating the batch_manager will also create the batches
// with the two parameters that are passed in.
Batch_Container(int start_hru = 1, int total_hru_count = 0,
int num_hru_per_batch = 0);
// returns the size of the batch list
int getBatchesRemaining();
int getTotalBatches();
// Find an unsolved batch, set it to assigned and return it.
std::optional<Batch> getUnsolvedBatch();
// Update the batch status to solved and write the output to a file.
void updateBatch_success(Batch successful_batch, std::string output_csv, std::string hostname);
// Update the batch status but do not write the output to a file.
void updateBatch_success(Batch successful_batch);
// Update batch by id
void updateBatch_success(int batch_id, double run_time, double read_time,
double write_time);
// Update the batch to assigned = true
void setBatchAssigned(Batch batch);
// Update the batch to assigned = false
void setBatchUnassigned(Batch batch);
// Check if there are batches left to solve
bool hasUnsolvedBatches();
// TODO: Needs implementation
void updateBatch_failure(Batch failed_batch);
std::string getAllBatchInfoString();
double getTotalReadTime();
double getTotalWriteTime();
/**
* A client has found to be disconnected. Unassign all batches
* that were assigned to the disconnected client. The client id
* is passed in as a parameter
*/
void updatedBatch_disconnectedClient(int client_id);
/**
* Create the csv file for the completed batches.
*/
void inititalizeCSVOutput(std::string csv_output_name);
/**
* @brief Print the batches from the batch list
*
*/
void printBatches();
std::string getBatchesAsString();
/**
* @brief Find the batch with the batch_id parameter
* update the batches assigned actor member variable to false
*
*/
void updateBatchStatus_LostClient(int batch_id);
template <class Inspector>
friend bool inspect(Inspector& inspector, Batch_Container& batch_container) {
return inspector.object(batch_container).fields(
inspector.field("total_hru_count", batch_container.total_hru_count_),
inspector.field("num_hru_per_batch", batch_container.num_hru_per_batch_),
inspector.field("batches_remaining", batch_container.batches_remaining_),
inspector.field("batch_list", batch_container.batch_list_));
}
};
\ No newline at end of file
#pragma once
#include "caf/all.hpp"
#include <vector>
#include <string>
enum batch_status {
unassigned,
assigned,
solved,
failed
};
class Batch {
private:
int batch_id;
int start_hru;
int num_hru;
double run_time;
double read_time;
double write_time;
std::string assigned_host;
caf::actor assigned_actor;
batch_status status;
public:
Batch(int batch_id, int start_hru, int num_hru);
void printBatchInfo();
batch_status getBatchStatus();
int getBatchID();
int getStartHRU();
int getNumHRU();
void solvedBatch(double run_time, double read_time, double write_time);
void assignedBatch(std::string hostname, caf::actor actor_ref);
void updateRunTime(double run_time);
void writeBatchToFile(std::string file_name);
};
class Batch_Manager {
private:
std::vector<Batch> batch_list;
std::vector<Batch> solved_batches;
std::vector<Batch> failed_batches;
public:
};
\ No newline at end of file
#pragma once
#include "caf/all.hpp"
#include "batch_manager.hpp"
#include <optional>
#include "batch.hpp"
class Client {
private:
int id;
int batches_solved;
bool connected;
caf::actor client_actor;
std::string hostname;
Batch* current_batch;
int id;
int batches_solved;
std::optional<Batch> current_batch;
public:
Client(int id, caf::actor client_actor, std::string hostname);
Client(int id = -1, caf::actor client_actor = nullptr, std::string hostname = "");
// ####################################################################
// Getters
// ####################################################################
caf::actor getActor();
int getID();
std::string getHostname();
std::optional<Batch> getBatch();
// ####################################################################
// Setters
// ####################################################################
void setBatch(std::optional<Batch> batch);
// ####################################################################
// Methods
// ####################################################################
std::string toString();
// Serialization so CAF can send an object of this class to another actor
template <class Inspector>
friend bool inspect(Inspector& inspector, Client& client) {
return inspector.object(client).fields(
inspector.field("client_actor",client.client_actor),
inspector.field("hostname",client.hostname),
inspector.field("id",client.id),
inspector.field("batches_solved",client.batches_solved),
inspector.field("current_batch",client.current_batch));
}
};
\ No newline at end of file
#pragma once
#include "caf/all.hpp"
#include <vector>
#include "batch.hpp"
#include "client.hpp"
#include <optional>
class Client_Container {
private:
std::vector<Client> client_list;
int id_counter;
public:
Client_Container();
// ####################################################################
// Getters
// ####################################################################
int getNumClients();
std::vector<Client> getClientList();
std::optional<Client> getClient(caf::actor_addr client_ref);
// ####################################################################
// Setters
// ####################################################################
void setBatchForClient(caf::actor client_ref, std::optional<Batch> batch);
// ####################################################################
// Methods
// ####################################################################
// add a new client to the client_list
void addClient(caf::actor client_actor, std::string hostname);
// remove a client from the client_list
void removeClient(Client client);
// return a client that is not solving a batch or return an empty optional
std::optional<Client> getIdleClient();
// Check if the client list is empty
bool isEmpty();
// pops client at the end of the list
Client removeClient_fromBack();
// return printable string
std::string toString();
template <class Inspector>
friend bool inspect(Inspector& inspector, Client_Container& client_container) {
return inspector.object(client_container).fields(
inspector.field("client_list", client_container.client_list),
inspector.field("id_counter", client_container.id_counter));
}
};
......@@ -3,7 +3,8 @@
#include "caf/all.hpp"
#include "caf/io/all.hpp"
#include "timing_info.hpp"
#include "settings_functions.hpp"
#include "batch_container.hpp"
#include <chrono>
#include <string>
#include <vector>
......@@ -25,20 +26,30 @@ struct summa_actor_state {
// Program Parameters
int startGRU; // starting GRU for the simulation
int numGRU; // number of GRUs to compute
std::string configPath;// path to the fileManager.txt file
// Information about the jobs
int fileGRU; // number of GRUs in the file
std::string configPath; // path to the fileManager.txt file
int numFailed = 0; // Number of jobs that have failed
// Values Set By Summa_Actors_Settings.json
int maxGRUPerJob; // maximum number of GRUs a job can compute at once
int outputStrucSize;
caf::actor currentJob; // Reference to the current job actor
caf::actor parent;
// Batches
Batch_Container batch_container;
int current_batch_id;
// settings for all child actors (save in case we need to recover)
Summa_Actor_Settings summa_actor_settings;
File_Access_Actor_Settings file_access_actor_settings;
Job_Actor_Settings job_actor_settings;
HRU_Actor_Settings hru_actor_settings;
};
behavior summa_actor(stateful_actor<summa_actor_state>* self, int startGRU, int numGRU, std::string configPath, actor parent);
behavior summa_actor(stateful_actor<summa_actor_state>* self,
int startGRU, int numGRU,
Summa_Actor_Settings summa_actor_settings,
File_Access_Actor_Settings file_access_actor_settings,
Job_Actor_Settings job_actor_settings,
HRU_Actor_Settings hru_actor_settings, actor parent);
void spawnJob(stateful_actor<summa_actor_state>* self);
......
#pragma once
#include "caf/all.hpp"
#include "caf/io/all.hpp"
#include "summa_server.hpp"
#include <string>
#include <unistd.h>
#include <limits.h>
namespace caf {
// Inital behaviour that waits to connect to the lead server
behavior summa_backup_server_init(stateful_actor<summa_server_state>* self, Distributed_Settings distributed_settings,
Summa_Actor_Settings summa_actor_settings, File_Access_Actor_Settings file_access_actor_settings,
Job_Actor_Settings job_actor_settings, HRU_Actor_Settings hru_actor_settings);
// Function that is called ot connect to the lead server
void connecting_backup(stateful_actor<summa_server_state>* self, const std::string& host, uint16_t port);
behavior summa_backup_server(stateful_actor<summa_server_state>* self, const actor& server_actor);
}
\ No newline at end of file
......@@ -2,23 +2,48 @@
#include "caf/all.hpp"
#include "caf/io/all.hpp"
#include "settings_functions.hpp"
#include "batch.hpp"
#include "summa_actor.hpp"
#include "message_atoms.hpp"
#include <string>
#include <optional>
#include <unistd.h>
#include <limits.h>
namespace caf {
struct summa_client_state {
strong_actor_ptr current_server;
strong_actor_ptr current_server = nullptr;
actor current_server_actor;
std::vector<strong_actor_ptr> servers;
std::string hostname;
std::optional<std::string> config_path;
actor summa_actor_ref;
uint16_t port;
int batch_id;
int client_id; // id held by server
bool running = false; // initalized to false - flipped to true when client returns behavior summa_client
// tuple is the actor ref and hostname of the backup server
std::vector<std::tuple<caf::actor, std::string>> backup_servers_list;
Batch current_batch;
bool saved_batch = false;
Summa_Actor_Settings summa_actor_settings;
File_Access_Actor_Settings file_access_actor_settings;
Job_Actor_Settings job_actor_settings;
HRU_Actor_Settings hru_actor_settings;
};
behavior summa_client(stateful_actor<summa_client_state>* self, std::optional<std::string> config_path);
behavior unconnected(stateful_actor<summa_client_state>*);
behavior summa_client_init(stateful_actor<summa_client_state>* self);
behavior summa_client(stateful_actor<summa_client_state>* self);
void connecting(stateful_actor<summa_client_state>*, const std::string& host, uint16_t port);
behavior running(stateful_actor<summa_client_state>*, const actor& summa_server);
void findLeadServer(stateful_actor<summa_client_state>* self, strong_actor_ptr serv);
}
\ No newline at end of file
......@@ -2,29 +2,86 @@
#include "caf/all.hpp"
#include "caf/io/all.hpp"
#include "batch_manager.hpp"
#include "batch.hpp"
#include "batch_container.hpp"
#include "client.hpp"
#include "client_container.hpp"
#include "settings_functions.hpp"
#include "global.hpp"
#include "message_atoms.hpp"
#include <string>
#include <optional>
#include <thread>
#include <chrono>
#include <iostream>
namespace caf {
struct summa_server_state {
int total_hru_count;
int num_clients;
int num_hru_per_batch;
int batches_remaining = 0;
int batches_solved = 0;
std::string config_path;
std::vector<Batch> batch_list;
std::vector<Batch> solved_batches;
std::vector<Batch> failed_batches;
std::vector<Client> client_list;
std::string csv_output_name;
strong_actor_ptr current_server; // if server is a backup then this will be set to the lead server
actor current_server_actor;
std::string hostname;
std::string csv_file_path;
std::string csv_output_name = "/batch_results.csv";
Client_Container client_container;
Batch_Container batch_container;
// Actor Reference, Hostname
std::vector<std::tuple<caf::actor, std::string>> backup_servers_list;
// Settings Structures
Distributed_Settings distributed_settings;
Summa_Actor_Settings summa_actor_settings;
File_Access_Actor_Settings file_access_actor_settings;
Job_Actor_Settings job_actor_settings;
HRU_Actor_Settings hru_actor_settings;
};
behavior summa_server(stateful_actor<summa_server_state>* self, std::string config_path);
int assembleBatches(stateful_actor<summa_server_state>* self);
std::optional<int> getUnsolvedBatchID(stateful_actor<summa_server_state>* self);
}
\ No newline at end of file
// Summa Server setup behaviour - initializes the state for the server
behavior summa_server_init(stateful_actor<summa_server_state>* self,
Distributed_Settings distributed_settings,
Summa_Actor_Settings summa_actor_settings,
File_Access_Actor_Settings file_access_actor_settings,
Job_Actor_Settings job_actor_settings,
HRU_Actor_Settings hru_actor_settings);
// Summa Server behaviour - handles messages from clients
behavior summa_server(stateful_actor<summa_server_state>* self);
// Summa Server backup behaviour - handles the exit messages for clients
behavior summa_server_exit(stateful_actor<summa_server_state>* self);
// Creates the csv file that holds the results of the batches
void initializeCSVOutput(std::string csv_output_path);
// Send all connected actors the updated backup servers list
void sendAllBackupServersList(stateful_actor<summa_server_state>* self);
// Look for the lost backup server in the backup servers list and remove it
void findAndRemoveLostBackupServer(stateful_actor<summa_server_state>* self, actor_addr lost_backup_server);
// Check for an idle client to send the failed or next batch we find that is not assigned
void checkForIdleClients(stateful_actor<summa_server_state>* self);
void notifyBackupServersOfRemovedClient(stateful_actor<summa_server_state>* self, Client client);
// Finds the batch the lost client was working on and reassigns it to another client if available
// If no client is available then the batch is added back to the list to be reassigned later
void resolveLostClient(stateful_actor<summa_server_state>* self, Client client);
// Removes the backup server from the list of backup servers
// All connected actors are then notified of the change
void resolveLostBackupServer(stateful_actor<summa_server_state>* self, const down_msg& dm);
// Convience function to keep code clean - just does what you think it does
void printRemainingBatches(stateful_actor<summa_server_state>* self);
} // namespace caf
#### parent directory of the 'build' directory ####
ROOT_DIR = /Summa-Actors
#### Compilers ####
FC = gfortran # Fortran
CC = g++ # C++
#### Includes AND Libraries ####
INCLUDES = -I/usr/include -I/usr/local/include
LIBRARIES = -L/usr/lib -L/usr/local/lib -lnetcdff -lopenblas
ACTORS_INCLUDES = -I/usr/include -I/usr/local/include
ACTORS_LIBRARIES = -L/usr/lib -L/usr/local/lib -L/Summa-Actors/bin -lcaf_core -lcaf_io -lsumma -lopenblas -lnetcdff
# Production runs
FLAGS_NOAH = -g -O3 -ffree-form -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors
FLAGS_COMM = -g -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors
FLAGS_SUMMA = -g -O3 -ffree-line-length-none -fmax-errors=0 -fPIC -Wfatal-errors
FLAGS_ACTORS = -g -O3 -Wfatal-errors -std=c++17
# Debug runs
# FLAGS_NOAH = -g -O0 -ffree-form -ffree-line-length-none -fmax-errors=0 -fbacktrace -Wno-unused -Wno-unused-dummy-argument -fPIC
# FLAGS_COMM = -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
# FLAGS_SUMMA = -g -O0 -Wall -ffree-line-length-none -fmax-errors=0 -fbacktrace -fcheck=bounds -fPIC
# FLAGS_ACTORS = -g -O0 -Wall -std=c++17
#========================================================================
# PART 1: Define directory paths
#========================================================================
# Core directory that contains source code
F_KORE_DIR = $(ROOT_DIR)/build/source
# Location of the compiled modules
MOD_PATH = $(ROOT_DIR)/build
# Define the directory for the executables
EXE_PATH = $(ROOT_DIR)/bin
####################################################################################################
###################################### Assemble Fortran Files ######################################
####################################################################################################
# Define directories
DRIVER_DIR = $(F_KORE_DIR)/driver
HOOKUP_DIR = $(F_KORE_DIR)/hookup
NETCDF_DIR = $(F_KORE_DIR)/netcdf
DSHARE_DIR = $(F_KORE_DIR)/dshare
NUMREC_DIR = $(F_KORE_DIR)/numrec
NOAHMP_DIR = $(F_KORE_DIR)/noah-mp
ENGINE_DIR = $(F_KORE_DIR)/engine
ACTORS_DIR = $(F_KORE_DIR)/actors
JOB_ACTOR_DIR = $(ACTORS_DIR)/job_actor
FILE_ACCESS_DIR = $(ACTORS_DIR)/file_access_actor
HRU_ACTOR_DIR = $(ACTORS_DIR)/hru_actor
GRU_ACTOR_DIR = $(ACTORS_DIR)/gru_actor
# utilities
SUMMA_NRUTIL= \
nrtype.f90 \
f2008funcs.f90 \
nr_utility.f90
NRUTIL = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_NRUTIL))
# Numerical recipes procedures
# NOTE: all numerical recipes procedures are now replaced with free versions
SUMMA_NRPROC= \
expIntegral.f90 \
spline_int.f90
NRPROC = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_NRPROC))
# Hook-up modules (set files and directory paths)
SUMMA_HOOKUP= \
ascii_util.f90 \
summaActors_FileManager.f90
HOOKUP = $(patsubst %, $(HOOKUP_DIR)/%, $(SUMMA_HOOKUP))
# Data modules
SUMMA_DATAMS= \
multiconst.f90 \
var_lookup.f90 \
data_types.f90 \
globalData.f90 \
flxMapping.f90 \
get_ixname.f90
DATAMS = $(patsubst %, $(DSHARE_DIR)/%, $(SUMMA_DATAMS))
SUMMA_DEPEND_ON_FILEMANAGER= \
popMetadat.f90 \
outpt_stat.f90
DEPEND_ON_FILEMANAGER = $(patsubst %, $(DSHARE_DIR)/%, $(SUMMA_DEPEND_ON_FILEMANAGER))
# utility modules
SUMMA_UTILMS= \
time_utils.f90 \
mDecisions.f90 \
snow_utils.f90 \
soil_utils.f90 \
updatState.f90 \
matrixOper.f90
UTILMS = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_UTILMS))
# Model guts
SUMMA_MODGUT= \
MODGUT = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_MODGUT))
# Solver
SUMMA_SOLVER= \
vegPhenlgy.f90 \
diagn_evar.f90 \
stomResist.f90 \
groundwatr.f90 \
vegSWavRad.f90 \
vegNrgFlux.f90 \
ssdNrgFlux.f90 \
vegLiqFlux.f90 \
snowLiqFlx.f90 \
soilLiqFlx.f90 \
bigAquifer.f90 \
computFlux.f90 \
computResid.f90 \
computJacob.f90 \
eval8summa.f90 \
summaSolve.f90 \
systemSolv.f90 \
varSubstep.f90 \
opSplittin.f90 \
coupled_em.f90
SOLVER = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_SOLVER))
# Interface code for Fortran-C++
SUMMA_INTERFACE= \
cppwrap_datatypes.f90 \
cppwrap_auxiliary.f90 \
cppwrap_metadata.f90 \
INTERFACE = $(patsubst %, $(ACTORS_DIR)/global/%, $(SUMMA_INTERFACE))
SUMMA_FILEACCESS_INTERFACE = \
initOutputStruc.f90 \
deallocateOutputStruc.f90 \
cppwrap_fileAccess.f90
FILEACCESS_INTERFACE = $(patsubst %, $(FILE_ACCESS_DIR)/%, $(SUMMA_FILEACCESS_INTERFACE))
SUMMA_JOB_INTERFACE = \
job_actor.f90
JOB_INTERFACE = $(patsubst %, $(JOB_ACTOR_DIR)/%, $(SUMMA_JOB_INTERFACE))
SUMMA_HRU_INTERFACE = \
cppwrap_hru.f90
HRU_INTERFACE = $(patsubst %, $(HRU_ACTOR_DIR)/%, $(SUMMA_HRU_INTERFACE))
SUMMA_GRU_INTERFACE = \
gru_actor.f90
GRU_INTERFACE = $(patsubst %, $(GRU_ACTOR_DIR)/%, $(SUMMA_GRU_INTERFACE))
# Define routines for SUMMA preliminaries
SUMMA_PRELIM= \
conv_funcs.f90 \
sunGeomtry.f90 \
convE2Temp.f90 \
allocspaceActors.f90 \
alloc_file_access.f90\
checkStruc.f90 \
childStruc.f90 \
ffile_info.f90 \
read_attribute.f90 \
read_pinit.f90 \
pOverwrite.f90 \
read_paramActors.f90 \
paramCheck.f90 \
check_icondActors.f90 \
# allocspace.f90
PRELIM = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_PRELIM))
SUMMA_NOAHMP= \
module_model_constants.F \
module_sf_noahutl.F \
module_sf_noahlsm.F \
module_sf_noahmplsm.F
NOAHMP = $(patsubst %, $(NOAHMP_DIR)/%, $(SUMMA_NOAHMP))
# Define routines for the SUMMA model runs
SUMMA_MODRUN = \
indexState.f90 \
getVectorz.f90 \
updateVars.f90 \
var_derive.f90 \
read_forcingActors.f90 \
access_forcing.f90\
access_write.f90 \
derivforce.f90 \
snowAlbedo.f90 \
canopySnow.f90 \
tempAdjust.f90 \
snwCompact.f90 \
layerMerge.f90 \
layerDivide.f90 \
volicePack.f90 \
qTimeDelay.f90
MODRUN = $(patsubst %, $(ENGINE_DIR)/%, $(SUMMA_MODRUN))
# Define NetCDF routines
# OutputStrucWrite is not a netcdf subroutine and should be
# moved
SUMMA_NETCDF = \
netcdf_util.f90 \
def_output.f90 \
outputStrucWrite.f90 \
writeOutput.f90 \
read_icondActors.f90
NETCDF = $(patsubst %, $(NETCDF_DIR)/%, $(SUMMA_NETCDF))
# ... stitch together common programs
COMM_ALL = $(NRUTIL) $(NRPROC) $(DATAMS) $(INTERFACE) $(HOOKUP) $(DEPEND_ON_FILEMANAGER) $(UTILMS)
# ... stitch together SUMMA programs
SUMMA_ALL = $(NETCDF) $(PRELIM) $(MODRUN) $(SOLVER)
# Define the driver routine
SUMMA_DRIVER= \
summaActors_type.f90 \
summaActors_util.f90 \
summaActors_globalData.f90 \
summaActors_init.f90 \
SummaActors_setup.f90 \
summaActors_restart.f90 \
summaActors_forcing.f90 \
SummaActors_modelRun.f90 \
summaActors_alarms.f90 \
summaActors_wOutputStruc.f90
DRIVER = $(patsubst %, $(DRIVER_DIR)/%, $(SUMMA_DRIVER))
####################################################################################################
###################################### Assemble Fortran Files ######################################
####################################################################################################
####################################################################################################
######################################## Assemble C++ Files ########################################
####################################################################################################
INCLUDE_DIR = /Summa-Actors/build/includes
SOURCE_DIR = /Summa-Actors/build/source/actors
GLOBAL_INCLUDES = -I$(INCLUDE_DIR)/global
GLOBAL = $(SOURCE_DIR)/global/global.cpp
TIMEINFO = $(SOURCE_DIR)/global/timing_info.cpp
SUMMA_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/summa_actor
SUMMA_ACTOR = $(SOURCE_DIR)/summa_actor/summa_actor.cpp
SUMMA_CLIENT = $(SOURCE_DIR)/summa_actor/summa_client.cpp
SUMMA_SERVER = $(SOURCE_DIR)/summa_actor/summa_server.cpp
BATCH_MANGER = $(SOURCE_DIR)/summa_actor/batch_manager.cpp
CLIENT_MANAGER = $(SOURCE_DIR)/summa_actor/client.cpp
GRU_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/gru_actor
GRU_ACTOR = $(SOURCE_DIR)/gru_actor/gru_actor.cpp
JOB_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/job_actor
JOB_ACTOR = $(SOURCE_DIR)/job_actor/job_actor.cpp
GRUinfo = $(SOURCE_DIR)/job_actor/GRUinfo.cpp
FILE_ACCESS_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/file_access_actor
FILE_ACCESS_ACTOR = $(SOURCE_DIR)/file_access_actor/file_access_actor.cpp
FORCING_FILE_INFO = $(SOURCE_DIR)/file_access_actor/forcing_file_info.cpp
OUTPUT_MANAGER = $(SOURCE_DIR)/file_access_actor/output_manager.cpp
HRU_ACTOR_INCLUDES = -I$(INCLUDE_DIR)/hru_actor
HRU_ACTOR = $(SOURCE_DIR)/hru_actor/hru_actor.cpp
MAIN = $(F_KORE_DIR)/actors/main.cpp
ACTOR_TEST = $(F_KORE_DIR)/testing/testing_main.cc
####################################################################################################
######################################## Assemble C++ Files ########################################
####################################################################################################
#========================================================================
# PART 3: compilation
#======================================================================
all: fortran cpp
fortran: compile_noah compile_comm compile_summa link clean_fortran
cpp: compile_globals compile_hru_actor compile_gru_actor compile_file_access_actor compile_job_actor compile_summa_actor \
compile_summa_client compile_summa_server compile_main link_cpp clean_cpp
test: actors_test actors_testLink actorsClean
###################################################################################################################
############################################## COMPILE SUMMA-Fortran ##############################################
###################################################################################################################
compile_noah:
$(FC) $(FLAGS_NOAH) -c $(NRUTIL) $(NOAHMP)
# compile common routines
compile_comm:
$(FC) $(FLAGS_COMM) -c $(COMM_ALL) $(INCLUDES)
# compile SUMMA routines
compile_summa:
$(FC) $(FLAGS_SUMMA) -c $(SUMMA_ALL) $(DRIVER) $(JOB_INTERFACE) $(FILEACCESS_INTERFACE) $(HRU_INTERFACE) $(GRU_INTERFACE) $(INCLUDES)
# generate library
link:
$(FC) -shared *.o -o libsumma.so
mv libsumma.so $(ROOT_DIR)/bin
# Remove object files
clean_fortran:
rm -f *.o *.mod soil_veg_gen_parm__genmod.f90
###################################################################################################################
############################################## COMPILE SUMMA-Fortran ##############################################
###################################################################################################################
###################################################################################################################
################################################ COMPILE SUMMA-C++ ################################################
###################################################################################################################
compile_globals:
$(CC) $(FLAGS_ACTORS) -c $(GLOBAL) $(TIMEINFO) $(GLOBAL_INCLUDES)
compile_gru_actor:
$(CC) $(FLAGS_ACTORS) -c $(GRU_ACTOR) $(GRU_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES)
compile_hru_actor:
$(CC) $(FLAGS_ACTORS) -c $(HRU_ACTOR) $(HRU_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES)
compile_file_access_actor:
$(CC) $(FLAGS_ACTORS) -c $(FILE_ACCESS_ACTOR) $(FORCING_FILE_INFO) $(OUTPUT_MANAGER) \
$(FILE_ACCESS_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES)
compile_job_actor:
$(CC) $(FLAGS_ACTORS) -c $(JOB_ACTOR) $(GRUinfo) $(JOB_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES) \
$(FILE_ACCESS_ACTOR_INCLUDES) $(HRU_ACTOR_INCLUDES) $(GRU_ACTOR_INCLUDES)
compile_summa_actor:
$(CC) $(FLAGS_ACTORS) -c $(SUMMA_ACTOR) $(SUMMA_ACTOR_INCLUDES) $(GLOBAL_INCLUDES) $(ACTORS_INCLUDES) \
$(JOB_ACTOR_INCLUDES)
compile_summa_client:
$(CC) $(FLAGS_ACTORS) -c $(SUMMA_CLIENT) $(SUMMA_ACTOR_INCLUDES) $(GLOBAL_INCLUDES)
compile_summa_server:
$(CC) $(FLAGS_ACTORS) -c $(SUMMA_SERVER) $(BATCH_MANGER) $(CLIENT_MANAGER) $(SUMMA_ACTOR_INCLUDES) $(GLOBAL_INCLUDES)
compile_main:
$(CC) $(FLAGS_ACTORS) -c $(MAIN) $(GLOBAL_INCLUDES) $(SUMMA_ACTOR_INCLUDES) $(JOB_ACTOR_INCLUDES)
link_cpp:
$(CC) $(FLAGS_ACTORS) -o summaMain *.o $(ACTORS_LIBRARIES)
mv summaMain $(ROOT_DIR)/bin
clean_cpp:
rm *.o
###################################################################################################################
################################################ COMPILE SUMMA-C++ ################################################
###################################################################################################################
###################################################################################################################
################################################## COMPILE TESTS ##################################################
###################################################################################################################
actors_test:
$(CC) $(FLAGS_ACTORS) -c $(ACTOR_TEST) -std=c++17 $(ACTORS_INCLUDES)
actors_testLink:
$(CC) -o summaTest *.o $(ACTORS_LIBRARIES)
clean_lib:
rm *.so
module summaActors_deallocateOuptutStruct
USE nrtype
implicit none
public::deallocateOutputStruc
contains
subroutine deallocateOutputStruc(err)
USE globalData,only:outputStructure
implicit none
integer(i4b), intent(inout) :: err
err = 0
! Time
call deallocateData_output(outputStructure(1)%timeStruct(1)); deallocate(outputStructure(1)%timeStruct)
! Forc
call deallocateData_output(outputStructure(1)%forcStat(1)); deallocate(outputStructure(1)%forcStat)
call deallocateData_output(outputStructure(1)%forcStruct(1)); deallocate(outputStructure(1)%forcStruct)
! prog
call deallocateData_output(outputStructure(1)%progStat(1)); deallocate(outputStructure(1)%progStat)
call deallocateData_output(outputStructure(1)%progStruct(1)); deallocate(outputStructure(1)%progStruct)
! diag
call deallocateData_output(outputStructure(1)%diagStat(1)); deallocate(outputStructure(1)%diagStat)
call deallocateData_output(outputStructure(1)%diagStruct(1)); deallocate(outputStructure(1)%diagStruct)
! flux
call deallocateData_output(outputStructure(1)%fluxStat(1)); deallocate(outputStructure(1)%fluxStat)
call deallocateData_output(outputStructure(1)%fluxStruct(1)); deallocate(outputStructure(1)%fluxStruct)
! indx
call deallocateData_output(outputStructure(1)%indxStat(1)); deallocate(outputStructure(1)%indxStat)
call deallocateData_output(outputStructure(1)%indxStruct(1)); deallocate(outputStructure(1)%indxStruct)
! bvar
call deallocateData_output(outputStructure(1)%bvarStat(1)); deallocate(outputStructure(1)%bvarStat)
call deallocateData_output(outputStructure(1)%bvarStruct(1)); deallocate(outputStructure(1)%bvarStruct)
! id
call deallocateData_output(outputStructure(1)%idStruct(1)); deallocate(outputStructure(1)%idStruct)
! attr
call deallocateData_output(outputStructure(1)%attrStruct(1)); deallocate(outputStructure(1)%attrStruct)
! type
call deallocateData_output(outputStructure(1)%typeStruct(1)); deallocate(outputStructure(1)%typeStruct)
! mpar
call deallocateData_output(outputStructure(1)%mparStruct(1)); deallocate(outputStructure(1)%mparStruct)
! bpar
call deallocateData_output(outputStructure(1)%bparStruct(1)); deallocate(outputStructure(1)%bparStruct)
! finalize stats
call deallocateData_output(outputStructure(1)%finalizeStats(1)); deallocate(outputStructure(1)%finalizeStats)
end subroutine deallocateOutputStruc
subroutine deallocateData_output(dataStruct)
USE data_types,only:gru_hru_time_doubleVec, &
gru_hru_time_intVec, &
gru_hru_time_flagVec, &
gru_hru_time_int, &
gru_hru_int, &
gru_hru_time_int8, &
gru_hru_time_double, &
gru_hru_double, &
gru_double
implicit none
class(*),intent(inout) :: dataStruct
! local variables
integer(i4b) :: iGRU
integer(i4b) :: iHRU
integer(i4b) :: iVar
integer(i4b) :: iTim
select type(dataStruct)
class is (gru_hru_time_doubleVec)
do iGRU = 1, size(dataStruct%gru(:))
do iHRU = 1, size(dataStruct%gru(iGRU)%hru(:))
do iVar = 1, size(dataStruct%gru(iGRU)%hru(iHRU)%var(:))
do iTim = 1, size(dataStruct%gru(iGRU)%hru(iHRU)%var(iVar)%tim(:))
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var(iVar)%tim(iTim)%dat)
end do ! Time
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var(iVar)%tim)
end do ! var
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var)
end do ! hru
deallocate(dataStruct%gru(iGRU)%hru)
end do ! gru
deallocate(dataStruct%gru)
class is (gru_hru_time_intVec)
do iGRU = 1, size(dataStruct%gru(:))
do iHRU = 1, size(dataStruct%gru(iGRU)%hru(:))
do iVar = 1, size(dataStruct%gru(iGRU)%hru(iHRU)%var(:))
do iTim = 1, size(dataStruct%gru(iGRU)%hru(iHRU)%var(iVar)%tim(:))
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var(iVar)%tim(iTim)%dat)
end do ! Time
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var(iVar)%tim)
end do ! var
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var)
end do ! hru
deallocate(dataStruct%gru(iGRU)%hru)
end do ! gru
deallocate(dataStruct%gru)
class is (gru_hru_time_flagVec)
do iGRU = 1, size(dataStruct%gru(:))
do iHRU = 1, size(dataStruct%gru(iGRU)%hru(:))
do iTim = 1, size(dataStruct%gru(iGRU)%hru(iHRU)%tim(:))
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%tim(iTim)%dat)
end do ! Time
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%tim)
end do ! hru
deallocate(dataStruct%gru(iGRU)%hru)
end do ! gru
deallocate(dataStruct%gru)
class is (gru_hru_time_int)
do iGRU = 1, size(dataStruct%gru(:))
do iHRU = 1, size(dataStruct%gru(iGRU)%hru(:))
do iVar = 1, size(dataStruct%gru(iGRU)%hru(iHRU)%var(:))
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var(iVar)%tim)
end do ! var
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var)
end do ! hru
deallocate(dataStruct%gru(iGRU)%hru)
end do ! gru
deallocate(dataStruct%gru)
class is (gru_hru_int)
do iGRU = 1, size(dataStruct%gru(:))
do iHRU = 1, size(dataStruct%gru(iGRU)%hru(:))
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var)
end do ! hru
deallocate(dataStruct%gru(iGRU)%hru)
end do ! gru
deallocate(dataStruct%gru)
class is (gru_hru_time_int8)
do iGRU = 1, size(dataStruct%gru(:))
do iHRU = 1, size(dataStruct%gru(iGRU)%hru(:))
do iVar = 1, size(dataStruct%gru(iGRU)%hru(iHRU)%var(:))
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var(iVar)%tim)
end do ! var
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var)
end do ! hru
deallocate(dataStruct%gru(iGRU)%hru)
end do ! gru
deallocate(dataStruct%gru)
class is (gru_hru_time_double)
do iGRU = 1, size(dataStruct%gru(:))
do iHRU = 1, size(dataStruct%gru(iGRU)%hru(:))
do iVar = 1, size(dataStruct%gru(iGRU)%hru(iHRU)%var(:))
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var(iVar)%tim)
end do ! var
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var)
end do ! hru
deallocate(dataStruct%gru(iGRU)%hru)
end do ! gru
deallocate(dataStruct%gru)
class is (gru_hru_double)
do iGRU = 1, size(dataStruct%gru(:))
do iHRU = 1, size(dataStruct%gru(iGRU)%hru(:))
deallocate(dataStruct%gru(iGRU)%hru(iHRU)%var)
end do ! hru
deallocate(dataStruct%gru(iGRU)%hru)
end do ! gru
deallocate(dataStruct%gru)
class is (gru_double)
do iGRU = 1, size(dataStruct%gru(:))
deallocate(dataStruct%gru(iGRU)%var)
end do ! gru
deallocate(dataStruct%gru)
end select
end subroutine
end module
\ No newline at end of file
......@@ -18,10 +18,10 @@
! You should have received a copy of the GNU General Public License
! along with this program. If not, see <http://www.gnu.org/licenses/>.
module def_output_module
module def_output_actors_module
USE, intrinsic :: iso_c_binding
USE data_types,only:var_i
USE data_types,only:var_i
USE actor_data_types,only:netcdf_gru_actor_info
USE netcdf
USE netcdf_util_module,only:netcdf_err ! netcdf error handling function
USE netcdf_util_module,only:nc_file_close ! close NetCDF files
......@@ -72,7 +72,7 @@ contains
! **********************************************************************************************************
! public subroutine def_output: define model output file
! **********************************************************************************************************
subroutine def_output(handle_ncid,startGRU,nGRU,nHRU,err) bind(C, name='def_output')
subroutine def_output(ncid,startGRU,nGRU,nHRU,actor_info,err,message)
USE globalData,only:structInfo ! information on the data structures
USE globalData,only:forc_meta,attr_meta,type_meta ! metaData structures
USE globalData,only:prog_meta,diag_meta,flux_meta,deriv_meta ! metaData structures
......@@ -80,9 +80,7 @@ subroutine def_output(handle_ncid,startGRU,nGRU,nHRU,err) bind(C, name='def_outp
USE globalData,only:bpar_meta,bvar_meta,time_meta ! metaData structures
USE globalData,only:model_decisions ! model decisions
USE globalData,only:outFreq ! output frequencies
USE globalData,only:fname
! Some global variabels required in the writing process
USE globalData,only:outputTimeStep
USE globalData,only:nHRUrun
USE globalData,only:nGRUrun
USE globalData,only:gru_struc
......@@ -90,24 +88,23 @@ subroutine def_output(handle_ncid,startGRU,nGRU,nHRU,err) bind(C, name='def_outp
! modules that are not globalData
USE var_lookup,only:maxVarFreq ! # of available output frequencies
USE get_ixname_module,only:get_freqName ! get name of frequency from frequency index
USE summaActors_FileManager,only:OUTPUT_PATH,OUTPUT_PREFIX ! define output file
USE summaFileManager,only:OUTPUT_PATH,OUTPUT_PREFIX ! define output file
USE globalData,only:outputTimeStep ! output time step
! ---------------------------------------------------------------------------------------
! * variables from C++
! * Dummy Variables
! ---------------------------------------------------------------------------------------
type(c_ptr),intent(in), value :: handle_ncid ! ncid of the output file
integer(c_int),intent(in) :: startGRU ! startGRU for the entire job (for file creation)
integer(c_int),intent(in) :: nGRU ! number of GRUs
integer(c_int),intent(in) :: nHRU ! number of HRUs
integer(c_int),intent(out) :: err ! error code
! ---------------------------------------------------------------------------------------
! * Fortran Variables For Conversion
! ---------------------------------------------------------------------------------------
type(var_i),pointer :: ncid ! id of output file
type(var_i),pointer :: ncid ! id of output file
integer(i4b),intent(in) :: startGRU ! startGRU for the entire job (for file creation)
integer(i4b),intent(in) :: nGRU ! number of GRUs
integer(i4b),intent(in) :: nHRU ! number of HRUs
type(netcdf_gru_actor_info),intent(out):: actor_info ! netcdf actor information
character(*),intent(out) :: message ! error message
integer(i4b),intent(out) :: err ! error code
! ---------------------------------------------------------------------------------------
! * Local Subroutine Variables
! ---------------------------------------------------------------------------------------
character(len=256) :: message ! error message
integer(i4b) :: ivar ! loop through model decisions
integer(i4b) :: iFreq ! loop through output frequencies
integer(i4b) :: iStruct ! loop through structure types
......@@ -116,10 +113,7 @@ subroutine def_output(handle_ncid,startGRU,nGRU,nHRU,err) bind(C, name='def_outp
integer(i4b) :: iGRU
character(LEN=256) :: startGRUString ! String Variable to convert startGRU
character(LEN=256) :: numGRUString ! String Varaible to convert numGRU
! ---------------------------------------------------------------------------------------
! * Convert From C++ to Fortran
! ---------------------------------------------------------------------------------------
call c_f_pointer(handle_ncid, ncid)
character(len=1024) :: fname ! temporary filename
! initialize errors
......@@ -130,15 +124,7 @@ subroutine def_output(handle_ncid,startGRU,nGRU,nHRU,err) bind(C, name='def_outp
allocate(ncid%var(maxVarFreq))
ncid%var(:) = integerMissing
endif
! initalize outputTimeStep - keeps track of the step the GRU is writing for
if (.not.allocated(outputTimeStep))then
allocate(outputTimeStep(nGRU))
do iGRU = 1, nGRU
allocate(outputTimeStep(iGRU)%dat(maxVarFreq))
outputTimeStep(iGRU)%dat(:) = 1
end do
end if
! Set the global variable for the number of HRU and GRU in run
nGRUrun = nGRU
......@@ -154,10 +140,17 @@ subroutine def_output(handle_ncid,startGRU,nGRU,nHRU,err) bind(C, name='def_outp
do iFreq=1,maxvarFreq
if (ncid%var(iFreq)/=integerMissing) then
call nc_file_close(ncid%var(iFreq),err,cmessage)
if(err/=0)then; message=trim(message)//trim(cmessage); return; end if
if(err/=0)then
message=trim(message)//trim(cmessage)
print*, message
return
end if
endif
end do
! create initial file
! each file will have a master name with a frequency appended at the end:
! e.g., xxxxxxxxx_timestep.nc (for output at every model timestep)
......@@ -171,39 +164,67 @@ subroutine def_output(handle_ncid,startGRU,nGRU,nHRU,err) bind(C, name='def_outp
fstring = get_freqName(iFreq)
fname = trim(fileout)//'_'//trim(fstring)//'.nc'
call ini_create(nGRU,nHRU,gru_struc(1)%hruInfo(1)%nSoil,trim(fname),ncid%var(iFreq),err,cmessage)
if(err/=0)then; message=trim(message)//trim(cmessage); return; end if
if(err/=0)then; message=trim(message)//trim(cmessage); print*, message; return; end if
! define model decisions
do iVar = 1,size(model_decisions)
if(model_decisions(iVar)%iDecision.ne.integerMissing)then
call put_attrib(ncid%var(iFreq),model_decisions(iVar)%cOption,model_decisions(iVar)%cDecision,err,cmessage)
if(err/=0)then; message=trim(message)//trim(cmessage); return; end if
if(err/=0)then
message=trim(message)//trim(cmessage)
print*, message
return
end if
end if
end do
! define variables
do iStruct = 1,size(structInfo)
select case (trim(structInfo(iStruct)%structName))
case('attr' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,attr_meta, outputPrecision, err,cmessage) ! local attributes HRU
case('type' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,type_meta, nf90_int, err,cmessage) ! local classification
case('mpar' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,mpar_meta, outputPrecision, err,cmessage) ! model parameters
case('bpar' ); call def_variab(ncid%var(iFreq),iFreq,needGRU, noTime,bpar_meta, outputPrecision, err,cmessage) ! basin-average param
case('indx' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,indx_meta, nf90_int, err,cmessage) ! model variables
case('deriv'); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,deriv_meta,outputPrecision, err,cmessage) ! model derivatives
case('time' ); call def_variab(ncid%var(iFreq),iFreq, noHRU,needTime,time_meta, nf90_int, err,cmessage) ! model derivatives
case('forc' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,forc_meta, outputPrecision, err,cmessage) ! model forcing data
case('prog' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,prog_meta, outputPrecision, err,cmessage) ! model prognostics
case('diag' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,diag_meta, outputPrecision, err,cmessage) ! model diagnostic variables
case('flux' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,flux_meta, outputPrecision, err,cmessage) ! model fluxes
case('bvar' ); call def_variab(ncid%var(iFreq),iFreq,needGRU,needTime,bvar_meta, outputPrecision, err,cmessage) ! basin-average variables
case('id' ); cycle ! ids -- see write_hru_info()
case('attr' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,attr_meta, outputPrecision, err,cmessage) ! local attributes HRU
case('type' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,type_meta, nf90_int, err,cmessage) ! local classification
case('mpar' ); call def_variab(ncid%var(iFreq),iFreq,needHRU, noTime,mpar_meta, outputPrecision, err,cmessage) ! model parameters
case('bpar' ); call def_variab(ncid%var(iFreq),iFreq,needGRU, noTime,bpar_meta, outputPrecision, err,cmessage) ! basin-average param
case('indx' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,indx_meta, nf90_int, err,cmessage) ! model variables
case('deriv' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,deriv_meta,outputPrecision, err,cmessage) ! model derivatives
case('time' ); call def_variab(ncid%var(iFreq),iFreq, noHRU,needTime,time_meta, nf90_int, err,cmessage) ! model derivatives
case('forc' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,forc_meta, outputPrecision, err,cmessage) ! model forcing data
case('prog' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,prog_meta, outputPrecision, err,cmessage) ! model prognostics
case('diag' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,diag_meta, outputPrecision, err,cmessage) ! model diagnostic variables
case('flux' ); call def_variab(ncid%var(iFreq),iFreq,needHRU,needTime,flux_meta, outputPrecision, err,cmessage) ! model fluxes
case('bvar' ); call def_variab(ncid%var(iFreq),iFreq,needGRU,needTime,bvar_meta, outputPrecision, err,cmessage) ! basin-average variables
case('id' ); cycle
case('lookup'); cycle ! ids -- see write_hru_info()
case default; err=20; message=trim(message)//'unable to identify lookup structure';
end select
! error handling
if(err/=0)then;err=20;message=trim(message)//trim(cmessage)//'[structure = '//trim(structInfo(iStruct)%structName);return;end if
if(err/=0)then
err=20
message=trim(message)//trim(cmessage)//'[structure = '//trim(structInfo(iStruct)%structName)
print*, message
return
end if
end do ! iStruct
! write HRU dimension and ID for each output file
call write_hru_info(ncid%var(iFreq), err, cmessage); if(err/=0) then; message=trim(message)//trim(cmessage); return; end if
call write_hru_info(ncid%var(iFreq), err, cmessage)
if(err/=0) then
message=trim(message)//trim(cmessage)
print*, message
return
end if
! define timing variables for actors code
! TODO: Add attributes to these variables
err = nf90_def_var(ncid%var(iFreq),"run_time",outputPrecision,(/gru_DimID/),actor_info%run_time_var_id)
err = nf90_def_var(ncid%var(iFreq),"init_duration",outputPrecision,(/gru_DimID/),actor_info%init_duration_var_id)
err = nf90_def_var(ncid%var(iFreq),"forcing_duration",outputPrecision,(/gru_DimID/),actor_info%forcing_duration_var_id)
err = nf90_def_var(ncid%var(iFreq),"run_physics_duration",outputPrecision,(/gru_DimID/),actor_info%run_physics_duration_var_id)
err = nf90_def_var(ncid%var(iFreq),"write_output_duration",outputPrecision,(/gru_DimID/),actor_info%write_output_duration_var_id)
err = nf90_def_var(ncid%var(iFreq),"successful",nf90_int,(/gru_DimID/),actor_info%state_var_id)
err = nf90_def_var(ncid%var(iFreq),"num_attempts",nf90_int,(/gru_DimID/),actor_info%num_attempts_var_id)
err = nf90_def_var(ncid%var(iFreq),"rel_tol",outputPrecision,(/gru_DimID/),actor_info%rel_tol_var_id)
err = nf90_def_var(ncid%var(iFreq),"abs_tol",outputPrecision,(/gru_DimID/),actor_info%abs_tol_var_id)
if(err/=0) then; message=trim(message)//trim(cmessage); print*, message; return; end if
end do
end subroutine def_output
......@@ -515,4 +536,4 @@ subroutine ini_create(nGRU,nHRU,nSoil,infile,ncid,err,message)
end subroutine
end module def_output_module
end module def_output_actors_module