예제 #1
0
    def test_material_functions(self):
        from sfepy.fem import Material

        problem = self.problem
        conf = problem.conf

        ts = problem.get_default_ts(step=0)

        conf_mat1 = conf.get_item_by_name('materials', 'mf1')
        mat1 = Material.from_conf(conf_mat1, problem.functions)
        mat1.time_update(ts, None, mode='normal', problem=problem)

        coors = problem.domain.get_mesh_coors()
        assert_(nm.all(coors[:, 0] == mat1.get_data(None, None, 'x_0')))

        conf_mat2 = conf.get_item_by_name('materials', 'mf2')
        mat2 = Material.from_conf(conf_mat2, problem.functions)
        mat2.time_update(ts, None, mode='normal', problem=problem)

        assert_(nm.all(coors[:, 1] == mat2.get_data(None, None, 'x_1')))

        materials = problem.get_materials()
        materials.time_update(ts,
                              problem.equations,
                              mode='normal',
                              problem=problem)
        mat3 = materials['mf3']
        key = mat3.get_keys(region_name='Omega')[0]

        assert_(nm.all(mat3.get_data(key, 0, 'a') == 10.0))
        assert_(nm.all(mat3.get_data(key, 0, 'b') == 2.0))
        assert_(mat3.get_data(None, None, 'c') == 'ahoj')

        return True
예제 #2
0
    def test_material_functions(self):
        from sfepy.fem import Material

        problem = self.problem
        conf = problem.conf

        ts = problem.get_default_ts(step=0)

        conf_mat1 = conf.get_item_by_name('materials', 'mf1')
        mat1 = Material.from_conf(conf_mat1, problem.functions)
        mat1.time_update(ts, None, mode='normal', problem=problem)

        coors = problem.domain.get_mesh_coors()
        assert_(nm.all(coors[:,0] == mat1.get_data(None, None, 'x_0')))

        conf_mat2 = conf.get_item_by_name('materials', 'mf2')
        mat2 = Material.from_conf(conf_mat2, problem.functions)
        mat2.time_update(ts, None, mode='normal', problem=problem)

        assert_(nm.all(coors[:,1] == mat2.get_data(None, None, 'x_1')))

        materials = problem.get_materials()
        materials.time_update(ts, problem.equations, mode='normal',
                              problem=problem)
        mat3 = materials['mf3']
        key = mat3.get_keys(region_name='Omega')[0]

        assert_(nm.all(mat3.get_data(key, 0, 'a') == 10.0))
        assert_(nm.all(mat3.get_data(key, 0, 'b') == 2.0))
        assert_(mat3.get_data(None, None, 'c') == 'ahoj')

        return True
예제 #3
0
    def test_solving(self):
        from sfepy.base.base import IndexedStruct
        from sfepy.fem \
             import FieldVariable, Material, ProblemDefinition, \
                    Function, Equation, Equations, Integral
        from sfepy.fem.conditions import Conditions, EssentialBC
        from sfepy.terms import Term
        from sfepy.solvers.ls import ScipyDirect
        from sfepy.solvers.nls import Newton

        u = FieldVariable('u', 'unknown', self.field, self.dim)
        v = FieldVariable('v', 'test', self.field, self.dim,
                          primary_var_name='u')

        m = Material('m', lam=1.0, mu=1.0)
        f = Material('f', val=[[0.02], [0.01]])

        bc_fun = Function('fix_u_fun', fix_u_fun,
                          extra_args={'extra_arg' : 'hello'})

        fix_u = EssentialBC('fix_u', self.gamma1, {'u.all' : bc_fun})
        shift_u = EssentialBC('shift_u', self.gamma2, {'u.0' : 0.1})

        integral = Integral('i', order=3)

        t1 = Term.new('dw_lin_elastic_iso(m.lam, m.mu, v, u)',
                      integral, self.omega, m=m, v=v, u=u)

        t2 = Term.new('dw_volume_lvf(f.val, v)', integral, self.omega, f=f, v=v)

        eq = Equation('balance', t1 + t2)
        eqs = Equations([eq])

        ls = ScipyDirect({})

        nls_status = IndexedStruct()
        nls = Newton({}, lin_solver=ls, status=nls_status)

        pb = ProblemDefinition('elasticity', equations=eqs, nls=nls, ls=ls)
        ## pb.save_regions_as_groups('regions')

        pb.time_update(ebcs=Conditions([fix_u, shift_u]))

        state = pb.solve()

        name = op.join(self.options.out_dir, 'test_high_level_solving.vtk')
        pb.save_state(name, state)

        ok = nls_status.condition == 0
        if not ok:
            self.report('solver did not converge!')

        _ok = state.has_ebc()
        if not _ok:
            self.report('EBCs violated!')

        ok = ok and _ok

        return ok
