def _get_periodicBC_X(self, domain, dim): dim_dict = {1: ('y', per.match_y_plane), 2: ('z', per.match_z_plane)} dim_string = dim_dict[dim][0] match_plane = dim_dict[dim][1] min_, max_ = domain.get_mesh_bounding_box()[:, dim] min_x, max_x = domain.get_mesh_bounding_box()[:, 0] plus_ = self._subdomain_func(max_x=max_x, **{dim_string: (max_,)}) minus_ = self._subdomain_func(max_x=max_x, **{dim_string: (min_,)}) plus_string = dim_string + 'plus' minus_string = dim_string + 'minus' plus = Function(plus_string, plus_) minus = Function(minus_string, minus_) region_plus = domain.create_region( 'region_{0}_plus'.format(dim_string), 'vertices by {0}'.format( plus_string), 'facet', functions=Functions([plus])) region_minus = domain.create_region( 'region_{0}_minus'.format(dim_string), 'vertices by {0}'.format( minus_string), 'facet', functions=Functions([minus])) match_plane = Function( 'match_{0}_plane'.format(dim_string), match_plane) bc_dict = {'u.0': 'u.0'} bc = PeriodicBC('periodic_{0}'.format(dim_string), [region_plus, region_minus], bc_dict, match='match_{0}_plane'.format(dim_string)) return bc, match_plane
def _get_shift_displacementsBCs(self, domain): """ Fix the right top and bottom points in x, y and z Args: domain: an Sfepy domain Returns: the Sfepy boundary conditions """ min_xyz = domain.get_mesh_bounding_box()[0] max_xyz = domain.get_mesh_bounding_box()[1] kwargs = {} if len(min_xyz) == 3: kwargs = {'z': (max_xyz[2], min_xyz[2])} displacement = self.macro_strain * (max_xyz[0] - min_xyz[0]) shift_points_dict = {'u.0': displacement} shift_x_points_ = self._subdomain_func(x=(max_xyz[0],), y=(max_xyz[1], min_xyz[1]), **kwargs) shift_x_points = Function('shift_x_points', shift_x_points_) region_shift_points = domain.create_region( 'region_shift_points', 'vertices by shift_x_points', 'vertex', functions=Functions([shift_x_points])) return EssentialBC('shift_points_BC', region_shift_points, shift_points_dict)
def _get_fixed_displacementsBCs(self, domain): """ Fix the left top and bottom points in x, y and z Args: domain: an Sfepy domain Returns: the Sfepy boundary conditions """ min_xyz = domain.get_mesh_bounding_box()[0] max_xyz = domain.get_mesh_bounding_box()[1] kwargs = {} fix_points_dict = {'u.0': 0.0, 'u.1': 0.0} if len(min_xyz) == 3: kwargs = {'z': (max_xyz[2], min_xyz[2])} fix_points_dict['u.2'] = 0.0 fix_x_points_ = self._subdomain_func(x=(min_xyz[0],), y=(max_xyz[1], min_xyz[1]), **kwargs) fix_x_points = Function('fix_x_points', fix_x_points_) region_fix_points = domain.create_region( 'region_fix_points', 'vertices by fix_x_points', 'vertex', functions=Functions([fix_x_points])) return EssentialBC('fix_points_BC', region_fix_points, fix_points_dict)
def _get_periodicBCs(self, domain): dims = domain.get_mesh_bounding_box().shape[1] bc_list_YZ, func_list_YZ = list( zip(*[self._get_periodicBC_YZ(domain, i) for i in range(0, dims)])) bc_list_X, func_list_X = list( zip(*[self._get_periodicBC_X(domain, i) for i in range(1, dims)])) return Conditions( bc_list_YZ + bc_list_X), Functions(func_list_YZ + func_list_X)
def _get_linear_combinationBCs(self, domain): """ The right nodes are periodic with the left nodes but also displaced. Args: domain: an Sfepy domain Returns: the Sfepy boundary conditions """ min_xyz = domain.get_mesh_bounding_box()[0] max_xyz = domain.get_mesh_bounding_box()[1] xplus_ = self._subdomain_func(x=(max_xyz[0], )) xminus_ = self._subdomain_func(x=(min_xyz[0], )) xplus = Function('xplus', xplus_) xminus = Function('xminus', xminus_) region_x_plus = domain.create_region('region_x_plus', 'vertices by xplus', 'facet', functions=Functions([xplus])) region_x_minus = domain.create_region('region_x_minus', 'vertices by xminus', 'facet', functions=Functions([xminus])) match_x_plane = Function('match_x_plane', per.match_x_plane) def shift_(ts, coors, region): return np.ones_like( coors[:, 0]) * self.macro_strain * (max_xyz[0] - min_xyz[0]) shift = Function('shift', shift_) lcbc = LinearCombinationBC('lcbc', [region_x_plus, region_x_minus], {'u.0': 'u.0'}, match_x_plane, 'shifted_periodic', arguments=(shift, )) return Conditions([lcbc])
def from_conf(conf, options): from sfepy import data_dir from sfepy.discrete.fem import Mesh, FEDomain from sfepy.discrete import Functions mesh = Mesh("test mesh", data_dir + "/meshes/various_formats/abaqus_tet.inp") mesh.nodal_bcs["set0"] = [0, 7] domain = FEDomain("test domain", mesh) conf_functions = {"get_vertices": (get_vertices,), "get_cells": (get_cells,)} functions = Functions.from_conf(transform_functions(conf_functions)) test = Test(conf=conf, options=options, domain=domain, functions=functions) return test
def func(min_xyz, max_xyz): return pipe( dict(z_points=(max_xyz[2], min_xyz[2])) if len(min_xyz) == 3 else dict(), lambda x: subdomain_func( x_points=x_points_f(min_xyz, max_xyz), y_points=(max_xyz[1], min_xyz[1]), **x, ), lambda x: Function(f"{name}_x_points", x), lambda x: domain.create_region( f"region_{name}_points", f"vertices by {name}_x_points", "vertex", functions=Functions([x]), ), lambda x: EssentialBC( f"{name}_points_BC", x, points_dict_f(min_xyz, max_xyz) ), )
def from_conf( conf, options ): from sfepy import data_dir from sfepy.discrete.fem import Mesh, FEDomain from sfepy.discrete import Functions mesh = Mesh.from_file(data_dir + '/meshes/various_formats/abaqus_tet.inp') mesh.nodal_bcs['set0'] = [0, 7] domain = FEDomain('test domain', mesh) conf_functions = { 'get_vertices' : (get_vertices,), 'get_cells' : (get_cells,), } functions = Functions.from_conf(transform_functions(conf_functions)) test = Test(conf=conf, options=options, domain=domain, functions=functions) return test
def get_periodic_bcs(domain): """Get the periodic boundary conditions Args: domain: the Sfepy domain Returns: the boundary conditions and sfepy functions """ zipped = lambda x, f: pipe( range(x, domain.get_mesh_bounding_box().shape[1]), map_(f(domain)), lambda x: zip(*x), list, ) return pipe( (zipped(0, get_periodic_bc_yz), zipped(1, get_periodic_bc_x)), lambda x: (Conditions(x[0][0] + x[1][0]), Functions(x[0][1] + x[1][1])), )
def get_region_func(max_x, dim_string, domain, name_minmax): """Generate the Sfepy region Args: max_x: max value in the x direction dim_string: either "x", "y", or "z" domain: the Sfepy domain name_minmax: tuple of name and min / max Returns: the Sfepy region """ return pipe( subdomain_func(max_x=max_x, **{dim_string + "_points": (name_minmax[1],)}), lambda x: Function(dim_string + name_minmax[0], x), lambda x: domain.create_region( "region_{0}_{1}".format(dim_string, name_minmax[0]), "vertices by {0}".format(x.name), "facet", functions=Functions([x]), ), )
def get_bc(domain, delta_x, index, cond): """Make a displacement boundary condition Args: domain: the Sfepy domain delta_x: the mesh spacing index: the index (either 0 or 1) depends on direction of axes cond: the BC dictionary Returns: the Sfepy boundary condition """ return pipe( Function("fix_points", subdomain(index, domain, delta_x * 1e-3)), lambda x: domain.create_region( "region_fix_points", "vertices by fix_points", "vertex", functions=Functions([x]), ), lambda x: EssentialBC("fix_points_BC", x, cond), )
def test_epbcs(self): from sfepy.discrete import Function, Functions from sfepy.discrete.conditions import Conditions, PeriodicBC from sfepy.discrete.common.dof_info import expand_nodes_to_equations from sfepy.discrete.fem.periodic import match_y_line variables = self.variables regions = self.problem.domain.regions match_y_line = Function('match_y_line', match_y_line) pbc = PeriodicBC('pbc', [regions['LeftStrip'], regions['RightStrip']], {'u.[1,0]': 'u.[0,1]'}, match='match_y_line') functions = Functions([match_y_line]) epbcs = Conditions([pbc]) variables.equation_mapping(ebcs=None, epbcs=epbcs, ts=None, functions=functions) vec = init_vec(variables) variables.apply_ebc(vec) var = variables['u'] var_bcs = epbcs.group_by_variables()['u'] bc = var_bcs['pbc'] bc.canonize_dof_names(var.dofs) nods0 = var.field.get_dofs_in_region(bc.regions[0]) nods1 = var.field.get_dofs_in_region(bc.regions[1]) coors0 = var.field.get_coor(nods0) coors1 = var.field.get_coor(nods1) i0, i1 = match_y_line(coors0, coors1) eq0 = expand_nodes_to_equations(nods0[i0], bc.dofs[0], var.dofs) eq1 = expand_nodes_to_equations(nods1[i1], bc.dofs[1], var.dofs) ok = True _ok = len(nm.setdiff1d(eq0, var.eq_map.master)) == 0 if not _ok: self.report('master equations mismatch! (set(%s) == set(%s))' % (eq0, var.eq_map.master)) ok = ok and _ok _ok = len(nm.setdiff1d(eq1, var.eq_map.slave)) == 0 if not _ok: self.report('slave equations mismatch! (set(%s) == set(%s))' % (eq1, var.eq_map.slave)) ok = ok and _ok off = variables.di.indx['u'].start _ok = nm.allclose(vec[off + eq0], vec[off + eq1], atol=1e-14, rtol=0.0) if not _ok: self.report('periodicity test failed! (%s == %s)' % (vec[off + eq0], vec[off + eq0])) ok = ok and _ok return ok
def find_level_interface(domain, refine_flag): """ Find facets of the coarse mesh that are on the coarse-refined cell boundary. ids w.r.t. current mesh: - facets: global, local w.r.t. cells[:, 0], local w.r.t. cells[:, 1] - interface cells: - cells[:, 0] - cells to refine - cells[:, 1] - their facet sharing neighbors (w.r.t. both meshes) - cells[:, 2] - facet kind: 0 = face, 1 = edge """ if not refine_flag.any(): facets = nm.zeros((0, 3), dtype=nm.uint32) cells = nm.zeros((0, 3), dtype=nm.uint32) return facets, cells, 0, None, None def _get_refine(coors, domain=None): return nm.nonzero(refine_flag)[0] def _get_coarse(coors, domain=None): return nm.nonzero(1 - refine_flag)[0] get_refine = Function('get_refine', _get_refine) get_coarse = Function('get_coarse', _get_coarse) functions = Functions([get_refine, get_coarse]) region0 = domain.create_region('coarse', 'cells by get_coarse', functions=functions, add_to_regions=False, allow_empty=True) region1 = domain.create_region('refine', 'cells by get_refine', functions=functions, add_to_regions=False) cmesh = domain.mesh.cmesh dim = cmesh.dim if dim == 2: oe = 0 facets = nm.intersect1d(region0.facets, region1.facets) cmesh.setup_connectivity(dim - 1, dim) cells, offs = cmesh.get_incident(dim, facets, dim - 1, ret_offsets=True) assert_((nm.diff(offs) == 2).all()) ii = cmesh.get_local_ids(facets, dim - 1, cells, offs, dim) ii = ii.reshape((-1, 2)) cells = cells.reshape((-1, 2)) ii = nm.where(refine_flag[cells], ii[:, :1], ii[:, 1:]) cells = nm.where(refine_flag[cells], cells[:, :1], cells[:, 1:]) facets = nm.c_[facets, ii] cells = nm.c_[cells, nm.zeros_like(cells[:, 1])] else: # if dim == 3: gel = domain.geom_els['3_8'] epf = gel.get_edges_per_face() cmesh.setup_connectivity(dim, dim) fc, coffs = cmesh.get_incident(dim, region1.cells, dim, ret_offsets=True) cc = nm.repeat(region1.cells, nm.diff(coffs)) aux = nm.c_[cc, fc] """ nnn[:, 0] cells to refine, nnn[:, 1] non-refined neighbours, nnn[:, 2] neighbour kind : 0 face, 1 edge. """ nn = aux[refine_flag[fc] == 0] cf = nn[:, 0].copy().astype(nm.uint32) cc = nn[:, 1].copy().astype(nm.uint32) vc, vco = cmesh.get_incident(0, cc, dim, ret_offsets=True) vf, vfo = cmesh.get_incident(0, cf, dim, ret_offsets=True) vc = vc.reshape((-1, 8)) vf = vf.reshape((-1, 8)) nnn = [] oe = 0 ov = nn.shape[0] for ii in range(vc.shape[0]): aux = set(vc[ii]).intersection(vf[ii]) nc = len(aux) if nc == 1: nnn.append((0, 0, 2)) ov -= 1 elif nc == 4: nnn.append((nn[ii, 0], nn[ii, 1], 0)) oe += 1 else: nnn.append((nn[ii, 0], nn[ii, 1], 1)) nnn = nm.array(nnn) if nnn.shape[0] == 0: facets = nm.zeros((0, 3), dtype=nm.uint32) cells = nm.zeros((0, 4), dtype=nm.uint32) return facets, cells, 0, region0, region1 # Sort by neighbour kind, skip vertex-only neighbours. ii = nm.argsort(nnn[:, 2]) nnn = nnn[ii][:ov] cf = cf[ii][:ov] cc = cc[ii][:ov] ec, eco = cmesh.get_incident(1, cc, dim, ret_offsets=True) ef, efo = cmesh.get_incident(1, cf, dim, ret_offsets=True) ec = ec.reshape((-1, 12)) ef = ef.reshape((-1, 12)) fc, fco = cmesh.get_incident(2, cc, dim, ret_offsets=True) ff, ffo = cmesh.get_incident(2, cf, dim, ret_offsets=True) fc = fc.reshape((-1, 6)) ff = ff.reshape((-1, 6)) emask = nm.zeros((domain.shape.n_el, 12), dtype=nm.bool) ffs = [] for ii in range(oe): facet = nm.intersect1d(fc[ii], ff[ii])[0] i1 = nm.where(ff[ii] == facet)[0][0] i0 = nm.where(fc[ii] == facet)[0][0] ffs.append((facet, i1, i0)) emask[nnn[ii, 0], epf[i1]] = True for ii in range(oe, nnn.shape[0]): facet = nm.intersect1d(ec[ii], ef[ii])[0] i1 = nm.where(ef[ii] == facet)[0][0] i0 = nm.where(ec[ii] == facet)[0][0] ffs.append((facet, i1, i0)) ffs = nm.array(ffs) ie = nm.where(nnn[:, 2] == 1)[0] ennn = nnn[ie] effs = ffs[ie] omit = ie[emask[ennn[:, 0], effs[:, 1]]] valid = nm.ones(nnn.shape[0], dtype=nm.bool) valid[omit] = False cells = nnn[valid] facets = ffs[valid] return facets, cells, oe, region0, region1