Skip to main content
Glama
gabrielserrao

pyResToolbox MCP Server

generate_layer_distribution

Generate permeability and thickness distributions for reservoir simulation layers using Lorenz coefficient to model heterogeneity for waterflood performance prediction.

Instructions

Generate layered permeability distribution from Lorenz coefficient.

LAYER PROPERTY GENERATION - Creates detailed layer-by-layer permeability and thickness distribution matching specified heterogeneity. Essential for building reservoir simulation models and predicting waterflood performance.

Parameters:

  • lorenz (float, required): Lorenz coefficient (0-1). Must be 0 ≤ L ≤ 1. Typical: 0.2-0.7. Example: 0.6 for moderate heterogeneity.

  • nlay (int, required): Number of layers to generate. Must be > 0. Typical: 5-50. Example: 10 for 10-layer model.

  • k_avg (float, required): Average permeability in mD. Must be > 0. Typical: 10-1000 mD. Example: 100.0 mD.

  • h (float, optional, default=100.0): Total thickness in feet. Must be > 0. Typical: 50-500 ft. Example: 100.0 ft.

Method: Uses Dykstra-Parsons log-normal permeability distribution with correlation to Lorenz coefficient to generate realistic layer properties:

  1. Convert Lorenz to beta parameter

  2. Generate log-normal permeability distribution

  3. Sort layers by permeability (ascending)

  4. Assign equal thickness to each layer

  5. Calculate layer statistics

Output Properties: For each layer:

  • Thickness (ft): Layer thickness (equal for all layers)

  • Permeability (mD): Layer permeability (log-normal distribution)

  • Thickness Fraction: Fraction of total thickness

  • kh Fraction: Fraction of total flow capacity (k × h)

Statistics Calculated:

  • k_min, k_max: Minimum and maximum permeability

  • k_avg, k_median: Average and median permeability

  • k_std: Standard deviation

  • Heterogeneity ratio: k_max / k_min

Critical for:

  • Reservoir Simulation: Generate layer properties for simulation models

  • Waterflood Prediction: Predict sweep efficiency and recovery

  • Vertical Sweep Efficiency: Analyze vertical conformance

  • Conformance Studies: Evaluate production allocation

  • Upscaling: Create coarse-scale models from fine-scale data

  • Sensitivity Analysis: Test impact of heterogeneity on performance

Usage Example: For 10-layer simulation model with Lorenz=0.6:

{
    "lorenz": 0.6,
    "nlay": 10,
    "k_avg": 100.0,
    "h": 100.0
}

Result: 10 layers with permeabilities ranging from ~20 mD (low-k) to ~500 mD (high-k), each with 10 ft thickness. High-k layers have higher kh fractions.

Returns: Dictionary with:

  • layers (list): List of dicts with layer properties (thickness, permeability, fractions)

  • statistics (dict): Permeability statistics (min, max, avg, median, std, ratio)

  • total_thickness_ft (float): Total thickness

  • average_permeability_md (float): Average permeability

  • lorenz_coefficient (float): Input Lorenz coefficient

  • number_of_layers (int): Number of layers

  • method (str): "Dykstra-Parsons log-normal distribution"

  • note (str): Usage guidance

  • inputs (dict): Echo of input parameters

Common Mistakes:

  • Lorenz coefficient outside valid range (must be 0-1)

  • Too few layers (<5) causing poor resolution

  • Too many layers (>50) causing unnecessary complexity

  • Wrong average permeability (must match reservoir average)

  • Not understanding that layers are sorted by permeability

  • Confusing thickness fraction with absolute thickness

Example Usage:

{
    "lorenz": 0.6,
    "nlay": 10,
    "k_avg": 100.0,
    "h": 100.0
}

Result: 10 layers with log-normal permeability distribution, each 10 ft thick. Permeability ranges from ~20 mD to ~500 mD, matching Lorenz=0.6 heterogeneity.

