Skip to content

Commit

Permalink
Merge branch 'container_gui' of https://github.com/grouperenault/fmutool
Browse files Browse the repository at this point in the history
 into container_gui

# Conflicts:
#	CHANGELOG.md
#	fmu_manipulation_toolbox/assembly.py
#	fmu_manipulation_toolbox/gui.py
  • Loading branch information
Nicolas Laurent committed Jan 18, 2025
2 parents f3a693c + bf21c55 commit bae373b
Show file tree
Hide file tree
Showing 21 changed files with 694 additions and 107 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ This package was formerly known as `fmutool`.

## Version 1.8.2 (upcoming)
* FIXED: `fmucontainer` identifier (for coSimulation) does not contain ".fmu" anymore
* TODO: ADDED: take care of stoptime
* TODO: Expose parameters
* ADDED: GUI for `fmucontainer`
* ADDED: `fmucontainer` log more information when embedded FMU cannot be loaded
* ADDED: `fmucontainer` startTime and stopTime are deduced from 1st embedded FMU
* ADDED: `fmucontainer` support new option `-auto-parameter` (parameters are not exposed by default)
* [ ] ADDED: preliminary version of GUI for `fmucontainer`


## Version 1.8.1
* FIXED: `fmucontainer` read links from `.json` input files
* CHANGED: switch to PyQT6 and add minor GUI improvements

## Version 1.8
* CHANGE: Package in now known as `fmu_manipulation`
* CHANGE: Python Package in now known as `fmu-manipulation-toolbox`
* ADDED: `fmucontainer` support `canHandleVariableCommunicationStepSize`
* ADDED: `fmucontainer` support `.spp` or `.json` as input files
* ADDED: `fmucontainer` new `-dump` option to save container description
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ optional arguments:

