Num4Main.cpp — Main Entry Point¶
Num4Main.cpp is the main source file of the Marlim3 simulator. It contains the main() function, global variable declarations, data structures used for network convergence, and all top-level solver orchestration routines for steady-state and transient simulations.
Source: src/core/Num4Main.cpp
Table of Contents¶
- Command-Line Interface
- High-Level Execution Flow
- Simulation Modes Explained
- Global Variables
- Local Data Structures
- Key Functions
- main()
- Single-Branch Solvers
- Network Simulation
- Parametric Analysis
- Utility / Support Functions
- Output and Restart I/O
- Dependencies (Included Headers)
- Platform Macros
Command-Line Interface¶
The simulator accepts the following arguments (parsed in main()):
| Flag | Long Form | Description |
|---|---|---|
-h |
--help |
Show usage information |
-i |
--input FILE |
Input JSON file (default: teste1.json for single branch, rede.json for network) |
-o |
--output FILE |
Log output file (default: output/simulacao.log) |
-d |
--dir DIR |
Output directory for results |
-p |
--path PATH |
Path to external input files (e.g. PVTSIM tables) |
-t |
--threads N |
Number of threads (reserved for future use) |
-v |
--validate MODE |
JSON validation mode: JSON, SCHEMA, RULES, or OFF |
-s |
--simulate TYPE |
Simulation type (see below) |
Simulation Types (-s)¶
| Value | Enum | Description |
|---|---|---|
TRANSIENTE |
tipoSimulacao_t::transiente |
Single branch: steady-state + transient (default) |
INJETOR |
tipoSimulacao_t::poco_injetor |
Injection well system |
REDE |
tipoSimulacao_t::rede |
Flow network (production or injection) |
CONVECNAT |
tipoSimulacao_t::convecNatural |
2D natural convection in confined cross-section |
Validation Modes (-v)¶
| Value | Enum | Description |
|---|---|---|
| (default) | tipoValidacaoJson_t::none |
Default initial value; treated as no validation |
JSON |
tipoValidacaoJson_t::json |
Validate JSON structure/format |
SCHEMA |
tipoValidacaoJson_t::schema |
Validate JSON + schema syntax |
RULES |
tipoValidacaoJson_t::rules |
Validate JSON + schema + business rules |
OFF |
tipoValidacaoJson_t::off |
Skip all validation |
Note: Validation is currently forced to
OFFregardless of the user's choice (hardcoded override immediately after parsing the-vargument).
High-Level Execution Flow¶
main()
│
├── Record start time (nowGlobIni)
├── Parse command-line arguments (-i, -o, -s, -v, -d, -p, -t)
├── Register signal handlers (SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM)
├── logger.changeResultadoSimulacao(...) → register input filename and log path in the Logger; records execution date
├── determinarPathArqEntSai() → resolve input/output file paths
├── Open resultado.log manifest (unless INJETOR or CONVECNAT)
│
├── IF tipoSimulacao == REDE
│ ├── Rede arqRede(...) → read network JSON
│ ├── Set fields on the global shared-state struct `varGlob1D` (defined in `variaveisGlobais1D.h`): network flags (`chaverede`, `chaveredeT`, `chaveAnelGL`, `chaveRedeParalela`), file count (`narq`), fluid type (`fluidoRede`), max temperature (`TmaxR`)
│ ├── Determine network sub-type:
│ │ ├── Standard production network (not GL-loop, not parallel, not injection)
│ │ │ ├── descarteTramo() → mark inactive branches
│ │ │ ├── preProcRede() → decompose into internal sub-networks, write RedeInterna-{i}.json
│ │ │ ├── Write relatorioSucessoRede.dat header
│ │ │ ├── IF apenasPreProc == 0 (not pre-processing-only mode):
│ │ │ │ ├── Allocate SProd** malha[redeLeitura]
│ │ │ │ ├── For each sub-network: read RedeInterna-{i}.json → Rede, preparaRedeProd()
│ │ │ │ ├── #pragma omp parallel for: For each sub-network:
│ │ │ │ │ ├── solveRedeProd() → steady-state network solution
│ │ │ │ │ ├── IF chaveredeT == 1: SolveRedeTrans() → transient network solution
│ │ │ │ │ └── Reset vg1d globals (restartRede, relax, erroRede, etc.)
│ │ │ │ └── Append timing + date to relatorioSucessoRede.dat
│ │ ├── Injection network → RedeInj() (steady-state only)
│ │ ├── Gas-lift loop → RedeAnelGL() (steady-state + optional transient)
│ │ └── Parallel network → RedeParalela() (steady-state + optional transient)
│ │
├── ELSE IF tipoSimulacao == TRANSIENTE or INJETOR (single branch)
│ ├── SProd sistem1(...) → build from input JSON (constructor triggers parse + montasistema)
│ ├── ptrSistemaProducao = &sistem1 (for emergency snapshot on signal)
│ │
│ ├── IF perm == 1 (steady-state):
│ │ ├── IF AP == 0: SolveTramoSolteiro(sistem1, chutePerm)
│ │ │ ├── IF compositional (flashCompleto == 2):
│ │ │ │ ├── Pass 1 — switch all cells to black-oil → permanenteSimples()
│ │ │ │ ├── Extract pressure/flow-rate result as initial guess
│ │ │ │ ├── Restore compositional flags on all cells + accessories
│ │ │ │ ├── (Optional) preparaTabDin() → build dynamic PVT tables
│ │ │ │ └── Pass 2 — permanenteSimples() with compositional model
│ │ │ ├── IF black-oil or flash table: permanenteSimples() directly
│ │ │ └── Print profiles, trends, Poisson/Poroso outputs, LogEvento
│ │ ├── IF AP == 1, paralelAP == 0: leituraAP()
│ │ └── IF AP == 1, paralelAP == 1: leituraAPparalelo()
│
│ ├── ELSE IF perm == 2 (restart from snapshot):
│ │ └── ReadSnapShot(sistem1)
│
│ ├── IF transiente == 1:
│ │ ├── IF ConContEntrada == 1 (inlet source → imposed-flow BC):
│ │ │ └── Convert source terms to MC, Mliqini, QL, QG at cell 0; zero out sources
│ │ ├── Initialize cell-level fluid properties for all i = 0..ncel:
│ │ │ ├── Liquid density: rpC, rpL (+ initial copies rpCi, rpLi)
│ │ │ ├── Gas density: rgC, rgL (+ rgCi, rgLi)
│ │ │ ├── Compl. density: rcC, rcL (+ rcCi, rcLi)
│ │ │ ├── Oil viscosity: mipC
│ │ │ ├── Gas viscosity: migC
│ │ │ ├── Compl. viscosity: micC
│ │ │ └── Propagate to right-face: rpR, rgR, rcR, mipR, migR, micR from cell i+1
│ │ ├── determinaDT() → compute initial time step
│ │ ├── renovaTemp() → prepare mass transfer model + update source terms
│ │ ├── modoPerm = 0; modoTransiente = 1
│ │ ├── (Optional) IF modoDifus3D == 1:
│ │ │ ├── Construct solverP3D from UNV mesh
│ │ │ ├── Match coupling surface labels to cell indices
│ │ │ ├── Set tInt[], hI[] from cell temperatures and convection coefficients
│ │ │ ├── inicializaTransientePoisson()
│ │ │ └── Sub-cycling loop: transientePoissonDummy() until wall heat flux converges
│ │ ├── Set RGOMax = 14000 (black-oil dead-oil safety bound)
│ │ └── Time-stepping loop (while lixo5 < tfinal):
│ │ ├── SolveTrans() → advance one time step
│ │ ├── WriteSnapShot() at user-specified times (tempsnp[])
│ │ └── WriteSnapShot() → final snapshot after loop exits
│
├── ELSE IF tipoSimulacao == CONVECNAT
│ └── solv2D::resolve() → 2D natural convection finite-volume solver
│
├── Log INFO "SUCESSO", logger.writeOutputLog()
├── arqRelatorioPerfis.close() (skipped if INJETOR; called even for CONVECNAT despite manifest not being opened)
└── return EXIT_SUCCESS
The sections below describe each simulation mode in more detail.
Simulation Modes Explained¶
Single Branch (default)¶
The simplest mode. A single pipeline segment (SProd object) is created from the input JSON. Two independent simulation modes are available:
- Steady-state — iterates on pressure from downstream to upstream (marching scheme with root-finding on the boundary condition) until convergence. Used for design-point calculations and as the initial condition for transient runs.
- Transient — advances the system in time with explicit time-stepping (
SolveTransloop), capturing slug flow, start-up/shutdown, and other time-dependent phenomena.
The input JSON selects which class to run (or both sequentially: steady-state first as initialisation, then transient).
Network Modes¶
Four network topologies are supported. See Network Simulation for full details.
| Mode | Entry function | Description |
|---|---|---|
| Production | solveRedeProd() / RedeProd() |
Tree topology (collectors + affluents). Pre-processing decomposes into sub-networks solved in parallel via OpenMP. Steady-state + optional transient. |
| Injection | RedeInj() |
Same topology as production but reversed flow direction (surface → wells). Steady-state only. |
| Gas-Lift Loop | RedeAnelGL() |
Production branches coupled with an annular gas distribution line through drain points. Iterates until gas mass balance converges. |
| Parallel | RedeParalela() |
Two co-located pipelines (primary + secondary) coupled at shared fontechk sources. Alternating solves until pressure convergence. |
Natural Convection (2D)¶
A separate 2D finite-volume solver (solv2D) for natural convection in confined cross-sections (e.g., pipeline annuli during shutdowns). Not related to the 1D multiphase flow solver.
Global Variables¶
These variables are declared at file scope and shared across functions in Num4Main.cpp:
Simulation Metadata¶
| Variable | Type | Purpose |
|---|---|---|
versao |
string |
Version string, e.g. "Marlim - 3.5.0" |
nthrdMatriz |
int |
Number of threads for matrix operations (default: 1) |
tipoSimulacao |
tipoSimulacao_t |
Current simulation mode (default: transiente) |
logRede |
int |
Flag: 1 if running in network mode |
nomeRedePrincipal |
string |
Name of the main network input file |
Timing¶
| Variable | Type | Purpose |
|---|---|---|
nowGlobIni / nowGlobFim |
time_t |
Start / end wall-clock time |
diaIni, horaIni, minutoIni, segundoIni |
int |
Decomposed start time |
File Paths¶
| Variable | Type | Purpose |
|---|---|---|
pathArqEntrada |
string |
Directory of the input file |
pathArqExtEntrada |
string |
Directory for external inputs (PVTSIM, snapshots) |
pathPrefixoArqSaida |
string |
Output directory with trailing separator |
arqSaidaSnapShot |
string |
Snapshot output filename |
diretorioSaida |
string |
Output directory from -d argument |
I/O Objects¶
| Variable | Type | Purpose |
|---|---|---|
arqRelatorioPerfis |
ofstream |
Profile results report file (resultado.log) |
logger |
Logger |
Simulation logger (writes JSON log) |
ptrSistemaProducao |
SProd* |
Pointer to the active production system (used by signal handler for emergency snapshots) |
Network Globals¶
| Variable | Type | Purpose |
|---|---|---|
tramos |
vector<tramoAtivo> |
List of active network segments |
redesAlinhadas |
vector<tramoAtivo*> |
Aligned/ordered network pointers |
redeLeitura |
int |
Number of internal sub-networks after pre-processing |
Finite-Volume 2D Solver Globals¶
| Variable | Type | Purpose |
|---|---|---|
tempVF |
detTempo |
Time-stepping parameters for the 2D FV solver |
prop |
detProp |
Material properties for the 2D FV solver |
mapprop |
detMapProp |
Property mapping for the 2D FV solver |
CI |
detCI |
Initial conditions for the 2D FV solver |
CC |
detCC |
Boundary conditions for the 2D FV solver |
Easter Eggs¶
saidaTexto[16] and saidaSubTexto[16] — arrays of humorous quotes (in Portuguese) displayed on simulation completion. A random entry is selected with rand() % 16 at each run.
Local Data Structures¶
These struct types are defined within Num4Main.cpp and used exclusively by functions in this file.
fonteposic¶
Describes the position of a mass source (injection point) within the network.
struct fonteposic {
int nmani; // Number of manifolds connected to this source
int mani[10]; // Indices of connected manifolds (max 10)
double posicmani; // Position of the source along the manifold
};
noRede¶
Tracks convergence state at a network node during steady-state iterations.
struct noRede {
int naflu; // Number of upstream (affluent) branches
int ncole; // Number of downstream (collector) branches
int aflu[40]; // Indices of upstream branches (max 40)
int cole[40]; // Indices of downstream branches (max 40)
double normaP1; // Pressure norm at current iteration
double normaP0; // Pressure norm at previous iteration
double normaMass1; // Mass norm at current iteration
double normaMass0; // Mass norm at previous iteration
int cadastrado; // Whether this node has been registered
};
tramoAtivo¶
Describes an active segment in the network topology, including its connections and operational state.
struct tramoAtivo {
int ncoleta; // Number of downstream collectors
int nafluente; // Number of upstream feeders
int nbloqueio; // Number of blockages
int ativo; // Active flag (1 = active)
vector<int> coleta; // Indices of downstream branches
vector<int> afluente; // Indices of upstream branches
int bloqueio; // Blockage flag
int permanente; // Steady-state convergence flag
int presimposta; // Whether pressure is imposed at this branch
double presMon; // Upstream (montante) pressure
double presJus; // Downstream (jusante) pressure
int reverso; // Reverse-flow flag
int derivaPrincipal; // Main branch flag
string tramoJson; // Path to the branch's JSON input file
};
tramoPart¶
Auxiliary structure for tracking which branches participate in a blockage partition.
struct tramoPart {
int ntram; // Number of branches in this partition
int part[40]; // Indices of participating branches (max 40)
};
convergeNoPerm¶
Holds mixed/aggregated fluid properties at a network node during steady-state convergence. These are weighted averages of all branches feeding into the node.
struct convergeNoPerm {
double tL, tH; // Temperature range [low, high]
double qostdTot; // Total oil flow rate (std conditions)
double qgstdTot; // Total gas flow rate (std conditions)
double dengmist; // Mixed gas density
double yco2mist; // Mixed CO₂ mole fraction
double apimist; // Mixed API gravity
double qwmist; // Water flow rate
double mliqmist; // Mixed liquid mass flow rate
double mgasmist; // Mixed gas mass flow rate
double cpmist; // Mixed heat capacity
double tempmist; // Mixed temperature
double qlmistStd; // Mixed liquid volume rate (std)
double RGOmist; // Mixed gas-oil ratio
double bswmist; // Mixed BSW (basic sediment & water)
// ... plus negative-flow counterparts and compositional fields
ProFlu flu; // Resulting mixed fluid properties
};
Key Functions¶
main()¶
Signature: int main(int argc, char **argv)
The entry point of the simulator. See High-Level Execution Flow for the full annotated call tree. Key responsibilities:
- Records start time (
nowGlobIni) - Parses command-line arguments (
-i,-o,-s,-v,-d,-p,-t) - Registers OS signal handlers (SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM) →
signalHandler() - Configures logger and resolves file paths (
determinarPathArqEntSai) - Opens the output manifest file (
resultado.log) - Dispatches to the appropriate solver based on
tipoSimulacao: - Network (
REDE): reads network JSON →Rede, determines sub-type (production / injection / gas-lift / parallel), pre-processes topology, solves sub-networks in parallel with OpenMP - Single branch (
TRANSIENTE/INJETOR): constructsSProd; runs steady-state (SolveTramoSolteiroor parametric analysis); runs transient (initialises cell-level densities/viscosities and runs theSolveTransloop) - Natural convection (
CONVECNAT): constructs and runs 2D FV solver (solv2D::resolve) - Logs "SUCESSO", writes
simulacao.log, closesresultado.log
Single-Branch Solvers¶
Steady-State¶
permanenteSimples(SProd &sistem1, double inichute)¶
Dispatches to the appropriate busca (root-finding) method based on the inlet boundary-condition type (ConContEntrada) and whether the system is a production or injection well:
ConContEntrada |
Condition | Method called |
|---|---|---|
| 0 | Source at inlet (gas, liquid, IPR, porous) — choke inactive | buscaProdPfundoPerm(inichute) |
| 0 | Source at inlet — choke active | buscaProdPfundoPerm2(inichute) |
| 0 | Source at inlet — reverse flow | buscaProdPfundoPermRev(inichute) |
| 1 | Pressure at inlet — choke inactive | buscaProdPresPresPerm(chutemass) |
| 1 | Pressure at inlet — choke active | buscaProdPresPresPerm2(chutemass) or buscaProdPresPresPerm3(inichute) |
| 2 | Pressure + injection flow rate | buscaProdPfundoPerm3(pres) |
| — | Injection well (pocinjec == 1) |
buscaInjPfundoPerm1..5(inichute) depending on condpocinj.CC |
For ConContEntrada == 0 with a gas-lift service line (lingas == 1) and pressure-BC on the gas side (tipoCC == 0), the solver implements a nested retry loop: it first estimates the gas injection flow rate, solves with flow-rate BC, then switches back to pressure BC using the converged bottom-hole pressure as the initial guess. This retry loop runs up to 40 iterations.
SolveTramoSolteiro(SProd &sistem1, double chute0)¶
Top-level driver for solving a standalone branch (not part of a network). Implements the two-pass compositional strategy:
- If compositional (
flashCompleto == 2): - Pass 1 — Temporarily switch all cells and accessories (types 1, 2, 3, 10, 15, 16) to
flashCompleto = 0(black-oil). CallpermanenteSimples()with the user-supplied initial guess. - Extract the converged bottom-hole pressure (or flow rate) as a refined initial guess.
- Restore
flashCompleto = 2on all cells/accessories. SetbuscaIni = 0. - (Optional)
preparaTabDin()iftabelaDinamica == 1. - Pass 2 —
permanenteSimples()with the compositional model and the refined guess. - If black-oil or table — calls
permanenteSimples()directly. - Injection-well variant — same two-pass logic but uses
flashCompleto = 3for the first pass and injection-specificbuscamethods.
After convergence, writes:
imprimeProfile()/imprimeProfileG()→ spatial profiles (PERFISP,PERFISG)resumoPermanente()→ steady-state summary (resumoPermanente.dat)- Poisson 2D prints (
imprimePermanente) for cells withdifus2D == 1 - Poroso 2D prints (
imprimePseudo) for type-16 accessories - Radial porous profiles (
PerfisPocoRadial) for type-15 accessories ImprimeTrendPCab/P,ImprimeTrendGCab/G→ trend headers and initial dataLogEvento.datwith date, duration, version (when transient is not active)
Transient¶
The single-branch transient simulation is driven by the SolveTrans() loop inside main() (see High-Level Execution Flow). SolveTrans() is a method on SProd (SisProd.cpp) rather than a free function in Num4Main.cpp. The transient loop in main() initialises cell-level properties, calls determinaDT(), and iterates SolveTrans() → WriteSnapShot() until lixo5 ≥ tfinal.
Network Simulation¶
Full documentation: Network Simulation
Pre-Processing¶
Detailed documentation: Network Simulation — Pre-Processing Pipeline
| Function | Purpose |
|---|---|
descarteTramo(Rede&, int) |
Scan branches, mark inactive ones, prune connectivity, populate global tramos vector |
preProcRede(Rede&, int) |
DFS graph decomposition into independent sub-networks; write RedeInterna-{i}.json per sub-network |
gravaRedeInterna(...) |
Serialize a sub-network to JSON (configuration + re-indexed topology) |
preparaRedeProd(...) |
Build SProd objects for a sub-network from branch JSON files |
avaliaPerm(...) |
Multi-pass scan to deactivate zero-flow branches (see avaliaPerm) |
Steady-State Solvers and Convergence¶
Detailed documentation: Network Simulation — Steady-State Network Solver, Convergence, Node-Level Fluid Mixing, Initial Pressure Guess
Convergence loop and iteration cycles:
| Function | Purpose |
|---|---|
convergeRede(...) |
Outer convergence loop: calls cicloRede/cicloRedeComp until norm < limConverge or 200 iterations |
cicloRede(...) |
One iteration of the steady-state network solver (black-oil). Topological traversal, branch solves, node mixing, convergence norm |
cicloRedeComp(...) |
Compositional variant — molar composition tracking at nodes via totalizaCicloRedeComp() |
cicloRedeCompCego(...) |
"Blind" compositional cycle — decoupled one-shot pass for initial iterations |
cicloRedeInj(...) |
Injection network iteration cycle: topological traversal with injection-specific busca methods |
Node-level mixing and initial guess:
| Function | Purpose |
|---|---|
totalizaCicloRede(...) |
Aggregate fluid properties at a junction node (mass/energy-weighted mixing) |
totalizaCicloRedeComp(...) |
Compositional variant: molar-weighted composition mixing at nodes |
totalizaCicloRedeCompCego(...) |
Simplified molar mixing for blind compositional cycle |
chutePresRede(...) |
Recursive hydrostatic initial pressure guess for production networks |
chutePresRedeInj(...) |
Recursive hydrostatic initial pressure guess for injection networks |
Topology variant drivers:
Detailed documentation: Network Simulation — Production, Gas-Lift, Parallel, Injection
| Function | Purpose |
|---|---|
solveRedeProd(...) |
Production network entry point: avaliaPerm → convergeRede → output profiles |
RedeProd(...) |
Legacy combined driver: constructs SProd objects + solves. Single-branch fallback |
RedeInj(...) |
Injection network driver (steady-state only, uses cicloRedeInj) |
RedeAnelGL(...) |
Gas-lift loop driver: couples production branches with annular gas distribution |
RedeParalela(...) |
Parallel network driver: two co-located pipelines with shared fontechk sources |
Transient Solvers¶
Detailed documentation: Network Simulation — Transient Network Solver
| Function | Purpose |
|---|---|
SolveRedeTrans(...) |
Transient production-network driver: CFL time-stepping, coupling iteration, BC propagation, restart logic, snapshot I/O |
CicloRedeTrans(...) |
Single time-step BC propagation: topological traversal, mass-flux collection, fluid mixing at nodes, master/secondary collector assignment |
TransAnel(...) |
Transient gas-lift annulus driver |
SolveRedeParalelaTrans(...) |
Transient parallel network driver |
Parametric Analysis¶
leituraAP(string nomeArquivoAP, SProd &sistem1)¶
Runs a sequential parametric analysis: reads leituraAP.json, iterates over parameter combinations, calls SolveTramoSolteiro() for each case.
leituraAPparalelo(string nomeArquivoAP, string nomeArquivoLog, tipoValidacaoJson_t validacaoJson, SProd &sistem1)¶
Parallel parametric analysis using OpenMP. Each parameter case is solved in its own thread with an independent SProd copy.
leituraAPparaleloReserva(...)¶
Variant of parallel parametric analysis with reservoir-model coupling.
Utility / Support Functions¶
Snapshot I/O¶
| Function | Description |
|---|---|
WriteSnapShot(SProd&, double, int) |
Writes a snapshot file (.snp) of the full simulation state (all cell-level fields) to text |
ReadSnapShot(SProd&) |
Reads a snapshot to restart a simulation from a saved state |
Signal Handling and CLI¶
| Function | Description |
|---|---|
signalHandler(int) |
Handles OS signals: emergency snapshot, log, exit |
showUsage(string) |
Prints the command-line help message |
Path Resolution¶
| Function | Description |
|---|---|
determinarPathArqEntSai(...) |
Resolves input/output file paths from the input and log file arguments; sets pathArqEntrada, pathPrefixoArqSaida, and arqSaidaSnapShot |
determinarPathArqExtEntrada(string) |
Sets external input path (PVTSIM tables, snapshots) |
determinarPathSaida(string) |
Sets the output directory |
Flow-Rate Helpers¶
| Function | Description |
|---|---|
FQpesado(Cel*, int) |
Oil flow rate at std conditions (heavy oil / black-oil) |
FQleve(Cel*, int) |
Gas flow rate at std conditions (light component) |
Network Helper Functions¶
Detailed documentation: Network Simulation — Transient Helper Functions
| Function | Description |
|---|---|
celAfluFinal(...) |
Copies master collector's cell[0] into afluent ghost cell |
corrigeVazNo(...) |
Corrects unphysical negative mass at network nodes |
corrigeVazNoBuf(...) |
Buffered variant of node flow correction |
verificaFonteDuplaReversa(...) |
Detects dual sources with opposing flow signs |
trocaFonteColetor(...) |
Swaps cell[0] ↔ cell[1] accessories at reversed dual source |
retornaFonteColetor(...) |
Restores original source configuration after swap |
avaliaBloq(...) |
Evaluates manifold blocking at 2-way junctions |
verificaTramoVazPres(...) |
Finds branch with imposed flow/pressure boundary |
inativoColetor(...) |
Marks collector branches as inactive |
inativoAfluente(...) |
Marks affluent branches as inactive |
ranqueiaCol(...) |
Ranks collectors by depth in the network tree |
testaBloqueio(...) |
Tests if a branch is blocked |
conectaPrincipal(...) |
Couples flux data between primary and secondary branches at shared nodes |
chutePresRedeParalelaSec(...) |
Initial pressure guess for secondary branch |
calcPeriAnelGL(...) |
Steady-state solve of each well in gas-lift loop |
calcErroGL(...) |
Normalised gas mass balance error |
objetCC0(...) |
Objective function for annulus inlet pressure matching |
zriddr(...) |
Ridder's root-finding method for gas-lift pressure |
Compositional Fluid Updates¶
Detailed documentation: Network Simulation — Compositional Model Switching, Cell-Level Composition Propagation
| Function | Description |
|---|---|
atualizaComp(SProd&, int) |
Molar mixing at source cells (injection accessories) |
atualizaCel(SProd&, int) |
Composition propagation at plain cells (no source) |
alteraModoFluidoCompBlack(...) |
Switches all branches/cells from compositional to black-oil |
alteraModoFluidoBlackComp(...) |
Restores compositional model on all branches/cells |
preparaTabDin(SProd&) |
Builds dynamic PVT tables on a \((P, T)\) grid for fast bilinear interpolation |
Warning Messages¶
| Function | Description |
|---|---|
aviso(int i) |
Prints convergence failure warning for branch i |
aviso2(int i) |
Prints first-iteration convergence failure warning (suggests adjusting ParametroInicial) |
Output and Restart I/O¶
All simulator output is plain-text (no binary files). Every output path is prefixed by the global pathPrefixoArqSaida (resolved from the -d / -o arguments, defaulting to output/). A manifest file (resultado.log) records the name of each generated data file so that downstream tools can discover them.
Logger — Structured JSON Log¶
The Logger class (Log.h / Log.cpp) accumulates events during a run and serialises them to a JSON file via RapidJSON PrettyWriter.
| Severity | Enum | Label in JSON |
|---|---|---|
| None | LOGGER_NONE |
— |
| Informational | LOGGER_INFO |
"INFO" |
| Warning | LOGGER_AVISO |
"AVISO" |
| Failure | LOGGER_FALHA |
"FALHA" |
Event codes are defined as string macros:
| Code | Meaning |
|---|---|
1000 |
Unexpected exception |
1001 |
JSON format validation error |
1002 |
Schema validation error |
1003 |
Business rule validation failure |
1004 |
Business rule validation warning |
1100 |
Parse process finished (info) |
1101 |
Generic parse info |
1200 |
Simulation finished |
1300 |
Simulation cancelled |
The default output filename is simulacao.log (macro ARQUIVO_LOG_PADRAO). The global logger object is created in Num4Main.cpp and configured with changeResultadoSimulacao() after argument parsing. writeOutputLog() produces:
{
"versao": "Marlim - 3.5.0",
"resultadoSimulacao": {
"arquivo": "<input_file>",
"data": "dd/mm/yyyy",
"status": "sucesso" | "falha",
"logs": [
{
"log": "INFO" | "AVISO" | "FALHA",
"codigo": "1xxx",
"descricao": "<message + complement>",
"propriedade": "...",
"causa": "...",
"linha": 0
}
]
}
}
Convenience methods write_logs_and_exit() and log_write_logs_and_exit() combine logging with immediate program termination.
Snapshot Files (.snp) — Restart Checkpoints¶
WriteSnapShot() serialises the complete simulation state to a text file so that ReadSnapShot() can restore it for a restart run (triggered by perm == 2).
Filename pattern:
| Context | Pattern |
|---|---|
| Single branchh | Saida{N}-{inputName}.snp |
| Network branch | Tramo{T}-Saida{N}-{inputName}.snp |
where N = round(porc) is the snapshot index (percentage or sequence number).
Format: ASCII text, semicolon-delimited (;), 12-digit precision. A decorative header with a random motivational quote precedes the data. Records are located by marker strings ("->").
Data layout (standard mode, HISEP == 0):
-
System-level record — marker
"variavel de Sistema de Escoamento= ... ->":
presfim,pGSup,masChkSup,temperatura,ncelGas,presiniG,tempiniG,massfonte,mult, moving-average accumulators (presMedMov,jMedMov,alfMedMov,tMedMov), choke state (aberto,tempoaberto), intermittency totals, variable-length vectors (presVet,jVet,alfVet,tVet), intermittency cell data, buffered source terms. -
Production cells — one line per cell, marker
"Celula de producao= {i} ->":
134+ fields per cell covering temperatures, pressures (including buffer/ini variants), mass fluxes (L/C/R + buffers), void fractions, water cut, drift-flux parameters (c0,ud), mass-transfer terms, BCS pump state, flow-pattern indicators, flow rates, densities, PIG state (position, velocity, void fractions), choke derivatives, riser-gas fractions, fluid properties (API,RGO,Deng,BSW,yco2, viscosities, emulsion data), thermal layer state (calor.*: internal velocities, temperatures, convection coefficients, wall-temperature arrayTcamada[j][k]).
Conditional blocks: paraffin data (ifmodoParafina == 1), compositional data (ifflashCompleto == 2:npseudo,fracMol[], liquid/vapour compositions, beta, bubble-point, stock-tank densities). -
Gas-lift service cells (if
lingas > 0) — ~40 fields per gas cell including pressures, velocities, thermal data. -
Footer — simulation time
lixo5.
HISEP mode (HISEP == 1): writes a simplified CSV table (t ; HL ; slipRatio ; Usg ; Usl ; FlowPattern ; cell) for flow-pattern analysis.
ReadSnapShot() mirrors the write order exactly, using >> token extraction and consuming ";" delimiters. After restoring fields it calls RenovaFluido() to recompute derived properties (and atualizaPropComp() / atualizaPropCompStandard() for compositional runs).
Snapshot triggers:
| Trigger | Location |
|---|---|
| User-specified transient times | tempsnp[kontasnp] match during CicloRedeTrans / SolveRedeTrans |
| End of transient simulation | Final snapshot after the time loop exits |
| OS signal (emergency) | signalHandler() — writes checkpoint + log before exit() |
Profile Files — Spatial Distributions¶
Profile files capture the spatial distribution of variables along the pipeline at a given time instant.
| File pattern | Generator | Content |
|---|---|---|
PERFISP-{t}.dat |
Ler::imprimeProfile() |
Production-line profile (pressure, temperature, holdup, velocities, densities, flow pattern, etc.) |
PERFISG-{t}.dat |
Ler::imprimeProfileG() |
Gas-lift service-line profile |
PERFISTRANSP-{t}-{cell}.dat |
Ler::imprimeProfileTrans() |
Radial thermal profile (radius, temperature, heat flux) |
PerfisPocoRadial-{t}-{pos}.dat |
Num4Main | Radial porous-medium well profile (pressure, flow rates, saturations) |
Network branches prepend Tramo{T}-R-{nrede}- to the filename; parametric-analysis runs insert seqAP-{seq}-.
Format: text matrix, semicolon-delimited. A header line lists column names with units and an F/C annotation (face / centre). Columns are user-configurable via boolean flags in the input JSON (profp.*); the code conditionally includes each column in both the header and data rows.
Trend Files — Time Series at Fixed Positions¶
Trend files record the temporal evolution of variables at user-selected axial positions during transient simulation.
| File pattern | Generator | Content |
|---|---|---|
TENDP-{dist}.dat |
SProd::ImprimeTrendPCab() + ImprimeTrendP() |
Production-line trends |
TENDG-{dist}.dat |
SProd::ImprimeTrendGCab() + ImprimeTrendG() |
Gas-lift service-line trends |
TENDTRANSP-{cel}-{cam}-{disc}.dat |
SProd::ImprimeTrendTransP() |
Thermal layer trends |
Format: text matrix, semicolon-delimited, width=20, precision=19. Three comment lines (# Comprimento, # Rotulo, # Indice da Celula) precede the column headers. Data is buffered in MatTrendP[i] / MatTrendG[i] matrices during time-stepping (filled by Ler::imprimeTrend()) and flushed to disk by the ImprimeTrend* methods in append mode (ios_base::app). Columns mirror the profile set and are controlled by the same per-position boolean flags (trendp[i].*).
Steady-State Summary¶
Ler::resumoPermanente() writes resumoPermanente.dat — a single-row summary of key steady-state results: standard flow rates (oil, oil + water, total liquid, gas), inlet/outlet pressures, choke pressures, gas-lift data, BCS pump performance (ΔP, power, head, in-situ flow rates), and intermittency criteria. Semicolon-delimited with a column-name header.
Output Manifest and Auxiliary Files¶
| File | Purpose |
|---|---|
resultado.log |
Manifest listing every profile/trend file generated (one filename per line). Opened in main(); each ImprimeTrend* / imprimeProfile* call appends its filename and flushes. |
relatorioSucessoRede.dat |
Network convergence report: header # RedeInterna ; # Tramo ; Permanente ; Ativo, one row per branch indicating success/failure. |
LogEvento.dat |
Human-readable event log per internal network (date, time, duration, version, motivational quote). Written in append mode. |
RedeInterna-{N}.json |
JSON topology file for each internal sub-network (produced by gravaRedeInterna()). |
sucessoAP.dat |
Parametric-analysis success/failure report (colon-delimited). |
variaveisInteresseAP.dat |
Parametric-analysis variables of interest (sequence, status, inlet pressure, outlet temperature). |
Dependencies (Included Headers)¶
The file includes headers organized into the following groups:
Core Simulation¶
| Header | Module |
|---|---|
SisProd.h |
SProd — production system class |
LerRede.h |
Rede — network reader |
Leitura.h |
Input file parsing, enums |
LeituraVapor.h |
Vapor/steam input parsing |
LerAP.h |
Parametric analysis reader |
variaveisGlobais1D.h |
varGlob1D — shared simulation state |
Log.h |
Logger — structured logging |
Fluid Properties¶
| Header | Module |
|---|---|
PropFlu.h |
ProFlu — fluid property calculations (black-oil) |
PropFluCol.h |
Collector fluid properties |
PropFluColVF.h |
Fluid properties for finite-volume solver |
PropVapor.h |
Vapor/steam properties |
Cell & Geometry¶
| Header | Module |
|---|---|
celula3.h |
Cel — cell (control volume) data structure |
celulaGas.h |
Gas-phase cell extensions |
celulaVapor.h |
Vapor/steam cell extensions |
celRad.h |
Radial cell (porous medium) |
celRad-Simples.h |
Simplified radial cell |
Geometria.h |
Pipe geometry |
GeometriaPoro.h |
Porous media geometry |
estruturas.h |
Core data structures |
estruturasPoisson3D.h |
3D Poisson solver data structures |
estruturasPoroso.h |
Porous media data structures |
estruturaTabDin.h |
Dynamic PVT table data structures |
estruturaUNV.h |
UNV mesh data structures (3D coupling) |
Mesh & 2D Elements¶
| Header | Module |
|---|---|
Elem2D.h |
2D finite-volume element |
Elem2DPoroso.h |
2D porous-medium element |
Elem3DPoisson.h |
3D Poisson element |
Malha2D.h |
2D mesh for heat diffusion |
Malha2DPoroso.h |
2D porous-medium mesh |
Malha3DPoisson.h |
3D Poisson mesh |
dados1Poisson.h |
1D Poisson data structures |
dados1Poroso.h |
1D porous-medium data structures |
dados3DPoisson.h |
3D Poisson data structures |
Porous Media¶
| Header | Module |
|---|---|
PorosoRad.h |
Radial porous-medium model |
PorosoRad-Simples.h |
Simplified radial porous-medium model |
Mass & Energy Sources¶
| Header | Module |
|---|---|
FonteMas.h |
Mass source terms |
FonteMassCHK.h |
Choke mass source |
FonteMasVap.h |
Vapor mass source |
TrocaCalor.h |
Heat transfer |
Artificial Lift¶
| Header | Module |
|---|---|
Bcsm2.h |
ESP (BCS) pump model |
BombaVol.h |
Volumetric pump model |
multiBCS.h |
Multi-stage BCS |
Solvers¶
| Header | Module |
|---|---|
solver.h |
solv2D — 2D finite-volume solver |
solverPoisson.h |
2D Poisson (heat diffusion) solver |
solver3DPoisson.h |
3D Poisson solver |
solverPoroso.h |
Porous media solver |
Math¶
| Header | Module |
|---|---|
Vetor.h |
Vcr<T> — vector template |
Matriz.h |
Matrix operations |
FerramentasNumericas.h |
Numerical utilities |
GradientCorrelations.h |
Pressure-gradient correlations |
Other¶
| Header | Module |
|---|---|
versao.h |
Version string (VERSAO macro) |
FA_Hidratos.h |
Hydrate formation model |
FA_Hidratos_Servico.h |
Hydrate formation — service-line variant |
chokegas.h |
Gas choke model |
estrat.h |
Flow pattern (stratification) |
criterioIntermiSevera.h |
Severe intermittency criterion |
Acidentes2.h |
Pipe fittings / singularities |
acessorios.h |
Accessories (valves, etc.) |
mapa.h |
Output mapping |
Platform Macros¶
The BARRA macro defines the path separator character based on the target OS:
| Platform | BARRA Value |
|---|---|
linux, LINUX, Linux, UNIX |
"/" |
WIN32, Win32, win32 |
"\\" |
| Other | "/\\" |
This macro is used by determinarPathArqEntSai() and related functions to construct file paths portably.