commit 5d714a38f356bc2b91e95a524fefdd42ee1d25ab
parent a4ae874974154ec141a123a6196cfc019b672fbd
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 10 Mar 2026 17:41:04 +0100
Add to sln-get the ability to print info about a level
Its new -d option can now be set to determine a level to query in
order to retrieve the number of nodes and vertices at this level.
This gives an indication of how much each level weighs in terms of data
quantity.
Diffstat:
2 files changed, 101 insertions(+), 21 deletions(-)
diff --git a/doc/sln-get.1 b/doc/sln-get.1
@@ -26,6 +26,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl hlmnrsv
+.Op Fl d Ar level
.Op Fl L Ar nlevels
.Op Fl R Ar nlevels
.Op Fl w Ar wavenumber
@@ -63,6 +64,13 @@ traversal options
The options are as follows:
.Bl -tag -width Ds
.\""""""""""""""""""""""""""""""""""
+.It Fl d Ar level
+Displays the description of the level in the tree structure,
+i.e., the number of nodes and the total number of vertices of their
+polylines.
+If the level provided is greater than the maximum depth of the tree,
+then its deepest level is queried.
+.\""""""""""""""""""""""""""""""""""
.It Fl h
Display short help and exit.
.\""""""""""""""""""""""""""""""""""
@@ -101,7 +109,7 @@ its wavenumber in cm^-1, and its associated spectrum value.
.\""""""""""""""""""""""""""""""""""
.It Fl n
Displays the description of the current node, i.e., its level relative to
-the root, the number of lines it partitions, and the number of mesh
+the root, the number of lines it partitions, and the number of polyline
vertices used to represent them at the node's hierarchical level.
.\""""""""""""""""""""""""""""""""""
.It Fl p Ar molparams
diff --git a/src/sln_get.c b/src/sln_get.c
@@ -39,10 +39,11 @@
enum child { LEFT, RIGHT };
enum output_type {
- OUTPUT_TREE_DESCRIPTOR,
+ OUTPUT_LEVEL_DESCRIPTOR,
OUTPUT_NODE_DESCRIPTOR,
OUTPUT_NODE_MESH,
OUTPUT_NODE_VALUE,
+ OUTPUT_TREE_DESCRIPTOR,
OUTPUT_COUNT__
};
@@ -68,11 +69,12 @@ struct args {
unsigned depth; /* Current depth in the tree */
/* Miscellaneous */
+ unsigned level; /* Queried level */
int quit;
int verbose;
int lines_in_shtr_format;
};
-#define ARGS_DEFAULT__ {NULL,NULL,NULL,OUTPUT_TREE_DESCRIPTOR,0,0,0,0,0,0,0}
+#define ARGS_DEFAULT__ {NULL,NULL,NULL,OUTPUT_TREE_DESCRIPTOR,0,0,0,0,0,0,0,0}
static const struct args ARGS_DEFAULT = ARGS_DEFAULT__;
struct cmd {
@@ -95,8 +97,8 @@ static void
usage(FILE* stream)
{
fprintf(stream,
-"usage: sln-get [-hlmnrsv] [-L nlevels] [-R nlevels] [-w wavenumber] -i lines\n"
-" -p molparams [tree]\n");
+"usage: sln-get [-hlmnrsv] [-d level] [-L nlevels] [-R nlevels] [-w wavenumber]\n"
+" -i lines -p molparams [tree]\n");
}
static void
@@ -143,8 +145,12 @@ args_init(struct args* args, int argc, char** argv)
*args = ARGS_DEFAULT;
- while((opt = getopt(argc, argv, "hi:L:lmnp:R:rsvw:")) != -1) {
+ while((opt = getopt(argc, argv, "d:hi:L:lmnp:R:rsvw:")) != -1) {
switch(opt) {
+ case 'd':
+ args->output_type = OUTPUT_LEVEL_DESCRIPTOR;
+ res = cstr_to_uint(optarg, &args->level);
+ break;
case 'h':
usage(stdout);
args->quit = 1;
@@ -300,23 +306,61 @@ error:
}
static res_T
-print_tree_descriptor(const struct cmd* cmd)
+print_level_descriptor(const struct cmd* cmd)
{
- struct sln_tree_desc desc = SLN_TREE_DESC_NULL;
+ /* Stack for visiting the tree depth-first */
+ struct { const struct sln_node* node; unsigned level; } stack[MAX_DEPTH];
+ int istack = 0;
+
+ /* Node data */
+ struct sln_node_desc desc = SLN_NODE_DESC_NULL;
+ const struct sln_node* node = NULL;
+
+ /* Level descriptor */
+ size_t nvertices = 0;
+ size_t nnodes = 0;
+
+ /* Miscellaneous */
+ unsigned level = 0;
res_T res = RES_OK;
- ASSERT(cmd);
- res = sln_tree_get_desc(cmd->tree, &desc);
- if(res != RES_OK) goto error;
+ ASSERT(cmd); /* Precondition */
- printf("#lines: %lu\n", (unsigned long)desc.nlines);
- printf("#nodes: %lu\n", (unsigned long)desc.nnodes);
- printf("tree depth: %u\n", desc.depth);
- printf("#vertices: %lu\n", (unsigned long)desc.nvertices);
- printf("type: %s\n", sln_mesh_type_cstr(desc.mesh_type));
- printf("decimation error: %.4e\n", desc.mesh_decimation_err);
- printf("line profile: %s\n", sln_line_profile_cstr(desc.line_profile));
- printf("#lines per leaf: %lu\n", (unsigned long)desc.max_nlines_per_leaf);
+ /* Push a dummy node which, once pop up, whill mark the end of recursion */
+ stack[istack].node = NULL;
+ stack[istack].level = UINT_MAX;
+ ++istack;
+
+ node = sln_tree_get_root(cmd->tree);
+
+ while(node) {
+ ASSERT(level <= cmd->args.level);
+
+ if(!sln_node_is_leaf(node) && level < cmd->args.level) {
+ /* Continue down the tree */
+ ++level;
+
+ /* Push the right child */
+ stack[istack ].node = sln_node_get_child(node, 1);
+ stack[istack++].level = level;
+
+ node = sln_node_get_child(node, 0); /* Visit the left child */
+
+ } else {
+ /* The queried level or a leaf is reached, update the descriptor */
+ if((res = sln_node_get_desc(node, &desc)) != RES_OK) goto error;
+ nvertices += desc.nvertices;
+ ++nnodes;
+
+ /* Pop the next node */;
+ node = stack[--istack].node;
+ level = stack[ istack].level;
+ }
+ }
+
+ /* Print the level description */
+ printf("#nodes: %lu\n", (unsigned long)nnodes);
+ printf("#vertices: %lu\n", (unsigned long)nvertices);
exit:
return res;
@@ -432,13 +476,38 @@ error:
}
static res_T
+print_tree_descriptor(const struct cmd* cmd)
+{
+ struct sln_tree_desc desc = SLN_TREE_DESC_NULL;
+ res_T res = RES_OK;
+ ASSERT(cmd);
+
+ res = sln_tree_get_desc(cmd->tree, &desc);
+ if(res != RES_OK) goto error;
+
+ printf("#lines: %lu\n", (unsigned long)desc.nlines);
+ printf("#nodes: %lu\n", (unsigned long)desc.nnodes);
+ printf("tree depth: %u\n", desc.depth);
+ printf("#vertices: %lu\n", (unsigned long)desc.nvertices);
+ printf("type: %s\n", sln_mesh_type_cstr(desc.mesh_type));
+ printf("decimation error: %.4e\n", desc.mesh_decimation_err);
+ printf("line profile: %s\n", sln_line_profile_cstr(desc.line_profile));
+ printf("#lines per leaf: %lu\n", (unsigned long)desc.max_nlines_per_leaf);
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
cmd_run(const struct cmd* cmd)
{
res_T res = RES_OK;
switch(cmd->args.output_type) {
- case OUTPUT_TREE_DESCRIPTOR:
- res = print_tree_descriptor(cmd);
+ case OUTPUT_LEVEL_DESCRIPTOR:
+ res = print_level_descriptor(cmd);
break;
case OUTPUT_NODE_DESCRIPTOR:
res = print_node_descriptor(cmd);
@@ -449,6 +518,9 @@ cmd_run(const struct cmd* cmd)
case OUTPUT_NODE_VALUE:
res = print_node_value(cmd);
break;
+ case OUTPUT_TREE_DESCRIPTOR:
+ res = print_tree_descriptor(cmd);
+ break;
default: FATAL("Unreachable code\n"); break;
}
if(res != RES_OK) goto error;