@equinor/neqsim
NeqSim (Non-Equilibrium Simulator) is a comprehensive Java library for fluid property estimation, process simulation, and engineering design.
Install
agr install @equinor/neqsim --target copilotWrites 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.mdin 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.mdfor 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.mdhas copy-paste starters for every common task (fluids, flash, equipment, PVT, tests, notebooks).Was this solved before? Search
docs/development/TASK_LOG.mdfor 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):
| Forbidden | Java 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 |
| Records | Regular class with fields |
Pattern matching instanceof | Traditional 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 justcheck) 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:
This builds the NeqSim JAR and copies it to the Python neqsim package for immediate use. Note: the runtime loads.\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\" -Forcelib/*(flat), so copy the JAR directly intoneqsim\lib\, not ajava11/java8subfolder.
API Consistency (MANDATORY)
When creating example files or documentation that references existing classes:
-
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
-
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 -
Do NOT assume API patterns - different classes may have different conventions:
- Some constructors take
String name, others takeProcessSystem - Method names like
addEquipmentvsaddEquipmentReliabilityvsaddEquipmentMtbf - Parameter counts vary (e.g., 3 params vs 4 params)
- Some constructors take
-
Inner classes and enums - verify the exact location:
- Enums may be in different classes:
RiskEvent.ConsequenceCategoryvsRiskMatrix.ConsequenceCategory - Inner classes require full path:
BowTieModel.Threat,PortfolioRiskAnalyzer.CommonCauseScenario - Check imports in the actual class to see which enum/type it uses
- Enums may be in different classes:
-
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
- Wrong:
-
Common API mistakes to avoid:
- Assuming
getXxx95()exists when actual method isgetXxx(int percentile) - Assuming enum constants like
SEVERE_WEATHERwhen actual isCommonCauseType.WEATHER - Assuming 1-arg constructors when 2+ args are required
- Calling methods on wrong class (e.g.,
analyzer.getFrequency()vsmodel.getFrequency()) - Assuming
calculate()when actual method iscalculateRisk()orrun() - Assuming convenience overloads like
addAsset(name, value1, value2, value3)when API isaddAsset(id, name, value) - Using descriptive names as IDs when API distinguishes between
idandnameparameters
- Assuming
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:
-
Write a JUnit 5 test that exercises every API call shown in the documentation.
- Append to
src/test/java/neqsim/DocExamplesCompilationTest.javafor 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.
- Append to
-
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.
- Use
-
Keep tests in sync - when documentation changes, update the corresponding test.
-
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.
-
Common doc-code bugs to catch with tests:
- Plus fraction names with
+character ("C20+"crashes - use"C20") - Wrong method names (
getUnitOperation()vsgetUnit()) - Wrong parameter types (
intvsdouble) - Calling characterization before setting mixing rule
- Wrong risk threshold descriptions not matching source logic
- Methods requiring unit strings (e.g.,
setDesignAmbientTemperature(15.0, "C")notsetDesignAmbientTemperature(15.0)) - Getter methods requiring arguments (e.g.,
getFanStaticPressure(flow)notgetFanStaticPressure())
- Plus fraction names with
- 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 callfluid.initProperties()before reading physical/transport properties.init(3)alone does NOT initialize transport properties (viscosity, thermal conductivity). Usefluid.initProperties()which calls bothinit(2)+initPhysicalProperties(). Without this,getViscosity(),getThermalConductivity(), andgetDensity()may return zero. - Phase Envelope Branch Labels (CRITICAL): When using
calcPTphaseEnvelope(true, 1.0)(bubblePointFirst=true),getBubblePointTemperatures()returns physically DEW curve data andgetDewPointTemperatures()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). Seeneqsim-api-patternsskill for the correct pattern. - Thermo Systems: Fluids are represented by
SystemInterfaceimplementations such asSystemSrkEosorSystemSrkCPAstatoil; always set a mixing rule (setMixingRule("classic")or numeric CPA rule) and callcreateDatabase(true)when introducing new components. - Process Equipment Pattern: Equipment extends
ProcessEquipmentBaseClassand is registered inside aProcessSystem;ProcessSystemenforces unique names and handles recycle/adjuster coordination, so reuse it for multi-unit workflows. UseMultiPortEquipmentas the base class for equipment with multiple inlet/outlet streams. - Stream Introspection: Every
ProcessEquipmentInterfaceexposesgetInletStreams()andgetOutletStreams()returningList<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 withgetController("tag"), list all withgetControllers(). The legacysetController()/getController()still work (backward-compatible). During dynamic simulationrunTransient(), theProcessSystemexplicitly 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 withprocess.getConnections(). - Unified Element Model:
ProcessElementInterfaceis the common supertype for equipment, controllers, and measurement devices. Query all elements withprocess.getAllElements(). This enables DEXPI export, topology analysis, and flowsheet introspection. - Streams & Cloning: Instantiate feeds with
Stream/StreamInterface, callsetFlowRate,setTemperature,setPressure, thenrun(); clone fluids (system.clone()) before branching to avoid shared state between trays or unit operations. - Distillation Column:
DistillationColumnprovides sequential, damped, and inside-out solvers; maintain solver metrics (lastIterationCount,lastMassResidual,lastEnergyResidual) and feed-tray bookkeeping when altering column logic to keep tests likeinsideOutSolverMatchesStandardOnDeethanizerCasegreen. - ProcessSystem Utilities: Use
ProcessSystem.add(unit)to build flowsheets,run()/run(UUID)for execution,copy()when duplicating equipment,connect()for explicit connections, andgetAllElements()to query all equipment, controllers, and measurements; modules can self-initialize throughModuleInterface- respect these hooks if you add packaged subsystems. - ProcessModel for Multi-Area Plants (MANDATORY): For large plants (platforms, gas plants), split into separate
ProcessSystemobjects per process area then combine withProcessModel. Useplant.add("area name", processSystem)to register named areas,plant.run()iterates until convergence,plant.get("area name")retrieves sub-processes, andplant.getConvergenceSummary()reports status. See the reference platform models for the canonical pattern: each area is a Python function returning aProcessSystem, cross-system streams are shared by object reference, and all systems are composed into aProcessModelat the end. NEVER add aProcessModuleorProcessModelto aProcessSystem- 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 overAUTO_TOLERANCE_STALL_WINDOW(5) outer passes while belowgetAutoToleranceCeiling()(1e-2). Report withgetAutoTuningSummary()/getAutoToleranceSummary()(also ingetConvergenceSummary()and theautoTuning/autoToleranceblocks ofgetConvergenceReportJson()). Any explicitsetTolerance()/ per-variable setter /runUntilConverged(n, tol)marks the tolerance user-owned and disables both behaviours — so do not set1e-3"to be helpful". Opt out withsetAutoTolerance(false)/setAutoConvergenceTuning(false). - Automation API (PREFERRED for agents): Use
ProcessAutomationfor string-addressable variable access instead of navigating Java class hierarchies. Get the facade viaprocess.getAutomation()orplant.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 withgetUnitList(), list variables withgetVariableList("unitName")(returnsSimulationVariablewith INPUT/OUTPUT type, address, unit, description), read values withgetVariableValue("Unit.stream.property", "unit"), write withsetVariableValue("Unit.property", value, "unit"). For multi-area models, use area-qualified addresses:"Area::Unit.stream.property"withgetAreaList()for discovery. - Agentic Automation Extensions:
ProcessAutomationnow exposes batch and introspection methods that emit a stable JSON schema (SCHEMA_VERSION = "1.0"):- Batch I/O:
getValues(addresses, unit)returnsMap<String, Double>of successfully read values;setValues(updates, unit, runAfter)writes many inputs and optionally runs once. - Dirty tracking:
isDirty(),runIfDirty(), andsetVariableValueAndRun(address, value, unit)avoid redundantrun()calls — the dirty flag flips on every successful write and clears afterrun(). - Introspection:
describe()returns the full unit/variable manifest as JSON;snapshot(scope)dumps variable values for a unit, area, or"*";getTopology()lists equipment andProcessConnectionedges;getNeighbors(unit)returns immediate upstream/downstream units. - Structured reads:
getStructured(address)returns aJsonElement— composition addresses (...composition,...components,...phaseFractions,...kvalues) yield objects/arrays instead of crashing the scalar accessor. - Pre-flight validation:
validateAddress(address)returnsnullfor good addresses or aDiagnosticResultwith the properErrorCategory(no exception thrown).getAllowedUnits(address)lists valid UOM strings. - Diagnostic taxonomy:
setVariableValueSafe/getVariableValueSafeJSON responses include category-tagged errors forUNIT_NOT_FOUND,PROPERTY_NOT_FOUND,PORT_NOT_FOUND,READ_ONLY_VARIABLE,VALUE_OUT_OF_BOUNDS,UNKNOWN_UNIT,INVALID_ADDRESS_FORMAT, andCONVERGENCE_FAILURE. - Thread safety:
AutomationDiagnosticsuses aCollections.synchronizedListhistory and aConcurrentHashMapof learned corrections so multiple agents may share a facade.
- Batch I/O:
- Closed-Loop Optimization —
evaluate()(PREFERRED for agent loops):run()returnsvoid, 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. Useevaluate(setpoints, setpointUnit, readbacks, readbackUnit, maxIterations, tolerance)(and the convenience overloadevaluate(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 singlefeasibleflag (true only when the run did not throw, the model converged, no unit failed, and every setpoint was accepted). Rejected setpoints land insetpointsRejectedand bad read-backs inreadbackErrors— both without throwing, so a malformed candidate degrades one trial instead of crashing the loop. Passnullas 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 nestedconvergencereport + per-areaareas),runJson()(single run with structured outcome),getRunStatusJson()(last status without re-running). All clear the dirty flag even on failure. Default tolerance5e-3is robust for plants with near-zero-flow anti-surge recycles. Through jpype wrap asjson.loads(str(result)). Pair withgetAdjustableParameters()for the bounded decision space. - Capacity Observation Snapshot —
getUtilizationSnapshot()(the observation vector):evaluate()is the action+reward step;getUtilizationSnapshot()is the matching observation step. BothProcessSystemandProcessModelexposegetUtilizationSnapshotJson(), andProcessAutomation.getUtilizationSnapshot()delegates to whichever it wraps. The snapshot is side-effect-free (never callsrun(), only reads already-computedCapacityConstraintutilization) so it is cheap to call every step. Per unit it reportsname,type,maxUtilization(0–1, NaN→0),maxUtilizationPercent,limitingConstraint,feasible,hardLimitExceeded,power_kW(compressors/pumps), and aconstraints[]breakdown; for aProcessModeleach unit also carries itsarea. Plant-wide it givesbottleneck(highest-utilization unit ornull),anyOverloaded,anyHardLimitExceeded, schema"1.0". Closed-loop RL pattern: observation =getUtilizationSnapshot(), action =evaluate()setpoints, reward = anevaluate()read-back penalized whenanyOverloadedor anymaxUtilization > 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 thepowerconstraint a basis viacomp.getMechanicalDesign().setMaxDesignPower(kW). Expanders:Expanderoverrides the inheritedCompressorcapacity 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), andexpander.setRatedRecoveredPower(kW)adds arecoveredPowerHARD constraint. Provenance: each constraint in the snapshot now carries itsdataSource(e.g."equipment","design") so an agent can tell a rated limit from an estimate. - AgenticProcessOptimizer (ML/agentic optimization):
auto.newOptimizer()returns anAgenticProcessOptimizer— a ready-made closed-loop search built onevaluate()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 fromgetAdjustableParametersJson(). Algorithm: bounded Nelder–Mead simplex with deterministic (seeded) random init (same seed + same problem ⇒ identical trajectory). Decision space:addVariable(addr, lo, hi, unit)oruseAdjustableParameters(). Objective:minimize/maximize/setObjective(addr, Sense, unit)orsetObjectiveFunction(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 gatedevaluate(), then reads the objective/constraints — a malformed candidate degrades one trial, andoptimize()/optimizeToJson()never throw. Every point is logged as aTrial(setpoints, readbacks, objective, penalty, feasibility, score) — the (state, action, reward) tape for offline RL. CallgetReadinessJson()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 classicneqsim.process.util.optimizerclasses (which take aFunction<double[],Double>over an opaqueProcessSystem). - Capacity / throughput / quality / batch helpers on
ProcessAutomation(bothProcessSystemandProcessModel): string-addressable, never-throwing, schema-versioned JSON helpers that close the loop for maximise-production studies.enableCapacityConstraints()enables capacity constraints on everyCapacityConstrainedEquipment(separators, pumps, valves, pipelines, heaters/coolers, heat exchangers, manifolds) so any type can bind as the bottleneck — it recreates compressor constraints viareinitializeCapacityConstraints()(surge/speed stay disabled when chartless, power stays enabled) rather than the blindenableAllConstraints(), 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 reachesutilizationLimit, 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 gascricondenbar_bara/cricondentherm_K(calcPTphaseEnvelope) on a cloned fluid (never throws;rvpError/envelopeErroron failure) — the spec side of a maximise-throughput-subject-to-RVP/cricondenbar search. Routing / feed-scale decision variables: feedflowRateis a writable INPUT; splitters expose one boundedsplitFactor_i(0–1) INPUT per outlet ingetAdjustableParameters()(read = current fraction; write = branch weight, renormalised to sum 1) soAgenticProcessOptimizer.useAdjustableParameters()picks them up automatically.evaluateBatchJson(candidates, unit, readbacks, maxParallel)scores a list of setpoint maps in one call — for aProcessSystemwithmaxParallel>1each candidate runs on an independentProcessSystem.copy()on its own thread (genuinely parallel, live model untouched), for aProcessModel(nocopy()) ormaxParallel==1it runs sequentially; each result carries the fullevaluatepayload (incl.converged/iterations/maxError/failedUnitName/failedUnitError) +index, root reportsparallel/feasibleCount/firstFeasibleIndex. Production + emissions: compose decision space (bounded setpoints + splitter routing + bounded feed scale) + feasibility (enableCapacityConstraints+ snapshot) + a rewardproduction − λ·Σ(compressor power)(compression power = CO2 proxy) viasetObjectiveFunction, orProductionOptimizer.optimizePareto[MAX production, MIN Σ power]. - Self-Healing Automation (PREFERRED for agents): Use
getVariableValueSafe()andsetVariableValueSafe()instead of direct get/set. These return JSON with the value on success, or diagnostics with suggestions, auto-corrections, and remediation hints on failure. Accessauto.getDiagnostics()for fuzzy name matching (autoCorrectName()), physical bounds validation (validatePhysicalBounds()), and operation tracking (getLearningReport()). TheAutomationDiagnosticsclass learns from past failures - corrections are cached and reused automatically. - Lifecycle State (Save/Restore/Compare): Use
ProcessSystemState.fromProcessSystem(process)andProcessModelState.fromProcessModel(plant)to create portable JSON snapshots. Save withstate.saveToFile("model.json"), load withProcessSystemState.loadFromFile("model.json"), validate withstate.validate(). Compare versions withProcessModelState.compare(v1, v2)returning aModelDiff(modified parameters, added/removed equipment). UsetoCompressedBytes()/fromCompressedBytes()for network transfer. All state classes live inneqsim.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 introduceSystem.out.printlnorSystem.err.printlnin Java code (including tests, examples, and generated snippets). Use parameterized logger calls such aslogger.info("message {}", value). - Build & Test Workflow: Use
./mvnw installfor a full build (Windows:mvnw.cmd install); run the entire suite with./mvnw testand checkstyle/spotbugs/pmd with./mvnw checkstyle:check spotbugs:check pmd:check. - Focused Tests: Use the Maven
-Dtestflag 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.xmland 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
.javafile, run./mvnw spotless:apply(Windows:mvnw.cmd spotless:apply) to reformat to the project style, thengit addthe changes before committing. CI runs./mvnw spotless:checkand FAILS the build on any unformatted file. Do not rely on local pre-commit hooks being installed, and NEVER bypass the gate withgit commit --no-verify. - Serialization & Copying: Many equipment classes rely on Java serialization (
ProcessEquipmentBaseClass.copy()); avoid introducing non-serializable fields or mark themtransientto preserve cloning. SpotBugs enforces this via the SE_BAD_FIELD rule. When adding fields to anySerializableclass (equipment, measurement devices, mechanical design, thermo phases), use the correct modifier order:private transient Type field;orprivate final transient Type field;. Common non-serializable types that needtransient:Function,BiConsumer,Consumer,Thread, JDBCConnection/Statement, Apache Commons Math interpolators, and any inner class that doesn't implementSerializable. TheProcessLogicinterface extendsSerializable. - 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/resourcesinstead 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
@authorand@version, (2) method description, (3)@paramfor EVERY parameter with type and valid range, (4)@returndescribing what is returned (for non-void methods), (5)@throwsfor 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
summaryattribute (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
@seewith plain text like@see IEC 61508- this causes "reference not found" errors - Only use
@seewith 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
| Error | Cause | Fix |
|---|---|---|
| "no summary or caption for table" | Missing <caption> | Add <caption> after <table> |
| "attribute not supported in HTML5: summary" | Using summary="" on table | Remove summary attribute |
| "reference not found" | Invalid @see reference | Use valid class/method reference or move to description |
| "no @param for X" | Missing parameter documentation | Add @param X description |
| "no @return" | Missing return documentation | Add @return description |
| "no @throws for X" | Method throws exception without doc | Add @throws X description |
| "unexpected end tag" | Mismatched HTML tags like extra </p> | Check tag nesting, remove orphan closing tags |
| "semicolon missing" | Malformed HTML in JavaDoc | Check HTML tag closure |
| "bad use of '>'" | Lambda arrow -> or comparison > in JavaDoc | Use > for > or rewrite lambdas as anonymous classes |
Methods with throws Clause (CRITICAL)
- EVERY method with a
throwsclause MUST have@throwsdocumentation 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
>entity:if (value > 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
Optionalwhere they enhance readability. NEVER useString.repeat()- useStringUtils.repeat()from Apache Commons. NEVER usevar,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, overridevalidateSetup()to add custom validation. Seeneqsim.util.validationpackage and docs/integration/ai_validation_framework.md. - AI-Friendly Error Handling: Exceptions in
neqsim.util.exceptionprovidegetRemediation()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-troubleshootingskill for ranked recovery strategies before retrying blindly. - Input Validation: Before creating NeqSim objects, validate inputs using the
neqsim-input-validationskill - 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-baselinesskill. This prevents silent accuracy drift. - Standards Lookup: For any engineering task, identify applicable industry standards using the
neqsim-standards-lookupskill. It maps equipment types to standards (API, NORSOK, DNV, ISO, ASME), provides CSV database query patterns, and defines thestandards_appliedschema 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-dataskill for tagreader API patterns, tag mapping, digital twin loops, and data quality handling. See also the@plant.dataagent. - 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-reconciliationskill. - API Changelog: Check
CHANGELOG_AGENT_NOTES.mdin 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.scoutagent or theneqsim-capability-mapskill to identify what NeqSim can do, find gaps, and plan implementations. The result MUST be saved tostep1_scope_and_research/capability_assessment.md(mandatory artifact for Standard/Comprehensive tasks). - Skill Discovery: Run
python devtools/skill_search.py "<task title>" --top 5at the start of any task to surface the most relevant skills via TF-IDF over the SKILL.mddescriptionfields. Prefer this over manual lookup inskill-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.jsonto 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 incapability_assessment.md§4b/§4c and mirror it intoresults.jsonagent_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 MCPcomposeWorkflow/composeMultiServerWorkflowor anengineering-harnessstudy instead of a single agent. - Literature & Document Pull: Use
@literature.scoutto fetch papers, standards, and internal STID/vendor docs intostep1_scope_and_research/references/. The agent writesreferences/manifest.jsonand summarises sources intonotes.md. - Pre-PR Quality Gate: Before opening a PR for a task, invoke
@review <task folder>(read-only). It wrapsvalidate_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.ymlrunsdevtools/verify_skills_agents.py(front-matter + skill-index reference check) anddevtools/generate_agent_skill_map.py(auto-generatesdocs/development/AGENT_SKILL_MAP.md) on every PR touching.github/skills/or.github/agents/. The map is rebuilt fromLoaded 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-assuranceskill for comprehensive patterns covering all flow assurance threats with NeqSim code patterns. Rigorous CO2 corrosion from a brine usesNorsokM506ElectrolyteBridge(electrolyte pH + FeCO3 film); per-segment corrosion+scale profiles usePipeSegmentIntegrity; mineral scale usesElectrolyteScaleCalculator/ScaleKinetics/BrineMixingScaleEvaluator. See also the@flow.assuranceagent. - 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-hammerskill. PreferWaterHammerStudyand MCPrunWaterHammerfor 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-hydrogenskill for CO2 phase behavior, impurity management, injection well analysis, and H2 pipeline design. See also the@ccs.hydrogenagent. - Power Generation: For gas turbines, steam turbines, HRSG, or combined cycle systems, use the
neqsim-power-generationskill 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-modelingskill. 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-readingskill. Usedevtools/pdf_to_figures.pyto convert PDF pages to PNG images, thenview_imagefor multimodal analysis of engineering drawings. See also the@read technical documentsagent. 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-retrieverskill. Supports local directories, manual upload toreferences/, and pluggable retrieval backends (configured via gitignoreddevtools/doc_retrieval_config.yaml). Documents are classified by type, filtered by relevance to the task, and fed into theneqsim-technical-document-readingpipeline 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-ruptureskill. Retrieve P&IDs/STIDs, line lists, piping specs, material certificates, flange/bolt/gasket data, fire-zone/PFP documents, relief basis, and acceptance criteria before runningneqsim.process.safety.rupturecalculations. Report missing final-design evidence explicitly inresults.jsonassumptions/gaps. - Auto-Validation for New Equipment: When creating a new class that extends
ProcessEquipmentBaseClass, ALWAYS generate avalidateSetup()method that checks: (1) required input streams are connected, (2) required parameters are set and within valid ranges, (3) returnValidationResultwith 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) andHeatExchangerDesignFeasibilityReport(TEMA/ASME + cost + 14 HX suppliers) produce FEASIBLE / FEASIBLE_WITH_WARNINGS / NOT_FEASIBLE verdicts and comprehensive JSON reports. Seeneqsim-api-patternsskill for usage patterns. - Auto-Annotation for Public Methods: When adding new public methods to core classes (SystemInterface, ProcessEquipmentInterface), consider adding
@AIExposableannotation with description, category, example, and@AIParameterannotations 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:
- Update
REFERENCE_MANUAL_INDEX.mdwith the new file entry - Update the relevant section's
index.md(e.g.,docs/examples/index.md) - Verify ALL links to other docs using
file_searchbefore adding them - See "Documentation Links (MANDATORY)" section below for link guidelines
- Update
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:
- Front matter MUST be the first thing in the file (before any content)
- Use three dashes
---to delimit the YAML block titleshould be descriptive but concise (appears in search results)descriptionshould include searchable keywords relevant to the content- Do NOT duplicate the title as an H1 heading immediately after front matter (Jekyll handles this)
- 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." - 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 Pattern | Why It Fails | Solution |
|---|---|---|
<div> containing markdown tables (|---|) | Parser ignores markdown inside HTML blocks | Use pure markdown OR pure HTML |
<div> containing numbered lists (1. Item) | Lists don't render as lists | Remove div wrapper or use <ol><li> |
<div> containing bullet lists (- Item) | Lists don't render as lists | Remove div wrapper or use <ul><li> |
Correct Patterns
For styled content boxes, choose ONE approach:
-
Pure Markdown (preferred for tables/lists):
### Section Title **Heading text:** | Column 1 | Column 2 | |----------|----------| | Data | Data | > *Note: Use blockquotes for callouts* -
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
| Wrong | Correct | Issue |
|---|---|---|
\[ P = \frac{RT}{v-b} \] | $$ P = \frac{RT}{v-b} $$ | \[...\] stripped by parser |
\(T_r\) | $T_r$ | \(...\) less reliable |
$$ P = ... $$ where | $$ P = ... $$ + newline + where | No text on same line as $$ |
Equation inside <div> | Move equation outside HTML block | Markdown not processed in HTML |
Verification
After adding equations, preview locally or check that:
- Display equations appear centered on their own line
- Inline math renders within the text flow
- 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
-
ALWAYS verify target files exist before adding links:
- Use
file_searchto confirm the file exists in the repository - Check the exact path and filename (case-sensitive on some systems)
- Use
-
Use correct relative paths based on the source file location:
- From
docs/fielddevelopment/todocs/process/: use../process/filename.md - From
docs/examples/todocs/tutorials/: use../tutorials/filename.md - Within same folder: use just
filename.md
- From
-
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 Area | Path | Example Files |
|---|---|---|
| Process equipment | docs/process/ | separators.md, compressors.md, heat-exchangers.md |
| Field development | docs/fielddevelopment/ | pressure_boundary_optimization.md, CAPACITY_CONSTRAINT_FRAMEWORK.md |
| Thermodynamics | docs/thermo/ | equations-of-state.md, flash-calculations.md |
| Examples | docs/examples/ | *.ipynb, *.java, index.md |
| Tutorials | docs/tutorials/ | Getting started guides |
| Troubleshooting | docs/troubleshooting/ | Common issues and solutions |
When Adding New Documentation
-
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)
- Add entry to
-
Cross-reference related docs with verified links:
## Related Documentation - [Pressure Boundary Optimization](pressure_boundary_optimization.md) - [Capacity Constraint Framework](CAPACITY_CONSTRAINT_FRAMEWORK.md) -
For Jupyter notebooks, also add to:
docs/examples/index.md- Examples indexdocs/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
.mdfiles exist (usefile_search("**/filename.md")) - All linked
.ipynbnotebooks exist - All linked
.javaexamples 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 estimationneqsim-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 onSeparator. SeeAGENTS.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
- Required columns:
-
TechnicalRequirements_Piping.csv: Piping code-specific design values
- Required columns:
Code,ParameterName,Value,Unit,Description
- Required columns:
-
Standards Tables (in
designdata/standards/subdirectory):api_standards.csv- API standard parametersasme_standards.csv- ASME code requirementsdnv_iso_en_standards.csv- DNV/ISO/EN requirementsnorsok_standards.csv- NORSOK requirementsstandards_index.csv- Index mapping equipment types to applicable standards
Jupyter Notebook Creation Guidelines
Full patterns are in the
neqsim-notebook-patternsskill. Load it before creating notebooks.
Key rules (always apply):
- Use
devtools/neqsim_dev_setup.pyfor task notebooks and runner workflows: callneqsim_init(project_root=PROJECT_ROOT, ...), then use classes throughns.*orns.JClass(...). Do not usefrom neqsim import jneqsimin 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.jsonin 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 indocs/development/TASK_LOG.md— search before starting from scratch.
Key rules (always apply):
- Create task folder FIRST:
neqsim new-task "title" --type X --author "Name" - All output goes to
task_solve/YYYY-MM-DD_slug/— never toexamples/,docs/, or workspace root - 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/). Runpython devtools/generate_sources_md.py task_solve/YYYY-MM-DD_slug --organizeto file loose docs and (re)build the distributablereferences/SOURCES.md+references/collection_manifest.jsonso the whole task folder can be handed to others. - Follow the 3-step workflow: Scope & Research → Analysis & Evaluation → Report
- Benchmark validation (MANDATORY): Compare NeqSim results against independent reference data
- Uncertainty analysis: Monte Carlo with P10/P50/P90 + tornado diagram (MANDATORY for Standard/Comprehensive tasks with economics or reserves; optional for Quick tasks)
- Risk evaluation: Risk register with ISO 31000 5×5 matrix (MANDATORY for Standard/Comprehensive tasks; optional for Quick tasks)
- Consistency check: Run
python devtools/consistency_checker.pybefore generating reports - 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
| Domain | What NeqSim provides |
|---|---|
| Thermodynamics | 60+ equation-of-state models (SRK, PR, CPA, GERG-2008, and more), flash calculations (TP, PH, PS, dew, bubble), phase envelopes |
| Physical properties | Density, viscosity, thermal conductivity, surface tension, diffusion coefficients |
| Process simulation | 33+ equipment types: separators, compressors, heat exchangers, valves, distillation columns, pumps, reactors |
| Pipeline & flow | Steady-state and transient multiphase pipe flow (Beggs & Brill, two-fluid model), pipe networks |
| PVT simulation | CME, CVD, differential liberation, separator tests, swelling tests, saturation pressure |
| Safety | Depressurization/blowdown, PSV sizing (API 520/521), source term generation, safety envelopes |
| Standards | ISO 6976 (gas quality), NORSOK, DNV, API, ASME compliance checks |
| Mechanical design | Wall thickness, weight estimation, cost analysis for pipelines, vessels, wells (SURF) |
| Field development | Production 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 LLM | MCP 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):
| Catalog | What it holds | Where |
|---|---|---|
| Community agents | Public AI agents for thermodynamics, process, flow assurance, energy & field development | equinor/neqsim-community-agents |
| Community skills | Public reusable engineering skills for agentic workflows | equinor/neqsim-community-skills |
| Enterprise agents / skills | Internal, company-private agents & skills governed in private repos (enterprise-agents.yaml / enterprise-skills.yaml) — kept separate from public content | Private 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.yamlin governed internal repos. These are never committed to the public NeqSim repos; they are discovered per-user (via~/.neqsim/private-*.yamland gh-CLI / Git Credential Manager auth).private-initwrites 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 in | Why |
|---|---|---|
| Extends the engine, or is tied to specific NeqSim Java classes/signatures and must ship in the same PR as the code | this 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 thresholds | enterprise (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
| Language | Repository |
|---|---|
| Python | pip install neqsim |
| MATLAB | equinor/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 trueAlso prefer cloning inside your user profile (e.g.
C:\Users\<id>\Documents\GitHub\neqsim) rather than a short drive root, and avoidC:\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... | Use | Requires |
|---|---|---|
| Quick property lookup via LLM | MCP Server + any LLM client | Java 21+ (or Docker) |
| Python scripting / Jupyter notebooks | pip install neqsim | Python 3.9+, JVM |
| Embed in a Java application | Maven dependency | Java 17+ (default) or Java 8+ (use the -Java8 artifact) |
| Full engineering study with reports | @solve.task agent in VS Code | VS Code + GitHub Copilot |
| .NET / MATLAB integration | Language bindings | See linked repos |
Java version matrix
| Component | Java Version | Notes |
|---|---|---|
| NeqSim core library | 17+ (default) | Default neqsim artifact targets Java 17 bytecode |
NeqSim core library (-Java8) | 8+ | Java 8 compatible artifact built from pomJava8.xml |
| MCP server | 21+ | Quarkus-based; thin wrapper around core |
| Python users | No Java coding | JVM bundled via jpype |
| Running prebuilt MCP jar | 21+ | Download from releases |
Core modules
| Module | Package | Purpose |
|---|---|---|
| Thermodynamics | thermo/ | 60+ EOS implementations, flash calculations, phase equilibria |
| Physical properties | physicalproperties/ | Density, viscosity, thermal conductivity, surface tension |
| Fluid mechanics | fluidmechanics/ | Single- and multiphase pipe flow, pipeline networks |
| Process equipment | process/equipment/ | 33+ unit operations (separators, compressors, HX, valves, ...) |
| Chemical reactions | chemicalreactions/ | Equilibrium and kinetic reaction models |
| Parameter fitting | statistics/ | Regression, parameter estimation, Monte Carlo |
| Process simulation | process/ | 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 theneqsimcommand install into the venv and stay on PATH; skip it and you may hit "neqsimis not recognized".The
installscript finds a working Python for you and runspython -m pipunder the hood, so it works even whenpip/pythonare not on PATH. To install manually, usepython -m pip install -e devtools/(not barepip).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 runpy -m pip install -e devtools/.
Tip: Using a virtual environment (
python -m venv .venvthen activate it) avoids PATH issues on all platforms. See devtools/README.md ifneqsimis not found, or usepython -m neqsim_clias 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
- CONTRIBUTING.md - Code of conduct, PR process, AI-assisted contributions
- VISION_AGENTS.md - What belongs in the agentic system (core vs. community)
- Developer setup guide - Build, test, and project structure
- Contributing structure - Where to place code, tests, and resources
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 Contribution | Difficulty | What to do |
|---|---|---|---|
| 1 | Contribute a skill | Easy | Write a SKILL.md with domain knowledge - neqsim new-skill "name" (guide, example skill) |
| 2 | Add a NIST validation benchmark | Easy | Compare NeqSim flash results to NIST data in docs/benchmarks/ |
| 3 | Create a Jupyter notebook example | Medium | Add a worked example to examples/notebooks/ |
| 4 | Add an MCP example to the catalog | Easy | Add a new entry in ExampleCatalog.java |
| 5 | Fix a broken doc link | Easy | Search docs/**/*.md for dead links and fix them |
| 6 | Add a unit test for existing equipment | Medium | Add 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
| Resource | Link |
|---|---|
| Set up agents & skills | docs/integration/agents_and_skills_setup.md - start-here install for VS Code + enterprise setup |
| User documentation | equinor.github.io/neqsim |
| Benchmark gallery | docs/benchmarks/ - validation against NIST, published data |
| Reference manual index | REFERENCE_MANUAL_INDEX.md (350+ pages) |
| MCP tool contract | MCP_CONTRACT.md - stable API for agent builders |
| JavaDoc API | JavaDoc |
| Jupyter notebooks | examples/notebooks/ (30+ examples) |
| Discussion forum | GitHub Discussions |
| Releases | GitHub Releases |
| NeqSim homepage | equinor.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
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