Ejemplo n.º 1
0
def get_green_strain_sym3d(mtx_c, c33):
    r"""
    Get the 3D Green strain tensor in symmetric storage.

    Parameters
    ----------
    mtx_c ; array
        The in-plane right Cauchy-Green deformation tensor
        :math:`C_{ij}`, :math:`i, j = 1, 2`, shape `(n_el, n_qp, dim-1,
        dim-1)`.
    c33 : array
        The component :math:`C_{33}` computed from the incompressibility
        condition, shape `(n_el, n_qp)`.

    Returns
    -------
    mtx_e : array
        The membrane Green strain :math:`E_{ij} = \frac{1}{2} (C_{ij}) -
        \delta_{ij}`, symmetric storage: items (11, 22, 33, 12, 13, 23),
        shape `(n_el, n_qp, sym, 1)`.
    """
    n_el, n_qp, dm, _ = mtx_c.shape
    dim = dm + 1
    sym = dim2sym(dim)

    mtx_e = nm.empty((n_el, n_qp, sym, 1), dtype=mtx_c.dtype)

    mtx_e[..., 0, 0] = 0.5 * (mtx_c[..., 0, 0] - 1.0)
    mtx_e[..., 1, 0] = 0.5 * (mtx_c[..., 1, 1] - 1.0)
    mtx_e[..., 2, 0] = 0.5 * (c33 - 1.0)
    mtx_e[..., 3, 0] = 0.5 * mtx_c[..., 0, 1]
    mtx_e[..., 4:, 0] = 0.0

    return mtx_e
Ejemplo n.º 2
0
def get_green_strain_sym3d(mtx_c, c33):
    r"""
    Get the 3D Green strain tensor in symmetric storage.

    Parameters
    ----------
    mtx_c ; array
        The in-plane right Cauchy-Green deformation tensor
        :math:`C_{ij}`, :math:`i, j = 1, 2`, shape `(n_el, n_qp, dim-1,
        dim-1)`.
    c33 : array
        The component :math:`C_{33}` computed from the incompressibility
        condition, shape `(n_el, n_qp)`.

    Returns
    -------
    mtx_e : array
        The membrane Green strain :math:`E_{ij} = \frac{1}{2} (C_{ij}) -
        \delta_{ij}`, symmetric storage: items (11, 22, 33, 12, 13, 23),
        shape `(n_el, n_qp, sym, 1)`.
    """
    n_el, n_qp, dm, _ = mtx_c.shape
    dim = dm + 1
    sym = dim2sym(dim)

    mtx_e = nm.empty((n_el, n_qp, sym, 1), dtype=mtx_c.dtype)

    mtx_e[..., 0, 0] = 0.5 * (mtx_c[..., 0, 0] - 1.0)
    mtx_e[..., 1, 0] = 0.5 * (mtx_c[..., 1, 1] - 1.0)
    mtx_e[..., 2, 0] = 0.5 * (c33 - 1.0)
    mtx_e[..., 3, 0] = 0.5 * mtx_c[..., 0, 1]
    mtx_e[..., 4:, 0] = 0.0

    return mtx_e
Ejemplo n.º 3
0
def create_omega(fdir):
    r"""
    Create the fibre direction tensor :math:`\omega_{ij} = d_i d_j`.
    """
    n_el, n_qp, dim, _ = fdir.shape
    sym = dim2sym(dim)
    omega = nm.empty((n_el, n_qp, sym, 1), dtype=nm.float64)
    for ii, (ir, ic) in enumerate(iter_sym(dim)):
        omega[..., ii, 0] = fdir[..., ir, 0] * fdir[..., ic, 0]

    return omega
Ejemplo n.º 4
0
    def get_eval_shape(self, mat, virtual, state,
                       mode=None, term_mode=None, diff_var=None, **kwargs):
        from sfepy.mechanics.tensors import dim2sym

        n_el, n_qp, dim, n_en, n_c = self.get_data_shape(state)
        sym = dim2sym(dim)

        if mode != 'qp':
            n_qp = 1

        return (n_el, n_qp, sym, 1), state.dtype
Ejemplo n.º 5
0
def create_omega(fdir):
    r"""
    Create the fibre direction tensor :math:`\omega_{ij} = d_i d_j`.
    """
    n_el, n_qp, dim, _ = fdir.shape
    sym = dim2sym(dim)
    omega = nm.empty((n_el, n_qp, sym, 1), dtype=nm.float64)
    for ii, (ir, ic) in enumerate(iter_sym(dim)):
        omega[..., ii, 0] = fdir[..., ir, 0] * fdir[..., ic, 0]

    return omega
Ejemplo n.º 6
0
    def get_eval_shape(self,
                       a1,
                       a2,
                       h0,
                       virtual,
                       state,
                       mode=None,
                       term_mode=None,
                       diff_var=None,
                       **kwargs):
        n_el, n_qp, dim, n_en, n_c = self.get_data_shape(state)
        sym = dim2sym(dim)

        return (n_el, 1, sym, 1), state.dtype
Ejemplo n.º 7
0
    def init_data_struct(self, state_shape, name='family_data'):
        from sfepy.mechanics.tensors import dim2sym

        n_el, n_qp, dim, n_en, n_c = state_shape
        sym = dim2sym(dim); sym

        shdict = dict(( (k, v) for k, v in six.iteritems(locals())\
            if k in ['n_el', 'n_qp', 'dim', 'n_en', 'n_c', 'sym']))

        data = Struct(name=name)
        setattr(data, 'names', self.data_names)
        for key in self.data_names:
            shape = [shdict[sh] if type(sh) is str else sh\
                 for sh in self.data_shapes[key]]
            setattr(data, key, nm.zeros(shape, dtype=nm.float64))

        return data
Ejemplo n.º 8
0
    def eval_function(out, a1, a2, h0, mtx_c, c33, mtx_b, mtx_t, geo,
                      term_mode, fmode):

        if term_mode == 'strain':
            out_qp = membranes.get_green_strain_sym3d(mtx_c, c33)

        elif term_mode == 'stress':
            n_el, n_qp, dm, _ = mtx_c.shape
            dim = dm + 1
            sym = dim2sym(dim)
            out_qp = nm.zeros((n_el, n_qp, sym, 1), dtype=mtx_c.dtype)

            stress = eval_membrane_mooney_rivlin(a1, a2, mtx_c, c33, 0)
            out_qp[..., 0:2, 0] = stress[..., 0:2, 0]
            out_qp[..., 3, 0] = stress[..., 2, 0]

        status = geo.integrate(out, out_qp, fmode)
        out[:, 0, :, 0] = transform_data(out.squeeze(), mtx=mtx_t)

        return status
Ejemplo n.º 9
0
    def eval_function(out, a1, a2, h0, mtx_c, c33, mtx_b, mtx_t, geo,
                      term_mode, fmode):

        if term_mode == 'strain':
            out_qp = membranes.get_green_strain_sym3d(mtx_c, c33)

        elif term_mode == 'stress':
            n_el, n_qp, dm, _ = mtx_c.shape
            dim = dm + 1
            sym = dim2sym(dim)
            out_qp = nm.zeros((n_el, n_qp, sym, 1), dtype=mtx_c.dtype)

            stress = eval_membrane_mooney_rivlin(a1, a2, mtx_c, c33, 0)
            out_qp[..., 0:2, 0] = stress[..., 0:2, 0]
            out_qp[..., 3, 0] = stress[..., 2, 0]

        status = geo.integrate(out, out_qp, fmode)
        out[:, 0, :, 0] = transform_data(out.squeeze(), mtx=mtx_t)

        return status
Ejemplo n.º 10
0
def make_term_args(arg_shapes, arg_kinds, arg_types, ats_mode, domain,
                   material_value=None, poly_space_base=None):
    from sfepy.base.base import basestr
    from sfepy.discrete import FieldVariable, Material, Variables, Materials
    from sfepy.discrete.fem import Field
    from sfepy.solvers.ts import TimeStepper
    from sfepy.mechanics.tensors import dim2sym

    omega = domain.regions['Omega']
    dim = domain.shape.dim
    sym = dim2sym(dim)

    def _parse_scalar_shape(sh):
        if isinstance(sh, basestr):
            if sh == 'D':
                return dim

            elif sh == 'D2':
                return dim**2

            elif sh == 'S':
                return sym

            elif sh == 'N': # General number ;)
                return 1

            else:
                return int(sh)

        else:
            return sh

    def _parse_tuple_shape(sh):
        if isinstance(sh, basestr):
            return [_parse_scalar_shape(ii.strip()) for ii in sh.split(',')]

        else:
            return (int(sh),)

    args = {}
    str_args = []
    materials = []
    variables = []
    for ii, arg_kind in enumerate(arg_kinds):
        if arg_kind != 'ts':
            if ats_mode is not None:
                extended_ats = arg_types[ii] + ('/%s' % ats_mode)

            else:
                extended_ats = arg_types[ii]

            try:
                sh = arg_shapes[arg_types[ii]]

            except KeyError:
                sh = arg_shapes[extended_ats]

        if arg_kind.endswith('variable'):
            shape = _parse_scalar_shape(sh[0] if isinstance(sh, tuple) else sh)
            field = Field.from_args('f%d' % ii, nm.float64, shape, omega,
                                    approx_order=1,
                                    poly_space_base=poly_space_base)

            if arg_kind == 'virtual_variable':
                if sh[1] is not None:
                    istate = arg_types.index(sh[1])

                else:
                    # Only virtual variable in arguments.
                    istate = -1
                    # -> Make fake variable.
                    var = FieldVariable('u-1', 'unknown', field)
                    var.set_constant(0.0)
                    variables.append(var)

                var = FieldVariable('v', 'test', field,
                                    primary_var_name='u%d' % istate)

            elif arg_kind == 'state_variable':
                var = FieldVariable('u%d' % ii, 'unknown', field)
                var.set_constant(0.0)

            elif arg_kind == 'parameter_variable':
                var = FieldVariable('p%d' % ii, 'parameter', field,
                                    primary_var_name='(set-to-None)')
                var.set_constant(0.0)

            variables.append(var)
            str_args.append(var.name)
            args[var.name] = var

        elif arg_kind.endswith('material'):
            if sh is None: # Switched-off opt_material.
                continue

            prefix = ''
            if isinstance(sh, basestr):
                aux = sh.split(':')
                if len(aux) == 2:
                    prefix, sh = aux

            if material_value is None:
                material_value = 1.0

            shape = _parse_tuple_shape(sh)
            if (len(shape) > 1) or (shape[0] > 1):
                if ((len(shape) == 2) and (shape[0] ==  shape[1])
                    and (material_value != 0.0)):
                    # Identity matrix.
                    val = nm.eye(shape[0], dtype=nm.float64)

                else:
                    # Array.
                    val = nm.empty(shape, dtype=nm.float64)
                    val.fill(material_value)

                values = {'%sc%d' % (prefix, ii)
                          : val}

            elif (len(shape) == 1) and (shape[0] == 1):
                # Single scalar as a special value.
                values = {'.c%d' % ii : material_value}

            else:
                raise ValueError('wrong material shape! (%s)' % shape)

            mat = Material('m%d' % ii, values=values)

            materials.append(mat)
            str_args.append(mat.name + '.' + 'c%d' % ii)
            args[mat.name] = mat

        elif arg_kind == 'ts':
            ts = TimeStepper(0.0, 1.0, 1.0, 5)
            str_args.append('ts')
            args['ts'] = ts

        else:
            str_args.append('user%d' % ii)
            args[str_args[-1]] = None

    materials = Materials(materials)
    variables = Variables(variables)

    return args, str_args, materials, variables
Ejemplo n.º 11
0
    def check_shapes(self, *args, **kwargs):
        """
        Check term argument shapes at run-time.
        """
        from sfepy.base.base import output
        from sfepy.mechanics.tensors import dim2sym

        dim = self.region.dim
        sym = dim2sym(dim)

        def _parse_scalar_shape(sh):
            if isinstance(sh, basestr):
                if sh == 'D':
                    return dim

                elif sh == 'D2':
                    return dim**2

                elif sh == 'S':
                    return sym

                elif sh == 'N':  # General number.
                    return nm.inf

                elif sh == 'str':
                    return 'str'

                else:
                    return int(sh)

            else:
                return sh

        def _parse_tuple_shape(sh):
            if isinstance(sh, basestr):
                return tuple(
                    (_parse_scalar_shape(ii.strip()) for ii in sh.split(',')))

            else:
                return (int(sh), )

        arg_kinds = get_arg_kinds(self.ats)

        arg_shapes_list = self.arg_shapes
        if not isinstance(arg_shapes_list, list):
            arg_shapes_list = [arg_shapes_list]

        # Loop allowed shapes until a match is found, else error.
        allowed_shapes = []
        prev_shapes = {}
        actual_shapes = {}
        for _arg_shapes in arg_shapes_list:
            # Unset shapes are taken from the previous iteration.
            arg_shapes = copy(prev_shapes)
            arg_shapes.update(_arg_shapes)
            prev_shapes = arg_shapes

            allowed_shapes.append(arg_shapes)

            n_ok = 0
            for ii, arg_kind in enumerate(arg_kinds):
                if arg_kind in ('user', 'ts'):
                    n_ok += 1
                    continue

                arg = args[ii]
                key = '%s:%s' % (self.ats[ii], self.arg_names[ii])

                if self.mode is not None:
                    extended_ats = self.ats[ii] + ('/%s' % self.mode)

                else:
                    extended_ats = self.ats[ii]

                try:
                    sh = arg_shapes[self.ats[ii]]

                except KeyError:
                    sh = arg_shapes[extended_ats]

                if arg_kind.endswith('variable'):
                    n_el, n_qp, _dim, n_en, n_c = self.get_data_shape(arg)
                    actual_shapes[key] = (n_c, )
                    shape = _parse_scalar_shape(
                        sh[0] if isinstance(sh, tuple) else sh)
                    if nm.isinf(shape):
                        n_ok += 1

                    else:
                        n_ok += shape == n_c

                elif arg_kind.endswith('material'):
                    if arg is None:  # Switched-off opt_material.
                        n_ok += sh is None
                        continue

                    if sh is None:
                        continue

                    prefix = ''
                    if isinstance(sh, basestr):
                        aux = tuple(ii.strip() for ii in sh.split(':'))
                        if len(aux) == 2:
                            prefix, sh = aux

                    if sh == 'str':
                        n_ok += isinstance(arg, basestr)
                        continue

                    shape = _parse_tuple_shape(sh)
                    ls = len(shape)

                    aarg = nm.array(arg, ndmin=1)
                    actual_shapes[key] = aarg.shape

                    # Substiture general dimension 'N' with actual value.
                    iinfs = nm.where(nm.isinf(shape))[0]
                    if len(iinfs):
                        shape = list(shape)
                        for iinf in iinfs:
                            shape[iinf] = aarg.shape[-ls + iinf]
                        shape = tuple(shape)

                    if (ls > 1) or (shape[0] > 1):
                        # Array.
                        n_ok += shape == aarg.shape[-ls:]
                        actual_shapes[key] = aarg.shape[-ls:]

                    elif (ls == 1) and (shape[0] == 1):
                        # Scalar constant or callable as term argument
                        from numbers import Number
                        n_ok += isinstance(arg, Number) or callable(arg)

                else:
                    n_ok += 1

            if n_ok == len(arg_kinds):
                break

        else:
            term_str = self.get_str()
            output('allowed argument shapes for term "%s":' % term_str)
            output(allowed_shapes)
            output('actual argument shapes:')
            output(actual_shapes)
            raise ValueError(
                'wrong arguments shapes for "%s" term! (see above)' % term_str)
Ejemplo n.º 12
0
def describe_deformation(el_disps, bfg):
    """
    Describe deformation of a thin incompressible 2D membrane in 3D
    space, composed of flat finite element faces.

    The coordinate system of each element (face), i.e. the membrane
    mid-surface, should coincide with the `x`, `y` axes of the `x-y`
    plane.

    Parameters
    ----------
    el_disps : array
        The displacements of element nodes, shape `(n_el, n_ep, dim)`.
    bfg : array
        The in-plane base function gradients, shape `(n_el, n_qp, dim-1,
        n_ep)`.

    Returns
    -------
    mtx_c ; array
        The in-plane right Cauchy-Green deformation tensor
        :math:`C_{ij}`, :math:`i, j = 1, 2`.
    c33 : array
        The component :math:`C_{33}` computed from the incompressibility
        condition.
    mtx_b : array
        The discrete Green strain variation operator.
    """
    sh = bfg.shape
    n_ep = sh[3]

    dim = el_disps.shape[2]
    sym2 = dim2sym(dim-1)

    # Repeat el_disps by number of quadrature points.
    el_disps_qp = insert_strided_axis(el_disps, 1, bfg.shape[1])

    # Transformed (in-plane) displacement gradient with
    # shape (n_el, n_qp, 2 (-> a), 3 (-> i)), du_i/dX_a.
    du = dot_sequences(bfg, el_disps_qp)

    # Deformation gradient F w.r.t. in plane coordinates.
    # F_{ia} = dx_i / dX_a,
    # a \in {1, 2} (rows), i \in {1, 2, 3} (columns).
    mtx_f = du + nm.eye(dim - 1, dim, dtype=du.dtype)

    # Right Cauchy-Green deformation tensor C.
    # C_{ab} = F_{ka} F_{kb}, a, b \in {1, 2}.
    mtx_c = dot_sequences(mtx_f, mtx_f, 'ABT')

    # C_33 from incompressibility.
    c33 = 1.0 / (mtx_c[..., 0, 0] * mtx_c[..., 1, 1]
                 - mtx_c[..., 0, 1]**2)

    # Discrete Green strain variation operator.
    mtx_b = nm.empty((sh[0], sh[1], sym2, dim * n_ep), dtype=nm.float64)
    mtx_b[..., 0, 0*n_ep:1*n_ep] = bfg[..., 0, :] * mtx_f[..., 0, 0:1]
    mtx_b[..., 0, 1*n_ep:2*n_ep] = bfg[..., 0, :] * mtx_f[..., 0, 1:2]
    mtx_b[..., 0, 2*n_ep:3*n_ep] = bfg[..., 0, :] * mtx_f[..., 0, 2:3]
    mtx_b[..., 1, 0*n_ep:1*n_ep] = bfg[..., 1, :] * mtx_f[..., 1, 0:1]
    mtx_b[..., 1, 1*n_ep:2*n_ep] = bfg[..., 1, :] * mtx_f[..., 1, 1:2]
    mtx_b[..., 1, 2*n_ep:3*n_ep] = bfg[..., 1, :] * mtx_f[..., 1, 2:3]
    mtx_b[..., 2, 0*n_ep:1*n_ep] = bfg[..., 1, :] * mtx_f[..., 0, 0:1] \
                                   + bfg[..., 0, :] * mtx_f[..., 1, 0:1]
    mtx_b[..., 2, 1*n_ep:2*n_ep] = bfg[..., 0, :] * mtx_f[..., 1, 1:2] \
                                   + bfg[..., 1, :] * mtx_f[..., 0, 1:2]
    mtx_b[..., 2, 2*n_ep:3*n_ep] = bfg[..., 0, :] * mtx_f[..., 1, 2:3] \
                                   + bfg[..., 1, :] * mtx_f[..., 0, 2:3]

    return mtx_c, c33, mtx_b