예제 #4
0
    def test_boundary_fluxes( self ):
        import os.path as op
        from sfepy.linalg import rotation_matrix2d
        from sfepy.fem.evaluate import BasicEvaluator
        from sfepy.fem import Material
        problem = self.problem

        angles = [0, 30, 45]
        region_names = ['Left', 'Right', 'Gamma']
        values = [5.0, -5.0, 0.0]

        variables = problem.get_variables()
        get_state = variables.get_state_part_view
        state = self.state.copy(deep=True)

        problem.time_update(ebcs={}, epbcs={})
#        problem.save_ebc( 'aux.vtk' )

        state.apply_ebc()
        ev = BasicEvaluator( problem )
        aux = ev.eval_residual(state())

        field = variables['t'].field

        conf_m = problem.conf.get_item_by_name('materials', 'm')
        m = Material.from_conf(conf_m, problem.functions)

        name = op.join( self.options.out_dir,
                        op.split( problem.domain.mesh.name )[1] + '_%02d.mesh' ) 

        orig_coors = problem.get_mesh_coors().copy()
        ok = True
        for ia, angle in enumerate( angles ):
            self.report( '%d: mesh rotation %d degrees' % (ia, angle) )
            problem.domain.mesh.transform_coors( rotation_matrix2d( angle ),
                                                 ref_coors = orig_coors )
            problem.set_mesh_coors(problem.domain.mesh.coors,
                                   update_fields=True)
            problem.domain.mesh.write( name % angle, io = 'auto' )
            for ii, region_name in enumerate( region_names ):
                flux_term = 'd_surface_flux.i2.%s( m.K, t )' % region_name
                val1 = problem.evaluate(flux_term, t=variables['t'], m=m)

                rvec = get_state( aux, 't', True )
                reg = problem.domain.regions[region_name]
                nods = field.get_dofs_in_region(reg, merge=True)
                val2 = rvec[nods].sum() # Assume 1 dof per node.

                ok = ok and ((abs( val1 - values[ii] ) < 1e-10) and
                             (abs( val2 - values[ii] ) < 1e-10))
                self.report( '  %d. %s: %e == %e == %e'\
                             % (ii, region_name, val1, val2, values[ii]) )

        # Restore original coordinates.
        problem.domain.mesh.transform_coors(rotation_matrix2d(0),
                                            ref_coors=orig_coors)
        problem.set_mesh_coors(problem.domain.mesh.coors,
                               update_fields=True)

        return ok
예제 #5
0
    def test_boundary_fluxes(self):
        import os.path as op
        from sfepy.linalg import rotation_matrix2d
        from sfepy.fem.evaluate import BasicEvaluator
        from sfepy.fem import Material
        problem = self.problem

        angles = [0, 30, 45]
        region_names = ['Left', 'Right', 'Gamma']
        values = [5.0, -5.0, 0.0]

        variables = problem.get_variables()
        get_state = variables.get_state_part_view
        state = self.state.copy(deep=True)

        problem.time_update(ebcs={}, epbcs={})
        #        problem.save_ebc( 'aux.vtk' )

        state.apply_ebc()
        ev = BasicEvaluator(problem)
        aux = ev.eval_residual(state())

        field = variables['t'].field

        conf_m = problem.conf.get_item_by_name('materials', 'm')
        m = Material.from_conf(conf_m, problem.functions)

        name = op.join(self.options.out_dir,
                       op.split(problem.domain.mesh.name)[1] + '_%02d.mesh')

        orig_coors = problem.get_mesh_coors().copy()
        ok = True
        for ia, angle in enumerate(angles):
            self.report('%d: mesh rotation %d degrees' % (ia, angle))
            problem.domain.mesh.transform_coors(rotation_matrix2d(angle),
                                                ref_coors=orig_coors)
            problem.set_mesh_coors(problem.domain.mesh.coors,
                                   update_fields=True)
            problem.domain.mesh.write(name % angle, io='auto')
            for ii, region_name in enumerate(region_names):
                flux_term = 'd_surface_flux.i2.%s( m.K, t )' % region_name
                val1 = problem.evaluate(flux_term, t=variables['t'], m=m)

                rvec = get_state(aux, 't', True)
                reg = problem.domain.regions[region_name]
                nods = field.get_dofs_in_region(reg, merge=True)
                val2 = rvec[nods].sum()  # Assume 1 dof per node.

                ok = ok and ((abs(val1 - values[ii]) < 1e-10) and
                             (abs(val2 - values[ii]) < 1e-10))
                self.report( '  %d. %s: %e == %e == %e'\
                             % (ii, region_name, val1, val2, values[ii]) )

        # Restore original coordinates.
        problem.domain.mesh.transform_coors(rotation_matrix2d(0),
                                            ref_coors=orig_coors)
        problem.set_mesh_coors(problem.domain.mesh.coors, update_fields=True)

        return ok
