← Browse

@equinor/neqsim

NeqSim (Non-Equilibrium Simulator) is a comprehensive Java library for fluid property estimation, process simulation, and engineering design.

instructionscopilot

Install

agr install @equinor/neqsim --target copilot

Writes 1 file into .github/copilot-instructions.md, pinned to git-b3e79847.

  • .github/copilot-instructions.md

Document

NeqSim AI Guidance for Coding Agents

Quick Orientation

Start here: Read CONTEXT.md in the repo root for a 60-second overview of the entire codebase - repo map, code patterns, build commands, and constraints.

Solving a task? See docs/development/TASK_SOLVING_GUIDE.md for the step-by-step workflow: classify the task, find similar past solutions, write code, verify, log it.

Looking for code patterns? docs/development/CODE_PATTERNS.md has copy-paste starters for every common task (fluids, flash, equipment, PVT, tests, notebooks).

Was this solved before? Search docs/development/TASK_LOG.md for keywords. Every solved task gets an entry there - check before starting from scratch.


WARNING: CRITICAL: Java 8 Compatibility (READ FIRST)

All code MUST compile with Java 8. The CI build will FAIL if you use Java 9+ features.

This applies to ALL Java files including test classes in src/test/java/.

FORBIDDEN Java 9+ Features (NEVER USE):

ForbiddenJava 8 Alternative
"str".repeat(n)StringUtils.repeat("str", n) (Apache Commons)
var x = ...Explicit type declaration: String x = ..., Map<String, Object> map = ...
List.of(a, b)Arrays.asList(a, b) or Collections.singletonList(a)
Set.of(a, b)new HashSet<>(Arrays.asList(a, b))
Map.of(k, v)Collections.singletonMap(k, v) or HashMap
str.isBlank()str.trim().isEmpty()
str.strip()str.trim()
str.lines()str.split("\\R") or BufferedReader
Optional.isEmpty()!optional.isPresent()
Text blocks """..."""Regular strings with \n
RecordsRegular class with fields
Pattern matching instanceofTraditional instanceof + cast

Common var Replacement Examples:

// WRONG (Java 10+):
var map = someMethod.toMap();
var list = getItems();
var result = calculate();

// CORRECT (Java 8):
Map<String, Object> map = someMethod.toMap();
List<String> list = getItems();
CalculationResult result = calculate();

Required Import for String Repeat:

import org.apache.commons.lang3.StringUtils;
// Usage: StringUtils.repeat("=", 70)

⚠️ CRITICAL: Run Spotless After Editing ANY Java File (READ SECOND)

The CI runs spotless:check (via the pre-commit GitHub Action) and FAILS the build on any unformatted .java file. AI-generated/edited Java is NOT auto-formatted — agents that hand-indent multi-line method chains or long string concatenations WILL produce violations (this is exactly what failed PR #2324).

Mandatory workflow after creating OR editing ANY .java file (main, test, or examples) — before committing:

.\mvnw.cmd spotless:apply    # reformats to the project style (Windows)
git add <the reformatted files>
.\mvnw.cmd spotless:check    # OPTIONAL local verify — this is what CI runs
  • Run spotless:apply (NOT just check) to actually fix the files.
  • Do NOT rely on local pre-commit hooks being installed — run it explicitly.
  • NEVER bypass with git commit --no-verify.
  • This is non-negotiable: a single unformatted file fails the entire CI build.

Quick Commands

  • Package and Update Python: When the user says "package and update python" or similar, run these commands:
    .\mvnw.cmd package -DskipTests
     Copy-Item -Path "C:\Users\ESOL\Documents\GitHub\neqsim\target\neqsim-3.16.0.jar" -Destination "C:\Users\ESOL\AppData\Roaming\Python\Python312\site-packages\neqsim\lib\" -Force
    
    This builds the NeqSim JAR and copies it to the Python neqsim package for immediate use. Note: the runtime loads lib/* (flat), so copy the JAR directly into neqsim\lib\, not a java11/java8 subfolder.

API Consistency (MANDATORY)

When creating example files or documentation that references existing classes:

  1. ALWAYS verify method signatures before using them - read the actual class to confirm:

    • Constructor parameters (type and order)
    • Method names exist and have correct parameter types
    • Return types match expected usage
  2. Common API verification pattern:

    # Before writing example code that uses SomeClass:
    1. Search for the class: file_search("**/SomeClass.java")
    2. Read constructor and method signatures
    3. Use only methods that actually exist with correct parameter types
    
  3. Do NOT assume API patterns - different classes may have different conventions:

    • Some constructors take String name, others take ProcessSystem
    • Method names like addEquipment vs addEquipmentReliability vs addEquipmentMtbf
    • Parameter counts vary (e.g., 3 params vs 4 params)
  4. Inner classes and enums - verify the exact location:

    • Enums may be in different classes: RiskEvent.ConsequenceCategory vs RiskMatrix.ConsequenceCategory
    • Inner classes require full path: BowTieModel.Threat, PortfolioRiskAnalyzer.CommonCauseScenario
    • Check imports in the actual class to see which enum/type it uses
  5. Object-based vs convenience APIs - do NOT assume convenience methods exist:

    • Wrong: model.addThreat("name", 0.1) (assuming convenience overload)
    • Right: First check if method takes objects: model.addThreat(new Threat(...))
    • Many APIs use builder patterns or require creating objects explicitly
  6. Common API mistakes to avoid:

    • Assuming getXxx95() exists when actual method is getXxx(int percentile)
    • Assuming enum constants like SEVERE_WEATHER when actual is CommonCauseType.WEATHER
    • Assuming 1-arg constructors when 2+ args are required
    • Calling methods on wrong class (e.g., analyzer.getFrequency() vs model.getFrequency())
    • Assuming calculate() when actual method is calculateRisk() or run()
    • Assuming convenience overloads like addAsset(name, value1, value2, value3) when API is addAsset(id, name, value)
    • Using descriptive names as IDs when API distinguishes between id and name parameters

Documentation Code Verification (MANDATORY)

Every code example in documentation MUST be verified by a runnable test. Documentation is NOT complete until the test has been executed and passes.

When writing documentation that includes Java or Python code examples:

  1. Write a JUnit 5 test that exercises every API call shown in the documentation.

    • Append to src/test/java/neqsim/DocExamplesCompilationTest.java for general utilities.
    • Or create a dedicated test in the appropriate package directory.
    • The test must instantiate classes, call all documented methods, and assert results are non-null/valid.
  2. Run the test and confirm all assertions pass before finalizing documentation.

    • Use ./mvnw test -Dtest=DocExamplesCompilationTest (or the specific test class).
    • If the test fails, fix the documentation code - do NOT finalize with broken examples.
    • This step is NON-NEGOTIABLE - never skip it, even for "simple" examples.
  3. Keep tests in sync - when documentation changes, update the corresponding test.

  4. For Python examples: verify the equivalent Java API calls work (Python examples call the same Java methods via jpype). If the Java test passes, the Python example will work.

  5. Common doc-code bugs to catch with tests:

    • Plus fraction names with + character ("C20+" crashes - use "C20")
    • Wrong method names (getUnitOperation() vs getUnit())
    • Wrong parameter types (int vs double)
    • Calling characterization before setting mixing rule
    • Wrong risk threshold descriptions not matching source logic
    • Methods requiring unit strings (e.g., setDesignAmbientTemperature(15.0, "C") not setDesignAmbientTemperature(15.0))
    • Getter methods requiring arguments (e.g., getFanStaticPressure(flow) not getFanStaticPressure())

  • Mission Focus: NeqSim is a Java toolkit for thermodynamics and process simulation; changes usually affect physical property models (src/main/java/neqsim/thermo) or process equipment (src/main/java/neqsim/process).
  • Architecture Overview: Packages map to the seven base modules in docs/modules.md; keep new code within the existing package boundaries so thermodynamic, property, and process layers stay decoupled.
  • Property Initialization After Flash (CRITICAL): After any flash calculation (TPflash, PHflash, PSflash, etc.), you MUST call fluid.initProperties() before reading physical/transport properties. init(3) alone does NOT initialize transport properties (viscosity, thermal conductivity). Use fluid.initProperties() which calls both init(2) + initPhysicalProperties(). Without this, getViscosity(), getThermalConductivity(), and getDensity() may return zero.
  • Phase Envelope Branch Labels (CRITICAL): When using calcPTphaseEnvelope(true, 1.0) (bubblePointFirst=true), getBubblePointTemperatures() returns physically DEW curve data and getDewPointTemperatures() returns physically BUBBLE curve data (labels are swapped). Always classify branches by physical reasoning: the branch with the higher maximum temperature is the dew curve (contains cricondentherm). See neqsim-api-patterns skill for the correct pattern.
  • Thermo Systems: Fluids are represented by SystemInterface implementations such as SystemSrkEos or SystemSrkCPAstatoil; always set a mixing rule (setMixingRule("classic") or numeric CPA rule) and call createDatabase(true) when introducing new components.
  • Process Equipment Pattern: Equipment extends ProcessEquipmentBaseClass and is registered inside a ProcessSystem; ProcessSystem enforces unique names and handles recycle/adjuster coordination, so reuse it for multi-unit workflows. Use MultiPortEquipment as the base class for equipment with multiple inlet/outlet streams.
  • Stream Introspection: Every ProcessEquipmentInterface exposes getInletStreams() and getOutletStreams() returning List<StreamInterface>. Use these to walk flowsheets programmatically, build topology graphs, or auto-generate DEXPI/P&IDs. Equipment classes (Separator, Mixer, Splitter, etc.) override these to return their specific connected streams.
  • Named Controllers: Attach multiple controllers to equipment via addController("tag", controller), retrieve with getController("tag"), list all with getControllers(). The legacy setController()/getController() still work (backward-compatible). During dynamic simulation runTransient(), the ProcessSystem explicitly runs all controller devices and measurement devices each timestep.
  • Explicit Connections: Record typed connection metadata via process.connect(source, target, ProcessConnection.ConnectionType.MATERIAL, "label"). Connection types: MATERIAL, ENERGY, SIGNAL. Query with process.getConnections().
  • Unified Element Model: ProcessElementInterface is the common supertype for equipment, controllers, and measurement devices. Query all elements with process.getAllElements(). This enables DEXPI export, topology analysis, and flowsheet introspection.
  • Streams & Cloning: Instantiate feeds with Stream/StreamInterface, call setFlowRate, setTemperature, setPressure, then run(); clone fluids (system.clone()) before branching to avoid shared state between trays or unit operations.
  • Distillation Column: DistillationColumn provides sequential, damped, and inside-out solvers; maintain solver metrics (lastIterationCount, lastMassResidual, lastEnergyResidual) and feed-tray bookkeeping when altering column logic to keep tests like insideOutSolverMatchesStandardOnDeethanizerCase green.
  • ProcessSystem Utilities: Use ProcessSystem.add(unit) to build flowsheets, run()/run(UUID) for execution, copy() when duplicating equipment, connect() for explicit connections, and getAllElements() to query all equipment, controllers, and measurements; modules can self-initialize through ModuleInterface - respect these hooks if you add packaged subsystems.
  • ProcessModel for Multi-Area Plants (MANDATORY): For large plants (platforms, gas plants), split into separate ProcessSystem objects per process area then combine with ProcessModel. Use plant.add("area name", processSystem) to register named areas, plant.run() iterates until convergence, plant.get("area name") retrieves sub-processes, and plant.getConvergenceSummary() reports status. See the reference platform models for the canonical pattern: each area is a Python function returning a ProcessSystem, cross-system streams are shared by object reference, and all systems are composed into a ProcessModel at the end. NEVER add a ProcessModule or ProcessModel to a ProcessSystem - it will throw TypeError.
  • Self-configuring convergence (do NOT hand-pick numbers): plant.runUntilConverged(maxIterations) derives its own flow-noise filters (boundary flow floor, absolute flow tolerance, per-unit low-flow bypass) from the plant's own feed rate, and — when no tolerance was set — its own accuracy: DEFAULT_ENGINEERING_TOLERANCE (1e-3 relative on flow/T/P) instead of the historical 1e-4, plus acceptance of a residual that stops improving over AUTO_TOLERANCE_STALL_WINDOW (5) outer passes while below getAutoToleranceCeiling() (1e-2). Report with getAutoTuningSummary() / getAutoToleranceSummary() (also in getConvergenceSummary() and the autoTuning / autoTolerance blocks of getConvergenceReportJson()). Any explicit setTolerance() / per-variable setter / runUntilConverged(n, tol) marks the tolerance user-owned and disables both behaviours — so do not set 1e-3 "to be helpful". Opt out with setAutoTolerance(false) / setAutoConvergenceTuning(false).
  • Automation API (PREFERRED for agents): Use ProcessAutomation for string-addressable variable access instead of navigating Java class hierarchies. Get the facade via process.getAutomation() or plant.getAutomation()the same cached instance is returned on every call so diagnostics history, learned corrections, and the dirty flag persist across agent turns. Discover equipment with getUnitList(), list variables with getVariableList("unitName") (returns SimulationVariable with INPUT/OUTPUT type, address, unit, description), read values with getVariableValue("Unit.stream.property", "unit"), write with setVariableValue("Unit.property", value, "unit"). For multi-area models, use area-qualified addresses: "Area::Unit.stream.property" with getAreaList() for discovery.
  • Agentic Automation Extensions: ProcessAutomation now exposes batch and introspection methods that emit a stable JSON schema (SCHEMA_VERSION = "1.0"):
    • Batch I/O: getValues(addresses, unit) returns Map<String, Double> of successfully read values; setValues(updates, unit, runAfter) writes many inputs and optionally runs once.
    • Dirty tracking: isDirty(), runIfDirty(), and setVariableValueAndRun(address, value, unit) avoid redundant run() calls — the dirty flag flips on every successful write and clears after run().
    • Introspection: describe() returns the full unit/variable manifest as JSON; snapshot(scope) dumps variable values for a unit, area, or "*"; getTopology() lists equipment and ProcessConnection edges; getNeighbors(unit) returns immediate upstream/downstream units.
    • Structured reads: getStructured(address) returns a JsonElement — composition addresses (...composition, ...components, ...phaseFractions, ...kvalues) yield objects/arrays instead of crashing the scalar accessor.
    • Pre-flight validation: validateAddress(address) returns null for good addresses or a DiagnosticResult with the proper ErrorCategory (no exception thrown). getAllowedUnits(address) lists valid UOM strings.
    • Diagnostic taxonomy: setVariableValueSafe/getVariableValueSafe JSON responses include category-tagged errors for UNIT_NOT_FOUND, PROPERTY_NOT_FOUND, PORT_NOT_FOUND, READ_ONLY_VARIABLE, VALUE_OUT_OF_BOUNDS, UNKNOWN_UNIT, INVALID_ADDRESS_FORMAT, and CONVERGENCE_FAILURE.
    • Thread safety: AutomationDiagnostics uses a Collections.synchronizedList history and a ConcurrentHashMap of learned corrections so multiple agents may share a facade.
  • Closed-Loop Optimization — evaluate() (PREFERRED for agent loops): run() returns void, so the agentic run primitives are the key addition that makes a flowsheet an optimization target — each returns one schema-versioned JSON object and never throws. Use evaluate(setpoints, setpointUnit, readbacks, readbackUnit, maxIterations, tolerance) (and the convenience overload evaluate(setpoints, unit, readbacks)) as the atomic optimizer step: it applies a batch of setpoints, runs to convergence, gates feasibility, and reads back objectives in one call. Gate trials on the single feasible flag (true only when the run did not throw, the model converged, no unit failed, and every setpoint was accepted). Rejected setpoints land in setpointsRejected and bad read-backs in readbackErrors — both without throwing, so a malformed candidate degrades one trial instead of crashing the loop. Pass null as the unit for a mixed-unit batch (each variable uses its default unit: bara, K, kg/hr). Lower-level gated runs: runUntilConvergedJson(maxIter, tol) (multi-area embeds the nested convergence report + per-area areas), runJson() (single run with structured outcome), getRunStatusJson() (last status without re-running). All clear the dirty flag even on failure. Default tolerance 5e-3 is robust for plants with near-zero-flow anti-surge recycles. Through jpype wrap as json.loads(str(result)). Pair with getAdjustableParameters() for the bounded decision space.
  • Capacity Observation Snapshot — getUtilizationSnapshot() (the observation vector): evaluate() is the action+reward step; getUtilizationSnapshot() is the matching observation step. Both ProcessSystem and ProcessModel expose getUtilizationSnapshotJson(), and ProcessAutomation.getUtilizationSnapshot() delegates to whichever it wraps. The snapshot is side-effect-free (never calls run(), only reads already-computed CapacityConstraint utilization) so it is cheap to call every step. Per unit it reports name, type, maxUtilization (0–1, NaN→0), maxUtilizationPercent, limitingConstraint, feasible, hardLimitExceeded, power_kW (compressors/pumps), and a constraints[] breakdown; for a ProcessModel each unit also carries its area. Plant-wide it gives bottleneck (highest-utilization unit or null), anyOverloaded, anyHardLimitExceeded, schema "1.0". Closed-loop RL pattern: observation = getUtilizationSnapshot(), action = evaluate() setpoints, reward = an evaluate() read-back penalized when anyOverloaded or any maxUtilization > 1. Chartless compressors: surge/stonewall/speed constraints are present-but-disabled (their distance-to-surge is undefined and would otherwise pin utilization at a degenerate flat 100%), so such machines report smooth power-driven utilization — give the power constraint a basis via comp.getMechanicalDesign().setMaxDesignPower(kW). Expanders: Expander overrides the inherited Compressor capacity logic so it no longer reports a spurious ~150% — the consumed-power constraints (power, ratedPower) are removed, isSimulationValid() is expander-correct (negative shaft power / cooler outlet are valid), and expander.setRatedRecoveredPower(kW) adds a recoveredPower HARD constraint. Provenance: each constraint in the snapshot now carries its dataSource (e.g. "equipment", "design") so an agent can tell a rated limit from an estimate.
  • AgenticProcessOptimizer (ML/agentic optimization): auto.newOptimizer() returns an AgenticProcessOptimizer — a ready-made closed-loop search built on evaluate() and designed for ML/agentic loops. It works in string addresses, a never-throwing schema-versioned JSON contract, and a replayable trajectory, so an agent can build a problem straight from getAdjustableParametersJson(). Algorithm: bounded Nelder–Mead simplex with deterministic (seeded) random init (same seed + same problem ⇒ identical trajectory). Decision space: addVariable(addr, lo, hi, unit) or useAdjustableParameters(). Objective: minimize/maximize/setObjective(addr, Sense, unit) or setObjectiveFunction(Function<Map<String,Double>,Double>) for custom reward shaping over decisions+constraint readbacks+watches (addWatch). Constraints: addConstraintLessOrEqual/addConstraintGreaterOrEqual/addConstraint(addr, type, limit, unit, penaltyWeight) folded in as weighted quadratic penalties. Each trial sets the decision variables, runs one gated evaluate(), then reads the objective/constraints — a malformed candidate degrades one trial, and optimize()/optimizeToJson() never throw. Every point is logged as a Trial (setpoints, readbacks, objective, penalty, feasibility, score) — the (state, action, reward) tape for offline RL. Call getReadinessJson() for a machine-readable self-rating (never_throws/deterministic/bounded_action_space/json_io/reward_shaping/constraint_handling/trajectory_logging/feasibility_gating = full; gradient_based = none; global_optimum_guarantee = partial; parallel_evaluation = none). Tuning: setMaxEvaluations, setInnerConvergence(maxIter, tol), setConvergenceTolerance, setSeed. Distinct from the classic neqsim.process.util.optimizer classes (which take a Function<double[],Double> over an opaque ProcessSystem).
  • Capacity / throughput / quality / batch helpers on ProcessAutomation (both ProcessSystem and ProcessModel): string-addressable, never-throwing, schema-versioned JSON helpers that close the loop for maximise-production studies. enableCapacityConstraints() enables capacity constraints on every CapacityConstrainedEquipment (separators, pumps, valves, pipelines, heaters/coolers, heat exchangers, manifolds) so any type can bind as the bottleneck — it recreates compressor constraints via reinitializeCapacityConstraints() (surge/speed stay disabled when chartless, power stays enabled) rather than the blind enableAllConstraints(), and adds the separator Souders-Brown gas-load constraint; set each type's design basis first. findMaxThroughputJson(feedAddresses, min, max, unit, utilizationLimit) enables the constraints then bisects the total feed rate (feeds scaled proportionally) until the first unit reaches utilizationLimit, leaving the model at the feasible max and returning {maxRate, feasibleAtMin, bindingUnit, bindingConstraint, bindingUtilizationPercent}. getProductQualityJson(address[, refTempC]) returns export-oil RVP/TVP (Standard_ASTM_D6377) and gas cricondenbar_bara/cricondentherm_K (calcPTphaseEnvelope) on a cloned fluid (never throws; rvpError/envelopeError on failure) — the spec side of a maximise-throughput-subject-to-RVP/cricondenbar search. Routing / feed-scale decision variables: feed flowRate is a writable INPUT; splitters expose one bounded splitFactor_i (0–1) INPUT per outlet in getAdjustableParameters() (read = current fraction; write = branch weight, renormalised to sum 1) so AgenticProcessOptimizer.useAdjustableParameters() picks them up automatically. evaluateBatchJson(candidates, unit, readbacks, maxParallel) scores a list of setpoint maps in one call — for a ProcessSystem with maxParallel>1 each candidate runs on an independent ProcessSystem.copy() on its own thread (genuinely parallel, live model untouched), for a ProcessModel (no copy()) or maxParallel==1 it runs sequentially; each result carries the full evaluate payload (incl. converged/iterations/maxError/failedUnitName/failedUnitError) + index, root reports parallel/feasibleCount/firstFeasibleIndex. Production + emissions: compose decision space (bounded setpoints + splitter routing + bounded feed scale) + feasibility (enableCapacityConstraints + snapshot) + a reward production − λ·Σ(compressor power) (compression power = CO2 proxy) via setObjectiveFunction, or ProductionOptimizer.optimizePareto [MAX production, MIN Σ power].
  • Self-Healing Automation (PREFERRED for agents): Use getVariableValueSafe() and setVariableValueSafe() instead of direct get/set. These return JSON with the value on success, or diagnostics with suggestions, auto-corrections, and remediation hints on failure. Access auto.getDiagnostics() for fuzzy name matching (autoCorrectName()), physical bounds validation (validatePhysicalBounds()), and operation tracking (getLearningReport()). The AutomationDiagnostics class learns from past failures - corrections are cached and reused automatically.
  • Lifecycle State (Save/Restore/Compare): Use ProcessSystemState.fromProcessSystem(process) and ProcessModelState.fromProcessModel(plant) to create portable JSON snapshots. Save with state.saveToFile("model.json"), load with ProcessSystemState.loadFromFile("model.json"), validate with state.validate(). Compare versions with ProcessModelState.compare(v1, v2) returning a ModelDiff (modified parameters, added/removed equipment). Use toCompressedBytes()/fromCompressedBytes() for network transfer. All state classes live in neqsim.process.processmodel.lifecycle.
  • Data & Resources: Component metadata lives under src/main/resources; heavy datasets (e.g., neqsim_component_names.txt) must remain synchronized with thermodynamic model expectations before publishing new components.
  • Logging & Diagnostics (MANDATORY): log4j2 powers runtime logging, and all Java logging/output must use a logger (org.apache.logging.log4j.Logger). NEVER introduce System.out.println or System.err.println in Java code (including tests, examples, and generated snippets). Use parameterized logger calls such as logger.info("message {}", value).
  • Build & Test Workflow: Use ./mvnw install for a full build (Windows: mvnw.cmd install); run the entire suite with ./mvnw test and checkstyle/spotbugs/pmd with ./mvnw checkstyle:check spotbugs:check pmd:check.
  • Focused Tests: Use the Maven -Dtest flag to run individual classes or methods; this keeps solver regressions quick to triage.
  • Style & Formatting: Java code follows Google style with project overrides from .config/checkstyle_neqsim.xml and formatter profiles (.config/neqsim_formatter.xml); keep indentation at two spaces and respect existing comment minimalism.
  • Code Formatting (Spotless) - MANDATORY: AI-generated Java is NOT auto-formatted. After creating or editing ANY .java file, run ./mvnw spotless:apply (Windows: mvnw.cmd spotless:apply) to reformat to the project style, then git add the changes before committing. CI runs ./mvnw spotless:check and FAILS the build on any unformatted file. Do not rely on local pre-commit hooks being installed, and NEVER bypass the gate with git commit --no-verify.
  • Serialization & Copying: Many equipment classes rely on Java serialization (ProcessEquipmentBaseClass.copy()); avoid introducing non-serializable fields or mark them transient to preserve cloning. SpotBugs enforces this via the SE_BAD_FIELD rule. When adding fields to any Serializable class (equipment, measurement devices, mechanical design, thermo phases), use the correct modifier order: private transient Type field; or private final transient Type field;. Common non-serializable types that need transient: Function, BiConsumer, Consumer, Thread, JDBC Connection/Statement, Apache Commons Math interpolators, and any inner class that doesn't implement Serializable. The ProcessLogic interface extends Serializable.
  • External Dependencies: Core math depends on EJML, Commons Math, JAMA, and MTJ; check numerical stability when swapping linear algebra routines, and keep JSON/YAML handling aligned with gson/jackson versions pinned in pom.xml.
  • Java 8 Compatibility (MANDATORY): See the critical section at the top of this document. All code MUST compile with Java 8. The CI build will FAIL if you use Java 9+ features like String.repeat(), var, List.of(), etc.
  • Sample Flow:
SystemInterface gas = new SystemSrkEos(216.0, 30.0);
gas.addComponent("methane", 0.5);
gas.setMixingRule("classic");
Stream feed = new Stream("feed", gas);
feed.setFlowRate(100.0, "kg/hr");
feed.run();
DistillationColumn column = new DistillationColumn("Deethanizer", 5, true, false);
column.addFeedStream(feed, 5);
column.setSolverType(DistillationColumn.SolverType.INSIDE_OUT);
column.run();
  • Test Authoring Tips: Place new tests under the matching feature package (see docs/wiki/test-overview.md) and assert on physical outputs or solver residuals rather than internal arrays to keep tests resilient.
  • Regression Safety: When modifying solver logic or property correlations, capture baseline values in tests and drop CSV/JSON fixtures into src/test/resources instead of hardcoding magic numbers in code.
  • Documentation Touchpoints: Update README sections or docs/wiki entries when adding new models; the docs mirror the package layout and help downstream consumers understand new unit operations.
  • Community Norms: Engage on GitHub issues or discussions for design questions; NeqSim has an active user base familiar with thermodynamics and process simulation who can provide valuable insights.
  • Performance Considerations: Profile long-running simulations with Java Flight Recorder or VisualVM; optimize critical loops in thermodynamic calculations but prioritize clarity and maintainability in the codebase.
  • JavaDoc Standards (MANDATORY): ALWAYS document ALL classes and methods (public, protected, AND private) with complete JavaDoc. The Maven JavaDoc plugin checks all methods. Required elements: (1) class-level description with @author and @version, (2) method description, (3) @param for EVERY parameter with type and valid range, (4) @return describing what is returned (for non-void methods), (5) @throws for each exception. Before completing any code change, verify JavaDoc is complete and accurate. Update JavaDoc when modifying method signatures. Private methods also require complete JavaDoc with all @param and @return tags.

JavaDoc HTML5 Compatibility (MANDATORY)

When writing JavaDoc, ensure HTML5 compatibility for the Maven JavaDoc plugin:

Tables

  • ALWAYS include <caption> element after <table> tag
  • NEVER use the summary attribute (deprecated in HTML5)
  • Correct format:
/**
 * <table>
 * <caption>Description of table contents</caption>
 * <tr><th>Header</th></tr>
 * <tr><td>Data</td></tr>
 * </table>
 */

@see Tags

  • NEVER use @see with plain text like @see IEC 61508 - this causes "reference not found" errors
  • Only use @see with valid Java references: @see ClassName, @see #methodName, @see package.ClassName#method
  • For standards references, put them in the description text instead:
/**
 * Implements safety functions per IEC 61508 and IEC 61511 standards.
 */

Common JavaDoc Errors to Avoid

ErrorCauseFix
"no summary or caption for table"Missing <caption>Add <caption> after <table>
"attribute not supported in HTML5: summary"Using summary="" on tableRemove summary attribute
"reference not found"Invalid @see referenceUse valid class/method reference or move to description
"no @param for X"Missing parameter documentationAdd @param X description
"no @return"Missing return documentationAdd @return description
"no @throws for X"Method throws exception without docAdd @throws X description
"unexpected end tag"Mismatched HTML tags like extra </p>Check tag nesting, remove orphan closing tags
"semicolon missing"Malformed HTML in JavaDocCheck HTML tag closure
"bad use of '>'"Lambda arrow -> or comparison > in JavaDocUse &gt; for > or rewrite lambdas as anonymous classes

Methods with throws Clause (CRITICAL)

  • EVERY method with a throws clause MUST have @throws documentation for each exception
  • This applies to ALL methods including private methods
  • Format:
/**
 * Writes data to the output.
 *
 * @param out the appendable to write to
 * @param data the data to write
 * @throws IOException if an I/O error occurs during writing
 */
private void writeData(Appendable out, String data) throws IOException {

HTML Tag Nesting

  • NEVER have orphan closing tags (e.g., </p> without matching <p>)
  • Check that <ul> lists end with </ul>, not </p>
  • Common mistake: ending a list with </ul></p> when there's no opening <p> after the list
  • Wrong:
/**
 * <ul>
 * <li>Item one</li>
 * </ul>
 * </p>
 */
  • Correct:
/**
 * <ul>
 * <li>Item one</li>
 * </ul>
 */

Lambda Expressions in JavaDoc Examples

  • NEVER use lambda arrow syntax (->) in JavaDoc code examples - it causes HTML parsing errors
  • Instead, use anonymous inner class syntax or escape the arrow
  • Wrong: list.forEach(item -> doSomething(item));
  • Correct: list.forEach(new Consumer() { public void accept(Object item) { ... } });
  • For comparisons, use &gt; entity: if (value &gt; threshold)

Verification

Before committing, run ./mvnw javadoc:javadoc to catch JavaDoc errors early.

  • Java 8 Features: All new code must be Java 8 compatible; use streams, lambdas, and Optional where they enhance readability. NEVER use String.repeat() - use StringUtils.repeat() from Apache Commons. NEVER use var, List.of(), Map.of(), text blocks, or any Java 9+ syntax. See the critical Java 8 Compatibility section at the top of this document for complete list.
  • Validation Framework: Use SimulationValidator.validate(object) before running simulations to catch configuration errors early. When extending equipment, override validateSetup() to add custom validation. See neqsim.util.validation package and docs/integration/ai_validation_framework.md.
  • AI-Friendly Error Handling: Exceptions in neqsim.util.exception provide getRemediation() hints. When adding new errors, include actionable fix suggestions that AI agents can parse.
  • Troubleshooting: When simulations fail (flash non-convergence, zero properties, recycle divergence), consult the neqsim-troubleshooting skill for ranked recovery strategies before retrying blindly.
  • Input Validation: Before creating NeqSim objects, validate inputs using the neqsim-input-validation skill - catches physically impossible temperatures, pressures, compositions, and wrong component names.
  • Regression Baselines: When modifying solver logic or property correlations, capture baseline values FIRST using the neqsim-regression-baselines skill. This prevents silent accuracy drift.
  • Standards Lookup: For any engineering task, identify applicable industry standards using the neqsim-standards-lookup skill. It maps equipment types to standards (API, NORSOK, DNV, ISO, ASME), provides CSV database query patterns, and defines the standards_applied schema for results.json. Standards compliance is mandatory for all task scales.
  • Plant Data Integration: When connecting NeqSim models to plant historian data (OSIsoft PI, Aspen IP.21), use the neqsim-plant-data skill for tagreader API patterns, tag mapping, digital twin loops, and data quality handling. See also the @plant.data agent.
  • Model Calibration and Data Reconciliation: When reducing model-vs-plant mismatch, tuning parameters with bounded optimization, reconciling noisy measurements, or producing train/validation fit reports, use the neqsim-model-calibration-and-data-reconciliation skill.
  • API Changelog: Check CHANGELOG_AGENT_NOTES.md in the repo root for recent API changes, new classes, deprecated methods, and known method name corrections.
  • Capability Assessment: Before starting complex engineering tasks, use the @capability.scout agent or the neqsim-capability-map skill to identify what NeqSim can do, find gaps, and plan implementations. The result MUST be saved to step1_scope_and_research/capability_assessment.md (mandatory artifact for Standard/Comprehensive tasks).
  • Skill Discovery: Run python devtools/skill_search.py "<task title>" --top 5 at the start of any task to surface the most relevant skills via TF-IDF over the SKILL.md description fields. Prefer this over manual lookup in skill-index.json (which is now a curated short-list, not exhaustive).
  • Agent Discovery: Run python devtools/agent_search.py "<task title>" --top 8 --json --out step1_scope_and_research/agent_plan.json to rank the best specialist agents across all repos (neqsim + community + enterprise) — the search output lists the skills each agent loads. Record the chosen agents and the composition/workflow in capability_assessment.md §4b/§4c and mirror it into results.json agent_workflow_plan. Prefer delegating to a specialist agent (so its governance and internal workflow are reused) over re-loading its skills manually. For tasks spanning ≥3 disciplines, compose a declarative workflow via MCP composeWorkflow/composeMultiServerWorkflow or an engineering-harness study instead of a single agent.
  • Literature & Document Pull: Use @literature.scout to fetch papers, standards, and internal STID/vendor docs into step1_scope_and_research/references/. The agent writes references/manifest.json and summarises sources into notes.md.
  • Pre-PR Quality Gate: Before opening a PR for a task, invoke @review <task folder> (read-only). It wraps validate_task_results.py, consistency_checker.py, capability-assessment presence, figure→discussion traceability, and repo-memory hits, returning a PASS/WARN/FAIL grade.
  • Skills/Agents CI Lint: .github/workflows/skills_agents_lint.yml runs devtools/verify_skills_agents.py (front-matter + skill-index reference check) and devtools/generate_agent_skill_map.py (auto-generates docs/development/AGENT_SKILL_MAP.md) on every PR touching .github/skills/ or .github/agents/. The map is rebuilt from Loaded skills: lines in agent files; CI fails if the committed map is stale.
  • Flow Assurance: For hydrate, wax, asphaltene, corrosion, or pipeline hydraulics analyses, use the neqsim-flow-assurance skill for comprehensive patterns covering all flow assurance threats with NeqSim code patterns. Rigorous CO2 corrosion from a brine uses NorsokM506ElectrolyteBridge (electrolyte pH + FeCO3 film); per-segment corrosion+scale profiles use PipeSegmentIntegrity; mineral scale uses ElectrolyteScaleCalculator / ScaleKinetics / BrineMixingScaleEvaluator. See also the @flow.assurance agent.
  • Water/Liquid Hammer: For fast valve closure, ESD, pump trip, check-valve slam, hydraulic surge, or STID/tagreader-based surge screening, use the neqsim-water-hammer skill. Prefer WaterHammerStudy and MCP runWaterHammer for complete workflows that combine route geometry, field-data overrides, event schedules, pressure envelopes, and design-pressure validation.
  • CCS and Hydrogen: For CO2 capture/transport/storage or hydrogen systems (blending, electrolysis, blue/green H2), use the neqsim-ccs-hydrogen skill for CO2 phase behavior, impurity management, injection well analysis, and H2 pipeline design. See also the @ccs.hydrogen agent.
  • Power Generation: For gas turbines, steam turbines, HRSG, or combined cycle systems, use the neqsim-power-generation skill for equipment patterns and efficiency calculations.
  • Platform Process Modeling: For building full topside process models of oil & gas platforms (FPSO, fixed, semi-sub) from design documents or operational data, use the neqsim-platform-modeling skill. Covers multi-stage separation with oil recycles, recompression trains with compressor curves and anti-surge, export/injection compression, scrubber liquid recovery, Cv-based valve flow, iteration strategies, and structured result extraction. Derived from 15+ production NCS platform models.
  • Technical Document and Image Reading: For extracting data from PDFs, Word docs, Excel files, and engineering images (P&IDs, mechanical drawings, vendor API datasheets, compressor maps, phase envelopes), use the neqsim-technical-document-reading skill. Use devtools/pdf_to_figures.py to convert PDF pages to PNG images, then view_image for multimodal analysis of engineering drawings. See also the @read technical documents agent. The skill includes structured extraction patterns for P&ID topology (equipment/valve/instrument tags, piping), vendor datasheet operating conditions, mechanical arrangement dimensions, material certificates, trapped-liquid rupture evidence packs, and performance map digitization.
  • Vendor Document Retrieval: For retrieving vendor documents (compressor curves, mechanical drawings, data sheets) for engineering tasks, use the neqsim-stid-retriever skill. Supports local directories, manual upload to references/, and pluggable retrieval backends (configured via gitignored devtools/doc_retrieval_config.yaml). Documents are classified by type, filtered by relevance to the task, and fed into the neqsim-technical-document-reading pipeline for data extraction.
  • Trapped-Liquid Fire Rupture Studies: For blocked-in liquid, trapped liquid, thermal expansion rupture, no relief, flange/pipe rupture under fire, or PFP-demand studies, use the neqsim-trapped-liquid-fire-rupture skill. Retrieve P&IDs/STIDs, line lists, piping specs, material certificates, flange/bolt/gasket data, fire-zone/PFP documents, relief basis, and acceptance criteria before running neqsim.process.safety.rupture calculations. Report missing final-design evidence explicitly in results.json assumptions/gaps.
  • Auto-Validation for New Equipment: When creating a new class that extends ProcessEquipmentBaseClass, ALWAYS generate a validateSetup() method that checks: (1) required input streams are connected, (2) required parameters are set and within valid ranges, (3) return ValidationResult with remediation hints for each issue.
  • Equipment Design Feasibility Reports: After running compressors or heat exchangers in a process simulation, use the Design Feasibility Report classes to assess if equipment is realistic to build and operate. CompressorDesignFeasibilityReport (API 617 + cost + 15 OEM suppliers + curve generation) and HeatExchangerDesignFeasibilityReport (TEMA/ASME + cost + 14 HX suppliers) produce FEASIBLE / FEASIBLE_WITH_WARNINGS / NOT_FEASIBLE verdicts and comprehensive JSON reports. See neqsim-api-patterns skill for usage patterns.
  • Auto-Annotation for Public Methods: When adding new public methods to core classes (SystemInterface, ProcessEquipmentInterface), consider adding @AIExposable annotation with description, category, example, and @AIParameter annotations documenting valid ranges/options.
  • Jupyter Notebook Examples: When creating Jupyter notebook examples, ensure they run end-to-end and reflect the latest API changes; place them in the notebooks/ directory and link to them from the main documentation. Follow the neqsim-python direct Java API bindings as shown at https://github.com/equinor/neqsim-python?tab=readme-ov-file#4-direct-java-access-full-control
  • Add markdown files with documentation: When adding documentation as markdown files:
    1. Update REFERENCE_MANUAL_INDEX.md with the new file entry
    2. Update the relevant section's index.md (e.g., docs/examples/index.md)
    3. Verify ALL links to other docs using file_search before adding them
    4. See "Documentation Links (MANDATORY)" section below for link guidelines

Markdown Documentation Guidelines (MANDATORY)

Jekyll Front Matter (REQUIRED for Search)

ALL markdown documentation files in docs/ MUST have Jekyll YAML front matter at the very beginning of the file for proper search indexing. Without front matter, files may not appear in search results with proper titles.

Required format:

---
title: Your Document Title
description: A concise description (1-2 sentences) of what the document covers. Include key terms users might search for.
---

Example for a thermodynamics guide:

---
title: Reading Fluid Properties in NeqSim
description: Comprehensive guide to calculating and reading thermodynamic and physical properties from fluids, phases, and components. Covers init levels, TPflash, density, enthalpy, viscosity, units, volume translation, and JSON reports.
---

Rules:

  1. Front matter MUST be the first thing in the file (before any content)
  2. Use three dashes --- to delimit the YAML block
  3. title should be descriptive but concise (appears in search results)
  4. description should include searchable keywords relevant to the content
  5. Do NOT duplicate the title as an H1 heading immediately after front matter (Jekyll handles this)
  6. CRITICAL: Quote values containing colons - In YAML, colons have special meaning. If your title or description contains a colon (:), wrap the entire value in double quotes:
    # WRONG - causes YAML parse error:
    title: PVT Workflow: From Lab Data to Model
    description: This guide covers: setup, configuration, and testing.
    
    # CORRECT - quoted values:
    title: "PVT Workflow: From Lab Data to Model"
    description: "This guide covers: setup, configuration, and testing."
    
  7. Avoid trailing colons - Don't end descriptions with a colon (e.g., description: "Features include:") - complete the sentence instead

Files that already have front matter: Check if they have both title and description. If missing description, add it.

When creating or editing markdown documentation files:

HTML and Markdown Mixing Rules

NEVER mix markdown syntax inside HTML block elements. Many markdown parsers don't process markdown inside <div> tags.

Problematic PatternWhy It FailsSolution
<div> containing markdown tables (|---|)Parser ignores markdown inside HTML blocksUse pure markdown OR pure HTML
<div> containing numbered lists (1. Item)Lists don't render as listsRemove div wrapper or use <ol><li>
<div> containing bullet lists (- Item)Lists don't render as listsRemove div wrapper or use <ul><li>

Correct Patterns

For styled content boxes, choose ONE approach:

  1. Pure Markdown (preferred for tables/lists):

    ### Section Title
    
    **Heading text:**
    
    | Column 1 | Column 2 |
    |----------|----------|
    | Data     | Data     |
    
    > *Note: Use blockquotes for callouts*
    
  2. Pure HTML (for complex styling):

    <div style="background: #e8f5e9; padding: 1rem;">
    <h4>Title</h4>
    <ul>
    <li>Item one</li>
    <li>Item two</li>
    </ul>
    </div>
    

Table Formatting

  • Always include a blank line before and after tables
  • Use consistent column separator widths: |----------| not |---|
  • Ensure header separator row has same column count as data rows

List Formatting

  • Always include a blank line before numbered/bullet lists
  • For nested content after bold headers, add a blank line:
    **Suggested Approach:**
    
    1. **Step one:** Description here
    2. **Step two:** Description here
    

LaTeX Math Equations (MANDATORY for KaTeX Rendering)

The documentation site uses KaTeX for math rendering. Use the correct delimiters to ensure equations render properly.

Display Math (Block Equations)

USE $$...$$ for display/block equations:

The cubic equation of state:

$$
P = \frac{RT}{v - b} - \frac{a(T)}{(v + \epsilon b)(v + \sigma b)}
$$

Where $P$ is pressure and $T$ is temperature.

NEVER use \[...\] - these delimiters are often stripped by markdown processors and render as plain text like [ P = \frac{RT}{v-b} ].

Inline Math

USE $...$ for inline math:

The acentric factor $\omega$ affects the alpha function $\alpha(T_r, \omega)$.

NEVER use \(...\) - these are less reliably rendered.

Common LaTeX Mistakes to Avoid

WrongCorrectIssue
\[ P = \frac{RT}{v-b} \]$$ P = \frac{RT}{v-b} $$\[...\] stripped by parser
\(T_r\)$T_r$\(...\) less reliable
$$ P = ... $$ where$$ P = ... $$ + newline + whereNo text on same line as $$
Equation inside <div>Move equation outside HTML blockMarkdown not processed in HTML

Verification

After adding equations, preview locally or check that:

  1. Display equations appear centered on their own line
  2. Inline math renders within the text flow
  3. No raw LaTeX syntax (backslashes, braces) appears in rendered output

Documentation Links (MANDATORY)

When adding links to other documentation files, follow these rules to prevent broken links:

Link Verification Rules

  1. ALWAYS verify target files exist before adding links:

    • Use file_search to confirm the file exists in the repository
    • Check the exact path and filename (case-sensitive on some systems)
  2. Use correct relative paths based on the source file location:

    • From docs/fielddevelopment/ to docs/process/: use ../process/filename.md
    • From docs/examples/ to docs/tutorials/: use ../tutorials/filename.md
    • Within same folder: use just filename.md
  3. Prefer existing documentation over creating placeholder links:

    • If a linked file doesn't exist, either create it OR link to an existing alternative
    • NEVER add links to files that don't exist

Common Documentation Paths

Documentation AreaPathExample Files
Process equipmentdocs/process/separators.md, compressors.md, heat-exchangers.md
Field developmentdocs/fielddevelopment/pressure_boundary_optimization.md, CAPACITY_CONSTRAINT_FRAMEWORK.md
Thermodynamicsdocs/thermo/equations-of-state.md, flash-calculations.md
Examplesdocs/examples/*.ipynb, *.java, index.md
Tutorialsdocs/tutorials/Getting started guides
Troubleshootingdocs/troubleshooting/Common issues and solutions

When Adding New Documentation

  1. Update index files when creating new documentation:

    • Add entry to docs/REFERENCE_MANUAL_INDEX.md (master index of 360+ files)
    • Add entry to the relevant section's index.md (e.g., docs/examples/index.md)
  2. Cross-reference related docs with verified links:

    ## Related Documentation
    
    - [Pressure Boundary Optimization](pressure_boundary_optimization.md)
    - [Capacity Constraint Framework](CAPACITY_CONSTRAINT_FRAMEWORK.md)
    
  3. For Jupyter notebooks, also add to:

    • docs/examples/index.md - Examples index
    • docs/REFERENCE_MANUAL_INDEX.md - Master reference

Link Format Examples

<!-- Same directory -->
[Related Topic](related-topic.md)

<!-- Parent directory -->
[Process Overview](../process/index.md)

<!-- Sibling directory -->
[Tutorial](../tutorials/getting-started.md)

<!-- Link to specific section -->
[VFP Tables](pressure_boundary_optimization.md#vfp-generation)

<!-- Link to Java example -->
[Java Example](MultiScenarioVFPExample.java)

<!-- Link to notebook -->
[Notebook Tutorial](ProductionSystem_BottleneckAnalysis.ipynb)

Broken Link Prevention Checklist

Before finalizing documentation with links:

  • All linked .md files exist (use file_search("**/filename.md"))
  • All linked .ipynb notebooks exist
  • All linked .java examples exist
  • Relative paths are correct for source file location
  • Index files updated for new documentation
  • No links to planned-but-not-created files

Mechanical Design & Well Design (MANDATORY)

Full patterns are in skills - load them before implementing:

  • neqsim-api-patterns - Equipment design feasibility reports, separator mechanical design, cost estimation
  • neqsim-subsea-and-wells - Well casing design (API 5C3), SURF cost, barrier verification (NORSOK D-010)
  • neqsim-standards-lookup - Industry standards mapping (ASME, API, DNV, ISO, NORSOK)

Architecture: MechanicalDesign class + DataSource class + Calculator class + JSON reporting. Physical dimensions and internals are configured through SeparatorMechanicalDesign, NOT directly on Separator. See AGENTS.md "Separator MechanicalDesign Architecture" and "Well Mechanical Design" sections for details.

  • Location: designdata/MaterialPipeProperties.csv, designdata/MaterialPlateProperties.csv, etc.

  • Required columns: MaterialGrade, SMYS_psi, SMTS_psi, Density_kg_m3, Standard

  • TechnicalRequirements_Process.csv: Equipment-specific design parameters by company

    • Required columns: Company, EquipmentType, ParameterName, Value, Unit, Standard
  • TechnicalRequirements_Piping.csv: Piping code-specific design values

    • Required columns: Code, ParameterName, Value, Unit, Description
  • Standards Tables (in designdata/standards/ subdirectory):

    • api_standards.csv - API standard parameters
    • asme_standards.csv - ASME code requirements
    • dnv_iso_en_standards.csv - DNV/ISO/EN requirements
    • norsok_standards.csv - NORSOK requirements
    • standards_index.csv - Index mapping equipment types to applicable standards

Jupyter Notebook Creation Guidelines

Full patterns are in the neqsim-notebook-patterns skill. Load it before creating notebooks.

Key rules (always apply):

  • Use devtools/neqsim_dev_setup.py for task notebooks and runner workflows: call neqsim_init(project_root=PROJECT_ROOT, ...), then use classes through ns.* or ns.JClass(...). Do not use from neqsim import jneqsim in repository task notebooks because it can load a stale installed package.
  • Temperature in Kelvin, pressure in bara by default in Java API
  • Always set mixing rule: fluid.setMixingRule("classic")
  • Call fluid.initProperties() after flash before reading transport properties
  • Every notebook MUST be executed — use NeqSim Runner by default for task notebooks; unexecuted notebooks are incomplete
  • Include 2-3 matplotlib figures with axis labels, units, titles, legends, grids
  • Save results to results.json in the task folder

See AGENTS.md "Jupyter Notebook Creation Guidelines" section for common class import paths and the full getting-results reference.

Task-Solving Workflow (MANDATORY)

Full workflow is in docs/development/TASK_SOLVING_GUIDE.md. Read it before starting any task. Past solved tasks are indexed in docs/development/TASK_LOG.md — search before starting from scratch.

Key rules (always apply):

  1. Create task folder FIRST: neqsim new-task "title" --type X --author "Name"
  2. All output goes to task_solve/YYYY-MM-DD_slug/ — never to examples/, docs/, or workspace root
  3. All downloaded documents go inside the task folder at step1_scope_and_research/references/, filed into per-source subfolders (stid/, pepr/, tr2000/, maintenance/, servicenow/, tagreader/, seeq/, rigga/, vendor/, lab/, literature/, web/, manual/). Run python devtools/generate_sources_md.py task_solve/YYYY-MM-DD_slug --organize to file loose docs and (re)build the distributable references/SOURCES.md + references/collection_manifest.json so the whole task folder can be handed to others.
  4. Follow the 3-step workflow: Scope & ResearchAnalysis & EvaluationReport
  5. Benchmark validation (MANDATORY): Compare NeqSim results against independent reference data
  6. Uncertainty analysis: Monte Carlo with P10/P50/P90 + tornado diagram (MANDATORY for Standard/Comprehensive tasks with economics or reserves; optional for Quick tasks)
  7. Risk evaluation: Risk register with ISO 31000 5×5 matrix (MANDATORY for Standard/Comprehensive tasks; optional for Quick tasks)
  8. Consistency check: Run python devtools/consistency_checker.py before generating reports
  9. After completing: Add entry to docs/development/TASK_LOG.md

Task Log Entry Format

Privacy rule: Task log entries are public/reusable memory. Do not include company/operator names, field/facility/asset names, equipment tag numbers, internal document names, private system names, access diagnostics, or task folder slugs containing those details. Use generic descriptors and private task folder (redacted) for confidential task outputs.

### YYYY-MM-DD — Short task title
**Type:** A (Property) | B (Process) | C (PVT) | D (Standards) | E (Feature) | F (Design) | G (Workflow) | G (Workflow)
**Keywords:** comma, separated, search, terms
**Solution:** path/to/test/or/notebook
**Notes:** Key decisions, gotchas, or results

Repository README

Describes equinor/neqsim as a whole, which may contain artifacts other than this one. Where this artifact had no useful description of its own, its summary was taken from here.


What is NeqSim?

NeqSim (Non-Equilibrium Simulator) is a comprehensive Java library for fluid property estimation, process simulation, and engineering design. It covers the full process engineering workflow, from thermodynamic modeling and PVT analysis through equipment sizing, pipeline flow, safety studies, and field development economics.

Developed at NTNU and maintained by Equinor, NeqSim is used for real-world oil & gas, carbon capture, hydrogen, and energy applications.

Use it from Java, Python, Jupyter notebooks, .NET, MATLAB, or let an AI agent drive it via natural language.

Key capabilities

DomainWhat NeqSim provides
Thermodynamics60+ equation-of-state models (SRK, PR, CPA, GERG-2008, and more), flash calculations (TP, PH, PS, dew, bubble), phase envelopes
Physical propertiesDensity, viscosity, thermal conductivity, surface tension, diffusion coefficients
Process simulation33+ equipment types: separators, compressors, heat exchangers, valves, distillation columns, pumps, reactors
Pipeline & flowSteady-state and transient multiphase pipe flow (Beggs & Brill, two-fluid model), pipe networks
PVT simulationCME, CVD, differential liberation, separator tests, swelling tests, saturation pressure
SafetyDepressurization/blowdown, PSV sizing (API 520/521), source term generation, safety envelopes
StandardsISO 6976 (gas quality), NORSOK, DNV, API, ASME compliance checks
Mechanical designWall thickness, weight estimation, cost analysis for pipelines, vessels, wells (SURF)
Field developmentProduction forecasting, concept screening, NPV/IRR economics, Monte Carlo uncertainty

See the full documentation, Java Wiki, or ask questions in Discussions.

Quick Start

Python - try it in 30 seconds

A Python wrapper is available on pip. Install using pip install neqsim.

See neqsim-python for more details.

Java - add to your project

Maven Central (simplest - no authentication needed):

<dependency>
  <groupId>com.equinor.neqsim</groupId>
  <artifactId>neqsim</artifactId>
  <version>3.16.0</version>
</dependency>
import neqsim.thermo.system.SystemSrkEos;
import neqsim.thermodynamicoperations.ThermodynamicOperations;

SystemSrkEos fluid = new SystemSrkEos(273.15 + 25.0, 60.0);
fluid.addComponent("methane", 0.85);
fluid.addComponent("ethane", 0.10);
fluid.addComponent("propane", 0.05);
fluid.setMixingRule("classic");

ThermodynamicOperations ops = new ThermodynamicOperations(fluid);
ops.TPflash();
fluid.initProperties();

System.out.println("Density: " + fluid.getDensity("kg/m3") + " kg/m3");

AI agent - describe your problem in plain English

@solve.task hydrate formation temperature for wet gas at 100 bara

The agent scopes the task, builds a NeqSim simulation, validates results, and generates a Word + HTML report with no coding required.


What can you do with NeqSim?

from neqsim import jneqsim

fluid = jneqsim.thermo.system.SystemSrkEos(273.15 + 15.0, 100.0)
fluid.addComponent("methane", 0.90)
fluid.addComponent("CO2", 0.05)
fluid.addComponent("nitrogen", 0.05)
fluid.setMixingRule("classic")

ops = jneqsim.thermodynamicoperations.ThermodynamicOperations(fluid)
ops.TPflash()
fluid.initProperties()

print(f"Density:      {fluid.getDensity('kg/m3'):.2f} kg/m3")
print(f"Molar mass:   {fluid.getMolarMass('kg/mol'):.4f} kg/mol")
print(f"Phases:       {fluid.getNumberOfPhases()}")
from neqsim import jneqsim

fluid = jneqsim.thermo.system.SystemSrkEos(273.15 + 30.0, 80.0)
fluid.addComponent("methane", 0.80)
fluid.addComponent("ethane", 0.12)
fluid.addComponent("propane", 0.05)
fluid.addComponent("n-butane", 0.03)
fluid.setMixingRule("classic")

Stream = jneqsim.process.equipment.stream.Stream
Separator = jneqsim.process.equipment.separator.Separator
Compressor = jneqsim.process.equipment.compressor.Compressor
ProcessSystem = jneqsim.process.processmodel.ProcessSystem

feed = Stream("Feed", fluid)
feed.setFlowRate(50000.0, "kg/hr")

separator = Separator("HP Separator", feed)
compressor = Compressor("Export Compressor", separator.getGasOutStream())
compressor.setOutletPressure(150.0, "bara")

process = ProcessSystem()
process.add(feed)
process.add(separator)
process.add(compressor)
process.run()

print(f"Compressor power: {compressor.getPower('kW'):.0f} kW")
print(f"Gas out temp:     {compressor.getOutletStream().getTemperature() - 273.15:.1f} C")
from neqsim import jneqsim

fluid = jneqsim.thermo.system.SystemSrkEos(273.15 + 5.0, 80.0)
fluid.addComponent("methane", 0.90)
fluid.addComponent("ethane", 0.06)
fluid.addComponent("propane", 0.03)
fluid.addComponent("water", 0.01)
fluid.setMixingRule("classic")
fluid.setMultiPhaseCheck(True)

ops = jneqsim.thermodynamicoperations.ThermodynamicOperations(fluid)
ops.hydrateFormationTemperature()

print(f"Hydrate T: {fluid.getTemperature() - 273.15:.2f} C")
from neqsim import jneqsim

fluid = jneqsim.thermo.system.SystemSrkEos(273.15 + 40.0, 120.0)
fluid.addComponent("methane", 0.95)
fluid.addComponent("ethane", 0.05)
fluid.setMixingRule("classic")

Stream = jneqsim.process.equipment.stream.Stream
PipeBeggsAndBrills = jneqsim.process.equipment.pipeline.PipeBeggsAndBrills

feed = Stream("Inlet", fluid)
feed.setFlowRate(200000.0, "kg/hr")

pipe = PipeBeggsAndBrills("Export Pipeline", feed)
pipe.setPipeWallRoughness(5e-5)
pipe.setLength(50000.0)       # 50 km
pipe.setDiameter(0.508)        # 20 inch
pipe.setNumberOfIncrements(20)
pipe.run()

outlet = pipe.getOutletStream()
print(f"Outlet pressure: {outlet.getPressure():.1f} bara")
print(f"Outlet temp:     {outlet.getTemperature() - 273.15:.1f} C")

Explore 30+ Jupyter notebooks in examples/notebooks/:

  • Phase envelope calculation
  • TEG dehydration process
  • Vessel depressurization / blowdown
  • Heat exchanger thermal-hydraulic design
  • Production bottleneck analysis
  • Risk simulation and visualization
  • Data reconciliation and parameter estimation
  • Reservoir-to-export integrated workflows
  • Multiphase transient pipe flow

Agentic Engineering & MCP Server

LLMs reason well but hallucinate physics. NeqSim is exact on thermodynamics but needs context. Together, they form a complete engineering system. The LLM reasons. NeqSim computes. Provenance proves it.

MCP Server - give any LLM access to rigorous thermodynamics

The NeqSim MCP Server lets any MCP-compatible client (VS Code Copilot, Claude Desktop, Cursor, etc.) run real calculations. Install in seconds:

# Docker (no Java needed)
docker pull ghcr.io/equinor/neqsim-mcp-server:latest
Ask the LLMMCP Tool
"Dew point of 85% methane, 10% ethane, 5% propane at 50 bara?"runFlash
"How does density change from 0 to 50 C at 80 bara?"runBatch
"Phase envelope for this natural gas"getPhaseEnvelope
"Simulate gas through a separator then compressor to 120 bara"runProcess

Every response includes provenance metadata (EOS model, convergence, assumptions, limitations). See the MCP Server docs and setup guide.

AI task-solving workflow

@solve.task TEG dehydration sizing for 50 MMSCFD wet gas

The agent creates a task folder, runs NeqSim simulations, validates results, and generates a Word + HTML report with no coding required. See the tutorial or workflow reference.

Agents & skills — the extension ecosystem

Agentic NeqSim is built from two layers you can mix and extend:

  • Skills = the knowledge layer. Structured markdown that encodes domain expertise (API patterns, decision rules, reference data). Agents read skills to know how to do something correctly.
  • Agents = the workflow layer. A role + objective + the skills it loads. Agents drive NeqSim to complete a job (e.g. @solve.task, @field.development).

Content comes from four tiers — core (shipped in this repo under .github/skills and .github/agents, auto-loaded), community (public, installable), enterprise (company-private/internal), and local private (just you):

CatalogWhat it holdsWhere
Community agentsPublic AI agents for thermodynamics, process, flow assurance, energy & field developmentequinor/neqsim-community-agents
Community skillsPublic reusable engineering skills for agentic workflowsequinor/neqsim-community-skills
Enterprise agents / skillsInternal, company-private agents & skills governed in private repos (enterprise-agents.yaml / enterprise-skills.yaml) — kept separate from public contentPrivate company repos (see the enterprise guide)

Ecosystem at a glance — how the pieces relate:

graph TD
    CORE["NeqSim core<br/>Java engine + .github/skills + .github/agents<br/>(auto-loaded)"]
    MCP["MCP Server<br/>rigorous calculations for any LLM"]
    CAG["Community agents<br/>public workflows"]
    CSK["Community skills<br/>public knowledge"]
    EAG["Enterprise agents / skills<br/>internal, company-private"]
    PRIV["Local private<br/>~/.neqsim (just you)"]
    VSC["VS Code Copilot / Claude / Cursor / Codex"]

    CORE --> MCP
    CAG --> CSK
    EAG --> CSK
    CSK --> CORE
    CAG --> CORE
    EAG --> CORE
    PRIV --> CORE
    CORE -->|neqsim agent/skill install| VSC
    MCP --> VSC

Install and use them with the neqsim CLI (all user-scope, no admin — see the no-admin runbook):

neqsim agent list                 # browse the community catalog
neqsim agent search hydrate       # find an agent by keyword
neqsim agent install --all --vscode   # export agents+skills to ~/.copilot for VS Code Copilot
neqsim skill install --all        # install community skills

neqsim agent private-init         # scaffold a private/enterprise catalog
# ...or register a private repo AND sign in with browser SSO in one step:
neqsim agent private-init --repo my-org/neqsim-enterprise-agents --login
neqsim skill private-init --repo my-org/neqsim-enterprise-skills --login
  • How internal (enterprise) content works: a company publishes private enterprise-agents.yaml / enterprise-skills.yaml in governed internal repos. These are never committed to the public NeqSim repos; they are discovered per-user (via ~/.neqsim/private-*.yaml and gh-CLI / Git Credential Manager auth). private-init writes and then prints the path to those per-user files (~/.neqsim/private-agents.yaml / private-skills.yaml) so you can edit them afterwards. See Enterprise Agent & Skill Repositories.
  • Full details: the Skills & Agents Guide explains the four tiers, packaging, canonical installs vs tool exports, and how to author your own.

Where does a new skill or agent go? (recommendation for how to work)

Decide by coupling and confidentiality, not by "coding vs using":

If it…It belongs inWhy
Extends the engine, or is tied to specific NeqSim Java classes/signatures and must ship in the same PR as the codethis repo (.github/skills, .github/agents)versions in lockstep with the API; testable against real classes
Solves tasks with NeqSim but is engine-agnostic, screening-level, or just orchestrates existing capabilities (releases on its own cadence)community (skills / agents)public, reusable, no NeqSim internals
Uses internal knowledge, internal tools, company policy, or confidential thresholdsenterprise (private repos)never committed to public repos

One-line test: validated & API-coupled → this repo · educational screening → community · company policy or confidential → enterprise/private. See VISION_AGENTS.md and the Where Does This Go? guide for the full decision tree.


Use NeqSim in Java

<dependency>
  <groupId>com.equinor.neqsim</groupId>
  <artifactId>neqsim</artifactId>
  <version>3.16.0</version>
</dependency>

The Quick Start above shows the core pattern (create a fluid, run a flash, and read properties). For process simulation, add equipment to a ProcessSystem and call run(); see the Java Getting Started Guide for full examples.

Learn more: Java Getting Started Guide | JavaDoc | Wiki | Colab demo


Use NeqSim in Python

pip install neqsim

NeqSim Python gives you direct access to the full Java API via the jneqsim gateway. All Java classes are available, including thermodynamics, process equipment, PVT, standards, and more.

from neqsim import jneqsim

# All Java classes accessible through jneqsim
SystemSrkEos = jneqsim.thermo.system.SystemSrkEos
ProcessSystem = jneqsim.process.processmodel.ProcessSystem
Stream = jneqsim.process.equipment.stream.Stream
# ... 200+ classes available

Explore 30+ ready-to-run Jupyter notebooks in examples/notebooks/.

Other language bindings

LanguageRepository
Pythonpip install neqsim
MATLABequinor/neqsimmatlab
.NET (C#)equinor/neqsimcapeopen

Develop & Contribute

Clone and build

git clone https://github.com/equinor/neqsim.git
cd neqsim
./mvnw install        # Linux/macOS
mvnw.cmd install      # Windows

Windows: enable long paths before cloning. Maven's target/ directory can produce paths longer than the legacy 260-character limit, causing checkout or build errors. Enable long-path support once (user-scope, no admin required):

git config --global core.longpaths true

Also prefer cloning inside your user profile (e.g. C:\Users\<id>\Documents\GitHub\neqsim) rather than a short drive root, and avoid C:\Program Files (which needs elevated rights to write).

Restricted / corporate PC (no admin rights)

Everything below installs into your user profile and needs no administrator rights — the common situation on locked-down corporate PCs. Prerequisites (Git, Python, a JDK, VS Code) must already be provisioned per-user (e.g. via your software portal or winget --scope user).

# 0. One-time Git setting (user-scope, no admin)
git config --global core.longpaths true

# 1. Clone into your user profile
cd $HOME\Documents\GitHub
git clone https://github.com/equinor/neqsim.git
cd neqsim

# 2. Python devtools in a venv (keeps the 'neqsim' command on PATH)
py -3 -m venv .venv
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned   # per-process, no admin
.\.venv\Scripts\Activate.ps1
.\install.ps1
neqsim doctor          # verifies Python, Java/JDK, Maven wrapper, agents

# 3. Java build — needs a JDK. No admin? Let the installer fetch a PORTABLE JDK:
.\install.ps1 -InstallJdk       # downloads Temurin into ~/.neqsim\jdk, sets user env vars
# (or install a JDK manually and set JAVA_HOME yourself), then in a NEW terminal:
.\mvnw.cmd install -DskipTests

# 4. Install AI agents into ~/.copilot for VS Code Copilot (no admin)
neqsim agent install --all --vscode
neqsim skill install --all

Run tests

./mvnw test                                    # all tests
./mvnw test -Dtest=SeparatorTest               # single class
./mvnw test -Dtest=SeparatorTest#testTwoPhase  # single method
./mvnw checkstyle:check spotbugs:check pmd:check  # static analysis

Code formatting (Spotless)

Java formatting is enforced by Spotless. CI runs a check-only gate (it never edits or pushes your code), so format locally before pushing:

./mvnw spotless:apply     # auto-format all Java files
./mvnw spotless:check      # verify formatting — must exit 0 before pushing

Optionally, install local pre-commit hooks to format on commit and verify on push (requires a local JDK + Maven):

pip install pre-commit
pre-commit install --hook-type pre-commit --hook-type pre-push
pre-commit run --all-files   # run hooks manually across the repo

See CONTRIBUTING.md for details.

Open in VS Code

The repository includes a ready-to-use dev container; just open the repo in VS Code with container support:

git clone https://github.com/equinor/neqsim.git
cd neqsim
code .

Architecture

graph TB
    subgraph core["NeqSim Core (Java 8+)"]
        THERMO["Thermodynamics<br/>60+ EOS models"]
        PROCESS["Process Simulation<br/>33+ equipment types"]
        PVT["PVT Simulation"]
        MECH["Mechanical Design<br/>& Standards"]
    end

    subgraph access["Access Layers"]
        PYTHON["Python / Jupyter<br/>pip install neqsim"]
        JAVA["Java / Maven<br/>Direct API"]
        MCP["MCP Server (Java 21+)<br/>LLM integration"]
        AGENTS["AI Agents<br/>VS Code Copilot"]
    end

    PYTHON --> THERMO
    PYTHON --> PROCESS
    JAVA --> THERMO
    JAVA --> PROCESS
    MCP --> THERMO
    MCP --> PROCESS
    AGENTS --> MCP
    AGENTS --> PYTHON

Which entry point should I use?

I want to...UseRequires
Quick property lookup via LLMMCP Server + any LLM clientJava 21+ (or Docker)
Python scripting / Jupyter notebookspip install neqsimPython 3.9+, JVM
Embed in a Java applicationMaven dependencyJava 17+ (default) or Java 8+ (use the -Java8 artifact)
Full engineering study with reports@solve.task agent in VS CodeVS Code + GitHub Copilot
.NET / MATLAB integrationLanguage bindingsSee linked repos

Java version matrix

ComponentJava VersionNotes
NeqSim core library17+ (default)Default neqsim artifact targets Java 17 bytecode
NeqSim core library (-Java8)8+Java 8 compatible artifact built from pomJava8.xml
MCP server21+Quarkus-based; thin wrapper around core
Python usersNo Java codingJVM bundled via jpype
Running prebuilt MCP jar21+Download from releases

Core modules

ModulePackagePurpose
Thermodynamicsthermo/60+ EOS implementations, flash calculations, phase equilibria
Physical propertiesphysicalproperties/Density, viscosity, thermal conductivity, surface tension
Fluid mechanicsfluidmechanics/Single- and multiphase pipe flow, pipeline networks
Process equipmentprocess/equipment/33+ unit operations (separators, compressors, HX, valves, ...)
Chemical reactionschemicalreactions/Equilibrium and kinetic reaction models
Parameter fittingstatistics/Regression, parameter estimation, Monte Carlo
Process simulationprocess/Flowsheet assembly, dynamic simulation, recycle/adjuster coordination

For details see docs/modules.md.

Contributing

We welcome contributions of all kinds: bug fixes, new models, examples, documentation, and notebook recipes. AI-assisted PRs are first-class contributions; see CONTRIBUTING.md.

New here? Get started (Windows, PowerShell):

git clone https://github.com/equinor/neqsim.git
cd neqsim
py -3 -m venv .venv
.\.venv\Scripts\Activate.ps1   # activate the venv FIRST so 'neqsim' lands on PATH
.\install.cmd                  # or .\install.ps1  (append 'uv' for the fast installer)
neqsim onboard                 # interactive setup (Java, Maven, build, Python, agents)

macOS/Linux:

git clone https://github.com/equinor/neqsim.git && cd neqsim
python3 -m venv .venv && source .venv/bin/activate
./install.sh
neqsim onboard

Activate the venv before running install. The installer does not create or activate a venv — it only detects an already-active one. Activating first means the package and the neqsim command install into the venv and stay on PATH; skip it and you may hit "neqsim is not recognized".

The install script finds a working Python for you and runs python -m pip under the hood, so it works even when pip/python are not on PATH. To install manually, use python -m pip install -e devtools/ (not bare pip).

Windows: "install.ps1 is not digitally signed" error? This is PowerShell's execution policy, not a problem with the file. Run the pure-batch installer .\install.cmd (calls Python/pip directly, works even when the policy is locked by Group Policy), or just run py -m pip install -e devtools/.

Tip: Using a virtual environment (python -m venv .venv then activate it) avoids PATH issues on all platforms. See devtools/README.md if neqsim is not found, or use python -m neqsim_cli as a fallback.

Or skip local setup entirely: Open in GitHub Codespaces, with everything pre-installed in the browser.

Then explore and contribute:

neqsim try                 # interactive playground - experiment with NeqSim instantly
neqsim contribute          # guided wizard - picks the right path for you
neqsim doctor              # quick diagnostic if something isn't working

Where to start

Skills are markdown files containing engineering knowledge (code patterns, design rules, troubleshooting tips) that AI agents load automatically when solving related tasks. Contributing a skill is the easiest way to make the agentic system smarter, with no Java required.

Public, reusable skills and agents live in their own community repos — equinor/neqsim-community-skills and equinor/neqsim-community-agents — while company-private ones go in internal enterprise repos (see below).

#First ContributionDifficultyWhat to do
1Contribute a skillEasyWrite a SKILL.md with domain knowledge - neqsim new-skill "name" (guide, example skill)
2Add a NIST validation benchmarkEasyCompare NeqSim flash results to NIST data in docs/benchmarks/
3Create a Jupyter notebook exampleMediumAdd a worked example to examples/notebooks/
4Add an MCP example to the catalogEasyAdd a new entry in ExampleCatalog.java
5Fix a broken doc linkEasySearch docs/**/*.md for dead links and fix them
6Add a unit test for existing equipmentMediumAdd tests under src/test/java/neqsim/

Community Skill and Agent Catalogs

Browse and install community-contributed skills, or publish your own:

neqsim skill list                    # browse the catalog and discovered repositories
neqsim skill install <name>          # install a skill
neqsim skill install <name> --target vscode   # also export to your ~/.copilot/skills folder
neqsim skill doctor                  # check private-catalog authentication readiness
neqsim skill doctor --target vscode  # verify VS Code skill exports
neqsim skill publish user/repo-name  # publish yours (creates a draft PR)

Browse and install community-contributed agents separately from skills:

neqsim agent list                    # browse installable agent workflows
neqsim agent search hydrate          # search by name, tag, description, or required skill
neqsim agent install <name>          # install an agent definition
neqsim agent install <name> --target vscode   # also export the agent and required skills for VS Code
neqsim agent install --all           # install every agent in the catalog
neqsim agent doctor --target vscode  # verify VS Code exports and required skill visibility
neqsim agent validate <name-or-path> # validate an installed or local agent package
neqsim agent schema                  # show the supported agent.yaml fields

Both neqsim agent doctor --target ... and neqsim skill doctor --target ... accept --profile path/to/export-profile.json to check a declared export set. Without a profile, missing exports are warnings; with a profile, expected-but-missing exports are errors and extra exports are warnings.

By default, installed community and private content is kept out of the Git-tracked workspace: skills install to ~/.neqsim/skills/, agents install to ~/.neqsim/agents/, and --target vscode writes generated copies to the personal ~/.copilot/skills and ~/.copilot/agents folders (which VS Code and the GitHub Copilot CLI scan in every workspace). Use --vscode-scope workspace only when a maintainer intentionally wants a generated .github/skills or .github/agents copy.

The catalog can list individual skills directly and can also point to public multi-skill GitHub repositories. When a repository is listed under repositories: in community-skills.yaml, neqsim skill list reads the online repo catalog first and falls back to scanning matching SKILL.md files, so new skills can appear without adding one entry per skill to the NeqSim repo.

Agents follow the same discovery model through community-agents.yaml, but they are kept as a separate install type. Skills are reusable engineering knowledge; agents are role/workflow definitions that can declare required_skills and are installed to ~/.neqsim/agents/. Agent packages can include an agent.yaml manifest with supported domains, inputs, outputs, MCP tool requirements, human review policy, and trust level. Installing an agent downloads and validates the definition only; execution is an explicit action in the AI tool that uses it.

The shared public home for reusable community skills is equinor/neqsim-community-skills. The shared public home for reusable community agents is equinor/neqsim-community-agents. Put skills there when they are public, reproducible, useful beyond one project, and do not need to live in NeqSim core. Good candidates include educational screening workflows, public validation helpers, open engineering checklists, agent guidance around existing NeqSim workflows, and examples with synthetic or public data. Keep proprietary methods, plant data, private tag names, internal URLs, company standards, and project-specific design bases out of the public community repos; use private enterprise skill and agent repositories for those.

See Setting up Agents and Skills for the start-here install walkthrough, the Skills Guide for the full walkthrough, Enterprise Agent and Skill Repositories for company-private repository setup, community-skills.yaml and community-agents.yaml for the catalogs, and .github/skills/README.md for the quick contribution guide.

All tests and ./mvnw checkstyle:check must pass before a PR is merged.


Documentation & Resources

ResourceLink
Set up agents & skillsdocs/integration/agents_and_skills_setup.md - start-here install for VS Code + enterprise setup
User documentationequinor.github.io/neqsim
Benchmark gallerydocs/benchmarks/ - validation against NIST, published data
Reference manual indexREFERENCE_MANUAL_INDEX.md (350+ pages)
MCP tool contractMCP_CONTRACT.md - stable API for agent builders
JavaDoc APIJavaDoc
Jupyter notebooksexamples/notebooks/ (30+ examples)
Discussion forumGitHub Discussions
ReleasesGitHub Releases
NeqSim homepageequinor.github.io/neqsimhome

Authors

Even Solbraa (esolbraa@gmail.com), Marlene Louise Lund

NeqSim development was initiated at NTNU. A number of master and PhD students have contributed to its development, and we greatly acknowledge their contributions.

License

Apache-2.0

Trust

Not scanned yet. Artifacts are graded after they are crawled, so a recently discovered one may have no result for a while.

Versions

  • git-b3e79847b0b82026-08-04