Coder Social home page Coder Social logo

wisdem / wombat Goto Github PK

View Code? Open in Web Editor NEW
20.0 13.0 11.0 367.3 MB

Windfarm Operations & Maintenance cost-Benefit Analysis Tool

Home Page: https://wisdem.github.io/WOMBAT/

License: Apache License 2.0

Python 99.83% TeX 0.17%
simulation wind-energy python3 simpy operations-maintenance

wombat's Introduction

WISDEM®

Actions Status Coverage Status Documentation Status

The Wind-Plant Integrated System Design and Engineering Model (WISDEM®) is a set of models for assessing overall wind plant cost of energy (COE). The models use wind turbine and plant cost and energy production as well as financial models to estimate COE and other wind plant system attributes. WISDEM® is accessed through Python, is built using OpenMDAO, and uses several sub-models that are also implemented within OpenMDAO. These sub-models can be used independently but they are required to use the overall WISDEM® turbine design capability. Please install all of the pre-requisites prior to installing WISDEM® by following the directions below. For additional information about the NWTC effort in systems engineering that supports WISDEM® development, please visit the official NREL systems engineering for wind energy website.

Author: NREL WISDEM Team

Documentation

See local documentation in the docs-directory or access the online version at https://wisdem.readthedocs.io/en/master/

Packages

WISDEM® is a family of modules. The core modules are:

  • CommonSE includes several libraries shared among modules
  • FloatingSE works with the floating platforms
  • DrivetrainSE sizes the drivetrain and generator systems (formerly DriveSE and GeneratorSE)
  • TowerSE is a tool for tower (and monopile) design
  • RotorSE is a tool for rotor design
  • NREL CSM is the regression-based turbine mass, cost, and performance model
  • ORBIT is the process-based balance of systems cost model for offshore plants
  • LandBOSSE is the process-based balance of systems cost model for land-based plants
  • Plant_FinanceSE runs the financial analysis of a wind plant

The core modules draw upon some utility packages, which are typically compiled code with python wrappers:

  • Airfoil Preppy is a tool to handle airfoil polar data
  • CCBlade is the BEM module of WISDEM
  • pyFrame3DD brings libraries to handle various coordinate transformations
  • MoorPy is a quasi-static mooring line model
  • pyOptSparse provides some additional optimization algorithms to OpenMDAO

Installation

Installation with Anaconda is the recommended approach because of the ability to create self-contained environments suitable for testing and analysis. WISDEM® requires Anaconda 64-bit. However, the conda command has begun to show its age and we now recommend the one-for-one replacement with the Miniforge3 distribution, which is much more lightweight and more easily solves for the WISDEM package dependencies.

Installation as a "library"

To use WISDEM's modules as a library for incorporation into other scripts or tools, WISDEM is available via conda install wisdem or pip install wisdem, assuming that you have already setup your python environment. Note that on Windows platforms, we suggest using conda exclusively.

Installation for direct use

These instructions are for interaction with WISDEM directly, the use of its examples, and the direct inspection of its source code.

The installation instructions below use the environment name, "wisdem-env," but any name is acceptable. For those working behind company firewalls, you may have to change the conda authentication with conda config --set ssl_verify no. Proxy servers can also be set with conda config --set proxy_servers.http http://id:pw@address:port and conda config --set proxy_servers.https https://id:pw@address:port. To setup an environment based on a different Github branch of WISDEM, simply substitute the branch name for master in the setup line.

  1. Setup and activate the Anaconda environment from a prompt (Anaconda3 Power Shell on Windows or Terminal.app on Mac)

    conda config --add channels conda-forge
    conda env create --name wisdem-env -f https://raw.githubusercontent.com/WISDEM/WISDEM/master/environment.yml
    conda activate wisdem-env
    
  2. In order to directly use the examples in the repository and peek at the code when necessary, we recommend all users install WISDEM in developer / editable mode using the instructions here. If you really just want to use WISDEM as a library and lean on the documentation, you can always do conda install wisdem and be done. Note the differences between Windows and Mac/Linux build systems. For Linux, we recommend using the native compilers (for example, gcc and gfortran in the default GNU suite).

    conda install -y petsc4py mpi4py                 # (Mac / Linux only)
    conda install -y gfortran                        # (Mac only without Homebrew or Macports compilers)
    conda install -y m2w64-toolchain libpython       # (Windows only)
    git clone https://github.com/WISDEM/WISDEM.git
    cd WISDEM
    pip install --no-deps -e . -v
    

NOTE: To use WISDEM again after installation is complete, you will always need to activate the conda environment first with conda activate wisdem-env

Run Unit Tests

Each package has its own set of unit tests. These can be run in batch with the test_all.py script located in the top level test-directory.

Feedback

For software issues please use https://github.com/WISDEM/WISDEM/issues. For functionality and theory related questions and comments please use the NWTC forum for Systems Engineering Software Questions.

wombat's People

Contributors