예제 #6
0
def make_h1_projection_data(target, eval_data):
    """
    Project scalar data given by a material-like `eval_data()` function to a
    scalar `target` field variable using the :math:`H^1` dot product.
    """
    order = target.field.approx_order * 2
    integral = Integral('i', order=order)

    un = target.name
    v = FieldVariable('v', 'test', target.field, 1, primary_var_name=un)
    lhs1 = Term.new('dw_volume_dot(v, %s)' % un,
                    integral,
                    target.field.region,
                    v=v,
                    **{un: target})
    lhs2 = Term.new('dw_laplace(v, %s)' % un,
                    integral,
                    target.field.region,
                    v=v,
                    **{un: target})

    def _eval_data(ts, coors, mode, **kwargs):
        if mode == 'qp':
            val = eval_data(ts, coors, mode, 'val', **kwargs)
            gval = eval_data(ts, coors, mode, 'grad', **kwargs)
            return {'val': val, 'gval': gval}

    m = Material('m', function=_eval_data)
    rhs1 = Term.new('dw_volume_lvf(m.val, v)',
                    integral,
                    target.field.region,
                    m=m,
                    v=v)
    rhs2 = Term.new('dw_diffusion_r(m.gval, v)',
                    integral,
                    target.field.region,
                    m=m,
                    v=v)

    eq = Equation('projection', lhs1 + lhs2 - rhs1 - rhs2)
    eqs = Equations([eq])

    ls = ScipyDirect({})

    nls_status = IndexedStruct()
    nls = Newton({}, lin_solver=ls, status=nls_status)

    pb = ProblemDefinition('aux', equations=eqs, nls=nls, ls=ls)

    pb.time_update()

    # This sets the target variable with the projection solution.
    pb.solve()

    if nls_status.condition != 0:
        output('H1 projection: solver did not converge!')
