Skip to content

Commit

Permalink
Improve PEP8 conformity
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Gustafsson committed Mar 9, 2019
1 parent 112fc9f commit c8ad891
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 93 deletions.
1 change: 0 additions & 1 deletion skfem/assembly/global_basis/global_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ def default_parameters(self):
parameters for 'w'."""
raise NotImplementedError("Default parameters not implemented.")


def interpolate(self,
w: ndarray) -> Any:
"""Interpolate a solution vector to quadrature points.
Expand Down
148 changes: 82 additions & 66 deletions skfem/mesh/mesh.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import numpy as np
import matplotlib.pyplot as plt
import warnings

from typing import Dict, Optional, Tuple,\
Type, TypeVar, Union,\
Callable
Callable, Any

import numpy as np
from numpy import ndarray
import matplotlib.pyplot as plt


MeshType = TypeVar('MeshType', bound='Mesh')
DimTuple = Union[Tuple[float], Tuple[float, float], Tuple[float, float, float]]


class Mesh():
"""A finite element mesh.
This is an abstract superclass. See the following implementations:
- :class:`~skfem.mesh.MeshTri`, triangular mesh
Expand Down Expand Up @@ -41,39 +42,50 @@ class Mesh():
types.
name
A string which is used in pretty printing the object.
subdomains
Named subsets of elements.
boundaries
Named subsets of boundary facets.
external
If Mesh is loaded from external format (object), the original
representation is kept here.
"""

refdom: str = "none"
refdom: str = "none"
brefdom: str = "none"
meshio_type: str = "none"
name: str = "Abstract"

p: ndarray = np.array([])
t: ndarray = np.array([])
p: ndarray = np.array([])
t: ndarray = np.array([])

subdomains: Dict[str, ndarray] = {}
boundaries: Dict[str, ndarray] = {}
external: Any = None

def __init__(self):
"""Check that p and t are C_CONTIGUOUS as this leads
to better performance."""
if self.p is not None:
if self.p.flags['F_CONTIGUOUS']:
if self.p.shape[1]>1000:
if self.p.shape[1] > 1000:
warnings.warn("Mesh.__init__(): Transforming " +
"over 100 vertices to C_CONTIGUOUS.")
"over 100 vertices to C_CONTIGUOUS.")
self.p = np.ascontiguousarray(self.p)
if self.t is not None:
if self.t.flags['F_CONTIGUOUS']:
if self.t.shape[1]>1000:
if self.t.shape[1] > 1000:
warnings.warn("Mesh.__init__(): Transforming " +
"over 100 elements to C_CONTIGUOUS.")
"over 100 elements to C_CONTIGUOUS.")
self.t = np.ascontiguousarray(self.t)

def __str__(self):
return self.__repr__()

def __repr__(self):
return self.name + " mesh "\
"with " + str(self.p.shape[1]) + " vertices " \
"with " + str(self.p.shape[1]) + " vertices "\
"and " + str(self.t.shape[1]) + " elements."

def show(self):
Expand Down Expand Up @@ -104,7 +116,7 @@ def _adaptive_refine(self, marked):

def refine(self, arg: Optional[Union[int, ndarray]] = None):
"""Refine the mesh.
Parameters
----------
arg
Expand All @@ -116,12 +128,12 @@ def refine(self, arg: Optional[Union[int, ndarray]] = None):
"""
if arg is None:
self._uniform_refine()
elif type(arg) is int:
elif isinstance(arg, int):
for itr in range(arg):
self._uniform_refine()
elif type(arg) is list:
elif isinstance(arg, list):
self._adaptive_refine(np.array(arg))
elif type(arg) is ndarray:
elif isinstance(arg, ndarray):
self._adaptive_refine(arg)
else:
raise NotImplementedError("The given parameter type not supported.")
Expand Down Expand Up @@ -161,7 +173,7 @@ def remove_elements(self, element_indices: ndarray) -> MeshType:
reverse[ptix] = np.arange(len(ptix))
newt = reverse[newt]
newp = self.p[:, ptix]
if newp.shape[1]==0.0:
if newp.shape[1] == 0.0:
raise Exception("The new mesh contains no points!")
meshclass = type(self)
return meshclass(newp, newt.astype(np.intp))
Expand Down Expand Up @@ -224,106 +236,106 @@ def _validate(self):
msg = "Mesh._validate(): Mesh contains duplicate vertices."
warnings.warn(msg)
# check that all points are at least in some element
if len(np.setdiff1d(np.arange(self.p.shape[1]), np.unique(self.t))):
if len(np.setdiff1d(np.arange(self.p.shape[1]), np.unique(self.t))) > 0:
msg = ("Mesh._validate(): Mesh contains a vertex "
"not belonging to any element.")
raise Exception(msg)