Ejemplo n.º 13
0
def define(filename_mesh=None):

    eta = 3.6e-3
    if filename_mesh is None:
        filename_mesh = osp.join(data_dir, 'meso_perf_2ch_puc.vtk')
        # filename_mesh = osp.join(data_dir, 'perf_mic_2chbx.vtk')

    mesh = Mesh.from_file(filename_mesh)

    poroela_micro_file = osp.join(data_dir, 'perf_BD2B_mic.py')
    dim = 3
    sym = (dim + 1) * dim // 2
    sym_eye = 'nm.array([1,1,0])' if dim == 2 else 'nm.array([1,1,1,0,0,0])'

    bbox = mesh.get_bounding_box()
    regions = define_box_regions(mesh.dim, bbox[0], bbox[1], eps=1e-3)

    regions.update({
        'Z':
        'all',
        'Gamma_Z': ('vertices of surface', 'facet'),
        # matrix
        'Zm':
        'cells of group 3',
        'Zm_left': ('r.Zm *v r.Left', 'vertex'),
        'Zm_right': ('r.Zm *v r.Right', 'vertex'),
        'Zm_bottom': ('r.Zm *v r.Bottom', 'vertex'),
        'Zm_top': ('r.Zm *v r.Top', 'vertex'),
        "Gamma_Zm": ('(r.Zm *v r.Zc1) +v (r.Zm *v r.Zc2)', 'facet', 'Zm'),
        'Gamma_Zm1': ('r.Zm *v r.Zc1', 'facet', 'Zm'),
        'Gamma_Zm2': ('r.Zm *v r.Zc2', 'facet', 'Zm'),
        # first canal
        'Zc1':
        'cells of group 1',
        'Zc01': ('r.Zc1 -v r.Gamma_Zc1', 'vertex'),
        'Zc1_left': ('r.Zc01 *v r.Left', 'vertex'),
        'Zc1_right': ('r.Zc01 *v r.Right', 'vertex'),
        # 'Zc1_bottom': ('r.Zc01 *v r.Bottom', 'vertex'),
        # 'Zc1_top': ('r.Zc01 *v r.Top', 'vertex'),
        'Gamma_Zc1': ('r.Zm *v r.Zc1', 'facet', 'Zc1'),
        'Center_c1': ('vertex 973', 'vertex'),  # canal center
        # 'Center_c1': ('vertex 1200', 'vertex'),  # canal center

        # second canal
        'Zc2':
        'cells of group 2',
        'Zc02': ('r.Zc2 -v r.Gamma_Zc2', 'vertex'),
        'Zc2_left': ('r.Zc02 *v r.Left', 'vertex'),
        'Zc2_right': ('r.Zc02 *v r.Right', 'vertex'),
        # 'Zc2_bottom': ('r.Zc02 *v r.Bottom', 'vertex'),
        # 'Zc2_top': ('r.Zc02 *v r.Top', 'vertex'),
        'Gamma_Zc2': ('r.Zm *v r.Zc2', 'facet', 'Zc2'),
        'Center_c2': ('vertex 487', 'vertex'),  # canal center
        # 'Center_c2': ('vertex 1254', 'vertex'),  # canal center
    })

    if dim == 3:
        regions.update({
            'Zm_far': ('r.Zm *v r.Far', 'vertex'),
            'Zm_near': ('r.Zm *v r.Near', 'vertex'),
            #         'Zc1_far': ('r.Zc01 *v r.Far', 'vertex'),
            #         'Zc1_near': ('r.Zc01 *v r.Near', 'vertex'),
            #         'Zc2_far': ('r.Zc02 *v r.Far', 'vertex'),
            #         'Zc2_near': ('r.Zc02 *v r.Near', 'vertex'),
        })

    fields = {
        'one': ('real', 'scalar', 'Z', 1),
        'displacement': ('real', 'vector', 'Zm', 1),
        'pressure_m': ('real', 'scalar', 'Zm', 1),
        'pressure_c1': ('real', 'scalar', 'Zc1', 1),
        'displacement_c1': ('real', 'vector', 'Zc1', 1),
        'velocity1': ('real', 'vector', 'Zc1', 2),
        'pressure_c2': ('real', 'scalar', 'Zc2', 1),
        'displacement_c2': ('real', 'vector', 'Zc2', 1),
        'velocity2': ('real', 'vector', 'Zc2', 2),
    }

    variables = {
        # displacement
        'u': ('unknown field', 'displacement', 0),
        'v': ('test field', 'displacement', 'u'),
        'Pi_u': ('parameter field', 'displacement', 'u'),
        'U1': ('parameter field', 'displacement', '(set-to-None)'),
        'U2': ('parameter field', 'displacement', '(set-to-None)'),
        'uc1': ('unknown field', 'displacement_c1', 6),
        'vc1': ('test field', 'displacement_c1', 'uc1'),
        'uc2': ('unknown field', 'displacement_c2', 7),
        'vc2': ('test field', 'displacement_c2', 'uc2'),
        # velocity in canal 1
        'w1': ('unknown field', 'velocity1', 1),
        'z1': ('test field', 'velocity1', 'w1'),
        'Pi_w1': ('parameter field', 'velocity1', 'w1'),
        'par1_w1': ('parameter field', 'velocity1', '(set-to-None)'),
        'par2_w1': ('parameter field', 'velocity1', '(set-to-None)'),
        # velocity in canal 2
        'w2': ('unknown field', 'velocity2', 2),
        'z2': ('test field', 'velocity2', 'w2'),
        'Pi_w2': ('parameter field', 'velocity2', 'w2'),
        'par1_w2': ('parameter field', 'velocity2', '(set-to-None)'),
        'par2_w2': ('parameter field', 'velocity2', '(set-to-None)'),
        # pressure
        'pm': ('unknown field', 'pressure_m', 3),
        'qm': ('test field', 'pressure_m', 'pm'),
        'Pm1': ('parameter field', 'pressure_m', '(set-to-None)'),
        'Pm2': ('parameter field', 'pressure_m', '(set-to-None)'),
        'Pi_pm': ('parameter field', 'pressure_m', 'pm'),
        'pc1': ('unknown field', 'pressure_c1', 4),
        'qc1': ('test field', 'pressure_c1', 'pc1'),
        'par1_pc1': ('parameter field', 'pressure_c1', '(set-to-None)'),
        'par2_pc1': ('parameter field', 'pressure_c1', '(set-to-None)'),
        'pc2': ('unknown field', 'pressure_c2', 5),
        'qc2': ('test field', 'pressure_c2', 'pc2'),
        'par1_pc2': ('parameter field', 'pressure_c2', '(set-to-None)'),
        'par2_pc2': ('parameter field', 'pressure_c2', '(set-to-None)'),
        # one
        'one': ('parameter field', 'one', '(set-to-None)'),
    }

    functions = {
        'match_x_plane': (per.match_x_plane,),
        'match_y_plane': (per.match_y_plane,),
        'match_z_plane': (per.match_z_plane,),
        'get_homog': (lambda ts, coors, mode=None, problem=None, **kwargs:\
            get_homog(coors, mode, problem, poroela_micro_file, **kwargs),),
    }
    materials = {
        'hmatrix':
        'get_homog',
        'fluid': ({
            'eta_c': eta * nm.eye(dim2sym(dim)),
        }, ),
        'mat': ({
            'k1': nm.array([[1, 0, 0]]).T,
            'k2': nm.array([[0, 1, 0]]).T,
            'k3': nm.array([[0, 0, 1]]).T,
        }, ),
    }

    ebcs = {
        'fixed_u': ('Corners', {
            'um.all': 0.0
        }),
        'fixed_pm': ('Corners', {
            'p.0': 0.0
        }),
        'fixed_w1': ('Center_c1', {
            'w1.all': 0.0
        }),
        'fixed_w2': ('Center_c2', {
            'w2.all': 0.0
        }),
    }

    epbcs, periodic = get_periodic_bc([('u', 'Zm'), ('pm', 'Zm'),
                                       ('pc1', 'Zc1'), ('w1', 'Zc1'),
                                       ('pc2', 'Zc2'), ('w2', 'Zc2')])

    all_periodic1 = periodic['per_w1'] + periodic['per_pc1']
    all_periodic2 = periodic['per_w2'] + periodic['per_pc2']

    integrals = {
        'i': 4,
    }

    options = {
        'coefs': 'coefs',
        'coefs_filename': 'coefs_meso',
        'requirements': 'requirements',
        'volume': {
            'variables': ['u', 'pc1', 'pc2'],
            'expression':
            'd_volume.i.Zm(u) + d_volume.i.Zc1(pc1)+d_volume.i.Zc2(pc2)',
        },
        'output_dir': data_dir + '/results/meso',
        'file_per_var': True,
        'save_format': 'vtk',  # Global setting.
        'dump_format': 'h5',  # Global setting.
        'absolute_mesh_path': True,
        'multiprocessing': False,
        'ls': 'ls',
        'nls': 'ns_m15',
        'output_prefix': 'Meso:',
    }

    solvers = {
        'ls': ('ls.mumps', {}),
        'ls_s1': ('ls.schur_mumps', {
            'schur_variables': ['pc1'],
            'fallback': 'ls'
        }),
        'ls_s2': ('ls.schur_mumps', {
            'schur_variables': ['pc2'],
            'fallback': 'ls'
        }),
        'ns': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-14,
            'eps_r': 1e-3,
            'problem': 'nonlinear'
        }),
        'ns_em15': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-15,
            'eps_r': 1e-3,
            'problem': 'nonlinear'
        }),
        'ns_em12': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-12,
            'eps_r': 1e-3,
            'problem': 'nonlinear'
        }),
        'ns_em9': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-9,
            'eps_r': 1e-3,
            'problem': 'nonlinear'
        }),
        'ns_em6': ('nls.newton', {
            'i_max': 1,
            'eps_a': 1e-4,
            'eps_r': 1e-3,
            'problem': 'nonlinear'
        }),
    }

    #Definition of homogenized coefficients, see (33)-(35)
    coefs = {
        'A': {
            'requires': ['pis_u', 'corrs_omega_ij'],
            'expression':
            'dw_lin_elastic.i.Zm(hmatrix.A, U1, U2)',
            'set_variables': [('U1', ('corrs_omega_ij', 'pis_u'), 'u'),
                              ('U2', ('corrs_omega_ij', 'pis_u'), 'u')],
            'class':
            cb.CoefSymSym,
        },
        'B_aux1': {
            'status': 'auxiliary',
            'requires': ['corrs_omega_ij'],
            'expression': '- dw_surface_ltr.i.Gamma_Zm(U1)',  # !!! -
            'set_variables': [('U1', 'corrs_omega_ij', 'u')],
            'class': cb.CoefSym,
        },
        'B_aux2': {
            'status':
            'auxiliary',
            'requires': ['corrs_omega_ij', 'pis_u', 'corr_one'],
            'expression':
            'dw_biot.i.Zm(hmatrix.B, U1, one)',
            'set_variables': [('U1', ('corrs_omega_ij', 'pis_u'), 'u'),
                              ('one', 'corr_one', 'one')],
            'class':
            cb.CoefSym,
        },
        'B': {
            'requires': ['c.B_aux1', 'c.B_aux2', 'c.vol_c'],
            'expression': 'c.B_aux1 + c.B_aux2 + c.vol_c* %s' % sym_eye,
            'class': cb.CoefEval,
        },
        'H11': {
            'requires': ['corrs_phi_k_1'],
            'expression':
            'dw_diffusion.i.Zm(hmatrix.K, Pm1, Pm2)',
            'set_variables': [('Pm1', 'corrs_phi_k_1', 'pm'),
                              ('Pm2', 'corrs_phi_k_1', 'pm')],
            'class':
            cb.CoefDimDim,
        },
        'H12': {
            'requires': ['corrs_phi_k_1', 'corrs_phi_k_2'],
            'expression':
            'dw_diffusion.i.Zm(hmatrix.K, Pm1, Pm2)',
            'set_variables': [('Pm1', 'corrs_phi_k_1', 'pm'),
                              ('Pm2', 'corrs_phi_k_2', 'pm')],
            'class':
            cb.CoefDimDim,
        },
        'H21': {
            'requires': ['corrs_phi_k_1', 'corrs_phi_k_2'],
            'expression':
            'dw_diffusion.i.Zm(hmatrix.K, Pm1, Pm2)',
            'set_variables': [('Pm1', 'corrs_phi_k_2', 'pm'),
                              ('Pm2', 'corrs_phi_k_1', 'pm')],
            'class':
            cb.CoefDimDim,
        },
        'H22': {
            'requires': ['corrs_phi_k_2'],
            'expression':
            'dw_diffusion.i.Zm(hmatrix.K, Pm1, Pm2)',
            'set_variables': [('Pm1', 'corrs_phi_k_2', 'pm'),
                              ('Pm2', 'corrs_phi_k_2', 'pm')],
            'class':
            cb.CoefDimDim,
        },
        'K': {
            'requires': ['corrs_pi_k', 'pis_pm'],
            'expression':
            'dw_diffusion.i.Zm(hmatrix.K, Pm1, Pm2)',
            'set_variables': [('Pm1', ('corrs_pi_k', 'pis_pm'), 'pm'),
                              ('Pm2', ('corrs_pi_k', 'pis_pm'), 'pm')],
            'class':
            cb.CoefDimDim,
        },
        'Q1': {
            'requires': ['corrs_phi_k_1', 'pis_pm'],
            'expression':
            'dw_diffusion.i.Zm(hmatrix.K, Pm1, Pm2)',
            'set_variables': [('Pm1', 'pis_pm', 'pm'),
                              ('Pm2', 'corrs_phi_k_1', 'pm')],
            'class':
            cb.CoefDimDim,
        },
        'P1': {
            'requires': ['c.Q1', 'c.vol'],
            'expression': 'c.vol["fraction_Zc1"] * nm.eye(%d) - c.Q1' % dim,
            'class': cb.CoefEval,
        },
        'P1T': {
            'requires': ['c.P1'],
            'expression': 'c.P1.T',
            'class': cb.CoefEval,
        },
        'Q2': {
            'requires': ['corrs_phi_k_2', 'pis_pm'],
            'expression':
            'dw_diffusion.i.Zm(hmatrix.K, Pm1, Pm2)',
            'set_variables': [('Pm1', 'pis_pm', 'pm'),
                              ('Pm2', 'corrs_phi_k_2', 'pm')],
            'class':
            cb.CoefDimDim,
        },
        'P2': {
            'requires': ['c.Q2', 'c.vol'],
            'expression': 'c.vol["fraction_Zc2"] * nm.eye(%d) - c.Q2' % dim,
            'class': cb.CoefEval,
        },
        'P2T': {
            'requires': ['c.P2'],
            'expression': 'c.P2.T',
            'class': cb.CoefEval,
        },
        'M_aux1': {
            'status': 'auxiliary',
            'requires': [],
            'expression': 'ev_volume_integrate_mat.i.Zm(hmatrix.M, one)',
            'set_variables': [],
            'class': cb.CoefOne,
        },
        'M_aux2': {
            'status':
            'auxiliary',
            'requires': ['corrs_omega_p', 'corr_one'],
            'expression':
            'dw_biot.i.Zm(hmatrix.B, U1, one)',
            'set_variables': [('U1', 'corrs_omega_p', 'u'),
                              ('one', 'corr_one', 'one')],
            'class':
            cb.CoefOne,
        },
        'M_aux3': {
            'status': 'auxiliary',
            'requires': ['corrs_omega_p'],
            'expression': ' dw_surface_ltr.i.Gamma_Zm(U1)',
            'set_variables': [('U1', 'corrs_omega_p', 'u')],
            'class': cb.CoefOne,
        },
        'M': {
            'requires': ['c.M_aux1', 'c.M_aux2', 'c.M_aux3'],
            'expression': 'c.M_aux1 + c.M_aux2 -c.M_aux3 ',
            'class': cb.CoefEval,
        },
        'S1': {
            'requires': ['corrs_psi_ij_1', 'pis_w1'],
            'expression':
            'dw_lin_elastic.i.Zc1(fluid.eta_c, par1_w1, par2_w1)',
            'set_variables': [('par1_w1', ('corrs_psi_ij_1', 'pis_w1'), 'w1'),
                              ('par2_w1', ('corrs_psi_ij_1', 'pis_w1'), 'w1')],
            'class':
            cb.CoefSymSym,
        },
        'S2': {
            'requires': ['corrs_psi_ij_2', 'pis_w2'],
            'expression':
            'dw_lin_elastic.i.Zc2(fluid.eta_c, par1_w2, par2_w2)',
            'set_variables': [('par1_w2', ('corrs_psi_ij_2', 'pis_w2'), 'w2'),
                              ('par2_w2', ('corrs_psi_ij_2', 'pis_w2'), 'w2')],
            'class':
            cb.CoefSymSym,
        },
        'vol': {
            'regions': ['Zm', 'Zc1', 'Zc2'],
            'expression': 'd_volume.i.%s(one)',
            'class': cb.VolumeFractions,
        },
        'surf_vol': {
            'regions': ['Zm', 'Zc1', 'Zc2'],
            'expression': 'd_surface.i.%s(one)',
            'class': cb.VolumeFractions,
        },
        'surf_c': {
            'requires': ['c.surf_vol'],
            'expression':
            'c.surf_vol["fraction_Zc1"]+c.surf_vol["fraction_Zc2"]',
            'class': cb.CoefEval,
        },
        'vol_c': {
            'requires': ['c.vol'],
            'expression': 'c.vol["fraction_Zc1"]+c.vol["fraction_Zc2"]',
            'class': cb.CoefEval,
        },
        'filenames': {},
    }
    #Definition of mesoscopic corrector problems
    requirements = {
        'corr_one': {
            'variable': 'one',
            'expression':
            "nm.ones((problem.fields['one'].n_vertex_dof, 1), dtype=nm.float64)",
            'class': cb.CorrEval,
        },
        'pis_u': {
            'variables': ['u'],
            'class': cb.ShapeDimDim,
            'save_name': 'corrs_pis_u',
            'dump_variables': ['u'],
        },
        'pis_pm': {
            'variables': ['pm'],
            'class': cb.ShapeDim,
        },
        'pis_w1': {
            'variables': ['w1'],
            'class': cb.ShapeDimDim,
        },
        'pis_w2': {
            'variables': ['w2'],
            'class': cb.ShapeDimDim,
        },
        # Corrector problem, see (31)_1
        'corrs_omega_ij': {
            'requires': ['pis_u'],
            'ebcs': ['fixed_u'],
            'epbcs': periodic['per_u'],
            'is_linear': True,
            'equations': {
                'balance_of_forces':
                """dw_lin_elastic.i.Zm(hmatrix.A, v, u)
                   = - dw_lin_elastic.i.Zm(hmatrix.A, v, Pi_u)"""
            },
            'set_variables': [('Pi_u', 'pis_u', 'u')],
            'class': cb.CorrDimDim,
            'save_name': 'corrs_omega_ij',
            'dump_variables': ['u'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em6'
            },
            'is_linear': True,
        },
        # Corrector problem, see (31)_2
        'corrs_omega_p': {
            'requires': ['corr_one'],
            'ebcs': ['fixed_u'],
            'epbcs': periodic['per_u'],
            'equations': {
                'balance_of_forces':
                """dw_lin_elastic.i.Zm(hmatrix.A, v, u)
                     = dw_biot.i.Zm(hmatrix.B, v, one)
                     - dw_surface_ltr.i.Gamma_Zm(v)""",
            },
            'set_variables': [('one', 'corr_one', 'one')],
            'class': cb.CorrOne,
            'save_name': 'corrs_omega_p',
            'dump_variables': ['u'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em9'
            },
        },
        # Corrector problem, see (31)_3
        'corrs_pi_k': {
            'requires': ['pis_pm'],
            'ebcs': [],  # ['fixed_pm'],
            'epbcs': periodic['per_pm'],
            'is_linear': True,
            'equations': {
                'eq':
                """dw_diffusion.i.Zm(hmatrix.K, qm, pm)
                   = - dw_diffusion.i.Zm(hmatrix.K, qm, Pi_pm)""",
            },
            'set_variables': [('Pi_pm', 'pis_pm', 'pm')],
            'class': cb.CorrDim,
            'save_name': 'corrs_pi_k',
            'dump_variables': ['pm'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em12'
            },
        },
        # Corrector problem, see (31)_4
        'corrs_phi_k_1': {
            'requires': [],
            'ebcs': [],
            'epbcs': periodic['per_pm'],
            'equations': {
                'eq':
                """dw_diffusion.i.Zm(hmatrix.K, qm, pm)
                   = - dw_surface_ndot.i.Gamma_Zm1(mat.k%d, qm)""",
            },
            'class': cb.CorrEqPar,
            'eq_pars': [(ii + 1) for ii in range(dim)],
            'save_name': 'corrs_phi_k_1',
            'dump_variables': ['pm'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em9'
            },
        },
        'corrs_phi_k_2': {
            'requires': [],
            'ebcs': [],
            'epbcs': periodic['per_pm'],
            'equations': {
                'eq':
                """dw_diffusion.i.Zm(hmatrix.K, qm, pm)
                   = - dw_surface_ndot.i.Gamma_Zm2(mat.k%d, qm)""",
            },
            'class': cb.CorrEqPar,
            'eq_pars': [(ii + 1) for ii in range(dim)],
            'save_name': 'corrs_phi_k_2',
            'dump_variables': ['pm'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em9'
            },
        },
        # Corrector problem, see (32)
        'corrs_psi_ij_1': {
            'requires': ['pis_w1'],
            'ebcs': ['fixed_w1'],
            'epbcs': periodic['per_w1'] + periodic['per_pc1'],
            'equations': {
                'eq1':
                """2*dw_lin_elastic.i.Zc1(fluid.eta_c, z1, w1)
                     - dw_stokes.i.Zc1(z1, pc1)
                   = - 2*dw_lin_elastic.i.Zc1(fluid.eta_c, z1, Pi_w1)""",
                'eq2':
                """dw_stokes.i.Zc1(w1, qc1)
                   = - dw_stokes.i.Zc1(Pi_w1, qc1)"""
            },
            'set_variables': [('Pi_w1', 'pis_w1', 'w1')],
            'class': cb.CorrDimDim,
            'save_name': 'corrs_psi_ij_1',
            'dump_variables': ['w1', 'pc1'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em15'
            },
            # 'solvers': {'ls': 'ls_s1', 'nls': 'ns_em15'},
            'is_linear': True,
        },
        'corrs_psi_ij_2': {
            'requires': ['pis_w2'],
            'ebcs': ['fixed_w2'],
            'epbcs': periodic['per_w2'] + periodic['per_pc2'],
            'equations': {
                'eq1':
                """2*dw_lin_elastic.i.Zc2(fluid.eta_c, z2, w2)
                     - dw_stokes.i.Zc2(z2, pc2)
                   = - 2*dw_lin_elastic.i.Zc2(fluid.eta_c, z2, Pi_w2)""",
                'eq2':
                """dw_stokes.i.Zc2(w2, qc2)
                   = - dw_stokes.i.Zc2(Pi_w2, qc2)"""
            },
            'set_variables': [('Pi_w2', 'pis_w2', 'w2')],
            'class': cb.CorrDimDim,
            'save_name': 'corrs_psi_ij_1',
            'dump_variables': ['w2', 'pc2'],
            'solvers': {
                'ls': 'ls',
                'nls': 'ns_em15'
            },
            # 'solvers': {'ls': 'ls_s2', 'nls': 'ns_em15'},
            'is_linear': True,
        },
    }

    return locals()
