@@ -691,3 +691,201 @@ String jsonReport = design.toJson();
691691
692692---
693693
694+ ## Jupyter Notebook Creation Guidelines (MANDATORY)
695+
696+ When creating Jupyter notebooks for NeqSim examples, follow these critical patterns:
697+
698+ ### Import Pattern (USE THIS EXACT PATTERN)
699+
700+ **CORRECT** - Use the `jneqsim` gateway for direct Java access:
701+ ```python
702+ # Import NeqSim - Direct Java Access via jneqsim
703+ from neqsim import jneqsim
704+
705+ # Import commonly used Java classes through the jneqsim gateway
706+ SystemSrkEos = jneqsim.thermo.system.SystemSrkEos
707+ ProcessSystem = jneqsim.process.processmodel.ProcessSystem
708+ Stream = jneqsim.process.equipment.stream.Stream
709+ Separator = jneqsim.process.equipment.separator.Separator
710+ Compressor = jneqsim.process.equipment.compressor.Compressor
711+ Cooler = jneqsim.process.equipment.heatexchanger.Cooler
712+ Heater = jneqsim.process.equipment.heatexchanger.Heater
713+ ```
714+
715+ **WRONG** - Do NOT use jpype imports directly for new notebooks:
716+ ```python
717+ # WRONG - This pattern may not work reliably
718+ import jpype
719+ import jpype.imports
720+ from jpype.types import *
721+ if not jpype.isJVMStarted():
722+ jpype.startJVM(classpath=['../target/classes'])
723+ from neqsim.thermo.system import SystemSrkEos # Direct jpype import
724+ ```
725+
726+ ### Common Problems and Solutions
727+
728+ | Problem | Cause | Solution |
729+ |---------|-------|----------|
730+ | `ModuleNotFoundError: No module named 'neqsim'` | neqsim-python not installed | Run `pip install neqsim` |
731+ | `AttributeError: 'NoneType' object has no attribute...` | JVM not started | Use `from neqsim import jneqsim` which auto-starts JVM |
732+ | `TypeError: No matching overloads found` | Wrong parameter types | Cast Python types explicitly: `float(value)`, `str(name)` |
733+ | Import fails for nested classes | Wrong import path | Use `jneqsim.package.subpackage.ClassName` pattern |
734+ | `RuntimeError: JVM cannot be restarted` | JVM already started/stopped | Restart the kernel |
735+
736+ ### Temperature and Pressure Units
737+
738+ **CRITICAL**: NeqSim Java API uses **Kelvin** for temperatures and **bara** for pressures by default!
739+
740+ ```python
741+ # Creating fluid - temperature in KELVIN, pressure in bara
742+ fluid = SystemSrkEos(273.15 + 25.0, 60.0) # 25°C, 60 bara
743+
744+ # Setting stream conditions - can use unit strings
745+ stream.setTemperature(30.0, "C") # Celsius
746+ stream.setPressure(60.0, "bara") # bara
747+
748+ # Getting values - returns KELVIN
749+ temp_kelvin = stream.getTemperature()
750+ temp_celsius = stream.getTemperature() - 273.15 # Convert to Celsius
751+
752+ # WRONG - forgetting Kelvin conversion
753+ temp = fluid.getTemperature() # This is in Kelvin!
754+ print(f"Temperature: {temp}°C " ) # WRONG - will show ~298°C instead of 25°C
755+ ```
756+
757+ ### Required Steps for Fluid Creation
758+
759+ Always follow this sequence:
760+ ```python
761+ # 1. Create fluid with (T_Kelvin, P_bara)
762+ fluid = SystemSrkEos(273.15 + 25.0, 60.0)
763+
764+ # 2. Add components (name, mole_fraction)
765+ fluid.addComponent(" methane" , 0.85)
766+ fluid.addComponent(" ethane" , 0.10)
767+ fluid.addComponent(" propane" , 0.05)
768+
769+ # 3. MANDATORY: Set mixing rule
770+ fluid.setMixingRule(" classic" )
771+
772+ # 4. Optional but recommended for custom components
773+ # fluid.createDatabase(True)
774+ ```
775+
776+ **NEVER skip the mixing rule** - simulations will fail or give wrong results without it.
777+
778+ ### Process Equipment Connections
779+
780+ ```python
781+ # Create process system
782+ process = ProcessSystem(" My Process " )
783+
784+ # Feed stream
785+ feed = Stream(" Feed " , fluid)
786+ feed.setFlowRate(50000.0, " kg/ hr" )
787+ process.add(feed)
788+
789+ # Equipment takes inlet stream in constructor
790+ separator = Separator(" HP Sep " , feed) # Stream object, not name
791+ process.add(separator)
792+
793+ # Get outlet streams from equipment
794+ gas_out = separator.getGasOutStream() # Gas phase
795+ liquid_out = separator.getLiquidOutStream() # Liquid phase
796+
797+ # Connect to next equipment
798+ compressor = Compressor(" Comp " , gas_out)
799+ process.add(compressor)
800+
801+ # For equipment outlet
802+ next_stream = compressor.getOutletStream()
803+ ```
804+
805+ ### Common Class Import Paths
806+
807+ ```python
808+ # Thermo systems
809+ SystemSrkEos = jneqsim.thermo.system.SystemSrkEos
810+ SystemPrEos = jneqsim.thermo.system.SystemPrEos
811+ SystemSrkCPAstatoil = jneqsim.thermo.system.SystemSrkCPAstatoil
812+
813+ # Process equipment
814+ ProcessSystem = jneqsim.process.processmodel.ProcessSystem
815+ Stream = jneqsim.process.equipment.stream.Stream
816+ Separator = jneqsim.process.equipment.separator.Separator
817+ ThreePhaseSeparator = jneqsim.process.equipment.separator.ThreePhaseSeparator
818+ Compressor = jneqsim.process.equipment.compressor.Compressor
819+ Expander = jneqsim.process.equipment.expander.Expander
820+ Heater = jneqsim.process.equipment.heatexchanger.Heater
821+ Cooler = jneqsim.process.equipment.heatexchanger.Cooler
822+ HeatExchanger = jneqsim.process.equipment.heatexchanger.HeatExchanger
823+ Mixer = jneqsim.process.equipment.mixer.Mixer
824+ Splitter = jneqsim.process.equipment.splitter.Splitter
825+ ThrottlingValve = jneqsim.process.equipment.valve.ThrottlingValve
826+ Recycle = jneqsim.process.equipment.util.Recycle
827+ Adjuster = jneqsim.process.equipment.util.Adjuster
828+
829+ # Pipes
830+ AdiabaticPipe = jneqsim.process.equipment.pipeline.AdiabaticPipe
831+ PipeBeggsAndBrills = jneqsim.process.equipment.pipeline.PipeBeggsAndBrills
832+
833+ # Distillation
834+ DistillationColumn = jneqsim.process.equipment.distillation.DistillationColumn
835+ ```
836+
837+ ### Getting Results
838+
839+ ```python
840+ # After running process
841+ process.run()
842+
843+ # Stream properties
844+ stream.getTemperature() # Kelvin
845+ stream.getPressure() # bara
846+ stream.getFlowRate(" kg/ hr" ) # Mass flow with unit
847+
848+ # Fluid properties
849+ fluid = stream.getFluid()
850+ fluid.getDensity(" kg/ m3" ) # Density
851+ fluid.getMolarMass(" kg/ mol" ) # Molar mass
852+ fluid.getZ() # Compressibility factor
853+ fluid.getNumberOfPhases() # Phase count
854+ fluid.hasPhaseType(" gas" ) # Check phase presence
855+
856+ # Compressor
857+ comp.getPower(" kW" ) # Power consumption
858+ comp.getOutletStream() # Outlet stream
859+
860+ # Heat exchangers
861+ heater.getDuty() # Heat duty in Watts
862+ cooler.getDuty() # Cooling duty (positive = heat removed)
863+ ```
864+
865+ ### Notebook Structure Best Practice
866+
867+ 1. **Introduction cell** - Describe what the notebook demonstrates
868+ 2. **Setup cell** - All imports in one cell
869+ 3. **Fluid creation** - Separate cell for creating thermodynamic system
870+ 4. **Process building** - Build process step by step
871+ 5. **Run simulation** - Single `process.run()` call
872+ 6. **Results** - Extract and display results
873+ 7. **Visualization** - Plots using matplotlib
874+ 8. **Tips/Next steps** - Summary and links to related examples
875+
876+ ### Type Conversion for Java
877+
878+ When passing values to Java methods, ensure correct types:
879+ ```python
880+ # Explicitly convert to float for numeric parameters
881+ pressure = 60.0 # Already float
882+ comp.setOutletPressure(float(pressure)) # Explicit conversion if unsure
883+
884+ # String parameters
885+ stream.setFlowRate(50000.0, str(" kg/ hr" )) # Usually not needed but safe
886+
887+ # Boolean
888+ fluid.setMultiPhaseCheck(True) # Python bool works
889+ ```
890+
891+ ---
0 commit comments