def save(self,
filename: str,
pointData: Optional[Union[ndarray, Dict[str, ndarray]]] = None,
cellData: Optional[Union[ndarray, Dict[str, ndarray]]] = None) -> None:
point_data: Optional[Union[ndarray, Dict[str, ndarray]]] = None,
cell_data: Optional[Union[ndarray, Dict[str, ndarray]]] = None) -> None:
"""Export the mesh and fields using meshio.
Parameters
----------
filename
The filename for vtk-file.
pointData
point_data
Data related to the vertices of the mesh. Numpy array for one
output or dict for multiple.
cellData
output, or dict for multiple.
cell_data
Data related to the elements of the mesh. Numpy array for one
output or dict for multiple
output, or dict for multiple
"""
import meshio

if pointData is not None:
if type(pointData) != dict:
pointData = {'0':pointData}
if point_data is not None:
if not isinstance(point_data, dict):
point_data = {'0' : point_data}

if cellData is not None:
if type(cellData) != dict:
cellData = {'0':cellData}
if cell_data is not None:
if not isinstance(point_data, dict):
cell_data = {'0' : cell_data}

cells = { self.meshio_type : self.t.T }
mesh = meshio.Mesh(self.p.T, cells, pointData, cellData)
cells = {self.meshio_type : self.t.T}
mesh = meshio.Mesh(self.p.T, cells, point_data, cell_data)
meshio.write(filename, mesh)

def _parse_submeshes(self) -> None:
"""Parse submeshes from self.external.
Call after creating a mesh using Mesh.from_meshio to parse Mesh.external into
Mesh.boundaries and Mesh.subdomains. Supports currently gmsh only.
Call after creating a mesh using Mesh.from_meshio to parse Mesh.external
into Mesh.boundaries and Mesh.subdomains. Supports currently gmsh only.
"""

# element to boundary element type mapping
bnd_type = {
'triangle':'line',
'quad':'line',
'tetra':'triangle',
'hexahedron':'quad',
'triangle' : 'line',
'quad' : 'line',
'tetra' : 'triangle',
'hexahedron' : 'quad',
}[self.meshio_type]

def find_tagname(t):
def find_tagname(tag):
for key in self.external.field_data:
if self.external.field_data[key][0] == t:
return key
if self.external.field_data[key][0] == tag:
return key
return None

# fill self.subdomains
if self.meshio_type in self.external.cell_data and \
if self.meshio_type in self.external.cell_data and\
'gmsh:physical' in self.external.cell_data[self.meshio_type]:
elements = self.external.cells[self.meshio_type]
elements_tag = self.external.cell_data[self.meshio_type]['gmsh:physical']

self.subdomains = {}
tags = np.unique(elements_tag)

for tag in tags:
t_set = np.nonzero(tag == elements_tag)[0]
self.subdomains[find_tagname(tag)] = t_set

# fill self.boundaries
if bnd_type in self.external.cell_data and \
if bnd_type in self.external.cell_data and\
'gmsh:physical' in self.external.cell_data[bnd_type]:
facets = self.external.cells[bnd_type]
facets_tag = self.external.cell_data[bnd_type]['gmsh:physical']
bndfacets = self.boundary_facets()

# put meshio facets to dict
dic = {tuple(np.sort(facets[i])): facets_tag[i] for i in range(facets.shape[0])}

dic = {tuple(np.sort(facets[i])) : facets_tag[i]
for i in range(facets.shape[0])}

# get index of corresponding Mesh.facets for each meshio
# facet found in the dict
ix = np.array([[dic[tuple(np.sort(self.facets[:, i]))], i]
for i in bndfacets
if tuple(np.sort(self.facets[:, i])) in dic])
index = np.array([[dic[tuple(np.sort(self.facets[:, i]))], i]
for i in bndfacets
if tuple(np.sort(self.facets[:, i])) in dic])

