Skip to content
Snippets Groups Projects
Commit 755972f9 authored by Martin Bauer's avatar Martin Bauer
Browse files

Python config mechanism: option to select scenario idx via env-var

parent ad9c95d5
Branches
Tags
No related merge requests found
...@@ -45,6 +45,7 @@ To register a certain python function as callback it has to be set as attribute ...@@ -45,6 +45,7 @@ To register a certain python function as callback it has to be set as attribute
""" """
from __future__ import print_function, absolute_import, division, unicode_literals from __future__ import print_function, absolute_import, division, unicode_literals
import os
from functools import partial from functools import partial
...@@ -52,9 +53,10 @@ from functools import partial ...@@ -52,9 +53,10 @@ from functools import partial
class callback: class callback:
"""Decorator class to mark a Python function as waLBerla callback""" """Decorator class to mark a Python function as waLBerla callback"""
def __init__(self, callbackFunction ):
def __init__(self, callbackFunction):
if not type(callbackFunction) is str: if not type(callbackFunction) is str:
raise Exception( "waLBerla callback: Name of function has to be a string" ) raise Exception("waLBerla callback: Name of function has to be a string")
self.callbackFunction = callbackFunction self.callbackFunction = callbackFunction
def __call__(self, f): def __call__(self, f):
...@@ -63,7 +65,7 @@ class callback: ...@@ -63,7 +65,7 @@ class callback:
except ImportError: except ImportError:
try: try:
import walberla_cpp import walberla_cpp
setattr( walberla_cpp.callbacks, self.callbackFunction, f) setattr(walberla_cpp.callbacks, self.callbackFunction, f)
except ImportError: except ImportError:
# fail silently if waLBerla is not available # fail silently if waLBerla is not available
pass pass
...@@ -71,7 +73,6 @@ class callback: ...@@ -71,7 +73,6 @@ class callback:
return f return f
# ---------------------------- "Callback Classes" ------------------------------------------------------------- # ---------------------------- "Callback Classes" -------------------------------------------------------------
...@@ -81,7 +82,6 @@ def memberCallback(f): ...@@ -81,7 +82,6 @@ def memberCallback(f):
return f return f
class ScenarioManager: class ScenarioManager:
"""Use this class to simulate multiple scenarios """Use this class to simulate multiple scenarios
A scenario is an instance of a class with member callbacks. A scenario is an instance of a class with member callbacks.
...@@ -95,57 +95,72 @@ class ScenarioManager: ...@@ -95,57 +95,72 @@ class ScenarioManager:
When config is called again the calbacks of the next scenario are activated. When config is called again the calbacks of the next scenario are activated.
""" """
def __init__(self): def __init__(self):
self._scenarios = [] self._scenarios = []
self._startScenario = 0 self._startScenario = 0
def add(self, scenario): def add(self, scenario):
"""Adds a scenario to the manager and activates the manager itself""" """Adds a scenario to the manager and activates the manager itself"""
self._scenarios.append( scenario ) self._scenarios.append(scenario)
self.activate() self.activate()
def activate(self): def activate(self):
"""Activates this scenario manager instance""" """Activates this scenario manager instance"""
try: try:
import walberla_cpp import walberla_cpp
boundFunc = self._configLoopCallback boundFunc = self._configLoopCallback
setattr( walberla_cpp.callbacks, "config", boundFunc ) setattr(walberla_cpp.callbacks, "config", boundFunc)
except ImportError: except ImportError:
pass pass
def restrictScenarios( self, startScenario=0 ): def restrictScenarios(self, startScenario=0):
"""Simulates not all scenarios registered at this manager, but skips the first startScenario-1 scenarios""" """Simulates not all scenarios registered at this manager, but skips the first startScenario-1 scenarios"""
self._startScenario = startScenario self._startScenario = startScenario
def _configLoopCallback( self, *args, **kwargs ): def _configLoopCallback(self, *args, **kwargs):
def findCallbacks( classType ): def findCallbacks(classType):
res = dict() res = dict()
for key,value in classType.__dict__.items(): for key, value in classType.__dict__.items():
if( hasattr(value, "waLBerla_callback_member") ): if hasattr(value, "waLBerla_callback_member"):
res[ key ] = value res[key] = value
return res return res
def get_config_from_scenario(sc):
callbacks = findCallbacks(type(sc))
for callback_name, callback_func in callbacks.items():
if callback_name == 'config':
continue
bound_callback = partial(callback_func, sc) # bind the 'self' parameter of member function
setattr(walberla_cpp.callbacks, callback_name, bound_callback)
if 'config' not in callbacks:
walberla_cpp.log_warning_on_root("Error: Registered Scenario of class '%s' has no 'config' callback. Skipping... " % (type(sc),))
return None
config = sc.config(*args, **kwargs)
return config
try: try:
import walberla_cpp import walberla_cpp
for idx, scenario in enumerate( self._scenarios ): if 'WALBERLA_SCENARIO_IDX' in os.environ:
if idx < self._startScenario: continue #Skip over all scenarios with id < startScenario scenario_idx = int(os.environ['WALBERLA_SCENARIO_IDX'])
try:
callbacks = findCallbacks( type( scenario ) ) scenario = self._scenarios[scenario_idx]
for callbackName, callbackFunc in callbacks.items(): except IndexError:
if callbackName == 'config': continue walberla_cpp.log_info_on_root("Scenario does not exists - all scenarios simulated?")
boundCallback = partial( callbackFunc, scenario) # bind the 'self' parameter of member function exit(1)
setattr( walberla_cpp.callbacks, callbackName, boundCallback ) walberla_cpp.log_info_on_root("Simulating Scenario %d of %d :" % (scenario_idx, len(self._scenarios)))
yield get_config_from_scenario(scenario)
if 'config' not in callbacks: else:
walberla_cpp.log_warning_on_root( "Error: Registered Scenario of class '%s' has no 'config' callback. Skipping... " % ( type(scenario) ,) ) for idx, scenario in enumerate(self._scenarios):
continue if idx < self._startScenario:
continue # Skip over all scenarios with id < startScenario
cfg = None
while cfg is None:
cfg = get_config_from_scenario(scenario)
walberla_cpp.log_info_on_root("Simulating Scenario %d of %d :" % (idx, len(self._scenarios)))
yield cfg
walberla_cpp.log_info_on_root( "Simulating Scenario %d of %d :" % ( idx+1, len(self._scenarios) ) )
config = scenario.config( *args, **kwargs )
yield config
except ImportError: except ImportError:
pass pass
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment