Ion Exchange¶
DWSIM Plus
Available with a DWSIM Plus (Patreon) subscription.
![]()
Ion Exchange Unit Operation — removes target ions from a feed stream via resin selectivity equilibrium (single-stage or staged counter-current). Ports ───── Inlet 0 : Feed Inlet 1 : Regenerant (optional — only used if connected) Outlet 0 : Treated Effluent Outlet 1 : Spent Regenerant / Eluate (optional — only set if connected)
DWSIM.UnitOperations.ElectrolyteOps.IonExchangeUnitOperation
Assembly DWSIM.UnitOperations.ElectrolyteOps.dll · Object ← BaseClass ← UnitOpBaseClass ← IonExchangeUnitOperation
At a glance¶

| Port | Index | Connected in the example |
|---|---|---|
| Inlet, material | 0 |
Hard-water |
| Inlet, material | 1 |
Regenerant |
| Outlet, material | 0 |
Soft-water |
| Outlet, material | 1 |
Spent-brine |
Example¶
This code runs on every build of this site, and the output below is what it printed.
fs = (Flowsheet.Create("IonExchangeExample")
.WithCompounds("Water", "Calcium (ion)", "Magnesium (ion)", "Sodium (ion)", "Chloride (ion)")
.WithPropertyPackage(PropertyPackages.Plus.ElectrolyteNRTL))
# Hard water, 10 kg/s: 3 mmol/L Ca2+ and 1 mmol/L Mg2+ as chlorides (400 mg/L as CaCO3)
hard = (fs.AddMaterialStream("Hard-water").At(Q.Celsius(20.0), Q.Bar(3.0))
.SetCompoundMolarFlow("Water", 10.0 / 0.018015)
.SetCompoundMolarFlow("Calcium (ion)", 0.030)
.SetCompoundMolarFlow("Magnesium (ion)", 0.010)
.SetCompoundMolarFlow("Chloride (ion)", 0.080))
# NaCl regenerant brine, 1 kg/s at about 10 wt%
brine = (fs.AddMaterialStream("Regenerant").At(Q.Celsius(20.0), Q.Bar(3.0))
.SetCompoundMolarFlow("Water", 0.9 / 0.018015)
.SetCompoundMolarFlow("Sodium (ion)", 1.7)
.SetCompoundMolarFlow("Chloride (ion)", 1.7))
soft = fs.AddMaterialStream("Soft-water")
spent = fs.AddMaterialStream("Spent-brine")
ix = (fs.AddIonExchange("IX-1")
.WithResinType(IXResinType.StrongAcidCation)
.WithRegenerantIon(IXRegenerantIon.Na)
.WithResinCapacityEqPerL(1.8)
.WithBedVolume(Q.CubicMeters(2.0))
.WithOperationMode(IXOperationMode.StagedCountercurrent)
.WithStages(4)
.ConnectFeed(hard, 0).ConnectFeed(brine, 1)
.ConnectProduct(soft, 0).ConnectProduct(spent, 1))
fs.AutoLayout()
fs.Solve()
r = ix.Object.Results
for ion in r.IonResults:
if ion.Charge > 0 and ion.FeedConcentration > 0.0:
print(f"{ion.IonName:16s} {ion.FeedConcentration:5.2f} -> {ion.EffluentConcentration:.4f} meq/L "
f"({ion.RemovalEfficiency:.1f} % removed)")
print(f"Hardness {r.FeedTotalHardness:.0f} -> {r.EffluentTotalHardness:.2f} mg/L as CaCO3")
print(f"Na+ released {soft.Object.Phases[0].Compounds['Sodium (ion)'].MolarFlow * 1000.0:.1f} mmol/s")
Output
Calcium (ion) 5.98 -> 0.0000 meq/L (100.0 % removed)
Magnesium (ion) 1.99 -> 0.0000 meq/L (100.0 % removed)
Hardness 399 -> 0.00 mg/L as CaCO3
Na+ released 80.0 mmol/s
DWSIM 10.2.11.0, generated 2026-10-08.
Properties¶
IDs accepted by GetPropertyValue, SetPropertyValue, the sensitivity analysis, the optimizer, the Adjust block and dynamic events. Units are SI; pass another unit system to GetPropertyValue to get them converted.
| ID | Name | Unit (SI) | Input |
|---|---|---|---|
Resin Type |
yes | ||
Resin Capacity |
eq/L | yes | |
Bed Volume |
m3 | yes | |
Operation Mode |
yes | ||
Number of Stages |
yes | ||
Regenerant Ion |
yes | ||
Design Flow Rate |
m3/s | yes | |
Effluent Molar Flow |
mol/s | result | |
Feed Total Hardness |
mg/L CaCO3 | result | |
Effluent Total Hardness |
mg/L CaCO3 | result | |
Resin Saturation Fraction |
result | ||
Bed Volumes to Breakthrough |
result |
Learn more¶
API members¶
Public members declared by this class. Inherited members are documented on the base classes.
Constructors¶
Properties¶
ComponentDescription: Gets or sets the CAPE-OPEN component description for this unit operation.
Gets or sets the CAPE-OPEN component description for this unit operation.
Config: Gets or sets the input configuration: resin type, capacity and bed volume, operation mode and number of stages...
Gets or sets the input configuration: resin type, capacity and bed volume, operation mode and number of stages, regenerant ion, counter-ion compound, selectivity coefficients and design flow rate.
IsPremium: Gets a value indicating that this unit operation is listed in the Premium group of the object palette (always true).
Gets a value indicating that this unit operation is listed in the Premium group of the object palette (always true).
MobileCompatible: Gets a value indicating whether this unit operation is compatible with mobile interfaces (always false).
Gets a value indicating whether this unit operation is compatible with mobile interfaces (always false).
ObjectClass: Gets the simulation object class category (separators).
Gets the simulation object class category (separators).
Prefix: Gets the default name prefix for this unit operation ('IX-').
Gets the default name prefix for this unit operation ("IX-").
Methods¶
Calculate(object): Calculates the object.
Calculates the object.
| Parameter | Type | Description |
|---|---|---|
args |
Object |
CloneXML(): Creates a deep copy of this object by round-tripping through XML serialization.
Creates a deep copy of this object by round-tripping through XML serialization.
CloseEditForm(): Closes the editor of this object, if it is open.
Closes the editor of this object, if it is open.
CreateConnectors(): Creates the graphic connector definitions on the flowsheet: feed inlet (left) and regenerant inlet (bottom), treated...
Creates the graphic connector definitions on the flowsheet: feed inlet (left) and regenerant inlet (bottom), treated effluent and spent regenerant outlets (right). The unit exchanges no energy, so it has no energy connector.
DeCalculate(): Decalculates the object.
Decalculates the object.
DisplayEditForm(): Opens the editor of this object.
Opens the editor of this object. A host that has no editor for it does nothing.
Draw(object): Draws the unit operation on the given SkiaSharp canvas: the embedded photo in photorealistic mode (draw mode 2)...
Draws the unit operation on the given SkiaSharp canvas: the embedded photo in photorealistic mode (draw mode 2), otherwise the vector icon.
| Parameter | Type | Description |
|---|---|---|
g |
Object |
The SkiaSharp canvas. |
GetChartModel(string): Builds an OxyPlot model of the effluent-to-feed ratio of every ion against the bed volumes treated, by running the...
Builds an OxyPlot model of the effluent-to-feed ratio of every ion against the bed volumes treated, by running the exchange model (Kremser or single-stage equilibrium) over a range of liquid volumes; the 10 % breakthrough estimate is marked.
| Parameter | Type | Description |
|---|---|---|
name |
String |
GetChartModelNames(): Chart names the PFD chart object can embed.
Chart names the PFD chart object can embed.
GetDisplayDescription(): Returns the description string for this unit operation type.
Returns the description string for this unit operation type.
GetDisplayName(): Returns the display name for this unit operation type.
Returns the display name for this unit operation type.
GetIconBitmapBytes(): Returns the raw bytes of the icon image for this unit operation.
Returns the raw bytes of the icon image for this unit operation.
GetPreferredGraphicObjectHeight(): Returns the preferred height of the flowsheet graphic object, in pixels.
Returns the preferred height of the flowsheet graphic object, in pixels.
GetPreferredGraphicObjectWidth(): Returns the preferred width of the flowsheet graphic object, in pixels.
Returns the preferred width of the flowsheet graphic object, in pixels.
GetProperties(PropertyType): Get a list of all properties of the object.
Get a list of all properties of the object.
| Parameter | Type | Description |
|---|---|---|
proptype |
PropertyType |
Type of the property. |
GetPropertyUnit(string, IUnitsOfMeasure): Gets the units of a property.
Gets the units of a property.
| Parameter | Type | Description |
|---|---|---|
prop |
String |
Property identifier. |
su |
IUnitsOfMeasure |
Units system to use. Null to use the default (SI) system. |
GetPropertyValue(string, IUnitsOfMeasure): Returns the value of a named property, converting from SI to the current unit system.
Returns the value of a named property, converting from SI to the current unit system. Falls back to extra properties if the property is not found in the base implementation.
| Parameter | Type | Description |
|---|---|---|
prop |
String |
The property identifier string. |
su |
IUnitsOfMeasure |
Optional units-of-measure system used for conversion; uses the shared SI system when Nothing. |
LoadData(List<XElement>): Restores the unit operation.
Restores the unit operation. The Config element, when present, is loaded into the existing Config; files saved without it keep the default configuration.
| Parameter | Type | Description |
|---|---|---|
data |
List<XElement> |
The XML elements written by SaveData. |
PopulateEditorPanel(object): Populates the cross-platform (Avalonia) editor panel with controls.
Populates the cross-platform (Avalonia) editor panel with controls.
| Parameter | Type | Description |
|---|---|---|
ctner |
Object |
The editor panel (layout container) to populate. |
ReturnInstance(string): Creates and returns a new instance for deserialization.
Creates and returns a new instance for deserialization.
| Parameter | Type | Description |
|---|---|---|
typename |
String |
The type name to instantiate. |
SaveData(): Serializes the unit operation, with its Config written as a Config element.
Serializes the unit operation, with its Config written as a Config element.
SetPropertyValue(string, object, IUnitsOfMeasure): Sets the value of a property.
Sets the value of a property.
| Parameter | Type | Description |
|---|---|---|
prop |
String |
Property identifier. |
propval |
Object |
Property value to set at the specified units. |
su |
IUnitsOfMeasure |
Units system to use. Null to use the default (SI) system. |