Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .github/workflows/CI_FAModel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@ jobs:
run: |
pip install git+https://github.com/NREL/MoorPy@dev

- name: Example run
run: |
cd examples
python example_driver.py false

- name: Test run
run: |
cd tests
pytest .

# - name: Example run
# run: |
# cd examples
# python example_driver.py false


83 changes: 83 additions & 0 deletions examples/05_Anchors/anchor_helical.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@

from famodel.anchors.anchor import Anchor

# --- Soil profile for helical pile in clay ---
profile_map = [
{
'name': 'CPT_H1',
'x': 0.0, 'y': 0.0,
'layers': [
{'top': 1.0, 'bottom': 3.0, 'soil_type': 'clay', 'gamma_top': 8.0, 'gamma_bot': 9.0, 'Su_top': 60, 'Su_bot': 50},
{'top': 3.0, 'bottom': 7.0, 'soil_type': 'clay', 'gamma_top': 15.0, 'gamma_bot': 25.0, 'Su_top': 100, 'Su_bot': 150},
{'top': 7.0, 'bottom': 25.0, 'soil_type': 'clay', 'gamma_top': 25.0, 'gamma_bot': 50.0, 'Su_top': 200, 'Su_bot': 400}
]
}
]

# --- Define helical anchor ---
anchor = Anchor(
dd = {
'type': 'helical',
'design': {
'D': 1.5, # Helix diameter (m)
'L': 12.0, # Total length (m)
'd': 0.5, # Shaft diameter (m)
'zlug': 3.0 # Padeye depth (m)
}
},
r = [0.0, 0.0, 0.0]
)

# --- Assign mooring loads and properties ---
anchor.loads = {
'Hm': 80e4,
'Vm': 50e3
}
anchor.line_type = 'chain'
anchor.d = 0.16
anchor.w = 5000.0

# --- Assign local soil ---
anchor.setSoilProfile(profile_map)

# --- Step 1: Lug Forces ---
layers, Ha, Va = anchor.getLugForces(
Hm = anchor.loads['Hm'],
Vm = anchor.loads['Vm'],
zlug = anchor.dd['design']['zlug'],
line_type = anchor.line_type,
d = anchor.d,
w = anchor.w,
plot = True
)

print('\nLug Forces Computed:')
print(f'Ha = {Ha:.2f} N')
print(f'Va = {Va:.2f} N')

# --- Step 2: Capacity ---
anchor.getCapacityAnchor(
Hm = anchor.loads['Hm'],
Vm = anchor.loads['Vm'],
zlug = anchor.dd['design']['zlug'],
line_type = anchor.line_type,
d = anchor.d,
w = anchor.w,
plot = False
)

print('\nCapacity Results:')
for key, val in anchor.anchorCapacity.items():
print(f'{key}: {val:.2f}')

# --- Step 3: Optimize Anchor Geometry ---
anchor.getSizeAnchor(
geom = [anchor.dd['design']['L'], anchor.dd['design']['D']],
geomKeys = ['L', 'D'],
geomBounds = [(6.0, 25.0), (0.5, 2.0)],
loads = None,
lambdap_con = [6, 15],
zlug_fix = True,
safety_factor = {'SF_horizontal': 1, 'SF_vertical': 1},
plot = False
)
82 changes: 82 additions & 0 deletions examples/05_Anchors/anchor_pile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@

from famodel.anchors.anchor import Anchor

# --- Define soil profile ---
profile_map = [
{
'name': 'CPT_D1',
'x': 0.0, 'y': 0.0,
'layers': [
{'top': 1.0, 'bottom': 6.0, 'soil_type': 'clay', 'gamma_top': 9.0, 'gamma_bot': 10.0, 'Su_top': 25, 'Su_bot': 40},
{'top': 6.0, 'bottom': 15.0, 'soil_type': 'clay', 'gamma_top': 10.0, 'gamma_bot': 10.0, 'Su_top': 80, 'Su_bot': 100},
{'top': 15.0, 'bottom': 35.0, 'soil_type': 'clay', 'gamma_top': 10.0, 'gamma_bot': 10.5, 'Su_top': 100, 'Su_bot': 100}
]
}
]

