Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
T
TopFarm2
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
TOPFARM
TopFarm2
Commits
9733117e
There was a problem fetching the pipeline summary.
Commit
9733117e
authored
6 years ago
by
Mikkel Friis-Møller
Browse files
Options
Downloads
Plain Diff
Merge branch '14-remove-position-offset-in-pyfuga' into 'master'
Resolve "remove position offset in pyfuga" Closes
#14
See merge request
!23
parents
c47bcc88
ab463c63
No related branches found
Branches containing commit
No related tags found
Tags containing commit
1 merge request
!23
Resolve "remove position offset in pyfuga"
Pipeline
#
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
tests/test_fuga/test_pyfuga.py
+86
-97
86 additions, 97 deletions
tests/test_fuga/test_pyfuga.py
topfarm/cost_models/fuga/py_fuga.py
+20
-38
20 additions, 38 deletions
topfarm/cost_models/fuga/py_fuga.py
with
106 additions
and
135 deletions
tests/test_fuga/test_pyfuga.py
+
86
−
97
View file @
9733117e
'''
Created on 16. apr. 2018
@author: mmpe
'''
from
threading
import
Thread
import
threading
import
time
import
unittest
import
numpy
as
np
import
pytest
from
topfarm.cost_models.fuga.pascal_dll
import
PascalDLL
from
topfarm.cost_models.fuga.py_fuga
import
PyFuga
from
topfarm.cost_models.fuga.py_fuga
import
PyFuga
,
fugalib_path
import
os
from
topfarm.cost_models.fuga
import
py_fuga
from
topfarm
import
TopFarm
...
...
@@ -20,31 +12,15 @@ from topfarm import TopFarm
fuga_path
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
py_fuga
.
__file__
))
+
'
/Colonel/
'
def
_test_parallel
(
id
):
pyFuga
=
PyFuga
()
pyFuga
.
setup
(
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
'
)
print
(
pyFuga
.
stdout_filename
,
id
)
for
i
in
range
(
1
):
print
(
threading
.
current_thread
(),
id
)
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
([
0
,
0
],
[
0
,
200
]),
[
14.044704
,
16.753474
,
0.401041
,
0.838316
])
time
.
sleep
(
1
)
class
Test
(
unittest
.
TestCase
):
def
lib_missing
(
self
):
lib_path
=
os
.
path
.
dirname
(
py_fuga
.
__file__
)
+
"
/Colonel/FugaLib/FugaLib.%s
"
%
(
'
so
'
,
'
dll
'
)[
os
.
name
==
'
nt
'
]
def
check_lib_exists
():
if
os
.
path
.
isfile
(
fugalib_path
)
is
False
:
pytest
.
xfail
(
"
Fugalib
'
%s
'
not found
\n
"
%
fugalib_path
)
if
os
.
path
.
isfile
(
lib_path
)
is
False
:
pytest
.
xfail
(
"
Fugalib missing
"
)
raise
Warning
(
"
Fugalib
'
%s
'
not found
\n
"
%
lib_path
)
return
False
def
get_fuga
(
self
,
tb_x
=
[
423974
,
424033
],
tb_y
=
[
6151447
,
6150889
]):
@pytest.fixture
def
get_fuga
():
def
_fuga
(
tb_x
=
[
423974
,
424033
],
tb_y
=
[
6151447
,
6150889
]):
check_lib_exists
()
pyFuga
=
PyFuga
()
pyFuga
.
setup
(
farm_name
=
'
Horns Rev 1
'
,
turbine_model_path
=
fuga_path
+
'
LUT/
'
,
turbine_model_name
=
'
Vestas_V80_(2_MW_offshore)[h=67.00]
'
,
...
...
@@ -52,74 +28,87 @@ class Test(unittest.TestCase):
mast_position
=
(
0
,
0
,
70
),
z0
=
0.0001
,
zi
=
400
,
zeta0
=
0
,
farms_dir
=
fuga_path
+
'
LUT/Farms/
'
,
wind_atlas_path
=
'
Horns Rev 1/hornsrev_north_only.lib
'
,
climate_interpolation
=
False
)
return
pyFuga
return
_fuga
def
testCheckVersion
(
self
):
if
self
.
lib_missing
():
return
lib
=
PascalDLL
(
fuga_path
+
"
FugaLib/FugaLib.%s
"
%
(
'
so
'
,
'
dll
'
)[
os
.
name
==
'
nt
'
])
self
.
assertRaisesRegex
(
Exception
,
"
This version of FugaLib supports interface version
"
,
lib
.
CheckInterfaceVersion
,
1
)
pyFuga
=
self
.
get_fuga
()
# check that current interface version match
pyFuga
.
cleanup
()
def
testSetup
(
self
):
if
self
.
lib_missing
():
return
pyFuga
=
self
.
get_fuga
()
self
.
assertEqual
(
pyFuga
.
get_no_tubines
(),
2
)
self
.
assertIn
(
"
Loading
"
,
pyFuga
.
log
)
# check that new setup resets number of turbines
pyFuga
=
self
.
get_fuga
()
self
.
assertEqual
(
pyFuga
.
get_no_tubines
(),
2
)
pyFuga
.
cleanup
()
def
testAEP_one_tb
(
self
):
if
self
.
lib_missing
():
return
pyFuga
=
self
.
get_fuga
([
0
],
[
0
])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
(
np
.
array
([[
0
],
[
0
]]).
T
),
[
7.450272
,
7.450272
,
0.424962
,
1.
])
pyFuga
.
cleanup
()
def
testAEP
(
self
):
if
self
.
lib_missing
():
return
pyFuga
=
self
.
get_fuga
()
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
(
np
.
array
([[
0
,
200
],
[
0
,
0
]]).
T
),
[
14.866138
,
14.900544
,
0.423981
,
0.997691
])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep_gradients
(
np
.
array
([[
0
,
200
],
[
0
,
0
]]).
T
),
0
)
@pytest.fixture
def
pyFuga
():
return
get_fuga
()()
def
_test_parallel
(
i
):
pyFuga
=
get_fuga
()()
print
(
pyFuga
.
stdout_filename
,
i
)
for
_
in
range
(
1
):
print
(
threading
.
current_thread
(),
i
)
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
(
np
.
array
([[
0
,
0
],
[
0
,
200
]]).
T
),
[
12.124883
,
14.900544
,
0.3458
,
0.813721
])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep_gradients
(
np
.
array
([[
0
,
0
],
[
0
,
200
]]).
T
),
[[
-
0.001794
,
0.001794
],
[
-
0.008126
,
0.008126
],
[
0.
,
0.
]])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
(
np
.
array
([[
0
,
200
],
[
0
,
200
]]).
T
),
[
14.864909
,
14.900544
,
0.423946
,
0.997608
])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep_gradients
(
np
.
array
([[
0
,
200
],
[
0
,
200
]]).
T
),
[[
-
5.165553e-06
,
5.165553e-06
],
[
1.599768e-06
,
-
1.599768e-06
],
[
0.000000e+00
,
0.000000e+00
]])
pyFuga
.
cleanup
()
def
testAEP_topfarm
(
self
):
if
self
.
lib_missing
():
return
pyFuga
=
self
.
get_fuga
()
init_pos
=
[[
0
,
0
],
[
200
,
0
]]
tf
=
TopFarm
(
init_pos
,
pyFuga
.
get_TopFarm_cost_component
(),
160
,
init_pos
,
boundary_type
=
'
square
'
)
tf
.
evaluate
()
np
.
testing
.
assert_array_almost_equal
(
tf
.
get_cost
(),
-
14.866138
)
def
test_pyfuga_cmd
(
self
):
if
self
.
lib_missing
():
return
pyFuga
=
PyFuga
()
pyFuga
.
execute
(
r
'
echo
"
ColonelInit
"'
)
self
.
assertEqual
(
pyFuga
.
log
.
strip
().
split
(
"
\n
"
)[
-
1
],
'
ColonelInit
'
)
time
.
sleep
(
1
)
def
testCheckVersion
(
get_fuga
):
check_lib_exists
()
lib
=
PascalDLL
(
fuga_path
+
"
FugaLib/FugaLib.%s
"
%
(
'
so
'
,
'
dll
'
)[
os
.
name
==
'
nt
'
])
with
pytest
.
raises
(
Exception
,
match
=
"
This version of FugaLib supports interface version
"
):
lib
.
CheckInterfaceVersion
(
1
)
pyFuga
=
get_fuga
()
# check that current interface version match
pyFuga
.
cleanup
()
# def test_parallel(self):
# from multiprocessing import Pool
#
# with Pool(5) as p:
# print(p.map(_test_parallel, [1, 2]))
def
testSetup
(
get_fuga
):
pyFuga
=
get_fuga
()
assert
pyFuga
.
get_no_turbines
()
==
2
assert
"
Loading
"
in
pyFuga
.
log
# check that new setup resets number of turbines
pyFuga
=
get_fuga
()
assert
pyFuga
.
get_no_turbines
()
==
2
pyFuga
.
cleanup
()
def
testAEP_one_tb
(
get_fuga
):
pyFuga
=
get_fuga
([
0
],
[
0
])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
(
np
.
array
([[
0
],
[
0
]]).
T
),
[
7.450272
,
7.450272
,
0.424962
,
1.
])
pyFuga
.
cleanup
()
def
testAEP
(
pyFuga
):
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
(
np
.
array
([[
0
,
200
],
[
0
,
0
]]).
T
),
[
14.866138
,
14.900544
,
0.423981
,
0.997691
])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep_gradients
(
np
.
array
([[
0
,
200
],
[
0
,
0
]]).
T
),
0
)
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
(
np
.
array
([[
0
,
0
],
[
0
,
200
]]).
T
),
[
12.124883
,
14.900544
,
0.3458
,
0.813721
])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep_gradients
(
np
.
array
([[
0
,
0
],
[
0
,
200
]]).
T
),
[[
-
0.001794
,
0.001794
],
[
-
0.008126
,
0.008126
],
[
0.
,
0.
]])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
(
np
.
array
([[
0
,
200
],
[
0
,
200
]]).
T
),
[
14.864909
,
14.900544
,
0.423946
,
0.997608
])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep_gradients
(
np
.
array
([[
0
,
200
],
[
0
,
200
]]).
T
),
[[
-
5.165553e-06
,
5.165553e-06
],
[
1.599768e-06
,
-
1.599768e-06
],
[
0.000000e+00
,
0.000000e+00
]])
pyFuga
.
cleanup
()
def
testLargeOffset
(
pyFuga
):
o
=
1.e16
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep
(
np
.
array
([[
0
+
o
,
0
+
o
],
[
0
+
o
,
200
+
o
]]).
T
),
[
12.124883
,
14.900544
,
0.3458
,
0.813721
])
np
.
testing
.
assert_array_almost_equal
(
pyFuga
.
get_aep_gradients
(),
[[
-
0.001794
,
0.001794
],
[
-
0.008126
,
0.008126
],
[
0.
,
0.
]])
def
testAEP_topfarm
(
get_fuga
):
pyFuga
=
get_fuga
()
init_pos
=
[[
0
,
0
],
[
200
,
0
]]
tf
=
TopFarm
(
init_pos
,
pyFuga
.
get_TopFarm_cost_component
(),
160
,
init_pos
,
boundary_type
=
'
square
'
)
tf
.
evaluate
()
np
.
testing
.
assert_array_almost_equal
(
tf
.
get_cost
(),
-
14.866138
)
def
test_pyfuga_cmd
():
check_lib_exists
()
pyFuga
=
PyFuga
()
pyFuga
.
execute
(
r
'
echo
"
ColonelInit
"'
)
assert
pyFuga
.
log
.
strip
().
split
(
"
\n
"
)[
-
1
]
==
'
ColonelInit
'
if
__name__
==
"
__main__
"
:
unittest
.
main
()
# @pytest.mark.xfail
# def test_parallel():
# from multiprocessing import Pool
# with Pool(5) as p:
# print(p.map(_test_parallel, [1, 2]))
This diff is collapsed.
Click to expand it.
topfarm/cost_models/fuga/py_fuga.py
+
20
−
38
View file @
9733117e
...
...
@@ -19,6 +19,7 @@ c_double_p = POINTER(c_double)
c_int_p
=
POINTER
(
ctypes
.
c_int32
)
fuga_path
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
__file__
))
+
'
/Colonel/
'
fugalib_path
=
os
.
path
.
dirname
(
__file__
)
+
"
/Colonel/FugaLib/FugaLib.%s
"
%
(
'
so
'
,
'
dll
'
)[
os
.
name
==
'
nt
'
]
class
PyFuga
(
object
):
...
...
@@ -29,11 +30,10 @@ class PyFuga(object):
with
NamedTemporaryFile
()
as
f
:
self
.
stdout_filename
=
f
.
name
+
"
pyfuga.txt
"
lib_path
=
os
.
path
.
dirname
(
__file__
)
+
"
/Colonel/FugaLib/FugaLib.%s
"
%
(
'
so
'
,
'
dll
'
)[
os
.
name
==
'
nt
'
]
if
os
.
path
.
isfile
(
lib_path
)
is
False
:
raise
Exception
(
"
Fuga lib cannot be found:
'
%s
'"
%
lib_path
)
if
os
.
path
.
isfile
(
fugalib_path
)
is
False
:
raise
Exception
(
"
Fuga lib cannot be found:
'
%s
'"
%
fugalib_path
)
self
.
lib
=
PascalDLL
(
lib_path
)
self
.
lib
=
PascalDLL
(
fuga
lib_path
)
self
.
lib
.
CheckInterfaceVersion
(
self
.
interface_version
)
self
.
lib
.
Initialize
(
self
.
stdout_filename
)
...
...
@@ -45,9 +45,8 @@ class PyFuga(object):
self
.
lib
.
Setup
(
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
)
tb_x_ctype
,
tb_y_ctype
=
self
.
tb_ctypes
(
tb_x
,
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
))
...
...
@@ -55,7 +54,7 @@ class PyFuga(object):
assert
os
.
path
.
isfile
(
farms_dir
+
wind_atlas_path
),
farms_dir
+
wind_atlas_path
self
.
lib
.
SetupWindClimate
(
farms_dir
,
wind_atlas_path
,
climate_interpolation
)
#
assert len(tb_x) == self.get_no_tubines(), self.log + "\n%d!=%d" % (self.get_no_tubines(),len(tb_x))
assert
len
(
tb_x
)
==
self
.
get_no_tu
r
bines
(),
self
.
log
+
"
\n
%d!=%d
"
%
(
self
.
get_no_tu
r
bines
(),
len
(
tb_x
))
def
cleanup
(
self
):
if
hasattr
(
self
,
'
lib
'
):
...
...
@@ -72,16 +71,22 @@ class PyFuga(object):
except
Exception
:
pass
def
get_no_tubines
(
self
):
def
get_no_tu
r
bines
(
self
):
no_turbines_p
=
c_int_p
(
c_int
(
0
))
self
.
lib
.
GetNoTurbines
(
no_turbines_p
)
return
no_turbines_p
.
contents
.
value
def
move_turbines
(
self
,
tb_x
,
tb_y
):
assert
len
(
tb_x
)
==
len
(
tb_y
)
==
self
.
get_no_tubines
(),
(
len
(
tb_x
),
len
(
tb_y
),
self
.
get_no_tubines
())
tb_x_ctype
=
np
.
array
(
tb_x
,
dtype
=
np
.
float
).
ctypes
tb_y_ctype
=
np
.
array
(
tb_y
,
dtype
=
np
.
float
).
ctypes
def
tb_ctypes
(
self
,
tb_x
,
tb_y
):
assert
len
(
tb_x
)
==
len
(
tb_y
)
# remove mean offset to avoid loosing precision due to high offset
self
.
tb_x_offset
,
self
.
tb_y_offset
=
np
.
mean
(
tb_x
),
np
.
mean
(
tb_y
)
tb_x
=
np
.
array
(
tb_x
,
dtype
=
np
.
float
)
-
self
.
tb_x_offset
tb_y
=
np
.
array
(
tb_y
,
dtype
=
np
.
float
)
-
self
.
tb_y_offset
return
tb_x
.
ctypes
,
tb_y
.
ctypes
def
move_turbines
(
self
,
tb_x
,
tb_y
):
assert
len
(
tb_x
)
==
len
(
tb_y
)
==
self
.
get_no_turbines
(),
(
len
(
tb_x
),
len
(
tb_y
),
self
.
get_no_turbines
())
tb_x_ctype
,
tb_y_ctype
=
self
.
tb_ctypes
(
tb_x
,
tb_y
)
self
.
lib
.
MoveTurbines
(
tb_x_ctype
.
data_as
(
c_double_p
),
tb_y_ctype
.
data_as
(
c_double_p
))
def
get_aep
(
self
,
turbine_positions
=
None
):
...
...
@@ -92,7 +97,6 @@ class PyFuga(object):
AEPGros_p
=
c_double_p
(
c_double
(
0
))
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)
net
,
gros
,
cap
=
[
p
.
contents
.
value
for
p
in
[
AEPNet_p
,
AEPGros_p
,
capacity_p
]]
return
(
net
,
gros
,
cap
,
net
/
gros
)
...
...
@@ -100,15 +104,14 @@ class PyFuga(object):
if
turbine_positions
is
not
None
:
self
.
move_turbines
(
turbine_positions
[:,
0
],
turbine_positions
[:,
1
])
n_wt
=
self
.
get_no_tubines
()
n_wt
=
self
.
get_no_tu
r
bines
()
dAEPdxyz
=
np
.
zeros
(
n_wt
),
np
.
zeros
(
n_wt
),
np
.
zeros
(
n_wt
)
dAEPdxyz_ctype
=
[
dAEP
.
ctypes
for
dAEP
in
dAEPdxyz
]
self
.
lib
.
GetAEPGradients
(
*
[
dAEP_ctype
.
data_as
(
c_double_p
)
for
dAEP_ctype
in
dAEPdxyz_ctype
])
#print(tb_x, tb_y, dAEPdxyz)
return
np
.
array
(
dAEPdxyz
)
def
get_TopFarm_cost_component
(
self
):
n_wt
=
self
.
get_no_tubines
()
n_wt
=
self
.
get_no_tu
r
bines
()
return
AEPCostModelComponent
(
n_wt
,
lambda
*
args
:
self
.
get_aep
(
*
args
)[
0
],
# only aep
lambda
*
args
:
self
.
get_aep_gradients
(
*
args
)[:
2
])
# only dAEPdx and dAEPdy
...
...
@@ -118,27 +121,6 @@ class PyFuga(object):
with
open
(
self
.
stdout_filename
)
as
fid
:
return
fid
.
read
()
# self.execute("""seed=0
# initialize
# set output file "out.txt"
# load farm "Horns Rev 1"
# 7 point integration off
# meandering off
# insert met mast 0.0 0.0 70.0
# z0=0.0001
# zi=400.0
# zeta0=0.0
# load wakes
# gaussian fit on
# proximity penalty off
# gradients on
# Wind climates interpolation on
# load wind atlas "Horns Rev 1\hornsrev2.lib"
# relative move all turbines -426733.0 -6149501.5
# gradients off
# calculate AEP
# get Farm AEP""")
def
execute
(
self
,
script
):
res
=
self
.
lib
.
ExecuteScript
(
script
.
encode
())
print
(
"
#
"
+
str
(
res
)
+
"
#
"
)
...
...
@@ -153,7 +135,7 @@ def try_me():
mast_position
=
(
0
,
0
,
70
),
z0
=
0.0001
,
zi
=
400
,
zeta0
=
0
,
farms_dir
=
fuga_path
+
'
LUT/Farms/
'
,
wind_atlas_path
=
'
Horns Rev 1\hornsrev.lib
'
)
print
(
pyFuga
.
get_no_tubines
())
print
(
pyFuga
.
get_no_tu
r
bines
())
print
(
pyFuga
.
get_aep
(
np
.
array
([[
0
,
0
],
[
0
,
1000
]])))
print
(
pyFuga
.
get_aep
(
np
.
array
([[
0
,
1000
],
[
0
,
0
]])))
print
(
pyFuga
.
get_aep_gradients
(
np
.
array
([[
0
,
0
],
[
0
,
100
]])))
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment