We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/gabrielserrao/pyrestoolbox-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""Reservoir heterogeneity analysis example.
This example demonstrates Lorenz coefficient calculations and
layer property generation for reservoir simulation.
"""
import asyncio
from fastmcp.client import Client
from pyrestoolbox_mcp import mcp
async def heterogeneity_analysis():
"""Reservoir heterogeneity analysis workflow."""
# Client context
async with Client(mcp) as client:
print("=" * 80)
print("Reservoir Heterogeneity Analysis")
print("=" * 80)
# Example 1: Convert Lorenz to Beta
print("\nExample 1: Lorenz Coefficient to Beta Conversion")
print("-" * 80)
lorenz_values = [0.2, 0.4, 0.6, 0.8]
print(f"{'Lorenz Coeff':>15} | {'Beta':>10} | {'Interpretation':>20}")
print("-" * 50)
for lc in lorenz_values:
beta_result = await client.call_tool(
"lorenz_to_beta",
{"value": lc},
)
beta = beta_result["beta"]
if lc < 0.3:
interp = "Homogeneous"
elif lc < 0.6:
interp = "Moderate"
else:
interp = "Heterogeneous"
print(f"{lc:15.3f} | {beta:10.4f} | {interp:>20}")
# Example 2: Convert Beta to Lorenz
print("\nExample 2: Beta to Lorenz Coefficient Conversion")
print("-" * 80)
beta_values = [0.3, 0.5, 0.7, 0.9]
print(f"{'Beta':>10} | {'Lorenz Coeff':>15} | {'Interpretation':>20}")
print("-" * 50)
for beta_val in beta_values:
lorenz_result = await client.call_tool(
"beta_to_lorenz",
{"value": beta_val},
)
lc = lorenz_result["lorenz_coefficient"]
if lc < 0.3:
interp = "Homogeneous"
elif lc < 0.6:
interp = "Moderate"
else:
interp = "Heterogeneous"
print(f"{beta_val:10.3f} | {lc:15.4f} | {interp:>20}")
# Example 3: Calculate Lorenz from flow fractions
print("\nExample 3: Lorenz from Production Data")
print("-" * 80)
# Simulated PLT data: flow fractions and kh fractions for 5 layers
flow_fracs = [0.45, 0.25, 0.15, 0.10, 0.05] # Flow allocation
perm_fracs = [0.30, 0.25, 0.20, 0.15, 0.10] # kh allocation
lorenz_from_data = await client.call_tool(
"lorenz_from_flow_fractions",
{
"flow_frac": flow_fracs,
"perm_frac": perm_fracs,
},
)
print(f"Number of Layers: {lorenz_from_data['number_of_layers']}")
print(f"Lorenz Coefficient: {lorenz_from_data['lorenz_coefficient']:.4f}")
print(f"Interpretation: {lorenz_from_data['interpretation']}")
print("\nLayer-by-Layer Analysis:")
print(f"{'Layer':>8} | {'Flow %':>10} | {'kh %':>10} | {'Ratio':>10}")
print("-" * 45)
for i, (ff, pf) in enumerate(zip(flow_fracs, perm_fracs)):
ratio = ff / pf if pf > 0 else 0
print(f"{i+1:8d} | {ff*100:10.2f} | {pf*100:10.2f} | {ratio:10.2f}")
# Example 4: Generate layer distribution
print("\nExample 4: Generate Layer Permeability Distribution")
print("-" * 80)
lorenz_target = 0.6
n_layers = 10
total_h = 100.0 # Total thickness (ft)
avg_k = 150.0 # Average permeability (mD)
layer_dist = await client.call_tool(
"generate_layer_distribution",
{
"lorenz": lorenz_target,
"nlay": n_layers,
"h": total_h,
"k_avg": avg_k,
},
)
print(f"Target Lorenz Coefficient: {lorenz_target:.2f}")
print(f"Number of Layers: {n_layers}")
print(f"Total Thickness: {total_h:.1f} ft")
print(f"Average Permeability: {avg_k:.1f} mD")
print(f"\n{'Layer':>8} | {'h (ft)':>10} | {'k (mD)':>10} | {'h_frac':>10} | {'kh_frac':>10}")
print("-" * 55)
for layer in layer_dist["layers"]:
print(
f"{layer['layer']:8d} | {layer['thickness_ft']:10.2f} | "
f"{layer['permeability_md']:10.2f} | {layer['thickness_fraction']:10.4f} | "
f"{layer['kh_fraction']:10.4f}"
)
stats = layer_dist["statistics"]
print("\nPermeability Statistics:")
print(f" Minimum: {stats['k_min_md']:.2f} mD")
print(f" Maximum: {stats['k_max_md']:.2f} mD")
print(f" Average: {stats['k_avg_md']:.2f} mD")
print(f" Median: {stats['k_median_md']:.2f} mD")
print(f" Std Dev: {stats['k_std_md']:.2f} mD")
print(f" Heterogeneity Ratio: {stats['heterogeneity_ratio']:.2f}")
# Example 5: Flow fractions from Lorenz
print("\nExample 5: Flow Fractions from Lorenz Coefficient")
print("-" * 80)
flow_profile = await client.call_tool(
"flow_fractions_from_lorenz",
{"value": lorenz_target},
)
print(f"Lorenz Coefficient: {lorenz_target:.2f}")
print(f"\nLorenz Curve Data (first 10 points):")
print(f"{'Cum Flow':>12} | {'Cum Storage':>15}")
print("-" * 30)
flow_cap = flow_profile["cumulative_flow_capacity"]
storage_cap = flow_profile["cumulative_storage_capacity"]
for i in range(min(10, len(flow_cap))):
print(f"{flow_cap[i]:12.4f} | {storage_cap[i]:15.4f}")
# Example 6: Compare different heterogeneity levels
print("\nExample 6: Compare Different Heterogeneity Levels")
print("-" * 80)
lorenz_levels = [0.2, 0.4, 0.6, 0.8]
print(f"\n{'Lorenz':>10} | {'k_min (mD)':>15} | {'k_max (mD)':>15} | {'Ratio':>10}")
print("-" * 55)
for lc in lorenz_levels:
dist = await client.call_tool(
"generate_layer_distribution",
{
"lorenz": lc,
"nlay": 10,
"h": 100.0,
"k_avg": 150.0,
},
)
stats = dist["statistics"]
print(
f"{lc:10.2f} | {stats['k_min_md']:15.2f} | {stats['k_max_md']:15.2f} | "
f"{stats['heterogeneity_ratio']:10.2f}"
)
print("\n" + "=" * 80)
print("Reservoir Heterogeneity Analysis completed successfully!")
print("=" * 80)
if __name__ == "__main__":
asyncio.run(heterogeneity_analysis())