Skip to content

Commit

Permalink
Merge pull request #3608 from KratosMultiphysics/core/new-app-importer
Browse files Browse the repository at this point in the history
Cleaning up Python module import infrastructure
  • Loading branch information
jcotela authored Jan 16, 2019
2 parents e821b18 + f114752 commit c110c57
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 693 deletions.
4 changes: 0 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -435,10 +435,8 @@ endif(DEFINED KRATOS_INSTALL_PREFIX)
# install core files for the KratosMultiphysics python module
# note that this does not install KratosLoader.py, as it is different for installation and packaging runs (see next code block)
install(FILES "${CMAKE_SOURCE_DIR}/kratos/python_interface/__init__.py" DESTINATION KratosMultiphysics )
install(FILES "${CMAKE_SOURCE_DIR}/kratos/python_interface/kratos_utilities.py" DESTINATION KratosMultiphysics )
install(FILES "${CMAKE_SOURCE_DIR}/kratos/python_interface/kratos_globals.py" DESTINATION KratosMultiphysics )
install(FILES "${CMAKE_SOURCE_DIR}/kratos/python_interface/application_importer.py" DESTINATION KratosMultiphysics )
install(FILES "${CMAKE_SOURCE_DIR}/kratos/python_interface/kratos_unittest.py" DESTINATION KratosMultiphysics RENAME KratosUnittest.py )

