Skip to content
Snippets Groups Projects
Commit 575d8afc authored by Mads M. Pedersen's avatar Mads M. Pedersen
Browse files

clean up and adapted to fugalib submodule

parent ae2c36de
No related branches found
No related tags found
1 merge request!1Add fugalib submodule
Subproject commit daff6eef6b227076613aa5a2175272b4c3653adc
Subproject commit abe02a0372b4ae9f3a07d4aad4d96ff3e8386ce6
from contextlib import contextmanager
from ctypes import cdll, c_char_p, c_double
import ctypes
import io
import os
import sys
import tempfile
from contextlib import contextmanager
import ctypes
import io
import os
import sys
import tempfile
import os
import sys
from contextlib import contextmanager
@contextmanager
def stdout_redirected(to=os.devnull):
fd = sys.stdout.fileno()
def _redirect_stdout(to):
# if sys.stdout is not sys.__stdout__:
# sys.stdout.close() # + implicit flush()
os.dup2(to.fileno(), fd) # fd writes to 'to' file
# sys.stdout = os.fdopen(fd, 'w') # Python writes to fd
with os.fdopen(os.dup(fd), 'w') as old_stdout:
_redirect_stdout(to)
# with open(to, 'w') as file:
# _redirect_stdout(to=file)
try:
yield # allow code to be run with the redirected stdout
finally:
_redirect_stdout(to=old_stdout) # restore stdout.
# buffering and flags such as
# CLOEXEC may be different
class PascalDLL(object):
def __init__(self, path):
self.lib = cdll.LoadLibrary(path)
def __getattr__(self, name):
def func_wrap(*args):
func = getattr(self.lib, name)
......@@ -57,22 +16,9 @@ class PascalDLL(object):
if isinstance(arg, float):
return c_double(arg)
return arg
fmt_args = list(map(fmt, args))
err = func(*fmt_args)
if err:
raise Exception("Exception from Fugalib: " + err.decode())
# with tempfile.TemporaryFile(mode='w+') as fp:
# # with stdout_redirected(to=fp):
# # fmt_args = map(fmt, args)
# # err = func(*fmt_args)
# fmt_args = map(fmt, args)
# err = func(*fmt_args)
# # fp.seek(0)
# # self.stdout += fp.read()
# if err:
# #print ("#"+self.stdout+"#")
# raise Exception("Exception from Fugalib: " + err.decode())
return func_wrap
......@@ -3,14 +3,17 @@ Created on 23. mar. 2018
@author: mmpe
'''
import numpy as np
import atexit
from ctypes import *
from topfarm.cost_models.fuga.pascal_dll import PascalDLL
import ctypes
from openmdao.core.explicitcomponent import ExplicitComponent
from topfarm.cost_models.cost_model_wrappers import AEPCostModelComponent
import os
from tempfile import NamedTemporaryFile, mkstemp
from openmdao.core.explicitcomponent import ExplicitComponent
import numpy as np
from topfarm.cost_models.cost_model_wrappers import AEPCostModelComponent
from topfarm.cost_models.fuga.pascal_dll import PascalDLL
c_double_p = POINTER(c_double)
......@@ -18,16 +21,52 @@ c_int_p = POINTER(ctypes.c_int32)
class PyFuga(object):
# def __init__(self, dll_path, farms_dir, farm_name='Horns Rev 1', turbine_model_path='./LUT/',
# mast_position=(0,0,70), z0=0.0001, zi=400, zeta0=0, wind_atlas_path='Horns Rev 1\hornsrev.lib'):
def __init__(self):
path = r'C:\Sandbox\Topfarm\Colonel\FugaLib/'
interface_version = 2
def __init__(self, logfile='',
farm_name='Horns Rev 1',
turbine_model_path='./LUT/', turbine_model_name='Vestas_V80_(2_MW_offshore)[h=67.00]',
tb_x=[423974, 424033], tb_y=[6151447, 6150889],
mast_position=(0, 0, 70), z0=0.0001, zi=400, zeta0=0,
farms_dir='./LUT/', wind_atlas_path='Horns Rev 1\hornsrev.lib'):
atexit.register(self.cleanup)
self.stdout_filename = NamedTemporaryFile().name + ".txt"
self.lib = PascalDLL(os.path.dirname(__file__) + "/Colonel/FugaLib/FugaLib.dll")
self.lib.CheckInterfaceVersion(self.interface_version)
self.lib.Setup(self.stdout_filename, float(mast_position[0]), float(mast_position[1]), float(mast_position[2]),
float(z0), float(zi), float(zeta0))
tb_x_ctype = np.array(tb_x, dtype=np.float).ctypes
tb_y_ctype = np.array(tb_y, dtype=np.float).ctypes
assert len(tb_x) == len(tb_y)
self.lib.AddWindFarm(farm_name, turbine_model_path, turbine_model_name,
len(tb_x), tb_x_ctype.data_as(c_double_p), tb_y_ctype.data_as(c_double_p))
assert os.path.isfile(farms_dir + wind_atlas_path), farms_dir + wind_atlas_path
self.lib.SetupWindClimate(farms_dir, wind_atlas_path)
assert len(tb_x) == self.get_no_tubines(), self.log + "\n%d" % self.get_no_tubines()
# self.lib.setup_old(farms_dir, farm_name, turbine_model_path,
# float(mast_position[0]), float(mast_position[1]), float(mast_position[2]),
# float(z0),float(zi),float(zeta0),
# wind_atlas_path)
def cleanup(self):
self.lib.Exit()
if os.path.isfile(self.stdout_filename):
os.remove(self.stdout_filename)
def __init__old(self):
path = r'C:\mmpe\programming\pascal\Fuga\Colonel\FugaLib/'
self.lib = PascalDLL(path + 'FugaLib.dll')
#
self.lib.setup(path + '../LUT/Farms/', 'Horns Rev 1', path + '../LUT/',
0., 0., 70.,
0.0001, 400., 0.,
'Horns Rev 1\hornsrev.lib')
'Horns Rev 1\hornsrev0.lib')
def get_no_tubines(self):
no_turbines_p = c_int_p(c_int(0))
......@@ -40,7 +79,7 @@ class PyFuga(object):
tb_y_ctype = np.array(tb_y, dtype=np.float).ctypes
self.lib.MoveTurbines(tb_x_ctype.data_as(c_double_p), tb_y_ctype.data_as(c_double_p))
def get_aep(self, tb_x, tb_y):
self.move_turbines(tb_x, tb_y)
......@@ -49,8 +88,8 @@ class PyFuga(object):
capacity_p = c_double_p(c_double(0))
self.lib.getAEP(AEPNet_p, AEPGros_p, capacity_p)
#print(tb_x, tb_y, AEPNet_p.contents.value, (15.850434458235156 - AEPNet_p.contents.value) / .000001)
print(AEPNet_p.contents.value)
return (AEPNet_p.contents.value, AEPGros_p.contents.value, capacity_p.contents.value)
net, gros, cap = [p.contents.value for p in [AEPNet_p, AEPGros_p, capacity_p]]
return (net, gros, cap, net / gros)
def get_aep_gradients(self, tb_x, tb_y):
self.move_turbines(tb_x, tb_y)
......@@ -67,6 +106,10 @@ class PyFuga(object):
lambda *args: self.get_aep(*args)[0], # only aep
lambda *args: self.get_aep_gradients(*args)[:2]) # only dAEPdx and dAEPdy
@property
def log(self):
with open(self.stdout_filename) as fid:
return fid.read()
# self.execute("""seed=0
# initialize
......@@ -96,7 +139,7 @@ class PyFuga(object):
if __name__ == '__main__':
path = r'C:\Sandbox\Topfarm\Colonel/'
path = r'Colonel/'
dll_path = path + 'FugaLib/FugaLib.dll'
farms_dir = path + 'LUT/Farms/'
farm_name = 'Horns Rev 1'
......@@ -104,8 +147,8 @@ if __name__ == '__main__':
mast_position = (0., 0., 70.)
z0, zi, zeta0 = 0.0001, 400., 0.,
wind_atlas_path = 'Horns Rev 1\hornsrev.lib'
pyFuga = PyFuga()
# pyFuga = PyFuga(dll_path, farms_dir, farm_name, turbine_model_path, mast_position, z0,zi,zeta0, wind_atlas_path)
pyFuga = PyFuga(dll_path, farms_dir, farm_name, turbine_model_path, mast_position, z0, zi, zeta0, wind_atlas_path)
print(pyFuga.get_no_tubines())
print(pyFuga.get_aep([0, 0], [0, 1000]))
print(pyFuga.get_aep([0, 1000], [0, 0]))
......
......@@ -3,16 +3,19 @@ Created on 16. apr. 2018
@author: mmpe
'''
import unittest
from topfarm.cost_models.fuga.py_fuga import PyFuga
import numpy as np
from threading import Thread
import threading
import time
from cost_models.fuga.pascal_dll import PascalDLL
import unittest
import numpy as np
from topfarm.cost_models.fuga.pascal_dll import PascalDLL
from topfarm.cost_models.fuga.py_fuga import PyFuga
import os
from topfarm.cost_models.fuga import py_fuga
fuga_path = r'C:\mmpe\programming\pascal\Fuga\Colonel/'
fuga_path = os.path.abspath(os.path.dirname(py_fuga.__file__)) + '/Colonel/'
def test_parallel(id):
pyFuga = PyFuga(fuga_path + "FugaLib/FugaLib.dll",
......@@ -32,12 +35,11 @@ def test_parallel(id):
class Test(unittest.TestCase):
def get_fuga(self):
return PyFuga(fuga_path + "FugaLib/FugaLib.dll",
farm_name='Horns Rev 1',
return PyFuga(farm_name='Horns Rev 1',
turbine_model_path=fuga_path + 'LUT/', turbine_model_name='Vestas_V80_(2_MW_offshore)[h=67.00]',
tb_x=[423974, 424033], tb_y=[6151447, 6150889],
mast_position=(0, 0, 70), z0=0.0001, zi=400, zeta0=0,
farms_dir=fuga_path + 'LUT/Farms/', wind_atlas_path='Horns Rev 1\hornsrev0.lib')
farms_dir=fuga_path + 'LUT/Farms/', wind_atlas_path='Horns Rev 1\hornsrev_north_only.lib')
......@@ -61,7 +63,7 @@ class Test(unittest.TestCase):
np.testing.assert_array_almost_equal(pyFuga.get_aep_gradients([0, 200], [0, 200]), [[0.002905, -0.002905],
[-0.001673, 0.001673],
[0., 0.]])
print (pyFuga.log)
#print (pyFuga.log)
def test_parallel(self):
from multiprocessing import Pool
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment