# 3pc-laminate

`3pc-laminate` is a Python library used to define a composite laminate and compute its properties based on classical lamination theory. It provides a `Laminate` class to define the stacking sequence of plies and compute its overall behavior, built upon the `Ply` class (provided by the `3pc-ply` package).

## Installation

Use the package manager [pip](https://pip.pypa.io/en/stable/) to install `3pc-laminate`. Since `3pc-laminate`, `3pc-ply` and `3pc-material` are publicly available on PyPI, you can install them directly:

```bash
pip install 3pc-laminate 3pc-ply 3pc-material
```

## API Reference

### `Laminate` Class

The primary component of this package is the `Laminate` class, which holds a stacking sequence of plies and dynamically calculates transformed stiffness matrices and engineering constants.

```python
from laminate.laminate import Laminate
```

#### Required Parameters

When initializing `Laminate` directly, the following parameters are required:

*   **`lamID`** *(str)*: Laminate identifier.
*   **`stacking_sequence`** *(list)*: List of `Ply` objects starting from the bottom of the laminate (at `-thickness/2.0`) and ending at the top of the laminate (at `+thickness/2.0`), i.e., full stacking sequence.
*   **`offset`** *(str or float)*: Reference plane offset from midplane. Can be `"top"`, `"bottom"`, `"mid"`, or a float value.

#### Calculated Properties

The class automatically calculates the following properties lazily:

*   **`thickness`**: Total laminate thickness.
*   **`rho`**: Average laminate density using rule of mixtures.
*   **`z`**: List of z-coordinates for each ply interface relative to the reference plane.
*   **`A`**: Extensional stiffness matrix of the laminate.
*   **`B`**: Coupling stiffness matrix of the laminate.
*   **`D`**: Bending stiffness matrix of the laminate.
*   **`ABD`**: Full stiffness matrix in the form of `[[A, B], [B, D]]`.
*   **`A44`**, **`A45`**, **`A55`**: Transverse shear stiffnesses.
*   **`gamma`**, **`delta`**: Laminate properties measuring the effects of D16 and D26 respectively.
*   **`Ex`**, **`Ey`**, **`Gxy`**, **`vxy`**, **`vyx`**: In-plane engineering constants.
*   **`Efx`**, **`Efy`**, **`Gfxy`**, **`vfxy`**, **`vfyx`**: Flexural engineering constants.
*   **`alphax`**, **`alphay`**, **`alphaxy`**: Thermal expansion coefficients.
*   **`betax`**, **`betay`**, **`betaxy`**: Hygral (moisture) expansion coefficients.

### Methods

#### `Laminate.fromDict(**kwargs)`

Initializes a `Laminate` instance using a dictionary of keyword arguments. This is ideal for loading configurations from JSON files or dictionaries.

---

## Usage Examples

### Basic Initialization

Below is an example of defining a laminate using plies and materials.

```python
from material.orthotropic import Orthotropic
from ply.ply import Ply
from laminate.laminate import Laminate

# Define the material first
zg_material = Orthotropic(
    matID="zg",
    E1=181.0, 
    E2=10.3,
    G12=7.17, 
    G13=7.17, 
    G23=7.17, 
    v12=0.28,
    rho=1.5
)

# Define plies
ply_0 = Ply(plyID="1", angle=0.0, material=zg_material, thickness=0.125)
ply_90 = Ply(plyID="2", angle=90.0, material=zg_material, thickness=0.125)

# Define laminate (0/90)s
lam = Laminate(
    lamID="lam_01", 
    stacking_sequence=[ply_0, ply_90, ply_90, ply_0],
    offset="mid"
)

# Access Computed Properties
print("A Matrix:\\n", lam.A)
print("Effective Ex:", lam.Ex)
print("Effective Ey:", lam.Ey)
```

### Initializing from a Dictionary

You can load your laminate directly from a dictionary.

```python
lam_dict = {
    "lamID": "lam_02",
    "stacking_sequence": [ply_0, ply_90],
    "offset": "bottom"
}

lam_2 = Laminate.fromDict(**lam_dict)
print("Total thickness:", lam_2.thickness)
```

## Commands

The package provides a command-line interface entry point. After installing, you can run the main application using:

```bash
laminate
```
*(Currently, this serves as an entry point defined in `laminate.main:main`)*