Note: This generates idealized layer properties assuming log-normal permeability distribution and equal layer thickness. For actual reservoirs, use measured core or log data when available. Layer properties are ready for direct use in reservoir simulation models.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
requestYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The core handler function for the 'generate_layer_distribution' tool. It uses pyrestoolbox.layer.lorenz_2_layers to generate a log-normal permeability distribution across the specified number of layers matching the input Lorenz coefficient, computes layer properties (thickness, perm, fractions), statistics, and returns structured output.
    @mcp.tool()
    def generate_layer_distribution(request: LayerDistributionRequest) -> dict:
        """Generate layered permeability distribution from Lorenz coefficient.
    
        **LAYER PROPERTY GENERATION** - Creates detailed layer-by-layer permeability
        and thickness distribution matching specified heterogeneity. Essential for
        building reservoir simulation models and predicting waterflood performance.
    
        **Parameters:**
        - **lorenz** (float, required): Lorenz coefficient (0-1). Must be 0 ≤ L ≤ 1.
          Typical: 0.2-0.7. Example: 0.6 for moderate heterogeneity.
        - **nlay** (int, required): Number of layers to generate. Must be > 0.
          Typical: 5-50. Example: 10 for 10-layer model.
        - **k_avg** (float, required): Average permeability in mD. Must be > 0.
          Typical: 10-1000 mD. Example: 100.0 mD.
        - **h** (float, optional, default=100.0): Total thickness in feet.
          Must be > 0. Typical: 50-500 ft. Example: 100.0 ft.
    
        **Method:**
        Uses Dykstra-Parsons log-normal permeability distribution with correlation
        to Lorenz coefficient to generate realistic layer properties:
        1. Convert Lorenz to beta parameter
        2. Generate log-normal permeability distribution
        3. Sort layers by permeability (ascending)
        4. Assign equal thickness to each layer
        5. Calculate layer statistics
    
        **Output Properties:**
        For each layer:
        - **Thickness (ft):** Layer thickness (equal for all layers)
        - **Permeability (mD):** Layer permeability (log-normal distribution)
        - **Thickness Fraction:** Fraction of total thickness
        - **kh Fraction:** Fraction of total flow capacity (k × h)
    
        **Statistics Calculated:**
        - k_min, k_max: Minimum and maximum permeability
        - k_avg, k_median: Average and median permeability
        - k_std: Standard deviation
        - Heterogeneity ratio: k_max / k_min
    
        **Critical for:**
        - **Reservoir Simulation:** Generate layer properties for simulation models
        - **Waterflood Prediction:** Predict sweep efficiency and recovery
        - **Vertical Sweep Efficiency:** Analyze vertical conformance
        - **Conformance Studies:** Evaluate production allocation
        - **Upscaling:** Create coarse-scale models from fine-scale data
        - **Sensitivity Analysis:** Test impact of heterogeneity on performance
    
        **Usage Example:**
        For 10-layer simulation model with Lorenz=0.6:
        ```python
        {
            "lorenz": 0.6,
            "nlay": 10,
            "k_avg": 100.0,
            "h": 100.0
        }
        ```
        Result: 10 layers with permeabilities ranging from ~20 mD (low-k) to ~500 mD
        (high-k), each with 10 ft thickness. High-k layers have higher kh fractions.
    
        **Returns:**
        Dictionary with:
        - **layers** (list): List of dicts with layer properties (thickness, permeability, fractions)
        - **statistics** (dict): Permeability statistics (min, max, avg, median, std, ratio)
        - **total_thickness_ft** (float): Total thickness
        - **average_permeability_md** (float): Average permeability
        - **lorenz_coefficient** (float): Input Lorenz coefficient
        - **number_of_layers** (int): Number of layers
        - **method** (str): "Dykstra-Parsons log-normal distribution"
        - **note** (str): Usage guidance
        - **inputs** (dict): Echo of input parameters
    
        **Common Mistakes:**
        - Lorenz coefficient outside valid range (must be 0-1)
        - Too few layers (<5) causing poor resolution
        - Too many layers (>50) causing unnecessary complexity
        - Wrong average permeability (must match reservoir average)
        - Not understanding that layers are sorted by permeability
        - Confusing thickness fraction with absolute thickness
    
        **Example Usage:**
        ```python
        {
            "lorenz": 0.6,
            "nlay": 10,
            "k_avg": 100.0,
            "h": 100.0
        }
        ```
        Result: 10 layers with log-normal permeability distribution, each 10 ft thick.
        Permeability ranges from ~20 mD to ~500 mD, matching Lorenz=0.6 heterogeneity.
    
        **Note:** This generates idealized layer properties assuming log-normal
        permeability distribution and equal layer thickness. For actual reservoirs,
        use measured core or log data when available. Layer properties are ready
        for direct use in reservoir simulation models.
        """
        # lorenz_2_layers returns np.ndarray of permeabilities, assuming equal thickness
        k_values = layer.lorenz_2_layers(
            lorenz=request.lorenz,
            nlayers=request.nlay,
            k_avg=request.k_avg,
        )
        
        # Assume equal thickness layers
        h_values = np.ones(request.nlay) * request.h / request.nlay
        
        layer_data = []
        for i in range(request.nlay):
            layer_data.append({
                "layer": i + 1,
                "thickness_ft": float(h_values[i]),
                "permeability_md": float(k_values[i]),
                "thickness_fraction": float(h_values[i] / np.sum(h_values)),
                "kh_fraction": float(
                    k_values[i] * h_values[i] / np.sum(k_values * h_values)
                ),
            })
    
        # Calculate statistics
        statistics = {
            "k_min_md": float(np.min(k_values)),
            "k_max_md": float(np.max(k_values)),
            "k_avg_md": float(np.mean(k_values)),
            "k_median_md": float(np.median(k_values)),
            "k_std_md": float(np.std(k_values)),
            "heterogeneity_ratio": float(np.max(k_values) / np.min(k_values)),
        }
    
        return {
            "layers": layer_data,
            "statistics": statistics,
            "total_thickness_ft": float(np.sum(h_values)),
            "average_permeability_md": request.k_avg,
            "lorenz_coefficient": request.lorenz,
            "number_of_layers": request.nlay,
            "method": "Dykstra-Parsons log-normal distribution",
            "inputs": request.model_dump(),
            "note": "Use layer properties directly in reservoir simulation models",
        }
  • Pydantic BaseModel defining the input schema (LayerDistributionRequest) with validation for lorenz (0-1), nlay (1-100), h (>0), k_avg (>0), normalize (bool). Includes example in json_schema_extra.
    class LayerDistributionRequest(BaseModel):
        """Request model for layer distribution generation."""
    
        model_config = ConfigDict(
            json_schema_extra={
                "example": {
                    "lorenz": 0.7,
                    "nlay": 10,
                    "normalize": True,
                }
            }
        )
    
        lorenz: float = Field(
            ..., ge=0, le=1, description="Lorenz coefficient (0=homogeneous, 1=heterogeneous)"
        )
        nlay: int = Field(..., gt=0, le=100, description="Number of layers")
        h: float = Field(1.0, gt=0, description="Total thickness (ft, default=1 for normalized)")
        k_avg: float = Field(
            1.0, gt=0, description="Average permeability (mD, default=1 for normalized)"
        )
        normalize: bool = Field(
            True, description="Normalize output (h and k fractions vs absolute)"
        )
  • Explicit registration of all layer tools (including generate_layer_distribution) by calling register_layer_tools(mcp) in the main server setup.
    register_layer_tools(mcp)
  • Import of the register_layer_tools function used to register the layer tools module.
    from .tools.layer_tools import register_layer_tools
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and excels at behavioral disclosure. It explains the mathematical method (Dykstra-Parsons log-normal distribution), output structure, common mistakes, limitations (idealized properties vs actual reservoir data), and specific constraints like layer sorting and equal thickness assignment.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is comprehensive but lengthy with some redundancy (usage example appears twice). While well-structured with clear sections, it could be more concise by eliminating repetition and tightening some explanations without losing essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity, no annotations, and rich output schema, the description provides complete context. It explains the method, output structure, applications, limitations, and practical considerations, making it fully self-contained for an AI agent to understand and use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Despite 0% schema description coverage, the description provides extensive parameter documentation including purpose, valid ranges, typical values, examples, and practical guidance. It covers all parameters (lorenz, nlay, k_avg, h) and explains their relationships and constraints beyond what the bare schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool generates layered permeability distributions from a Lorenz coefficient, specifying it creates detailed layer-by-layer permeability and thickness distributions. It distinguishes from siblings by focusing on reservoir simulation model building and waterflood prediction, which none of the sibling tools mention.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool (reservoir simulation, waterflood prediction, conformance studies, etc.) and includes a 'Critical for' section with specific applications. However, it doesn't explicitly state when NOT to use it or name specific alternative tools among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

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