dmulas avatar gbarter avatar pre-commit-ci[bot] avatar rhammond2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wombat's Issues

Strings with a fork don't resolve correctly

When an array cable string splits into two diverging upstream paths, the upstream cable/turbine connections don't resolve correctly. Likely a customized graph model is required for this scenario instead of a sequentially defined, CSV-based model.

More sensible repair time starts

It would be great if any operations at site wouldn't start until the next shift if less than an hour or two of work will be done on that task in the current shift.

Alternatively, it could make sense for shifts to be continuous with a rotating crew for x number of days until a vessel refresh is required, with a default of a single shift to maintain compatibility with land-based servicing regimes.

Weather Model

To better understand the tradeoffs in weather conditions, it would be ideal to have a probabilistic weather model, as opposed to a fixed weather model. In addition, it would enable more robust model comparison for various global regions with some predefined inputs to be used for weather profile generation instead of creating/downloading and modifying unique weather profiles.

Windfarm/Turbine Losses Model

A model to post-hoc apply aggregate model losses (wake, electrical, etc.) would be ideal to better translate between the power production model and what is typically seen in operational analyses.

Double counting weather delays

If CTVs are always on site, the total duration of all activities should be equal to the simulation period. This isn't the case. Comparing the cumulative CTV activity duration and the env_time, it looks like the CTV is allowing 2x each weather delay to elapse before it tries to do anything. This also appears to be true for vessels that are not always on site.

distance_km is NaN for CTVs

With the latest update, the distance_km output metric is reporting NaN for CTVs (and sometimes DSVs but not always). Nothing is obviously wrong with the CTV distances in the events log
image

Random seed not respected when specified in configuration file that is loaded automatically given a library path and configuration file name

I seem to have found a small bug in which the random seed I set in my configuration file is not being used in the simulation.

I created my simulation using Simulation() rather than the Simulation.from_config(). Unlike when using the from_config function, when using the default class initialization my random seed loads correctly as part of the Simulation.config attribute but is not applied to the Simulation.random_seed attribute directly. When Simulation._setup_simulation() calls, it passes only the random_seed attribute on the simulation object, not the version from the config attribute, when it instantiates the WombatEnvironment class. As a result, the environment detects no random seed.

Apologies if I have misunderstood something, but it seems like this is probably not the desired behaviour. Everything works fine if I pass the random seed directly as a parameter into the Simulation() function, or if I load using from_config(), so it seems to just be this one case which has the problem.

I am using WOMBAT v0.9.3.

Monte Carlo Simulation Methodoloy

To better understand the effect of model uncertainty, it would be great to have the ability to model a probability distribution surrounding the failure rates in the model.

Additional Weather Constraint Support

Enable the ability to model sea surface icing or turbine icing for crew accessibility/safety constraints. This would require humidity, temperature, and visibility constraints (helicopter access).

Multi-Crew Handoff

Functionality to enable multiple service crews in one servicing equipment, particularly for offshore wind scenarios would enable more realistic crew transfer vessel functionality

Event log file does not have headers or column names

I was running the how_to jupyter notebook (see the code that I ran below) and encounter the following errors. I think the issue is that the code expects the first column of the event log file to have the column names. I can resolve this issue by setting the read_option to be ReadOptions(autogenerate_column_names=True), but then another error popped up as the code is expecting the some fixed column names such as date_time.

Code

from time import perf_counter
from wombat import Simulation
from wombat.core.library import load_yaml, DINWOODIE

library_path = DINWOODIE
config = load_yaml(library_path / "project/config", "base.yaml")
sim = Simulation.from_config(config)
sim.env.cleanup_log_files()

start = perf_counter()
sim.run()
end = perf_counter()
timing = end - start
print(f"Run time: {timing / 60:,.2f} minutes")

Error Message

ValueError                                Traceback (most recent call last)
Cell In[2], line 2
      1 start = perf_counter()
----> 2 sim.run()
      3 end = perf_counter()
      4 timing = end - start

File ~/miniconda3/envs/wisdem/lib/python3.10/site-packages/wombat/core/simulation_api.py:326, in Simulation.run(self, until, create_metrics, save_metrics_inputs)
    324     self.save_metrics_inputs()
    325 if create_metrics:
--> 326     self.initialize_metrics()

File ~/miniconda3/envs/wisdem/lib/python3.10/site-packages/wombat/core/simulation_api.py:330, in Simulation.initialize_metrics(self)
    328 def initialize_metrics(self) -> None:
    329     """Instantiates the ``metrics`` attribute after the simulation is run."""
--> 330     events = self.env.load_events_log_dataframe()
    331     operations = self.env.load_operations_log_dataframe()
    332     power_potential, power_production = self.env.power_production_potential_to_csv(
    333         windfarm=self.windfarm, operations=operations, return_df=True
    334     )