Ejemplo n.º 14
0
def eval_membrane_mooney_rivlin(a1, a2, mtx_c, c33, mode):
    """
    Evaluate stress or tangent stiffness of the Mooney-Rivlin membrane.

    [1] Baoguo Wu, Xingwen Du and Huifeng Tan: A three-dimensional FE
    nonlinear analysis of membranes, Computers & Structures 59 (1996),
    no. 4, 601--605.
    """
    a12 = 2.0 * a1[..., 0, 0]
    a22 = 2.0 * a2[..., 0, 0]

    sh = mtx_c.shape
    sym = dim2sym(sh[2])

    c11 = mtx_c[..., 0, 0]
    c12 = mtx_c[..., 0, 1]
    c22 = mtx_c[..., 1, 1]
    pressure = c33 * (a12 + a22 * (c11 + c22))

    if mode == 0:
        out = nm.empty((sh[0], sh[1], sym, 1))

        # S_11, S_22, S_12.
        out[..., 0, 0] = -pressure * c22 * c33 + a12 + a22 * (c22 + c33)
        out[..., 1, 0] = -pressure * c11 * c33 + a12 + a22 * (c11 + c33)
        out[..., 2, 0] = +pressure * c12 * c33 - a22 * c12

    else:
        out = nm.empty((sh[0], sh[1], sym, sym))

        dp11 = a22 * c33 - pressure * c22 * c33
        dp22 = a22 * c33 - pressure * c11 * c33
        dp12 = 2.0 * pressure * c12 * c33

        # D_11, D_22, D_33
        out[..., 0, 0] = - 2.0 * ((a22 - pressure * c22) * c22 * c33**2
                                  + c33 * c22 * dp11)
        out[..., 1, 1] = - 2.0 * ((a22 - pressure * c11) * c11 * c33**2
                                  + c33 * c11 * dp22)
        out[..., 2, 2] = - a22 + pressure * (c33 + 2.0 * c12**2 * c33**2) \
                         + c12 * c33 * dp12

        # D_21, D_31, D_32
        out[..., 1, 0] = 2.0 * ((a22 - pressure * c33
                                 - (a22 - pressure * c11) * c22 * c33**2)
                                - c33 * c11 * dp11)
        out[..., 2, 0] = 2.0 * (-pressure * c12 * c22 * c33**2
                                + c12 * c33 * dp11)
        out[..., 2, 1] = 2.0 * (-pressure * c12 * c11 * c33**2
                                + c12 * c33 * dp22)

        out[..., 0, 1] = out[..., 1, 0]
        out[..., 0, 2] = out[..., 2, 0]
        out[..., 1, 2] = out[..., 2, 1]

        # D_12, D_13, D_23
        ## out[..., 0, 1] = 2.0 * ((a22 - pressure * c33
        ##                          - (a22 - pressure * c22) * c11 * c33**2)
        ##                         - c33 * c22 * dp22)
        ## out[..., 0, 2] = 2.0 * (a22 - pressure * c22) * c12 * c33**2 \
        ##                  - c33 * c22 * dp12
        ## out[..., 1, 2] = 2.0 * (a22 - pressure * c11) * c12 * c33**2 \
        ##                  - c33 * c11 * dp12

    return out