```
usage: fmucontainer [-h] [-fmu-directory FMU_DIRECTORY] -container filename.{csv|json|ssp},[:step_size] [-debug]
[-no-auto-input] [-no-auto-output] [-no-auto-link] [-mt] [-profile] [-dump-json]
[-no-auto-input] [-no-auto-output] [-auto-parameter] [-no-auto-link] [-mt] [-profile] [-dump-json]
Generate FMU from FMU's
Expand All @@ -136,6 +136,7 @@ optional arguments:
-debug Add lot of useful log during the process. (default: False)
-no-auto-input Create ONLY explicit input. (default: True)
-no-auto-output Create ONLY explicit output. (default: True)
-auto-parameter Expose parameters of the embedded fmu's. (default: False)
-no-auto-link Create ONLY explicit links. (default: True)
-mt Enable Multi-Threaded mode for the generated container. (default: False)
-profile Enable Profiling mode for the generated container. (default: False)
Expand Down
6 changes: 5 additions & 1 deletion container/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ message("FMI_PLATFORM: ${FMI_PLATFORM}")
add_library(container SHARED
container.c container.h
fmu.c fmu.h
hash.c hash.h
library.c library.h
logger.c logger.h
profile.c profile.h
Expand All @@ -45,9 +46,12 @@ target_include_directories(container PRIVATE
if (UNIX AND NOT APPLE)
target_link_libraries(container Threads::Threads)
endif()
if (WIN32)
target_link_libraries(container Imagehlp.lib)
endif()
set_target_properties(container PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../fmu_manipulation_toolbox/resources/${FMI_PLATFORM}"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../fmu_manipulation_toolbox/resources/${FMI_PLATFORM}")

#target_compile_options(container PRIVATE /W4 /WX)
#target_compile_options(container PRIVATE /W4 /WX)

64 changes: 32 additions & 32 deletions container/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@

/* unimplemented fmi2 functions */
#define __NOT_IMPLEMENTED__ \
container_t* container = (container_t*)c; \
logger(container, fmi2Error, "Function '%s' is not implemented", __func__); \
logger(fmi2Error, "Function '%s' is not implemented", __func__); \
return fmi2Error;


Expand Down Expand Up @@ -58,9 +57,9 @@ static int read_mt_flag(container_t* container, config_file_t* file) {
return -2;

if (container->mt)
logger(container, fmi2Warning, "Container use MULTI thread");
logger(fmi2Warning, "Container use MULTI thread");
else
logger(container, fmi2Warning, "Container use MONO thread");
logger(fmi2Warning, "Container use MONO thread");

return 0;
}
Expand All @@ -73,7 +72,7 @@ static int read_profiling_flag(container_t* container, config_file_t* file) {
return -2;

if (container->profiling)
logger(container, fmi2Warning, "Container use PROFILING");
logger(fmi2Warning, "Container use PROFILING");

return 0;
}
Expand All @@ -84,7 +83,7 @@ static int read_conf_time_step(container_t* container, config_file_t* file) {
return -1;
if (sscanf(file->line, "%le", &container->time_step) < 1)
return -2;
logger(container, fmi2OK, "Container time_step = %e", container->time_step);
logger(fmi2OK, "Container time_step = %e", container->time_step);
return 0;
}

Expand All @@ -97,7 +96,7 @@ static int read_conf_fmu(container_t *container, const char *dirname, config_fil
if (sscanf(file->line, "%d", &nb_fmu) < 1)
return -2;

logger(container, fmi2OK, "%d FMU's to be loaded", nb_fmu);
logger(fmi2OK, "%d FMU's to be loaded", nb_fmu);
if (!nb_fmu) {
container->fmu = NULL;
return 0;
Expand Down Expand Up @@ -130,10 +129,10 @@ static int read_conf_fmu(container_t *container, const char *dirname, config_fil
return -1;
const char *guid = file->line;

logger(container, fmi2OK, "Loading '%s.dll' from directory '%s'", identifier, directory);
logger(fmi2OK, "Loading '%s.dll' from directory '%s'", identifier, directory);

if (fmu_load_from_directory(container, i, directory, identifier, guid)) {
logger(container, fmi2Error, "Cannot load from directory '%s'", directory);
logger(fmi2Error, "Cannot load from directory '%s'", directory);
free(identifier);
return -4;
}
Expand Down Expand Up @@ -413,70 +412,70 @@ static int read_conf(container_t* container, const char* dirname) {
filename[sizeof(filename) - 1] = '\0';
strncat(filename, "/container.txt", sizeof(filename) - strlen(filename) - 1);

logger(container, fmi2OK, "Reading '%s'...", filename);
logger(fmi2OK, "Reading '%s'...", filename);
file.fp = fopen(filename, "rt");
if (!file.fp) {
logger(container, fmi2Error, "Cannot open '%s': %s.", filename, strerror(errno));
logger(fmi2Error, "Cannot open '%s': %s.", filename, strerror(errno));
return -1;
}
if (read_mt_flag(container, &file)) {
fclose(file.fp);
logger(container, fmi2Error, "Cannot configure MT flag.");
logger(fmi2Error, "Cannot configure MT flag.");
return -2;
}

if (read_profiling_flag(container, &file)) {
fclose(file.fp);
logger(container, fmi2Error, "Cannot configure PROFILING flag.");
logger(fmi2Error, "Cannot configure PROFILING flag.");
return -2;
}

if (read_conf_time_step(container, &file)) {
fclose(file.fp);
logger(container, fmi2Error, "Cannot set time step.");
logger(fmi2Error, "Cannot set time step.");
return -2;
}

if (read_conf_fmu(container, dirname, &file)) {
fclose(file.fp);
logger(container, fmi2Error, "Cannot load embedded FMU's.");
logger(fmi2Error, "Cannot load embedded FMU's.");
return -3;
}

if (read_conf_io(container, &file)) {
fclose(file.fp);
logger(container, fmi2Error, "Cannot allocate local variables.");
logger(fmi2Error, "Cannot allocate local variables.");
return -4;
}

if (read_conf_vr(container, &file)) {
fclose(file.fp);
logger(container, fmi2Error, "Cannot read translation table.");
logger(fmi2Error, "Cannot read translation table.");
return -5;
}

logger(container, fmi2OK, "Real : %d local variables and %d ports", container->nb_local_reals, container->nb_ports_reals);
logger(container, fmi2OK, "Integer : %d local variables and %d ports", container->nb_local_integers, container->nb_ports_integers);
logger(container, fmi2OK, "Boolean : %d local variables and %d ports", container->nb_local_booleans, container->nb_ports_booleans);
logger(container, fmi2OK, "String : %d local variables and %d ports", container->nb_local_strings, container->nb_ports_strings);
logger(fmi2OK, "Real : %d local variables and %d ports", container->nb_local_reals, container->nb_ports_reals);
logger(fmi2OK, "Integer : %d local variables and %d ports", container->nb_local_integers, container->nb_ports_integers);
logger(fmi2OK, "Boolean : %d local variables and %d ports", container->nb_local_booleans, container->nb_ports_booleans);
logger(fmi2OK, "String : %d local variables and %d ports", container->nb_local_strings, container->nb_ports_strings);

for (int i = 0; i < container->nb_fmu; i += 1) {
if (read_conf_fmu_io(&container->fmu[i].fmu_io, &file)) {
fclose(file.fp);
return -6;
}

logger(container, fmi2OK, "FMU#%d: IN %d reals, %d integers, %d booleans, %d strings", i,
logger(fmi2OK, "FMU#%d: IN %d reals, %d integers, %d booleans, %d strings", i,
container->fmu[i].fmu_io.reals.in.nb,
container->fmu[i].fmu_io.integers.in.nb,
container->fmu[i].fmu_io.booleans.in.nb,
container->fmu[i].fmu_io.strings.in.nb);
logger(container, fmi2OK, "FMU#%d: START %d reals, %d integers, %d booleans, %d strings", i,
logger(fmi2OK, "FMU#%d: START %d reals, %d integers, %d booleans, %d strings", i,
container->fmu[i].fmu_io.start_reals.nb,
container->fmu[i].fmu_io.start_integers.nb,
container->fmu[i].fmu_io.start_strings.nb,
container->fmu[i].fmu_io.start_strings.nb);
logger(container, fmi2OK, "FMU#%d: OUT %d reals, %d integers, %d booleans, %d strings", i,
logger(fmi2OK, "FMU#%d: OUT %d reals, %d integers, %d booleans, %d strings", i,
container->fmu[i].fmu_io.reals.out.nb,
container->fmu[i].fmu_io.integers.out.nb,
container->fmu[i].fmu_io.booleans.out.nb,
Expand Down Expand Up @@ -533,6 +532,7 @@ fmi2Component fmi2Instantiate(fmi2String instanceName,
container->debug = loggingOn;
container->logger = functions->logger;

logger_init(container); /* logger() is available starting this point ! */
container->mt = 0;
container->nb_fmu = 0;
container->fmu = NULL;
Expand All @@ -559,13 +559,13 @@ fmi2Component fmi2Instantiate(fmi2String instanceName,
container->time = 0.0;
container->tolerance = 1.0e-8;

logger(container, fmi2OK, "Container model loading...");
logger(fmi2OK, "Container model loading...");
if (read_conf(container, fmuResourceLocation + strlen("file:///"))) {
logger(container, fmi2Error, "Cannot read container configuration.");
logger(fmi2Error, "Cannot read container configuration.");
fmi2FreeInstance(container);
return NULL;
}
logger(container, fmi2OK, "Container configuration read.");
logger(fmi2OK, "Container configuration read.");

for(int i=0; i < container->nb_fmu; i += 1) {
fmi2Status status = fmuInstantiate(&container->fmu[i],
Expand All @@ -574,7 +574,7 @@ fmi2Component fmi2Instantiate(fmi2String instanceName,
visible,
container->debug);
if (status != fmi2OK) {
logger(container, fmi2Error, "Cannot Instiantiate FMU#%d", i);
logger(fmi2Error, "Cannot Instiantiate FMU#%d", i);
fmi2FreeInstance(container);
return NULL;
}
Expand Down Expand Up @@ -659,7 +659,7 @@ fmi2Status fmi2SetupExperiment(fmi2Component c,
}

container->time = startTime;
logger(container, fmi2OK, "fmi2SetupExperiment -- OK");
logger(fmi2OK, "fmi2SetupExperiment -- OK");
return fmi2OK;
}

Expand Down Expand Up @@ -940,7 +940,7 @@ static fmi2Status do_internal_step_parallel_mt(container_t* container, fmi2Real
for (int i = 0; i < container->nb_fmu; i += 1) {
status = do_step_get_outputs(container, i);
if (status != fmi2OK) {
logger(container, fmi2Error, "Container: FMU#%d failed doStep.", i);
logger(fmi2Error, "Container: FMU#%d failed doStep.", i);
return status;
}

Expand Down Expand Up @@ -970,7 +970,7 @@ static fmi2Status do_internal_step_parallel(container_t* container, fmi2Real cur
/* COMPUTATION */
status = fmuDoStep(fmu, currentCommunicationPoint, step_size, noSetFMUStatePriorToCurrentPoint);
if (status != fmi2OK) {
logger(container, fmi2Error, "Container: FMU#%d failed doStep.", i);
logger(fmi2Error, "Container: FMU#%d failed doStep.", i);
return status;
}
}
Expand Down Expand Up @@ -1014,7 +1014,7 @@ fmi2Status fmi2DoStep(fmi2Component c,
container->time = current_time;

if (fabs(currentCommunicationPoint + communicationStepSize - current_time) > container->tolerance) {
logger(container, fmi2Warning, "CommunicationStepSize should be divisible by %e", container->time_step);
logger(fmi2Warning, "CommunicationStepSize should be divisible by %e", container->time_step);
return fmi2Warning;
}

Expand Down
Loading

0 comments on commit bae373b

Please sign in to comment.