cleanup
This commit is contained in:
27
gridmanager/CMakeLists.backup
Normal file
27
gridmanager/CMakeLists.backup
Normal file
@@ -0,0 +1,27 @@
|
||||
set(TOOL_NAME gridmanager)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_search_module(EDITLINE REQUIRED libeditline)
|
||||
include_directories(${EDITLINE_INCLUDE_DIRS})
|
||||
link_directories(${EDITLINE_LIBRARY_DIRS})
|
||||
|
||||
aux_source_directory(. TOOL_SRC)
|
||||
add_executable(${TOOL_NAME} ${TOOL_SRC})
|
||||
|
||||
set_target_properties(${TOOL_NAME} PROPERTIES INSTALL_RPATH /usr/local/lib)
|
||||
set_target_properties(${TOOL_NAME} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
target_link_libraries(${TOOL_NAME} PRIVATE ${GCTL_LIB})
|
||||
target_link_libraries(${TOOL_NAME} PRIVATE ${GCTL_GRAPHIC_LIB})
|
||||
target_link_libraries(${TOOL_NAME} PRIVATE gctl_mesh)
|
||||
target_link_libraries(${TOOL_NAME} PRIVATE ${WaveLib_LIB})
|
||||
target_link_libraries(${TOOL_NAME} PRIVATE ${EDITLINE_LIBRARIES})
|
||||
|
||||
install(TARGETS ${TOOL_NAME} RUNTIME DESTINATION sbin)
|
||||
|
||||
file(GLOB HELP_DOC *.md)
|
||||
install(FILES ${HELP_DOC} DESTINATION sbin/share)
|
776
gridmanager/gridmanager.cpp
Normal file
776
gridmanager/gridmanager.cpp
Normal file
@@ -0,0 +1,776 @@
|
||||
/********************************************************
|
||||
* ██████╗ ██████╗████████╗██╗
|
||||
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
||||
* ██║ ███╗██║ ██║ ██║
|
||||
* ██║ ██║██║ ██║ ██║
|
||||
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
||||
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
||||
* Geophysical Computational Tools & Library (GCTL)
|
||||
*
|
||||
* Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn)
|
||||
*
|
||||
* GCTL is distributed under a dual licensing scheme. You can redistribute
|
||||
* it and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation, either version 2
|
||||
* of the License, or (at your option) any later version. You should have
|
||||
* received a copy of the GNU Lesser General Public License along with this
|
||||
* program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* If the terms and conditions of the LGPL v.2. would prevent you from using
|
||||
* the GCTL, please consider the option to obtain a commercial license for a
|
||||
* fee. These licenses are offered by the GCTL's original author. As a rule,
|
||||
* licenses are provided "as-is", unlimited in time for a one time fee. Please
|
||||
* send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget
|
||||
* to include some description of your company and the realm of its activities.
|
||||
* Also add information on how to contact you by electronic and paper mail.
|
||||
******************************************************/
|
||||
|
||||
#include "gridmanager.h"
|
||||
// We use the editline library to handle all inputs
|
||||
#include "editline.h"
|
||||
// install configuration
|
||||
#include "../gctl_toolkits_config.h"
|
||||
|
||||
cmd_pair curr_cmd; // Executing command
|
||||
gctl::regular_grid rg; // Grid object
|
||||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
* Strip whitespace from the start and end of STRING. Return a pointer
|
||||
* into STRING.
|
||||
*/
|
||||
char *stripwhite(char *string)
|
||||
{
|
||||
char *s, *t;
|
||||
|
||||
for (s = string; isspace(*s); s++) ;
|
||||
|
||||
if (*s == 0)
|
||||
return s;
|
||||
|
||||
t = s + strlen(s) - 1;
|
||||
while (t > s && isspace(*t))
|
||||
t--;
|
||||
*++t = '\0';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Generator function for command completion. STATE lets us
|
||||
know whether to start from scratch; without any state
|
||||
(i.e. STATE == 0), then we start at the top of the list. */
|
||||
char *command_generator(const char *text, int state)
|
||||
{
|
||||
static int list_index, len;
|
||||
|
||||
/* If this is a new word to complete, initialize now. This
|
||||
includes saving the length of TEXT for efficiency, and
|
||||
initializing the index variable to 0. */
|
||||
if (!state)
|
||||
{
|
||||
list_index = 0;
|
||||
len = strlen(text);
|
||||
}
|
||||
|
||||
/* Return the next name which partially matches from the command list. */
|
||||
while (list_index < CMD_NUM)
|
||||
{
|
||||
if (std::string(text) == commands[list_index].name.substr(0, len))
|
||||
{
|
||||
//const char* name = commands[list_index].name.data();
|
||||
return strdup(commands[list_index].name.data());
|
||||
}
|
||||
else list_index++;
|
||||
}
|
||||
|
||||
/* If no names matched, then return NULL. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to complete on the contents of TEXT. START and END
|
||||
* bound the region of rl_line_buffer that contains the word to
|
||||
* complete. TEXT is the word to complete. We can use the entire
|
||||
* contents of rl_line_buffer in case we want to do some simple
|
||||
* parsing. Return the array of matches, or NULL if there aren't any.
|
||||
*/
|
||||
char **gridmanager_completion(const char *text, int start, int end)
|
||||
{
|
||||
char **matches = nullptr;
|
||||
|
||||
/* If this word is at the start of the line, then it is a command
|
||||
to complete. Otherwise it is the name of a file in the current
|
||||
directory. */
|
||||
if (start == 0) matches = rl_completion_matches(text, command_generator);
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
void initialize_readline(void)
|
||||
{
|
||||
/* Allow conditional parsing of the ~/.inputrc file. */
|
||||
rl_readline_name = "gridmanager";
|
||||
|
||||
/* Tell the completer that we want a crack first. */
|
||||
rl_attempted_completion_function = gridmanager_completion;
|
||||
}
|
||||
|
||||
} // End C section
|
||||
|
||||
void display_cmds()
|
||||
{
|
||||
std::clog << "Command:\n";
|
||||
for (size_t i = 0; i < CMD_NUM - 1; i++)
|
||||
{
|
||||
std::clog << std::setw(12) << commands[i].name << ":\t" << commands[i].brief << "\n";
|
||||
}
|
||||
|
||||
std::clog << "\nEnter \"<command>?\" to see detailed instructions.\n\n";
|
||||
std::clog << "Keywords:\n";
|
||||
for (size_t i = 0; i < KEY_NUM; i++)
|
||||
{
|
||||
std::clog << std::setw(12) << keywords[i].name << ":\t" << keywords[i].brief << "\n";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void display_help(std::string input_cmd)
|
||||
{
|
||||
std::string install_dir = GCTL_TOOLKITS_INSTALL_PREFIX;
|
||||
std::ifstream helpin;
|
||||
open_infile(helpin, install_dir + "/sbin/share/readme_gridmanager", ".md");
|
||||
|
||||
std::string tmp_l, tmp_help;
|
||||
std::vector<std::string> cmds;
|
||||
std::vector<std::string> helps;
|
||||
while (getline(helpin, tmp_l))
|
||||
{
|
||||
if (tmp_l.substr(0, 4) == "####")
|
||||
{
|
||||
cmds.push_back(tmp_l.substr(5));
|
||||
tmp_help = "";
|
||||
while (getline(helpin, tmp_l))
|
||||
{
|
||||
if (tmp_l == "") break;
|
||||
else tmp_help += tmp_l + "\n";
|
||||
}
|
||||
helps.push_back(tmp_help);
|
||||
}
|
||||
}
|
||||
helpin.close();
|
||||
|
||||
std::string cmd_str;
|
||||
for (size_t j = 0; j < cmds.size(); j++)
|
||||
{
|
||||
parse_string_to_value(cmds[j], ' ', true, cmd_str);
|
||||
if (input_cmd == cmd_str)
|
||||
{
|
||||
replace_all(tmp_l, cmds[j], "\\", "");
|
||||
std::cout << GCTL_BOLDGREEN << tmp_l << GCTL_RESET << "\n";
|
||||
std::cout << helps[j] << "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void exec_cmd(std::string cmd)
|
||||
{
|
||||
std::string cmd_name;
|
||||
parse_string_to_value(cmd, ' ', true, cmd_name);
|
||||
|
||||
// show instruction if there is a question mark at end of the command
|
||||
if (cmd_name.back() == '?')
|
||||
{
|
||||
cmd_name = cmd_name.substr(0, cmd_name.length() - 1);
|
||||
display_help(cmd_name);
|
||||
return;
|
||||
}
|
||||
|
||||
// set default command to null
|
||||
curr_cmd = commands[CMD_NUM - 1];
|
||||
for (size_t i = 0; i < CMD_NUM - 1; i++)
|
||||
{
|
||||
if (cmd_name == commands[i].name)
|
||||
{
|
||||
curr_cmd = commands[i]; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (curr_cmd.func_p == nullptr) throw gctl::runtime_error("Invalid command: " + cmd_name);
|
||||
|
||||
std::vector<std::string> cmd_units;
|
||||
parse_string_with_quotes(cmd, cmd_units);
|
||||
|
||||
return curr_cmd.func_p(cmd_units);
|
||||
}
|
||||
|
||||
// This function is defined to avoid potential breakdown while running in script mode.
|
||||
void quit(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void mesh_info(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// info [\<new-grid-name\>] [\<new-info\>]
|
||||
if (cmd_units.size() == 1)
|
||||
{
|
||||
rg.show_info();
|
||||
return;
|
||||
}
|
||||
|
||||
gctl::array<std::string> copy_str(2, "null");
|
||||
for (size_t i = 1; i <= GCTL_MIN(cmd_units.size() - 1, 2); i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
if (copy_str[0] != "null") rg.set_meshname(copy_str[0]);
|
||||
if (copy_str[1] != "null") rg.set_meshinfo(copy_str[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef GCTL_MESH_EXPRTK
|
||||
|
||||
inline double expr2double(std::string s)
|
||||
{
|
||||
exprtk::symbol_table<double> sym_tab;
|
||||
exprtk::expression<double> expr;
|
||||
exprtk::parser<double> p;
|
||||
|
||||
sym_tab.add_constants();
|
||||
expr.register_symbol_table(sym_tab);
|
||||
p.compile(s, expr);
|
||||
|
||||
return expr.value();
|
||||
}
|
||||
|
||||
#endif // GCTL_MESH_EXPRTK
|
||||
|
||||
void new_grid(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// new \<new-file\> \<xnum\> \<ynum\> \<xmin\> \<ymin\> \<dx\> \<dy\> [\<info\>]
|
||||
if (cmd_units.size() < 8) throw std::runtime_error("new-grid: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(8, "null");
|
||||
for (size_t i = 1; i <= GCTL_MIN(cmd_units.size() - 1, 8); i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
if (rg.initiated()) rg.clear_regular_grid();
|
||||
|
||||
double xmin, ymin, dx, dy;
|
||||
#ifdef GCTL_MESH_EXPRTK
|
||||
|
||||
xmin = expr2double(copy_str[3]);
|
||||
ymin = expr2double(copy_str[4]);
|
||||
dx = expr2double(copy_str[5]);
|
||||
dy = expr2double(copy_str[6]);
|
||||
|
||||
#else
|
||||
|
||||
xmin = atof(copy_str[3].c_str());
|
||||
ymin = atof(copy_str[4].c_str());
|
||||
dx = atof(copy_str[5].c_str());
|
||||
dy = atof(copy_str[6].c_str());
|
||||
|
||||
#endif // GCTL_MESH_EXPRTK
|
||||
|
||||
rg.init(copy_str[0], copy_str[7], atoi(copy_str[1].c_str()),
|
||||
atoi(copy_str[2].c_str()), xmin, ymin, dx, dy);
|
||||
return;
|
||||
}
|
||||
|
||||
void open_grid(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// open binary <file>
|
||||
// open netcdf <file> [<x-name> <y-name>] [<data-name>] [node|cell]
|
||||
// open surfer <file> <new-data-name> [surfer6-text|surfer6-binary|surfer7] [node|cell]
|
||||
if (cmd_units.size() < 3) throw std::runtime_error("open: insufficient parameters.");
|
||||
|
||||
if (cmd_units[1] == "binary") open_binary(cmd_units);
|
||||
else if (cmd_units[1] == "netcdf") open_netcdf(cmd_units);
|
||||
else if (cmd_units[1] == "surfer") open_surfer(cmd_units);
|
||||
else throw std::runtime_error("open: unknown file format.");
|
||||
return;
|
||||
}
|
||||
|
||||
void save_grid(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// save binary <file>
|
||||
// save netcdf <file> [<data-name>|node|cell]
|
||||
// save surfer <file> <data-name> [surfer6-text|surfer6-binary|surfer7]
|
||||
// save gmsh <file>
|
||||
// save text <file> <data-name> [<data-name>]...
|
||||
if (cmd_units.size() < 3) throw std::runtime_error("save: insufficient parameters.");
|
||||
|
||||
if (cmd_units[1] == "binary") save_binary(cmd_units);
|
||||
else if (cmd_units[1] == "netcdf") save_netcdf(cmd_units);
|
||||
else if (cmd_units[1] == "surfer") save_surfer(cmd_units);
|
||||
else if (cmd_units[1] == "gmsh") save_gmsh(cmd_units);
|
||||
else if (cmd_units[1] == "text") save_text(cmd_units);
|
||||
else throw std::runtime_error("save: unknown file format.");
|
||||
return;
|
||||
}
|
||||
|
||||
void open_binary(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// open binary <file>
|
||||
rg.load_binary(cmd_units[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
void save_binary(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// save binary <file>
|
||||
rg.save_binary(cmd_units[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
void open_netcdf(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// open netcdf <file> [<x-name> <y-name>] [<data-name>] [node|cell]
|
||||
if (cmd_units.size() < 3) throw std::runtime_error("open: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(5, "null");
|
||||
for (size_t i = 0; i < GCTL_MIN(cmd_units.size() - 2, 5); i++)
|
||||
{
|
||||
copy_str[i] = cmd_units[i + 2];
|
||||
}
|
||||
|
||||
mesh_data_type_e d_type = NodeData;
|
||||
if (copy_str[4] == "cell") d_type = ElemData;
|
||||
else if (copy_str[4] == "node") d_type = NodeData;
|
||||
|
||||
if (copy_str[1] == "null") copy_str[1] = "x";
|
||||
if (copy_str[2] == "null") copy_str[2] = "y";
|
||||
if (copy_str[3] == "null") rg.load_netcdf_grid(copy_str[0], d_type, copy_str[1], copy_str[2]);
|
||||
else rg.load_netcdf_grid(copy_str[0], d_type, copy_str[1], copy_str[2], copy_str[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
void save_netcdf(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// save netcdf <file> [<data-name>|node|cell] [xname] [yname]
|
||||
if (cmd_units.size() < 3) throw std::runtime_error("save: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(4, "null");
|
||||
for (size_t i = 0; i < GCTL_MIN(cmd_units.size() - 2, 4); i++)
|
||||
{
|
||||
copy_str[i] = cmd_units[i + 2];
|
||||
}
|
||||
|
||||
std::string xname = "x", yname = "y";
|
||||
if (copy_str[2] != "null") xname = copy_str[2];
|
||||
if (copy_str[3] != "null") yname = copy_str[3];
|
||||
|
||||
if (copy_str[1] == "null") rg.save_netcdf_grid(copy_str[0], NodeData, xname, yname);
|
||||
else if (copy_str[1] == "node") rg.save_netcdf_grid(copy_str[0], NodeData, xname, yname);
|
||||
else if (copy_str[1] == "cell") rg.save_netcdf_grid(copy_str[0], ElemData, xname, yname);
|
||||
else rg.save_netcdf_grid(copy_str[0], copy_str[1], xname, yname);
|
||||
return;
|
||||
}
|
||||
|
||||
void save_gmsh(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// save gmsh <file>
|
||||
if (cmd_units.size() < 3) throw std::runtime_error("save: insufficient parameters.");
|
||||
|
||||
rg.save_gmsh_withdata(cmd_units[2], OverWrite, NotPacked);
|
||||
return;
|
||||
}
|
||||
|
||||
void open_surfer(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// open surfer <file> [<new-data-name>] [surfer6-text|surfer6-binary|surfer7] [node|cell]
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("open: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(4, "null");
|
||||
for (size_t i = 0; i < GCTL_MIN(cmd_units.size() - 2, 4); i++)
|
||||
{
|
||||
copy_str[i] = cmd_units[i + 2];
|
||||
}
|
||||
|
||||
surfer_file_type_e st = Surfer6Text;
|
||||
if (copy_str[2] == "surfer6-text") st = Surfer6Text;
|
||||
else if (copy_str[2] == "surfer6-binary") st = Surfer6Binary;
|
||||
else if (copy_str[2] == "surfer7") st = Surfer7Grid;
|
||||
|
||||
mesh_data_type_e d_type = NodeData;
|
||||
if (copy_str[3] == "node") d_type = NodeData;
|
||||
else if (copy_str[3] == "cell") d_type = ElemData;
|
||||
|
||||
if (copy_str[1] == "null") rg.load_surfer_grid(copy_str[0], "Untitled", d_type, st);
|
||||
else rg.load_surfer_grid(copy_str[0], copy_str[3], d_type, st);
|
||||
return;
|
||||
}
|
||||
|
||||
void save_surfer(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// save surfer <file> <data-name> [surfer6-text|surfer6-binary|surfer7]
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("save: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(3, "null");
|
||||
for (size_t i = 0; i < GCTL_MIN(cmd_units.size() - 2, 3); i++)
|
||||
{
|
||||
copy_str[i] = cmd_units[i + 2];
|
||||
}
|
||||
|
||||
surfer_file_type_e st = Surfer6Text;
|
||||
if (copy_str[2] == "surfer6-text") st = Surfer6Text;
|
||||
else if (copy_str[2] == "surfer6-binary") st = Surfer6Binary;
|
||||
else if (copy_str[2] == "surfer7") st = Surfer7Grid;
|
||||
|
||||
rg.save_surfer_grid(copy_str[0], copy_str[1] ,st);
|
||||
return;
|
||||
}
|
||||
|
||||
void save_text(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// save text <file> <data-name>
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("save: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(cmd_units.size() - 3, "null");
|
||||
for (size_t i = 0; i < cmd_units.size() - 3; i++)
|
||||
{
|
||||
copy_str[i] = cmd_units[i + 3];
|
||||
}
|
||||
|
||||
rg.save_text(cmd_units[2], copy_str);
|
||||
return;
|
||||
}
|
||||
|
||||
void data_cloud(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// data-cloud \<new-data-name\> node|cell \<data-could-file\> \<search-x\> \<search-y\> \<search-deg\>
|
||||
if (cmd_units.size() < 7) throw std::runtime_error("data-cloud: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(7, "null");
|
||||
for (size_t i = 1; i <= GCTL_MIN(cmd_units.size() - 1, 7); i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
mesh_data_type_e d_type = NodeData;
|
||||
if (copy_str[1] == "node") d_type = NodeData;
|
||||
else if (copy_str[1] == "cell") d_type = ElemData;
|
||||
else throw std::runtime_error("open-surfer: invalid grid data type.");
|
||||
|
||||
geodsv_io text_in;
|
||||
text_in.load_text(copy_str[2]);
|
||||
|
||||
array<point2dc> posi_arr;
|
||||
_1d_array data_vec;
|
||||
text_in.get_column_point2dc(posi_arr, 0, 1);
|
||||
text_in.get_column(data_vec, 2);
|
||||
|
||||
rg.load_data_cloud(posi_arr, data_vec, atof(copy_str[3].c_str()), atof(copy_str[4].c_str()), atof(copy_str[5].c_str()), copy_str[0], d_type);
|
||||
return;
|
||||
}
|
||||
|
||||
void gradient(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// gradient <data-name> <new-data-name> dx|dy <order>
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("gradient: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(4, "null");
|
||||
for (size_t i = 1; i <= GCTL_MIN(cmd_units.size() - 1, 4); i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
gradient_type_e g_type;
|
||||
if (copy_str[2] == "dx") g_type = Dx;
|
||||
else if (copy_str[2] == "dy") g_type = Dy;
|
||||
else throw std::runtime_error("gradient: invalid gradient type.");
|
||||
|
||||
int order = 1;
|
||||
if (copy_str[3] != "null") order = atoi(copy_str[3].c_str());
|
||||
|
||||
rg.gradient(copy_str[0], copy_str[1], g_type, order);
|
||||
return;
|
||||
}
|
||||
|
||||
void wavelet(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// wavelet \<data-name\> \<wavelet-name\> \<order\> [\<show-summary\>]
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("wavelet: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(4, "null");
|
||||
for (size_t i = 1; i <= GCTL_MIN(cmd_units.size() - 1, 4); i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
int order = order = atoi(copy_str[2].c_str());
|
||||
|
||||
if (copy_str[3] == "yes") rg.wavelet(copy_str[0], copy_str[1], order, true);
|
||||
else rg.wavelet(copy_str[0], copy_str[1], order, false);
|
||||
return;
|
||||
}
|
||||
|
||||
void sum_data(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// sum-data \<new-data\> \<data1\> \<data2\>
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("sum: insufficient parameters.");
|
||||
|
||||
rg.sum(cmd_units[1], cmd_units[2], cmd_units[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
void diff_data(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// diff \<new-data\> \<data1\> \<data2\>
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("diff: insufficient parameters.");
|
||||
|
||||
rg.diff(cmd_units[1], cmd_units[2], cmd_units[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
void bool_data(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// bool \<new-data-name\> \<data-name1> \<bool-data\> [reverse]
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("bool: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(4, "null");
|
||||
for (size_t i = 1; i <= GCTL_MIN(cmd_units.size() - 1, 4); i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
if (copy_str[3] == "reverse") rg.boolean(copy_str[0], copy_str[1], copy_str[2], true);
|
||||
else rg.boolean(copy_str[0], copy_str[1], copy_str[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
void func_data(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// function \<expression\> \<new-data-name\>
|
||||
if (cmd_units.size() < 3) throw std::runtime_error("function: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(3, "null");
|
||||
for (size_t i = 0; i <= GCTL_MIN(cmd_units.size() - 1, 3); i++)
|
||||
{
|
||||
copy_str[i] = cmd_units[i + 1];
|
||||
}
|
||||
|
||||
rg.function(copy_str[0], copy_str[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
void calculator(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// calculator \<expression\> \<var1,data-name1\> \<var2,data-name2\>...
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("calculator: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(cmd_units.size() - 1, "null");
|
||||
for (size_t i = 1; i <= cmd_units.size() - 1; i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
array<std::string> var_list(copy_str.size() - 1), data_list(copy_str.size() - 1);
|
||||
for (size_t i = 0; i < var_list.size(); i++)
|
||||
{
|
||||
parse_string_to_value(copy_str[i + 1], ',', true, var_list[i], data_list[i]);
|
||||
}
|
||||
|
||||
rg.calculator(copy_str[0], var_list, data_list);
|
||||
return;
|
||||
}
|
||||
|
||||
void data_output(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// data-output enable|disable \<data-name1\> \<data-name2\>...
|
||||
if (cmd_units.size() < 3) throw std::runtime_error("data-output: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(cmd_units.size() - 1, "null");
|
||||
for (size_t i = 1; i <= cmd_units.size() - 1; i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
meshdata *data_ptr;
|
||||
if (copy_str[0] == "enable")
|
||||
{
|
||||
for (size_t i = 1; i < copy_str.size(); i++)
|
||||
{
|
||||
data_ptr = rg.get_data_ptr(copy_str[i]);
|
||||
data_ptr->output_ok_ = true;
|
||||
}
|
||||
}
|
||||
else if (copy_str[0] == "disable")
|
||||
{
|
||||
for (size_t i = 1; i < copy_str.size(); i++)
|
||||
{
|
||||
data_ptr = rg.get_data_ptr(copy_str[i]);
|
||||
data_ptr->output_ok_ = false;
|
||||
}
|
||||
}
|
||||
else throw std::runtime_error("data-output: invalid operation type.");
|
||||
return;
|
||||
}
|
||||
|
||||
void data_rename(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// data-rename [\<old-name\>] [\<new-name\>]
|
||||
if (cmd_units.size() < 3) throw std::runtime_error("rename: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(2, "null");
|
||||
for (size_t i = 1; i <= GCTL_MIN(cmd_units.size() - 1, 2); i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
meshdata &curr_data = rg.get_data(copy_str[0]);
|
||||
curr_data.name_ = copy_str[1];
|
||||
return;
|
||||
}
|
||||
|
||||
void data_view(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// plot [\<data-name\>]...
|
||||
if (cmd_units.size() < 2) throw std::runtime_error("view: insufficient parameters.");
|
||||
|
||||
for (size_t i = 1; i < cmd_units.size(); i++)
|
||||
{
|
||||
rg.view(cmd_units[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void data_plot(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// plot [\<data-name\>]...
|
||||
if (cmd_units.size() < 2) throw std::runtime_error("plot: insufficient parameters.");
|
||||
|
||||
for (size_t i = 1; i < cmd_units.size(); i++)
|
||||
{
|
||||
rg.plot(cmd_units[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void get_stats(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// statistic \<data-name1\> \<data-name2\>...
|
||||
if (cmd_units.size() < 2) throw std::runtime_error("statistic: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(cmd_units.size() - 1, "null");
|
||||
for (size_t i = 1; i <= cmd_units.size() - 1; i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
meshdata *data_ptr;
|
||||
std::vector<double> stats;
|
||||
for (size_t i = 0; i < copy_str.size(); i++)
|
||||
{
|
||||
data_ptr = rg.get_data_ptr(copy_str[i]);
|
||||
data_ptr->show_info();
|
||||
data_ptr->show_stats();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void get_profile(const std::vector<std::string> &cmd_units)
|
||||
{
|
||||
// profile \<data-name\> \<out-file\> {\<x\>,\<y\> \<x\>,\<y\> \<num\>}|{\<xy-file\>}
|
||||
if (cmd_units.size() < 4) throw std::runtime_error("profile: insufficient parameters.");
|
||||
|
||||
gctl::array<std::string> copy_str(5, "null");
|
||||
for (size_t i = 1; i <= GCTL_MIN(cmd_units.size() - 1, 5); i++)
|
||||
{
|
||||
copy_str[i - 1] = cmd_units[i];
|
||||
}
|
||||
|
||||
array<point2dc> xys;
|
||||
array<double> p_data;
|
||||
if (access(copy_str[2].c_str(), R_OK))
|
||||
{
|
||||
point2dc st_p, ed_p;
|
||||
gctl::parse_string_to_value(copy_str[2], ',', true, st_p.x, st_p.y);
|
||||
gctl::parse_string_to_value(copy_str[3], ',', true, ed_p.x, ed_p.y);
|
||||
rg.extract_profile(copy_str[0], st_p, ed_p, atoi(copy_str[4].c_str()), xys, p_data);
|
||||
}
|
||||
else // File exist
|
||||
{
|
||||
geodsv_io fio;
|
||||
fio.load_text(copy_str[2]);
|
||||
fio.get_column_point2dc(xys, 0, 1);
|
||||
|
||||
rg.extract_points(copy_str[0], xys, p_data);
|
||||
}
|
||||
|
||||
std::ofstream ofile;
|
||||
open_outfile(ofile, copy_str[1], ".txt");
|
||||
ofile << "# x y d val\n";
|
||||
for (size_t i = 0; i < xys.size(); i++)
|
||||
{
|
||||
ofile << xys[i].x << " " << xys[i].y << " " << distance(xys[0], xys[i]) << " " << p_data[i] << "\n";
|
||||
}
|
||||
ofile.close();
|
||||
return;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc >= 2)
|
||||
{
|
||||
std::string tmp_l;
|
||||
std::ifstream cmdin;
|
||||
|
||||
// Run commands from files. Each line is a command.
|
||||
// You can give more than one file
|
||||
for (size_t i = 1; i < argc; i++) try
|
||||
{
|
||||
open_infile(cmdin, argv[i]);
|
||||
while (getline(cmdin, tmp_l) && tmp_l != "" && tmp_l[0] != '#')
|
||||
{
|
||||
exec_cmd(tmp_l);
|
||||
}
|
||||
cmdin.close();
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, "run gridmanager in the interactive mode for instructions.", 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setlocale(LC_CTYPE, "");
|
||||
initialize_readline(); /* Bind our completer. */
|
||||
|
||||
display_logo();
|
||||
std::clog << "gridmanager - conversion, compuatation and manipulation of the grid data.\n";
|
||||
std::clog << "Enter '?' to see all available commands.\n";
|
||||
|
||||
std::string cmd_str;
|
||||
char *c_line = (char *)NULL;
|
||||
char *c_line_s = (char *)NULL;
|
||||
bool quit = false;
|
||||
|
||||
while (!quit) try
|
||||
{
|
||||
c_line = readline(">> ");
|
||||
if (!c_line) break;
|
||||
|
||||
c_line_s = stripwhite(c_line);
|
||||
cmd_str = c_line_s;
|
||||
|
||||
if (cmd_str == "quit") quit = true;
|
||||
else if (cmd_str == "?") display_cmds();
|
||||
else exec_cmd(cmd_str);
|
||||
|
||||
free(c_line);
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, "Enter 'help' for instructions.", 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
110
gridmanager/gridmanager.h
Normal file
110
gridmanager/gridmanager.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/********************************************************
|
||||
* ██████╗ ██████╗████████╗██╗
|
||||
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
||||
* ██║ ███╗██║ ██║ ██║
|
||||
* ██║ ██║██║ ██║ ██║
|
||||
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
||||
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
||||
* Geophysical Computational Tools & Library (GCTL)
|
||||
*
|
||||
* Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn)
|
||||
*
|
||||
* GCTL is distributed under a dual licensing scheme. You can redistribute
|
||||
* it and/or modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation, either version 2
|
||||
* of the License, or (at your option) any later version. You should have
|
||||
* received a copy of the GNU Lesser General Public License along with this
|
||||
* program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* If the terms and conditions of the LGPL v.2. would prevent you from using
|
||||
* the GCTL, please consider the option to obtain a commercial license for a
|
||||
* fee. These licenses are offered by the GCTL's original author. As a rule,
|
||||
* licenses are provided "as-is", unlimited in time for a one time fee. Please
|
||||
* send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget
|
||||
* to include some description of your company and the realm of its activities.
|
||||
* Also add information on how to contact you by electronic and paper mail.
|
||||
******************************************************/
|
||||
|
||||
#ifndef GCTL_MESH_GRIDMANAGER_H
|
||||
#define GCTL_MESH_GRIDMANAGER_H
|
||||
|
||||
#include "gctl/io/term_io.h"
|
||||
#include "gctl/io/dsv_io.h"
|
||||
#include "gctl/mesh/regular_grid.h"
|
||||
|
||||
using namespace gctl;
|
||||
|
||||
// Function pointer for commands
|
||||
typedef void (*cmd_func_ptr)(const std::vector<std::string> &cmd_units);
|
||||
|
||||
struct cmd_pair
|
||||
{
|
||||
std::string name;
|
||||
cmd_func_ptr func_p;
|
||||
std::string brief;
|
||||
};
|
||||
|
||||
void quit(const std::vector<std::string> &cmd_units);
|
||||
void mesh_info(const std::vector<std::string> &cmd_units);
|
||||
void new_grid(const std::vector<std::string> &cmd_units);
|
||||
void data_cloud(const std::vector<std::string> &cmd_units);
|
||||
void gradient(const std::vector<std::string> &cmd_units);
|
||||
void wavelet(const std::vector<std::string> &cmd_units);
|
||||
void sum_data(const std::vector<std::string> &cmd_units);
|
||||
void diff_data(const std::vector<std::string> &cmd_units);
|
||||
void bool_data(const std::vector<std::string> &cmd_units);
|
||||
void func_data(const std::vector<std::string> &cmd_units);
|
||||
void calculator(const std::vector<std::string> &cmd_units);
|
||||
void data_output(const std::vector<std::string> &cmd_units);
|
||||
void data_rename(const std::vector<std::string> &cmd_units);
|
||||
void data_view(const std::vector<std::string> &cmd_units);
|
||||
void data_plot(const std::vector<std::string> &cmd_units);
|
||||
void get_stats(const std::vector<std::string> &cmd_units);
|
||||
void get_profile(const std::vector<std::string> &cmd_units);
|
||||
|
||||
void open_grid(const std::vector<std::string> &cmd_units);
|
||||
void save_grid(const std::vector<std::string> &cmd_units);
|
||||
void open_binary(const std::vector<std::string> &cmd_units);
|
||||
void save_binary(const std::vector<std::string> &cmd_units);
|
||||
void open_netcdf(const std::vector<std::string> &cmd_units);
|
||||
void save_netcdf(const std::vector<std::string> &cmd_units);
|
||||
void save_gmsh(const std::vector<std::string> &cmd_units);
|
||||
void open_surfer(const std::vector<std::string> &cmd_units);
|
||||
void save_surfer(const std::vector<std::string> &cmd_units);
|
||||
void save_text(const std::vector<std::string> &cmd_units);
|
||||
|
||||
#define CMD_NUM 20
|
||||
const cmd_pair commands[CMD_NUM] = {
|
||||
{"info", mesh_info, "Show mesh's information."},
|
||||
{"init", new_grid, "Initialize a new grid framework."},
|
||||
{"open", open_grid, "Open a grid file."},
|
||||
{"save", save_grid, "Save grid data to a file."},
|
||||
{"cloud", data_cloud, "Import grid data from data cloud."},
|
||||
{"gradient", gradient, "Calculate directional gradients."},
|
||||
{"wavelet", wavelet, "Decompose grid data using the wavelet algorithm."},
|
||||
{"sum", sum_data, "Calculate the sum of two grid data."},
|
||||
{"diff", diff_data, "Calculate the difference of two grid data."},
|
||||
{"bool", bool_data, "Preform the boolean operation of grid data."},
|
||||
{"function", func_data, "Generate grid data from a mathematic expression."},
|
||||
{"calculator", calculator, "Preform the mathematic operation of grid data."},
|
||||
{"output", data_output, "Set output properites of grid data."},
|
||||
{"rename", data_rename, "Rename a grid data."},
|
||||
{"view", data_view, "Display a grid data using the exprtk library."},
|
||||
{"plot", data_plot, "Plot a grid data using the GMT library."},
|
||||
{"statistic", get_stats, "Show statistics of grid data."},
|
||||
{"profile", get_profile, "Extract profile data of a grid data."},
|
||||
{"quit", quit, "Quit the program."},
|
||||
{"null", nullptr, "null"}
|
||||
};
|
||||
|
||||
#define KEY_NUM 6
|
||||
const cmd_pair keywords[KEY_NUM] = {
|
||||
{"netcdf", nullptr, "netCDF format."},
|
||||
{"surfer", nullptr, "Surfer format."},
|
||||
{"binary", nullptr, "GCTL native format."},
|
||||
{"gmsh", nullptr, "Gmsh format."},
|
||||
{"node", nullptr, "Node registered data."},
|
||||
{"cell", nullptr, "Cell registered data."}
|
||||
};
|
||||
|
||||
#endif // GCTL_MESH_GRIDMANAGER_H
|
60
gridmanager/readme_gridmanager.md
Normal file
60
gridmanager/readme_gridmanager.md
Normal file
@@ -0,0 +1,60 @@
|
||||
#### quit
|
||||
Does what it says.
|
||||
|
||||
#### info [\<new-grid-name\>] [\<new-info\>]
|
||||
Show and/or edit information of the grid. This option could be used to assign new name and information to the grid. If the input name or information contain spaces, enclose them with quotes.
|
||||
|
||||
#### init \<new-file\> \<xnum\> \<ynum\> \<xmin\> \<ymin\> \<dx\> \<dy\> [\<info\>]
|
||||
(Re)create a new grid. 'xnum' and 'ynum' are point numbers on the x and y directions.
|
||||
'xmin' and 'ymin' are the minimal values of the grid's coordinates. 'dx' and
|
||||
'dy' are the grid spacings. Extra 'info' about the new grid could be added here.
|
||||
Mathematic expresstions could be used to specify the grid ranges.
|
||||
|
||||
#### open binary|netcdf|surfer \<file\>
|
||||
1. `open binary <file>` Open a grid stored in the GCTL native binary format (.2m file).
|
||||
2. `open netcdf <file> [<x-name> <y-name>] [<data-name>] [node|cell]` Open a grid stored in the netCDF format. 'node' (default) or 'cell' indicates whether the input grid data should be node or cell registed. names of the input grid's x-axial and y-axial should be given id they are not 'x' and 'y'. A \<data-name\> could be given to read the specficed data. Otherwise all grid data will be readed.
|
||||
3. `open surfer <file> [<new-data-name>] [surfer6-text|surfer6-binary|surfer7] [node|cell]` Open a grid stored in the Surfer formats. 'node' (default) or 'cell' indicates whether the input grid data should be node or cell registed. 'surfer6-text' (default), 'surfer6-binary' and 'surfer7' are the expected grid format. Since no data name is stored in the Surfer grid, a new data name could be given.
|
||||
|
||||
#### save binary|netcdf|surfer|gmsh \<file\>
|
||||
1. `save binary <file>` Save the grid using the GCTL native binary format (.2m file).
|
||||
2. `save netcdf <file> [<data-name>|node|cell] [xname] [yname]` Save grid data using the netCDF format. A \<data-name\> could be given to write the specficed data. Use 'node' (default) or 'cell' to write all node or cell registed data, respectively.
|
||||
3. `save surfer <file> <data-name> [surfer6-text|surfer6-binary|surfer7]` Save grid data using the Surfer format. A \<data-name\> must be given to write the specficed data. 'surfer6-text', 'surfer6-binary' and 'surfer7' are the outputing grid format.
|
||||
4. `save gmsh <file>` Save the grid using the Gmsh legacy format. This command will write all data that are allowed for outputing.
|
||||
5. `save text <file>` Save the grid data to text file.
|
||||
|
||||
#### cloud \<new-data-name\> node|cell \<data-could-file\> \<search-x\> \<search-y\> \<search-deg\>
|
||||
Import a randomly distributed data could (namely a xyz data). Note that a grid must exist before the use this command. 'node' or 'cell' indicates whether the input could data should be node or cell registed. \<data-could-file\> is the input data file. \<search-x\>,\<search-y\> and \<search-deg\> defines an oval of which the command is used to interpolate the could data to grid points.
|
||||
|
||||
#### gradient \<data-name\> \<new-data-name\> dx|dy \<order\>
|
||||
Calculate directional gradient(s) of the selected data. The new gradient data will have the same
|
||||
data type of the used data. 'dx' and 'dy' give the calculation directions. higher orders of the gradient could be specified by given them at the end of the command.
|
||||
|
||||
#### wavelet \<data-name\> \<wavelet-name\> \<order\> [\<show-summary\>]
|
||||
Using a wavelet \<wavelet-name\> to decompose the selecte data. Avaiable wavelets include 'bd2'... .The order of decomposition could be set using \<order\>. And set \<show-summary\> to yes to see the summary.
|
||||
|
||||
#### sum \<new-data\> \<data1\> \<data2\>
|
||||
Calculate the sum of the two data. The arguments' format should be clear enough.
|
||||
|
||||
#### diff \<new-data\> \<data1\> \<data2\>
|
||||
Calculate the difference of the two data. The arguments' format should be clear enough.
|
||||
|
||||
#### bool \<new-data-name\> \<data-name1> \<bool-data\> [reverse]
|
||||
Preform the bool operation on the slected data set. Put 'reverse' to for a reversed calculation.
|
||||
|
||||
#### calculator \<expression\> \<var1,data-name1\> \<var2,data-name2\>...
|
||||
Preform mathematic calculation using stored data. \<expression\> is a string that describles the expected calculation. For example, 'c := a + b' represents a summation between two data 'a' and 'b'. And the sum is stored in data 'c'. Note that 'a', 'b' and 'c' are algebraic symbols. So they must be tided to actual data using \<var,data-name\>, in which \<var\> is the algebraic symbol, \<data-name>\ is the data name. Remeber to put the output data name at the first place and if the input expression contain spaces, enclose them with quotes.
|
||||
|
||||
#### function \<expression\> \<new-data-name\>
|
||||
Create a new grid data named \<new-data-name\> from a mathematic expression. Default algebraic symbols 'f', 'x' and 'y' are defined for the resultent data, x-coordinate and y-coordinate, respectively. For example, 'f := x + y' represents a summation of the grid coordinates.
|
||||
|
||||
#### output enable|disable \<data-name1\> \<data-name2\>...
|
||||
Enable or disable output of the given data.
|
||||
|
||||
#### rename [\<old-name\>] [\<new-name\>]
|
||||
Change data name.
|
||||
|
||||
#### statistic \<data-name1\> \<data-name2\>...
|
||||
Show statistics of the selected data.
|
||||
|
||||
#### profile \<data-name\> \<out-file\> {\<x\>,\<y\> \<x\>,\<y\> \<num\>}|\<xy-file\>
|
||||
Extract a profile from the selected data and output to a text file.
|
Reference in New Issue
Block a user