Ejemplo n.º 15
0
def make_term_args(arg_shapes, arg_kinds, arg_types, ats_mode, domain):
    from sfepy.base.base import basestr
    from sfepy.fem import Field, FieldVariable, Material, Variables, Materials
    from sfepy.mechanics.tensors import dim2sym

    omega = domain.regions['Omega']
    dim = domain.shape.dim
    sym = dim2sym(dim)

    def _parse_scalar_shape(sh):
        if isinstance(sh, basestr):
            if sh == 'D':
                return dim

            elif sh == 'S':
                return sym

            elif sh == 'N':  # General number ;)
                return 5

            else:
                return int(sh)

        else:
            return sh

    def _parse_tuple_shape(sh):
        if isinstance(sh, basestr):
            return [_parse_scalar_shape(ii.strip()) for ii in sh.split(',')]

        else:
            return (int(sh), )

    args = {}
    str_args = []
    materials = []
    variables = []
    for ii, arg_kind in enumerate(arg_kinds):
        if ats_mode is not None:
            extended_ats = arg_types[ii] + ('/%s' % ats_mode)

        else:
            extended_ats = arg_types[ii]

        try:
            sh = arg_shapes[arg_types[ii]]

        except KeyError:
            sh = arg_shapes[extended_ats]

        if arg_kind.endswith('variable'):
            shape = _parse_scalar_shape(sh[0] if isinstance(sh, tuple) else sh)
            field = Field.from_args('f%d' % ii,
                                    nm.float64,
                                    shape,
                                    omega,
                                    approx_order=1)

            if arg_kind == 'virtual_variable':
                if sh[1] is not None:
                    istate = arg_types.index(sh[1])

                else:
                    # Only virtual variable in arguments.
                    istate = -1
                    # -> Make fake variable.
                    var = FieldVariable('u-1', 'unknown', field, shape)
                    var.set_constant(0.0)
                    variables.append(var)

                var = FieldVariable('v',
                                    'test',
                                    field,
                                    shape,
                                    primary_var_name='u%d' % istate)

            elif arg_kind == 'state_variable':
                var = FieldVariable('u%d' % ii, 'unknown', field, shape)
                var.set_constant(0.0)

            elif arg_kind == 'parameter_variable':
                var = FieldVariable('p%d' % ii,
                                    'parameter',
                                    field,
                                    shape,
                                    primary_var_name='(set-to-None)')
                var.set_constant(0.0)

            variables.append(var)
            str_args.append(var.name)
            args[var.name] = var

        elif arg_kind.endswith('material'):
            if sh is None:  # Switched-off opt_material.
                continue

            prefix = ''
            if isinstance(sh, basestr):
                aux = sh.split(':')
                if len(aux) == 2:
                    prefix, sh = aux

            shape = _parse_tuple_shape(sh)
            if (len(shape) > 1) or (shape[0] > 1):
                # Array.
                values = {
                    '%sc%d' % (prefix, ii): nm.ones(shape, dtype=nm.float64)
                }

            elif (len(shape) == 1) and (shape[0] == 1):
                # Single scalar as a special value.
                values = {'.c%d' % ii: 1.0}

            else:
                raise ValueError('wrong material shape! (%s)' % shape)

            mat = Material('m%d' % ii, values=values)

            materials.append(mat)
            str_args.append(mat.name + '.' + 'c%d' % ii)
            args[mat.name] = mat

        else:
            str_args.append('user%d' % ii)
            args[str_args[-1]] = None

    materials = Materials(materials)
    variables = Variables(variables)

    return args, str_args, materials, variables
