forked from SAP-archive/fedem-solvers
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtest_extfunc.py
More file actions
123 lines (107 loc) · 3.83 KB
/
test_extfunc.py
File metadata and controls
123 lines (107 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# SPDX-FileCopyrightText: 2023 SAP SE
#
# SPDX-License-Identifier: Apache-2.0
#
# This file is part of FEDEM - https://openfedem.org
"""
This Python test basically does the same as the solver test
located in the folder `../../../solverTests/Cantilever-extFunc`.
It therefore reuses the input-files from that folder.
The test uses two environment variables:
FEDEM_SOLVER = Full path to the solver shared object library
TEST_DIR = Full path to the parent folder of the solver tests
"""
from os import environ
from math import sin, cos
from fedempy.solver import FedemSolver
from test_utils import compare_lists
def ext_func(func_id, x):
"""
Hard-coded external function evaluations to test against.
"""
if func_id == 1:
return 1.0e7 * sin(x)
elif func_id == 2:
return 5.0e3 * (cos(2.5 * x) - 1.0)
else:
return 0.0
# List of function IDs to extract results for.
fId = [3, 4, 5]
n_out = len(fId)
# Start the fedem solver in the $TEST_DIR/Cantilever-extFunc folder.
# From that folder, read solver options from the Setup.fco file,
# and read model data from the Model.fsi file.
wrkdir = environ["TEST_DIR"] + "/Cantilever-extFunc"
slvopt = ["-cwd=" + wrkdir, "-fco=Setup.fco", "-fsifile=Model.fsi"]
solver = FedemSolver(environ["FEDEM_SOLVER"], slvopt, True)
print("\n#### Running dynamics solver in", wrkdir)
print("Comparing with response variables in TipPosition.asc")
# Read reference values to compare with from file
rfile = open(wrkdir + "/TipPosition.asc", "r")
for line in rfile:
print(line.strip())
if line[0:5] == "#DESC":
next(rfile) # skip the first data line (t=0.0)
break
# Time step loop
ierr = 0
do_continue = True
references = []
while do_continue and solver.ierr.value == 0:
# Evaluate the external functions
t = solver.get_next_time()
solver.set_ext_func(1, ext_func(1, t))
solver.set_ext_func(2, ext_func(2, t))
# Solve for next time step
do_continue = solver.solve_next()
# Extract the results
outputs = [float(solver.get_function(func_id)) for func_id in fId]
outputs.insert(0, float(t))
# Read reference data from file
reference = [float(x) for x in next(rfile).split()]
# Compare response values
ierr += compare_lists(t, outputs, reference, 1.0e-8)
references.append(reference)
if ierr > 0:
print(f" *** Detected {ierr} discrepancies, test not passed")
else:
print(f" * All response values match, checked {len(references)} steps")
# Simulation finished, terminate by closing down the result database, etc.
rfile.close()
ierr += abs(solver.solver_done())
if ierr == 0 and solver.ierr.value == 0:
print("Time step loop OK, solver closed")
else:
exit(ierr + abs(solver.ierr.value))
# Start over, read all input once again (from same working directory)
ierr = solver.solver_init(slvopt)
if ierr < 0:
exit(ierr)
# Run 100 steps using the Window function
n_step = 100
inputs = [0.0] * (2 * n_step)
t = solver.get_current_time()
dt = solver.get_next_time() - t
for i in range(n_step):
inputs[2 * i] = ext_func(1, t + dt * (i + 1))
inputs[2 * i + 1] = ext_func(2, t + dt * (i + 1))
outputs, stat = solver.solve_window(n_step, inputs, fId)
if not stat:
print("End of simulation was reached")
# Compare response values
ierr = 0
for i in range(n_step):
t = references[i][0]
output = [float(outputs[i * n_out + j]) for j in range(n_out)]
output.insert(0, t)
ierr += compare_lists(t, output, references[i], 1.0e-8)
if ierr > 0:
print(f" *** Detected {ierr} discrepancies, test not passed")
else:
print(f" * All response values match, checked {n_step} steps")
# Simulation finished, terminate by closing down the result database, etc.
ierr += abs(solver.solver_done())
if ierr == 0 and solver.ierr.value == 0:
print("Time window OK, solver closed")
else:
exit(ierr + abs(solver.ierr.value))