예제 #7
0
    def test_boundary_fluxes(self):
        from sfepy.fem.evaluate import BasicEvaluator
        from sfepy.fem import Material
        problem = self.problem

        region_names = ['Gamma']

        variables = problem.get_variables()
        get_state = variables.get_state_part_view
        state = self.state.copy(deep=True)

        problem.time_update(ebcs={}, epbcs={})
        ## problem.save_ebc( 'aux.vtk' )

        state.apply_ebc()
        ev = BasicEvaluator(problem)
        aux = ev.eval_residual(state())

        field = variables['t'].field

        conf_m = problem.conf.get_item_by_name('materials', 'm')
        m = Material.from_conf(conf_m, problem.functions)

        ok = True
        for ii, region_name in enumerate(region_names):
            flux_term = 'd_surface_flux.1.%s( m.K, t )' % region_name
            val1 = problem.evaluate(flux_term, t=variables['t'], m=m)

            rvec = get_state(aux, 't', True)
            reg = problem.domain.regions[region_name]
            nods = field.get_dofs_in_region(reg, merge=True)
            val2 = rvec[nods].sum()  # Assume 1 dof per node.

            eps = 1e-2
            ok = ok and ((abs(val1 - val2) < eps))
            self.report( '%d. %s: |%e - %e| = %e < %.2e'\
                         % (ii, region_name, val1, val2, abs( val1 - val2 ),
                            eps) )

        return ok
    def test_boundary_fluxes( self ):
        from sfepy.fem.evaluate import BasicEvaluator
        from sfepy.fem import Material
        problem = self.problem

        region_names = ['Gamma']

        variables = problem.get_variables()
        get_state = variables.get_state_part_view
        state = self.state.copy(deep=True)

        problem.time_update(ebcs={}, epbcs={})
        ## problem.save_ebc( 'aux.vtk' )

        state.apply_ebc()
        ev = BasicEvaluator( problem )
        aux = ev.eval_residual(state())

        field = variables['t'].field

        conf_m = problem.conf.get_item_by_name('materials', 'm')
        m = Material.from_conf(conf_m, problem.functions)

        ok = True
        for ii, region_name in enumerate( region_names ):
            flux_term = 'd_surface_flux.1.%s( m.K, t )' % region_name
            val1 = problem.evaluate(flux_term, t=variables['t'], m=m)

            rvec = get_state( aux, 't', True )
            reg = problem.domain.regions[region_name]
            nods = field.get_dofs_in_region(reg, merge=True)
            val2 = rvec[nods].sum() # Assume 1 dof per node.

            eps = 1e-2
            ok = ok and ((abs( val1 - val2 ) < eps))
            self.report( '%d. %s: |%e - %e| = %e < %.2e'\
                         % (ii, region_name, val1, val2, abs( val1 - val2 ),
                            eps) )

        return ok
예제 #9
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
예제 #10
0
def main():
    from sfepy import data_dir

    parser = OptionParser(usage=usage, version='%prog')
    parser.add_option('-s',
                      '--show',
                      action="store_true",
                      dest='show',
                      default=False,
                      help=help['show'])
    options, args = parser.parse_args()

    mesh = Mesh.from_file(data_dir + '/meshes/2d/rectangle_tri.mesh')
    domain = Domain('domain', mesh)

    min_x, max_x = domain.get_mesh_bounding_box()[:, 0]
    eps = 1e-8 * (max_x - min_x)
    omega = domain.create_region('Omega', 'all')
    gamma1 = domain.create_region('Gamma1',
                                  'nodes in x < %.10f' % (min_x + eps))
    gamma2 = domain.create_region('Gamma2',
                                  'nodes in x > %.10f' % (max_x - eps))

    field = H1NodalVolumeField('fu',
                               nm.float64,
                               'vector',
                               omega,
                               approx_order=2)

    u = FieldVariable('u', 'unknown', field, mesh.dim)
    v = FieldVariable('v', 'test', field, mesh.dim, primary_var_name='u')

    m = Material('m', lam=1.0, mu=1.0)
    f = Material('f', val=[[0.02], [0.01]])

    integral = Integral('i', order=3)

    t1 = Term.new('dw_lin_elastic_iso(m.lam, m.mu, v, u)',
                  integral,
                  omega,
                  m=m,
                  v=v,
                  u=u)
    t2 = Term.new('dw_volume_lvf(f.val, v)', integral, omega, f=f, v=v)
    eq = Equation('balance', t1 + t2)
    eqs = Equations([eq])

    fix_u = EssentialBC('fix_u', gamma1, {'u.all': 0.0})

    bc_fun = Function('shift_u_fun', shift_u_fun, extra_args={'shift': 0.01})
    shift_u = EssentialBC('shift_u', gamma2, {'u.0': bc_fun})

    ls = ScipyDirect({})

    nls_status = IndexedStruct()
    nls = Newton({}, lin_solver=ls, status=nls_status)

    pb = ProblemDefinition('elasticity', equations=eqs, nls=nls, ls=ls)
    pb.save_regions_as_groups('regions')

    pb.time_update(ebcs=Conditions([fix_u, shift_u]))

    vec = pb.solve()
    print nls_status

    pb.save_state('linear_elasticity.vtk', vec)

    if options.show:
        view = Viewer('linear_elasticity.vtk')
        view(vector_mode='warp_norm',
             rel_scaling=2,
             is_scalar_bar=True,
             is_wireframe=True)
