Source code for simudo.mesh.refine

from __future__ import absolute_import, division, print_function

from builtins import bytes, dict, int, range, str, super
from functools import partial

import numpy as np

import dolfin


[docs]def refine_forever(refinement_objs, make_predicate): while True: mesh = refinement_objs['mesh'] predicate = make_predicate() mf = predicate_to_meshfunction(mesh, predicate, predicate.dim) if not any(mf.array()): break mesh2 = adapt(mesh, mf) for k, v in refinement_objs.items(): if v is mesh: v = mesh2 else: v = adapt(v, mesh2) refinement_objs[k] = v return mesh
[docs]def predicate_to_meshfunction(mesh, predicate, dim): mf = dolfin.MeshFunction( "bool", mesh, dim, False) mark_using_predicate(mf, mesh, predicate) return mf
[docs]def mark_using_predicate(mf, mesh, predicate): for entity in dolfin.entities(mesh, mf.dim()): if predicate(entity): mf[entity] = True
[docs]def cell_predicate_expr_threshold(mesh, function, threshold): '''function must be a dolfin.FunctionSpace or pint wrapper around one''' if hasattr(function, 'units'): threshold = threshold.m_as(function.units) function = function.magnitude fvec = function.vector() dofmap = function.function_space().dofmap() def predicate(cell): cell_index = cell.index() cell_dofs = dofmap.cell_dofs(cell_index) val = np.amax(np.abs(fvec[cell_dofs])) return (val >= threshold) or None return predicate
[docs]def adapt(obj, *args, **kwargs): if isinstance(obj, (dolfin.cpp.mesh.MeshFunctionBool, dolfin.cpp.mesh.MeshFunctionDouble, dolfin.cpp.mesh.MeshFunctionInt, dolfin.cpp.mesh.MeshFunctionSizet)): return adapt_mf(obj, *args, **kwargs) # why it's stupid: # https://bitbucket.org/fenics-project/dolfin/issues/319/faulty-memory-management-in-adapt dolfin.adapt(obj, *args, **kwargs) return obj.child()
[docs]def adapt_mf(mf, new_mesh): # why it's stupid: see adapt_workaround # why it's even stupider: # MeshFunction::child() has two C++ methods associated (differing # only in a const on the return type) and SWIG couldn't # distinguish between them, so it errors out. bad = dolfin.adapt(mf, new_mesh) good = dolfin.MeshFunction("size_t", new_mesh, mf.dim(), 0) good.array()[:] = bad.array()[:] del bad return good