# Path: sucemfem/Forms.py
# class NullForm(object):
# class GalerkinInteriorForms(object):
# class EMGalerkinInteriorForms(GalerkinInteriorForms):
# class CombineGalerkinForms(object):
#     def __add__(self, other):
#     def set_material_functions(self, material_functions):
#     def set_function_space(self, function_space):
#     def get_mass_form(self):
#     def get_stiffness_form(self):
#     def get_mass_form(self):
#     def get_stiffness_form(self):
#     def set_interior_forms(self, interior_forms):
#     def set_boundary_conditions(self, boundary_conditions):
#     def get_combined_forms(self):
#         V = self.function_space = function_space
# 
# Path: sucemfem/Materials.py
# class MaterialProperties(object):
# class MaterialPropertiesFactory(object):
# class MaterialFunctionFactory(object):
#     def __init__(self):
#     def init_values(self, **kwargs):
#     def set_eps_r(self, eps_r):
#     def set_mu_r(self, mu_r):
#     def get_eps_r(self):
#     def get_mu_r(self):
#     def get_mu_r_inv(self):
#     def get_eps(self):
#     def get_mu(self):
#     def __init__(self, material_regions):
#     def get_material_properties(self):
#     def __init__(self, region_material_properties, region_meshfunction, mesh):
#     def get_material_functions(self, *property_names):
# 
# Path: sucemfem/SystemMatrices.py
# class SystemMatrices(object):
#     MatrixClass = dolfin.PETScMatrix
# 
#     def set_matrix_class(self, matrix_class):
#         """Set matrix class to use for system matrix.
# 
#         Overrides the default value (dolfin.PETScMatrix) set in the
#         class definition
#         
#         """
#         self.MatrixClass = matrix_class
# 
#     def set_matrix_forms(self, matrix_forms):
#         """Set matrix_forms with a dict mapping matrix names to bilinear forms"""
#         self.matrix_forms = matrix_forms
# 
#     def set_boundary_conditions(self, boundary_conditions):
#         """Set boundary_conditions with instance of BoundaryConditions"""
#         self.boundary_conditions = boundary_conditions
# 
#     def calc_system_matrices(self):
#         """Calculate and return system matrices in a dict"""
#         system_matrices = dict()
#         for matname, form in self.matrix_forms.items():
#             mat = self.MatrixClass()
#             if isinstance(form, Forms.NullForm):
#                 mat = None
#             else:
#                 dolfin.assemble(form, tensor=mat)
#                 self.boundary_conditions.apply_essential(mat)
#             system_matrices[matname] = mat
# 
#         return system_matrices
# 
# Path: sucemfem/BoundaryConditions/container.py
# class BoundaryConditions(object):
#     def __init__(self):
#         self.boundary_conditions = {}
#         
#     def add_boundary_condition(self, boundary_condition):
#         bc_num = boundary_condition.region_number
#         # boundary condition numbers have to be unique
#         assert(bc_num not in self.boundary_conditions)
#         self.boundary_conditions[bc_num] = boundary_condition
# 
#     def apply_essential(self, A, b=None):
#         """
#         Apply essential boundary conditions to system matrix A and optional RHS b
#         """
#         for bc_num, bc in self.boundary_conditions.items():
#             apply_fn = bc.get_essential_application_func()
#             if b: apply_fn(A, b)
#             else: apply_fn(A)
# 
#     def get_linear_form(self):
#         """Get boundary conditions contribution to RHS linear form
#         """
#         lin_form = Forms.NullForm()
#         for bc_num, bc in self.boundary_conditions.items():
#             lin_form = lin_form + bc.get_linear_form()
# 
#         return lin_form
# 
#     def get_bilinear_form(self):
#         """Get boundary conditions contribution to bilinear form
#         """
# 
#         bilin_form = Forms.NullForm()
#         for bc_num, bc in self.boundary_conditions.items():
#             bilin_form = bilin_form + bc.get_bilinear_form()
# 
#         return bilin_form
# 
#     def set_function_space(self, function_space):
#         """Set all the boundary conditions in the collection's function_space
#         """
#         self.function_space = function_space
#         for bc in self.boundary_conditions.values():
#             bc.set_function_space(function_space)


import dolfin
from sucemfem import Forms 
from sucemfem import Materials 
from sucemfem import SystemMatrices
from sucemfem.BoundaryConditions import BoundaryConditions
        
    def _init_function_space (self):
        """If required, initialise a dolfin function space from the stored mesh, element_type, and basis function order information.
        """
        if self.function_space is None:
            self.function_space = dolfin.FunctionSpace(
                self.mesh, self.element_type, self.basis_order)
    
    def _init_interior_forms(self):
        """Initialise the Galerkin interior forms for the problem.
        """
        self.interior_forms = Forms.EMGalerkinInteriorForms()
        self.interior_forms.set_material_functions(self.material_functions)
        self.interior_forms.set_function_space(self.function_space)
            
    def _init_material_properties (self):
        mat_props_fac = Materials.MaterialPropertiesFactory ( self.material_regions )
        mat_func_fac = Materials.MaterialFunctionFactory(
            mat_props_fac.get_material_properties(), 
            self.region_meshfunction, 
            self.mesh )
        self.material_functions = mat_func_fac.get_material_functions ( 'eps_r', 'mu_r' )
    
    def _init_system_matrices (self, matrix_class=None):
        """Initialise the system matrices associated with the problem.
        
        @keyword matrix_class: An optional dolfin class to use for matrix storage.
            (default: None).
        """
        bilin_forms = self.combined_forms.get_forms()

