Skip to content
Snippets Groups Projects
h2_vs_hs2.py 50.1 KiB
Newer Older
# -*- coding: utf-8 -*-
"""
Created on Mon Nov  2 15:23:15 2015

@author: dave
"""
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import absolute_import
from builtins import range
from builtins import zip
from builtins import dict
from builtins import str
from builtins import int
from future import standard_library
standard_library.install_aliases()
from builtins import object

import os

import numpy as np
#import scipy.interpolate as interpolate
import pandas as pd
from matplotlib import pyplot as plt

from wetb.prepost import Simulations as sim
from wetb.prepost import dlcdefs
from wetb.prepost import hawcstab2 as hs2
from wetb.prepost import mplutils
class ConfigBase(object):
    def set_master_defaults(self):
        """Create a set of default master tags that are required for proper
        compatibility with Simulations.py
        """
        mt = {}
        # =====================================================================
        # required tags and their defaults
        # =====================================================================
        mt['[dt_sim]'] = 0.01
        mt['[hawc2_exe]'] = 'hawc2-latest'
        # convergence_limits  0.001  0.005  0.005 ;
        # critical one, risidual on the forces: 0.0001 = 1e-4
        mt['[epsresq]'] = '1.0' # default=10.0
        # increment residual
        mt['[epsresd]'] = '0.5' # default= 1.0
        # constraint equation residual
        mt['[epsresg]'] = '1e-8' # default= 1e-7
        # folder names for the saved results, htc, data, zip files
        # Following dirs are relative to the model_dir_server and they specify
        # the location of where the results, logfiles, animation files that where
        # run on the server should be copied to after the simulation has finished.
        # on the node, it will try to copy the turbulence files from these dirs
        mt['[animation_dir]'] = 'animation/'
        mt['[control_dir]']   = 'control/'
        mt['[data_dir]']      = 'data/'
        mt['[eigen_analysis]'] = False
        mt['[eigenfreq_dir]'] = False
        mt['[htc_dir]']       = 'htc/'
        mt['[log_dir]']       = 'logfiles/'
        mt['[meander_dir]']   = False
        mt['[opt_dir]']       = False
        mt['[pbs_out_dir]']   = 'pbs_out/'
        mt['[res_dir]']       = 'res/'
        mt['[iter_dir]']      = 'iter/'
        mt['[turb_dir]']      = 'turb/'
        mt['[turb_db_dir]']   = '../turb/'
        mt['[wake_dir]']      = False
        mt['[hydro_dir]']     = False
        mt['[mooring_dir]']   = False
        mt['[externalforce]'] = False
        mt['[Case folder]']   = 'NoCaseFolder'
        # zip_root_files only is used when copy to run_dir and zip creation, define
        # in the HtcMaster object
        mt['[zip_root_files]'] = []
        # only active on PBS level, so files have to be present in the run_dir
        mt['[copyback_files]'] = []   # copyback_resultfile
        mt['[copyback_frename]'] = [] # copyback_resultrename
        mt['[copyto_files]'] = []     # copyto_inputfile
        mt['[copyto_generic]'] = []   # copyto_input_required_defaultname
        # =====================================================================
        # required tags by HtcMaster and PBS in order to function properly
        # =====================================================================
        # the express queue ('#PBS -q xpresq') has a maximum walltime of 1h
        mt['[pbs_queue_command]'] = '#PBS -q workq'
        # walltime should have following format: hh:mm:ss
        mt['[walltime]'] = '04:00:00'
        mt['[auto_walltime]'] = False

        return mt

    def opt_tags_h2_eigenanalysis(self, basename):
        """Return opt_tags suitable for a standstill HAWC2 eigen analysis.
        """
        opt_tags = [self.opt_h2.copy()]
        opt_tags[0].update(self.eigenan.copy())
        opt_tags[0]['[Case id.]'] = '%s_hawc2_eigenanalysis' % basename
        opt_tags[0]['[blade_damp_x]'] = 0.0
        opt_tags[0]['[blade_damp_y]'] = 0.0
        opt_tags[0]['[blade_damp_z]'] = 0.0
        opt_tags[0]['[blade_nbodies]'] = 1
        opt_tags[0]['[Windspeed]'] = 0.0
        opt_tags[0]['[initspeed_rotor_rads]'] = 0.0
        opt_tags[0]['[operational_data]'] = 'empty.opt'
        opt_tags[0]['[eigen_analysis]'] = True
        opt_tags[0]['[output]'] = False
        opt_tags[0]['[t0]'] = 0.0
        opt_tags[0]['[time stop]'] = 0.0

        return opt_tags

    def opt_tags_hs_structure_body_eigen(self, basename):
        """Return opt_tags suitable for a standstill HAWCStab2 body eigen
        analysis, at 0 RPM.
        """
        opt_tags = [self.opt_hs2.copy()]
        opt_tags[0]['[Case id.]'] = '%s_hs2_eigenanalysis' % basename
        opt_tags[0]['[blade_damp_x]'] = 0.0
        opt_tags[0]['[blade_damp_y]'] = 0.0
        opt_tags[0]['[blade_damp_z]'] = 0.0
        opt_tags[0]['[blade_nbodies]'] = 1
        opt_tags[0]['[Windspeed]'] = 0.0
        opt_tags[0]['[initspeed_rotor_rads]'] = 0.0
        opt_tags[0]['[fixspeed_rotor_rads]'] = 0.0
        opt_tags[0]['[operational_data]'] = 'empty.opt'
        opt_tags[0]['[hs2_blademodes]'] = True

        return opt_tags

    def opt_tags_hs2(self, basename):

        opt_tags = [self.opt_hs2.copy()]
        opt_tags[0]['[Case id.]'] = '%s_hawcstab2' % basename
        return opt_tags

    def set_hs2opdata(self, master, basename):
        """Load the HS2 operational data file and create opt_tags for HAWC2
        cases.

        Returns
        -------
        opt_tags : list of dicts
        """
        fpath = os.path.join(master.tags['[data_dir]'],
                             master.tags['[operational_data]'])
        hs2_res = hs2.results()
        hs2_res.load_operation(fpath)
        omegas = hs2_res.operation.rotorspeed_rpm.values*np.pi/30.0
        winds = hs2_res.operation.windspeed.values
        pitchs = -1.0*hs2_res.operation.pitch_deg.values

        return self.set_opdata(winds, pitchs, omegas, basename=basename)

    def set_opdata(self, winds, pitchs, omegas, basename=None):
        """Return opt_tags for HAWC2 based on an HAWCStab2 operational data
        file.

        Parameters
        ----------

        winds : ndarray(n)
            wind speed for given operating point [m/s]

        pitchs : ndarray(n)
            pitch angle at given operating point [deg]

        omegas : ndarray(n)
            rotor speed at given operating point [rad/s]

        basename : str, default=None
            If not None, the [Case id.] tag is composed out of the basename,
            wind speed, pitch angle and rotor speed. If set to None, the
            [Case id.] tag is not set.

        Returns
        -------
        opt_tags : list of dicts
        """

        # the HAWC2 cases
        opt_tags = []
        for wind, pitch, omega in zip(winds, pitchs, omegas):
            opt_dict = {}
            opt_dict.update(self.opt_h2.copy())
            opt_dict.update(self.fix_op.copy())
            rpl = (basename, wind, pitch, omega)
            if basename is not None:
                tmp = '%s_%02.0fms_%04.01fdeg_%04.02frads_hawc2' % rpl
                opt_dict['[Case id.]'] = tmp
            opt_dict['[Windspeed]'] = wind
            opt_dict['[blade_pitch_deg]'] = pitch
            opt_dict['[fixspeed_rotor_rads]'] = omega
            opt_dict['[initspeed_rotor_rads]'] = omega
#            opt_dict['[t0]'] = int(2000.0/opt_dict['[Windspeed]']) # or 2000?
Loading
Loading full blame...