# --- Create driven pile anchor ---
anchor = Anchor(
dd = {
'type': 'driven',
'design': {
'L': 15.0, # Embedded length
'D': 1.75, # Diameter
'zlug': 3.0 # Padeye depth
}
},
r = [0.0, 0.0, 0.0]
)

# Assign mooring loads
anchor.loads = {
'Hm': 8.0e5,
'Vm': 2.5e5
}
anchor.line_type = 'chain'
anchor.d = 0.16
anchor.w = 5000.0

# Assign local soil
anchor.setSoilProfile(profile_map)

# --- Step 1: Lug Forces ---
layers, Ha, Va = anchor.getLugForces(
Hm = anchor.loads['Hm'],
Vm = anchor.loads['Vm'],
zlug = anchor.dd['design']['zlug'],
line_type = anchor.line_type,
d = anchor.d,
w = anchor.w,
plot = True
)

print('\nLug Forces Computed:')
print(f'Ha = {Ha:.2f} N')
print(f'Va = {Va:.2f} N')

# --- Step 2: Capacity ---
anchor.getCapacityAnchor(
Hm = anchor.loads['Hm'],
Vm = anchor.loads['Vm'],
zlug = anchor.dd['design']['zlug'],
line_type = anchor.line_type,
d = anchor.d,
w = anchor.w,
plot = True
)

print('\nCapacity Results:')
for key, val in anchor.anchorCapacity.items():
print(f'{key}: {val:.2f}')

# --- Step 3: Optimize Anchor Geometry ---
anchor.getSizeAnchor(
geom = [anchor.dd['design']['L'], anchor.dd['design']['D']],
geomKeys = ['L', 'D'],
geomBounds = [(2.0, 70.0), (0.25, 3.0)],
loads = None,
lambdap_con = [4, 50],
zlug_fix = True,
safety_factor = {'SF_horizontal': 1, 'SF_vertical': 1},
plot = True
)
77 changes: 77 additions & 0 deletions examples/05_Anchors/anchor_plate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

from famodel.anchors.anchor import Anchor
from famodel.anchors.anchors_famodel.support_plots import plot_load

# --- Define soil profile ---
profile_map = [
{
'name': 'CPT_A1',
'x': 0.0, 'y': 0.0,
'layers': [
{'top': 2.0, 'bottom': 4.0, 'soil_type': 'clay', 'gamma_top': 8.0, 'gamma_bot': 8.5, 'Su_top': 10, 'Su_bot': 25},
{'top': 4.0, 'bottom': 6.0, 'soil_type': 'clay', 'gamma_top': 8.5, 'gamma_bot': 9.0, 'Su_top': 15, 'Su_bot': 40},
{'top': 6.0, 'bottom': 16.0, 'soil_type': 'clay', 'gamma_top': 9.0, 'gamma_bot': 9.5, 'Su_top': 50, 'Su_bot': 100},
{'top': 16.0, 'bottom': 25.0, 'soil_type': 'clay', 'gamma_top': 9.5, 'gamma_bot': 9.5, 'Su_top': 100, 'Su_bot': 100}
]
}
]

# --- Create plate anchor ---
anchor = Anchor(
dd = {'type': 'plate', 'design': {'B': 3.0, 'L': 6.0, 'zlug': 14.0, 'beta': 30.0}},
r = [100.0, 100.0, 0.0]
)

# --- Assign load and mooring properties ---
anchor.loads = {
'Hm': 3.5e6,
'Vm': 2.5e6
}
anchor.line_type = 'chain'
anchor.d = 0.16
anchor.w = 5000.0

# --- Set soil profile based on anchor location ---
anchor.setSoilProfile(profile_map)