예제 #11
0
def main():
    parser = OptionParser(usage=usage, version='%prog')
    parser.add_option('-b',
                      '--basis',
                      metavar='name',
                      action='store',
                      dest='basis',
                      default='lagrange',
                      help=help['basis'])
    parser.add_option('-n',
                      '--max-order',
                      metavar='order',
                      type=int,
                      action='store',
                      dest='max_order',
                      default=10,
                      help=help['max_order'])
    parser.add_option('-m',
                      '--matrix',
                      metavar='type',
                      action='store',
                      dest='matrix_type',
                      default='laplace',
                      help=help['matrix_type'])
    parser.add_option('-g',
                      '--geometry',
                      metavar='name',
                      action='store',
                      dest='geometry',
                      default='2_4',
                      help=help['geometry'])
    options, args = parser.parse_args()

    dim, n_ep = int(options.geometry[0]), int(options.geometry[2])
    output('reference element geometry:')
    output('  dimension: %d, vertices: %d' % (dim, n_ep))

    n_c = {'laplace': 1, 'elasticity': dim}[options.matrix_type]

    output('matrix type:', options.matrix_type)
    output('number of variable components:', n_c)

    output('polynomial space:', options.basis)

    output('max. order:', options.max_order)

    mesh = Mesh.from_file(data_dir +
                          '/meshes/elements/%s_1.mesh' % options.geometry)
    domain = Domain('domain', mesh)
    omega = domain.create_region('Omega', 'all')

    orders = nm.arange(1, options.max_order + 1, dtype=nm.int)
    conds = []

    order_fix = 0 if options.geometry in ['2_4', '3_8'] else 1

    for order in orders:
        output('order:', order, '...')

        field = Field.from_args('fu',
                                nm.float64,
                                n_c,
                                omega,
                                approx_order=order,
                                space='H1',
                                poly_space_base=options.basis)

        to = field.approx_order
        quad_order = 2 * (max(to - order_fix, 0))
        output('quadrature order:', quad_order)

        integral = Integral('i', order=quad_order)
        qp, _ = integral.get_qp(options.geometry)
        output('number of quadrature points:', qp.shape[0])

        u = FieldVariable('u', 'unknown', field, n_c)
        v = FieldVariable('v', 'test', field, n_c, primary_var_name='u')

        m = Material('m', lam=1.0, mu=1.0)

        if options.matrix_type == 'laplace':
            term = Term.new('dw_laplace(m.mu, v, u)',
                            integral,
                            omega,
                            m=m,
                            v=v,
                            u=u)
            n_zero = 1

        else:
            assert_(options.matrix_type == 'elasticity')
            term = Term.new('dw_lin_elastic_iso(m.lam, m.mu, v, u)',
                            integral,
                            omega,
                            m=m,
                            v=v,
                            u=u)
            n_zero = (dim + 1) * dim / 2

        term.setup()

        output('assembling...')
        tt = time.clock()
        mtx, iels = term.evaluate(mode='weak', diff_var='u')
        output('...done in %.2f s' % (time.clock() - tt))
        mtx = mtx[0][0, 0]

        try:
            assert_(nm.max(nm.abs(mtx - mtx.T)) < 1e-10)

        except:
            from sfepy.base.base import debug
            debug()

        output('matrix shape:', mtx.shape)

        eigs = eig(mtx, method='eig.sgscipy', eigenvectors=False)
        eigs.sort()

        # Zero 'true' zeros.
        eigs[:n_zero] = 0.0

        ii = nm.where(eigs < 0.0)[0]
        if len(ii):
            output('matrix is not positive semi-definite!')

        ii = nm.where(eigs[n_zero:] < 1e-12)[0]
        if len(ii):
            output('matrix has more than %d zero eigenvalues!' % n_zero)

        output('smallest eigs:\n', eigs[:10])

        ii = nm.where(eigs > 0.0)[0]
        emin, emax = eigs[ii[[0, -1]]]

        output('min:', emin, 'max:', emax)

        cond = emax / emin
        conds.append(cond)

        output('condition number:', cond)

        output('...done')

    plt.figure(1)
    plt.semilogy(orders, conds)
    plt.xticks(orders, orders)
    plt.xlabel('polynomial order')
    plt.ylabel('condition number')
    plt.grid()

    plt.figure(2)
    plt.loglog(orders, conds)
    plt.xticks(orders, orders)
    plt.xlabel('polynomial order')
    plt.ylabel('condition number')
    plt.grid()

    plt.show()