File ~/miniconda3/envs/wisdem/lib/python3.10/site-packages/wombat/core/environment.py:679, in WombatEnvironment.load_events_log_dataframe(self)
    671 convert_options = pa.csv.ConvertOptions(
    672     timestamp_parsers=["%Y-%m-%d %H:%M:%S.%f", "%Y-%m-%d %H:%M:%S"]
    673 )
    674 parse_options = pa.csv.ParseOptions(delimiter="|")
    675 log_df = pa.csv.read_csv(
    676     self.events_log_fname,
    677     convert_options=convert_options,
    678     parse_options=parse_options,
--> 679 ).to_pandas()
    680 if not pd.api.types.is_datetime64_any_dtype(log_df.datetime):
    681     log_df.datetime = pd.to_datetime(
    682         log_df.datetime, yearfirst=True, format="mixed"
    683     )

File ~/miniconda3/envs/wisdem/lib/python3.10/site-packages/pyarrow/array.pxi:837, in pyarrow.lib._PandasConvertible.to_pandas()

File ~/miniconda3/envs/wisdem/lib/python3.10/site-packages/pyarrow/table.pxi:4114, in pyarrow.lib.Table._to_pandas()

File ~/miniconda3/envs/wisdem/lib/python3.10/site-packages/pyarrow/pandas_compat.py:819, in table_to_blockmanager(options, table, categories, ignore_metadata, types_mapper)
    816     ext_columns_dtypes = _get_extension_dtypes(table, [], types_mapper)
    818 _check_data_column_metadata_consistency(all_columns)
--> 819 columns = _deserialize_column_index(table, all_columns, column_indexes)
    820 blocks = _table_to_blocks(options, table, categories, ext_columns_dtypes)
    822 axes = [columns, index]

File ~/miniconda3/envs/wisdem/lib/python3.10/site-packages/pyarrow/pandas_compat.py:938, in _deserialize_column_index(block_table, all_columns, column_indexes)
    935     columns = _reconstruct_columns_from_metadata(columns, column_indexes)
    937 # ARROW-1751: flatten a single level column MultiIndex for pandas 0.21.0
--> 938 columns = _flatten_single_level_multiindex(columns)
    940 return columns

File ~/miniconda3/envs/wisdem/lib/python3.10/site-packages/pyarrow/pandas_compat.py:1184, in _flatten_single_level_multiindex(index)
   1182     # Cheaply check that we do not somehow have duplicate column names
   1183     if not index.is_unique:
-> 1184         raise ValueError('Found non-unique column index')
   1186     return pd.Index(
   1187         [levels[_label] if _label != -1 else None for _label in labels],
   1188         dtype=dtype,
   1189         name=index.names[0]
   1190     )
   1191 return index

ValueError: Found non-unique column index

First 4 lines of the event log file (note no column names)

2023-06-20 21:56:06.625773|2003-01-01 00:00:00|0|S00T1|subassemblies created: ['turbine']|windfarm initialization|initialization|S00T1|S00T1|||1.0|1|0|0|na|na|0|0|0|0|0|0
2023-06-20 21:56:06.657014|2003-01-01 00:00:00|0|S00T2|subassemblies created: ['turbine']|windfarm initialization|initialization|S00T2|S00T2|||1.0|1|0|0|na|na|0|0|0|0|0|0
2023-06-20 21:56:06.685828|2003-01-01 00:00:00|0|S00T3|subassemblies created: ['turbine']|windfarm initialization|initialization|S00T3|S00T3|||1.0|1|0|0|na|na|0|0|0|0|0|0

Swap Pandas out for Polars for simulation-specific tasks

Pandas 2.0 has greatly decreased the runtime performance of WOMBAT due to significantly slower indexing and search. Initial tests confirm that Polars is significantly faster at the exact operations required in the simulation, and so it'd be beneficial to convert the weather dataframe, specifically. Below is an example of extracting a single row from the weather profile in both pandas and polars.

image

Tow-to-Port Repair Logic

A major innovation in offshore wind will be tow-to-port repairs, and should be considered for the next batch of model updates.

Date-Based Maintenance

Potentially consider providing date, or set of dates for when to trigger a timeout instead of a fixed time frequency. This allows maintenance to be scheduled in particular times of year.

Tow-to-Port Costing Improvements

After some external review it would be best to revamp the tow-to-port model now that it works and does pretty well overall compare to other models.

  • Swap out the monthly fee for an annual lease fee
  • Include port usage fees
  • Include tugboat mobilization costs
  • Tugboats should attempt to find a suitable weather window prior to beginning the travel out to site, reducing the overall weather delays associated with tugboats

Support for weather profiles with many columns

Weather profiles that have more columns than ["datetime", "windspeed", "wave_height"] will cause an error here: https://github.com/WISDEM/WOMBAT/blob/main/wombat/core/environment.py#L520.

A simple fix such as the following could allow for more robust workflows using WOMBAT:

  1. reordering the columns to be in the expected order when setting up the weather data
  2. when getting the weather forecast in-code, use the following:
    wind, wave, hour, *_ = self.weather.values[start:end].T

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.