Skip to content

Commit

Permalink
Merge pull request #4 from padmec-reservoir/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
gpkc authored Aug 29, 2017
2 parents 0456a6b + 56c1407 commit 9c4478d
Show file tree
Hide file tree
Showing 69 changed files with 9,107 additions and 659,777 deletions.
88 changes: 12 additions & 76 deletions elliptic/Kernel/AdjKernelMixin.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import numpy as np
import itertools

from KernelBase import KernelBase
from elliptic.Physical import PhysicalBase


class AdjKernelMixin(KernelBase):

cache_adj = False
adj = {}
adj_str = {}
for (bridge_dim, target_dim, depth) in itertools.product(
*itertools.repeat([0, 1, 2, 3], 3)):
tag_name = "_adj_tag_{0}{1}{2}".format(
bridge_dim, target_dim, depth)
adj_str[(bridge_dim, target_dim, depth)] = tag_name

@classmethod
def get_adj(cls, m, elem, bridge_dim,
target_dim, depth=1):
def get_adj(self, elem, bridge_dim, target_dim, depth=1):
"""Returns the elements adjacent to the element `elem`, through
`bridge_dim`, with dimension `target_dim`, and with the given `depth`.
Parameters
----------
m: elliptic.Mesh.Mesh.Mesh
Mesh object that is running the kernel.
elem:
Target element to get the adjacencies.
bridge_dim: unsigned int
Expand All @@ -30,73 +29,10 @@ def get_adj(cls, m, elem, bridge_dim,
Returns
-------
list
List of the adjacent elements.
iterable
Iterable of the adjacent elements.
"""
if cls.cache_adj:
try:
return cls.adj[(elem, bridge_dim, target_dim, depth)]
except KeyError:
cls.adj[
(elem,
bridge_dim,
target_dim,
depth)] = m.mesh_topo_util.get_bridge_adjacencies(
np.asarray([elem]),
bridge_dim,
target_dim,
depth)

return cls.adj[(elem, bridge_dim, target_dim, depth)]
else:
adj = m.mesh_topo_util.get_bridge_adjacencies(
np.asarray([elem]),
bridge_dim,
target_dim,
depth)
tag_name = self.adj_str[(bridge_dim, target_dim, depth)]
adj = self.mesh.get_adj(elem, tag_name)

return adj

@classmethod
def get_adj_physical(cls, m, elem, bridge_dim,
target_dim, depth=1, phys_type=(PhysicalBase,)):
"""Gets the Physical instances of the adjacent elements.
Parameters
----------
m: elliptic.Mesh.Mesh.Mesh
Mesh object that is running the kernel.
elem:
Target element to get the adjacent physicals.
bridge_dim: unsigned int
Bridge dimention through which the adjacent elements are obtained.
target_dim: unsigned int
Target dimesion. The adjacent elements will have this dimension.
depth: unsigned int, optional
Depth of the adjacency query. Defaults to 1.
phys_type: Iterable of elliptic.Physical.Physical, optional
The target Physical types (class). If not set, defaults to
[None].
If set, will return the first Physical of the given types that is
found.
Returns
-------
list of elliptic.Physical.Physical or elliptic.Physical.Physical
If `phys_type` is set to none, will return the first Physical
found. Returns a list containing all Physicals found otherwise.
"""
adj = cls.get_adj(m, elem, bridge_dim, target_dim, depth)
adj = set(adj)
physicals = []
for tag, elemset in m.tag2entset.iteritems():
if adj.intersection(elemset):
phys = m.physical_manager[tag]
for phys_check in phys_type:
if isinstance(phys, phys_check):
return phys

physicals.append(m.physical_manager[tag])

if not phys_type:
return physicals
136 changes: 81 additions & 55 deletions elliptic/Kernel/ArrayKernelMixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,19 @@ class FillArrayKernelBase(KernelBase):
solution_dim = -1
share = False

@classmethod
def check_kernel(cls):
"""Checks if the kernel has defined the `solution_dim` attribute.
"""
super(FillArrayKernelBase, cls).check_kernel()
if cls.solution_dim < 0:
raise ValueError("Kernel not properly initialized.")