Ejemplo n.º 16
0
def eval_membrane_mooney_rivlin(a1, a2, mtx_c, c33, mode):
    """
    Evaluate stress or tangent stiffness of the Mooney-Rivlin membrane.

    [1] Baoguo Wu, Xingwen Du and Huifeng Tan: A three-dimensional FE
    nonlinear analysis of membranes, Computers & Structures 59 (1996),
    no. 4, 601--605.
    """
    a12 = 2.0 * a1[..., 0, 0]
    a22 = 2.0 * a2[..., 0, 0]

    sh = mtx_c.shape
    sym = dim2sym(sh[2])

    c11 = mtx_c[..., 0, 0]
    c12 = mtx_c[..., 0, 1]
    c22 = mtx_c[..., 1, 1]
    pressure = c33 * (a12 + a22 * (c11 + c22))

    if mode == 0:
        out = nm.empty((sh[0], sh[1], sym, 1))

        # S_11, S_22, S_12.
        out[..., 0, 0] = -pressure * c22 * c33 + a12 + a22 * (c22 + c33)
        out[..., 1, 0] = -pressure * c11 * c33 + a12 + a22 * (c11 + c33)
        out[..., 2, 0] = +pressure * c12 * c33 - a22 * c12

    else:
        out = nm.empty((sh[0], sh[1], sym, sym))

        dp11 = a22 * c33 - pressure * c22 * c33
        dp22 = a22 * c33 - pressure * c11 * c33
        dp12 = 2.0 * pressure * c12 * c33

        # D_11, D_22, D_33
        out[..., 0, 0] = - 2.0 * ((a22 - pressure * c22) * c22 * c33**2
                                  + c33 * c22 * dp11)
        out[..., 1, 1] = - 2.0 * ((a22 - pressure * c11) * c11 * c33**2
                                  + c33 * c11 * dp22)
        out[..., 2, 2] = - a22 + pressure * (c33 + 2.0 * c12**2 * c33**2) \
                         + c12 * c33 * dp12

        # D_21, D_31, D_32
        out[..., 1, 0] = 2.0 * ((a22 - pressure * c33
                                 - (a22 - pressure * c11) * c22 * c33**2)
                                - c33 * c11 * dp11)
        out[..., 2, 0] = 2.0 * (-pressure * c12 * c22 * c33**2
                                + c12 * c33 * dp11)
        out[..., 2, 1] = 2.0 * (-pressure * c12 * c11 * c33**2
                                + c12 * c33 * dp22)

        out[..., 0, 1] = out[..., 1, 0]
        out[..., 0, 2] = out[..., 2, 0]
        out[..., 1, 2] = out[..., 2, 1]

        # D_12, D_13, D_23
        ## out[..., 0, 1] = 2.0 * ((a22 - pressure * c33
        ##                          - (a22 - pressure * c22) * c11 * c33**2)
        ##                         - c33 * c22 * dp22)
        ## out[..., 0, 2] = 2.0 * (a22 - pressure * c22) * c12 * c33**2 \
        ##                  - c33 * c22 * dp12
        ## out[..., 1, 2] = 2.0 * (a22 - pressure * c11) * c12 * c33**2 \
        ##                  - c33 * c11 * dp12

    return out
