star-line

Structure for accelerating line importance sampling
git clone git://git.meso-star.fr/star-line.git
Log | Files | Refs | README | LICENSE

commit 73e50f5a351a6bb185473e1a26c62ea823db5bdd
parent db121368383fa3e47ec60eaf126218f15c006c83
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  4 Mar 2026 17:05:05 +0100

Start implementation of sln-get utility

It queries the data of a tree and prints it on the standard output.
Currently, the default behavior is to print general information about
the tree, such as the number of nodes. Enable -m option displays instead
the tree root mesh

Diffstat:
MMakefile | 7+++++--
Asrc/sln_get.c | 257+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 262 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile @@ -82,7 +82,7 @@ libsln.o: $(OBJ) ################################################################################ # Utils ################################################################################ -UTIL_SRC = src/sln_build.c +UTIL_SRC = src/sln_build.c src/sln_get.c UTIL_OBJ = $(UTIL_SRC:.c=.o) UTIL_DEP = $(UTIL_SRC:.c=.d) @@ -97,11 +97,14 @@ LDFLAGS_UTIL = $(LDFLAGS_EXE) $(LIBS_UTIL) utils: library $(UTIL_DEP) @$(MAKE) -fMakefile \ $$(for i in $(UTIL_DEP); do printf -- '-f%s\n' "$${i}"; done) \ - sln-build + sln-build sln-get sln-build: config.mk sln-local.pc src/sln_build.o $(LIBNAME) $(CC) $(CFLAGS_UTIL) -o $@ src/sln_build.o $(LDFLAGS_UTIL) +sln-get: config.mk sln-local.pc src/sln_get.o $(LIBNAME) + $(CC) $(CFLAGS_UTIL) -o $@ src/sln_get.o $(LDFLAGS_UTIL) + $(UTIL_DEP): config.mk sln-local.pc @$(CC) $(CFLAGS_UTIL) -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ diff --git a/src/sln_get.c b/src/sln_get.c @@ -0,0 +1,257 @@ +/* Copyright (C) 2022, 2026 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2026 Université de Lorraine + * Copyright (C) 2022 Centre National de la Recherche Scientifique + * Copyright (C) 2022 Université Paul Sabatier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#define _POSIX_C_SOURCE 200112L /* getopt */ + +#include "sln.h" + +#include <rsys/mem_allocator.h> + +#include <unistd.h> + +/* Draft of the command sln-get # Default print information + [-lr] # go to left/right + [-L<n>] [-R<n>] # go to n times left/right + [-m] # output mesh + [-v] # verbosity + [-h] # short help + [tree] */ + +enum output_type { + OUTPUT_DESCRIPTOR, + OUTPUT_MESH, + OUTPUT_COUNT__ +}; + +struct args { + const char* tree; /* NULL <=> read from standard input */ + + enum output_type output_type; + + /* Miscellaneous */ + int quit; + int verbose; +}; +#define ARGS_DEFAULT__ {NULL, OUTPUT_DESCRIPTOR, 0, 0} +static const struct args ARGS_DEFAULT = ARGS_DEFAULT__; + +struct cmd { + struct args args; + + struct sln_device* sln; + struct sln_tree* tree; + + struct shtr* shtr; +}; +#define CMD_NULL__ {0} +static const struct cmd CMD_NULL = CMD_NULL__; + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static void +usage(FILE* stream) +{ + fprintf(stream, "usage: sln-get [-hmv] [tree]\n"); +} + +static res_T +args_init(struct args* args, int argc, char** argv) +{ + int opt = 0; + res_T res = RES_OK; + + ASSERT(args); + + *args = ARGS_DEFAULT; + + while((opt = getopt(argc, argv, "hmv")) != -1) { + switch(opt) { + case 'h': + usage(stdout); + args->quit = 1; + goto exit; + case 'm': args->output_type = OUTPUT_MESH; break; + case 'v': args->verbose += (args->verbose < 3); break; + default: res = RES_BAD_ARG; break; + } + if(res != RES_OK) { + if(optarg) { + fprintf(stderr, "%s: invalid option argument '%s' -- '%c'\n", + argv[0], optarg, opt); + } + goto error; + } + } + + if(optind < argc) args->tree = argv[optind]; + +exit: + return res; +error: + usage(stderr); + goto exit; +} + +static void +cmd_release(struct cmd* cmd) +{ + ASSERT(cmd); + if(cmd->sln) SLN(device_ref_put(cmd->sln)); + if(cmd->tree) SLN(tree_ref_put(cmd->tree)); + if(cmd->shtr) SHTR(ref_put(cmd->shtr)); +} + +static res_T +cmd_init(struct cmd* cmd, const struct args* args) +{ + struct sln_device_create_args sln_args = SLN_DEVICE_CREATE_ARGS_DEFAULT; + struct sln_tree_read_args tree_args = SLN_TREE_READ_ARGS_NULL; + struct shtr_create_args shtr_args = SHTR_CREATE_ARGS_DEFAULT; + res_T res = RES_OK; + + ASSERT(cmd && args); + + *cmd = CMD_NULL; + + shtr_args.verbose = args->verbose; + res = shtr_create(&shtr_args, &cmd->shtr); + if(res != RES_OK) goto error; + + sln_args.verbose = args->verbose; + res = sln_device_create(&sln_args, &cmd->sln); + if(res != RES_OK) goto error; + + tree_args.shtr = cmd->shtr; + if(args->tree) { + tree_args.file = NULL; + tree_args.filename = args->tree; + } else { + tree_args.file = stdin; + tree_args.filename = "stdin"; + } + res = sln_tree_read(cmd->sln, &tree_args, &cmd->tree); + if(res != RES_OK) goto error; + + cmd->args = *args; + +exit: + return res; +error: + cmd_release(cmd); + *cmd = CMD_NULL; + goto exit; +} + +static res_T +print_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("#nodes: %lu\n", (unsigned long)desc.nnodes); + 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 +print_mesh(const struct cmd* cmd) +{ + struct sln_mesh mesh = SLN_MESH_NULL; + const struct sln_node* node = NULL; + size_t i = 0; + res_T res = RES_OK; + ASSERT(cmd); + + node = sln_tree_get_root(cmd->tree); + if(node == NULL) goto exit; /* Tree is empty */ + + res = sln_node_get_mesh(cmd->tree, node, &mesh); + if(res != RES_OK) goto error; + + FOR_EACH(i, 0, mesh.nvertices) { + printf("%g %g\n", + mesh.vertices[i].wavenumber, + mesh.vertices[i].ka); + } + +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_DESCRIPTOR: + res = print_descriptor(cmd); + break; + case OUTPUT_MESH: + res = print_mesh(cmd); + break; + default: FATAL("Unreachable code\n"); break; + } + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; +} + +/******************************************************************************* + * The program + ******************************************************************************/ +int +main(int argc, char** argv) +{ + struct args args = ARGS_DEFAULT; + struct cmd cmd = CMD_NULL; + int err = 0; + res_T res = RES_OK; + + if((res = args_init(&args, argc, argv)) != RES_OK) goto error; + if(args.quit) goto exit; + + if((res = cmd_init(&cmd, &args)) != RES_OK) goto error; + if((res = cmd_run(&cmd)) != RES_OK) goto error; + +exit: + cmd_release(&cmd); + CHK(mem_allocated_size() == 0); + return err; +error: + err = 1; + goto exit; +}