@classmethod
def init_kernel(cls, m):
def __init__(self, mesh):
"""Initializes the `array_name` attribute, defaulting it to the Kernel's
class name if it was not defined.
"""
super(FillArrayKernelBase, cls).init_kernel(m)
if not cls.array_name:
cls.array_name = cls.__name__
super(FillArrayKernelBase, self).__init__(mesh)

@classmethod
def create_array(cls, matrix_manager):
if not self.array_name:
self.array_name = self.__class__.__name__

self.create_array()

def create_array(self):
"""Abstract method. Defines how the array associated with the Kernel
and the Mesh will be created.
Expand All @@ -55,8 +47,7 @@ def create_array(cls, matrix_manager):
"""
raise NotImplementedError

@classmethod
def fill_array(cls, mesh, vals):
def fill_array(self, vals):
"""Abstract method. Defines how to fill the associated array with
calculated values during the run method.
Expand All @@ -67,15 +58,13 @@ def fill_array(cls, mesh, vals):
"""
raise NotImplementedError

@classmethod
def get_array(cls, matrix_manager):
def get_array(self):
"""Defines how the associated array can be obtained.
"""
raise NotImplementedError

@classmethod
def set_dependency_vectors(cls, mesh):
def set_dependency_vectors(self):
"""Iterates over the `depends` attribute, and adds the associated array
of each Kernel, if applicable, with an attribute on this Kernel.
Expand All @@ -91,74 +80,104 @@ def set_dependency_vectors(cls, mesh):
>>> class Test2(DimensionEntityKernelMixin, FillMatrixKernelMixin):
... #...
... depends = [Test1]
... @classmethod
... def run(cls, m, elem):
... Test1_val = cls.Test1_array[elem]
"""
for dep in cls.depends:
if issubclass(dep, FillArrayKernelBase):
ar = dep.get_array(mesh.matrix_manager)
readonly_ar = ReadOnlyMatrix(ar, mesh.id_map)
setattr(cls, dep.array_name + '_array', readonly_ar)
if self.depends_instances:
for dep in self.depends_instances:
if isinstance(dep, FillArrayKernelBase):
ar = dep.get_array(self.mesh.matrix_manager)
readonly_ar = ReadOnlyMatrix(ar, self.mesh.id_map)
setattr(self, dep.array_name + '_array', readonly_ar)


class FillVectorKernelMixin(FillArrayKernelBase):
"""Defines a mixin for kernels that will fill a vector array.
"""

@classmethod
def create_array(cls, matrix_manager):
def __init__(self, mesh, solution_access=None):
super(FillVectorKernelMixin, self).__init__(mesh)
self.solution_access = solution_access

def create_array(self):
"""Defines how the associated vector will be created.
"""
matrix_manager.create_vector(
cls.solution_dim, cls.array_name, cls.share)
self.mesh.matrix_manager.create_vector(
self.solution_dim, self.array_name, self.share)

@classmethod
def fill_array(cls, mesh, vals):
def fill_array(self, vals):
"""Defines how the associated vector will be filled within the run()
method.
Parameters
----------
mesh: elliptic.Mesh.Mesh.Mesh
Mesh object that is running the kernel.
vals: list
List of (line, value) values.
"""
id_map = mesh.id_map
matrix_manager = mesh.matrix_manager
id_map = self.mesh.id_map
matrix_manager = self.mesh.matrix_manager

for elem, value in vals:
row = id_map[elem]
matrix_manager.fill_vector(cls.array_name, row, value)
matrix_manager.fill_vector(self.array_name, row, value)

@classmethod
def get_array(cls, matrix_manager):
def get_array(self):
"""Defines how the associated vector can be obtained.
"""
return matrix_manager.get_vector(cls.array_name)
return self.mesh.matrix_manager.get_vector(self.array_name)

def set_dependency_vectors(self):
super(FillVectorKernelMixin, self).set_dependency_vectors()
if self.solution_access:
for dep in self.solution_access:
ar = dep.get_array(self.mesh.matrix_manager)
readonly_ar = ReadOnlyMatrix(ar, self.mesh.id_map)
setattr(self, dep.array_name + '_array', readonly_ar)


class TransientExplicitKernelMixin(FillVectorKernelMixin):