Ejemplo n.º 17
0
    def get_eval_shape(self, a1, a2, h0, virtual, state,
                       mode=None, term_mode=None, diff_var=None, **kwargs):
        n_el, n_qp, dim, n_en, n_c = self.get_data_shape(state)
        sym = dim2sym(dim)

        return (n_el, 1, sym, 1), state.dtype
Ejemplo n.º 18
0
    def check_shapes(self, *args, **kwargs):
        """
        Check term argument shapes at run-time.
        """
        from sfepy.base.base import output
        from sfepy.mechanics.tensors import dim2sym

        dim = self.region.dim
        sym = dim2sym(dim)

        def _parse_scalar_shape(sh):
            if isinstance(sh, basestr):
                if sh == 'D':
                    return dim

                elif sh == 'S':
                    return sym

                elif sh == 'N': # General number.
                    return nm.inf

                else:
                    return int(sh)

            else:
                return sh

        def _parse_tuple_shape(sh):
            if isinstance(sh, basestr):
                return tuple((_parse_scalar_shape(ii.strip())
                              for ii in sh.split(',')))

            else:
                return (int(sh),)

        arg_kinds = get_arg_kinds(self.ats)

        arg_shapes_list = self.arg_shapes
        if not isinstance(arg_shapes_list, list):
            arg_shapes_list = [arg_shapes_list]

        # Loop allowed shapes until a match is found, else error.
        allowed_shapes = []
        prev_shapes = {}
        for _arg_shapes in arg_shapes_list:
            # Unset shapes are taken from the previous iteration.
            arg_shapes = copy(prev_shapes)
            arg_shapes.update(_arg_shapes)
            prev_shapes = arg_shapes

            allowed_shapes.append(arg_shapes)

            n_ok = 0
            for ii, arg_kind in enumerate(arg_kinds):
                if arg_kind in ('user', 'ts'):
                    n_ok += 1
                    continue

                arg = args[ii]

                if self.mode is not None:
                    extended_ats = self.ats[ii] + ('/%s' % self.mode)

                else:
                    extended_ats = self.ats[ii]

                try:
                    sh = arg_shapes[self.ats[ii]]

                except KeyError:
                    sh = arg_shapes[extended_ats]

                if arg_kind.endswith('variable'):
                    n_el, n_qp, _dim, n_en, n_c = self.get_data_shape(arg)
                    shape = _parse_scalar_shape(sh[0] if isinstance(sh, tuple)
                                                else sh)
                    if nm.isinf(shape):
                        n_ok += 1

                    else:
                        n_ok += shape == n_c

                elif arg_kind.endswith('material'):
                    if arg is None: # Switched-off opt_material.
                        n_ok += sh is None
                        continue

                    if sh is None:
                        continue

                    prefix = ''
                    if isinstance(sh, basestr):
                        aux = sh.split(':')
                        if len(aux) == 2:
                            prefix, sh = aux

                    shape = _parse_tuple_shape(sh)
                    ls = len(shape)

                    aarg = nm.array(arg, ndmin=1)

                    # Substiture general dimension 'N' with actual value.
                    iinfs = nm.where(nm.isinf(shape))[0]
                    if len(iinfs):
                        shape = list(shape)
                        for iinf in iinfs:
                            shape[iinf] = aarg.shape[-ls+iinf]
                        shape = tuple(shape)

                    if (ls > 1) or (shape[0] > 1):
                        # Array.
                        n_ok += shape == aarg.shape[-ls:]

                    elif (ls == 1) and (shape[0] == 1):
                        # Scalar constant.
                        from numbers import Number
                        n_ok += isinstance(arg, Number)

                else:
                    n_ok += 1

            if n_ok == len(arg_kinds):
                break

        else:
            term_str = '%s.%d.%s(%s)' % (self.name, self.integral.order,
                                         self.region.name, self.arg_str)
            output('allowed argument shapes for term "%s":' % term_str)
            output(allowed_shapes)
            raise ValueError('wrong arguments shapes for "%s" term! (see above)'
                             % term_str)
Ejemplo n.º 19
0
def describe_deformation(el_disps, bfg):
    """
    Describe deformation of a thin incompressible 2D membrane in 3D
    space, composed of flat finite element faces.

    The coordinate system of each element (face), i.e. the membrane
    mid-surface, should coincide with the `x`, `y` axes of the `x-y`
    plane.

    Parameters
    ----------
    el_disps : array
        The displacements of element nodes, shape `(n_el, n_ep, dim)`.
    bfg : array
        The in-plane base function gradients, shape `(n_el, n_qp, dim-1,
        n_ep)`.

    Returns
    -------
    mtx_c ; array
        The in-plane right Cauchy-Green deformation tensor
        :math:`C_{ij}`, :math:`i, j = 1, 2`.
    c33 : array
        The component :math:`C_{33}` computed from the incompressibility
        condition.
    mtx_b : array
        The discrete Green strain variation operator.
    """
    sh = bfg.shape
    n_ep = sh[3]

    dim = el_disps.shape[2]
    sym2 = dim2sym(dim-1)

    # Repeat el_disps by number of quadrature points.
    el_disps_qp = insert_strided_axis(el_disps, 1, bfg.shape[1])

    # Transformed (in-plane) displacement gradient with
    # shape (n_el, n_qp, 2 (-> a), 3 (-> i)), du_i/dX_a.
    du = dot_sequences(bfg, el_disps_qp)

    # Deformation gradient F w.r.t. in plane coordinates.
    # F_{ia} = dx_i / dX_a,
    # a \in {1, 2} (rows), i \in {1, 2, 3} (columns).
    mtx_f = du + nm.eye(dim - 1, dim, dtype=du.dtype)

    # Right Cauchy-Green deformation tensor C.
    # C_{ab} = F_{ka} F_{kb}, a, b \in {1, 2}.
    mtx_c = dot_sequences(mtx_f, mtx_f, 'ABT')

    # C_33 from incompressibility.
    c33 = 1.0 / (mtx_c[..., 0, 0] * mtx_c[..., 1, 1]
                 - mtx_c[..., 0, 1]**2)

    # Discrete Green strain variation operator.
    mtx_b = nm.empty((sh[0], sh[1], sym2, dim * n_ep), dtype=nm.float64)
    mtx_b[..., 0, 0*n_ep:1*n_ep] = bfg[..., 0, :] * mtx_f[..., 0, 0:1]
    mtx_b[..., 0, 1*n_ep:2*n_ep] = bfg[..., 0, :] * mtx_f[..., 0, 1:2]
    mtx_b[..., 0, 2*n_ep:3*n_ep] = bfg[..., 0, :] * mtx_f[..., 0, 2:3]
    mtx_b[..., 1, 0*n_ep:1*n_ep] = bfg[..., 1, :] * mtx_f[..., 1, 0:1]
    mtx_b[..., 1, 1*n_ep:2*n_ep] = bfg[..., 1, :] * mtx_f[..., 1, 1:2]
    mtx_b[..., 1, 2*n_ep:3*n_ep] = bfg[..., 1, :] * mtx_f[..., 1, 2:3]
    mtx_b[..., 2, 0*n_ep:1*n_ep] = bfg[..., 1, :] * mtx_f[..., 0, 0:1] \
                                   + bfg[..., 0, :] * mtx_f[..., 1, 0:1]
    mtx_b[..., 2, 1*n_ep:2*n_ep] = bfg[..., 0, :] * mtx_f[..., 1, 1:2] \
                                   + bfg[..., 1, :] * mtx_f[..., 0, 1:2]
    mtx_b[..., 2, 2*n_ep:3*n_ep] = bfg[..., 0, :] * mtx_f[..., 1, 2:3] \
                                   + bfg[..., 1, :] * mtx_f[..., 0, 2:3]

    return mtx_c, c33, mtx_b