Source code for sfepy.discrete.iga.utils

"""
Utility functions based on igakit.
"""
from __future__ import absolute_import
import numpy as nm

from sfepy.base.base import Struct
from sfepy.discrete.fem import Mesh
from sfepy.mesh.mesh_generators import get_tensor_product_conn
import six
from six.moves import range

[docs]def create_linear_fe_mesh(nurbs, pars=None): """ Convert a NURBS object into a nD-linear tensor product FE mesh. Parameters ---------- nurbs : igakit.nurbs.NURBS instance The NURBS object. pars : sequence of array, optional The values of parameters in each parametric dimension. If not given, the values are set so that the resulting mesh has the same number of vertices as the number of control points/basis functions of the NURBS object. Returns ------- coors : array The coordinates of mesh vertices. conn : array The vertex connectivity array. desc : str The cell kind. """ knots = nurbs.knots shape = nurbs.weights.shape if pars is None: pars = [] for ii, kv in enumerate(knots): par = nm.linspace(kv[0], kv[-1], shape[ii]) pars.append(par) coors = nurbs(*pars) coors.shape = (-1, coors.shape[-1]) conn, desc = get_tensor_product_conn([len(ii) for ii in pars]) if (coors[:, -1] == 0.0).all(): coors = coors[:, :-1] return coors, conn, desc
[docs]def create_mesh_and_output(nurbs, pars=None, **kwargs): """ Create a nD-linear tensor product FE mesh using :func:`create_linear_fe_mesh()`, evaluate field variables given as keyword arguments in the mesh vertices and create a dictionary of output data usable by Mesh.write(). Parameters ---------- nurbs : igakit.nurbs.NURBS instance The NURBS object. pars : sequence of array, optional The values of parameters in each parametric dimension. If not given, the values are set so that the resulting mesh has the same number of vertices as the number of control points/basis functions of the NURBS object. **kwargs : kwargs The field variables as keyword arguments. Their names serve as keys in the output dictionary. Returns ------- mesh : Mesh instance The finite element mesh. out : dict The output dictionary. """ coors, conn, desc = create_linear_fe_mesh(nurbs, pars) mat_id = nm.zeros(conn.shape[0], dtype=nm.int32) mesh = Mesh.from_data('nurbs', coors, None, [conn], [mat_id], [desc]) out = {} for key, variable in six.iteritems(kwargs): if variable.ndim == 2: nc = variable.shape[1] field = variable.reshape(nurbs.weights.shape + (nc,)) else: field = variable.reshape(nurbs.weights.shape) nc = 1 vals = nurbs.evaluate(field, *pars) out[key] = Struct(name='output_data', mode='vertex', data=vals.reshape((-1, nc))) return mesh, out
[docs]def save_basis(nurbs, pars): """ Save a NURBS object basis on a FE mesh corresponding to the given parametrization in VTK files. Parameters ---------- nurbs : igakit.nurbs.NURBS instance The NURBS object. pars : sequence of array, optional The values of parameters in each parametric dimension. """ coors, conn, desc = create_linear_fe_mesh(nurbs, pars) mat_id = nm.zeros(conn.shape[0], dtype=nm.int32) mesh = Mesh.from_data('nurbs', coors, None, [conn], [mat_id], [desc]) n_dof = nurbs.weights.ravel().shape[0] variable = nm.zeros(n_dof, dtype=nm.float64) field = variable.reshape(nurbs.weights.shape) for ic in range(n_dof): variable[ic - 1] = 0.0 variable[ic] = 1.0 vals = nurbs.evaluate(field, *pars).reshape((-1)) out = {} out['bf'] = Struct(name='output_data', mode='vertex', data=vals[:, None]) mesh.write('iga_basis_%03d.vtk' % ic, io='auto', out=out)