71 lines
2.4 KiB
Python
71 lines
2.4 KiB
Python
import copy
|
|
from typing import Any, Dict, Union
|
|
|
|
import numpy as np
|
|
from skfem import MeshTri1
|
|
|
|
|
|
class Domain:
|
|
"""Square domain [0,1]x[0,1] with initial coarse mesh and fine integration mesh."""
|
|
|
|
def __init__(
|
|
self,
|
|
*,
|
|
domain_config: Dict[Union[str, int], Any],
|
|
random_state: np.random.RandomState,
|
|
):
|
|
xmin, ymin, xmax, ymax = domain_config.get("boundary", [0.0, 0.0, 1.0, 1.0])
|
|
self._boundary = np.array([xmin, ymin, xmax, ymax])
|
|
self._random_state = random_state
|
|
|
|
num_elements = domain_config.get("initial_num_elements", None)
|
|
if num_elements is not None:
|
|
domain_area = (xmax - xmin) * (ymax - ymin)
|
|
self._max_volume = 2.0 * domain_area / float(num_elements)
|
|
else:
|
|
self._max_volume = domain_config.get("max_initial_element_volume", 0.05)
|
|
|
|
self._initial_mesh = self._create_initial_mesh()
|
|
|
|
@property
|
|
def initial_mesh(self) -> MeshTri1:
|
|
return copy.deepcopy(self._initial_mesh)
|
|
|
|
def replace_initial_mesh(self, mesh: MeshTri1) -> None:
|
|
"""Replace the stored initial mesh (e.g. after Nyquist enforcement)."""
|
|
self._initial_mesh = mesh
|
|
|
|
def get_integration_mesh(self) -> MeshTri1:
|
|
return self._initial_mesh.refined(4)
|
|
|
|
@property
|
|
def boundary_line_segments(self) -> np.ndarray:
|
|
boundary_edges = self._initial_mesh.boundary_facets()
|
|
boundary_node_indices = self._initial_mesh.facets[:, boundary_edges]
|
|
return self._initial_mesh.p[:, boundary_node_indices].T.reshape(-1, 4)
|
|
|
|
def _create_initial_mesh(self) -> MeshTri1:
|
|
return self._meshpy_square()
|
|
|
|
def _meshpy_square(self) -> MeshTri1:
|
|
import meshpy.triangle as triangle
|
|
|
|
xmin, ymin, xmax, ymax = self._boundary
|
|
points = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)]
|
|
facets = [(0, 1), (1, 2), (2, 3), (3, 0)]
|
|
|
|
info = triangle.MeshInfo()
|
|
info.set_points(points)
|
|
info.set_facets(facets)
|
|
|
|
mesh = triangle.build(info, max_volume=self._max_volume)
|
|
vertices = np.array(mesh.points).T
|
|
triangles = np.array(mesh.elements).T
|
|
return MeshTri1(vertices, triangles)
|
|
|
|
|
|
def create_domain(
|
|
*, domain_config: Dict[Union[str, int], Any], random_state: np.random.RandomState
|
|
) -> Domain:
|
|
return Domain(domain_config=domain_config, random_state=random_state)
|