# Path: sucemfem/Forms.py
# class NullForm(object):
# class GalerkinInteriorForms(object):
# class EMGalerkinInteriorForms(GalerkinInteriorForms):
# class CombineGalerkinForms(object):
#     def __add__(self, other):
#     def set_material_functions(self, material_functions):
#     def set_function_space(self, function_space):
#     def get_mass_form(self):
#     def get_stiffness_form(self):
#     def get_mass_form(self):
#     def get_stiffness_form(self):
#     def set_interior_forms(self, interior_forms):
#     def set_boundary_conditions(self, boundary_conditions):
#     def get_combined_forms(self):
#         V = self.function_space = function_space
# 
# Path: sucemfem/Materials.py
# class MaterialProperties(object):
# class MaterialPropertiesFactory(object):
# class MaterialFunctionFactory(object):
#     def __init__(self):
#     def init_values(self, **kwargs):
#     def set_eps_r(self, eps_r):
#     def set_mu_r(self, mu_r):
#     def get_eps_r(self):
#     def get_mu_r(self):
#     def get_mu_r_inv(self):
#     def get_eps(self):
#     def get_mu(self):
#     def __init__(self, material_regions):
#     def get_material_properties(self):
#     def __init__(self, region_material_properties, region_meshfunction, mesh):
#     def get_material_functions(self, *property_names):
# 
# Path: sucemfem/SystemMatrices.py
# class SystemMatrices(object):
#     MatrixClass = dolfin.PETScMatrix
# 
#     def set_matrix_class(self, matrix_class):
#         """Set matrix class to use for system matrix.
# 
#         Overrides the default value (dolfin.PETScMatrix) set in the
#         class definition
#         
#         """
#         self.MatrixClass = matrix_class
# 
#     def set_matrix_forms(self, matrix_forms):
#         """Set matrix_forms with a dict mapping matrix names to bilinear forms"""
#         self.matrix_forms = matrix_forms
# 
#     def set_boundary_conditions(self, boundary_conditions):
#         """Set boundary_conditions with instance of BoundaryConditions"""
#         self.boundary_conditions = boundary_conditions
# 
#     def calc_system_matrices(self):
#         """Calculate and return system matrices in a dict"""
#         system_matrices = dict()
#         for matname, form in self.matrix_forms.items():
#             mat = self.MatrixClass()
#             if isinstance(form, Forms.NullForm):
#                 mat = None
#             else:
#                 dolfin.assemble(form, tensor=mat)
#                 self.boundary_conditions.apply_essential(mat)
#             system_matrices[matname] = mat
# 
#         return system_matrices
# 
# Path: sucemfem/BoundaryConditions/container.py
# class BoundaryConditions(object):
#     def __init__(self):
#         self.boundary_conditions = {}
#         
#     def add_boundary_condition(self, boundary_condition):
#         bc_num = boundary_condition.region_number
#         # boundary condition numbers have to be unique
#         assert(bc_num not in self.boundary_conditions)
#         self.boundary_conditions[bc_num] = boundary_condition
# 
#     def apply_essential(self, A, b=None):
#         """
#         Apply essential boundary conditions to system matrix A and optional RHS b
#         """
#         for bc_num, bc in self.boundary_conditions.items():
#             apply_fn = bc.get_essential_application_func()
#             if b: apply_fn(A, b)
#             else: apply_fn(A)
# 
#     def get_linear_form(self):
#         """Get boundary conditions contribution to RHS linear form
#         """
#         lin_form = Forms.NullForm()
#         for bc_num, bc in self.boundary_conditions.items():
#             lin_form = lin_form + bc.get_linear_form()
# 
#         return lin_form
# 
#     def get_bilinear_form(self):
#         """Get boundary conditions contribution to bilinear form
#         """
# 
#         bilin_form = Forms.NullForm()
#         for bc_num, bc in self.boundary_conditions.items():
#             bilin_form = bilin_form + bc.get_bilinear_form()
# 
#         return bilin_form
# 
#     def set_function_space(self, function_space):
#         """Set all the boundary conditions in the collection's function_space
#         """
#         self.function_space = function_space
#         for bc in self.boundary_conditions.values():
#             bc.set_function_space(function_space)


# Path: sucemfem/ProblemConfigurations/EMProblem.py
import dolfin
from sucemfem import Forms 
from sucemfem import Materials 
from sucemfem import SystemMatrices
from sucemfem.BoundaryConditions import BoundaryConditions

        
    def _init_function_space (self):
        """If required, initialise a dolfin function space from the stored mesh, element_type, and basis function order information.
        """
        if self.function_space is None:
            self.function_space = dolfin.FunctionSpace(
                self.mesh, self.element_type, self.basis_order)
    
    def _init_interior_forms(self):
        """Initialise the Galerkin interior forms for the problem.
        """
        self.interior_forms = Forms.EMGalerkinInteriorForms()
        self.interior_forms.set_material_functions(self.material_functions)
        self.interior_forms.set_function_space(self.function_space)
            
    def _init_material_properties (self):
        mat_props_fac = Materials.MaterialPropertiesFactory ( self.material_regions )
        mat_func_fac = Materials.MaterialFunctionFactory(
            mat_props_fac.get_material_properties(), 
            self.region_meshfunction, 
            self.mesh )
        self.material_functions = mat_func_fac.get_material_functions ( 'eps_r', 'mu_r' )
    
    def _init_system_matrices (self, matrix_class=None):
        """Initialise the system matrices associated with the problem.
        
        @keyword matrix_class: An optional dolfin class to use for matrix storage.
            (default: None).
        """
        bilin_forms = self.combined_forms.get_forms()

        sysmats = SystemMatrices.SystemMatrices()