SfePy NTC

Source code for sfepy.discrete.conditions

"""
The Dirichlet, periodic and linear combination boundary condition
classes, as well as the initial condition class.
"""
import numpy as nm

from sfepy.base.base import basestr, Container, Struct
from sfepy.discrete.functions import Function

[docs]def get_condition_value(val, functions, kind, name): """ Check a boundary/initial condition value type and return the value or corresponding function. """ if type(val) == str: if functions is not None: try: fun = functions[val] except IndexError: raise ValueError('unknown function %s given for %s %s!' % (val, kind, name)) else: raise ValueError('no functions given for %s %s!' % (kind, name)) elif (isinstance(val, Function) or nm.isscalar(val) or isinstance(val, nm.ndarray)): fun = val else: raise ValueError('unknown value type for %s %s!' % (kind, name)) return fun
def _get_region(name, regions, bc_name): try: region = regions[name] except IndexError: msg = "no region '%s' used in condition %s!" % (name, bc_name) raise IndexError(msg) return region
[docs]class Conditions(Container): """ Container for various conditions. """ @staticmethod
[docs] def from_conf(conf, regions): conds = [] for key, cc in conf.iteritems(): times = cc.get('times', None) if 'ebc' in key: region = _get_region(cc.region, regions, cc.name) cond = EssentialBC(cc.name, region, cc.dofs, key=key, times=times) elif 'epbc' in key: rs = [_get_region(ii, regions, cc.name) for ii in cc.region] cond = PeriodicBC(cc.name, rs, cc.dofs, cc.match, key=key, times=times) elif 'lcbc' in key: if isinstance(cc.region, basestr): rs = [_get_region(cc.region, regions, cc.name), None] else: rs = [_get_region(ii, regions, cc.name) for ii in cc.region] cond = LinearCombinationBC(cc.name, rs, cc.dofs, cc.dof_map_fun, cc.kind, key=key, times=times, arguments=cc.get('arguments', None)) elif 'ic' in key: region = _get_region(cc.region, regions, cc.name) cond = InitialCondition(cc.name, region, cc.dofs, key=key) else: raise ValueError('unknown condition type! (%s)' % key) conds.append(cond) obj = Conditions(conds) return obj
[docs] def group_by_variables(self, groups=None): """ Group boundary conditions of each variable. Each condition is a group is a single condition. Parameters ---------- groups : dict, optional If present, update the `groups` dictionary. Returns ------- out : dict The dictionary with variable names as keys and lists of single condition instances as values. """ if groups is None: out = {} else: out = groups for cond in self: for single_cond in cond.iter_single(): vname = single_cond.dofs[0].split('.')[0] out.setdefault(vname, Conditions()).append(single_cond) return out
[docs] def canonize_dof_names(self, dofs): """ Canonize the DOF names using the full list of DOFs of a variable. """ for cond in self: cond.canonize_dof_names(dofs)
[docs] def sort(self): """ Sort boundary conditions by their key. """ self._objs.sort(cmp=lambda i1, i2: cmp(i1.key, i2.key)) self.update()
[docs] def zero_dofs(self): """ Set all boundary condition values to zero, if applicable. """ for cond in self: if isinstance(cond, EssentialBC): cond.zero_dofs()
def _canonize(dofs, all_dofs): """ Helper function. """ vname, dd = dofs.split('.') if dd == 'all': cdofs = all_dofs elif dd[0] == '[': cdofs = [vname + '.' + ii.strip() for ii in dd[1:-1].split(',')] else: cdofs = [dofs] return cdofs
[docs]class Condition(Struct): """ Common boundary condition methods. """ def __init__(self, name, **kwargs): Struct.__init__(self, name=name, **kwargs) self.is_single = False
[docs] def iter_single(self): """ Create a single condition instance for each item in self.dofs and yield it. """ for dofs, val in self.dofs.iteritems(): single_cond = self.copy(name=self.name) single_cond.is_single = True single_cond.dofs = [dofs, val] yield single_cond
[docs] def canonize_dof_names(self, dofs): """ Canonize the DOF names using the full list of DOFs of a variable. Assumes single condition instance. """ self.dofs[0] = _canonize(self.dofs[0], dofs)
[docs]class EssentialBC(Condition): """ Essential boundary condidion. Parameters ---------- name : str The boundary condition name. region : Region instance The region where the boundary condition is applied. dofs : dict The boundary condition specification defining the constrained DOFs and their values. key : str, optional The sorting key. times : list or str, optional The list of time intervals or a function returning True at time steps, when the condition applies. """ def __init__(self, name, region, dofs, key='', times=None): Condition.__init__(self, name=name, region=region, dofs=dofs, key=key, times=times)
[docs] def zero_dofs(self): """ Set all essential boundary condition values to zero. """ if self.is_single: self.dofs[1] = 0.0 else: new_dofs = {} for key in self.dofs.iterkeys(): new_dofs[key] = 0.0 self.dofs = new_dofs
[docs]class PeriodicBC(Condition): """ Periodic boundary condidion. Parameters ---------- name : str The boundary condition name. regions : list of two Region instances The master region and the slave region where the DOFs should match. dofs : dict The boundary condition specification defining the DOFs in the master region and the corresponding DOFs in the slave region. match : str The name of function for matching corresponding nodes in the two regions. key : str, optional The sorting key. times : list or str, optional The list of time intervals or a function returning True at time steps, when the condition applies. """ def __init__(self, name, regions, dofs, match, key='', times=None): Condition.__init__(self, name=name, regions=regions, dofs=dofs, match=match, key=key, times=times)
[docs] def canonize_dof_names(self, dofs): """ Canonize the DOF names using the full list of DOFs of a variable. Assumes single condition instance. """ self.dofs[0] = _canonize(self.dofs[0], dofs) self.dofs[1] = _canonize(self.dofs[1], dofs)
[docs]class LinearCombinationBC(Condition): """ Linear combination boundary condidion. Parameters ---------- name : str The boundary condition name. regions : list of two Region instances The constrained (master) DOFs region and the new (slave) DOFs region. The latter can be None if new DOFs are not field variable DOFs. dofs : dict The boundary condition specification defining the constrained DOFs and the new DOFs (can be None). dof_map_fun : str The name of function for mapping the constrained DOFs to new DOFs (can be None). kind : str The linear combination condition kind. key : str, optional The sorting key. times : list or str, optional The list of time intervals or a function returning True at time steps, when the condition applies. arguments: tuple, optional Additional arguments, depending on the condition kind. """ def __init__(self, name, regions, dofs, dof_map_fun, kind, key='', times=None, arguments=None): Condition.__init__(self, name=name, regions=regions, dofs=dofs, dof_map_fun=dof_map_fun, kind=kind, key=key, times=times, arguments=arguments)
[docs] def get_var_names(self): """ Get names of variables corresponding to the constrained and new DOFs. """ names = [self.dofs[0].split('.')[0]] if self.dofs[1] is not None: names.append(self.dofs[1].split('.')[0]) return names
[docs] def canonize_dof_names(self, dofs0, dofs1=None): """ Canonize the DOF names using the full list of DOFs of a variable. Assumes single condition instance. """ self.dofs[0] = _canonize(self.dofs[0], dofs0) if self.dofs[1] is not None: self.dofs[1] = _canonize(self.dofs[1], dofs1)
[docs]class InitialCondition(Condition): """ Initial condidion. Parameters ---------- name : str The initial condition name. region : Region instance The region where the initial condition is applied. dofs : dict The initial condition specification defining the constrained DOFs and their values. key : str, optional The sorting key. """ def __init__(self, name, region, dofs, key=''): Condition.__init__(self, name=name, region=region, dofs=dofs, key=key)