fileSink
Represente un recepteur de sortie fichier.
📝Syntaxe
Block type: fileSink
📥Arguments d'entrée
Paramètre Description
input ports 1 port(s) d entree declare(s).
📄Description

Represente un recepteur de sortie fichier.

Module nflow_blocks
Bibliotheque Blocs puits
Type fileSink
Libelle Output File

Description

Represente un recepteur de sortie fichier.

Ports

Entree(s)

Port Role Cote Position
Port_1 Signal numerique lu par le bloc. left x=0, y=40

Sortie(s)

Ce bloc ne declare aucune sortie.

Parametres

Parametre Valeur par defaut
path output.csv

Cles de l inspecteur

Ces cles serialisees sont exposees par l inspecteur du bloc.

Caracteristiques du bloc

Type de bloc fileSink
Famille Blocs puits
Taille graphique 80 x 80
Phases none
Traversee directe voir Algorithmes
Etat ou historique interne non observe dans le code documente
Type de donnees signaux valeurs numeriques double

Algorithmes

Capacites et limites

La page decrit le comportement runtime natif observe dans les sources C++ du module. Les phases declarees indiquent quand le moteur de simulation appelle le bloc.

Generation de code : prise en charge pour C et Rust.

Sources d implementation

Manifestmodules/nflow_blocks/libraries/sink/library.json
{
  "id": "builtin.sink",
  "title": "Sinks",
  "version": "1.0.0",
  "format": "nflow-2",
  "metadata": {
    "author": "Allan CORNET",
    "created": "2026-03-21",
    "tool": "Nelson nflow"
  },
  "comment": "Blocks for visualizing or exporting simulation results",
  "license": "LGPL-3.0",
  "builtin": true,
  "blocks": [
    {
      "type": "scope",
      "label": "Scope",
      "icon": "scope.svg",
      "phases": [
        "INIT",
        "AFTER_STEP"
      ],
      "width": 220,
      "height": 160,
      "inputs": [
        {
          "x": 0,
          "y": 40,
          "side": "left"
        },
        {
          "x": 0,
          "y": 80,
          "side": "left"
        },
        {
          "x": 0,
          "y": 120,
          "side": "left"
        }
      ],
      "outputs": [],
      "defaultParams": {
        "TMin": "",
        "TMax": "",
        "YMin": "",
        "YMax": "",
        "width": 220,
        "height": 160,
        "ShowTickLabels": false
      },
      "render": {
        "type": "plot",
        "path": "M{axisX} {axisTop} L{axisX} {axisY} L{axisRight-2} {axisY}"
      }
    },
    {
      "type": "xyScope",
      "icon": "xyScope.svg",
      "label": "XY Scope",
      "phases": [
        "INIT",
        "AFTER_STEP"
      ],
      "width": 220,
      "height": 160,
      "inputs": [
        {
          "x": 0,
          "y": 50,
          "side": "left"
        },
        {
          "x": 0,
          "y": 110,
          "side": "left"
        }
      ],
      "outputs": [],
      "defaultParams": {
        "XMin": "",
        "XMax": "",
        "YMin": "",
        "YMax": "",
        "width": 220,
        "height": 160,
        "ShowTickLabels": false
      },
      "render": {
        "type": "plot",
        "path": "M{axisX} {axisY} L{axisRight-2} {axisTop+8}"
      }
    },
    {
      "type": "xyzScope",
      "label": "XYZ Scope",
      "icon": "xyzScope.svg",
      "phases": [
        "INIT",
        "AFTER_STEP"
      ],
      "width": 220,
      "height": 180,
      "inputs": [
        {
          "x": 0,
          "y": 50,
          "side": "left"
        },
        {
          "x": 0,
          "y": 90,
          "side": "left"
        },
        {
          "x": 0,
          "y": 130,
          "side": "left"
        }
      ],
      "outputs": [],
      "defaultParams": {
        "XMin": "",
        "XMax": "",
        "YMin": "",
        "YMax": "",
        "ZMin": "",
        "ZMax": "",
        "width": 220,
        "height": 180,
        "RotationX": 30,
        "RotationY": 45
      },
      "render": {
        "type": "plot",
        "path": "M{axisX} {axisY} L{axisRight-2} {axisY-20}"
      }
    },
    {
      "type": "fileSink",
      "icon": "fileSink.svg",
      "label": "Output File",
      "phases": [],
      "width": 80,
      "height": 80,
      "inputs": [
        {
          "x": 0,
          "y": 40,
          "side": "left"
        }
      ],
      "outputs": [],
      "defaultParams": {
        "FileName": "output.csv"
      },
      "render": {
        "type": "image",
        "src": "fileSink.svg"
      }
    },
    {
      "type": "labelSink",
      "icon": "labelSink.svg",
      "label": "Label Sink",
      "phases": [],
      "width": 40,
      "height": 40,
      "inputs": [
        {
          "x": 0,
          "y": 20,
          "side": "left"
        }
      ],
      "outputs": [],
      "defaultParams": {
        "GotoTag": "x",
        "ShowNode": true
      },
      "render": {
        "type": "math",
        "bodyClass": "block-body",
        "mathGroupClass": "label-sink-math",
        "formula": "{params.GotoTag}"
      }
    },
    {
      "type": "display",
      "icon": "display.svg",
      "label": "Display",
      "phases": [
        "INIT",
        "AFTER_STEP"
      ],
      "width": 120,
      "height": 60,
      "inputs": [
        {
          "x": 0,
          "y": 30,
          "side": "left"
        }
      ],
      "outputs": [],
      "defaultParams": {
        "Label": "Display",
        "Format": "short",
        "Decimation": 1,
        "Floating": false
      },
      "render": {
        "type": "math",
        "bodyClass": "block-body",
        "mathGroupClass": "display-math",
        "formula": "\\mathsf{Disp}"
      }
    },
    {
      "type": "toWorkspace",
      "label": "To Workspace",
      "icon": "toWorkspace.svg",
      "phases": [
        "INIT",
        "AFTER_STEP"
      ],
      "width": 80,
      "height": 48,
      "inputs": [
        {
          "x": 0,
          "y": 24,
          "side": "left"
        }
      ],
      "outputs": [],
      "defaultParams": {
        "VariableName": "simout",
        "MaxDataPoints": "inf",
        "Decimation": 1,
        "SaveFormat": "Structure With Time",
        "SampleTime": "-1"
      },
      "render": {
        "type": "math",
        "formula": "\\mathtt{{params.VariableName}}",
        "textSize": 14
      }
    },
    {
      "type": "terminator",
      "label": "Terminator",
      "icon": "terminator.svg",
      "phases": [],
      "width": 40,
      "height": 40,
      "inputs": [
        {
          "x": 0,
          "y": 20,
          "side": "left"
        }
      ],
      "outputs": [],
      "defaultParams": {},
      "render": {
        "type": "image",
        "src": "exports/terminator.svg",
        "svgMode": "element",
        "preserveAspectRatio": "none",
        "x": 0,
        "y": 0,
        "width": 40,
        "height": 40
      }
    },
    {
      "type": "stopSimulation",
      "label": "Stop",
      "icon": "stopSimulation.svg",
      "phases": [
        "AFTER_STEP"
      ],
      "width": 40,
      "height": 40,
      "inputs": [
        {
          "x": 0,
          "y": 20,
          "side": "left"
        }
      ],
      "outputs": [],
      "defaultParams": {}
    }
  ]
}
Runtimemodules/nflow_blocks/src/cpp/sink/fileSink.cpp
//=============================================================================
// Copyright (c) 2016-present Allan CORNET (Nelson)
//=============================================================================
// This file is part of Nelson.
//=============================================================================
// LICENCE_BLOCK_BEGIN
// SPDX-License-Identifier: LGPL-3.0-or-later
// LICENCE_BLOCK_END
//=============================================================================
#include "SimEngineTypes.hpp"
#include "BlockRegistry.hpp"
#include "FieldNames.hpp"
#include "NFlowBlockDescriptor.hpp"
#include <algorithm>
#include <cstdio>
#include <string>
#include "sink_blocks.hpp"
//=============================================================================
// fileSink: streams its input signal to a CSV file at major steps. INIT
// truncates the file (FileName parameter, default "output.csv") and writes
// the header "t,<id>" (vector inputs: "t,<id>_0,<id>_1,..."); AFTER_STEP
// appends one row per sample. The file is opened and closed per phase so a
// crashed or cancelled run keeps every row written so far. An unwritable
// path is skipped silently (the simulation itself is unaffected).
//
// Code generation lowers the block to a labelSink-shaped model output (a
// column in the generated runner's CSV) instead of an fopen in model.c;
// see the pipeline's fileSink rewrite.
//=============================================================================
namespace {
std::string
fileSinkPath(const Nelson::NFlow::Block& b, const Nelson::NFlow::ValMap& vars)
{
    nflow::BlockDescriptor bd(b, vars);
    std::string p = bd.paramStr("FileName", "");
    if (p.empty()) {
        p = bd.paramStr("Filename", "");
    }
    if (p.empty()) {
        p = "output.csv";
    }
    return p;
}
} // namespace
//=============================================================================
bool
Nelson::NFlow::handleFileSink(SimCtx& ctx, const Block& b, Phase phase)
{
    if (phase != Phase::INIT && phase != Phase::AFTER_STEP) {
        return false;
    }
    const std::string path = fileSinkPath(b, ctx.variables);
    SigView v = getInputSig(ctx, b.nid, 0);
    const int w = std::max(1, v.width);
    if (phase == Phase::INIT) {
        FILE* f = fopen(path.c_str(), "wt");
        if (!f) {
            return false;
        }
        fputs("t", f);
        if (w == 1) {
            fprintf(f, ",%s", b.id.c_str());
        } else {
            for (int k = 0; k < w; ++k) {
                fprintf(f, ",%s_%d", b.id.c_str(), k);
            }
        }
        fputs("\n", f);
        fclose(f);
        return false;
    }
    FILE* f = fopen(path.c_str(), "at");
    if (!f) {
        return false;
    }
    fprintf(f, "%.15g", ctx.t);
    for (int k = 0; k < w; ++k) {
        fprintf(f, ",%.15g", sigAt(v, k));
    }
    fputs("\n", f);
    fclose(f);
    return false;
}
//=============================================================================
🔗Voir aussi
scopedisplayfileSource
🕔Historique des versions
Version Description
1.0.0 initial version
Modifier cette page sur GitHub