# read meshio tag numbers and names
tags = ix[:, 0]
tags = index[:, 0]
self.boundaries = {}

for tag in np.unique(tags):
tagix = np.nonzero(tags == tag)[0]
self.boundaries[find_tagname(tag)] = ix[tagix, 1]
tagindex = np.nonzero(tags == tag)[0]
self.boundaries[find_tagname(tag)] = index[tagindex, 1]

@classmethod
def from_meshio(cls: Type[MeshType], meshdata) -> MeshType:
"""Translate a mesh from `meshio
<https://github.com/nschloe/meshio>`_.
Parameters
----------
meshdata
Expand All @@ -342,7 +354,7 @@ def from_meshio(cls: Type[MeshType], meshdata) -> MeshType:
t = np.ascontiguousarray(meshdata.cells[cls.meshio_type].T)
mesh = cls(p, t)
mesh.external = meshdata

# load submeshes, currently gmsh only
try:
mesh._parse_submeshes()
Expand All @@ -353,16 +365,16 @@ def from_meshio(cls: Type[MeshType], meshdata) -> MeshType:
print(e)

return mesh
else:
raise Exception("The mesh contains no elements of type " + cls.meshio_type)

raise Exception("The mesh contains no elements of type " + cls.meshio_type)

@classmethod
def load(cls: Type[MeshType],
filename: str,
from_url: Optional[bool] = False) -> MeshType:
"""Load an external mesh from file or url using `meshio
<https://github.com/nschloe/meshio>`_.
Parameters
----------
filename
Expand All @@ -372,7 +384,7 @@ def load(cls: Type[MeshType],
"""
import meshio

if from_url:
import tempfile
from urllib.request import urlopen
Expand All @@ -382,7 +394,7 @@ def load(cls: Type[MeshType],
tmp.write(urlopen(filename).read())
tmp.flush()
filename = tmp.name

return cls.from_meshio(meshio.read(filename))

def boundary_nodes(self) -> ndarray:
Expand All @@ -406,3 +418,7 @@ def element_finder(self) -> Callable[[ndarray], ndarray]:
indices corresponding to the input points."""
raise NotImplementedError("element_finder not implemented" +\
"for the given Mesh type.")

@staticmethod
def strip_extra_coordinates(p: ndarray) -> ndarray:
return p
22 changes: 11 additions & 11 deletions skfem/mesh/mesh2d/mesh2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,34 +148,34 @@ def mirror(self, a: float, b: float, c: float) -> MeshType:

def save(self,
filename: str,
pointData: Optional[Union[ndarray, Dict[str, ndarray]]] = None,
cellData: Optional[Union[ndarray, Dict[str, ndarray]]] = None) -> None:
point_data: Optional[Union[ndarray, Dict[str, ndarray]]] = None,
cell_data: Optional[Union[ndarray, Dict[str, ndarray]]] = None) -> None:
"""Export the mesh and fields using meshio. (2D version.)
Parameters
----------
filename
The filename for vtk-file.
pointData
point_data
Data related to the vertices of the mesh. Numpy array for one
output or dict for multiple.
cellData
cell_data
Data related to the elements of the mesh. Numpy array for one
output or dict for multiple
"""
import meshio

if pointData is not None:
if type(pointData) != dict:
pointData = {'0':pointData}
if point_data is not None:
if type(point_data) != dict:
point_data = {'0':point_data}

if cellData is not None:
if type(cellData) != dict:
cellData = {'0':cellData}
if cell_data is not None:
if type(cell_data) != dict:
cell_data = {'0':cell_data}

cells = { self.meshio_type : self.t.T }
mesh = meshio.Mesh(self.p.T, cells, pointData, cellData)
mesh = meshio.Mesh(self.p.T, cells, point_data, cell_data)
meshio.write(filename, mesh)

def param(self) -> float:
Expand Down
4 changes: 0 additions & 4 deletions skfem/mesh/mesh3d/mesh3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,3 @@ def param(self) -> float:
"""Return mesh parameter, viz the length of the longest edge."""
return np.max(np.linalg.norm(np.diff(self.p[:, self.edges], axis=1),
axis=0))

@staticmethod
def strip_extra_coordinates(p: ndarray) -> ndarray:
return p
Loading

0 comments on commit c8ad891

Please sign in to comment.