# --- Step 1: Lug Forces ---
layers, Ha, Va = anchor.getLugForces(
Hm = anchor.loads['Hm'],
Vm = anchor.loads['Vm'],
zlug = anchor.dd['design']['zlug'],
line_type = anchor.line_type,
d = anchor.d,
w = anchor.w,
plot = True
)

print('\nLug Forces Computed:')
print(f'Ha = {Ha:.2f} N')
print(f'Va = {Va:.2f} N')

# --- Step 2: Capacity Evaluation ---
anchor.getCapacityAnchor(
Hm = anchor.loads['Hm'],
Vm = anchor.loads['Vm'],
zlug = anchor.dd['design']['zlug'],
line_type = anchor.line_type,
d = anchor.d,
w = anchor.w,
plot = True
)

print('\nCapacity Results:')
for key, value in anchor.anchorCapacity.items():
print(f'{key}: {value:.2f}')

# --- Step 3: Optimize Anchor Geometry ---
anchor.getSizeAnchor(
geom = [anchor.dd['design']['B'], anchor.dd['design']['L']],
geomKeys = ['B', 'L'],
geomBounds = [(0.5, 6.0), (2.0, 12.0)],
loads = None,
lambdap_con = [2, 4], # less critical for plates
zlug_fix = True,
safety_factor = {'SF_combined': 3},
plot = True
)
69 changes: 69 additions & 0 deletions examples/05_Anchors/anchor_soil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

import sys
sys.path.append(r'C:\Code\FAModel_anchors\famodel')

from project import Project
from anchors.anchor import Anchor

# Step 1: Initialize and load soil
proj = Project()
proj.loadSoil(
filename='inputs/GulfOfMaine_soil_layered_100x100.txt',
soil_mode='layered',
profile_source='inputs/GulfOfMaine_soil_profiles.yaml')

for label, props in proj.soilProps.items():
print(f"{label}: {props}")

# Step 2: Create and register an anchor at a known position in the grid
anchor = Anchor(
dd = {'type': 'suction', 'design': {'D': 2.5, 'L': 15.0, 'zlug': 10.67}},
r = [54.0, -4450.0, 0.0])

# Step 3: Assign local soil profile from project (nearest neighbor lookup)
soil_id, soil_profile = proj.getSoilAtLocation(anchor.r[0], anchor.r[1])
anchor.soilProps = {soil_id: soil_profile}
anchor.setSoilProfile([{ 'name': soil_id, 'layers': soil_profile }]) # ensures `anchor.soil_profile` is set

# Step 4: Assign loads and line
anchor.loads = {'Hm': 2e6, 'Vm': 1.5e6}
anchor.line_type = 'chain'
anchor.d = 0.16
anchor.w = 5000.0

# Step 5: Run capacity check and optimization
anchor.getLugForces(
Hm=anchor.loads['Hm'], Vm=anchor.loads['Vm'],
zlug = anchor.dd['design']['zlug'],
d=anchor.d, w=anchor.w,
plot=True)

anchor.getCapacityAnchor(
Hm=anchor.loads['Hm'], Vm=anchor.loads['Vm'],
zlug = anchor.dd['design']['zlug'],
line_type=anchor.line_type, d=anchor.d, w=anchor.w,
mass_update=True,
plot=True)
anchor.getCostAnchor()
print(f'Material cost: {anchor.cost["Material cost"]:.2f} USD [2024]')

results = anchor.getSizeAnchor_gradient(
geom=[anchor.dd['design']['L'], anchor.dd['design']['D']],
geomKeys= ['L','D'],
geomBounds=[(12.0, 18.0), (1.5, 3.5)],
safety_factor={'SF_combined': 1},
zlug_fix=False,
lambdap_con=[4, 6],
step_size=0.2,
tol=0.05,
max_iter=30,
verbose=True)

# Step 6: Report
print('\nFinal Optimized Anchor:')
print('Design:', anchor.dd['design'])
print('Capacity Results:', anchor.anchorCapacity)
anchor.getCostAnchor()
print(f'Material cost: {anchor.cost["Material cost"]:.2f} USD [2024]')


Loading
Loading