# Remove the tags in the event of multiple versions of boost being found
# in the same directory
Expand Down Expand Up @@ -466,7 +464,6 @@ kratos_applications=os.path.abspath(os.path.join(os.path.dirname(__file__),'../a
kratos_scripts=os.path.abspath(os.path.join(os.path.dirname(__file__),'../kratos/python_scripts'))
kratos_tests=os.path.abspath(os.path.join(os.path.dirname(__file__),'../kratos/tests'))
sys.path.append(kratos_libs)
sys.path.append(kratos_applications)
sys.path.append(kratos_scripts)
sys.path.append(kratos_tests)
")
Expand Down Expand Up @@ -495,7 +492,6 @@ kratos_applications=\"${CMAKE_SOURCE_DIR}/applications\"
kratos_scripts=\"${CMAKE_INSTALL_PREFIX}/kratos/python_scripts\"
kratos_tests=\"${CMAKE_INSTALL_PREFIX}/kratos/tests\"
sys.path.append(kratos_libs)
sys.path.append(kratos_applications)
sys.path.append(kratos_scripts)
sys.path.append(kratos_tests) ")
endif(${INSTALL_PYTHON_FILES} MATCHES ON)
9 changes: 3 additions & 6 deletions applications/MappingApplication/MappingApplication.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
from __future__ import print_function, absolute_import, division

# Application dependent names and paths
import KratosMultiphysics as KM
from KratosMappingApplication import *
application = KratosMappingApplication()
application_name = "KratosMappingApplication"
application_folder = "MappingApplication"

# The following lines are common for all applications
from .. import application_importer
import inspect
caller = inspect.stack()[1] # Information about the file that imported this, to check for unexpected imports
application_importer.ImportApplication(application,application_name,application_folder,caller,__path__)
KM._ImportApplicationAsModule(application, application_name, application_folder, __path__)

'''
TODO:
Expand All @@ -27,4 +24,4 @@
- Delete copy and assignment-constructors?
- testing => do some logical tests with USE_TRANSPOSE
- MapperFlags: Check that they are used correctly and all of them are used in tests (USE_TRANSPOSE)
'''
'''
634 changes: 0 additions & 634 deletions applications/applications_interface.py

This file was deleted.

27 changes: 18 additions & 9 deletions kratos/python_interface/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
from __future__ import print_function, absolute_import, division #makes KratosMultiphysics backward compatible with python 2.6 and 2.7
import os.path
import sys
import inspect
from . import kratos_globals

from .kratos_utilities import *

# this adds the libs/ and applications/ folders to sys.path
from . import KratosLoader

Expand All @@ -19,6 +15,7 @@ def __ModuleInitDetail():
and the parallel DataCommunicator are initialized when the Kernel is built.
It is defined as a function to avoid polluting the Kratos namespace with local variables.
"""
import sys
if "--using-mpi" in sys.argv[1:]:
try:
import KratosMultiphysics.mpi
Expand All @@ -33,15 +30,27 @@ def __ModuleInitDetail():

__ModuleInitDetail()

KratosGlobals = kratos_globals.KratosGlobals(
Kernel(), inspect.stack()[1], KratosLoader.kratos_applications)

# Initialize Kernel so that core variables have an assigned Key even if we are not importing applications
KratosGlobals.Kernel.Initialize()
KratosGlobals = kratos_globals.KratosGlobalsImpl(
Kernel(), KratosLoader.kratos_applications)

# adding the scripts in "kratos/python_scripts" such that they are treated as a regular python-module
__path__.append(KratosLoader.kratos_scripts)

def _ImportApplicationAsModule(application, application_name, application_folder, mod_path):
Kernel = KratosGlobals.Kernel
applications_root = KratosGlobals.ApplicationsRoot

Logger.PrintInfo("", "Importing " + application_name)

# adding the scripts in "APP_NAME/python_scripts" such that they are treated as a regular python-module
application_path = os.path.join(applications_root, application_folder)
python_path = os.path.join(application_path, 'python_scripts')
mod_path.append(python_path)

# Add application to kernel
Kernel.ImportApplication(application)


def CheckForPreviousImport():
warn_msg = '"CheckForPreviousImport" is not needed any more and can be safely removed\n'
warn_msg += 'It does nothing any more'
Expand Down
47 changes: 16 additions & 31 deletions kratos/python_interface/application_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,22 @@
def ImportApplication(application, application_name, application_folder, caller, mod_path=None):
Globals = KratosMultiphysics.KratosGlobals
Kernel = Globals.Kernel
main_caller = Globals.AuthorizedCaller
applications_root = Globals.ApplicationsRoot
# caller and main_caller are generated from the output of inspect.stack().
# In particular position [1] is the name of the file containing the call.
# Note that position [0] (a frame instance) could also be used for the check,
# but can return false if both calls are made from the python interpreter
if main_caller[1] != caller[1]:
msg = "\n***\n* Python file " + str(caller[1]) + "\n* requires " + str(application_name) + "\n* Please import it from your main Python script, " +str(main_caller[1]+"\n* If your main Python script is already importing it, you may need to re-order the imports"+'\n***')
# print caller
# print main_caller
raise RuntimeError(msg)
elif application_name not in Globals.RequestedApplications: # This check is possibly redundant, as Python won't import the same module twice
Logger.PrintInfo("", "Importing " + application_name)
# Add application to dictionary of registered applications
Globals.RequestedApplications[application_name] = application
# Add python scrips folder to path
application_path = os.path.join(applications_root, application_folder)
python_path = os.path.join(application_path, 'python_scripts')
sys.path.append(python_path)
# Add constitutive laws python scrips folder to path
constitutive_laws_path = os.path.join(python_path, 'constitutive_laws')
sys.path.append(constitutive_laws_path)

# adding the scripts in "APP_NAME/python_scripts" such that they are treated as a regular python-module
if mod_path is not None: # optional for backwards compatibility
mod_path.append(python_path)
Logger.PrintInfo("", "Importing " + application_name)

# Add python scrips folder to path
application_path = os.path.join(applications_root, application_folder)
python_path = os.path.join(application_path, 'python_scripts')
sys.path.append(python_path)
# Add constitutive laws python scrips folder to path
constitutive_laws_path = os.path.join(python_path, 'constitutive_laws')
sys.path.append(constitutive_laws_path)

# adding the scripts in "APP_NAME/python_scripts" such that they are treated as a regular python-module
if mod_path is not None: # optional for backwards compatibility
mod_path.append(python_path)

# Add application to kernel
Kernel.ImportApplication(application)

# Add application to kernel
Kernel.ImportApplication(application)
# Dynamic renumbering of variables to ensure consistency
Kernel.Initialize()
for iterName, iterApplication in list(Globals.RequestedApplications.items()):
# print("Initializing",iterName)
Kernel.InitializeApplication(iterApplication)
11 changes: 2 additions & 9 deletions kratos/python_interface/kratos_globals.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
from __future__ import print_function, absolute_import, division #makes KratosMultiphysics backward compatible with python 2.6 and 2.7

class KratosGlobals:
class KratosGlobalsImpl(object):

def __init__(self, ThisKernel, ThisCaller, ApplicationsRoot):
def __init__(self, ThisKernel, ApplicationsRoot):
self.__dict__["Kernel"] = ThisKernel
self.__dict__["RequestedApplications"] = dict()
self.__dict__["AuthorizedCaller"] = ThisCaller
self.__dict__["ApplicationsRoot"] = ApplicationsRoot
self.__dict__["ApplicationsInterfaceIsDeprecated"] = False

def __setattr__(self, name, value):
if name in self.__dict__:
# self.__dict__[name] = value
print("Ignoring request to set KratosGlobals attribute", name)
else:
print("Ignoring request to set unknown KratosGlobals attribute:", name)

def echo(self):
print("Kernel:", self.Kernel)
print("RequestedApplications:", self.RequestedApplications)
print("Main Python script:", self.AuthorizedCaller)
print("Kratos Applications base folder:", self.ApplicationsRoot)
return

def GetFlag(self, FlagName):
""" This method returns the flag with the given name
Expand Down
File renamed without changes.
File renamed without changes.

0 comments on commit c110c57

Please sign in to comment.