@classmethod
def init_kernel(cls, m):
super(TransientExplicitKernelMixin, cls).init_kernel(m)
setattr(cls, 'array_name_old', cls.array_name + '_old')

@classmethod
def create_array(cls, matrix_manager):
super(TransientExplicitKernelMixin, cls).create_array(matrix_manager)
matrix_manager.create_vector(
cls.solution_dim, cls.array_name_old, True)

@classmethod
def set_dependency_vectors(cls, mesh):
super(TransientExplicitKernelMixin, cls).set_dependency_vectors(mesh)
ar = mesh.matrix_manager.get_vector(cls.array_name_old)
readonly_ar = ReadOnlyMatrix(ar, mesh.id_map)
setattr(cls, cls.array_name + '_old_array', readonly_ar)


class FillMatrixKernelMixin(FillArrayKernelBase):
"""Defines a mixin for kernels that will fill a matrix array.
"""

@classmethod
def create_array(cls, matrix_manager):
def __init__(self, mesh, solution_access=None):
super(FillMatrixKernelMixin, self).__init__(mesh)
self.solution_access = solution_access

def create_array(self):
"""Defines how the associated matrix will be created.
"""
matrix_manager.create_matrix(
cls.solution_dim, cls.array_name, cls.share)
self.mesh.matrix_manager.create_matrix(
self.solution_dim, self.array_name, self.share)

@classmethod
def fill_array(cls, mesh, vals):
def fill_array(self, vals):
"""Defines how the associated matrix will be filled within the run()
method.
Expand All @@ -171,25 +190,32 @@ def fill_array(cls, mesh, vals):
have a list of (line, columns, values) value. The 'set' values will
be set on the matrix, and the 'sum' values will be summed.
"""
id_map = mesh.id_map
matrix_manager = mesh.matrix_manager
id_map = self.mesh.id_map
matrix_manager = self.mesh.matrix_manager

set_values = vals['set']
sum_values = vals['sum']

for elem, cols, values in set_values:
row = id_map[elem]
cols = [id_map[col] for col in cols]
matrix_manager.fill_matrix(cls.array_name, row, cols, values)
matrix_manager.fill_matrix(self.array_name, row, cols, values)

for elem, cols, values in sum_values:
row = id_map[elem]
cols = [id_map[col] for col in cols]
matrix_manager.sum_into_matrix(cls.array_name, row, cols, values)
matrix_manager.sum_into_matrix(self.array_name, row, cols, values)

@classmethod
def get_array(cls, matrix_manager):
def get_array(self):
"""Defines how the associated matrix can be obtained.
"""
return matrix_manager.get_matrix(cls.array_name)
return self.mesh.matrix_manager.get_matrix(self.array_name)

def set_dependency_vectors(self):
super(FillMatrixKernelMixin, self).set_dependency_vectors()
if self.solution_access:
for dep in self.solution_access:
ar = dep.get_array(self.mesh.matrix_manager)
readonly_ar = ReadOnlyMatrix(ar, self.mesh.id_map)
setattr(self, dep.array_name + '_array', readonly_ar)
25 changes: 10 additions & 15 deletions elliptic/Kernel/EntityKernelMixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,18 @@ class DimensionEntityKernelMixin(KernelBase):
"""
entity_dim = -1

@classmethod
def check_kernel(cls):
if cls.entity_dim == -1:
raise ValueError(
'Value of entity_dim not initialized in {0}'.format(
cls.__name__))

super(DimensionEntityKernelMixin, cls).check_kernel()

@classmethod
def get_elements(cls, m):
ents = m.get_entities_by_meshset('ROOT', cls.entity_dim)
def get_elements(self):
ents = self.mesh.dimension_entities(self.entity_dim)
return ents


class MeshSetEntityKernelMixin(KernelBase):
"""Kernel that iterates over all entities of a meshset.
class MeshSetEntityKernelMixin(DimensionEntityKernelMixin):
"""Kernel that iterates over all meshsets from a tag.
"""
meshset_name = ""
meshset_tag_name = ""

def get_elements(self):
ents = self.mesh.get_entities_by_meshset(
self.meshset_tag_name, self.entity_dim)
return ents
Loading

0 comments on commit 9c4478d

Please sign in to comment.